From 20667a1333c0faf14c59a9809d54471ba9a6a4f9 Mon Sep 17 00:00:00 2001 From: Seth Williams <92401567+swilliams-northpointkc@users.noreply.github.com> Date: Tue, 24 Jan 2023 11:56:24 -0600 Subject: [PATCH 01/11] BMAPS-1689 Fork Vector-Tiles-Google-Maps and set up as NPM package (#1) * Clean up VSCode-related files * Add npm project and configs * Add config files * Add basic unit test * Add sourceType of module to eslint configs * Restore example screenshot --- .eslintrc.js | 30 + .gitattributes | 63 - .gitignore | 366 +- Properties/AssemblyInfo.cs | 34 - Vector Tiles Google Maps.csproj | 154 - Vector Tiles Google Maps.sln | 25 - Web.Debug.config | 30 - Web.Release.config | 31 - Web.config | 18 - _config.yml | 1 - bundleconfig.json | 16 - jsconfig.json | 10 + package-lock.json | 7955 +++++++++++++++++++++++++++++++ package.json | 24 + packages.config | 4 - tests/helloWorld.spec.js | 5 + 16 files changed, 8027 insertions(+), 739 deletions(-) create mode 100644 .eslintrc.js delete mode 100644 .gitattributes delete mode 100644 Properties/AssemblyInfo.cs delete mode 100644 Vector Tiles Google Maps.csproj delete mode 100644 Vector Tiles Google Maps.sln delete mode 100644 Web.Debug.config delete mode 100644 Web.Release.config delete mode 100644 Web.config delete mode 100644 _config.yml delete mode 100644 bundleconfig.json create mode 100644 jsconfig.json create mode 100644 package-lock.json create mode 100644 package.json delete mode 100644 packages.config create mode 100644 tests/helloWorld.spec.js diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..1484d15 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,30 @@ +module.exports = { + root: true, + env: { + 'jest': true, + 'browser': true, + 'node': true, + }, + extends: [ + 'eslint:recommended', + 'google', + 'plugin:jest/recommended', + 'plugin:jest/style', + ], + parserOptions: { + 'ecmaVersion': 2022, + 'sourceType': 'module', + }, + plugins: ['jest'], + rules: { + 'require-jsdoc': 'off', + 'max-len': ['error', { + 'ignoreStrings': true, + 'ignoreTemplateLiterals': true, + 'ignoreRegExpLiterals': true, + 'ignoreUrls': true, + 'code': 120, + }], + 'jest/no-disabled-tests': ['error'], + }, +}; diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 1ff0c42..0000000 --- a/.gitattributes +++ /dev/null @@ -1,63 +0,0 @@ -############################################################################### -# Set default behavior to automatically normalize line endings. -############################################################################### -* text=auto - -############################################################################### -# Set default behavior for command prompt diff. -# -# This is need for earlier builds of msysgit that does not have it on by -# default for csharp files. -# Note: This is only used by command line -############################################################################### -#*.cs diff=csharp - -############################################################################### -# Set the merge driver for project and solution files -# -# Merging from the command prompt will add diff markers to the files if there -# are conflicts (Merging from VS is not affected by the settings below, in VS -# the diff markers are never inserted). Diff markers may cause the following -# file extensions to fail to load in VS. An alternative would be to treat -# these files as binary and thus will always conflict and require user -# intervention with every merge. To do so, just uncomment the entries below -############################################################################### -#*.sln merge=binary -#*.csproj merge=binary -#*.vbproj merge=binary -#*.vcxproj merge=binary -#*.vcproj merge=binary -#*.dbproj merge=binary -#*.fsproj merge=binary -#*.lsproj merge=binary -#*.wixproj merge=binary -#*.modelproj merge=binary -#*.sqlproj merge=binary -#*.wwaproj merge=binary - -############################################################################### -# behavior for image files -# -# image files are treated as binary by default. -############################################################################### -#*.jpg binary -#*.png binary -#*.gif binary - -############################################################################### -# diff behavior for common document formats -# -# Convert binary document formats to text before diffing them. This feature -# is only available from the command line. Turn it on by uncommenting the -# entries below. -############################################################################### -#*.doc diff=astextplain -#*.DOC diff=astextplain -#*.docx diff=astextplain -#*.DOCX diff=astextplain -#*.dot diff=astextplain -#*.DOT diff=astextplain -#*.pdf diff=astextplain -#*.PDF diff=astextplain -#*.rtf diff=astextplain -#*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore index 9491a2f..413d431 100644 --- a/.gitignore +++ b/.gitignore @@ -1,363 +1,3 @@ -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. -## -## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore - -# User-specific files -*.rsuser -*.suo -*.user -*.userosscache -*.sln.docstates - -# User-specific files (MonoDevelop/Xamarin Studio) -*.userprefs - -# Mono auto generated files -mono_crash.* - -# Build results -[Dd]ebug/ -[Dd]ebugPublic/ -[Rr]elease/ -[Rr]eleases/ -x64/ -x86/ -[Ww][Ii][Nn]32/ -[Aa][Rr][Mm]/ -[Aa][Rr][Mm]64/ -bld/ -[Bb]in/ -[Oo]bj/ -[Oo]ut/ -[Ll]og/ -[Ll]ogs/ - -# Visual Studio 2015/2017 cache/options directory -.vs/ -# Uncomment if you have tasks that create the project's static files in wwwroot -#wwwroot/ - -# Visual Studio 2017 auto generated files -Generated\ Files/ - -# MSTest test Results -[Tt]est[Rr]esult*/ -[Bb]uild[Ll]og.* - -# NUnit -*.VisualState.xml -TestResult.xml -nunit-*.xml - -# Build Results of an ATL Project -[Dd]ebugPS/ -[Rr]eleasePS/ -dlldata.c - -# Benchmark Results -BenchmarkDotNet.Artifacts/ - -# .NET Core -project.lock.json -project.fragment.lock.json -artifacts/ - -# ASP.NET Scaffolding -ScaffoldingReadMe.txt - -# StyleCop -StyleCopReport.xml - -# Files built by Visual Studio -*_i.c -*_p.c -*_h.h -*.ilk -*.meta -*.obj -*.iobj -*.pch -*.pdb -*.ipdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.tmp_proj -*_wpftmp.csproj -*.log -*.vspscc -*.vssscc -.builds -*.pidb -*.svclog -*.scc - -# Chutzpah Test files -_Chutzpah* - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opendb -*.opensdf -*.sdf -*.cachefile -*.VC.db -*.VC.VC.opendb - -# Visual Studio profiler -*.psess -*.vsp -*.vspx -*.sap - -# Visual Studio Trace Files -*.e2e - -# TFS 2012 Local Workspace -$tf/ - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper*/ -*.[Rr]e[Ss]harper -*.DotSettings.user - -# TeamCity is a build add-in -_TeamCity* - -# DotCover is a Code Coverage Tool -*.dotCover - -# AxoCover is a Code Coverage Tool -.axoCover/* -!.axoCover/settings.json - -# Coverlet is a free, cross platform Code Coverage Tool -coverage*.json -coverage*.xml -coverage*.info - -# Visual Studio code coverage results -*.coverage -*.coveragexml - -# NCrunch -_NCrunch_* -.*crunch*.local.xml -nCrunchTemp_* - -# MightyMoose -*.mm.* -AutoTest.Net/ - -# Web workbench (sass) -.sass-cache/ - -# Installshield output folder -[Ee]xpress/ - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish/ - -# Publish Web Output -*.[Pp]ublish.xml -*.azurePubxml -# Note: Comment the next line if you want to checkin your web deploy settings, -# but database connection strings (with potential passwords) will be unencrypted -*.pubxml -*.publishproj - -# Microsoft Azure Web App publish settings. Comment the next line if you want to -# checkin your Azure Web App publish settings, but sensitive information contained -# in these scripts will be unencrypted -PublishScripts/ - -# NuGet Packages -*.nupkg -# NuGet Symbol Packages -*.snupkg -# The packages folder can be ignored because of Package Restore -**/[Pp]ackages/* -# except build/, which is used as an MSBuild target. -!**/[Pp]ackages/build/ -# Uncomment if necessary however generally it will be regenerated when needed -#!**/[Pp]ackages/repositories.config -# NuGet v3's project.json files produces more ignorable files -*.nuget.props -*.nuget.targets - -# Microsoft Azure Build Output -csx/ -*.build.csdef - -# Microsoft Azure Emulator -ecf/ -rcf/ - -# Windows Store app package directories and files -AppPackages/ -BundleArtifacts/ -Package.StoreAssociation.xml -_pkginfo.txt -*.appx -*.appxbundle -*.appxupload - -# Visual Studio cache files -# files ending in .cache can be ignored -*.[Cc]ache -# but keep track of directories ending in .cache -!?*.[Cc]ache/ - -# Others -ClientBin/ -~$* -*~ -*.dbmdl -*.dbproj.schemaview -*.jfm -*.pfx -*.publishsettings -orleans.codegen.cs - -# Including strong name files can present a security risk -# (https://github.com/github/gitignore/pull/2483#issue-259490424) -#*.snk - -# Since there are multiple workflows, uncomment next line to ignore bower_components -# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) -#bower_components/ - -# RIA/Silverlight projects -Generated_Code/ - -# Backup & report files from converting an old project file -# to a newer Visual Studio version. Backup files are not needed, -# because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML -UpgradeLog*.htm -ServiceFabricBackup/ -*.rptproj.bak - -# SQL Server files -*.mdf -*.ldf -*.ndf - -# Business Intelligence projects -*.rdl.data -*.bim.layout -*.bim_*.settings -*.rptproj.rsuser -*- [Bb]ackup.rdl -*- [Bb]ackup ([0-9]).rdl -*- [Bb]ackup ([0-9][0-9]).rdl - -# Microsoft Fakes -FakesAssemblies/ - -# GhostDoc plugin setting file -*.GhostDoc.xml - -# Node.js Tools for Visual Studio -.ntvs_analysis.dat -node_modules/ - -# Visual Studio 6 build log -*.plg - -# Visual Studio 6 workspace options file -*.opt - -# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) -*.vbw - -# Visual Studio LightSwitch build output -**/*.HTMLClient/GeneratedArtifacts -**/*.DesktopClient/GeneratedArtifacts -**/*.DesktopClient/ModelManifest.xml -**/*.Server/GeneratedArtifacts -**/*.Server/ModelManifest.xml -_Pvt_Extensions - -# Paket dependency manager -.paket/paket.exe -paket-files/ - -# FAKE - F# Make -.fake/ - -# CodeRush personal settings -.cr/personal - -# Python Tools for Visual Studio (PTVS) -__pycache__/ -*.pyc - -# Cake - Uncomment if you are using it -# tools/** -# !tools/packages.config - -# Tabs Studio -*.tss - -# Telerik's JustMock configuration file -*.jmconfig - -# BizTalk build output -*.btp.cs -*.btm.cs -*.odx.cs -*.xsd.cs - -# OpenCover UI analysis results -OpenCover/ - -# Azure Stream Analytics local run output -ASALocalRun/ - -# MSBuild Binary and Structured Log -*.binlog - -# NVidia Nsight GPU debugger configuration file -*.nvuser - -# MFractors (Xamarin productivity tool) working folder -.mfractor/ - -# Local History for Visual Studio -.localhistory/ - -# BeatPulse healthcheck temp database -healthchecksdb - -# Backup folder for Package Reference Convert tool in Visual Studio 2017 -MigrationBackup/ - -# Ionide (cross platform F# VS Code tools) working folder -.ionide/ - -# Fody - auto-generated XML schema -FodyWeavers.xsd \ No newline at end of file +.DS_Store +node_modules +/dist \ No newline at end of file diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs deleted file mode 100644 index ae4fb7f..0000000 --- a/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Vector_Tiles_Google_Maps")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Vector_Tiles_Google_Maps")] -[assembly: AssemblyCopyright("Copyright © 2021")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("dab49a7d-6e90-404d-ad1e-93c68eafce26")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Revision and Build Numbers -// by using the '*' as shown below: -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file diff --git a/Vector Tiles Google Maps.csproj b/Vector Tiles Google Maps.csproj deleted file mode 100644 index 1e9d109..0000000 --- a/Vector Tiles Google Maps.csproj +++ /dev/null @@ -1,154 +0,0 @@ - - - - - Debug - AnyCPU - - - 2.0 - {DAB49A7D-6E90-404D-AD1E-93C68EAFCE26} - {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} - Library - Properties - Vector_Tiles_Google_Maps - Vector Tiles Google Maps - v4.7.2 - true - - 44390 - - - - - - - - - true - full - false - bin\ - DEBUG;TRACE - prompt - 4 - - - true - pdbonly - true - bin\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - - - - - - - packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll - - - - - - vector-tiles-google-maps.js - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Web.config - - - Web.config - - - - 10.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - - - - - - True - True - 56013 - / - https://localhost:44390/ - False - False - - - False - - - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - \ No newline at end of file diff --git a/Vector Tiles Google Maps.sln b/Vector Tiles Google Maps.sln deleted file mode 100644 index 7880227..0000000 --- a/Vector Tiles Google Maps.sln +++ /dev/null @@ -1,25 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.31112.23 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Vector Tiles Google Maps", "Vector Tiles Google Maps.csproj", "{DAB49A7D-6E90-404D-AD1E-93C68EAFCE26}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {DAB49A7D-6E90-404D-AD1E-93C68EAFCE26}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DAB49A7D-6E90-404D-AD1E-93C68EAFCE26}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DAB49A7D-6E90-404D-AD1E-93C68EAFCE26}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DAB49A7D-6E90-404D-AD1E-93C68EAFCE26}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {A9D7F879-778E-47D3-8DD0-E5973F7D0CA6} - EndGlobalSection -EndGlobal diff --git a/Web.Debug.config b/Web.Debug.config deleted file mode 100644 index 3ab6aa0..0000000 --- a/Web.Debug.config +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/Web.Release.config b/Web.Release.config deleted file mode 100644 index 3398859..0000000 --- a/Web.Release.config +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/Web.config b/Web.config deleted file mode 100644 index 507c053..0000000 --- a/Web.config +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/_config.yml b/_config.yml deleted file mode 100644 index 259a24e..0000000 --- a/_config.yml +++ /dev/null @@ -1 +0,0 @@ -theme: jekyll-theme-tactile \ No newline at end of file diff --git a/bundleconfig.json b/bundleconfig.json deleted file mode 100644 index 919f161..0000000 --- a/bundleconfig.json +++ /dev/null @@ -1,16 +0,0 @@ -[ - { - "outputFileName": "dist/vector-tiles-google-maps.js", - "inputFiles": [ - "lib/protobuf/Protobuf.js", - "lib/vectortiles/VectorTile.js", - "lib/vectortiles/VectorTileFeature.js", - "lib/vectortiles/VectorTileLayer.js", - "lib/vectortiles/Point.js", - "lib/mercator/Mercator.js", - "src/MVTFeature.js", - "src/MVTLayer.js", - "src/MVTSource.js" - ] - } -] \ No newline at end of file diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 0000000..0ded586 --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,10 @@ +{ + "exclude": ["node_modules"], + "compilerOptions": { + "jsx": "preserve", + "baseUrl": "./", + "paths": { + "@/*" : ["src/*"], + } + } +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..d134624 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,7955 @@ +{ + "name": "vector-tiles-google-maps", + "version": "0.0.1", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "vector-tiles-google-maps", + "version": "0.0.1", + "license": "MIT", + "devDependencies": { + "eslint": "^8.32.0", + "eslint-config-google": "^0.14.0", + "eslint-plugin-jest": "^27.2.1", + "jest": "^29.4.0" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.20.10", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.10.tgz", + "integrity": "sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.20.12", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz", + "integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.7", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helpers": "^7.20.7", + "@babel/parser": "^7.20.7", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.12", + "@babel/types": "^7.20.7", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.2", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.7.tgz", + "integrity": "sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.7", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", + "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.20.5", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "dev": true, + "dependencies": { + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "dev": true, + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.20.11", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz", + "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.10", + "@babel/types": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.13.tgz", + "integrity": "sha512-nzJ0DWCL3gB5RCXbUO3KIMMsBY2Eqbx8mBpKGE/02PgyRQFcPQLbkQ1vyy596mZLaP+dAfD+R4ckASzNVmW3jg==", + "dev": true, + "dependencies": { + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.13", + "@babel/types": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/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/@babel/highlight/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/@babel/highlight/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/@babel/highlight/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/@babel/highlight/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/@babel/highlight/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/@babel/highlight/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/@babel/parser": { + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.13.tgz", + "integrity": "sha512-gFDLKMfpiXCsjt4za2JA9oTMn70CeseCehb11kRZgvd7+F67Hih3OHOK24cRrWECJ/ljfPGac6ygXAs/C8kIvw==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", + "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", + "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.19.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.13.tgz", + "integrity": "sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.7", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.20.13", + "@babel/types": "^7.20.7", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/types": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", + "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "node_modules/@eslint/eslintrc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", + "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.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/@humanwhocodes/config-array": { + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.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": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.4.0.tgz", + "integrity": "sha512-xpXud7e/8zo4syxQlAMDz+EQiFsf8/zXDPslBYm+UaSJ5uGTKQHhbSHfECp7Fw1trQtopjYumeved0n3waijhQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.4.0", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.4.0", + "jest-util": "^29.4.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.4.0.tgz", + "integrity": "sha512-E7oCMcENobBFwQXYjnN2IsuUSpRo5jSv7VYk6O9GyQ5kVAfVSS8819I4W5iCCYvqD6+1TzyzLpeEdZEik81kNw==", + "dev": true, + "dependencies": { + "@jest/console": "^29.4.0", + "@jest/reporters": "^29.4.0", + "@jest/test-result": "^29.4.0", + "@jest/transform": "^29.4.0", + "@jest/types": "^29.4.0", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.4.0", + "jest-config": "^29.4.0", + "jest-haste-map": "^29.4.0", + "jest-message-util": "^29.4.0", + "jest-regex-util": "^29.2.0", + "jest-resolve": "^29.4.0", + "jest-resolve-dependencies": "^29.4.0", + "jest-runner": "^29.4.0", + "jest-runtime": "^29.4.0", + "jest-snapshot": "^29.4.0", + "jest-util": "^29.4.0", + "jest-validate": "^29.4.0", + "jest-watcher": "^29.4.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.4.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/environment": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.4.0.tgz", + "integrity": "sha512-ocl1VGDcZHfHnYLTqkBY7yXme1bF4x0BevJ9wb6y0sLOSyBCpp8L5fEASChB+wU53WMrIK6kBfGt+ZYoM2kcdw==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^29.4.0", + "@jest/types": "^29.4.0", + "@types/node": "*", + "jest-mock": "^29.4.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.4.0.tgz", + "integrity": "sha512-IiDZYQ/Oi94aBT0nKKKRvNsB5JTyHoGb+G3SiGoDxz90JfL7SLx/z5IjB0fzBRzy7aLFQOCbVJlaC2fIgU6Y9Q==", + "dev": true, + "dependencies": { + "expect": "^29.4.0", + "jest-snapshot": "^29.4.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.4.0.tgz", + "integrity": "sha512-w/JzTYIqjmPFIM5OOQHF9CawFx2daw1256Nzj4ZqWX96qRKbCq9WYRVqdySBKHHzuvsXLyTDIF6y61FUyrhmwg==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.2.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.4.0.tgz", + "integrity": "sha512-8sitzN2QrhDwEwH3kKcMMgrv/UIkmm9AUgHixmn4L++GQ0CqVTIztm3YmaIQooLmW3O4GhizNTTCyq3iLbWcMw==", + "dev": true, + "dependencies": { + "@jest/types": "^29.4.0", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.4.0", + "jest-mock": "^29.4.0", + "jest-util": "^29.4.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.4.0.tgz", + "integrity": "sha512-Q64ZRgGMVL40RcYTfD2GvyjK7vJLPSIvi8Yp3usGPNPQ3SCW+UCY9KEH6+sVtBo8LzhcjtCXuZEd7avnj/T0mQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.4.0", + "@jest/expect": "^29.4.0", + "@jest/types": "^29.4.0", + "jest-mock": "^29.4.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.4.0.tgz", + "integrity": "sha512-FjJwrD1XOQq/AXKrvnOSf0RgAs6ziUuGKx8+/R53Jscc629JIhg7/m241gf1shUm/fKKxoHd7aCexcg7kxvkWQ==", + "dev": true, + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.4.0", + "@jest/test-result": "^29.4.0", + "@jest/transform": "^29.4.0", + "@jest/types": "^29.4.0", + "@jridgewell/trace-mapping": "^0.3.15", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.4.0", + "jest-util": "^29.4.0", + "jest-worker": "^29.4.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/schemas": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.0.tgz", + "integrity": "sha512-0E01f/gOZeNTG76i5eWWSupvSHaIINrTie7vCyjiYFKgzNdyEGd12BUv4oNBFHOqlHDbtoJi3HrQ38KCC90NsQ==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.25.16" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.2.0.tgz", + "integrity": "sha512-1NX9/7zzI0nqa6+kgpSdKPK+WU1p+SJk3TloWZf5MzPbxri9UEeXX5bWZAPCzbQcyuAzubcdUHA7hcNznmRqWQ==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.15", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.4.0.tgz", + "integrity": "sha512-EtRklzjpddZU/aBVxJqqejfzfOcnehmjNXufs6u6qwd05kkhXpAPhZdt8bLlQd7cA2nD+JqZQ5Dx9NX5Jh6mjA==", + "dev": true, + "dependencies": { + "@jest/console": "^29.4.0", + "@jest/types": "^29.4.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.4.0.tgz", + "integrity": "sha512-pEwIgdfvEgF2lBOYX3DVn3SrvsAZ9FXCHw7+C6Qz87HnoDGQwbAselhWLhpgbxDjs6RC9QUJpFnrLmM5uwZV+g==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.4.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.4.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.4.0.tgz", + "integrity": "sha512-hDjw3jz4GnvbyLMgcFpC9/34QcUhVIzJkBqz7o+3AhgfhGRzGuQppuLf5r/q7lDAAyJ6jzL+SFG7JGsScHOcLQ==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.4.0", + "@jridgewell/trace-mapping": "^0.3.15", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.4.0", + "jest-regex-util": "^29.2.0", + "jest-util": "^29.4.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^5.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.0.tgz", + "integrity": "sha512-1S2Dt5uQp7R0bGY/L2BpuwCSji7v12kY3o8zqwlkbYBmOY956SKk+zOWqmfhHSINegiAVqOXydAYuWpzX6TYsQ==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.4.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "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/@sinclair/typebox": { + "version": "0.25.21", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.21.tgz", + "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==", + "dev": true + }, + "node_modules/@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz", + "integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^2.0.0" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.0.tgz", + "integrity": "sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz", + "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==", + "dev": true, + "dependencies": { + "@babel/types": "^7.3.0" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", + "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, + "node_modules/@types/node": { + "version": "18.11.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz", + "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==", + "dev": true + }, + "node_modules/@types/prettier": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", + "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==", + "dev": true + }, + "node_modules/@types/semver": { + "version": "7.3.13", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", + "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", + "dev": true + }, + "node_modules/@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, + "node_modules/@types/yargs": { + "version": "17.0.20", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.20.tgz", + "integrity": "sha512-eknWrTHofQuPk2iuqDm1waA7V6xPlbgBoaaXEgYkClhLOnB0TtbW+srJaOToAgawPxPlHQzwypFA2bhZaUGP5A==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", + "dev": true + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.49.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.49.0.tgz", + "integrity": "sha512-clpROBOiMIzpbWNxCe1xDK14uPZh35u4QaZO1GddilEzoCLAEz4szb51rBpdgurs5k2YzPtJeTEN3qVbG+LRUQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.49.0", + "@typescript-eslint/visitor-keys": "5.49.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.49.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.49.0.tgz", + "integrity": "sha512-7If46kusG+sSnEpu0yOz2xFv5nRz158nzEXnJFCGVEHWnuzolXKwrH5Bsf9zsNlOQkyZuk0BZKKoJQI+1JPBBg==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.49.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.49.0.tgz", + "integrity": "sha512-PBdx+V7deZT/3GjNYPVQv1Nc0U46dAHbIuOG8AZ3on3vuEKiPDwFE/lG1snN2eUB9IhF7EyF7K1hmTcLztNIsA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.49.0", + "@typescript-eslint/visitor-keys": "5.49.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "5.49.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.49.0.tgz", + "integrity": "sha512-cPJue/4Si25FViIb74sHCLtM4nTSBXtLx1d3/QT6mirQ/c65bV8arBEebBJJizfq8W2YyMoPI/WWPFWitmNqnQ==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.49.0", + "@typescript-eslint/types": "5.49.0", + "@typescript-eslint/typescript-estree": "5.49.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0", + "semver": "^7.3.7" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "5.49.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.49.0.tgz", + "integrity": "sha512-v9jBMjpNWyn8B6k/Mjt6VbUS4J1GvUlR4x3Y+ibnP1z7y7V4n0WRz+50DY6+Myj0UaXVSuUlHohO+eZ8IJEnkg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.49.0", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/acorn": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "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/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-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": "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/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/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/babel-jest": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.4.0.tgz", + "integrity": "sha512-M61cGPg4JBashDvIzKoIV/y95mSF6x3ome7CMEaszUTHD4uo6dtC6Nln+fvRTspYNtwy8lDHl5lmoTBSNY/a+g==", + "dev": true, + "dependencies": { + "@jest/transform": "^29.4.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.4.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.4.0.tgz", + "integrity": "sha512-a/sZRLQJEmsmejQ2rPEUe35nO1+C9dc9O1gplH1SXmJxveQSRUYdBk8yGZG/VOUuZs1u2aHZJusEGoRMbhhwCg==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.4.0.tgz", + "integrity": "sha512-fUB9vZflUSM3dO/6M2TCAepTzvA4VkOvl67PjErcrQMGt9Eve7uazaeyCZ2th3UtI7ljpiBJES0F7A1vBRsLZA==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^29.4.0", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "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/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.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.21.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.9" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "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/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": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001447", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001447.tgz", + "integrity": "sha512-bdKU1BQDPeEXe9A39xJnGtY0uRq/z5osrnXUw0TcK+EYno45Y+U7QU9HhHEyzvMDffpYadFXi3idnSNkcwLkTw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + } + ] + }, + "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/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.1.tgz", + "integrity": "sha512-4jYS4MOAaCIStSRwiuxc4B8MYhIe676yO1sYGzARnjXkWpmzZMMYxY6zu8WYWDhSuth5zhrQ1rhNSibyyvv4/w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", + "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", + "dev": true + }, + "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/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/collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", + "dev": true + }, + "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/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/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/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/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/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/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", + "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.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/diff-sequences": { + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.3.1.tgz", + "integrity": "sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "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/electron-to-chromium": { + "version": "1.4.284", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", + "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", + "dev": true + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "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/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "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": { + "version": "8.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.32.0.tgz", + "integrity": "sha512-nETVXpnthqKPFyuY2FNjz/bEd6nbosRgKbkgS/y1C7LJop96gYHWpiguLecMHQ2XCPxn77DS0P+68WzG6vkZSQ==", + "dev": true, + "dependencies": { + "@eslint/eslintrc": "^1.4.1", + "@humanwhocodes/config-array": "^0.11.8", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "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.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.4.0", + "esquery": "^1.4.0", + "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", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", + "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.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "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-google": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/eslint-config-google/-/eslint-config-google-0.14.0.tgz", + "integrity": "sha512-WsbX4WbjuMvTdeVL6+J3rK1RGhCTqjsFjX7UMSMgZiyxxaNLkoJENbrGExzERFeoTpGw3F3FypTiWAP9ZXzkEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + }, + "peerDependencies": { + "eslint": ">=5.16.0" + } + }, + "node_modules/eslint-plugin-jest": { + "version": "27.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.2.1.tgz", + "integrity": "sha512-l067Uxx7ZT8cO9NJuf+eJHvt6bqJyz2Z29wykyEdz/OtmcELQl2MQGQLX8J94O1cSJWAwUSEvCjwjA7KEK3Hmg==", + "dev": true, + "dependencies": { + "@typescript-eslint/utils": "^5.10.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^5.0.0", + "eslint": "^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "jest": { + "optional": true + } + } + }, + "node_modules/eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/espree": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", + "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", + "dev": true, + "dependencies": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "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/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/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/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.4.0.tgz", + "integrity": "sha512-pzaAwjBgLEVxBh6ZHiqb9Wv3JYuv6m8ntgtY7a48nS+2KbX0EJkPS3FQlKiTZNcqzqJHNyQsfjqN60w1hPUBfQ==", + "dev": true, + "dependencies": { + "@jest/expect-utils": "^29.4.0", + "jest-get-type": "^29.2.0", + "jest-matcher-utils": "^29.4.0", + "jest-message-util": "^29.4.0", + "jest-util": "^29.4.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "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-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "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-glob/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/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.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "dependencies": { + "bser": "2.1.1" + } + }, + "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.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "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-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true + }, + "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.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/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "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-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "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/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "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": "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/globals": { + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + }, + "node_modules/grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "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/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/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/ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "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/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "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/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "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/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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-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-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "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-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-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-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/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.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", + "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.4.0.tgz", + "integrity": "sha512-Zfd4UzNxPkSoHRBkg225rBjQNa6pVqbh20MGniAzwaOzYLd+pQUcAwH+WPxSXxKFs+QWYfPYIq9hIVSmdVQmPA==", + "dev": true, + "dependencies": { + "@jest/core": "^29.4.0", + "@jest/types": "^29.4.0", + "import-local": "^3.0.2", + "jest-cli": "^29.4.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.4.0.tgz", + "integrity": "sha512-rnI1oPxgFghoz32Y8eZsGJMjW54UlqT17ycQeCEktcxxwqqKdlj9afl8LNeO0Pbu+h2JQHThQP0BzS67eTRx4w==", + "dev": true, + "dependencies": { + "execa": "^5.0.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.4.0.tgz", + "integrity": "sha512-/pFBaCeLzCavRWyz14JwFgpZgPpEZdS6nPnREhczbHl2wy2UezvYcVp5akVFfUmBaA4ThAUp0I8cpgkbuNOm3g==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.4.0", + "@jest/expect": "^29.4.0", + "@jest/test-result": "^29.4.0", + "@jest/types": "^29.4.0", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.4.0", + "jest-matcher-utils": "^29.4.0", + "jest-message-util": "^29.4.0", + "jest-runtime": "^29.4.0", + "jest-snapshot": "^29.4.0", + "jest-util": "^29.4.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.4.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-cli": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.4.0.tgz", + "integrity": "sha512-YUkICcxjUd864VOzbfQEi2qd2hIIOd9bRF7LJUNyhWb3Khh3YKrbY0LWwoZZ4WkvukiNdvQu0Z4s6zLsY4hYfg==", + "dev": true, + "dependencies": { + "@jest/core": "^29.4.0", + "@jest/test-result": "^29.4.0", + "@jest/types": "^29.4.0", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^29.4.0", + "jest-util": "^29.4.0", + "jest-validate": "^29.4.0", + "prompts": "^2.0.1", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-config": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.4.0.tgz", + "integrity": "sha512-jtgd72nN4Mob4Oego3N/pLRVfR2ui1hv+yO6xR/SUi5G7NtZ/grr95BJ1qRSDYZshuA0Jw57fnttZHZKb04+CA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.4.0", + "@jest/types": "^29.4.0", + "babel-jest": "^29.4.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.4.0", + "jest-environment-node": "^29.4.0", + "jest-get-type": "^29.2.0", + "jest-regex-util": "^29.2.0", + "jest-resolve": "^29.4.0", + "jest-runner": "^29.4.0", + "jest-util": "^29.4.0", + "jest-validate": "^29.4.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.4.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-diff": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.4.0.tgz", + "integrity": "sha512-s8KNvFx8YgdQ4fn2YLDQ7N6kmVOP68dUDVJrCHNsTc3UM5jcmyyFeYKL8EPWBQbJ0o0VvDGbWp8oYQ1nsnqnWw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.3.1", + "jest-get-type": "^29.2.0", + "pretty-format": "^29.4.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-docblock": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.2.0.tgz", + "integrity": "sha512-bkxUsxTgWQGbXV5IENmfiIuqZhJcyvF7tU4zJ/7ioTutdz4ToB5Yx6JOFBpgI+TphRY4lhOyCWGNH/QFQh5T6A==", + "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.4.0.tgz", + "integrity": "sha512-LTOvB8JDVFjrwXItyQiyLuDYy5PMApGLLzbfIYR79QLpeohS0bcS6j2HjlWuRGSM8QQQyp+ico59Blv+Jx3fMw==", + "dev": true, + "dependencies": { + "@jest/types": "^29.4.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.2.0", + "jest-util": "^29.4.0", + "pretty-format": "^29.4.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-environment-node": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.4.0.tgz", + "integrity": "sha512-WVveE3fYSH6FhDtZdvXhFKeLsDRItlQgnij+HQv6ZKxTdT1DB5O0sHXKCEC3K5mHraMs1Kzn4ch9jXC7H4L4wA==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.4.0", + "@jest/fake-timers": "^29.4.0", + "@jest/types": "^29.4.0", + "@types/node": "*", + "jest-mock": "^29.4.0", + "jest-util": "^29.4.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz", + "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.4.0.tgz", + "integrity": "sha512-m/pIEfoK0HoJz4c9bkgS5F9CXN2AM22eaSmUcmqTpadRlNVBOJE2CwkgaUzbrNn5MuAqTV1IPVYwWwjHNnk8eA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.4.0", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.2.0", + "jest-util": "^29.4.0", + "jest-worker": "^29.4.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-leak-detector": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.4.0.tgz", + "integrity": "sha512-fEGHS6ijzgSv5exABkCecMHNmyHcV52+l39ZsxuwfxmQMp43KBWJn2/Fwg8/l4jTI9uOY9jv8z1dXGgL0PHFjA==", + "dev": true, + "dependencies": { + "jest-get-type": "^29.2.0", + "pretty-format": "^29.4.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.4.0.tgz", + "integrity": "sha512-pU4OjBn96rDdRIaPUImbPiO2ETyRVzkA1EZVu9AxBDv/XPDJ7JWfkb6IiDT5jwgicaPHMrB/fhVa6qjG6potfA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.4.0", + "jest-get-type": "^29.2.0", + "pretty-format": "^29.4.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.4.0.tgz", + "integrity": "sha512-0FvobqymmhE9pDEifvIcni9GeoKLol8eZspzH5u41g1wxYtLS60a9joT95dzzoCgrKRidNz64eaAXyzaULV8og==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.4.0", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.4.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-mock": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.4.0.tgz", + "integrity": "sha512-+ShT5i+hcu/OFQRV0f/V/YtwpdFcHg64JZ9A8b40JueP+X9HNrZAYGdkupGIzsUK8AucecxCt4wKauMchxubLQ==", + "dev": true, + "dependencies": { + "@jest/types": "^29.4.0", + "@types/node": "*", + "jest-util": "^29.4.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.2.0.tgz", + "integrity": "sha512-6yXn0kg2JXzH30cr2NlThF+70iuO/3irbaB4mh5WyqNIvLLP+B6sFdluO1/1RJmslyh/f9osnefECflHvTbwVA==", + "dev": true, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.4.0.tgz", + "integrity": "sha512-g7k7l53T+uC9Dp1mbHyDNkcCt0PMku6Wcfpr1kcMLwOHmM3vucKjSM5+DSa1r4vlDZojh8XH039J3z4FKmtTSw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.4.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.4.0", + "jest-validate": "^29.4.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.4.0.tgz", + "integrity": "sha512-hxfC84trREyULSj1Cm+fMjnudrrI2dVQ04COjZRcjCZ97boJlPtfJ+qrl/pN7YXS2fnu3wTHEc3LO094pngL6A==", + "dev": true, + "dependencies": { + "jest-regex-util": "^29.2.0", + "jest-snapshot": "^29.4.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.4.0.tgz", + "integrity": "sha512-4zpcv0NOiJleqT0NAs8YcVbK8MhVRc58CBBn9b0Exc8VPU9GKI+DbzDUZqJYdkJhJSZFy2862l/F6hAqIow1hg==", + "dev": true, + "dependencies": { + "@jest/console": "^29.4.0", + "@jest/environment": "^29.4.0", + "@jest/test-result": "^29.4.0", + "@jest/transform": "^29.4.0", + "@jest/types": "^29.4.0", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.2.0", + "jest-environment-node": "^29.4.0", + "jest-haste-map": "^29.4.0", + "jest-leak-detector": "^29.4.0", + "jest-message-util": "^29.4.0", + "jest-resolve": "^29.4.0", + "jest-runtime": "^29.4.0", + "jest-util": "^29.4.0", + "jest-watcher": "^29.4.0", + "jest-worker": "^29.4.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.4.0.tgz", + "integrity": "sha512-2zumwaGXsIuSF92Ui5Pn5hZV9r7AHMclfBLikrXSq87/lHea9anQ+mC+Cjz/DYTbf/JMjlK1sjZRh8K3yYNvWg==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.4.0", + "@jest/fake-timers": "^29.4.0", + "@jest/globals": "^29.4.0", + "@jest/source-map": "^29.2.0", + "@jest/test-result": "^29.4.0", + "@jest/transform": "^29.4.0", + "@jest/types": "^29.4.0", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.4.0", + "jest-message-util": "^29.4.0", + "jest-mock": "^29.4.0", + "jest-regex-util": "^29.2.0", + "jest-resolve": "^29.4.0", + "jest-snapshot": "^29.4.0", + "jest-util": "^29.4.0", + "semver": "^7.3.5", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.4.0.tgz", + "integrity": "sha512-UnK3MhdEWrQ2J6MnlKe51tvN5FjRUBQnO4m1LPlDx61or3w9+cP/U0x9eicutgunu/QzE4WC82jj6CiGIAFYzw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.4.0", + "@jest/transform": "^29.4.0", + "@jest/types": "^29.4.0", + "@types/babel__traverse": "^7.0.6", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.4.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.4.0", + "jest-get-type": "^29.2.0", + "jest-haste-map": "^29.4.0", + "jest-matcher-utils": "^29.4.0", + "jest-message-util": "^29.4.0", + "jest-util": "^29.4.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.4.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-util": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.4.0.tgz", + "integrity": "sha512-lCCwlze7UEV8TpR9ArS8w0cTbcMry5tlBkg7QSc5og5kNyV59dnY2aKHu5fY2k5aDJMQpCUGpvL2w6ZU44lveA==", + "dev": true, + "dependencies": { + "@jest/types": "^29.4.0", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.4.0.tgz", + "integrity": "sha512-EXS7u594nX3aAPBnARxBdJ1eZ1cByV6MWrK0Qpt9lt/BcY0p0yYGp/EGJ8GhdLDQh+RFf8qMt2wzbbVzpj5+Vg==", + "dev": true, + "dependencies": { + "@jest/types": "^29.4.0", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.2.0", + "leven": "^3.1.0", + "pretty-format": "^29.4.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/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/jest-watcher": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.4.0.tgz", + "integrity": "sha512-PnnfLygNKelWOJwpAYlcsQjB+OxRRdckD0qiGmYng4Hkz1ZwK3jvCaJJYiywz2msQn4rBNLdriasJtv7YpWHpA==", + "dev": true, + "dependencies": { + "@jest/test-result": "^29.4.0", + "@jest/types": "^29.4.0", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.4.0", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.4.0.tgz", + "integrity": "sha512-dICMQ+Q4W0QVMsaQzWlA1FVQhKNz7QcDCOGtbk1GCAd0Lai+wdkQvfmQwL4MjGumineh1xz+6M5oMj3rfWS02A==", + "dev": true, + "dependencies": { + "@types/node": "*", + "jest-util": "^29.4.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/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/js-sdsl": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", + "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, + "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/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "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": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "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/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "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.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/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "dependencies": { + "tmpl": "1.0.5" + } + }, + "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.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.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/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/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/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/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz", + "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==", + "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/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/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/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "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.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "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-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "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/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "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/pirates": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", + "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "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/pretty-format": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.4.0.tgz", + "integrity": "sha512-J+EVUPXIBHCdWAbvGBwXs0mk3ljGppoh/076g1S8qYS8nVG4u/yrhMvyTFHYYYKWnDdgRLExx0vA7pzxVGdlNw==", + "dev": true, + "dependencies": { + "@jest/schemas": "^29.4.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "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/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "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/resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.9.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-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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.exports": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.0.tgz", + "integrity": "sha512-6K/gDlqgQscOlg9fSRpWstA8sYe8rbELsSTNpx+3kTrsVCzvSl0zIvRErM7fdl9ERWDsKnrLnwB+Ne89918XOg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "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/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "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/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "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/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/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "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/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/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "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/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": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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": "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/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/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "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/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "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/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" + } + }, + "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.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "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/typescript": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", + "dev": true, + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist-lint": "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/v8-to-istanbul": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", + "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/v8-to-istanbul/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "dependencies": { + "makeerror": "1.0.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/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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/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/write-file-atomic": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.0.tgz", + "integrity": "sha512-R7NYMnHSlV42K54lwY9lvW6MnSm1HSJqZL3xiSgi9E7//FYaI74r2G0rd+/X6VAMkHEdzxQaU5HUOXWUz5kA/w==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "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/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "node_modules/yargs": { + "version": "17.6.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", + "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", + "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/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/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" + } + } + }, + "dependencies": { + "@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "dev": true, + "requires": { + "@babel/highlight": "^7.18.6" + } + }, + "@babel/compat-data": { + "version": "7.20.10", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.10.tgz", + "integrity": "sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg==", + "dev": true + }, + "@babel/core": { + "version": "7.20.12", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.12.tgz", + "integrity": "sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg==", + "dev": true, + "requires": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.7", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-module-transforms": "^7.20.11", + "@babel/helpers": "^7.20.7", + "@babel/parser": "^7.20.7", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.12", + "@babel/types": "^7.20.7", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.2", + "semver": "^6.3.0" + }, + "dependencies": { + "convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.7.tgz", + "integrity": "sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==", + "dev": true, + "requires": { + "@babel/types": "^7.20.7", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" + }, + "dependencies": { + "@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + } + } + }, + "@babel/helper-compilation-targets": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", + "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.20.5", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "@babel/helper-environment-visitor": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", + "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "dev": true + }, + "@babel/helper-function-name": { + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", + "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "dev": true, + "requires": { + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", + "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-module-imports": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", + "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-module-transforms": { + "version": "7.20.11", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz", + "integrity": "sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.10", + "@babel/types": "^7.20.7" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", + "dev": true + }, + "@babel/helper-simple-access": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", + "dev": true, + "requires": { + "@babel/types": "^7.20.2" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", + "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "dev": true, + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "dev": true + }, + "@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", + "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "dev": true + }, + "@babel/helpers": { + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.13.tgz", + "integrity": "sha512-nzJ0DWCL3gB5RCXbUO3KIMMsBY2Eqbx8mBpKGE/02PgyRQFcPQLbkQ1vyy596mZLaP+dAfD+R4ckASzNVmW3jg==", + "dev": true, + "requires": { + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.13", + "@babel/types": "^7.20.7" + } + }, + "@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "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, + "requires": { + "color-convert": "^1.9.0" + } + }, + "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, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "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, + "requires": { + "color-name": "1.1.3" + } + }, + "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 + }, + "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 + }, + "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 + }, + "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, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/parser": { + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.13.tgz", + "integrity": "sha512-gFDLKMfpiXCsjt4za2JA9oTMn70CeseCehb11kRZgvd7+F67Hih3OHOK24cRrWECJ/ljfPGac6ygXAs/C8kIvw==", + "dev": true + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-jsx": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", + "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.18.6" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-typescript": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", + "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.19.0" + } + }, + "@babel/template": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" + } + }, + "@babel/traverse": { + "version": "7.20.13", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.13.tgz", + "integrity": "sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.7", + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-function-name": "^7.19.0", + "@babel/helper-hoist-variables": "^7.18.6", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/parser": "^7.20.13", + "@babel/types": "^7.20.7", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "dependencies": { + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", + "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", + "dev": true, + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + } + }, + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "@eslint/eslintrc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", + "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.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" + } + }, + "@humanwhocodes/config-array": { + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "dev": true, + "requires": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + } + }, + "@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 + }, + "@humanwhocodes/object-schema": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", + "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", + "dev": true + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "dependencies": { + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } + } + }, + "@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true + }, + "@jest/console": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.4.0.tgz", + "integrity": "sha512-xpXud7e/8zo4syxQlAMDz+EQiFsf8/zXDPslBYm+UaSJ5uGTKQHhbSHfECp7Fw1trQtopjYumeved0n3waijhQ==", + "dev": true, + "requires": { + "@jest/types": "^29.4.0", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.4.0", + "jest-util": "^29.4.0", + "slash": "^3.0.0" + } + }, + "@jest/core": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.4.0.tgz", + "integrity": "sha512-E7oCMcENobBFwQXYjnN2IsuUSpRo5jSv7VYk6O9GyQ5kVAfVSS8819I4W5iCCYvqD6+1TzyzLpeEdZEik81kNw==", + "dev": true, + "requires": { + "@jest/console": "^29.4.0", + "@jest/reporters": "^29.4.0", + "@jest/test-result": "^29.4.0", + "@jest/transform": "^29.4.0", + "@jest/types": "^29.4.0", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.4.0", + "jest-config": "^29.4.0", + "jest-haste-map": "^29.4.0", + "jest-message-util": "^29.4.0", + "jest-regex-util": "^29.2.0", + "jest-resolve": "^29.4.0", + "jest-resolve-dependencies": "^29.4.0", + "jest-runner": "^29.4.0", + "jest-runtime": "^29.4.0", + "jest-snapshot": "^29.4.0", + "jest-util": "^29.4.0", + "jest-validate": "^29.4.0", + "jest-watcher": "^29.4.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.4.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "@jest/environment": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.4.0.tgz", + "integrity": "sha512-ocl1VGDcZHfHnYLTqkBY7yXme1bF4x0BevJ9wb6y0sLOSyBCpp8L5fEASChB+wU53WMrIK6kBfGt+ZYoM2kcdw==", + "dev": true, + "requires": { + "@jest/fake-timers": "^29.4.0", + "@jest/types": "^29.4.0", + "@types/node": "*", + "jest-mock": "^29.4.0" + } + }, + "@jest/expect": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.4.0.tgz", + "integrity": "sha512-IiDZYQ/Oi94aBT0nKKKRvNsB5JTyHoGb+G3SiGoDxz90JfL7SLx/z5IjB0fzBRzy7aLFQOCbVJlaC2fIgU6Y9Q==", + "dev": true, + "requires": { + "expect": "^29.4.0", + "jest-snapshot": "^29.4.0" + } + }, + "@jest/expect-utils": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.4.0.tgz", + "integrity": "sha512-w/JzTYIqjmPFIM5OOQHF9CawFx2daw1256Nzj4ZqWX96qRKbCq9WYRVqdySBKHHzuvsXLyTDIF6y61FUyrhmwg==", + "dev": true, + "requires": { + "jest-get-type": "^29.2.0" + } + }, + "@jest/fake-timers": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.4.0.tgz", + "integrity": "sha512-8sitzN2QrhDwEwH3kKcMMgrv/UIkmm9AUgHixmn4L++GQ0CqVTIztm3YmaIQooLmW3O4GhizNTTCyq3iLbWcMw==", + "dev": true, + "requires": { + "@jest/types": "^29.4.0", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.4.0", + "jest-mock": "^29.4.0", + "jest-util": "^29.4.0" + } + }, + "@jest/globals": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.4.0.tgz", + "integrity": "sha512-Q64ZRgGMVL40RcYTfD2GvyjK7vJLPSIvi8Yp3usGPNPQ3SCW+UCY9KEH6+sVtBo8LzhcjtCXuZEd7avnj/T0mQ==", + "dev": true, + "requires": { + "@jest/environment": "^29.4.0", + "@jest/expect": "^29.4.0", + "@jest/types": "^29.4.0", + "jest-mock": "^29.4.0" + } + }, + "@jest/reporters": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.4.0.tgz", + "integrity": "sha512-FjJwrD1XOQq/AXKrvnOSf0RgAs6ziUuGKx8+/R53Jscc629JIhg7/m241gf1shUm/fKKxoHd7aCexcg7kxvkWQ==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.4.0", + "@jest/test-result": "^29.4.0", + "@jest/transform": "^29.4.0", + "@jest/types": "^29.4.0", + "@jridgewell/trace-mapping": "^0.3.15", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.4.0", + "jest-util": "^29.4.0", + "jest-worker": "^29.4.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + } + }, + "@jest/schemas": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.0.tgz", + "integrity": "sha512-0E01f/gOZeNTG76i5eWWSupvSHaIINrTie7vCyjiYFKgzNdyEGd12BUv4oNBFHOqlHDbtoJi3HrQ38KCC90NsQ==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.25.16" + } + }, + "@jest/source-map": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.2.0.tgz", + "integrity": "sha512-1NX9/7zzI0nqa6+kgpSdKPK+WU1p+SJk3TloWZf5MzPbxri9UEeXX5bWZAPCzbQcyuAzubcdUHA7hcNznmRqWQ==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.15", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + } + }, + "@jest/test-result": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.4.0.tgz", + "integrity": "sha512-EtRklzjpddZU/aBVxJqqejfzfOcnehmjNXufs6u6qwd05kkhXpAPhZdt8bLlQd7cA2nD+JqZQ5Dx9NX5Jh6mjA==", + "dev": true, + "requires": { + "@jest/console": "^29.4.0", + "@jest/types": "^29.4.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/test-sequencer": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.4.0.tgz", + "integrity": "sha512-pEwIgdfvEgF2lBOYX3DVn3SrvsAZ9FXCHw7+C6Qz87HnoDGQwbAselhWLhpgbxDjs6RC9QUJpFnrLmM5uwZV+g==", + "dev": true, + "requires": { + "@jest/test-result": "^29.4.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.4.0", + "slash": "^3.0.0" + } + }, + "@jest/transform": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.4.0.tgz", + "integrity": "sha512-hDjw3jz4GnvbyLMgcFpC9/34QcUhVIzJkBqz7o+3AhgfhGRzGuQppuLf5r/q7lDAAyJ6jzL+SFG7JGsScHOcLQ==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.4.0", + "@jridgewell/trace-mapping": "^0.3.15", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.4.0", + "jest-regex-util": "^29.2.0", + "jest-util": "^29.4.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^5.0.0" + } + }, + "@jest/types": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.4.0.tgz", + "integrity": "sha512-1S2Dt5uQp7R0bGY/L2BpuwCSji7v12kY3o8zqwlkbYBmOY956SKk+zOWqmfhHSINegiAVqOXydAYuWpzX6TYsQ==", + "dev": true, + "requires": { + "@jest/schemas": "^29.4.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + } + }, + "@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", + "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "dev": true + }, + "@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.14", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", + "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "@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, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@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 + }, + "@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, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@sinclair/typebox": { + "version": "0.25.21", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.21.tgz", + "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==", + "dev": true + }, + "@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz", + "integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^2.0.0" + } + }, + "@types/babel__core": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.0.tgz", + "integrity": "sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==", + "dev": true, + "requires": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@types/babel__generator": { + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz", + "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==", + "dev": true, + "requires": { + "@babel/types": "^7.3.0" + } + }, + "@types/graceful-fs": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", + "integrity": "sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", + "dev": true + }, + "@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*" + } + }, + "@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/json-schema": { + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "dev": true + }, + "@types/node": { + "version": "18.11.18", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.11.18.tgz", + "integrity": "sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA==", + "dev": true + }, + "@types/prettier": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", + "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==", + "dev": true + }, + "@types/semver": { + "version": "7.3.13", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", + "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", + "dev": true + }, + "@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, + "@types/yargs": { + "version": "17.0.20", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.20.tgz", + "integrity": "sha512-eknWrTHofQuPk2iuqDm1waA7V6xPlbgBoaaXEgYkClhLOnB0TtbW+srJaOToAgawPxPlHQzwypFA2bhZaUGP5A==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", + "dev": true + }, + "@typescript-eslint/scope-manager": { + "version": "5.49.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.49.0.tgz", + "integrity": "sha512-clpROBOiMIzpbWNxCe1xDK14uPZh35u4QaZO1GddilEzoCLAEz4szb51rBpdgurs5k2YzPtJeTEN3qVbG+LRUQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.49.0", + "@typescript-eslint/visitor-keys": "5.49.0" + } + }, + "@typescript-eslint/types": { + "version": "5.49.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.49.0.tgz", + "integrity": "sha512-7If46kusG+sSnEpu0yOz2xFv5nRz158nzEXnJFCGVEHWnuzolXKwrH5Bsf9zsNlOQkyZuk0BZKKoJQI+1JPBBg==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.49.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.49.0.tgz", + "integrity": "sha512-PBdx+V7deZT/3GjNYPVQv1Nc0U46dAHbIuOG8AZ3on3vuEKiPDwFE/lG1snN2eUB9IhF7EyF7K1hmTcLztNIsA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.49.0", + "@typescript-eslint/visitor-keys": "5.49.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/utils": { + "version": "5.49.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.49.0.tgz", + "integrity": "sha512-cPJue/4Si25FViIb74sHCLtM4nTSBXtLx1d3/QT6mirQ/c65bV8arBEebBJJizfq8W2YyMoPI/WWPFWitmNqnQ==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.49.0", + "@typescript-eslint/types": "5.49.0", + "@typescript-eslint/typescript-estree": "5.49.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0", + "semver": "^7.3.7" + }, + "dependencies": { + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + } + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.49.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.49.0.tgz", + "integrity": "sha512-v9jBMjpNWyn8B6k/Mjt6VbUS4J1GvUlR4x3Y+ibnP1z7y7V4n0WRz+50DY6+Myj0UaXVSuUlHohO+eZ8IJEnkg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.49.0", + "eslint-visitor-keys": "^3.3.0" + } + }, + "acorn": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "dev": true + }, + "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, + "requires": {} + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "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, + "requires": { + "type-fest": "^0.21.3" + }, + "dependencies": { + "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 + } + } + }, + "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 + }, + "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, + "requires": { + "color-convert": "^2.0.1" + } + }, + "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, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "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 + }, + "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 + }, + "babel-jest": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.4.0.tgz", + "integrity": "sha512-M61cGPg4JBashDvIzKoIV/y95mSF6x3ome7CMEaszUTHD4uo6dtC6Nln+fvRTspYNtwy8lDHl5lmoTBSNY/a+g==", + "dev": true, + "requires": { + "@jest/transform": "^29.4.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.4.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + } + }, + "babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.4.0.tgz", + "integrity": "sha512-a/sZRLQJEmsmejQ2rPEUe35nO1+C9dc9O1gplH1SXmJxveQSRUYdBk8yGZG/VOUuZs1u2aHZJusEGoRMbhhwCg==", + "dev": true, + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "requires": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + } + }, + "babel-preset-jest": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.4.0.tgz", + "integrity": "sha512-fUB9vZflUSM3dO/6M2TCAepTzvA4VkOvl67PjErcrQMGt9Eve7uazaeyCZ2th3UtI7ljpiBJES0F7A1vBRsLZA==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^29.4.0", + "babel-preset-current-node-syntax": "^1.0.0" + } + }, + "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 + }, + "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, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browserslist": { + "version": "4.21.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.9" + } + }, + "bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "requires": { + "node-int64": "^0.4.0" + } + }, + "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 + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001447", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001447.tgz", + "integrity": "sha512-bdKU1BQDPeEXe9A39xJnGtY0uRq/z5osrnXUw0TcK+EYno45Y+U7QU9HhHEyzvMDffpYadFXi3idnSNkcwLkTw==", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true + }, + "ci-info": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.1.tgz", + "integrity": "sha512-4jYS4MOAaCIStSRwiuxc4B8MYhIe676yO1sYGzARnjXkWpmzZMMYxY6zu8WYWDhSuth5zhrQ1rhNSibyyvv4/w==", + "dev": true + }, + "cjs-module-lexer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", + "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", + "dev": true + }, + "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, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true + }, + "collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", + "dev": true + }, + "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, + "requires": { + "color-name": "~1.1.4" + } + }, + "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 + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "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 + }, + "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, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", + "dev": true + }, + "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 + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true + }, + "detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true + }, + "diff-sequences": { + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.3.1.tgz", + "integrity": "sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ==", + "dev": true + }, + "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, + "requires": { + "path-type": "^4.0.0" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "electron-to-chromium": { + "version": "1.4.284", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", + "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", + "dev": true + }, + "emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true + }, + "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 + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "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 + }, + "eslint": { + "version": "8.32.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.32.0.tgz", + "integrity": "sha512-nETVXpnthqKPFyuY2FNjz/bEd6nbosRgKbkgS/y1C7LJop96gYHWpiguLecMHQ2XCPxn77DS0P+68WzG6vkZSQ==", + "dev": true, + "requires": { + "@eslint/eslintrc": "^1.4.1", + "@humanwhocodes/config-array": "^0.11.8", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "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.1.1", + "eslint-utils": "^3.0.0", + "eslint-visitor-keys": "^3.3.0", + "espree": "^9.4.0", + "esquery": "^1.4.0", + "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", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", + "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.1", + "regexpp": "^3.2.0", + "strip-ansi": "^6.0.1", + "strip-json-comments": "^3.1.0", + "text-table": "^0.2.0" + } + }, + "eslint-config-google": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/eslint-config-google/-/eslint-config-google-0.14.0.tgz", + "integrity": "sha512-WsbX4WbjuMvTdeVL6+J3rK1RGhCTqjsFjX7UMSMgZiyxxaNLkoJENbrGExzERFeoTpGw3F3FypTiWAP9ZXzkEw==", + "dev": true, + "requires": {} + }, + "eslint-plugin-jest": { + "version": "27.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.2.1.tgz", + "integrity": "sha512-l067Uxx7ZT8cO9NJuf+eJHvt6bqJyz2Z29wykyEdz/OtmcELQl2MQGQLX8J94O1cSJWAwUSEvCjwjA7KEK3Hmg==", + "dev": true, + "requires": { + "@typescript-eslint/utils": "^5.10.0" + } + }, + "eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + }, + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^2.0.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true + }, + "espree": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", + "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", + "dev": true, + "requires": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + } + }, + "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, + "requires": { + "estraverse": "^5.2.0" + } + }, + "estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "requires": { + "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" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true + }, + "expect": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.4.0.tgz", + "integrity": "sha512-pzaAwjBgLEVxBh6ZHiqb9Wv3JYuv6m8ntgtY7a48nS+2KbX0EJkPS3FQlKiTZNcqzqJHNyQsfjqN60w1hPUBfQ==", + "dev": true, + "requires": { + "@jest/expect-utils": "^29.4.0", + "jest-get-type": "^29.2.0", + "jest-matcher-utils": "^29.4.0", + "jest-message-util": "^29.4.0", + "jest-util": "^29.4.0" + } + }, + "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 + }, + "fast-glob": { + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dev": true, + "requires": { + "@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" + }, + "dependencies": { + "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, + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, + "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 + }, + "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 + }, + "fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "requires": { + "bser": "2.1.1" + } + }, + "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, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "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, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", + "dev": true + }, + "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 + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true + }, + "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 + }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true + }, + "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 + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "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" + } + }, + "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, + "requires": { + "is-glob": "^4.0.3" + } + }, + "globals": { + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "requires": { + "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" + } + }, + "graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + }, + "grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "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 + }, + "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 + }, + "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 + }, + "ignore": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "dev": true + }, + "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, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "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 + }, + "is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true + }, + "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, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "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 + }, + "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 + }, + "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 + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "requires": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + } + }, + "istanbul-reports": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", + "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jest": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.4.0.tgz", + "integrity": "sha512-Zfd4UzNxPkSoHRBkg225rBjQNa6pVqbh20MGniAzwaOzYLd+pQUcAwH+WPxSXxKFs+QWYfPYIq9hIVSmdVQmPA==", + "dev": true, + "requires": { + "@jest/core": "^29.4.0", + "@jest/types": "^29.4.0", + "import-local": "^3.0.2", + "jest-cli": "^29.4.0" + } + }, + "jest-changed-files": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.4.0.tgz", + "integrity": "sha512-rnI1oPxgFghoz32Y8eZsGJMjW54UlqT17ycQeCEktcxxwqqKdlj9afl8LNeO0Pbu+h2JQHThQP0BzS67eTRx4w==", + "dev": true, + "requires": { + "execa": "^5.0.0", + "p-limit": "^3.1.0" + } + }, + "jest-circus": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.4.0.tgz", + "integrity": "sha512-/pFBaCeLzCavRWyz14JwFgpZgPpEZdS6nPnREhczbHl2wy2UezvYcVp5akVFfUmBaA4ThAUp0I8cpgkbuNOm3g==", + "dev": true, + "requires": { + "@jest/environment": "^29.4.0", + "@jest/expect": "^29.4.0", + "@jest/test-result": "^29.4.0", + "@jest/types": "^29.4.0", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.4.0", + "jest-matcher-utils": "^29.4.0", + "jest-message-util": "^29.4.0", + "jest-runtime": "^29.4.0", + "jest-snapshot": "^29.4.0", + "jest-util": "^29.4.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.4.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + } + }, + "jest-cli": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.4.0.tgz", + "integrity": "sha512-YUkICcxjUd864VOzbfQEi2qd2hIIOd9bRF7LJUNyhWb3Khh3YKrbY0LWwoZZ4WkvukiNdvQu0Z4s6zLsY4hYfg==", + "dev": true, + "requires": { + "@jest/core": "^29.4.0", + "@jest/test-result": "^29.4.0", + "@jest/types": "^29.4.0", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^29.4.0", + "jest-util": "^29.4.0", + "jest-validate": "^29.4.0", + "prompts": "^2.0.1", + "yargs": "^17.3.1" + } + }, + "jest-config": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.4.0.tgz", + "integrity": "sha512-jtgd72nN4Mob4Oego3N/pLRVfR2ui1hv+yO6xR/SUi5G7NtZ/grr95BJ1qRSDYZshuA0Jw57fnttZHZKb04+CA==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.4.0", + "@jest/types": "^29.4.0", + "babel-jest": "^29.4.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.4.0", + "jest-environment-node": "^29.4.0", + "jest-get-type": "^29.2.0", + "jest-regex-util": "^29.2.0", + "jest-resolve": "^29.4.0", + "jest-runner": "^29.4.0", + "jest-util": "^29.4.0", + "jest-validate": "^29.4.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.4.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + } + }, + "jest-diff": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.4.0.tgz", + "integrity": "sha512-s8KNvFx8YgdQ4fn2YLDQ7N6kmVOP68dUDVJrCHNsTc3UM5jcmyyFeYKL8EPWBQbJ0o0VvDGbWp8oYQ1nsnqnWw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^29.3.1", + "jest-get-type": "^29.2.0", + "pretty-format": "^29.4.0" + } + }, + "jest-docblock": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.2.0.tgz", + "integrity": "sha512-bkxUsxTgWQGbXV5IENmfiIuqZhJcyvF7tU4zJ/7ioTutdz4ToB5Yx6JOFBpgI+TphRY4lhOyCWGNH/QFQh5T6A==", + "dev": true, + "requires": { + "detect-newline": "^3.0.0" + } + }, + "jest-each": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.4.0.tgz", + "integrity": "sha512-LTOvB8JDVFjrwXItyQiyLuDYy5PMApGLLzbfIYR79QLpeohS0bcS6j2HjlWuRGSM8QQQyp+ico59Blv+Jx3fMw==", + "dev": true, + "requires": { + "@jest/types": "^29.4.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.2.0", + "jest-util": "^29.4.0", + "pretty-format": "^29.4.0" + } + }, + "jest-environment-node": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.4.0.tgz", + "integrity": "sha512-WVveE3fYSH6FhDtZdvXhFKeLsDRItlQgnij+HQv6ZKxTdT1DB5O0sHXKCEC3K5mHraMs1Kzn4ch9jXC7H4L4wA==", + "dev": true, + "requires": { + "@jest/environment": "^29.4.0", + "@jest/fake-timers": "^29.4.0", + "@jest/types": "^29.4.0", + "@types/node": "*", + "jest-mock": "^29.4.0", + "jest-util": "^29.4.0" + } + }, + "jest-get-type": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz", + "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==", + "dev": true + }, + "jest-haste-map": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.4.0.tgz", + "integrity": "sha512-m/pIEfoK0HoJz4c9bkgS5F9CXN2AM22eaSmUcmqTpadRlNVBOJE2CwkgaUzbrNn5MuAqTV1IPVYwWwjHNnk8eA==", + "dev": true, + "requires": { + "@jest/types": "^29.4.0", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.3.2", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.2.0", + "jest-util": "^29.4.0", + "jest-worker": "^29.4.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + } + }, + "jest-leak-detector": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.4.0.tgz", + "integrity": "sha512-fEGHS6ijzgSv5exABkCecMHNmyHcV52+l39ZsxuwfxmQMp43KBWJn2/Fwg8/l4jTI9uOY9jv8z1dXGgL0PHFjA==", + "dev": true, + "requires": { + "jest-get-type": "^29.2.0", + "pretty-format": "^29.4.0" + } + }, + "jest-matcher-utils": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.4.0.tgz", + "integrity": "sha512-pU4OjBn96rDdRIaPUImbPiO2ETyRVzkA1EZVu9AxBDv/XPDJ7JWfkb6IiDT5jwgicaPHMrB/fhVa6qjG6potfA==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^29.4.0", + "jest-get-type": "^29.2.0", + "pretty-format": "^29.4.0" + } + }, + "jest-message-util": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.4.0.tgz", + "integrity": "sha512-0FvobqymmhE9pDEifvIcni9GeoKLol8eZspzH5u41g1wxYtLS60a9joT95dzzoCgrKRidNz64eaAXyzaULV8og==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.4.0", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.4.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + } + }, + "jest-mock": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.4.0.tgz", + "integrity": "sha512-+ShT5i+hcu/OFQRV0f/V/YtwpdFcHg64JZ9A8b40JueP+X9HNrZAYGdkupGIzsUK8AucecxCt4wKauMchxubLQ==", + "dev": true, + "requires": { + "@jest/types": "^29.4.0", + "@types/node": "*", + "jest-util": "^29.4.0" + } + }, + "jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "requires": {} + }, + "jest-regex-util": { + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.2.0.tgz", + "integrity": "sha512-6yXn0kg2JXzH30cr2NlThF+70iuO/3irbaB4mh5WyqNIvLLP+B6sFdluO1/1RJmslyh/f9osnefECflHvTbwVA==", + "dev": true + }, + "jest-resolve": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.4.0.tgz", + "integrity": "sha512-g7k7l53T+uC9Dp1mbHyDNkcCt0PMku6Wcfpr1kcMLwOHmM3vucKjSM5+DSa1r4vlDZojh8XH039J3z4FKmtTSw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.4.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.4.0", + "jest-validate": "^29.4.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + } + }, + "jest-resolve-dependencies": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.4.0.tgz", + "integrity": "sha512-hxfC84trREyULSj1Cm+fMjnudrrI2dVQ04COjZRcjCZ97boJlPtfJ+qrl/pN7YXS2fnu3wTHEc3LO094pngL6A==", + "dev": true, + "requires": { + "jest-regex-util": "^29.2.0", + "jest-snapshot": "^29.4.0" + } + }, + "jest-runner": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.4.0.tgz", + "integrity": "sha512-4zpcv0NOiJleqT0NAs8YcVbK8MhVRc58CBBn9b0Exc8VPU9GKI+DbzDUZqJYdkJhJSZFy2862l/F6hAqIow1hg==", + "dev": true, + "requires": { + "@jest/console": "^29.4.0", + "@jest/environment": "^29.4.0", + "@jest/test-result": "^29.4.0", + "@jest/transform": "^29.4.0", + "@jest/types": "^29.4.0", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.2.0", + "jest-environment-node": "^29.4.0", + "jest-haste-map": "^29.4.0", + "jest-leak-detector": "^29.4.0", + "jest-message-util": "^29.4.0", + "jest-resolve": "^29.4.0", + "jest-runtime": "^29.4.0", + "jest-util": "^29.4.0", + "jest-watcher": "^29.4.0", + "jest-worker": "^29.4.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + } + }, + "jest-runtime": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.4.0.tgz", + "integrity": "sha512-2zumwaGXsIuSF92Ui5Pn5hZV9r7AHMclfBLikrXSq87/lHea9anQ+mC+Cjz/DYTbf/JMjlK1sjZRh8K3yYNvWg==", + "dev": true, + "requires": { + "@jest/environment": "^29.4.0", + "@jest/fake-timers": "^29.4.0", + "@jest/globals": "^29.4.0", + "@jest/source-map": "^29.2.0", + "@jest/test-result": "^29.4.0", + "@jest/transform": "^29.4.0", + "@jest/types": "^29.4.0", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.4.0", + "jest-message-util": "^29.4.0", + "jest-mock": "^29.4.0", + "jest-regex-util": "^29.2.0", + "jest-resolve": "^29.4.0", + "jest-snapshot": "^29.4.0", + "jest-util": "^29.4.0", + "semver": "^7.3.5", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + } + }, + "jest-snapshot": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.4.0.tgz", + "integrity": "sha512-UnK3MhdEWrQ2J6MnlKe51tvN5FjRUBQnO4m1LPlDx61or3w9+cP/U0x9eicutgunu/QzE4WC82jj6CiGIAFYzw==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.4.0", + "@jest/transform": "^29.4.0", + "@jest/types": "^29.4.0", + "@types/babel__traverse": "^7.0.6", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.4.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.4.0", + "jest-get-type": "^29.2.0", + "jest-haste-map": "^29.4.0", + "jest-matcher-utils": "^29.4.0", + "jest-message-util": "^29.4.0", + "jest-util": "^29.4.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.4.0", + "semver": "^7.3.5" + } + }, + "jest-util": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.4.0.tgz", + "integrity": "sha512-lCCwlze7UEV8TpR9ArS8w0cTbcMry5tlBkg7QSc5og5kNyV59dnY2aKHu5fY2k5aDJMQpCUGpvL2w6ZU44lveA==", + "dev": true, + "requires": { + "@jest/types": "^29.4.0", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + } + }, + "jest-validate": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.4.0.tgz", + "integrity": "sha512-EXS7u594nX3aAPBnARxBdJ1eZ1cByV6MWrK0Qpt9lt/BcY0p0yYGp/EGJ8GhdLDQh+RFf8qMt2wzbbVzpj5+Vg==", + "dev": true, + "requires": { + "@jest/types": "^29.4.0", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.2.0", + "leven": "^3.1.0", + "pretty-format": "^29.4.0" + }, + "dependencies": { + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true + } + } + }, + "jest-watcher": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.4.0.tgz", + "integrity": "sha512-PnnfLygNKelWOJwpAYlcsQjB+OxRRdckD0qiGmYng4Hkz1ZwK3jvCaJJYiywz2msQn4rBNLdriasJtv7YpWHpA==", + "dev": true, + "requires": { + "@jest/test-result": "^29.4.0", + "@jest/types": "^29.4.0", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.4.0", + "string-length": "^4.0.1" + } + }, + "jest-worker": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.4.0.tgz", + "integrity": "sha512-dICMQ+Q4W0QVMsaQzWlA1FVQhKNz7QcDCOGtbk1GCAd0Lai+wdkQvfmQwL4MjGumineh1xz+6M5oMj3rfWS02A==", + "dev": true, + "requires": { + "@types/node": "*", + "jest-util": "^29.4.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "dependencies": { + "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, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "js-sdsl": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", + "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==", + "dev": true + }, + "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 + }, + "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, + "requires": { + "argparse": "^2.0.1" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "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 + }, + "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 + }, + "json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true + }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true + }, + "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, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "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, + "requires": { + "p-locate": "^5.0.0" + } + }, + "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 + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "requires": { + "tmpl": "1.0.5" + } + }, + "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 + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "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 + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "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 + }, + "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-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true + }, + "node-releases": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz", + "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==", + "dev": true + }, + "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 + }, + "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, + "requires": { + "path-key": "^3.0.0" + } + }, + "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, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "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.3" + } + }, + "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, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "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, + "requires": { + "p-limit": "^3.0.2" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "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, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "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 + }, + "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 + }, + "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 + }, + "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 + }, + "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 + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "pirates": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", + "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + } + } + }, + "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 + }, + "pretty-format": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.4.0.tgz", + "integrity": "sha512-J+EVUPXIBHCdWAbvGBwXs0mk3ljGppoh/076g1S8qYS8nVG4u/yrhMvyTFHYYYKWnDdgRLExx0vA7pzxVGdlNw==", + "dev": true, + "requires": { + "@jest/schemas": "^29.4.0", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + } + } + }, + "prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + } + }, + "punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "dev": true + }, + "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 + }, + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "dev": true + }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true + }, + "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 + }, + "resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "requires": { + "resolve-from": "^5.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } + } + }, + "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 + }, + "resolve.exports": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.0.tgz", + "integrity": "sha512-6K/gDlqgQscOlg9fSRpWstA8sYe8rbELsSTNpx+3kTrsVCzvSl0zIvRErM7fdl9ERWDsKnrLnwB+Ne89918XOg==", + "dev": true + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "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, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } + } + }, + "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, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "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 + }, + "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 + }, + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "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 + }, + "source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + } + } + }, + "string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "requires": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + } + }, + "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, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "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, + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + }, + "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 + }, + "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 + }, + "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, + "requires": { + "has-flag": "^4.0.0" + } + }, + "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 + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, + "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 + }, + "tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "dev": true + }, + "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, + "requires": { + "is-number": "^7.0.0" + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "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, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "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 + }, + "typescript": { + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", + "dev": true, + "peer": true + }, + "update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "dev": true, + "requires": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "v8-to-istanbul": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", + "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0" + }, + "dependencies": { + "convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + } + } + }, + "walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "requires": { + "makeerror": "1.0.12" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "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, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "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 + }, + "write-file-atomic": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.0.tgz", + "integrity": "sha512-R7NYMnHSlV42K54lwY9lvW6MnSm1HSJqZL3xiSgi9E7//FYaI74r2G0rd+/X6VAMkHEdzxQaU5HUOXWUz5kA/w==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + } + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "yargs": { + "version": "17.6.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", + "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", + "dev": true, + "requires": { + "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" + } + }, + "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 + }, + "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 + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..6199722 --- /dev/null +++ b/package.json @@ -0,0 +1,24 @@ +{ + "name": "vector-tiles-google-maps", + "version": "0.0.1", + "author": "Jesús Barrio Pérez", + "license": "MIT", + "scripts": { + "test": "jest" + }, + "devDependencies": { + "eslint": "^8.32.0", + "eslint-config-google": "^0.14.0", + "eslint-plugin-jest": "^27.2.1", + "jest": "^29.4.0" + }, + "moduleNameMapper": { + "^@/(.*)$": "/src/$1" + }, + "jest": { + "moduleNameMapper": { + "^@/(.*)$": "/src/$1", + "^\\$/(.*)$": "/tests/$1" + } + } +} \ No newline at end of file diff --git a/packages.config b/packages.config deleted file mode 100644 index 55d586f..0000000 --- a/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/tests/helloWorld.spec.js b/tests/helloWorld.spec.js new file mode 100644 index 0000000..d8e06c9 --- /dev/null +++ b/tests/helloWorld.spec.js @@ -0,0 +1,5 @@ +describe('Making sure Jest works', () => { + it('works', () => { + expect(undefined).toBeUndefined(); + }); +}); From 9b6837be198fc9721c7ce0710de0312f7e8ed46c Mon Sep 17 00:00:00 2001 From: Seth Williams <92401567+swilliams-northpointkc@users.noreply.github.com> Date: Tue, 31 Jan 2023 11:18:11 -0600 Subject: [PATCH 02/11] BMAPS-1690 Write tests to validate existing MVT functionality (#2) * Clean up VSCode-related files * Add npm project and configs * Add config files * Add basic unit test * Add sourceType of module to eslint configs * Restore example screenshot * Lint files * Provide module exports from Mercator.js * Add @googlemaps/jest-mocks package * Add Jest configs and testing packages * Add unit tests for Mercator.js * Add export to MVTFeature * Add setup script to set global Jest object * Add unit tests for MVTFeature * Move some mocks to common-mocks.js and test MVTLayer * Test MVTSource * Remove placeholder test --- jest.config.js | 11 + lib/mercator/Mercator.js | 272 +++++----- package-lock.json | 1069 +++++++++++++++++++++++++++++++++++++- package.json | 13 +- src/MVTFeature.js | 435 ++++++++-------- src/MVTLayer.js | 325 ++++++------ src/MVTSource.js | 945 +++++++++++++++++---------------- tests/MVTFeature.spec.js | 379 ++++++++++++++ tests/MVTLayer.spec.js | 157 ++++++ tests/MVTSource.spec.js | 317 +++++++++++ tests/Mercator.spec.js | 387 ++++++++++++++ tests/common-mocks.js | 94 ++++ tests/helloWorld.spec.js | 5 - tests/setup.js | 3 + 14 files changed, 3405 insertions(+), 1007 deletions(-) create mode 100644 jest.config.js create mode 100644 tests/MVTFeature.spec.js create mode 100644 tests/MVTLayer.spec.js create mode 100644 tests/MVTSource.spec.js create mode 100644 tests/Mercator.spec.js create mode 100644 tests/common-mocks.js delete mode 100644 tests/helloWorld.spec.js create mode 100644 tests/setup.js diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..a16fd63 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,11 @@ +export default { + transform: {}, + testEnvironment: 'jsdom', + moduleNameMapper: { + '^@/(.*)$': '/src/$1', + '^\\$/(.*)$': '/tests/$1', + }, + setupFiles: [ + '/tests/setup.js', + ], +}; diff --git a/lib/mercator/Mercator.js b/lib/mercator/Mercator.js index e7107f2..904e28a 100644 --- a/lib/mercator/Mercator.js +++ b/lib/mercator/Mercator.js @@ -1,152 +1,152 @@ -MERCATOR = { - fromLatLngToPoint: function (latLng) { - var siny = Math.min(Math.max(Math.sin(latLng.lat() * (Math.PI / 180)), - -.9999), - .9999); - return { - x: 128 + latLng.lng() * (256 / 360), - y: 128 + 0.5 * Math.log((1 + siny) / (1 - siny)) * -(256 / (2 * Math.PI)) - }; - }, +export function fromLatLngToPoint(latLng) { + const siny = Math.min(Math.max(Math.sin(latLng.lat() * (Math.PI / 180)), + -.9999), + .9999); + return { + x: 128 + latLng.lng() * (256 / 360), + y: 128 + 0.5 * Math.log((1 + siny) / (1 - siny)) * -(256 / (2 * Math.PI)), + }; +} - fromPointToLatLng: function (point) { - return { - lat: (2 * Math.atan(Math.exp((point.y - 128) / -(256 / (2 * Math.PI)))) - +export function fromPointToLatLng(point) { + return { + lat: (2 * Math.atan(Math.exp((point.y - 128) / -(256 / (2 * Math.PI)))) - Math.PI / 2) / (Math.PI / 180), - lng: (point.x - 128) / (256 / 360) - }; - }, + lng: (point.x - 128) / (256 / 360), + }; +} - getTileAtLatLng: function (latLng, zoom) { - var t = Math.pow(2, zoom), - s = 256 / t, - p = this.fromLatLngToPoint(latLng); - return { - x: Math.floor(p.x / s), - y: Math.floor(p.y / s), - z: zoom - }; - }, +export function getTileAtLatLng(latLng, zoom) { + const t = Math.pow(2, zoom); + const s = 256 / t; + const p = fromLatLngToPoint(latLng); + return { + x: Math.floor(p.x / s), + y: Math.floor(p.y / s), + z: zoom, + }; +} - getTileBounds: function (tile) { - tile = this.normalizeTile(tile); - var t = Math.pow(2, tile.z), - s = 256 / t, - sw = { - x: tile.x * s, - y: (tile.y * s) + s - }, - ne = { - x: tile.x * s + s, - y: (tile.y * s) - }; - return { - sw: this.fromPointToLatLng(sw), - ne: this.fromPointToLatLng(ne) - } - }, +export function getTileBounds(tile) { + tile = normalizeTile(tile); + const t = Math.pow(2, tile.z); + const s = 256 / t; + const sw = { + x: tile.x * s, + y: (tile.y * s) + s, + }; + const ne = { + x: tile.x * s + s, + y: (tile.y * s), + }; + return { + sw: fromPointToLatLng(sw), + ne: fromPointToLatLng(ne), + }; +} - normalizeTile: function (tile) { - var t = Math.pow(2, tile.z); - tile.x = ((tile.x % t) + t) % t; - tile.y = ((tile.y % t) + t) % t; - return tile; - }, +export function normalizeTile(tile) { + const t = Math.pow(2, tile.z); + tile.x = ((tile.x % t) + t) % t; + tile.y = ((tile.y % t) + t) % t; + return tile; +} - fromLatLngToPixels: function (map, latLng) { - var bounds = map.getBounds(); - var ne = bounds.getNorthEast(); - var sw = bounds.getSouthWest(); - var topRight = map.getProjection().fromLatLngToPoint(ne); - var bottomLeft = map.getProjection().fromLatLngToPoint(sw); - var scale = Math.pow(2, map.getZoom()); - var worldPoint = map.getProjection().fromLatLngToPoint(latLng); - return { - x: (worldPoint.x - bottomLeft.x) * scale, - y: (worldPoint.y - topRight.y) * scale - } - }, +export function fromLatLngToPixels(map, latLng) { + const bounds = map.getBounds(); + const ne = bounds.getNorthEast(); + const sw = bounds.getSouthWest(); + const topRight = map.getProjection().fromLatLngToPoint(ne); + const bottomLeft = map.getProjection().fromLatLngToPoint(sw); + const scale = Math.pow(2, map.getZoom()); + const worldPoint = map.getProjection().fromLatLngToPoint(latLng); + return { + x: (worldPoint.x - bottomLeft.x) * scale, + y: (worldPoint.y - topRight.y) * scale, + }; +} - fromLatLngToTilePoint: function (map, evt) { - var zoom = map.getZoom(); - var tile = this.getTileAtLatLng(evt.latLng, zoom); - var tileBounds = this.getTileBounds(tile); - var tileSwLatLng = new google.maps.LatLng(tileBounds.sw); - var tileNeLatLng = new google.maps.LatLng(tileBounds.ne); - var tileSwPixels = this.fromLatLngToPixels(map, tileSwLatLng); - var tileNePixels = this.fromLatLngToPixels(map, tileNeLatLng); - return { - x: evt.pixel.x - tileSwPixels.x, - y: evt.pixel.y - tileNePixels.y - } - }, +export function fromLatLngToTilePoint(map, evt) { + const zoom = map.getZoom(); + const tile = getTileAtLatLng(evt.latLng, zoom); + const tileBounds = getTileBounds(tile); + const tileSwLatLng = new google.maps.LatLng(tileBounds.sw); + const tileNeLatLng = new google.maps.LatLng(tileBounds.ne); + const tileSwPixels = fromLatLngToPixels(map, tileSwLatLng); + const tileNePixels = fromLatLngToPixels(map, tileNeLatLng); + return { + x: evt.pixel.x - tileSwPixels.x, + y: evt.pixel.y - tileNePixels.y, + }; +} - // todo: sometimes it does not work properly - isPointInPolygon: function (point, polygon) { - if (polygon && polygon.length) { - for (var c = false, i = -1, l = polygon.length, j = l - 1; ++i < l; j = i) { - ((polygon[i].y <= point.y && point.y < polygon[j].y) || (polygon[j].y <= point.y && point.y < polygon[i].y)) - && (point.x < (polygon[j].x - polygon[i].x) * (point.y - polygon[i].y) / (polygon[j].y - polygon[i].y) + polygon[i].x) - && (c = !c); - } - return c; - } - }, +// todo: sometimes it does not work properly +export function isPointInPolygon(point, polygon) { + if (polygon && polygon.length) { + // TODO refactor to use let instead of nasty var function scope to access c outside loop + for (var c = false, i = -1, l = polygon.length, j = l - 1; ++i < l; j = i) { + ((polygon[i].y <= point.y && point.y < polygon[j].y) || (polygon[j].y <= point.y && point.y < polygon[i].y)) && + (point.x < (polygon[j].x - polygon[i].x) * (point.y - polygon[i].y) / + (polygon[j].y - polygon[i].y) + polygon[i].x) && + (c = !c); + } + return c; + } +} - in_circle: function (center_x, center_y, radius, x, y) { - var square_dist = Math.pow((center_x - x), 2) + Math.pow((center_y - y), 2); - return square_dist <= Math.pow(radius, 2); - }, +export function inCircle(centerX, centerY, radius, x, y) { + const squareDist = Math.pow((centerX - x), 2) + Math.pow((centerY - y), 2); + return squareDist <= Math.pow(radius, 2); +} - getDistanceFromLine: function (point, line) { - var minDistance = Number.POSITIVE_INFINITY; - if (line && line.length > 1) { - for (var i = 0, l = line.length - 1; i < l; i++) { - var distance = this.projectPointOnLineSegment(point, line[i], line[i + 1]); - if (distance <= minDistance) { - minDistance = distance; - } - } - } - return minDistance; - }, +export function getDistanceFromLine(point, line) { + let minDistance = Number.POSITIVE_INFINITY; + if (line && line.length > 1) { + for (let i = 0, l = line.length - 1; i < l; i++) { + const distance = projectPointOnLineSegment(point, line[i], line[i + 1]); + if (distance <= minDistance) { + minDistance = distance; + } + } + } + return minDistance; +} - projectPointOnLineSegment: function (point, r0, r1) { - var x = point.x; - var y = point.y; - var x1 = r0.x; - var y1 = r0.y; - var x2 = r1.x; - var y2 = r1.y; +export function projectPointOnLineSegment(point, r0, r1) { + const x = point.x; + const y = point.y; + const x1 = r0.x; + const y1 = r0.y; + const x2 = r1.x; + const y2 = r1.y; - var A = x - x1; - var B = y - y1; - var C = x2 - x1; - var D = y2 - y1; + const A = x - x1; + const B = y - y1; + const C = x2 - x1; + const D = y2 - y1; - var dot = A * C + B * D; - var len_sq = C * C + D * D; - var param = -1; - if (len_sq != 0) //in case of 0 length line - param = dot / len_sq; + const dot = A * C + B * D; + const lenSq = C * C + D * D; + let param = -1; + if (lenSq != 0) // in case of 0 length line + { + param = dot / lenSq; + } - var xx, yy; + let xx; let yy; - if (param < 0) { - xx = x1; - yy = y1; - } - else if (param > 1) { - xx = x2; - yy = y2; - } - else { - xx = x1 + param * C; - yy = y1 + param * D; - } + if (param < 0) { + xx = x1; + yy = y1; + } else if (param > 1) { + xx = x2; + yy = y2; + } else { + xx = x1 + param * C; + yy = y1 + param * D; + } - var dx = x - xx; - var dy = y - yy; - return Math.sqrt(dx * dx + dy * dy); - } -} \ No newline at end of file + const dx = x - xx; + const dy = y - yy; + return Math.sqrt(dx * dx + dy * dy); +} diff --git a/package-lock.json b/package-lock.json index d134624..8391331 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,10 +9,12 @@ "version": "0.0.1", "license": "MIT", "devDependencies": { + "@googlemaps/jest-mocks": "2.7.5", "eslint": "^8.32.0", "eslint-config-google": "^0.14.0", "eslint-plugin-jest": "^27.2.1", - "jest": "^29.4.0" + "jest": "^29.4.0", + "jest-environment-jsdom": "^29.4.0" } }, "node_modules/@ampproject/remapping": { @@ -650,6 +652,12 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@googlemaps/jest-mocks": { + "version": "2.7.5", + "resolved": "https://registry.npmjs.org/@googlemaps/jest-mocks/-/jest-mocks-2.7.5.tgz", + "integrity": "sha512-fdHN/sN0Cpz+Acqe9Yhzvhqg/bhN4oMBoKToVIZgFhxafMXtUbQvfL12HiE9AmpvZgge2gBKTu11ImGRm3e2wg==", + "dev": true + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.8", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", @@ -1175,6 +1183,15 @@ "@sinonjs/commons": "^2.0.0" } }, + "node_modules/@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, "node_modules/@types/babel__core": { "version": "7.20.0", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.0.tgz", @@ -1249,6 +1266,17 @@ "@types/istanbul-lib-report": "*" } }, + "node_modules/@types/jsdom": { + "version": "20.0.1", + "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-20.0.1.tgz", + "integrity": "sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/tough-cookie": "*", + "parse5": "^7.0.0" + } + }, "node_modules/@types/json-schema": { "version": "7.0.11", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", @@ -1279,6 +1307,12 @@ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, + "node_modules/@types/tough-cookie": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.2.tgz", + "integrity": "sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==", + "dev": true + }, "node_modules/@types/yargs": { "version": "17.0.20", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.20.tgz", @@ -1416,6 +1450,12 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "dev": true + }, "node_modules/acorn": { "version": "8.8.2", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", @@ -1428,6 +1468,16 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-globals": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz", + "integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==", + "dev": true, + "dependencies": { + "acorn": "^8.1.0", + "acorn-walk": "^8.0.2" + } + }, "node_modules/acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", @@ -1437,6 +1487,27 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true, + "engines": { + "node": ">=0.4.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", @@ -1532,6 +1603,12 @@ "node": ">=8" } }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, "node_modules/babel-jest": { "version": "29.4.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.4.0.tgz", @@ -1822,6 +1899,18 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -1848,6 +1937,44 @@ "node": ">= 8" } }, + "node_modules/cssom": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", + "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==", + "dev": true + }, + "node_modules/cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cssstyle/node_modules/cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + }, + "node_modules/data-urls": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", + "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", + "dev": true, + "dependencies": { + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -1865,6 +1992,12 @@ } } }, + "node_modules/decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", + "dev": true + }, "node_modules/dedent": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", @@ -1886,6 +2019,15 @@ "node": ">=0.10.0" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -1928,6 +2070,18 @@ "node": ">=6.0.0" } }, + "node_modules/domexception": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", + "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", + "dev": true, + "dependencies": { + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/electron-to-chromium": { "version": "1.4.284", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", @@ -1952,6 +2106,18 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "node_modules/entities": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", + "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==", + "dev": true, + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -1982,6 +2148,79 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/escodegen": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "dev": true, + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, "node_modules/eslint": { "version": "8.32.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.32.0.tgz", @@ -2366,6 +2605,20 @@ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -2531,12 +2784,51 @@ "node": ">=8" } }, + "node_modules/html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "dev": true, + "dependencies": { + "whatwg-encoding": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, "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-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dev": true, + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "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", @@ -2546,6 +2838,18 @@ "node": ">=10.17.0" } }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -2690,6 +2994,12 @@ "node": ">=8" } }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true + }, "node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -2974,6 +3284,33 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-environment-jsdom": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.4.0.tgz", + "integrity": "sha512-z1tB/qtReousDnU695K38ZzoR6B3dRXazwgyhTHzMviSC2T3KmVy0T722fZxR2q3x/Jvv85JxU/2xs8kwX394w==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.4.0", + "@jest/fake-timers": "^29.4.0", + "@jest/types": "^29.4.0", + "@types/jsdom": "^20.0.0", + "@types/node": "*", + "jest-mock": "^29.4.0", + "jest-util": "^29.4.0", + "jsdom": "^20.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, "node_modules/jest-environment-node": { "version": "29.4.0", "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.4.0.tgz", @@ -3370,6 +3707,51 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsdom": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz", + "integrity": "sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==", + "dev": true, + "dependencies": { + "abab": "^2.0.6", + "acorn": "^8.8.1", + "acorn-globals": "^7.0.0", + "cssom": "^0.5.0", + "cssstyle": "^2.3.0", + "data-urls": "^3.0.2", + "decimal.js": "^10.4.2", + "domexception": "^4.0.0", + "escodegen": "^2.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.2", + "parse5": "^7.1.1", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.2", + "w3c-xmlserializer": "^4.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^2.0.0", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0", + "ws": "^8.11.0", + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, "node_modules/jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -3540,6 +3922,27 @@ "node": ">=8.6" } }, + "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", @@ -3606,6 +4009,12 @@ "node": ">=8" } }, + "node_modules/nwsapi": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz", + "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==", + "dev": true + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -3716,6 +4125,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dev": true, + "dependencies": { + "entities": "^4.4.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -3897,6 +4318,12 @@ "node": ">= 6" } }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true + }, "node_modules/punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", @@ -3906,6 +4333,12 @@ "node": ">=6" } }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -3953,6 +4386,12 @@ "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.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -4057,6 +4496,24 @@ "queue-microtask": "^1.2.2" } }, + "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/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, "node_modules/semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", @@ -4271,6 +4728,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -4318,6 +4781,33 @@ "node": ">=8.0" } }, + "node_modules/tough-cookie": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz", + "integrity": "sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==", + "dev": true, + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=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/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", @@ -4386,9 +4876,18 @@ "node": ">=4.2.0" } }, - "node_modules/update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", "dev": true, "funding": [ @@ -4421,6 +4920,16 @@ "punycode": "^2.1.0" } }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "node_modules/v8-to-istanbul": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", @@ -4441,6 +4950,18 @@ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", "dev": true }, + "node_modules/w3c-xmlserializer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", + "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", + "dev": true, + "dependencies": { + "xml-name-validator": "^4.0.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", @@ -4450,6 +4971,49 @@ "makeerror": "1.0.12" } }, + "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-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "dev": true, + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/whatwg-mimetype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", + "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", @@ -4510,6 +5074,42 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/ws": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.12.0.tgz", + "integrity": "sha512-kU62emKIdKVeEIOIKVegvqpXMSTAMLJozpHZaJNDYqBjzlSYXQGviYwN1osDLJ9av68qHd4a2oSjd7yD4pacig==", + "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/xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -5048,6 +5648,12 @@ "strip-json-comments": "^3.1.1" } }, + "@googlemaps/jest-mocks": { + "version": "2.7.5", + "resolved": "https://registry.npmjs.org/@googlemaps/jest-mocks/-/jest-mocks-2.7.5.tgz", + "integrity": "sha512-fdHN/sN0Cpz+Acqe9Yhzvhqg/bhN4oMBoKToVIZgFhxafMXtUbQvfL12HiE9AmpvZgge2gBKTu11ImGRm3e2wg==", + "dev": true + }, "@humanwhocodes/config-array": { "version": "0.11.8", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", @@ -5462,6 +6068,12 @@ "@sinonjs/commons": "^2.0.0" } }, + "@tootallnate/once": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", + "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "dev": true + }, "@types/babel__core": { "version": "7.20.0", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.0.tgz", @@ -5536,6 +6148,17 @@ "@types/istanbul-lib-report": "*" } }, + "@types/jsdom": { + "version": "20.0.1", + "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-20.0.1.tgz", + "integrity": "sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/tough-cookie": "*", + "parse5": "^7.0.0" + } + }, "@types/json-schema": { "version": "7.0.11", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", @@ -5566,6 +6189,12 @@ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", "dev": true }, + "@types/tough-cookie": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.2.tgz", + "integrity": "sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==", + "dev": true + }, "@types/yargs": { "version": "17.0.20", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.20.tgz", @@ -5656,12 +6285,28 @@ "eslint-visitor-keys": "^3.3.0" } }, + "abab": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", + "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", + "dev": true + }, "acorn": { "version": "8.8.2", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", "dev": true }, + "acorn-globals": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz", + "integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==", + "dev": true, + "requires": { + "acorn": "^8.1.0", + "acorn-walk": "^8.0.2" + } + }, "acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", @@ -5669,6 +6314,21 @@ "dev": true, "requires": {} }, + "acorn-walk": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", + "dev": true + }, + "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, + "requires": { + "debug": "4" + } + }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -5735,6 +6395,12 @@ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, "babel-jest": { "version": "29.4.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.4.0.tgz", @@ -5941,6 +6607,15 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -5964,6 +6639,40 @@ "which": "^2.0.1" } }, + "cssom": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", + "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==", + "dev": true + }, + "cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "requires": { + "cssom": "~0.3.6" + }, + "dependencies": { + "cssom": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", + "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", + "dev": true + } + } + }, + "data-urls": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", + "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", + "dev": true, + "requires": { + "abab": "^2.0.6", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0" + } + }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -5973,6 +6682,12 @@ "ms": "2.1.2" } }, + "decimal.js": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", + "dev": true + }, "dedent": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", @@ -5991,6 +6706,12 @@ "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", "dev": true }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true + }, "detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -6021,6 +6742,15 @@ "esutils": "^2.0.2" } }, + "domexception": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", + "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", + "dev": true, + "requires": { + "webidl-conversions": "^7.0.0" + } + }, "electron-to-chromium": { "version": "1.4.284", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", @@ -6039,6 +6769,12 @@ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, + "entities": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", + "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==", + "dev": true + }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -6060,6 +6796,60 @@ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", "dev": true }, + "escodegen": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", + "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", + "dev": true, + "requires": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + } + } + }, "eslint": { "version": "8.32.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.32.0.tgz", @@ -6343,6 +7133,17 @@ "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, + "form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -6459,18 +7260,57 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "html-encoding-sniffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", + "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "dev": true, + "requires": { + "whatwg-encoding": "^2.0.0" + } + }, "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 }, + "http-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", + "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", + "dev": true, + "requires": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + } + }, + "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, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, "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 }, + "iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, "ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -6573,6 +7413,12 @@ "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true }, + "is-potential-custom-element-name": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true + }, "is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -6777,6 +7623,22 @@ "pretty-format": "^29.4.0" } }, + "jest-environment-jsdom": { + "version": "29.4.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.4.0.tgz", + "integrity": "sha512-z1tB/qtReousDnU695K38ZzoR6B3dRXazwgyhTHzMviSC2T3KmVy0T722fZxR2q3x/Jvv85JxU/2xs8kwX394w==", + "dev": true, + "requires": { + "@jest/environment": "^29.4.0", + "@jest/fake-timers": "^29.4.0", + "@jest/types": "^29.4.0", + "@types/jsdom": "^20.0.0", + "@types/node": "*", + "jest-mock": "^29.4.0", + "jest-util": "^29.4.0", + "jsdom": "^20.0.0" + } + }, "jest-environment-node": { "version": "29.4.0", "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.4.0.tgz", @@ -7095,6 +7957,40 @@ "argparse": "^2.0.1" } }, + "jsdom": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz", + "integrity": "sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==", + "dev": true, + "requires": { + "abab": "^2.0.6", + "acorn": "^8.8.1", + "acorn-globals": "^7.0.0", + "cssom": "^0.5.0", + "cssstyle": "^2.3.0", + "data-urls": "^3.0.2", + "decimal.js": "^10.4.2", + "domexception": "^4.0.0", + "escodegen": "^2.0.0", + "form-data": "^4.0.0", + "html-encoding-sniffer": "^3.0.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.2", + "parse5": "^7.1.1", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.1.2", + "w3c-xmlserializer": "^4.0.0", + "webidl-conversions": "^7.0.0", + "whatwg-encoding": "^2.0.0", + "whatwg-mimetype": "^3.0.0", + "whatwg-url": "^11.0.0", + "ws": "^8.11.0", + "xml-name-validator": "^4.0.0" + } + }, "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", @@ -7225,6 +8121,21 @@ "picomatch": "^2.3.1" } }, + "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 + }, + "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, + "requires": { + "mime-db": "1.52.0" + } + }, "mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", @@ -7279,6 +8190,12 @@ "path-key": "^3.0.0" } }, + "nwsapi": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz", + "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==", + "dev": true + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -7356,6 +8273,15 @@ "lines-and-columns": "^1.1.6" } }, + "parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", + "dev": true, + "requires": { + "entities": "^4.4.0" + } + }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -7487,12 +8413,24 @@ "sisteransi": "^1.0.5" } }, + "psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", + "dev": true + }, "punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "dev": true }, + "querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true + }, "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -7517,6 +8455,12 @@ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true }, + "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 + }, "resolve": { "version": "1.22.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", @@ -7581,6 +8525,21 @@ "queue-microtask": "^1.2.2" } }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "requires": { + "xmlchars": "^2.2.0" + } + }, "semver": { "version": "7.3.8", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", @@ -7742,6 +8701,12 @@ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true }, + "symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", + "dev": true + }, "test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -7780,6 +8745,27 @@ "is-number": "^7.0.0" } }, + "tough-cookie": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz", + "integrity": "sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==", + "dev": true, + "requires": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + } + }, + "tr46": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", + "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "dev": true, + "requires": { + "punycode": "^2.1.1" + } + }, "tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", @@ -7823,6 +8809,12 @@ "dev": true, "peer": true }, + "universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true + }, "update-browserslist-db": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", @@ -7842,6 +8834,16 @@ "punycode": "^2.1.0" } }, + "url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dev": true, + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "v8-to-istanbul": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", @@ -7861,6 +8863,15 @@ } } }, + "w3c-xmlserializer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", + "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", + "dev": true, + "requires": { + "xml-name-validator": "^4.0.0" + } + }, "walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", @@ -7870,6 +8881,37 @@ "makeerror": "1.0.12" } }, + "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 + }, + "whatwg-encoding": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", + "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "dev": true, + "requires": { + "iconv-lite": "0.6.3" + } + }, + "whatwg-mimetype": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", + "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", + "dev": true + }, + "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, + "requires": { + "tr46": "^3.0.0", + "webidl-conversions": "^7.0.0" + } + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -7912,6 +8954,25 @@ "signal-exit": "^3.0.7" } }, + "ws": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.12.0.tgz", + "integrity": "sha512-kU62emKIdKVeEIOIKVegvqpXMSTAMLJozpHZaJNDYqBjzlSYXQGviYwN1osDLJ9av68qHd4a2oSjd7yD4pacig==", + "dev": true, + "requires": {} + }, + "xml-name-validator": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", + "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", + "dev": true + }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/package.json b/package.json index 6199722..0317a8b 100644 --- a/package.json +++ b/package.json @@ -3,22 +3,19 @@ "version": "0.0.1", "author": "Jesús Barrio Pérez", "license": "MIT", + "type": "module", "scripts": { - "test": "jest" + "test": "NODE_OPTIONS=--experimental-vm-modules jest" }, "devDependencies": { + "@googlemaps/jest-mocks": "2.7.5", "eslint": "^8.32.0", "eslint-config-google": "^0.14.0", "eslint-plugin-jest": "^27.2.1", - "jest": "^29.4.0" + "jest": "^29.4.0", + "jest-environment-jsdom": "^29.4.0" }, "moduleNameMapper": { "^@/(.*)$": "/src/$1" - }, - "jest": { - "moduleNameMapper": { - "^@/(.*)$": "/src/$1", - "^\\$/(.*)$": "/tests/$1" - } } } \ No newline at end of file diff --git a/src/MVTFeature.js b/src/MVTFeature.js index 97f06fc..d4d9d82 100644 --- a/src/MVTFeature.js +++ b/src/MVTFeature.js @@ -1,223 +1,222 @@ /* - * Created by Jesús Barrio on 04/2021 + * Created by Jes�s Barrio on 04/2021 */ -class MVTFeature { - constructor(options) { - this.mVTSource = options.mVTSource; - this.selected = options.selected; - this.featureId = options.featureId; - this.tiles = []; - this.style = options.style; - this.type = options.vectorTileFeature.type; - this.properties = options.vectorTileFeature.properties; - this.addTileFeature(options.vectorTileFeature, options.tileContext); - this._draw = options.customDraw || this.defaultDraw; - - if (this.selected) { - this.select(); - } - } - - addTileFeature(vectorTileFeature, tileContext) { - this.tiles[tileContext.id] = { - vectorTileFeature: vectorTileFeature, - divisor: vectorTileFeature.extent / tileContext.tileSize, - context2d: false, - paths2d: false - }; - } - - getTiles() { - return this.tiles; - } - - getTile(tileContext) { - return this.tiles[tileContext.id]; - } - - setStyle(style) { - this.style = style; - } - - redrawTiles() { - var zoom = this.mVTSource.map.getZoom(); - for (var id in this.tiles) { - this.mVTSource.deleteTileDrawn(id); - var idObject = this.mVTSource.getTileObject(id); - if (idObject.zoom == zoom) { - this.mVTSource.redrawTile(id); - } - } - } - - toggle() { - if (this.selected) { - this.deselect(); +export class MVTFeature { + constructor(options) { + this.mVTSource = options.mVTSource; + this.selected = options.selected; + this.featureId = options.featureId; + this.tiles = []; + this.style = options.style; + this.type = options.vectorTileFeature.type; + this.properties = options.vectorTileFeature.properties; + this.addTileFeature(options.vectorTileFeature, options.tileContext); + this._draw = options.customDraw || this.defaultDraw; + + if (this.selected) { + this.select(); + } + } + + addTileFeature(vectorTileFeature, tileContext) { + this.tiles[tileContext.id] = { + vectorTileFeature: vectorTileFeature, + divisor: vectorTileFeature.extent / tileContext.tileSize, + context2d: false, + paths2d: false, + }; + } + + getTiles() { + return this.tiles; + } + + getTile(tileContext) { + return this.tiles[tileContext.id]; + } + + setStyle(style) { + this.style = style; + } + + redrawTiles() { + const zoom = this.mVTSource.map.getZoom(); + for (const id in this.tiles) { + this.mVTSource.deleteTileDrawn(id); + const idObject = this.mVTSource.getTileObject(id); + if (idObject.zoom == zoom) { + this.mVTSource.redrawTile(id); + } + } + } + + toggle() { + if (this.selected) { + this.deselect(); + } else { + this.select(); + } + } + + select() { + this.selected = true; + this.mVTSource.featureSelected(this); + this.redrawTiles(); + } + + deselect() { + this.selected = false; + this.mVTSource.featureDeselected(this); + this.redrawTiles(); + } + + setSelected(selected) { + this.selected = selected; + } + + draw(tileContext) { + const tile = this.tiles[tileContext.id]; + let style = this.style; + if (this.selected && this.style.selected) { + style = this.style.selected; + } + + this._draw(tileContext, tile, style, this); + } + + defaultDraw(tileContext, tile, style) { + switch (this.type) { + case 1: // Point + this.drawPoint(tileContext, tile, style); + break; + + case 2: // LineString + this.drawLineString(tileContext, tile, style); + break; + + case 3: // Polygon + this.drawPolygon(tileContext, tile, style); + break; + } + } + + drawPoint(tileContext, tile, style) { + const coordinates = tile.vectorTileFeature.coordinates[0][0]; + const point = this.getPoint(coordinates, tileContext, tile.divisor); + const radius = style.radius || 3; + const context2d = this.getContext2d(tileContext.canvas, style); + context2d.beginPath(); + context2d.arc(point.x, point.y, radius, 0, Math.PI * 2); + context2d.closePath(); + context2d.fill(); + context2d.stroke(); + } + + drawLineString(tileContext, tile, style) { + tile.context2d = this.getContext2d(tileContext.canvas, style); + this.drawCoordinates(tileContext, tile); + tile.context2d.stroke(tile.paths2d); + } + + drawPolygon(tileContext, tile, style) { + tile.context2d = this.getContext2d(tileContext.canvas, style); + this.drawCoordinates(tileContext, tile); + tile.paths2d.closePath(); + + if (style.fillStyle) { + tile.context2d.fill(tile.paths2d); + } + if (style.strokeStyle) { + tile.context2d.stroke(tile.paths2d); + } + } + + drawCoordinates(tileContext, tile) { + const coordinates = tile.vectorTileFeature.coordinates; + tile.paths2d = new Path2D(); + for (let i = 0, length1 = coordinates.length; i < length1; i++) { + const coordinate = coordinates[i]; + const path2 = new Path2D(); + for (let j = 0, length2 = coordinate.length; j < length2; j++) { + const point = this.getPoint(coordinate[j], tileContext, tile.divisor); + if (j == 0) { + path2.moveTo(point.x, point.y); } else { - this.select(); + path2.lineTo(point.x, point.y); } - } - - select() { - this.selected = true; - this.mVTSource.featureSelected(this); - this.redrawTiles(); - } - - deselect() { - this.selected = false; - this.mVTSource.featureDeselected(this); - this.redrawTiles(); - } - - setSelected(selected) { - this.selected = selected; - } - - draw(tileContext) { - var tile = this.tiles[tileContext.id]; - var style = this.style; - if (this.selected && this.style.selected) { - style = this.style.selected; - } - - this._draw(tileContext, tile, style, this); - } - - defaultDraw(tileContext, tile, style) { - switch (this.type) { - case 1: //Point - this.drawPoint(tileContext, tile, style); - break; - - case 2: //LineString - this.drawLineString(tileContext, tile, style); - break; - - case 3: //Polygon - this.drawPolygon(tileContext, tile, style); - break; - } - } - - drawPoint(tileContext, tile, style) { - var coordinates = tile.vectorTileFeature.coordinates[0][0]; - var point = this.getPoint(coordinates, tileContext, tile.divisor); - var radius = style.radius || 3; - var context2d = this.getContext2d(tileContext.canvas, style); - context2d.beginPath(); - context2d.arc(point.x, point.y, radius, 0, Math.PI * 2); - context2d.closePath(); - context2d.fill(); - context2d.stroke(); - } - - drawLineString(tileContext, tile, style) { - tile.context2d = this.getContext2d(tileContext.canvas, style); - this.drawCoordinates(tileContext, tile); - tile.context2d.stroke(tile.paths2d); - } - - drawPolygon(tileContext, tile, style) { - tile.context2d = this.getContext2d(tileContext.canvas, style); - this.drawCoordinates(tileContext, tile); - tile.paths2d.closePath(); - - if (style.fillStyle) { - tile.context2d.fill(tile.paths2d); - } - if (style.strokeStyle) { - tile.context2d.stroke(tile.paths2d); - } - } - - drawCoordinates(tileContext, tile) { - var coordinates = tile.vectorTileFeature.coordinates; - tile.paths2d = new Path2D(); - for (var i = 0, length1 = coordinates.length; i < length1; i++) { - var coordinate = coordinates[i]; - let path2 = new Path2D(); - for (var j = 0, length2 = coordinate.length; j < length2; j++) { - var point = this.getPoint(coordinate[j], tileContext, tile.divisor); - if (j == 0) { - path2.moveTo(point.x, point.y); - } - else { - path2.lineTo(point.x, point.y); - } - } - tile.paths2d.addPath(path2); - } - } - - getPaths(tileContext) { - var paths = []; - var tile = this.tiles[tileContext.id]; - var coordinates = tile.vectorTileFeature.coordinates; - for (var i = 0, length1 = coordinates.length; i < length1; i++) { - var path = []; - var coordinate = coordinates[i]; - for (var j = 0, length2 = coordinate.length; j < length2; j++) { - var point = this.getPoint(coordinate[j], tileContext, tile.divisor); - path.push(point); - } - if (path.length > 0) { - paths.push(path); - } - } - return paths; - } - - getContext2d(canvas, style) { - var context2d = canvas.getContext('2d'); - for (var key in style) { - if (key === 'selected') { - continue; - } - context2d[key] = style[key]; - } - return context2d; - } - - getPoint(coords, tileContext, divisor) { - var point = { - x: coords.x / divisor, - y: coords.y / divisor - }; - - if (tileContext.parentId) { - point = this._getOverzoomedPoint(point, tileContext); - } - return point; - } - - _getOverzoomedPoint(point, tileContext) { - var parentTile = this.mVTSource.getTileObject(tileContext.parentId); - var currentTile = this.mVTSource.getTileObject(tileContext.id); - var zoomDistance = currentTile.zoom - parentTile.zoom; - - const scale = Math.pow(2, zoomDistance); - - let xScale = point.x * scale; - let yScale = point.y * scale; - - let xtileOffset = currentTile.x % scale; - let ytileOffset = currentTile.y % scale; - - point.x = xScale - (xtileOffset * tileContext.tileSize); - point.y = yScale - (ytileOffset * tileContext.tileSize); - - return point; - } - - isPointInPath(point, tileContext) { - var tile = this.getTile(tileContext); - var context2d = tile.context2d; - var paths2d = tile.paths2d; - if (!context2d || !paths2d) { - return false; - } - return context2d.isPointInPath(paths2d, point.x, point.y) - } -} \ No newline at end of file + } + tile.paths2d.addPath(path2); + } + } + + getPaths(tileContext) { + const paths = []; + const tile = this.tiles[tileContext.id]; + const coordinates = tile.vectorTileFeature.coordinates; + for (let i = 0, length1 = coordinates.length; i < length1; i++) { + const path = []; + const coordinate = coordinates[i]; + for (let j = 0, length2 = coordinate.length; j < length2; j++) { + const point = this.getPoint(coordinate[j], tileContext, tile.divisor); + path.push(point); + } + if (path.length > 0) { + paths.push(path); + } + } + return paths; + } + + getContext2d(canvas, style) { + const context2d = canvas.getContext('2d'); + for (const key in style) { + if (key === 'selected') { + continue; + } + context2d[key] = style[key]; + } + return context2d; + } + + getPoint(coords, tileContext, divisor) { + let point = { + x: coords.x / divisor, + y: coords.y / divisor, + }; + + if (tileContext.parentId) { // TODO likely a bug: needs to check for nullish value, not falsy + point = this._getOverzoomedPoint(point, tileContext); + } + return point; + } + + _getOverzoomedPoint(point, tileContext) { + const parentTile = this.mVTSource.getTileObject(tileContext.parentId); + const currentTile = this.mVTSource.getTileObject(tileContext.id); + const zoomDistance = currentTile.zoom - parentTile.zoom; + + const scale = Math.pow(2, zoomDistance); + + const xScale = point.x * scale; + const yScale = point.y * scale; + + const xtileOffset = currentTile.x % scale; + const ytileOffset = currentTile.y % scale; + + point.x = xScale - (xtileOffset * tileContext.tileSize); + point.y = yScale - (ytileOffset * tileContext.tileSize); + + return point; + } + + isPointInPath(point, tileContext) { + const tile = this.getTile(tileContext); + const context2d = tile.context2d; + const paths2d = tile.paths2d; + if (!context2d || !paths2d) { + return false; + } + return context2d.isPointInPath(paths2d, point.x, point.y); + } +} diff --git a/src/MVTLayer.js b/src/MVTLayer.js index d285cc4..ed9fb96 100644 --- a/src/MVTLayer.js +++ b/src/MVTLayer.js @@ -1,192 +1,195 @@ /* - * Created by Jesús Barrio on 04/2021 + * Created by Jes�s Barrio on 04/2021 */ -class MVTLayer { - constructor(options) { - this._lineClickTolerance = 2; - this._getIDForLayerFeature = options.getIDForLayerFeature; - this.style = options.style; - this.name = options.name; - this._filter = options.filter || false; - this._customDraw = options.customDraw || false; - this._canvasAndMVTFeatures = []; - this._mVTFeatures = []; +import {MVTFeature} from '@/MVTFeature.js'; + +export class MVTLayer { + constructor(options) { + this._lineClickTolerance = 2; + this._getIDForLayerFeature = options.getIDForLayerFeature; + this.style = options.style; + this.name = options.name; + this._filter = options.filter || false; + this._customDraw = options.customDraw || false; + this._canvasAndMVTFeatures = []; + this._mVTFeatures = []; + } + + parseVectorTileFeatures(mVTSource, vectorTileFeatures, tileContext) { + this._canvasAndMVTFeatures[tileContext.id] = { + canvas: tileContext.canvas, + features: [], + }; + for (let i = 0, length = vectorTileFeatures.length; i < length; i++) { + const vectorTileFeature = vectorTileFeatures[i]; + this._parseVectorTileFeature(mVTSource, vectorTileFeature, tileContext, i); } - - parseVectorTileFeatures(mVTSource, vectorTileFeatures, tileContext) { - this._canvasAndMVTFeatures[tileContext.id] = { - canvas: tileContext.canvas, - features: [] - } - for (var i = 0, length = vectorTileFeatures.length; i < length; i++) { - var vectorTileFeature = vectorTileFeatures[i]; - this._parseVectorTileFeature(mVTSource, vectorTileFeature, tileContext, i); - } - this.drawTile(tileContext); + this.drawTile(tileContext); + } + + _parseVectorTileFeature(mVTSource, vectorTileFeature, tileContext, i) { + if (this._filter && typeof this._filter === 'function') { + if (this._filter(vectorTileFeature, tileContext) === false) { + return; + } } - _parseVectorTileFeature(mVTSource, vectorTileFeature, tileContext, i) { - if (this._filter && typeof this._filter === 'function') { - if (this._filter(vectorTileFeature, tileContext) === false) { - return; - } - } - - var style = this.getStyle(vectorTileFeature); - var featureId = this._getIDForLayerFeature(vectorTileFeature) || i; - var mVTFeature = this._mVTFeatures[featureId]; - if (!mVTFeature) { - var selected = mVTSource.isFeatureSelected(featureId); - var options = { - mVTSource: mVTSource, - vectorTileFeature: vectorTileFeature, - tileContext: tileContext, - style: style, - selected: selected, - featureId: featureId, - customDraw: this._customDraw - } - mVTFeature = new MVTFeature(options); - this._mVTFeatures[featureId] = mVTFeature; - } else { - mVTFeature.setStyle(style); - mVTFeature.addTileFeature(vectorTileFeature, tileContext); - } - this._canvasAndMVTFeatures[tileContext.id].features.push(mVTFeature); + const style = this.getStyle(vectorTileFeature); + // TODO likely bug: should probably be checking for nullish, not falsy. + const featureId = this._getIDForLayerFeature(vectorTileFeature) || i; + let mVTFeature = this._mVTFeatures[featureId]; + if (!mVTFeature) { + const selected = mVTSource.isFeatureSelected(featureId); + const options = { + mVTSource: mVTSource, + vectorTileFeature: vectorTileFeature, + tileContext: tileContext, + style: style, + selected: selected, + featureId: featureId, + customDraw: this._customDraw, + }; + mVTFeature = new MVTFeature(options); + this._mVTFeatures[featureId] = mVTFeature; + } else { + mVTFeature.setStyle(style); + mVTFeature.addTileFeature(vectorTileFeature, tileContext); } - - drawTile(tileContext) { - var mVTFeatures = this._canvasAndMVTFeatures[tileContext.id].features; - if (!mVTFeatures) return; - var selectedFeatures = []; - for (var i = 0, length = mVTFeatures.length; i < length; i++) { - var mVTFeature = mVTFeatures[i]; - if (mVTFeature.selected) { - selectedFeatures.push(mVTFeature); - } else { - mVTFeature.draw(tileContext); - } - } - for (var i = 0, length = selectedFeatures.length; i < length; i++) { - selectedFeatures[i].draw(tileContext); - } + this._canvasAndMVTFeatures[tileContext.id].features.push(mVTFeature); + } + + drawTile(tileContext) { + const mVTFeatures = this._canvasAndMVTFeatures[tileContext.id].features; + if (!mVTFeatures) return; + const selectedFeatures = []; + for (var i = 0, length = mVTFeatures.length; i < length; i++) { + const mVTFeature = mVTFeatures[i]; + if (mVTFeature.selected) { + selectedFeatures.push(mVTFeature); + } else { + mVTFeature.draw(tileContext); + } } - - getCanvas(id) { - return this._canvasAndMVTFeatures[id].canvas; + for (var i = 0, length = selectedFeatures.length; i < length; i++) { + selectedFeatures[i].draw(tileContext); } + } - getStyle(feature) { - if (typeof this.style === 'function') { - return this.style(feature); - } - return this.style; - } + getCanvas(id) { + return this._canvasAndMVTFeatures[id].canvas; + } - setStyle(style) { - this.style = style; - for (var featureId in this._mVTFeatures) { - this._mVTFeatures[featureId].setStyle(style); - } + getStyle(feature) { + if (typeof this.style === 'function') { + return this.style(feature); } + return this.style; + } - setSelected(featureId) { - if (this._mVTFeatures[featureId] !== undefined) { - this._mVTFeatures[featureId].select(); - } + setStyle(style) { + this.style = style; + for (const featureId in this._mVTFeatures) { + this._mVTFeatures[featureId].setStyle(style); } + } - setFilter(filter) { - this._filter = filter; + setSelected(featureId) { + if (this._mVTFeatures[featureId] !== undefined) { + this._mVTFeatures[featureId].select(); } + } - handleClickEvent(event, mVTSource) { - var canvasAndFeatures = this._canvasAndMVTFeatures[event.tileContext.id]; - if (!canvasAndFeatures) return event; - var canvas = canvasAndFeatures.canvas; - var mVTFeatures = canvasAndFeatures.features; - - if (!canvas || !mVTFeatures) { - return event; - } - event.feature = this._handleClickEvent(event, mVTFeatures, mVTSource); - return event; - } + setFilter(filter) { + this._filter = filter; + } - _handleClickEvent(event, mVTFeatures, mVTSource) { - this.selectedFeature = null; + handleClickEvent(event, mVTSource) { + const canvasAndFeatures = this._canvasAndMVTFeatures[event.tileContext.id]; + if (!canvasAndFeatures) return event; + const canvas = canvasAndFeatures.canvas; + const mVTFeatures = canvasAndFeatures.features; - var tileContextId = event.tileContext.id; - var currentSelectedFeaturesInTile = mVTSource.getSelectedFeaturesInTile(tileContextId); - this._handleClickFeatures(event, currentSelectedFeaturesInTile); + if (!canvas || !mVTFeatures) { + return event; + } + event.feature = this._handleClickEvent(event, mVTFeatures, mVTSource); + return event; + } - if (this.selectedFeature != null) { - return this.selectedFeature; - } + _handleClickEvent(event, mVTFeatures, mVTSource) { + this.selectedFeature = null; - this._handleClickFeatures(event, mVTFeatures); - if (this.selectedFeature != null) { - return this.selectedFeature; - } + const tileContextId = event.tileContext.id; + const currentSelectedFeaturesInTile = mVTSource.getSelectedFeaturesInTile(tileContextId); + this._handleClickFeatures(event, currentSelectedFeaturesInTile); - return this.selectedFeature; + if (this.selectedFeature != null) { + return this.selectedFeature; } - _handleClickFeatures(event, mVTFeatures) { - this.minDistance = Number.POSITIVE_INFINITY; - - for (var i = mVTFeatures.length - 1; i >= 0; i--) { - var mVTFeature = mVTFeatures[i]; - this._handleClickFeature(event, mVTFeature); - if (this.selectedFeature != null) { - return this.selectedFeature; - } - } + this._handleClickFeatures(event, mVTFeatures); + if (this.selectedFeature != null) { + return this.selectedFeature; } - _handleClickFeature(event, mVTFeature) { - switch (mVTFeature.type) { - case 3:// polygon - this._handleClickFeaturePolygon(event, mVTFeature); - break; - default: { - this._handleClickFeatureDefault(event, mVTFeature); - break; - } - } + return this.selectedFeature; + } + + _handleClickFeatures(event, mVTFeatures) { + this.minDistance = Number.POSITIVE_INFINITY; + + for (let i = mVTFeatures.length - 1; i >= 0; i--) { + const mVTFeature = mVTFeatures[i]; + this._handleClickFeature(event, mVTFeature); + if (this.selectedFeature != null) { + return this.selectedFeature; + } } + } + + _handleClickFeature(event, mVTFeature) { + switch (mVTFeature.type) { + case 3:// polygon + this._handleClickFeaturePolygon(event, mVTFeature); + break; + default: { + this._handleClickFeatureDefault(event, mVTFeature); + break; + } + } + } - _handleClickFeaturePolygon(event, mVTFeature) { - if (mVTFeature.isPointInPath(event.tilePoint, event.tileContext)) { + _handleClickFeaturePolygon(event, mVTFeature) { + if (mVTFeature.isPointInPath(event.tilePoint, event.tileContext)) { + this.selectedFeature = mVTFeature; + this.minDistance = 0; + } + } + + _handleClickFeatureDefault(event, mVTFeature) { + const paths = mVTFeature.getPaths(event.tileContext); + for (let j = paths.length - 1; j >= 0; j--) { + const path = paths[j]; + switch (mVTFeature.type) { + case 1: // Point + if (MERCATOR.in_circle(path[0].x, path[0].y, mVTFeature.style.radius, event.tilePoint.x, event.tilePoint.y)) { this.selectedFeature = mVTFeature; this.minDistance = 0; - } - } - - _handleClickFeatureDefault(event, mVTFeature) { - var paths = mVTFeature.getPaths(event.tileContext); - for (var j = paths.length - 1; j >= 0; j--) { - var path = paths[j]; - switch (mVTFeature.type) { - case 1: // Point - if (MERCATOR.in_circle(path[0].x, path[0].y, mVTFeature.style.radius, event.tilePoint.x, event.tilePoint.y)) { - this.selectedFeature = mVTFeature; - this.minDistance = 0; - } - break; - case 2: // LineString - var distance = MERCATOR.getDistanceFromLine(event.tilePoint, path); - var thickness = (mVTFeature.selected && mVTFeature.style.selected ? mVTFeature.style.selected.lineWidth : mVTFeature.style.lineWidth); - if (distance < thickness / 2 + this._lineClickTolerance && distance < this.minDistance) { - this.selectedFeature = mVTFeature; - this.minDistance = distance; - } - break; - } - if (this.minDistance == 0) { - return this.selectedFeature; - } - } + } + break; + case 2: // LineString + var distance = MERCATOR.getDistanceFromLine(event.tilePoint, path); + var thickness = (mVTFeature.selected && mVTFeature.style.selected ? mVTFeature.style.selected.lineWidth : mVTFeature.style.lineWidth); + if (distance < thickness / 2 + this._lineClickTolerance && distance < this.minDistance) { + this.selectedFeature = mVTFeature; + this.minDistance = distance; + } + break; + } + if (this.minDistance == 0) { + return this.selectedFeature; + } } -}; \ No newline at end of file + } +} diff --git a/src/MVTSource.js b/src/MVTSource.js index ecbc1e6..655bd1d 100644 --- a/src/MVTSource.js +++ b/src/MVTSource.js @@ -1,505 +1,500 @@ /* - * Created by Jesús Barrio on 04/2021 + * Created by Jes�s Barrio on 04/2021 */ -class MVTSource { - constructor(map, options) { - var self = this; - this.map = map; - this._url = options.url || ""; //Url TO Vector Tile Source, - this._sourceMaxZoom = options.sourceMaxZoom || false; // Source maxzoom to enable overzoom - this._debug = options.debug || false; // Draw tiles lines and ids - this.getIDForLayerFeature = options.getIDForLayerFeature || function (feature) { - return feature.properties.id || feature.properties.Id || feature.properties.ID; - }; - this._visibleLayers = options.visibleLayers || false; // List of visible layers - this._xhrHeaders = options.xhrHeaders || {}; // Headers added to every url request - this._clickableLayers = options.clickableLayers || false; // List of layers that are clickable - this._filter = options.filter || false; // Filter features - this._cache = options.cache || false; // Load tiles in cache to avoid duplicated requests - this._tileSize = options.tileSize || 256; // Default tile size - this.tileSize = new google.maps.Size(this._tileSize, this._tileSize); - this.style = options.style || function (feature) { - var style = {}; - switch (feature.type) { - case 1: //'Point' - style.fillStyle = 'rgba(49,79,79,1)'; - style.radius = 5; - style.selected = { - fillStyle: 'rgba(255,255,0,0.5)', - radius: 6 - } - break; - case 2: //'LineString' - style.strokeStyle = 'rgba(136, 86, 167, 1)'; - style.lineWidth = 3; - style.selected = { - strokeStyle: 'rgba(255,25,0,0.5)', - lineWidth: 4 - } - break; - case 3: //'Polygon' - style.fillStyle = 'rgba(188, 189, 220, 0.5)'; - style.strokeStyle = 'rgba(136, 86, 167, 1)'; - style.lineWidth = 1; - style.selected = { - fillStyle: 'rgba(255,140,0,0.3)', - strokeStyle: 'rgba(255,140,0,1)', - lineWidth: 2 - } - break; - } - return style; - }; - this._customDraw = options.customDraw || false; - - this.mVTLayers = []; //Keep a list of the layers contained in the PBFs - this._tilesDrawn = []; // List of tiles drawn (when cache enabled) - this._visibleTiles = []; // tiles currently in the viewport - this._selectedFeatures = []; // list of selected features - if (options.selectedFeatures) { - this.setSelectedFeatures(options.selectedFeatures); - } - - this.map.addListener("zoom_changed", () => { - self._zoomChanged(); - }); - } - - getTile(coord, zoom, ownerDocument) { - var tileContext = this.drawTile(coord, zoom, ownerDocument); - this._setVisibleTile(tileContext); - return tileContext.canvas; - } - - releaseTile(canvas) { - //this._deleteVisibleTile(canvas.id); - } - - _zoomChanged() { - this._resetVisibleTiles(); - if (!this._cache) { - this._resetMVTLayers(); - } - } - - _resetMVTLayers() { - this.mVTLayers = []; - } - - _deleteVisibleTile(id) { - delete this._visibleTiles[id]; - } - - _resetVisibleTiles() { - this._visibleTiles = []; - } - - _setVisibleTile(tileContext) { - this._visibleTiles[tileContext.id] = tileContext; - } - - drawTile(coord, zoom, ownerDocument) { - var id = this.getTileId(zoom, coord.x, coord.y); - var tileContext = this._tilesDrawn[id]; - if (tileContext) { - return tileContext; - } - - tileContext = this._createTileContext(coord, zoom, ownerDocument); - this._xhrRequest(tileContext); - return tileContext; - } - - _createTileContext(coord, zoom, ownerDocument) { - var id = this.getTileId(zoom, coord.x, coord.y); - var canvas = this._createCanvas(ownerDocument, id); - var parentId = this._getParentId(id); - - return { - id: id, - canvas: canvas, - zoom: zoom, - tileSize: this._tileSize, - parentId: parentId - }; - } - - _getParentId(id) { - var parentId = false; - if (this._sourceMaxZoom) { - var tile = this.getTileObject(id); - if (tile.zoom > this._sourceMaxZoom) { - var zoomDistance = tile.zoom - this._sourceMaxZoom; - var zoom = tile.zoom - zoomDistance; - var x = tile.x >> zoomDistance; - var y = tile.y >> zoomDistance; - parentId = this.getTileId(zoom, x, y); - } +export class MVTSource { + constructor(map, options) { + const self = this; + this.map = map; + this._url = options.url || ''; // Url TO Vector Tile Source, + this._sourceMaxZoom = options.sourceMaxZoom || false; // Source maxzoom to enable overzoom + this._debug = options.debug || false; // Draw tiles lines and ids + this.getIDForLayerFeature = options.getIDForLayerFeature || function(feature) { + return feature.properties.id || feature.properties.Id || feature.properties.ID; + }; + this._visibleLayers = options.visibleLayers || false; // List of visible layers + this._xhrHeaders = options.xhrHeaders || {}; // Headers added to every url request + this._clickableLayers = options.clickableLayers || false; // List of layers that are clickable + this._filter = options.filter || false; // Filter features + this._cache = options.cache || false; // Load tiles in cache to avoid duplicated requests + this._tileSize = options.tileSize || 256; // Default tile size + this.tileSize = new google.maps.Size(this._tileSize, this._tileSize); + this.style = options.style || function(feature) { + const style = {}; + switch (feature.type) { + case 1: // 'Point' + style.fillStyle = 'rgba(49,79,79,1)'; + style.radius = 5; + style.selected = { + fillStyle: 'rgba(255,255,0,0.5)', + radius: 6, + }; + break; + case 2: // 'LineString' + style.strokeStyle = 'rgba(136, 86, 167, 1)'; + style.lineWidth = 3; + style.selected = { + strokeStyle: 'rgba(255,25,0,0.5)', + lineWidth: 4, + }; + break; + case 3: // 'Polygon' + style.fillStyle = 'rgba(188, 189, 220, 0.5)'; + style.strokeStyle = 'rgba(136, 86, 167, 1)'; + style.lineWidth = 1; + style.selected = { + fillStyle: 'rgba(255,140,0,0.3)', + strokeStyle: 'rgba(255,140,0,1)', + lineWidth: 2, + }; + break; + } + return style; + }; + this._customDraw = options.customDraw || false; + + this.mVTLayers = []; // Keep a list of the layers contained in the PBFs + this._tilesDrawn = []; // List of tiles drawn (when cache enabled) + this._visibleTiles = []; // tiles currently in the viewport + this._selectedFeatures = []; // list of selected features + if (options.selectedFeatures) { + this.setSelectedFeatures(options.selectedFeatures); + } + + this.map.addListener('zoom_changed', () => { + self._zoomChanged(); + }); + } + + getTile(coord, zoom, ownerDocument) { + const tileContext = this.drawTile(coord, zoom, ownerDocument); + this._setVisibleTile(tileContext); + return tileContext.canvas; + } + + releaseTile(canvas) { + // this._deleteVisibleTile(canvas.id); + } + + _zoomChanged() { + this._resetVisibleTiles(); + if (!this._cache) { + this._resetMVTLayers(); + } + } + + _resetMVTLayers() { + this.mVTLayers = []; + } + + _deleteVisibleTile(id) { + delete this._visibleTiles[id]; + } + + _resetVisibleTiles() { + this._visibleTiles = []; + } + + _setVisibleTile(tileContext) { + this._visibleTiles[tileContext.id] = tileContext; + } + + drawTile(coord, zoom, ownerDocument) { + const id = this.getTileId(zoom, coord.x, coord.y); + let tileContext = this._tilesDrawn[id]; + if (tileContext) { + return tileContext; + } + + tileContext = this._createTileContext(coord, zoom, ownerDocument); + this._xhrRequest(tileContext); + return tileContext; + } + + _createTileContext(coord, zoom, ownerDocument) { + const id = this.getTileId(zoom, coord.x, coord.y); + const canvas = this._createCanvas(ownerDocument, id); + const parentId = this._getParentId(id); + + return { + id: id, + canvas: canvas, + zoom: zoom, + tileSize: this._tileSize, + parentId: parentId, + }; + } + + _getParentId(id) { + let parentId = false; + if (this._sourceMaxZoom) { + const tile = this.getTileObject(id); + if (tile.zoom > this._sourceMaxZoom) { + const zoomDistance = tile.zoom - this._sourceMaxZoom; + const zoom = tile.zoom - zoomDistance; + const x = tile.x >> zoomDistance; + const y = tile.y >> zoomDistance; + parentId = this.getTileId(zoom, x, y); + } + } + return parentId; + } + + _createCanvas(ownerDocument, id) { + const canvas = ownerDocument.createElement('canvas'); + canvas.width = this._tileSize; + canvas.height = this._tileSize; + canvas.id = id; + return canvas; + } + + getTileId(zoom, x, y) { + return [zoom, x, y].join(':'); + } + + getTileObject(id) { + const values = id.split(':'); + return { + zoom: values[0], + x: values[1], + y: values[2], + }; + } + + _xhrRequest(tileContext) { + const self = this; + + const id = tileContext.parentId || tileContext.id; + const tile = this.getTileObject(id); + + const src = this._url + .replace('{z}', tile.zoom) + .replace('{x}', tile.x) + .replace('{y}', tile.y); + + const xmlHttpRequest = new XMLHttpRequest(); + xmlHttpRequest.onload = function() { + if (xmlHttpRequest.status == '200' && xmlHttpRequest.response) { + return self._xhrResponseOk(tileContext, xmlHttpRequest.response); + } + self._drawDebugInfo(tileContext); + }; + xmlHttpRequest.open('GET', src, true); + for (const header in this._xhrHeaders) { + xmlHttpRequest.setRequestHeader(header, this._xhrHeaders[header]); + } + xmlHttpRequest.responseType = 'arraybuffer'; + xmlHttpRequest.send(); + } + + _xhrResponseOk(tileContext, response) { + if (this.map.getZoom() != tileContext.zoom) { + return; + } + const uint8Array = new Uint8Array(response); + const pbf = new Pbf(uint8Array); + const vectorTile = new VectorTile(pbf); + this._drawVectorTile(vectorTile, tileContext); + } + + _setTileDrawn(tileContext) { + if (!this._cache) return; + this._tilesDrawn[tileContext.id] = tileContext; + } + + deleteTileDrawn(id) { + delete this._tilesDrawn[id]; + } + + _resetTileDrawn() { + this._tilesDrawn = []; + } + + _drawVectorTile(vectorTile, tileContext) { + if (this._visibleLayers) { + for (let i = 0, length = this._visibleLayers.length; i < length; i++) { + var key = this._visibleLayers[i]; + if (vectorTile.layers[key]) { + var vectorTileLayer = vectorTile.layers[key]; + this._drawVectorTileLayer(vectorTileLayer, key, tileContext); } - return parentId; - } - - _createCanvas(ownerDocument, id) { - const canvas = ownerDocument.createElement("canvas"); - canvas.width = this._tileSize; - canvas.height = this._tileSize; - canvas.id = id; - return canvas; - } - - getTileId(zoom, x, y) { - return [zoom, x, y].join(":"); - } - - getTileObject(id) { - var values = id.split(":"); - return { - zoom: values[0], - x: values[1], - y: values[2] - } - } - - _xhrRequest(tileContext) { - var self = this; - - var id = tileContext.parentId || tileContext.id; - var tile = this.getTileObject(id); - - var src = this._url - .replace("{z}", tile.zoom) - .replace("{x}", tile.x) - .replace("{y}", tile.y); - - var xmlHttpRequest = new XMLHttpRequest(); - xmlHttpRequest.onload = function () { - if (xmlHttpRequest.status == "200" && xmlHttpRequest.response) { - return self._xhrResponseOk(tileContext, xmlHttpRequest.response) - } - self._drawDebugInfo(tileContext); - }; - xmlHttpRequest.open('GET', src, true); - for (var header in this._xhrHeaders) { - xmlHttpRequest.setRequestHeader(header, this._xhrHeaders[header]); + } + } else { + for (var key in vectorTile.layers) { + var vectorTileLayer = vectorTile.layers[key]; + this._drawVectorTileLayer(vectorTileLayer, key, tileContext); + } + } + tileContext.vectorTile = vectorTile; + this._drawDebugInfo(tileContext); + this._setTileDrawn(tileContext); + } + + _drawVectorTileLayer(vectorTileLayer, key, tileContext) { + if (!this.mVTLayers[key]) { + this.mVTLayers[key] = this._createMVTLayer(key); + } + const mVTLayer = this.mVTLayers[key]; + mVTLayer.parseVectorTileFeatures(this, vectorTileLayer.parsedFeatures, tileContext); + } + + _createMVTLayer(key) { + const options = { + getIDForLayerFeature: this.getIDForLayerFeature, + filter: this._filter, + style: this.style, + name: key, + customDraw: this._customDraw, + }; + return new MVTLayer(options); + } + + _drawDebugInfo(tileContext) { + if (!this._debug) return; + const tile = this.getTileObject(tileContext.id); + const width = this._tileSize; + const height = this._tileSize; + const context2d = tileContext.canvas.getContext('2d'); + context2d.strokeStyle = '#000000'; + context2d.fillStyle = '#FFFF00'; + context2d.strokeRect(0, 0, width, height); + context2d.font = '12px Arial'; + context2d.fillRect(0, 0, 5, 5); + context2d.fillRect(0, height - 5, 5, 5); + context2d.fillRect(width - 5, 0, 5, 5); + context2d.fillRect(width - 5, height - 5, 5, 5); + context2d.fillRect(width / 2 - 5, height / 2 - 5, 10, 10); + context2d.strokeText(tileContext.zoom + ' ' + tile.x + ' ' + tile.y, width / 2 - 30, height / 2 - 10); + } + + onClick(event, callbackFunction, options) { + this._multipleSelection = (options && options.multipleSelection) || false; + options = this._getMouseOptions(options, false); + this._mouseEvent(event, callbackFunction, options); + } + + onMouseHover(event, callbackFunction, options) { + this._multipleSelection = false; + options = this._getMouseOptions(options, true); + this._mouseEvent(event, callbackFunction, options); + } + + _getMouseOptions(options, mouseHover) { + return { + mouseHover: mouseHover, + setSelected: options.setSelected || false, + toggleSelection: (options.toggleSelection === undefined || options.toggleSelection), + limitToFirstVisibleLayer: options.limitToFirstVisibleLayer || false, + delay: options.delay || 0, + }; + } + + _mouseEvent(event, callbackFunction, options) { + if (!event.pixel || !event.latLng) return; + + if (options.delay == 0) { + return this._mouseEventContinue(event, callbackFunction, options); + } + + this.event = event; + const me = this; + setTimeout(function() { + if (event != me.event) return; + me._mouseEventContinue(me.event, callbackFunction, options); + }, options.delay, event); + } + _mouseEventContinue(event, callbackFunction, options) { + callbackFunction = callbackFunction || function() { }; + const limitToFirstVisibleLayer = options.limitToFirstVisibleLayer || false; + const zoom = this.map.getZoom(); + const tile = MERCATOR.getTileAtLatLng(event.latLng, zoom); + const id = this.getTileId(tile.z, tile.x, tile.y); + const tileContext = this._visibleTiles[id]; + if (!tileContext) { + return; + } + event.tileContext = tileContext; + event.tilePoint = MERCATOR.fromLatLngToTilePoint(this.map, event); + + const clickableLayers = this._clickableLayers || Object.keys(this.mVTLayers) || []; + for (let i = clickableLayers.length - 1; i >= 0; i--) { + const key = clickableLayers[i]; + const layer = this.mVTLayers[key]; + if (layer) { + var event = layer.handleClickEvent(event, this); + this._mouseSelectedFeature(event, callbackFunction, options); + if (limitToFirstVisibleLayer && event.feature) { + break; } - xmlHttpRequest.responseType = 'arraybuffer'; - xmlHttpRequest.send(); - } - - _xhrResponseOk(tileContext, response) { - if (this.map.getZoom() != tileContext.zoom) { - return; - } - var uint8Array = new Uint8Array(response); - var pbf = new Pbf(uint8Array); - var vectorTile = new VectorTile(pbf); - this._drawVectorTile(vectorTile, tileContext); - } - - _setTileDrawn(tileContext) { - if (!this._cache) return; - this._tilesDrawn[tileContext.id] = tileContext; - } - - deleteTileDrawn(id) { - delete this._tilesDrawn[id]; - } - - _resetTileDrawn() { - this._tilesDrawn = []; - } - - _drawVectorTile(vectorTile, tileContext) { - if (this._visibleLayers) { - for (var i = 0, length = this._visibleLayers.length; i < length; i++) { - var key = this._visibleLayers[i]; - if (vectorTile.layers[key]) { - var vectorTileLayer = vectorTile.layers[key]; - this._drawVectorTileLayer(vectorTileLayer, key, tileContext); - } - } + } + } + } + + _mouseSelectedFeature(event, callbackFunction, options) { + if (options.setSelected) { + const feature = event.feature; + if (feature) { + if (options.mouseHover) { + if (!feature.selected) { + feature.select(); + } } else { - for (var key in vectorTile.layers) { - var vectorTileLayer = vectorTile.layers[key]; - this._drawVectorTileLayer(vectorTileLayer, key, tileContext); + if (options.toggleSelection) { + feature.toggle(); + } else { + if (!feature.selected) { + feature.select(); } + } } - tileContext.vectorTile = vectorTile; - this._drawDebugInfo(tileContext); - this._setTileDrawn(tileContext); - } - - _drawVectorTileLayer(vectorTileLayer, key, tileContext) { - if (!this.mVTLayers[key]) { - this.mVTLayers[key] = this._createMVTLayer(key); + } else { + if (options.mouseHover) { + this.deselectAllFeatures(); } - var mVTLayer = this.mVTLayers[key]; - mVTLayer.parseVectorTileFeatures(this, vectorTileLayer.parsedFeatures, tileContext); - } - - _createMVTLayer(key) { - var options = { - getIDForLayerFeature: this.getIDForLayerFeature, - filter: this._filter, - style: this.style, - name: key, - customDraw: this._customDraw - }; - return new MVTLayer(options); - } - - _drawDebugInfo(tileContext) { - if (!this._debug) return; - var tile = this.getTileObject(tileContext.id) - var width = this._tileSize; - var height = this._tileSize; - var context2d = tileContext.canvas.getContext('2d'); - context2d.strokeStyle = '#000000'; - context2d.fillStyle = '#FFFF00'; - context2d.strokeRect(0, 0, width, height); - context2d.font = "12px Arial"; - context2d.fillRect(0, 0, 5, 5); - context2d.fillRect(0, height - 5, 5, 5); - context2d.fillRect(width - 5, 0, 5, 5); - context2d.fillRect(width - 5, height - 5, 5, 5); - context2d.fillRect(width / 2 - 5, height / 2 - 5, 10, 10); - context2d.strokeText(tileContext.zoom + ' ' + tile.x + ' ' + tile.y, width / 2 - 30, height / 2 - 10); - } - - onClick(event, callbackFunction, options) { - this._multipleSelection = (options && options.multipleSelection) || false; - options = this._getMouseOptions(options, false); - this._mouseEvent(event, callbackFunction, options); - } - - onMouseHover(event, callbackFunction, options) { - this._multipleSelection = false; - options = this._getMouseOptions(options, true); - this._mouseEvent(event, callbackFunction, options); - } - - _getMouseOptions(options, mouseHover) { - return { - mouseHover: mouseHover, - setSelected: options.setSelected || false, - toggleSelection: (options.toggleSelection === undefined || options.toggleSelection), - limitToFirstVisibleLayer: options.limitToFirstVisibleLayer || false, - delay: options.delay || 0 + } + } + callbackFunction(event); + } + + deselectAllFeatures() { + const zoom = this.map.getZoom(); + const tilesToRedraw = []; + for (const featureId in this._selectedFeatures) { + const mVTFeature = this._selectedFeatures[featureId]; + if (!mVTFeature) continue; + mVTFeature.setSelected(false); + const tiles = mVTFeature.getTiles(); + for (const id in tiles) { + this.deleteTileDrawn(id); + const idObject = this.getTileObject(id); + if (idObject.zoom == zoom) { + tilesToRedraw[id] = true; } - } - - _mouseEvent(event, callbackFunction, options) { - if (!event.pixel || !event.latLng) return; - - if (options.delay == 0) { - return this._mouseEventContinue(event, callbackFunction, options); - } - - this.event = event; - var me = this; - setTimeout(function () { - if (event != me.event) return; - me._mouseEventContinue(me.event, callbackFunction, options); - }, options.delay, event); - - - } - _mouseEventContinue(event, callbackFunction, options) { - callbackFunction = callbackFunction || function () { }; - var limitToFirstVisibleLayer = options.limitToFirstVisibleLayer || false; - var zoom = this.map.getZoom(); - var tile = MERCATOR.getTileAtLatLng(event.latLng, zoom); - var id = this.getTileId(tile.z, tile.x, tile.y); - var tileContext = this._visibleTiles[id]; - if (!tileContext) { - return; - } - event.tileContext = tileContext; - event.tilePoint = MERCATOR.fromLatLngToTilePoint(this.map, event); - - var clickableLayers = this._clickableLayers || Object.keys(this.mVTLayers) || []; - for (var i = clickableLayers.length - 1; i >= 0; i--) { - var key = clickableLayers[i]; - var layer = this.mVTLayers[key]; - if (layer) { - var event = layer.handleClickEvent(event, this); - this._mouseSelectedFeature(event, callbackFunction, options); - if (limitToFirstVisibleLayer && event.feature) { - break; - } - } + } + } + this.redrawTiles(tilesToRedraw); + this._selectedFeatures = []; + } + + featureSelected(mVTFeature) { + if (!this._multipleSelection) { + this.deselectAllFeatures(); + } + this._selectedFeatures[mVTFeature.featureId] = mVTFeature; + } + + featureDeselected(mvtFeature) { + delete this._selectedFeatures[mvtFeature.featureId]; + } + + setSelectedFeatures(featuresIds) { + if (featuresIds.length > 1) { + this._multipleSelection = true; + } + this.deselectAllFeatures(); + for (let i = 0, length = featuresIds.length; i < length; i++) { + const featureId = featuresIds[i]; + this._selectedFeatures[featureId] = false; + for (const key in this.mVTLayers) { + this.mVTLayers[key].setSelected(featureId); + } + } + } + + isFeatureSelected(featureId) { + return this._selectedFeatures[featureId] != undefined; + } + + getSelectedFeatures() { + const selectedFeatures = []; + for (const featureId in this._selectedFeatures) { + selectedFeatures.push(this._selectedFeatures[featureId]); + } + return selectedFeatures; + } + + getSelectedFeaturesInTile(tileContextId) { + const selectedFeatures = []; + for (const featureId in this._selectedFeatures) { + const selectedFeature = this._selectedFeatures[featureId]; + for (const tile in selectedFeature.tiles) { + if (tile == tileContextId) { + selectedFeatures.push(selectedFeature); } + } } + return selectedFeatures; + } - _mouseSelectedFeature(event, callbackFunction, options) { - if (options.setSelected) { - var feature = event.feature; - if (feature) { - if (options.mouseHover) { - if (!feature.selected) { - feature.select(); - } - } - else { - if (options.toggleSelection) { - feature.toggle(); - } - else { - if (!feature.selected) { - feature.select(); - } - } - } - } - else { - if (options.mouseHover) { - this.deselectAllFeatures(); - } - } - } - callbackFunction(event); + setFilter(filter, redrawTiles) { + redrawTiles = (redrawTiles === undefined || redrawTiles); + this._filter = filter; + for (const key in this.mVTLayers) { + this.mVTLayers[key].setFilter(filter); } - - deselectAllFeatures() { - var zoom = this.map.getZoom(); - var tilesToRedraw = []; - for (var featureId in this._selectedFeatures) { - var mVTFeature = this._selectedFeatures[featureId]; - if (!mVTFeature) continue; - mVTFeature.setSelected(false); - var tiles = mVTFeature.getTiles(); - for (var id in tiles) { - this.deleteTileDrawn(id); - var idObject = this.getTileObject(id); - if (idObject.zoom == zoom) { - tilesToRedraw[id] = true; - } - } - } - this.redrawTiles(tilesToRedraw); - this._selectedFeatures = []; + if (redrawTiles) { + this.redrawAllTiles(); } + } - featureSelected(mVTFeature) { - if (!this._multipleSelection) { - this.deselectAllFeatures(); - } - this._selectedFeatures[mVTFeature.featureId] = mVTFeature; + setStyle(style, redrawTiles) { + redrawTiles = (redrawTiles === undefined || redrawTiles); + this.style = style; + for (const key in this.mVTLayers) { + this.mVTLayers[key].setStyle(style); } - featureDeselected(mvtFeature) { - delete this._selectedFeatures[mvtFeature.featureId]; + if (redrawTiles) { + this.redrawAllTiles(); } + } - setSelectedFeatures(featuresIds) { - if (featuresIds.length > 1) { - this._multipleSelection = true; - } - this.deselectAllFeatures(); - for (var i = 0, length = featuresIds.length; i < length; i++) { - var featureId = featuresIds[i]; - this._selectedFeatures[featureId] = false; - for (var key in this.mVTLayers) { - this.mVTLayers[key].setSelected(featureId); - } - } + setVisibleLayers(visibleLayers, redrawTiles) { + redrawTiles = (redrawTiles === undefined || redrawTiles); + this._visibleLayers = visibleLayers; + if (redrawTiles) { + this.redrawAllTiles(); } + } - isFeatureSelected(featureId) { - return this._selectedFeatures[featureId] != undefined; - } + getVisibleLayers() { + return this._visibleLayers; + } - getSelectedFeatures() { - var selectedFeatures = []; - for (var featureId in this._selectedFeatures) { - selectedFeatures.push(this._selectedFeatures[featureId]); - } - return selectedFeatures; - } - - getSelectedFeaturesInTile(tileContextId) { - var selectedFeatures = []; - for (var featureId in this._selectedFeatures) { - var selectedFeature = this._selectedFeatures[featureId]; - for (var tile in selectedFeature.tiles) { - if (tile == tileContextId) { - selectedFeatures.push(selectedFeature); - } - } - } - return selectedFeatures; - } - - setFilter(filter, redrawTiles) { - redrawTiles = (redrawTiles === undefined || redrawTiles); - this._filter = filter; - for (var key in this.mVTLayers) { - this.mVTLayers[key].setFilter(filter); - } - if (redrawTiles) { - this.redrawAllTiles(); - } - } - - setStyle(style, redrawTiles) { - redrawTiles = (redrawTiles === undefined || redrawTiles); - this.style = style - for (var key in this.mVTLayers) { - this.mVTLayers[key].setStyle(style); - } - - if (redrawTiles) { - this.redrawAllTiles(); - } - } + setClickableLayers(clickableLayers) { + this._clickableLayers = clickableLayers; + } - setVisibleLayers(visibleLayers, redrawTiles) { - redrawTiles = (redrawTiles === undefined || redrawTiles); - this._visibleLayers = visibleLayers; - if (redrawTiles) { - this.redrawAllTiles(); - } - } + redrawAllTiles() { + this._resetTileDrawn(); + this.redrawTiles(this._visibleTiles); + } - getVisibleLayers() { - return this._visibleLayers; + redrawTiles(tiles) { + for (const id in tiles) { + this.redrawTile(id); } + } - setClickableLayers(clickableLayers) { - this._clickableLayers = clickableLayers; - } - - redrawAllTiles() { - this._resetTileDrawn(); - this.redrawTiles(this._visibleTiles); - } + redrawTile(id) { + this.deleteTileDrawn(id); + const tileContext = this._visibleTiles[id]; + if (!tileContext || !tileContext.vectorTile) return; + this.clearTile(tileContext.canvas); + this._drawVectorTile(tileContext.vectorTile, tileContext); + } - redrawTiles(tiles) { - for (var id in tiles) { - this.redrawTile(id); - } - } - - redrawTile(id) { - this.deleteTileDrawn(id); - var tileContext = this._visibleTiles[id]; - if (!tileContext || !tileContext.vectorTile) return; - this.clearTile(tileContext.canvas); - this._drawVectorTile(tileContext.vectorTile, tileContext); - } - - clearTile(canvas) { - var context = canvas.getContext('2d'); - context.clearRect(0, 0, canvas.width, canvas.height); - } + clearTile(canvas) { + const context = canvas.getContext('2d'); + context.clearRect(0, 0, canvas.width, canvas.height); + } - setUrl(url, redrawTiles) { - redrawTiles = (redrawTiles === undefined || redrawTiles); - this._url = url; - this._resetMVTLayers(); - if (redrawTiles) { - this.redrawAllTiles(); - } + setUrl(url, redrawTiles) { + redrawTiles = (redrawTiles === undefined || redrawTiles); + this._url = url; + this._resetMVTLayers(); + if (redrawTiles) { + this.redrawAllTiles(); } -} \ No newline at end of file + } +} diff --git a/tests/MVTFeature.spec.js b/tests/MVTFeature.spec.js new file mode 100644 index 0000000..27e6782 --- /dev/null +++ b/tests/MVTFeature.spec.js @@ -0,0 +1,379 @@ +import {MVTFeature} from '@/MVTFeature.js'; +import {mockMVTSource, mockVectorTileFeatures, mockCanvas, mockContext} from './common-mocks'; + +const mockVectorTileFeature = mockVectorTileFeatures[0]; + +// This mocks Path2D of the Canvas API. +const mockAddPath = jest.fn(); +const mockMoveTo = jest.fn(); +const mockLineTo = jest.fn(); +class Path2D { + constructor() { + this.addPath = mockAddPath; + this.moveTo = mockMoveTo; + this.lineTo = mockLineTo; + } +} +global.Path2D = Path2D; + +const mockTile = { + divisor: 16, + vectorTileFeature: mockVectorTileFeature, + paths2d: { + closePath: jest.fn(), + }, +}; +const mockTileContext = { + id: 0, + tileSize: 4, + canvas: mockCanvas, +}; +const mockStyle = { + selected: false, + radius: 18, + fillStyle: true, + strokeStyle: true, +}; + +const mockDrawFn = jest.fn(); + +const mockOptions = () => ({ + mVTSource: mockMVTSource, + selected: true, + featureId: 'mock featureId', + style: mockStyle, + vectorTileFeature: mockVectorTileFeature, + tileContext: mockTileContext, + customDraw: mockDrawFn, +}); + +describe('MVTFeature', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + describe('Constructor', () => { + describe('Setting properties', () => { + it('sets base MVTFeature properties from options', () => { + const baseProperties = ['mVTSource', 'selected', 'featureId', 'style']; + const options = mockOptions(); + const mVTFeature = new MVTFeature(options); + + baseProperties.forEach((key) => expect(mVTFeature[key]).toBe(options[key])); + }); + it('starts with one tile', () => { + const mVTFeature = new MVTFeature(mockOptions()); + + expect(mVTFeature.tiles).toHaveLength(1); + }); + it('if selected, calls mVTSource.featureSelected with this feature', () => { + const mVTFeature = new MVTFeature(mockOptions()); + + expect(mockMVTSource.featureSelected).toHaveBeenCalledWith(mVTFeature); + }); + it('if not selected, does not call mVTSource.', () => { + const options = {...mockOptions(), selected: false}; + new MVTFeature(options); + + expect(mockMVTSource.featureSelected).not.toHaveBeenCalled(); + }); + }); + }); + describe('addTileFeature', () => { + it('adds the tile as expected', () => { + const mVTFeature = new MVTFeature(mockOptions()); + mVTFeature.addTileFeature(mockVectorTileFeature, mockTileContext); + + expect(mVTFeature.tiles[0]).toStrictEqual({ + vectorTileFeature: mockVectorTileFeature, + divisor: 16, + context2d: false, + paths2d: false, + }); + }); + it('creates a sparse `tiles` array if indices are skipped', () => { + const context = {id: 100, tileSize: 2}; + const mVTFeature = new MVTFeature(mockOptions()); + mVTFeature.addTileFeature(mockVectorTileFeature, context); + + expect(mVTFeature.tiles).toHaveLength(101); + // There will be two tiles (one from constructor, one from this test's call) + expect(Object.values(mVTFeature.tiles)).toHaveLength(2); + }); + }); + describe('redrawTiles', () => { + let mVTFeature; + beforeEach(() => { + mVTFeature = new MVTFeature(mockOptions()); + // Add six tiles for testing + for (let i = 1; i < 7; i++) { + mVTFeature.addTileFeature(mockVectorTileFeature, {...mockTileContext, id: i}); + } + }); + it('calls MVTSource.deleteTileDrawn for all tiles', () => { + mVTFeature.redrawTiles(); + + for (let i = 0; i < 7; i++) { + // It's called with the numbers as strings. + expect(mockMVTSource.deleteTileDrawn).toHaveBeenCalledWith(i.toString()); + } + }); + it('calls MVTSource.redrawTile only for tiles at current zoom', () => { + const expectedRedrawn = ['3', '5']; + const expectedNotRedrawn = ['0', '1', '2', '4', '6']; + + mVTFeature.redrawTiles(); + + expectedRedrawn.forEach((id) => + expect(mockMVTSource.redrawTile).toHaveBeenCalledWith(id), + ); + expectedNotRedrawn.forEach((id) => + expect(mockMVTSource.redrawTile).not.toHaveBeenCalledWith(id), + ); + }); + }); + describe('toggle', () => { + it('if feature is selected, calls MVTSource.featureDeselected with this feature', () => { + const mVTFeature = new MVTFeature({...mockOptions(), selected: true}); + jest.clearAllMocks(); + + mVTFeature.toggle(); + + expect(mockMVTSource.featureDeselected).toHaveBeenCalledWith(mVTFeature); + expect(mockMVTSource.featureSelected).not.toHaveBeenCalled(); + }); + it('if feature is not selected, calls MVTSource.featureSelected with this feature', () => { + const mVTFeature = new MVTFeature({...mockOptions(), selected: false}); + jest.clearAllMocks(); + + mVTFeature.toggle(); + + expect(mockMVTSource.featureSelected).toHaveBeenCalledWith(mVTFeature); + expect(mockMVTSource.featureDeselected).not.toHaveBeenCalled(); + }); + }); + describe('setSelected', () => { + it('sets the selected property on the feature', () => { + const mVTFeature = new MVTFeature(mockOptions()); + mVTFeature.setSelected(false); + + expect(mVTFeature.selected).toBe(false); + }); + it.each([true, false])('when setting to %s, does not call MVTSource methods', (value) => { + const mVTFeature = new MVTFeature({...mockOptions(), selected: !value}); + jest.clearAllMocks(); + + mVTFeature.setSelected(value); + + expect(mockMVTSource.featureSelected).not.toHaveBeenCalled(); + expect(mockMVTSource.featureDeselected).not.toHaveBeenCalled(); + }); + }); + describe('draw', () => { + it('calls the draw function with expected non-style arguments', () => { + const mVTFeature = new MVTFeature(mockOptions()); + const tile = mVTFeature.tiles[0]; + + mVTFeature.draw(mockTileContext); + + expect(mockDrawFn).toHaveBeenCalledWith( + mockTileContext, + tile, + expect.anything(), // style + mVTFeature, + ); + }); + it.each([ + {name: 'only feature is selected', featureSelected: false, styleSelected: true}, + {name: 'only style is selected', featureSelected: true, styleSelected: false}, + {name: 'neither feature nor style is selected', featureSelected: false, styleSelected: false}, + ])('When $name, calls the draw function with feature\'s style', ({featureSelected, styleSelected}) => { + const mVTFeature = new MVTFeature({ + ...mockOptions(), + selected: featureSelected, + style: {...mockStyle, selected: styleSelected}, + }); + const featureStyle = mVTFeature.style; + + mVTFeature.draw(mockTileContext); + + expect(mockDrawFn).toHaveBeenCalledWith(expect.anything(), expect.anything(), featureStyle, expect.anything()); + }); + it('When feature and style are selected, calls the draw function with style\'s selected', () => { + new MVTFeature({ + ...mockOptions(), + selected: true, + style: {...mockStyle, selected: true}, + }).draw(mockTileContext); + + expect(mockDrawFn).toHaveBeenCalledWith(expect.anything(), expect.anything(), true, expect.anything()); + }); + }); + describe('defaultDraw', () => { + it.each([ + {name: 'Point', type: 1, delegatee: 'drawPoint'}, + {name: 'LineString', type: 2, delegatee: 'drawLineString'}, + {name: 'Polygon', type: 3, delegatee: 'drawPolygon'}, + ])('when called with type $type ($name), delegates to $delegatee', ({type, delegatee}) => { + const mVTFeature = new MVTFeature({ + ...mockOptions(), + vectorTileFeature: {...mockVectorTileFeature, type}, + }); + mVTFeature.drawPoint = jest.fn(); + mVTFeature.drawLineString = jest.fn(); + mVTFeature.drawPolygon = jest.fn(); + const mockTile = 'foo'; + jest.clearAllMocks(); + + mVTFeature.defaultDraw(mockTileContext, mockTile, mockStyle); + + expect(mVTFeature[delegatee]).toHaveBeenCalledWith(mockTileContext, mockTile, mockStyle); + }); + }); + describe('drawPoint', () => { + it('calls the 2D canvas context functions as expected', () => { + new MVTFeature(mockOptions()) + .drawPoint(mockTileContext, mockTile, mockStyle); + + expect(mockCanvas.getContext).toHaveBeenCalledWith('2d'); + expect(mockContext().beginPath).toHaveBeenCalled(); + expect(mockContext().closePath).toHaveBeenCalled(); + expect(mockContext().fill).toHaveBeenCalled(); + expect(mockContext().stroke).toHaveBeenCalled(); + expect(mockContext().arc).toHaveBeenCalledWith(0.0625, 0.125, mockStyle.radius, 0, Math.PI * 2); + }); + it('calls the 2D canvas context with a radius of 3 by default', () => { + new MVTFeature(mockOptions()) + .drawPoint(mockTileContext, mockTile, {...mockStyle, radius: undefined}); + + expect(mockContext().arc).toHaveBeenCalledWith( + expect.anything(), expect.anything(), 3, expect.anything(), expect.anything(), + ); + }); + }); + describe('drawLineString', () => { + let mVTFeature; + beforeEach(() => { + mVTFeature = new MVTFeature(mockOptions()); + mVTFeature.drawCoordinates = jest.fn(); + jest.clearAllMocks(); + + mVTFeature.drawLineString(mockTileContext, mockTile, mockStyle); + }); + it('calls this.drawCoordinates with expected arguments', () => { + expect(mVTFeature.drawCoordinates).toHaveBeenCalledWith(mockTileContext, mockTile); + }); + it('calls the 2D canvas context functions as expected', () => { + expect(mockCanvas.getContext).toHaveBeenCalledWith('2d'); + expect(mockContext().stroke).toHaveBeenCalledWith(mockTile.paths2d); + }); + }); + describe('drawPolygon', () => { + let mVTFeature; + beforeEach(() => { + mVTFeature = new MVTFeature(mockOptions()); + mVTFeature.drawCoordinates = jest.fn(); + jest.clearAllMocks(); + }); + it('calls this.drawCoordinates with expected arguments', () => { + mVTFeature.drawPolygon(mockTileContext, mockTile, mockStyle); + + expect(mVTFeature.drawCoordinates).toHaveBeenCalledWith(mockTileContext, mockTile); + }); + it('calls closePath on the tile\'s paths2d', () => { + mVTFeature.drawPolygon(mockTileContext, mockTile, mockStyle); + + expect(mockTile.paths2d.closePath).toHaveBeenCalled(); + }); + const testConditions = [ + {fnName: 'fill', propName: 'fillStyle'}, + {fnName: 'stroke', propName: 'strokeStyle'}, + ]; + it.each(testConditions)('calls $fnName if style.$propName is true', ({fnName, propName}) => { + mVTFeature.drawPolygon(mockTileContext, mockTile, {...mockStyle, [propName]: true}); + + expect(mockContext()[fnName]).toHaveBeenCalledWith(mockTile.paths2d); + }); + it.each(testConditions)('doesn\'t call $fnName if style.$propName is false', ({fnName, propName}) => { + mVTFeature.drawPolygon(mockTileContext, mockTile, {...mockStyle, [propName]: false}); + + expect(mockContext()[fnName]).not.toHaveBeenCalled(); + }); + }); + describe('drawCoordinates', () => { + let tileCopy; + beforeEach(() => { + // Necessary because drawCoordinates mutates the tile. + tileCopy = {...mockTile}; + const mVTFeature = new MVTFeature(mockOptions()); + jest.clearAllMocks(); + + mVTFeature.drawCoordinates(mockTileContext, tileCopy); + }); + it('calls Path2D.moveTo with the point from first coordinates of each set', () => { + expect(mockMoveTo).toHaveBeenNthCalledWith(1, 0.0625, 0.125); + expect(mockMoveTo).toHaveBeenNthCalledWith(2, -0.125, 0.1875); + }); + it('calls Path2D.lineTo with points from other coordinates of each set', () => { + // First coordinate set. + expect(mockLineTo).toHaveBeenNthCalledWith(1, 0.125, 0.0625); + // Second coordinate set. + expect(mockLineTo).toHaveBeenNthCalledWith(2, 0, 0.1875); + expect(mockLineTo).toHaveBeenNthCalledWith(3, 0.1875, 0.1875); + }); + it('calls Path2D.addPath with the created Path2D', () => { + expect(mockAddPath).toHaveBeenCalledWith(expect.any(Path2D)); + }); + it('replaces the tile\'s Path2D with a new one', () => { + expect(mockTile.paths2d).not.toBe(tileCopy.paths2d); + }); + }); + describe('getPaths', () => { + it('returns expected array', () => { + const result = new MVTFeature(mockOptions()).getPaths(mockTileContext); + + expect(result).toStrictEqual([ + [ + {x: 0.0625, y: 0.125}, {x: 0.125, y: 0.0625}, + ], + [ + {x: -0.125, y: 0.1875}, {x: 0, y: 0.1875}, {x: 0.1875, y: 0.1875}, + ], + ]); + }); + }); + describe('getContext2d', () => { + it('retrieves the 2D context from the canvas', () => { + const mVTFeature = new MVTFeature(mockOptions()); + + mVTFeature.getContext2d(mockCanvas, mockStyle); + + expect(mockCanvas.getContext).toHaveBeenCalledWith('2d'); + }); + it('returns an object with expected properties copied from style', () => { + const mVTFeature = new MVTFeature(mockOptions()); + const testStyleProps = {fooProp: 'foo', barProp: 'bar'}; + + const result = mVTFeature.getContext2d(mockCanvas, {...mockStyle, ...testStyleProps}); + + expect(result).toStrictEqual(expect.objectContaining(testStyleProps)); + }); + it('does not copy `selected` from style to return value', () => { + const mVTFeature = new MVTFeature(mockOptions()); + + const result = mVTFeature.getContext2d(mockCanvas, {...mockStyle, selected: 'baz'}); + expect(result.selected).not.toBe('baz'); + }); + }); + describe('getPoint', () => { + it('returns expected value', () => { + const testCoords = {x: 97, y: 15}; + const result = new MVTFeature(mockOptions()).getPoint( + testCoords, + {...mockTileContext, id: 2, parentId: 1}, + 4, + ); + + expect(result).toStrictEqual({x: 93, y: 7}); + }); + }); +}); diff --git a/tests/MVTLayer.spec.js b/tests/MVTLayer.spec.js new file mode 100644 index 0000000..726337d --- /dev/null +++ b/tests/MVTLayer.spec.js @@ -0,0 +1,157 @@ +import {MVTLayer} from '@/MVTLayer.js'; +import {MVTFeature} from '@/MVTFeature.js'; +import {mockMVTSource, mockTileContext, mockVectorTileFeatures} from './common-mocks.js'; + +// TODO jest.mock does not seem to work at all like it does in Beyond Maps and I have +// no idea why. The MVTFeature class does _not_ get mocked by this line. +jest.mock('@/MVTFeature.js'); + +const mockStyle = jest.fn(() => 'style return'); +const mockDrawFn = jest.fn(); + +const mockOptions = () =>{ + let nextId = 123; + return { + getIDForLayerFeature: jest.fn(() => nextId++), + style: mockStyle, + name: 'Mock Name', + filter: jest.fn(() => true), + customDraw: mockDrawFn, + }; +}; + +describe('MVTLayer', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + describe('Constructor', () => { + it('Sets style and name properties from options', () => { + const options = mockOptions(); + const mVTLayer = new MVTLayer(options); + + expect(mVTLayer.style).toBe(options.style); + expect(mVTLayer.name).toBe(options.name); + }); + }); + describe('parseVectorTileFeatures', () => { + describe('Constructing MVTFeature', () => { + it('calls the MVTFeature constructor with expected options', () => { + const mVTLayer = new MVTLayer(mockOptions()); + mVTLayer.parseVectorTileFeatures(mockMVTSource, mockVectorTileFeatures.slice(0, 1), mockTileContext); + + // TODO this expect won't work until jest.mock() works. + // expect(MVTFeature).toHaveBeenCalledWith(expect.objectContaining({ + // mVTSource: mockMVTSource, + // vectorTileFeature: mockVectorTileFeatures[0], + // tileContext: mockTileContext, + // style: mockStyle, + // selected: false, // from MVTSource.isFeatureSelected + // featureId: 123, + // customDraw: mockDrawFn, + // })); + + expect(mVTLayer._mVTFeatures[123]).toStrictEqual(expect.any(MVTFeature)); + }); + it('creates one MVTFeature per VectorTileFeature supplied', () => { + const mVTLayer = new MVTLayer(mockOptions()); + mVTLayer.parseVectorTileFeatures(mockMVTSource, mockVectorTileFeatures, mockTileContext); + + expect(mVTLayer._mVTFeatures[123]).toStrictEqual(expect.any(MVTFeature)); + expect(mVTLayer._mVTFeatures[124]).toStrictEqual(expect.any(MVTFeature)); + expect(mVTLayer._mVTFeatures[125]).toBeUndefined(); + }); + it('if the getIDForLayerFeature function returns nothing, autoincrements MVTFeature IDs', () => { + const mVTLayer = new MVTLayer({...mockOptions(), getIDForLayerFeature: jest.fn()}); + mVTLayer.parseVectorTileFeatures(mockMVTSource, mockVectorTileFeatures, mockTileContext); + + expect(mVTLayer._mVTFeatures[0]).toStrictEqual(expect.any(MVTFeature)); + expect(mVTLayer._mVTFeatures[1]).toStrictEqual(expect.any(MVTFeature)); + expect(mVTLayer._mVTFeatures[2]).toBeUndefined(); + }); + it('does not add a MVTFeature if filter returns false', () => { + const mVTLayer = new MVTLayer({...mockOptions(), filter: jest.fn(() => false)}); + mVTLayer.parseVectorTileFeatures(mockMVTSource, mockVectorTileFeatures, mockTileContext); + + expect(mVTLayer._mVTFeatures).toHaveLength(0); + }); + it('calls MVTFeature.drawTile with tileContext', () => { + const mVTLayer = new MVTLayer(mockOptions()); + mVTLayer.drawTile = jest.fn(); + + mVTLayer.parseVectorTileFeatures(mockMVTSource, mockVectorTileFeatures, mockTileContext); + + expect(mVTLayer.drawTile).toHaveBeenCalledWith(mockTileContext); + }); + }); + describe('drawTile', () => { + let mVTLayer; + let features; + beforeEach(() => { + mVTLayer = new MVTLayer(mockOptions()); + mVTLayer.parseVectorTileFeatures(mockMVTSource, mockVectorTileFeatures, mockTileContext); + features = mVTLayer._mVTFeatures; + features.forEach((f) => f.draw = jest.fn()); + jest.clearAllMocks(); + }); + it('calls draw on each MVTFeature passing the tile context', () => { + mVTLayer.drawTile(mockTileContext); + + features.forEach(({draw}) => expect(draw).toHaveBeenCalledWith(mockTileContext)); + }); + it('when only first feature is selected, calls draw on it last', () => { + const [first, second] = features.slice(123, 125); + first.selected = true; + second.selected = false; + + mVTLayer.drawTile(mockTileContext); + + expect(second.draw.mock.invocationCallOrder[0]) + .toBeLessThan(first.draw.mock.invocationCallOrder[0]); + }); + it('when only second feature is selected, calls draw on it last', () => { + const [first, second] = features.slice(123, 125); + first.selected = false; + second.selected = true; + + mVTLayer.drawTile(mockTileContext); + + expect(first.draw.mock.invocationCallOrder[0]) + .toBeLessThan(second.draw.mock.invocationCallOrder[0]); + }); + }); + describe('getStyle', () => { + it('if MVTLayer\'s style is a function, call it on the passed-in feature', () => { + const mockFeature = {}; + const result = new MVTLayer(mockOptions()).getStyle(mockFeature); + + expect(mockStyle).toHaveBeenCalledWith(mockFeature); + expect(result).toBe('style return'); + }); + it('if MVTLayer\'s style is not a function, return it', () => { + const result = new MVTLayer({...mockOptions(), style: 'not a function'}).getStyle({}); + + expect(mockStyle).not.toHaveBeenCalled(); + expect(result).toBe('not a function'); + }); + }); + describe('setStyle', () => { + let mVTLayer; + beforeEach(() => { + mVTLayer = new MVTLayer(mockOptions()); + mVTLayer.parseVectorTileFeatures(mockMVTSource, mockVectorTileFeatures, mockTileContext); + }); + it('sets the MVTLayer\'s style property', () => { + mVTLayer.setStyle('new style'); + + expect(mVTLayer.style).toBe('new style'); + }); + it('calls setStyle on each feature', () => { + mVTLayer._mVTFeatures.forEach((f) => f.setStyle = jest.fn()); + + mVTLayer.setStyle('new style'); + + mVTLayer._mVTFeatures.forEach(({setStyle}) => expect(setStyle).toHaveBeenCalledWith('new style')); + }); + }); + }); +}); diff --git a/tests/MVTSource.spec.js b/tests/MVTSource.spec.js new file mode 100644 index 0000000..4aa7341 --- /dev/null +++ b/tests/MVTSource.spec.js @@ -0,0 +1,317 @@ +import {MVTSource} from '@/MVTSource'; +import {mockMap, mockCanvas, mockContext} from './common-mocks'; + +// TODO various functions access 'google' as a global. Refactor to use imports instead. +class Size { + constructor(size1, size2) { + this.size1 = size1; + this.size2 = size2; + } +} +global.google = { + maps: { + Size, + }, +}; + +const mockMVTFeature = { + featureId: 8, +}; + +const mockDrawFn = jest.fn(); + +const mockOptions = () => { + let nextId = 0; + return { + url: '', + sourceMaxZoom: 16, + debug: false, + getIDForLayerFeature: jest.fn(() => nextId++), + visibleLayers: undefined, + xhrHeaders: {}, + clickableLayers: undefined, + filter: jest.fn(), + cache: undefined, + tileSize: 128, + style: {}, + customDraw: mockDrawFn, + selectedFeatures: undefined, + }; +}; + +describe('MVTSource', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + describe('Constructor', () => { + it('sets MVTSource\'s map property', () => { + const map = mockMap(); + const mVTSource = new MVTSource(map, mockOptions()); + + expect(mVTSource.map).toBe(map); + }); + it('sets expected properties from options', () => { + const options = mockOptions(); + const mVTSource = new MVTSource(mockMap(), options); + + expect(mVTSource.getIDForLayerFeature).toBe(options.getIDForLayerFeature); + expect(mVTSource.tileSize).toStrictEqual(expect.any(Size)); + expect(mVTSource.tileSize.size1).toBe(options.tileSize); + expect(mVTSource.tileSize.size2).toBe(options.tileSize); + }); + // TODO something for setSelectedFeatures + it('registers a zoom_changed listener on the map', () => { + const map = mockMap(); + new MVTSource(map, mockOptions()); + + expect(map.addListener).toHaveBeenCalledWith('zoom_changed', expect.any(Function)); + }); + }); + describe('getTileId', () => { + it('returns expected id', () => { + const zoom = 10; + const x = 18; + const y = 28; + const mVTSource = new MVTSource(mockMap(), mockOptions()); + + expect(mVTSource.getTileId(zoom, x, y)).toBe('10:18:28'); + }); + }); + describe('getTileObject', () => { + it('returns expected object', () => { + const id = '8:55:143'; + const mVTSource = new MVTSource(mockMap(), mockOptions()); + + expect(mVTSource.getTileObject(id)).toStrictEqual({ + zoom: '8', + x: '55', + y: '143', + }); + }); + }); + describe('featureSelected', () => { + it('if multiple selection is disabled, calls MVTSource.deselectAllFeatures', () => { + const mVTSource = new MVTSource(mockMap(), mockOptions()); + mVTSource._multipleSelection = false; + mVTSource.deselectAllFeatures = jest.fn(); + + mVTSource.featureSelected(mockMVTFeature); + + expect(mVTSource.deselectAllFeatures).toHaveBeenCalled(); + }); + it('if multiple selection is enabled, does not call MVTSource.deselectAllFeatures', () => { + const mVTSource = new MVTSource(mockMap(), mockOptions()); + mVTSource._multipleSelection = true; + mVTSource.deselectAllFeatures = jest.fn(); + + mVTSource.featureSelected(mockMVTFeature); + + expect(mVTSource.deselectAllFeatures).not.toHaveBeenCalled(); + }); + it('adds the passed-in feature as a selected feature', () => { + const mVTSource = new MVTSource(mockMap(), mockOptions()); + mVTSource.featureSelected(mockMVTFeature); + + expect(mVTSource._selectedFeatures[mockMVTFeature.featureId]).toBe(mockMVTFeature); + }); + }); + describe('featureDeselected', () => { + it('removes the passed-in feature from selected features', () => { + const mVTSource = new MVTSource(mockMap(), mockOptions()); + mVTSource.featureSelected(mockMVTFeature); + jest.clearAllMocks(); + + mVTSource.featureDeselected(mockMVTFeature); + + expect(mVTSource._selectedFeatures[mockMVTFeature.featureId]).toBeUndefined(); + }); + }); + describe('setSelectedFeatures', () => { + const mockFeatureIds = [3, 4, 8]; + it('calls MVTSource.deselectAllFeatures', () => { + const mVTSource = new MVTSource(mockMap(), mockOptions()); + mVTSource.deselectAllFeatures = jest.fn(); + + mVTSource.setSelectedFeatures(mockFeatureIds); + + expect(mVTSource.deselectAllFeatures).toHaveBeenCalled(); + }); + it('enables multiple selection if more than one feature passed in', () => { + const mVTSource = new MVTSource(mockMap(), mockOptions()); + + mVTSource.setSelectedFeatures(mockFeatureIds); + + expect(mVTSource._multipleSelection).toBe(true); + }); + it('sets the passed-in features\' ids to false in selected features', () => { + const mVTSource = new MVTSource(mockMap(), mockOptions()); + + mVTSource.setSelectedFeatures(mockFeatureIds); + + expect(mVTSource._selectedFeatures[3]).toBe(false); + expect(mVTSource._selectedFeatures[4]).toBe(false); + expect(mVTSource._selectedFeatures[8]).toBe(false); + }); + }); + describe('getSelectedFeatures', () => { + it('returns expected non-sparse selected features array', () => { + const mVTSource = new MVTSource(mockMap(), mockOptions()); + mVTSource.setSelectedFeatures([9, 27, 101]); // sets entries to `false` + + expect(mVTSource.getSelectedFeatures()).toStrictEqual([false, false, false]); + }); + }); + describe('getSelectedFeaturesInTile', () => { + it('returns expected selected features', () => { + const mVTSource = new MVTSource(mockMap(), mockOptions()); + // Features at indices 1 and 3 have tiles at index 1. + mVTSource._selectedFeatures = [ + // eslint-disable-next-line no-sparse-arrays + {tiles: [,, true]}, {tiles: [, true, true]}, {tiles: [true]}, {tiles: [, true,,, true]}, + ]; + + const result = mVTSource.getSelectedFeaturesInTile(1); + + expect(result).toStrictEqual([mVTSource._selectedFeatures[1], mVTSource._selectedFeatures[3]]); + }); + }); + describe('setFilter', () => { + const mockNewFilter = jest.fn(); + it('sets the filter for all MVTLayers in MVTSource.mVTLayers', () => { + const mVTSource = new MVTSource(mockMap(), mockOptions()); + mVTSource.mVTLayers = [ + {setFilter: jest.fn()}, + {setFilter: jest.fn()}, + ]; + + mVTSource.setFilter(mockNewFilter, false); + + mVTSource.mVTLayers.forEach(({setFilter}) => expect(setFilter).toHaveBeenCalledWith(mockNewFilter)); + }); + it.each([ + {name: 'undefined', value: undefined}, + {name: 'truthy', value: 100}, + ])('calls MVTSource.redrawAllTiles if redraw tiles is $name', ({value}) => { + const mVTSource = new MVTSource(mockMap(), mockOptions()); + mVTSource.redrawAllTiles = jest.fn(); + + mVTSource.setFilter(mockNewFilter, value); + + expect(mVTSource.redrawAllTiles).toHaveBeenCalled(); + }); + it.each([ + {name: 'null', value: null}, + {name: 'zero', value: 0}, + ])('does not call MVTSource.redrawAllTiles if redraw tiles is $name', ({value}) => { + const mVTSource = new MVTSource(mockMap(), mockOptions()); + mVTSource.redrawAllTiles = jest.fn(); + + mVTSource.setFilter(mockNewFilter, value); + + expect(mVTSource.redrawAllTiles).not.toHaveBeenCalled(); + }); + }); + describe('setStyle', () => { + const mockNewStyle = jest.fn(); + it('sets the MVTSource\'s style property', () => { + const mVTSource = new MVTSource(mockMap(), mockOptions()); + + mVTSource.setStyle(mockNewStyle, false); + + expect(mVTSource.style).toBe(mockNewStyle); + }); + it('sets the style for all MVTLayers in MVTSource.mVTLayers', () => { + const mVTSource = new MVTSource(mockMap(), mockOptions()); + mVTSource.mVTLayers = [ + {setStyle: jest.fn()}, + {setStyle: jest.fn()}, + ]; + + mVTSource.setStyle(mockNewStyle, false); + + mVTSource.mVTLayers.forEach(({setStyle}) => expect(setStyle).toHaveBeenCalledWith(mockNewStyle)); + }); + it.each([ + {name: 'undefined', value: undefined}, + {name: 'truthy', value: 100}, + ])('calls MVTSource.redrawAllTiles if redraw tiles is $name', ({value}) => { + const mVTSource = new MVTSource(mockMap(), mockOptions()); + mVTSource.redrawAllTiles = jest.fn(); + + mVTSource.setStyle(mockNewStyle, value); + + expect(mVTSource.redrawAllTiles).toHaveBeenCalled(); + }); + it.each([ + {name: 'null', value: null}, + {name: 'zero', value: 0}, + ])('does not call MVTSource.redrawAllTiles if redraw tiles is $name', ({value}) => { + const mVTSource = new MVTSource(mockMap(), mockOptions()); + mVTSource.redrawAllTiles = jest.fn(); + + mVTSource.setStyle(mockNewStyle, value); + + expect(mVTSource.redrawAllTiles).not.toHaveBeenCalled(); + }); + }); + describe('setVisibleLayers', () => { + it.each([ + {name: 'undefined', value: undefined}, + {name: 'truthy', value: 100}, + ])('calls MVTSource.redrawAllTiles if redraw tiles is $name', ({value}) => { + const mVTSource = new MVTSource(mockMap(), mockOptions()); + mVTSource.redrawAllTiles = jest.fn(); + + mVTSource.setVisibleLayers('foo', value); + + expect(mVTSource.redrawAllTiles).toHaveBeenCalled(); + }); + it.each([ + {name: 'null', value: null}, + {name: 'zero', value: 0}, + ])('does not call MVTSource.redrawAllTiles if redraw tiles is $name', ({value}) => { + const mVTSource = new MVTSource(mockMap(), mockOptions()); + mVTSource.redrawAllTiles = jest.fn(); + + mVTSource.setVisibleLayers('foo', value); + + expect(mVTSource.redrawAllTiles).not.toHaveBeenCalled(); + }); + }); + describe('clearTile', () => { + it('retrieves the 2d canvas context', () => { + new MVTSource(mockMap(), mockOptions()).clearTile(mockCanvas); + + expect(mockCanvas.getContext).toHaveBeenCalledWith('2d'); + }); + it('calls 2d context\'s clearRect with expected arguments', () => { + new MVTSource(mockMap(), mockOptions()).clearTile(mockCanvas); + + expect(mockContext().clearRect).toHaveBeenCalledWith(0, 0, 512, 128); + }); + }); + describe('setUrl', () => { + it.each([ + {name: 'undefined', value: undefined}, + {name: 'truthy', value: 100}, + ])('calls MVTSource.redrawAllTiles if redraw tiles is $name', ({value}) => { + const mVTSource = new MVTSource(mockMap(), mockOptions()); + mVTSource.redrawAllTiles = jest.fn(); + + mVTSource.setUrl('foo', value); + + expect(mVTSource.redrawAllTiles).toHaveBeenCalled(); + }); + it.each([ + {name: 'null', value: null}, + {name: 'zero', value: 0}, + ])('does not call MVTSource.redrawAllTiles if redraw tiles is $name', ({value}) => { + const mVTSource = new MVTSource(mockMap(), mockOptions()); + mVTSource.redrawAllTiles = jest.fn(); + + mVTSource.setUrl('foo', value); + + expect(mVTSource.redrawAllTiles).not.toHaveBeenCalled(); + }); + }); +}); diff --git a/tests/Mercator.spec.js b/tests/Mercator.spec.js new file mode 100644 index 0000000..0e1c29f --- /dev/null +++ b/tests/Mercator.spec.js @@ -0,0 +1,387 @@ +import {initialize} from '@googlemaps/jest-mocks'; +import { + fromLatLngToPixels, + fromLatLngToPoint, + fromLatLngToTilePoint, + fromPointToLatLng, + getDistanceFromLine, + getTileAtLatLng, + getTileBounds, + inCircle, + isPointInPolygon, + normalizeTile, + projectPointOnLineSegment, +} from '../lib/mercator/Mercator.js'; + +initialize(); + +// TODO maybe use actual Google Maps API objects instead of mocks for more precise testing. +const mockLatLng = (lat = 0, lng = 0) => ({ + lat: () => lat, + lng: () => lng, +}); + +// TODO get rid of this class wrapper once this no longer needs to be class. +class MockLatLng { + constructor({lat, lng}) { + return mockLatLng(lat, lng); + } +} +// TODO fromLatLngToTilePoint accesses "google" as a global. This should be passed in or imported. +global.google = { + maps: { + LatLng: MockLatLng, + }, +}; + +const mockMap = () => ({ + getBounds: () => ({ + getNorthEast: () => ({lat: -15, lng: 30}), + getSouthWest: () => ({lat: 45, lng: -60}), + }), + getProjection: () => ({ + // Like the actual API function, this must work for both LatLng and LatLngLiteral arguments. + fromLatLngToPoint: ({lat, lng}) => { + if (lat instanceof Function) { + return {x: lat(), y: lng()}; + } else { + return {x: lat, y: lng}; + } + }, + }), + getZoom: () => 13, +}); + +const testLocations = [ + { + name: 'Kansas City', + latLng: mockLatLng(39.1, -94.58), + point: {x: 60.74311, y: 97.74630}, + pixel: {x: -48332.79999, y: -1020559.36}, + tiles: [ + { + tile: {x: 1, y: 3, z: 3}, + bounds: { + ne: {lat: 40.9799, lng: -90}, + sw: {lat: 0, lng: -135}, + }, + }, + { + tile: {x: 30, y: 48, z: 7}, + bounds: { + ne: {lat: 40.9799, lng: -92.8125}, + sw: {lat: 38.8226, lng: -95.625}, + }, + }, + { + tile: {x: 1943, y: 3127, z: 13}, + bounds: { + ne: {lat: 39.13006, lng: -94.57031}, + sw: {lat: 39.09596, lng: -94.61425}, + }, + }, + ], + }, + { + name: 'Sydney', + latLng: mockLatLng(-33.87, 151.21), + point: {x: 235.52711, y: 153.62464}, + pixel: {x: -646103.04, y: 992952.32000}, + tiles: [ + { + tile: {x: 7, y: 4, z: 3}, + bounds: { + ne: {lat: 0, lng: 180}, + sw: {lat: -40.9799, lng: 135}, + }, + }, + { + tile: {x: 117, y: 76, z: 7}, + bounds: { + ne: {lat: -31.95216, lng: 151.875}, + sw: {lat: -34.30714, lng: 149.0625}, + }, + }, + { + tile: {x: 7536, y: 4915, z: 13}, + bounds: { + ne: {lat: -33.83392, lng: 151.21582}, + sw: {lat: -33.87041, lng: 151.17188}, + }, + }, + ], + }, + { + name: 'Amsterdam', + latLng: mockLatLng(52.37, 4.89), + point: {x: 131.47733, y: 84.13152}, + pixel: {x: 60375.03999, y: -205701.12}, + tiles: [ + { + tile: {x: 4, y: 2, z: 3}, + bounds: { + ne: {lat: 66.51326, lng: 45}, + sw: {lat: 40.9799, lng: 0}, + }, + }, + { + tile: {x: 65, y: 42, z: 7}, + bounds: { + ne: {lat: 52.48278, lng: 5.625}, + sw: {lat: 50.73646, lng: 2.8125}, + }, + }, + { + tile: {x: 4207, y: 2692, z: 13}, + bounds: { + ne: {lat: 52.3756, lng: 4.92188}, + sw: {lat: 52.34876, lng: 4.87792}, + }, + }, + ], + }, + { + name: 'Quito', + latLng: mockLatLng(-0.22, -78.51), + point: {x: 72.17066, y: 128.15644}, + pixel: {x: -370442.24, y: -888913.92}, + tiles: [ + { + tile: {x: 2, y: 4, z: 3}, + bounds: { + ne: {lat: 0, lng: -45}, + sw: {lat: -40.9799, lng: -90}, + }, + }, + { + tile: {x: 36, y: 64, z: 7}, + bounds: { + ne: {lat: 0, lng: -75.9375}, + sw: {lat: -2.81137, lng: -78.75}, + }, + }, + { + tile: {x: 2309, y: 4101, z: 13}, + bounds: { + ne: {lat: -0.21973, lng: -78.48633}, + sw: {lat: -0.26367, lng: -78.53027}, + }, + }, + ], + }, +]; + +describe('Mercator.js', () => { + describe('fromLatLngToPoint', () => { + it.each(testLocations)('returns expected value for $name', ({latLng, point}) => { + const {x, y} = fromLatLngToPoint(latLng); + + expect(x).toBeCloseTo(point.x, 4); + expect(y).toBeCloseTo(point.y, 4); + }); + }); + describe('fromPointToLatLng', () => { + it.each(testLocations)('returns expected value for $name', ({latLng, point}) => { + const {lat, lng} = fromPointToLatLng(point); + + expect(lat).toBeCloseTo(latLng.lat(), 4); + expect(lng).toBeCloseTo(latLng.lng(), 4); + }); + }); + describe('getTileAtLatLng', () => { + describe.each([3, 7, 13])('At zoom level %s', (zoom) => { + it.each(testLocations)('returns expected value for $name', ({latLng, tiles}) => { + const tile = getTileAtLatLng(latLng, zoom); + const expectedTile = tiles.find(({tile}) => tile.z === zoom).tile; + + expect(tile).toStrictEqual(expectedTile); + }); + }); + it('returns a tile with `z` equal to the zoom level', () => { + const latLng = mockLatLng(-15, 25); + + for (let zoom = 1; zoom < 16; zoom++) { + expect(getTileAtLatLng(latLng, zoom).z).toBe(zoom); + } + }); + }); + describe('getTileBounds', () => { + describe.each([3, 7, 13])('At zoom level %s', (zoom) => { + it.each(testLocations)('returns expected value for $name', ({tiles}) => { + const {tile, bounds: expectedBounds} = tiles.find(({tile}) => tile.z === zoom); + const bounds = getTileBounds(tile); + + expect(bounds.ne.lat).toBeCloseTo(expectedBounds.ne.lat, 4); + expect(bounds.ne.lng).toBeCloseTo(expectedBounds.ne.lng, 4); + expect(bounds.sw.lat).toBeCloseTo(expectedBounds.sw.lat, 4); + expect(bounds.sw.lng).toBeCloseTo(expectedBounds.sw.lng, 4); + }); + }); + }); + describe('normalizeTile', () => { + const trueMadridTile = {x: 4011, y: 3088, z: 13}; + const parallelUniverseMadrids = () => [ + {world: 'Earth 1', tile: {x: 12203, y: 3088, z: 13}}, + {world: 'Earth 4', tile: {x: 36779, y: 3088, z: 13}}, + {world: 'Earth -2', tile: {x: -12373, y: 3088, z: 13}}, + ]; + it.each(parallelUniverseMadrids())('normalizes Madrid in $world to correct value', ({tile}) => { + const normalizedTile = normalizeTile(tile); + + expect(normalizedTile).toStrictEqual(trueMadridTile); + }); + // TODO normalizeTile ought to be made a pure function. Once that's done, invert this test. + it('returns the argument, mutated', () => { + const earth1MadridTile = parallelUniverseMadrids()[0].tile; + const normalizedTile = normalizeTile(earth1MadridTile); + + expect(normalizedTile).toBe(earth1MadridTile); + }); + }); + describe('fromLatLngToPixels', () => { + it.each(testLocations)('returns expected value for $name', ({latLng, pixel}) => { + const {x, y} = fromLatLngToPixels(mockMap(), latLng); + + expect(x).toBeCloseTo(pixel.x, 4); + expect(y).toBeCloseTo(pixel.y, 4); + }); + }); + describe('fromLatLngToTilePoint', () => { + const mockEvt = { + pixel: {x: 55, y: -165}, + latLng: {lat: () => -90.8105, lng: () => 71.4541}, + }; + + it('returns expected value', () => { + const {x, y} = fromLatLngToTilePoint(mockMap(), mockEvt); + + expect(x).toBeCloseTo(-126215.27845, 4); + expect(y).toBeCloseTo(-339765, 4); + }); + }); + describe('isPointInPolygon', () => { + const polygonTests = [ + { + name: 'a 1x1 square about the origin', + polygon: [ + {x: -1, y: 1}, + {x: 1, y: 1}, + {x: 1, y: -1}, + {x: -1, y: -1}, + ], + inside: {x: 0, y: 0}, + outside: {x: 0, y: 2}, + }, + { + name: 'a twisted 1x1 cross-quadrilateral about the origin', + polygon: [ + {x: -1, y: 1}, + {x: 1, y: -1}, + {x: -1, y: -1}, + {x: 1, y: 1}, + ], + inside: {x: .5, y: .75}, + outside: {x: .5, y: .25}, + }, + { + name: 'a polygon with hole in the middle', + polygon: [ + {x: -1, y: 1}, + {x: 1, y: 1}, + {x: 1, y: -1}, + {x: -2, y: -1}, + {x: -2, y: 2}, + {x: 2, y: 2}, + {x: 2, y: -2}, + {x: -3, y: -2}, + ], + inside: {x: 1.5, y: 1.5}, + outside: {x: 0, y: 0}, + }, + ]; + describe.each(polygonTests)('For $name', ({polygon, inside, outside}) => { + it('returns true for a point inside the polygon', () => { + expect(isPointInPolygon(inside, polygon)).toBe(true); + }); + it('returns false for a point outside the polygon', () => { + expect(isPointInPolygon(outside, polygon)).toBe(false); + }); + }); + it('returns undefined if polygon is not supplied', () => { + expect(isPointInPolygon({x: 0, y: 0})).toBeUndefined(); + }); + it('returns undefined if polygon has no points', () => { + expect(isPointInPolygon({x: 0, y: 0}, [])).toBeUndefined(); + }); + }); + describe('inCircle', () => { + it('returns true for a point in the circle', () => { + expect(inCircle(1, 1, 2, 2, 2)).toBe(true); + }); + it('returns false for a point outside the circle', () => { + expect(inCircle(-2, 3, 4, 2, 0)).toBe(false); + }); + it('returns true for a point on the edge of the circle', () => { + expect(inCircle(0, 1, 2, 0, 3)).toBe(true); + }); + it('returns true for the center of the circle', () => { + expect(inCircle(0, 0, 0, 0, 0)).toBe(true); + }); + }); + const lineTests = [ + { + name: 'a two-vertex line', + line: [ + {x: -1, y: 0}, + {x: 1, y: 0}, + ], + points: [ + {point: {x: 0, y: 1}, distance: 1}, + {point: {x: 2, y: 0}, distance: 1}, + {point: {x: 0, y: 0}, distance: 0}, + ], + }, + { + name: 'a triangle', + line: [ + {x: 0, y: 0}, + {x: 1, y: 0}, + {x: 0, y: 1}, + ], + points: [ + {point: {x: 1, y: 1}, distance: Math.sqrt(.5)}, + {point: {x: .5, y: 0}, distance: 0}, + {point: {x: 0, y: 10}, distance: 9}, + ], + }, + { + name: 'a line with duplicate vertices', + line: [ + {x: 0, y: 0}, + {x: 0, y: 0}, + {x: 2, y: 0}, + {x: 2, y: 0}, + {x: 2, y: 0}, + ], + points: [ + {point: {x: 1, y: 0}, distance: 0}, + {point: {x: 2, y: -2}, distance: 2}, + ], + }, + ]; + describe('getDistanceFromLine', () => { + describe.each(lineTests)('For $name', ({line, points}) => { + it.each(points)('returns $distance for point $point', ({distance, point}) => { + expect(getDistanceFromLine(point, line)).toBe(distance); + }); + }); + }); + describe('projectPointOnLineSegment', () => { + const twoVertexTests = lineTests.filter((t) => t.line.length === 2); + describe.each(twoVertexTests)('For $name', ({line, points}) => { + it.each(points)('returns $distance for point $point', ({distance, point}) => { + expect(projectPointOnLineSegment(point, line[0], line[1])).toBe(distance); + }); + }); + }); +}); diff --git a/tests/common-mocks.js b/tests/common-mocks.js new file mode 100644 index 0000000..544e53b --- /dev/null +++ b/tests/common-mocks.js @@ -0,0 +1,94 @@ +// Google Maps API map mock +const mockAddListener = jest.fn(); +export const mockMap = () => ({ + getBounds: () => ({ + getNorthEast: () => ({lat: -15, lng: 30}), + getSouthWest: () => ({lat: 45, lng: -60}), + }), + getProjection: () => ({ + // Like the actual API function, this must work for both LatLng and LatLngLiteral arguments. + fromLatLngToPoint: ({lat, lng}) => { + if (lat instanceof Function) { + return {x: lat(), y: lng()}; + } else { + return {x: lat, y: lng}; + } + }, + }), + getZoom: () => 13, + addListener: mockAddListener, +}); + +// Mock of MVTSource for use in testing other classes +export const mockMVTSource = { + isFeatureSelected: jest.fn(() => false), + featureSelected: jest.fn(), + featureDeselected: jest.fn(), + deleteTileDrawn: jest.fn(), + getTileObject: jest.fn((id) => [ + {zoom: 3}, + {zoom: 5, x: 1, y: 3}, + {zoom: 7, x: 5, y: 10}, + {zoom: 13}, + {zoom: 15}, + {zoom: 13}, + {zoom: 7}, + ][id]), + redrawTile: jest.fn(), + map: mockMap(), +}; + +export const mockVectorTileFeatures = [ + { + extent: 64, + type: 1, + properties: 'mock vector tile props', + // I don't fully understand what the shape of `coordinates` is supposed to be, + // but this satisfies the functions that use it. + coordinates: [ + [ + {x: 1, y: 2}, {x: 2, y: 1}, + ], + [ + {x: -2, y: 3}, {x: 0, y: 3}, {x: 3, y: 3}, + ], + ], + }, + { + extent: 32, + type: 2, + properties: 'mock props', + coordinates: [ + [{x: 0, y: 0}, {x: 3, y: 1}, {x: 5, y: -2}], + ], + }, +]; + +// These need to be the same across calls to mockContext. +const mockBeginPath = jest.fn(); +const mockClosePath = jest.fn(); +const mockArc = jest.fn(); +const mockFill = jest.fn(); +const mockStroke = jest.fn(); +const mockClearRect = jest.fn(); + +export const mockContext = () => ({ + beginPath: mockBeginPath, + closePath: mockClosePath, + arc: mockArc, + fill: mockFill, + stroke: mockStroke, + clearRect: mockClearRect, +}); + +export const mockCanvas = { + width: 512, + height: 128, + getContext: jest.fn(() => mockContext()), +}; + +export const mockTileContext = { + id: 0, + tileSize: 4, + canvas: mockCanvas, +}; diff --git a/tests/helloWorld.spec.js b/tests/helloWorld.spec.js deleted file mode 100644 index d8e06c9..0000000 --- a/tests/helloWorld.spec.js +++ /dev/null @@ -1,5 +0,0 @@ -describe('Making sure Jest works', () => { - it('works', () => { - expect(undefined).toBeUndefined(); - }); -}); diff --git a/tests/setup.js b/tests/setup.js new file mode 100644 index 0000000..5d69524 --- /dev/null +++ b/tests/setup.js @@ -0,0 +1,3 @@ +import {jest} from '@jest/globals'; +// Required to register global 'jest' while also supporting ES modules. +global.jest = jest; From 9da567b81e8eb118da3cc27b16430b75962a9be2 Mon Sep 17 00:00:00 2001 From: camden-obertop <52179320+camden-obertop@users.noreply.github.com> Date: Wed, 8 Feb 2023 09:38:27 -0600 Subject: [PATCH 03/11] BMAPS-1692 Removed Protobuf and added it as a dependency (#4) * Started removing protobuf * Added Vite * remove default from mvtlayer * undid previous thing --- dist/vector-tiles-google-maps.js | 1 - lib/protobuf/Protobuf.js | 1 - lib/vectortiles/Point.js | 4 +- lib/vectortiles/VectorTile.js | 8 +- lib/vectortiles/VectorTileFeature.js | 8 +- lib/vectortiles/VectorTileLayer.js | 8 +- package-lock.json | 74 ++ package.json | 5 +- src/MVTLayer.js | 5 +- src/MVTSource.js | 4 +- vector-tiles-google-maps/.gitignore | 24 + vector-tiles-google-maps/index.html | 9 + vector-tiles-google-maps/main.js | 3 + vector-tiles-google-maps/package-lock.json | 890 +++++++++++++++++++++ vector-tiles-google-maps/package.json | 13 + 15 files changed, 1043 insertions(+), 14 deletions(-) delete mode 100644 lib/protobuf/Protobuf.js create mode 100644 vector-tiles-google-maps/.gitignore create mode 100644 vector-tiles-google-maps/index.html create mode 100644 vector-tiles-google-maps/main.js create mode 100644 vector-tiles-google-maps/package-lock.json create mode 100644 vector-tiles-google-maps/package.json diff --git a/dist/vector-tiles-google-maps.js b/dist/vector-tiles-google-maps.js index c0c2df9..21236db 100644 --- a/dist/vector-tiles-google-maps.js +++ b/dist/vector-tiles-google-maps.js @@ -1,4 +1,3 @@ -!function (t) { if ("object" == typeof exports && "undefined" != typeof module) module.exports = t(); else if ("function" == typeof define && define.amd) define([], t); else { var i; i = "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof self ? self : this, i.Pbf = t() } }(function () { return function t(i, e, r) { function s(o, h) { if (!e[o]) { if (!i[o]) { var a = "function" == typeof require && require; if (!h && a) return a(o, !0); if (n) return n(o, !0); var u = new Error("Cannot find module '" + o + "'"); throw u.code = "MODULE_NOT_FOUND", u } var f = e[o] = { exports: {} }; i[o][0].call(f.exports, function (t) { var e = i[o][1][t]; return s(e ? e : t) }, f, f.exports, t, i, e, r) } return e[o].exports } for (var n = "function" == typeof require && require, o = 0; o < r.length; o++)s(r[o]); return s }({ 1: [function (t, i, e) { "use strict"; function r(t) { this.buf = ArrayBuffer.isView && ArrayBuffer.isView(t) ? t : new Uint8Array(t || 0), this.pos = 0, this.type = 0, this.length = this.buf.length } function s(t, i, e) { var r, s, n = e.buf; if (s = n[e.pos++], r = (112 & s) >> 4, s < 128) return o(t, r, i); if (s = n[e.pos++], r |= (127 & s) << 3, s < 128) return o(t, r, i); if (s = n[e.pos++], r |= (127 & s) << 10, s < 128) return o(t, r, i); if (s = n[e.pos++], r |= (127 & s) << 17, s < 128) return o(t, r, i); if (s = n[e.pos++], r |= (127 & s) << 24, s < 128) return o(t, r, i); if (s = n[e.pos++], r |= (1 & s) << 31, s < 128) return o(t, r, i); throw new Error("Expected varint not more than 10 bytes") } function n(t) { return t.type === r.Bytes ? t.readVarint() + t.pos : t.pos + 1 } function o(t, i, e) { return e ? 4294967296 * i + (t >>> 0) : 4294967296 * (i >>> 0) + (t >>> 0) } function h(t, i) { var e, r; if (t >= 0 ? (e = t % 4294967296 | 0, r = t / 4294967296 | 0) : (e = ~(-t % 4294967296), r = ~(-t / 4294967296), 4294967295 ^ e ? e = e + 1 | 0 : (e = 0, r = r + 1 | 0)), t >= 0x10000000000000000 || t < -0x10000000000000000) throw new Error("Given varint doesn't fit into 10 bytes"); i.realloc(10), a(e, r, i), u(r, i) } function a(t, i, e) { e.buf[e.pos++] = 127 & t | 128, t >>>= 7, e.buf[e.pos++] = 127 & t | 128, t >>>= 7, e.buf[e.pos++] = 127 & t | 128, t >>>= 7, e.buf[e.pos++] = 127 & t | 128, t >>>= 7, e.buf[e.pos] = 127 & t } function u(t, i) { var e = (7 & t) << 4; i.buf[i.pos++] |= e | ((t >>>= 3) ? 128 : 0), t && (i.buf[i.pos++] = 127 & t | ((t >>>= 7) ? 128 : 0), t && (i.buf[i.pos++] = 127 & t | ((t >>>= 7) ? 128 : 0), t && (i.buf[i.pos++] = 127 & t | ((t >>>= 7) ? 128 : 0), t && (i.buf[i.pos++] = 127 & t | ((t >>>= 7) ? 128 : 0), t && (i.buf[i.pos++] = 127 & t))))) } function f(t, i, e) { var r = i <= 16383 ? 1 : i <= 2097151 ? 2 : i <= 268435455 ? 3 : Math.ceil(Math.log(i) / (7 * Math.LN2)); e.realloc(r); for (var s = e.pos - 1; s >= t; s--)e.buf[s + r] = e.buf[s] } function d(t, i) { for (var e = 0; e < t.length; e++)i.writeVarint(t[e]) } function p(t, i) { for (var e = 0; e < t.length; e++)i.writeSVarint(t[e]) } function c(t, i) { for (var e = 0; e < t.length; e++)i.writeFloat(t[e]) } function l(t, i) { for (var e = 0; e < t.length; e++)i.writeDouble(t[e]) } function w(t, i) { for (var e = 0; e < t.length; e++)i.writeBoolean(t[e]) } function F(t, i) { for (var e = 0; e < t.length; e++)i.writeFixed32(t[e]) } function b(t, i) { for (var e = 0; e < t.length; e++)i.writeSFixed32(t[e]) } function v(t, i) { for (var e = 0; e < t.length; e++)i.writeFixed64(t[e]) } function g(t, i) { for (var e = 0; e < t.length; e++)i.writeSFixed64(t[e]) } function x(t, i) { return (t[i] | t[i + 1] << 8 | t[i + 2] << 16) + 16777216 * t[i + 3] } function V(t, i, e) { t[e] = i, t[e + 1] = i >>> 8, t[e + 2] = i >>> 16, t[e + 3] = i >>> 24 } function y(t, i) { return (t[i] | t[i + 1] << 8 | t[i + 2] << 16) + (t[i + 3] << 24) } function M(t, i, e) { for (var r = "", s = i; s < e;) { var n = t[s], o = null, h = n > 239 ? 4 : n > 223 ? 3 : n > 191 ? 2 : 1; if (s + h > e) break; var a, u, f; 1 === h ? n < 128 && (o = n) : 2 === h ? (a = t[s + 1], 128 === (192 & a) && (o = (31 & n) << 6 | 63 & a, o <= 127 && (o = null))) : 3 === h ? (a = t[s + 1], u = t[s + 2], 128 === (192 & a) && 128 === (192 & u) && (o = (15 & n) << 12 | (63 & a) << 6 | 63 & u, (o <= 2047 || o >= 55296 && o <= 57343) && (o = null))) : 4 === h && (a = t[s + 1], u = t[s + 2], f = t[s + 3], 128 === (192 & a) && 128 === (192 & u) && 128 === (192 & f) && (o = (15 & n) << 18 | (63 & a) << 12 | (63 & u) << 6 | 63 & f, (o <= 65535 || o >= 1114112) && (o = null))), null === o ? (o = 65533, h = 1) : o > 65535 && (o -= 65536, r += String.fromCharCode(o >>> 10 & 1023 | 55296), o = 56320 | 1023 & o), r += String.fromCharCode(o), s += h } return r } function S(t, i, e) { for (var r, s, n = 0; n < i.length; n++) { if (r = i.charCodeAt(n), r > 55295 && r < 57344) { if (!s) { r > 56319 || n + 1 === i.length ? (t[e++] = 239, t[e++] = 191, t[e++] = 189) : s = r; continue } if (r < 56320) { t[e++] = 239, t[e++] = 191, t[e++] = 189, s = r; continue } r = s - 55296 << 10 | r - 56320 | 65536, s = null } else s && (t[e++] = 239, t[e++] = 191, t[e++] = 189, s = null); r < 128 ? t[e++] = r : (r < 2048 ? t[e++] = r >> 6 | 192 : (r < 65536 ? t[e++] = r >> 12 | 224 : (t[e++] = r >> 18 | 240, t[e++] = r >> 12 & 63 | 128), t[e++] = r >> 6 & 63 | 128), t[e++] = 63 & r | 128) } return e } i.exports = r; var B = t("ieee754"); r.Varint = 0, r.Fixed64 = 1, r.Bytes = 2, r.Fixed32 = 5; var k = 4294967296, P = 1 / k; r.prototype = { destroy: function () { this.buf = null }, readFields: function (t, i, e) { for (e = e || this.length; this.pos < e;) { var r = this.readVarint(), s = r >> 3, n = this.pos; this.type = 7 & r, t(s, i, this), this.pos === n && this.skip(r) } return i }, readMessage: function (t, i) { return this.readFields(t, i, this.readVarint() + this.pos) }, readFixed32: function () { var t = x(this.buf, this.pos); return this.pos += 4, t }, readSFixed32: function () { var t = y(this.buf, this.pos); return this.pos += 4, t }, readFixed64: function () { var t = x(this.buf, this.pos) + x(this.buf, this.pos + 4) * k; return this.pos += 8, t }, readSFixed64: function () { var t = x(this.buf, this.pos) + y(this.buf, this.pos + 4) * k; return this.pos += 8, t }, readFloat: function () { var t = B.read(this.buf, this.pos, !0, 23, 4); return this.pos += 4, t }, readDouble: function () { var t = B.read(this.buf, this.pos, !0, 52, 8); return this.pos += 8, t }, readVarint: function (t) { var i, e, r = this.buf; return e = r[this.pos++], i = 127 & e, e < 128 ? i : (e = r[this.pos++], i |= (127 & e) << 7, e < 128 ? i : (e = r[this.pos++], i |= (127 & e) << 14, e < 128 ? i : (e = r[this.pos++], i |= (127 & e) << 21, e < 128 ? i : (e = r[this.pos], i |= (15 & e) << 28, s(i, t, this))))) }, readVarint64: function () { return this.readVarint(!0) }, readSVarint: function () { var t = this.readVarint(); return t % 2 === 1 ? (t + 1) / -2 : t / 2 }, readBoolean: function () { return Boolean(this.readVarint()) }, readString: function () { var t = this.readVarint() + this.pos, i = M(this.buf, this.pos, t); return this.pos = t, i }, readBytes: function () { var t = this.readVarint() + this.pos, i = this.buf.subarray(this.pos, t); return this.pos = t, i }, readPackedVarint: function (t, i) { var e = n(this); for (t = t || []; this.pos < e;)t.push(this.readVarint(i)); return t }, readPackedSVarint: function (t) { var i = n(this); for (t = t || []; this.pos < i;)t.push(this.readSVarint()); return t }, readPackedBoolean: function (t) { var i = n(this); for (t = t || []; this.pos < i;)t.push(this.readBoolean()); return t }, readPackedFloat: function (t) { var i = n(this); for (t = t || []; this.pos < i;)t.push(this.readFloat()); return t }, readPackedDouble: function (t) { var i = n(this); for (t = t || []; this.pos < i;)t.push(this.readDouble()); return t }, readPackedFixed32: function (t) { var i = n(this); for (t = t || []; this.pos < i;)t.push(this.readFixed32()); return t }, readPackedSFixed32: function (t) { var i = n(this); for (t = t || []; this.pos < i;)t.push(this.readSFixed32()); return t }, readPackedFixed64: function (t) { var i = n(this); for (t = t || []; this.pos < i;)t.push(this.readFixed64()); return t }, readPackedSFixed64: function (t) { var i = n(this); for (t = t || []; this.pos < i;)t.push(this.readSFixed64()); return t }, skip: function (t) { var i = 7 & t; if (i === r.Varint) for (; this.buf[this.pos++] > 127;); else if (i === r.Bytes) this.pos = this.readVarint() + this.pos; else if (i === r.Fixed32) this.pos += 4; else { if (i !== r.Fixed64) throw new Error("Unimplemented type: " + i); this.pos += 8 } }, writeTag: function (t, i) { this.writeVarint(t << 3 | i) }, realloc: function (t) { for (var i = this.length || 16; i < this.pos + t;)i *= 2; if (i !== this.length) { var e = new Uint8Array(i); e.set(this.buf), this.buf = e, this.length = i } }, finish: function () { return this.length = this.pos, this.pos = 0, this.buf.subarray(0, this.length) }, writeFixed32: function (t) { this.realloc(4), V(this.buf, t, this.pos), this.pos += 4 }, writeSFixed32: function (t) { this.realloc(4), V(this.buf, t, this.pos), this.pos += 4 }, writeFixed64: function (t) { this.realloc(8), V(this.buf, t & -1, this.pos), V(this.buf, Math.floor(t * P), this.pos + 4), this.pos += 8 }, writeSFixed64: function (t) { this.realloc(8), V(this.buf, t & -1, this.pos), V(this.buf, Math.floor(t * P), this.pos + 4), this.pos += 8 }, writeVarint: function (t) { return t = +t || 0, t > 268435455 || t < 0 ? void h(t, this) : (this.realloc(4), this.buf[this.pos++] = 127 & t | (t > 127 ? 128 : 0), void (t <= 127 || (this.buf[this.pos++] = 127 & (t >>>= 7) | (t > 127 ? 128 : 0), t <= 127 || (this.buf[this.pos++] = 127 & (t >>>= 7) | (t > 127 ? 128 : 0), t <= 127 || (this.buf[this.pos++] = t >>> 7 & 127))))) }, writeSVarint: function (t) { this.writeVarint(t < 0 ? 2 * -t - 1 : 2 * t) }, writeBoolean: function (t) { this.writeVarint(Boolean(t)) }, writeString: function (t) { t = String(t), this.realloc(4 * t.length), this.pos++; var i = this.pos; this.pos = S(this.buf, t, this.pos); var e = this.pos - i; e >= 128 && f(i, e, this), this.pos = i - 1, this.writeVarint(e), this.pos += e }, writeFloat: function (t) { this.realloc(4), B.write(this.buf, t, this.pos, !0, 23, 4), this.pos += 4 }, writeDouble: function (t) { this.realloc(8), B.write(this.buf, t, this.pos, !0, 52, 8), this.pos += 8 }, writeBytes: function (t) { var i = t.length; this.writeVarint(i), this.realloc(i); for (var e = 0; e < i; e++)this.buf[this.pos++] = t[e] }, writeRawMessage: function (t, i) { this.pos++; var e = this.pos; t(i, this); var r = this.pos - e; r >= 128 && f(e, r, this), this.pos = e - 1, this.writeVarint(r), this.pos += r }, writeMessage: function (t, i, e) { this.writeTag(t, r.Bytes), this.writeRawMessage(i, e) }, writePackedVarint: function (t, i) { this.writeMessage(t, d, i) }, writePackedSVarint: function (t, i) { this.writeMessage(t, p, i) }, writePackedBoolean: function (t, i) { this.writeMessage(t, w, i) }, writePackedFloat: function (t, i) { this.writeMessage(t, c, i) }, writePackedDouble: function (t, i) { this.writeMessage(t, l, i) }, writePackedFixed32: function (t, i) { this.writeMessage(t, F, i) }, writePackedSFixed32: function (t, i) { this.writeMessage(t, b, i) }, writePackedFixed64: function (t, i) { this.writeMessage(t, v, i) }, writePackedSFixed64: function (t, i) { this.writeMessage(t, g, i) }, writeBytesField: function (t, i) { this.writeTag(t, r.Bytes), this.writeBytes(i) }, writeFixed32Field: function (t, i) { this.writeTag(t, r.Fixed32), this.writeFixed32(i) }, writeSFixed32Field: function (t, i) { this.writeTag(t, r.Fixed32), this.writeSFixed32(i) }, writeFixed64Field: function (t, i) { this.writeTag(t, r.Fixed64), this.writeFixed64(i) }, writeSFixed64Field: function (t, i) { this.writeTag(t, r.Fixed64), this.writeSFixed64(i) }, writeVarintField: function (t, i) { this.writeTag(t, r.Varint), this.writeVarint(i) }, writeSVarintField: function (t, i) { this.writeTag(t, r.Varint), this.writeSVarint(i) }, writeStringField: function (t, i) { this.writeTag(t, r.Bytes), this.writeString(i) }, writeFloatField: function (t, i) { this.writeTag(t, r.Fixed32), this.writeFloat(i) }, writeDoubleField: function (t, i) { this.writeTag(t, r.Fixed64), this.writeDouble(i) }, writeBooleanField: function (t, i) { this.writeVarintField(t, Boolean(i)) } } }, { ieee754: 2 }], 2: [function (t, i, e) { e.read = function (t, i, e, r, s) { var n, o, h = 8 * s - r - 1, a = (1 << h) - 1, u = a >> 1, f = -7, d = e ? s - 1 : 0, p = e ? -1 : 1, c = t[i + d]; for (d += p, n = c & (1 << -f) - 1, c >>= -f, f += h; f > 0; n = 256 * n + t[i + d], d += p, f -= 8); for (o = n & (1 << -f) - 1, n >>= -f, f += r; f > 0; o = 256 * o + t[i + d], d += p, f -= 8); if (0 === n) n = 1 - u; else { if (n === a) return o ? NaN : (c ? -1 : 1) * (1 / 0); o += Math.pow(2, r), n -= u } return (c ? -1 : 1) * o * Math.pow(2, n - r) }, e.write = function (t, i, e, r, s, n) { var o, h, a, u = 8 * n - s - 1, f = (1 << u) - 1, d = f >> 1, p = 23 === s ? Math.pow(2, -24) - Math.pow(2, -77) : 0, c = r ? 0 : n - 1, l = r ? 1 : -1, w = i < 0 || 0 === i && 1 / i < 0 ? 1 : 0; for (i = Math.abs(i), isNaN(i) || i === 1 / 0 ? (h = isNaN(i) ? 1 : 0, o = f) : (o = Math.floor(Math.log(i) / Math.LN2), i * (a = Math.pow(2, -o)) < 1 && (o--, a *= 2), i += o + d >= 1 ? p / a : p * Math.pow(2, 1 - d), i * a >= 2 && (o++, a /= 2), o + d >= f ? (h = 0, o = f) : o + d >= 1 ? (h = (i * a - 1) * Math.pow(2, s), o += d) : (h = i * Math.pow(2, d - 1) * Math.pow(2, s), o = 0)); s >= 8; t[e + c] = 255 & h, c += l, h /= 256, s -= 8); for (o = o << s | h, u += s; u > 0; t[e + c] = 255 & o, c += l, o /= 256, u -= 8); t[e + c - l] |= 128 * w } }, {}] }, {}, [1])(1) }); function VectorTile(buffer, end) { this.layers = {}; this._buffer = buffer; diff --git a/lib/protobuf/Protobuf.js b/lib/protobuf/Protobuf.js deleted file mode 100644 index fba7f9c..0000000 --- a/lib/protobuf/Protobuf.js +++ /dev/null @@ -1 +0,0 @@ -!function (t) { if ("object" == typeof exports && "undefined" != typeof module) module.exports = t(); else if ("function" == typeof define && define.amd) define([], t); else { var i; i = "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof self ? self : this, i.Pbf = t() } }(function () { return function t(i, e, r) { function s(o, h) { if (!e[o]) { if (!i[o]) { var a = "function" == typeof require && require; if (!h && a) return a(o, !0); if (n) return n(o, !0); var u = new Error("Cannot find module '" + o + "'"); throw u.code = "MODULE_NOT_FOUND", u } var f = e[o] = { exports: {} }; i[o][0].call(f.exports, function (t) { var e = i[o][1][t]; return s(e ? e : t) }, f, f.exports, t, i, e, r) } return e[o].exports } for (var n = "function" == typeof require && require, o = 0; o < r.length; o++)s(r[o]); return s }({ 1: [function (t, i, e) { "use strict"; function r(t) { this.buf = ArrayBuffer.isView && ArrayBuffer.isView(t) ? t : new Uint8Array(t || 0), this.pos = 0, this.type = 0, this.length = this.buf.length } function s(t, i, e) { var r, s, n = e.buf; if (s = n[e.pos++], r = (112 & s) >> 4, s < 128) return o(t, r, i); if (s = n[e.pos++], r |= (127 & s) << 3, s < 128) return o(t, r, i); if (s = n[e.pos++], r |= (127 & s) << 10, s < 128) return o(t, r, i); if (s = n[e.pos++], r |= (127 & s) << 17, s < 128) return o(t, r, i); if (s = n[e.pos++], r |= (127 & s) << 24, s < 128) return o(t, r, i); if (s = n[e.pos++], r |= (1 & s) << 31, s < 128) return o(t, r, i); throw new Error("Expected varint not more than 10 bytes") } function n(t) { return t.type === r.Bytes ? t.readVarint() + t.pos : t.pos + 1 } function o(t, i, e) { return e ? 4294967296 * i + (t >>> 0) : 4294967296 * (i >>> 0) + (t >>> 0) } function h(t, i) { var e, r; if (t >= 0 ? (e = t % 4294967296 | 0, r = t / 4294967296 | 0) : (e = ~(-t % 4294967296), r = ~(-t / 4294967296), 4294967295 ^ e ? e = e + 1 | 0 : (e = 0, r = r + 1 | 0)), t >= 0x10000000000000000 || t < -0x10000000000000000) throw new Error("Given varint doesn't fit into 10 bytes"); i.realloc(10), a(e, r, i), u(r, i) } function a(t, i, e) { e.buf[e.pos++] = 127 & t | 128, t >>>= 7, e.buf[e.pos++] = 127 & t | 128, t >>>= 7, e.buf[e.pos++] = 127 & t | 128, t >>>= 7, e.buf[e.pos++] = 127 & t | 128, t >>>= 7, e.buf[e.pos] = 127 & t } function u(t, i) { var e = (7 & t) << 4; i.buf[i.pos++] |= e | ((t >>>= 3) ? 128 : 0), t && (i.buf[i.pos++] = 127 & t | ((t >>>= 7) ? 128 : 0), t && (i.buf[i.pos++] = 127 & t | ((t >>>= 7) ? 128 : 0), t && (i.buf[i.pos++] = 127 & t | ((t >>>= 7) ? 128 : 0), t && (i.buf[i.pos++] = 127 & t | ((t >>>= 7) ? 128 : 0), t && (i.buf[i.pos++] = 127 & t))))) } function f(t, i, e) { var r = i <= 16383 ? 1 : i <= 2097151 ? 2 : i <= 268435455 ? 3 : Math.ceil(Math.log(i) / (7 * Math.LN2)); e.realloc(r); for (var s = e.pos - 1; s >= t; s--)e.buf[s + r] = e.buf[s] } function d(t, i) { for (var e = 0; e < t.length; e++)i.writeVarint(t[e]) } function p(t, i) { for (var e = 0; e < t.length; e++)i.writeSVarint(t[e]) } function c(t, i) { for (var e = 0; e < t.length; e++)i.writeFloat(t[e]) } function l(t, i) { for (var e = 0; e < t.length; e++)i.writeDouble(t[e]) } function w(t, i) { for (var e = 0; e < t.length; e++)i.writeBoolean(t[e]) } function F(t, i) { for (var e = 0; e < t.length; e++)i.writeFixed32(t[e]) } function b(t, i) { for (var e = 0; e < t.length; e++)i.writeSFixed32(t[e]) } function v(t, i) { for (var e = 0; e < t.length; e++)i.writeFixed64(t[e]) } function g(t, i) { for (var e = 0; e < t.length; e++)i.writeSFixed64(t[e]) } function x(t, i) { return (t[i] | t[i + 1] << 8 | t[i + 2] << 16) + 16777216 * t[i + 3] } function V(t, i, e) { t[e] = i, t[e + 1] = i >>> 8, t[e + 2] = i >>> 16, t[e + 3] = i >>> 24 } function y(t, i) { return (t[i] | t[i + 1] << 8 | t[i + 2] << 16) + (t[i + 3] << 24) } function M(t, i, e) { for (var r = "", s = i; s < e;) { var n = t[s], o = null, h = n > 239 ? 4 : n > 223 ? 3 : n > 191 ? 2 : 1; if (s + h > e) break; var a, u, f; 1 === h ? n < 128 && (o = n) : 2 === h ? (a = t[s + 1], 128 === (192 & a) && (o = (31 & n) << 6 | 63 & a, o <= 127 && (o = null))) : 3 === h ? (a = t[s + 1], u = t[s + 2], 128 === (192 & a) && 128 === (192 & u) && (o = (15 & n) << 12 | (63 & a) << 6 | 63 & u, (o <= 2047 || o >= 55296 && o <= 57343) && (o = null))) : 4 === h && (a = t[s + 1], u = t[s + 2], f = t[s + 3], 128 === (192 & a) && 128 === (192 & u) && 128 === (192 & f) && (o = (15 & n) << 18 | (63 & a) << 12 | (63 & u) << 6 | 63 & f, (o <= 65535 || o >= 1114112) && (o = null))), null === o ? (o = 65533, h = 1) : o > 65535 && (o -= 65536, r += String.fromCharCode(o >>> 10 & 1023 | 55296), o = 56320 | 1023 & o), r += String.fromCharCode(o), s += h } return r } function S(t, i, e) { for (var r, s, n = 0; n < i.length; n++) { if (r = i.charCodeAt(n), r > 55295 && r < 57344) { if (!s) { r > 56319 || n + 1 === i.length ? (t[e++] = 239, t[e++] = 191, t[e++] = 189) : s = r; continue } if (r < 56320) { t[e++] = 239, t[e++] = 191, t[e++] = 189, s = r; continue } r = s - 55296 << 10 | r - 56320 | 65536, s = null } else s && (t[e++] = 239, t[e++] = 191, t[e++] = 189, s = null); r < 128 ? t[e++] = r : (r < 2048 ? t[e++] = r >> 6 | 192 : (r < 65536 ? t[e++] = r >> 12 | 224 : (t[e++] = r >> 18 | 240, t[e++] = r >> 12 & 63 | 128), t[e++] = r >> 6 & 63 | 128), t[e++] = 63 & r | 128) } return e } i.exports = r; var B = t("ieee754"); r.Varint = 0, r.Fixed64 = 1, r.Bytes = 2, r.Fixed32 = 5; var k = 4294967296, P = 1 / k; r.prototype = { destroy: function () { this.buf = null }, readFields: function (t, i, e) { for (e = e || this.length; this.pos < e;) { var r = this.readVarint(), s = r >> 3, n = this.pos; this.type = 7 & r, t(s, i, this), this.pos === n && this.skip(r) } return i }, readMessage: function (t, i) { return this.readFields(t, i, this.readVarint() + this.pos) }, readFixed32: function () { var t = x(this.buf, this.pos); return this.pos += 4, t }, readSFixed32: function () { var t = y(this.buf, this.pos); return this.pos += 4, t }, readFixed64: function () { var t = x(this.buf, this.pos) + x(this.buf, this.pos + 4) * k; return this.pos += 8, t }, readSFixed64: function () { var t = x(this.buf, this.pos) + y(this.buf, this.pos + 4) * k; return this.pos += 8, t }, readFloat: function () { var t = B.read(this.buf, this.pos, !0, 23, 4); return this.pos += 4, t }, readDouble: function () { var t = B.read(this.buf, this.pos, !0, 52, 8); return this.pos += 8, t }, readVarint: function (t) { var i, e, r = this.buf; return e = r[this.pos++], i = 127 & e, e < 128 ? i : (e = r[this.pos++], i |= (127 & e) << 7, e < 128 ? i : (e = r[this.pos++], i |= (127 & e) << 14, e < 128 ? i : (e = r[this.pos++], i |= (127 & e) << 21, e < 128 ? i : (e = r[this.pos], i |= (15 & e) << 28, s(i, t, this))))) }, readVarint64: function () { return this.readVarint(!0) }, readSVarint: function () { var t = this.readVarint(); return t % 2 === 1 ? (t + 1) / -2 : t / 2 }, readBoolean: function () { return Boolean(this.readVarint()) }, readString: function () { var t = this.readVarint() + this.pos, i = M(this.buf, this.pos, t); return this.pos = t, i }, readBytes: function () { var t = this.readVarint() + this.pos, i = this.buf.subarray(this.pos, t); return this.pos = t, i }, readPackedVarint: function (t, i) { var e = n(this); for (t = t || []; this.pos < e;)t.push(this.readVarint(i)); return t }, readPackedSVarint: function (t) { var i = n(this); for (t = t || []; this.pos < i;)t.push(this.readSVarint()); return t }, readPackedBoolean: function (t) { var i = n(this); for (t = t || []; this.pos < i;)t.push(this.readBoolean()); return t }, readPackedFloat: function (t) { var i = n(this); for (t = t || []; this.pos < i;)t.push(this.readFloat()); return t }, readPackedDouble: function (t) { var i = n(this); for (t = t || []; this.pos < i;)t.push(this.readDouble()); return t }, readPackedFixed32: function (t) { var i = n(this); for (t = t || []; this.pos < i;)t.push(this.readFixed32()); return t }, readPackedSFixed32: function (t) { var i = n(this); for (t = t || []; this.pos < i;)t.push(this.readSFixed32()); return t }, readPackedFixed64: function (t) { var i = n(this); for (t = t || []; this.pos < i;)t.push(this.readFixed64()); return t }, readPackedSFixed64: function (t) { var i = n(this); for (t = t || []; this.pos < i;)t.push(this.readSFixed64()); return t }, skip: function (t) { var i = 7 & t; if (i === r.Varint) for (; this.buf[this.pos++] > 127;); else if (i === r.Bytes) this.pos = this.readVarint() + this.pos; else if (i === r.Fixed32) this.pos += 4; else { if (i !== r.Fixed64) throw new Error("Unimplemented type: " + i); this.pos += 8 } }, writeTag: function (t, i) { this.writeVarint(t << 3 | i) }, realloc: function (t) { for (var i = this.length || 16; i < this.pos + t;)i *= 2; if (i !== this.length) { var e = new Uint8Array(i); e.set(this.buf), this.buf = e, this.length = i } }, finish: function () { return this.length = this.pos, this.pos = 0, this.buf.subarray(0, this.length) }, writeFixed32: function (t) { this.realloc(4), V(this.buf, t, this.pos), this.pos += 4 }, writeSFixed32: function (t) { this.realloc(4), V(this.buf, t, this.pos), this.pos += 4 }, writeFixed64: function (t) { this.realloc(8), V(this.buf, t & -1, this.pos), V(this.buf, Math.floor(t * P), this.pos + 4), this.pos += 8 }, writeSFixed64: function (t) { this.realloc(8), V(this.buf, t & -1, this.pos), V(this.buf, Math.floor(t * P), this.pos + 4), this.pos += 8 }, writeVarint: function (t) { return t = +t || 0, t > 268435455 || t < 0 ? void h(t, this) : (this.realloc(4), this.buf[this.pos++] = 127 & t | (t > 127 ? 128 : 0), void (t <= 127 || (this.buf[this.pos++] = 127 & (t >>>= 7) | (t > 127 ? 128 : 0), t <= 127 || (this.buf[this.pos++] = 127 & (t >>>= 7) | (t > 127 ? 128 : 0), t <= 127 || (this.buf[this.pos++] = t >>> 7 & 127))))) }, writeSVarint: function (t) { this.writeVarint(t < 0 ? 2 * -t - 1 : 2 * t) }, writeBoolean: function (t) { this.writeVarint(Boolean(t)) }, writeString: function (t) { t = String(t), this.realloc(4 * t.length), this.pos++; var i = this.pos; this.pos = S(this.buf, t, this.pos); var e = this.pos - i; e >= 128 && f(i, e, this), this.pos = i - 1, this.writeVarint(e), this.pos += e }, writeFloat: function (t) { this.realloc(4), B.write(this.buf, t, this.pos, !0, 23, 4), this.pos += 4 }, writeDouble: function (t) { this.realloc(8), B.write(this.buf, t, this.pos, !0, 52, 8), this.pos += 8 }, writeBytes: function (t) { var i = t.length; this.writeVarint(i), this.realloc(i); for (var e = 0; e < i; e++)this.buf[this.pos++] = t[e] }, writeRawMessage: function (t, i) { this.pos++; var e = this.pos; t(i, this); var r = this.pos - e; r >= 128 && f(e, r, this), this.pos = e - 1, this.writeVarint(r), this.pos += r }, writeMessage: function (t, i, e) { this.writeTag(t, r.Bytes), this.writeRawMessage(i, e) }, writePackedVarint: function (t, i) { this.writeMessage(t, d, i) }, writePackedSVarint: function (t, i) { this.writeMessage(t, p, i) }, writePackedBoolean: function (t, i) { this.writeMessage(t, w, i) }, writePackedFloat: function (t, i) { this.writeMessage(t, c, i) }, writePackedDouble: function (t, i) { this.writeMessage(t, l, i) }, writePackedFixed32: function (t, i) { this.writeMessage(t, F, i) }, writePackedSFixed32: function (t, i) { this.writeMessage(t, b, i) }, writePackedFixed64: function (t, i) { this.writeMessage(t, v, i) }, writePackedSFixed64: function (t, i) { this.writeMessage(t, g, i) }, writeBytesField: function (t, i) { this.writeTag(t, r.Bytes), this.writeBytes(i) }, writeFixed32Field: function (t, i) { this.writeTag(t, r.Fixed32), this.writeFixed32(i) }, writeSFixed32Field: function (t, i) { this.writeTag(t, r.Fixed32), this.writeSFixed32(i) }, writeFixed64Field: function (t, i) { this.writeTag(t, r.Fixed64), this.writeFixed64(i) }, writeSFixed64Field: function (t, i) { this.writeTag(t, r.Fixed64), this.writeSFixed64(i) }, writeVarintField: function (t, i) { this.writeTag(t, r.Varint), this.writeVarint(i) }, writeSVarintField: function (t, i) { this.writeTag(t, r.Varint), this.writeSVarint(i) }, writeStringField: function (t, i) { this.writeTag(t, r.Bytes), this.writeString(i) }, writeFloatField: function (t, i) { this.writeTag(t, r.Fixed32), this.writeFloat(i) }, writeDoubleField: function (t, i) { this.writeTag(t, r.Fixed64), this.writeDouble(i) }, writeBooleanField: function (t, i) { this.writeVarintField(t, Boolean(i)) } } }, { ieee754: 2 }], 2: [function (t, i, e) { e.read = function (t, i, e, r, s) { var n, o, h = 8 * s - r - 1, a = (1 << h) - 1, u = a >> 1, f = -7, d = e ? s - 1 : 0, p = e ? -1 : 1, c = t[i + d]; for (d += p, n = c & (1 << -f) - 1, c >>= -f, f += h; f > 0; n = 256 * n + t[i + d], d += p, f -= 8); for (o = n & (1 << -f) - 1, n >>= -f, f += r; f > 0; o = 256 * o + t[i + d], d += p, f -= 8); if (0 === n) n = 1 - u; else { if (n === a) return o ? NaN : (c ? -1 : 1) * (1 / 0); o += Math.pow(2, r), n -= u } return (c ? -1 : 1) * o * Math.pow(2, n - r) }, e.write = function (t, i, e, r, s, n) { var o, h, a, u = 8 * n - s - 1, f = (1 << u) - 1, d = f >> 1, p = 23 === s ? Math.pow(2, -24) - Math.pow(2, -77) : 0, c = r ? 0 : n - 1, l = r ? 1 : -1, w = i < 0 || 0 === i && 1 / i < 0 ? 1 : 0; for (i = Math.abs(i), isNaN(i) || i === 1 / 0 ? (h = isNaN(i) ? 1 : 0, o = f) : (o = Math.floor(Math.log(i) / Math.LN2), i * (a = Math.pow(2, -o)) < 1 && (o--, a *= 2), i += o + d >= 1 ? p / a : p * Math.pow(2, 1 - d), i * a >= 2 && (o++, a /= 2), o + d >= f ? (h = 0, o = f) : o + d >= 1 ? (h = (i * a - 1) * Math.pow(2, s), o += d) : (h = i * Math.pow(2, d - 1) * Math.pow(2, s), o = 0)); s >= 8; t[e + c] = 255 & h, c += l, h /= 256, s -= 8); for (o = o << s | h, u += s; u > 0; t[e + c] = 255 & o, c += l, o /= 256, u -= 8); t[e + c - l] |= 128 * w } }, {}] }, {}, [1])(1) }); \ No newline at end of file diff --git a/lib/vectortiles/Point.js b/lib/vectortiles/Point.js index da6d48a..04625aa 100644 --- a/lib/vectortiles/Point.js +++ b/lib/vectortiles/Point.js @@ -124,4 +124,6 @@ Point.convert = function (a) { return new Point(a[0], a[1]); } return a; -}; \ No newline at end of file +}; + +export default Point; \ No newline at end of file diff --git a/lib/vectortiles/VectorTile.js b/lib/vectortiles/VectorTile.js index 6b4413d..b85a6d4 100644 --- a/lib/vectortiles/VectorTile.js +++ b/lib/vectortiles/VectorTile.js @@ -1,4 +1,6 @@ -function VectorTile(buffer, end) { +import VectorTileLayer from './VectorTileLayer.js'; + +function VectorTile(buffer, end) { this.layers = {}; this._buffer = buffer; end = end || buffer.length; @@ -40,4 +42,6 @@ VectorTile.prototype.parseGeometries = function () { layer.parsedFeatures.push(feature); } } -} \ No newline at end of file +} + +export default VectorTile \ No newline at end of file diff --git a/lib/vectortiles/VectorTileFeature.js b/lib/vectortiles/VectorTileFeature.js index ae8ea44..0b37478 100644 --- a/lib/vectortiles/VectorTileFeature.js +++ b/lib/vectortiles/VectorTileFeature.js @@ -1,4 +1,6 @@ -function VectorTileFeature(buffer, end, extent, keys, values) { +import Point from './Point.js'; + +function VectorTileFeature(buffer, end, extent, keys, values) { this.properties = {}; // Public @@ -125,4 +127,6 @@ VectorTileFeature.prototype.bbox = function () { } return [x1, y1, x2, y2]; -}; \ No newline at end of file +}; + +export default VectorTileFeature; \ No newline at end of file diff --git a/lib/vectortiles/VectorTileLayer.js b/lib/vectortiles/VectorTileLayer.js index 479cf46..9acc9f3 100644 --- a/lib/vectortiles/VectorTileLayer.js +++ b/lib/vectortiles/VectorTileLayer.js @@ -1,4 +1,6 @@ -function VectorTileLayer(buffer, end) { +import VectorTileFeature from './VectorTileFeature.js'; + +function VectorTileLayer(buffer, end) { // Public this.version = 1; this.name = null; @@ -82,4 +84,6 @@ VectorTileLayer.prototype.feature = function (i) { var end = this._buffer.readVarint() + this._buffer.pos; return new VectorTileFeature(this._buffer, end, this.extent, this._keys, this._values); -}; \ No newline at end of file +}; + +export default VectorTileLayer; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 8391331..1f03e75 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,9 @@ "name": "vector-tiles-google-maps", "version": "0.0.1", "license": "MIT", + "dependencies": { + "pbf": "^3.2.1" + }, "devDependencies": { "@googlemaps/jest-mocks": "2.7.5", "eslint": "^8.32.0", @@ -2850,6 +2853,25 @@ "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==", + "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.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -4179,6 +4201,18 @@ "node": ">=8" } }, + "node_modules/pbf": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/pbf/-/pbf-3.2.1.tgz", + "integrity": "sha512-ClrV7pNOn7rtmoQVF4TS1vyU0WhYRnP92fzbfF75jAIwpnzdJXf8iTd4CMEqO4yUenH6NDqLiwjqlh6QgZzgLQ==", + "dependencies": { + "ieee754": "^1.1.12", + "resolve-protobuf-schema": "^2.1.0" + }, + "bin": { + "pbf": "bin/pbf" + } + }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -4318,6 +4352,11 @@ "node": ">= 6" } }, + "node_modules/protocol-buffers-schema": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz", + "integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==" + }, "node_modules/psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", @@ -4439,6 +4478,14 @@ "node": ">=4" } }, + "node_modules/resolve-protobuf-schema": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz", + "integrity": "sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==", + "dependencies": { + "protocol-buffers-schema": "^3.3.1" + } + }, "node_modules/resolve.exports": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.0.tgz", @@ -7311,6 +7358,11 @@ "safer-buffer": ">= 2.1.2 < 3.0.0" } }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, "ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -8312,6 +8364,15 @@ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true }, + "pbf": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/pbf/-/pbf-3.2.1.tgz", + "integrity": "sha512-ClrV7pNOn7rtmoQVF4TS1vyU0WhYRnP92fzbfF75jAIwpnzdJXf8iTd4CMEqO4yUenH6NDqLiwjqlh6QgZzgLQ==", + "requires": { + "ieee754": "^1.1.12", + "resolve-protobuf-schema": "^2.1.0" + } + }, "picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -8413,6 +8474,11 @@ "sisteransi": "^1.0.5" } }, + "protocol-buffers-schema": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz", + "integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==" + }, "psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", @@ -8495,6 +8561,14 @@ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, + "resolve-protobuf-schema": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz", + "integrity": "sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==", + "requires": { + "protocol-buffers-schema": "^3.3.1" + } + }, "resolve.exports": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.0.tgz", diff --git a/package.json b/package.json index 0317a8b..9b3149c 100644 --- a/package.json +++ b/package.json @@ -17,5 +17,8 @@ }, "moduleNameMapper": { "^@/(.*)$": "/src/$1" + }, + "dependencies": { + "pbf": "^3.2.1" } -} \ No newline at end of file +} diff --git a/src/MVTLayer.js b/src/MVTLayer.js index ed9fb96..8ddf177 100644 --- a/src/MVTLayer.js +++ b/src/MVTLayer.js @@ -1,10 +1,9 @@ /* * Created by Jes�s Barrio on 04/2021 */ +import {MVTFeature} from './MVTFeature.js'; -import {MVTFeature} from '@/MVTFeature.js'; - -export class MVTLayer { +export default class MVTLayer { constructor(options) { this._lineClickTolerance = 2; this._getIDForLayerFeature = options.getIDForLayerFeature; diff --git a/src/MVTSource.js b/src/MVTSource.js index 655bd1d..e801e8d 100644 --- a/src/MVTSource.js +++ b/src/MVTSource.js @@ -1,7 +1,9 @@ /* * Created by Jes�s Barrio on 04/2021 */ - +import Pbf from 'pbf'; +import VectorTile from '../lib/vectortiles/VectorTile.js'; +import MVTLayer from './MVTLayer.js'; export class MVTSource { constructor(map, options) { const self = this; diff --git a/vector-tiles-google-maps/.gitignore b/vector-tiles-google-maps/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/vector-tiles-google-maps/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/vector-tiles-google-maps/index.html b/vector-tiles-google-maps/index.html new file mode 100644 index 0000000..c6b5c90 --- /dev/null +++ b/vector-tiles-google-maps/index.html @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/vector-tiles-google-maps/main.js b/vector-tiles-google-maps/main.js new file mode 100644 index 0000000..567f2db --- /dev/null +++ b/vector-tiles-google-maps/main.js @@ -0,0 +1,3 @@ +import {MVTSource} from '../src/MVTSource.js'; + +window.MVTSource = MVTSource; \ No newline at end of file diff --git a/vector-tiles-google-maps/package-lock.json b/vector-tiles-google-maps/package-lock.json new file mode 100644 index 0000000..1578c18 --- /dev/null +++ b/vector-tiles-google-maps/package-lock.json @@ -0,0 +1,890 @@ +{ + "name": "vector-tiles-google-maps", + "version": "0.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "vector-tiles-google-maps", + "version": "0.0.0", + "devDependencies": { + "vite": "^4.1.0" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.16.17.tgz", + "integrity": "sha512-N9x1CMXVhtWEAMS7pNNONyA14f71VPQN9Cnavj1XQh6T7bskqiLLrSca4O0Vr8Wdcga943eThxnVp3JLnBMYtw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.16.17.tgz", + "integrity": "sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.16.17.tgz", + "integrity": "sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.16.17.tgz", + "integrity": "sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.16.17.tgz", + "integrity": "sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.16.17.tgz", + "integrity": "sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.16.17.tgz", + "integrity": "sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.16.17.tgz", + "integrity": "sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.16.17.tgz", + "integrity": "sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.16.17.tgz", + "integrity": "sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.16.17.tgz", + "integrity": "sha512-dTzNnQwembNDhd654cA4QhbS9uDdXC3TKqMJjgOWsC0yNCbpzfWoXdZvp0mY7HU6nzk5E0zpRGGx3qoQg8T2DQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.16.17.tgz", + "integrity": "sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.16.17.tgz", + "integrity": "sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.16.17.tgz", + "integrity": "sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.16.17.tgz", + "integrity": "sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.16.17.tgz", + "integrity": "sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.16.17.tgz", + "integrity": "sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.16.17.tgz", + "integrity": "sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.16.17.tgz", + "integrity": "sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.16.17.tgz", + "integrity": "sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.16.17.tgz", + "integrity": "sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.16.17.tgz", + "integrity": "sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.16.17.tgz", + "integrity": "sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.16.17", + "@esbuild/android-arm64": "0.16.17", + "@esbuild/android-x64": "0.16.17", + "@esbuild/darwin-arm64": "0.16.17", + "@esbuild/darwin-x64": "0.16.17", + "@esbuild/freebsd-arm64": "0.16.17", + "@esbuild/freebsd-x64": "0.16.17", + "@esbuild/linux-arm": "0.16.17", + "@esbuild/linux-arm64": "0.16.17", + "@esbuild/linux-ia32": "0.16.17", + "@esbuild/linux-loong64": "0.16.17", + "@esbuild/linux-mips64el": "0.16.17", + "@esbuild/linux-ppc64": "0.16.17", + "@esbuild/linux-riscv64": "0.16.17", + "@esbuild/linux-s390x": "0.16.17", + "@esbuild/linux-x64": "0.16.17", + "@esbuild/netbsd-x64": "0.16.17", + "@esbuild/openbsd-x64": "0.16.17", + "@esbuild/sunos-x64": "0.16.17", + "@esbuild/win32-arm64": "0.16.17", + "@esbuild/win32-ia32": "0.16.17", + "@esbuild/win32-x64": "0.16.17" + } + }, + "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/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "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/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/postcss": { + "version": "8.4.21", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", + "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + } + ], + "dependencies": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.9.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/rollup": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.14.0.tgz", + "integrity": "sha512-o23sdgCLcLSe3zIplT9nQ1+r97okuaiR+vmAPZPTDYB7/f3tgWIYNyiQveMsZwshBT0is4eGax/HH83Q7CG+/Q==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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/vite": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.1.1.tgz", + "integrity": "sha512-LM9WWea8vsxhr782r9ntg+bhSFS06FJgCvvB0+8hf8UWtvaiDagKYWXndjfX6kGl74keHJUcpzrQliDXZlF5yg==", + "dev": true, + "dependencies": { + "esbuild": "^0.16.14", + "postcss": "^8.4.21", + "resolve": "^1.22.1", + "rollup": "^3.10.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "less": "*", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + } + }, + "dependencies": { + "@esbuild/android-arm": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.16.17.tgz", + "integrity": "sha512-N9x1CMXVhtWEAMS7pNNONyA14f71VPQN9Cnavj1XQh6T7bskqiLLrSca4O0Vr8Wdcga943eThxnVp3JLnBMYtw==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.16.17.tgz", + "integrity": "sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg==", + "dev": true, + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.16.17.tgz", + "integrity": "sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.16.17.tgz", + "integrity": "sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.16.17.tgz", + "integrity": "sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.16.17.tgz", + "integrity": "sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.16.17.tgz", + "integrity": "sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.16.17.tgz", + "integrity": "sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.16.17.tgz", + "integrity": "sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.16.17.tgz", + "integrity": "sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.16.17.tgz", + "integrity": "sha512-dTzNnQwembNDhd654cA4QhbS9uDdXC3TKqMJjgOWsC0yNCbpzfWoXdZvp0mY7HU6nzk5E0zpRGGx3qoQg8T2DQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.16.17.tgz", + "integrity": "sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.16.17.tgz", + "integrity": "sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g==", + "dev": true, + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.16.17.tgz", + "integrity": "sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw==", + "dev": true, + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.16.17.tgz", + "integrity": "sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w==", + "dev": true, + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.16.17.tgz", + "integrity": "sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw==", + "dev": true, + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.16.17.tgz", + "integrity": "sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.16.17.tgz", + "integrity": "sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg==", + "dev": true, + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.16.17.tgz", + "integrity": "sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw==", + "dev": true, + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.16.17.tgz", + "integrity": "sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw==", + "dev": true, + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.16.17.tgz", + "integrity": "sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig==", + "dev": true, + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.16.17.tgz", + "integrity": "sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==", + "dev": true, + "optional": true + }, + "esbuild": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.16.17.tgz", + "integrity": "sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==", + "dev": true, + "requires": { + "@esbuild/android-arm": "0.16.17", + "@esbuild/android-arm64": "0.16.17", + "@esbuild/android-x64": "0.16.17", + "@esbuild/darwin-arm64": "0.16.17", + "@esbuild/darwin-x64": "0.16.17", + "@esbuild/freebsd-arm64": "0.16.17", + "@esbuild/freebsd-x64": "0.16.17", + "@esbuild/linux-arm": "0.16.17", + "@esbuild/linux-arm64": "0.16.17", + "@esbuild/linux-ia32": "0.16.17", + "@esbuild/linux-loong64": "0.16.17", + "@esbuild/linux-mips64el": "0.16.17", + "@esbuild/linux-ppc64": "0.16.17", + "@esbuild/linux-riscv64": "0.16.17", + "@esbuild/linux-s390x": "0.16.17", + "@esbuild/linux-x64": "0.16.17", + "@esbuild/netbsd-x64": "0.16.17", + "@esbuild/openbsd-x64": "0.16.17", + "@esbuild/sunos-x64": "0.16.17", + "@esbuild/win32-arm64": "0.16.17", + "@esbuild/win32-ia32": "0.16.17", + "@esbuild/win32-x64": "0.16.17" + } + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "dev": true + }, + "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 + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "postcss": { + "version": "8.4.21", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", + "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", + "dev": true, + "requires": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + } + }, + "resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "rollup": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.14.0.tgz", + "integrity": "sha512-o23sdgCLcLSe3zIplT9nQ1+r97okuaiR+vmAPZPTDYB7/f3tgWIYNyiQveMsZwshBT0is4eGax/HH83Q7CG+/Q==", + "dev": true, + "requires": { + "fsevents": "~2.3.2" + } + }, + "source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true + }, + "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 + }, + "vite": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.1.1.tgz", + "integrity": "sha512-LM9WWea8vsxhr782r9ntg+bhSFS06FJgCvvB0+8hf8UWtvaiDagKYWXndjfX6kGl74keHJUcpzrQliDXZlF5yg==", + "dev": true, + "requires": { + "esbuild": "^0.16.14", + "fsevents": "~2.3.2", + "postcss": "^8.4.21", + "resolve": "^1.22.1", + "rollup": "^3.10.0" + } + } + } +} diff --git a/vector-tiles-google-maps/package.json b/vector-tiles-google-maps/package.json new file mode 100644 index 0000000..3f328f2 --- /dev/null +++ b/vector-tiles-google-maps/package.json @@ -0,0 +1,13 @@ +{ + "name": "vector-tiles-google-maps", + "private": true, + "version": "0.0.0", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "devDependencies": { + "vite": "^4.1.0" + } +} \ No newline at end of file From 16fccbe1e4e21a26f0adf5ac70c8c4fee5e872ec Mon Sep 17 00:00:00 2001 From: Brian Roden <32974706+Bobbyjuba@users.noreply.github.com> Date: Wed, 8 Feb 2023 13:23:05 -0600 Subject: [PATCH 04/11] BMAPS-1694 Added @mapbox/vector-tile dependency (#3) * Started removing protobuf * Added Vite * remove default from mvtlayer * undid previous thing * Fixed issue with vector tile features not being parsed * Removed files * Fixed issue with MERCATOR * Removed API key --------- Co-authored-by: Camden Obertop --- examples/basic.html | 5 +- examples/click.html | 4 +- examples/hover.html | 4 +- examples/index.html | 28 +++++ lib/vectortiles/VectorTile.js | 47 --------- lib/vectortiles/VectorTileFeature.js | 132 ------------------------ lib/vectortiles/VectorTileLayer.js | 89 ---------------- package-lock.json | 27 +++++ package.json | 1 + src/MVTLayer.js | 5 +- src/MVTSource.js | 16 ++- vector-tiles-google-maps/vite.config.js | 13 +++ 12 files changed, 95 insertions(+), 276 deletions(-) create mode 100644 examples/index.html delete mode 100644 lib/vectortiles/VectorTile.js delete mode 100644 lib/vectortiles/VectorTileFeature.js delete mode 100644 lib/vectortiles/VectorTileLayer.js create mode 100644 vector-tiles-google-maps/vite.config.js diff --git a/examples/basic.html b/examples/basic.html index ff49fe4..1747ef2 100644 --- a/examples/basic.html +++ b/examples/basic.html @@ -19,7 +19,7 @@

Basic

- + - \ No newline at end of file diff --git a/examples/click.html b/examples/click.html index 696e739..c3054fd 100644 --- a/examples/click.html +++ b/examples/click.html @@ -22,7 +22,7 @@

Click

- + - \ No newline at end of file diff --git a/examples/hover.html b/examples/hover.html index c75cd11..6ae38c1 100644 --- a/examples/hover.html +++ b/examples/hover.html @@ -22,7 +22,7 @@

Hover

- + - \ No newline at end of file diff --git a/examples/index.html b/examples/index.html new file mode 100644 index 0000000..004c878 --- /dev/null +++ b/examples/index.html @@ -0,0 +1,28 @@ + + + + + + + Examples + + +

Examples

+
    +
  1. Basic - Basic loading vector tiles with debug enabled.
  2. +
  3. Cache - Cache enabled.
  4. +
  5. Click - Click to select one or multiple features.
  6. +
  7. Custom draw - Custom draw function for each feature.
  8. +
  9. Filter - Filter features by it properties.
  10. +
  11. Hover - On mouse hover event.
  12. +
  13. Layers - Add remove vector tiles layers.
  14. +
  15. Point, linestring and polygon - Show all type of geometries.
  16. +
  17. Preselected features - Set features as selected before loading.
  18. +
  19. Sectores parcels
  20. +
  21. Spanish parcels
  22. +
  23. Style filter and layer - Update the style, filter and visible layers simultaneously.
  24. +
  25. Styles feature - Style based on feature properties.
  26. +
  27. Styles - Change style dynamically.
  28. +
+ + \ No newline at end of file diff --git a/lib/vectortiles/VectorTile.js b/lib/vectortiles/VectorTile.js deleted file mode 100644 index b85a6d4..0000000 --- a/lib/vectortiles/VectorTile.js +++ /dev/null @@ -1,47 +0,0 @@ -import VectorTileLayer from './VectorTileLayer.js'; - -function VectorTile(buffer, end) { - this.layers = {}; - this._buffer = buffer; - end = end || buffer.length; - - while (buffer.pos < end) { - var val = buffer.readVarint(), - tag = val >> 3; - - if (tag == 3) { - var layer = this._readLayer(); - if (layer.length) { - this.layers[layer.name] = layer; - } - } else { - buffer.skip(val); - } - } - this.parseGeometries(); -} - -VectorTile.prototype._readLayer = function () { - var buffer = this._buffer, - bytes = buffer.readVarint(), - end = buffer.pos + bytes, - layer = new VectorTileLayer(buffer, end); - - buffer.pos = end; - return layer; -}; - -VectorTile.prototype.parseGeometries = function () { - for (var key in this.layers) { - var layer = this.layers[key]; - layer.parsedFeatures = []; - var featuresLength = layer._features.length; - for (var i = 0, len = featuresLength; i < len; i++) { - var feature = layer.feature(i); - feature.coordinates = feature.loadGeometry(); - layer.parsedFeatures.push(feature); - } - } -} - -export default VectorTile \ No newline at end of file diff --git a/lib/vectortiles/VectorTileFeature.js b/lib/vectortiles/VectorTileFeature.js deleted file mode 100644 index 0b37478..0000000 --- a/lib/vectortiles/VectorTileFeature.js +++ /dev/null @@ -1,132 +0,0 @@ -import Point from './Point.js'; - -function VectorTileFeature(buffer, end, extent, keys, values) { - this.properties = {}; - - // Public - this.extent = extent; - this.type = 0; - - // Private - this._buffer = buffer; - this._geometry = -1; - - end = end || buffer.length; - - while (buffer.pos < end) { - var val = buffer.readVarint(), - tag = val >> 3; - - if (tag == 1) { - this._id = buffer.readVarint(); - } else if (tag == 2) { - var tagLen = buffer.readVarint(), - tagEnd = buffer.pos + tagLen; - - while (buffer.pos < tagEnd) { - var key = keys[buffer.readVarint()]; - var value = values[buffer.readVarint()]; - this.properties[key] = value; - } - } else if (tag == 3) { - this.type = buffer.readVarint(); - } else if (tag == 4) { - this._geometry = buffer.pos; - buffer.skip(val); - } else { - buffer.skip(val); - } - } -} - -VectorTileFeature.types = ['Unknown', 'Point', 'LineString', 'Polygon']; - -VectorTileFeature.prototype.loadGeometry = function () { - var buffer = this._buffer; - buffer.pos = this._geometry; - - var bytes = buffer.readVarint(), - end = buffer.pos + bytes, - cmd = 1, - length = 0, - x = 0, - y = 0, - lines = [], - line; - - while (buffer.pos < end) { - if (!length) { - var cmd_length = buffer.readVarint(); - cmd = cmd_length & 0x7; - length = cmd_length >> 3; - } - - length--; - - if (cmd === 1 || cmd === 2) { - x += buffer.readSVarint(); - y += buffer.readSVarint(); - - if (cmd === 1) { - // moveTo - if (line) { - lines.push(line); - } - line = []; - } - - line.push(new Point(x, y)); - } else if (cmd === 7) { - // closePolygon - line.push(line[0].clone()); - } else { - throw new Error('unknown command ' + cmd); - } - } - - if (line) lines.push(line); - - return lines; -}; - -VectorTileFeature.prototype.bbox = function () { - var buffer = this._buffer; - buffer.pos = this._geometry; - - var bytes = buffer.readVarint(), - end = buffer.pos + bytes, - - cmd = 1, - length = 0, - x = 0, - y = 0, - x1 = Infinity, - x2 = -Infinity, - y1 = Infinity, - y2 = -Infinity; - - while (buffer.pos < end) { - if (!length) { - var cmd_length = buffer.readVarint(); - cmd = cmd_length & 0x7; - length = cmd_length >> 3; - } - - length--; - - if (cmd === 1 || cmd === 2) { - x += buffer.readSVarint(); - y += buffer.readSVarint(); - if (x < x1) x1 = x; - if (x > x2) x2 = x; - if (y < y1) y1 = y; - if (y > y2) y2 = y; - } else if (cmd !== 7) { - throw new Error('unknown command ' + cmd); - } - } - - return [x1, y1, x2, y2]; -}; - -export default VectorTileFeature; \ No newline at end of file diff --git a/lib/vectortiles/VectorTileLayer.js b/lib/vectortiles/VectorTileLayer.js deleted file mode 100644 index 9acc9f3..0000000 --- a/lib/vectortiles/VectorTileLayer.js +++ /dev/null @@ -1,89 +0,0 @@ -import VectorTileFeature from './VectorTileFeature.js'; - -function VectorTileLayer(buffer, end) { - // Public - this.version = 1; - this.name = null; - this.extent = 4096; - this.length = 0; - - // Private - this._buffer = buffer; - this._keys = []; - this._values = []; - this._features = []; - - var val, tag; - - end = end || buffer.length; - - while (buffer.pos < end) { - val = buffer.readVarint(); - tag = val >> 3; - - if (tag === 15) { - this.version = buffer.readVarint(); - } else if (tag === 1) { - this.name = buffer.readString(); - } else if (tag === 5) { - this.extent = buffer.readVarint(); - } else if (tag === 2) { - this.length++; - this._features.push(buffer.pos); - buffer.skip(val); - } else if (tag === 3) { - this._keys.push(buffer.readString()); - } else if (tag === 4) { - this._values.push(this.readFeatureValue()); - } else { - buffer.skip(val); - } - } -} - -VectorTileLayer.prototype.readFeatureValue = function () { - var buffer = this._buffer, - value = null, - bytes = buffer.readVarint(), - end = buffer.pos + bytes, - val, tag; - - while (buffer.pos < end) { - val = buffer.readVarint(); - tag = val >> 3; - - if (tag == 1) { - value = buffer.readString(); - } else if (tag == 2) { - //throw new Error('read float'); - value = buffer.readFloat(); - } else if (tag == 3) { - value = buffer.readDouble(); - } else if (tag == 4) { - value = buffer.readVarint(); - } else if (tag == 5) { - //throw new Error('read uint'); - value = buffer.readVarint(); - } else if (tag == 6) { - value = buffer.readSVarint(); - } else if (tag == 7) { - value = Boolean(buffer.readVarint()); - } else { - buffer.skip(val); - } - } - - return value; -}; - -// return feature `i` from this layer as a `VectorTileFeature` -VectorTileLayer.prototype.feature = function (i) { - if (i < 0 || i >= this._features.length) throw new Error('feature index out of bounds'); - - this._buffer.pos = this._features[i]; - var end = this._buffer.readVarint() + this._buffer.pos; - - return new VectorTileFeature(this._buffer, end, this.extent, this._keys, this._values); -}; - -export default VectorTileLayer; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 1f03e75..3ec6bd0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "0.0.1", "license": "MIT", "dependencies": { + "@mapbox/vector-tile": "^1.3.1", "pbf": "^3.2.1" }, "devDependencies": { @@ -1127,6 +1128,19 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, + "node_modules/@mapbox/point-geometry": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz", + "integrity": "sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ==" + }, + "node_modules/@mapbox/vector-tile": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@mapbox/vector-tile/-/vector-tile-1.3.1.tgz", + "integrity": "sha512-MCEddb8u44/xfQ3oD+Srl/tNcQoqTw3goGk2oLsrFxOTc3dUp+kAnby3PvAeeBYSMSjSPD1nd1AJA6W49WnoUw==", + "dependencies": { + "@mapbox/point-geometry": "~0.1.0" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -6065,6 +6079,19 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, + "@mapbox/point-geometry": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz", + "integrity": "sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ==" + }, + "@mapbox/vector-tile": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@mapbox/vector-tile/-/vector-tile-1.3.1.tgz", + "integrity": "sha512-MCEddb8u44/xfQ3oD+Srl/tNcQoqTw3goGk2oLsrFxOTc3dUp+kAnby3PvAeeBYSMSjSPD1nd1AJA6W49WnoUw==", + "requires": { + "@mapbox/point-geometry": "~0.1.0" + } + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", diff --git a/package.json b/package.json index 9b3149c..abaf8eb 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "^@/(.*)$": "/src/$1" }, "dependencies": { + "@mapbox/vector-tile": "^1.3.1", "pbf": "^3.2.1" } } diff --git a/src/MVTLayer.js b/src/MVTLayer.js index 8ddf177..5cfcd42 100644 --- a/src/MVTLayer.js +++ b/src/MVTLayer.js @@ -2,6 +2,7 @@ * Created by Jes�s Barrio on 04/2021 */ import {MVTFeature} from './MVTFeature.js'; +import * as MERCATOR from '../lib/mercator/Mercator.js'; export default class MVTLayer { constructor(options) { @@ -172,7 +173,7 @@ export default class MVTLayer { const path = paths[j]; switch (mVTFeature.type) { case 1: // Point - if (MERCATOR.in_circle(path[0].x, path[0].y, mVTFeature.style.radius, event.tilePoint.x, event.tilePoint.y)) { + if (MERCATOR.inCircle(path[0].x, path[0].y, mVTFeature.style.radius, event.tilePoint.x, event.tilePoint.y)) { this.selectedFeature = mVTFeature; this.minDistance = 0; } @@ -192,3 +193,5 @@ export default class MVTLayer { } } } + +export {MVTLayer} \ No newline at end of file diff --git a/src/MVTSource.js b/src/MVTSource.js index e801e8d..dad4af3 100644 --- a/src/MVTSource.js +++ b/src/MVTSource.js @@ -2,7 +2,8 @@ * Created by Jes�s Barrio on 04/2021 */ import Pbf from 'pbf'; -import VectorTile from '../lib/vectortiles/VectorTile.js'; +import {VectorTile} from '@mapbox/vector-tile'; +import * as MERCATOR from '../lib/mercator/Mercator.js'; import MVTLayer from './MVTLayer.js'; export class MVTSource { constructor(map, options) { @@ -196,6 +197,19 @@ export class MVTSource { const uint8Array = new Uint8Array(response); const pbf = new Pbf(uint8Array); const vectorTile = new VectorTile(pbf); + // This is copied from the code originally found in VectorTile.js + // It is necessary to actually load the geometry of each feature before they can be drawn + for (var key in vectorTile.layers) { + var layer = vectorTile.layers[key]; + layer.parsedFeatures = []; + var featuresLength = layer._features.length; + for (var i = 0, len = featuresLength; i < len; i++) { + var feature = layer.feature(i); + feature.coordinates = feature.loadGeometry(); + layer.parsedFeatures.push(feature); + } + vectorTile.layers[key] = layer; + } this._drawVectorTile(vectorTile, tileContext); } diff --git a/vector-tiles-google-maps/vite.config.js b/vector-tiles-google-maps/vite.config.js new file mode 100644 index 0000000..23f7249 --- /dev/null +++ b/vector-tiles-google-maps/vite.config.js @@ -0,0 +1,13 @@ +import { defineConfig } from "vite" + +export default defineConfig({ + build: { + rollupOptions: { + output: { + entryFileNames: `assets/[name].js`, + chunkFileNames: `assets/[name].js`, + assetFileNames: `assets/[name].[ext]` + } + } + } +}) \ No newline at end of file From b1905e47f6feb551509298db4762180f99849ddc Mon Sep 17 00:00:00 2001 From: camden-obertop <52179320+camden-obertop@users.noreply.github.com> Date: Fri, 10 Feb 2023 12:25:10 -0600 Subject: [PATCH 05/11] BMAPS-1693 Remove vectortiles Point (#5) --- examples/point-linestring-polygon.html | 4 +- lib/vectortiles/Point.js | 129 ------------------------- 2 files changed, 2 insertions(+), 131 deletions(-) delete mode 100644 lib/vectortiles/Point.js diff --git a/examples/point-linestring-polygon.html b/examples/point-linestring-polygon.html index 2ed603b..6672e67 100644 --- a/examples/point-linestring-polygon.html +++ b/examples/point-linestring-polygon.html @@ -18,7 +18,7 @@

Point, linestring and polygon

- + - \ No newline at end of file diff --git a/lib/vectortiles/Point.js b/lib/vectortiles/Point.js deleted file mode 100644 index 04625aa..0000000 --- a/lib/vectortiles/Point.js +++ /dev/null @@ -1,129 +0,0 @@ -function Point(x, y) { - this.x = x; - this.y = y; -} - -Point.prototype = { - clone: function () { return new Point(this.x, this.y); }, - - add: function (p) { return this.clone()._add(p); }, - sub: function (p) { return this.clone()._sub(p); }, - mult: function (k) { return this.clone()._mult(k); }, - div: function (k) { return this.clone()._div(k); }, - rotate: function (a) { return this.clone()._rotate(a); }, - matMult: function (m) { return this.clone()._matMult(m); }, - unit: function () { return this.clone()._unit(); }, - perp: function () { return this.clone()._perp(); }, - round: function () { return this.clone()._round(); }, - - mag: function () { - return Math.sqrt(this.x * this.x + this.y * this.y); - }, - - equals: function (p) { - return this.x === p.x && - this.y === p.y; - }, - - dist: function (p) { - return Math.sqrt(this.distSqr(p)); - }, - - distSqr: function (p) { - var dx = p.x - this.x, - dy = p.y - this.y; - return dx * dx + dy * dy; - }, - - angle: function () { - return Math.atan2(this.y, this.x); - }, - - angleTo: function (b) { - return Math.atan2(this.y - b.y, this.x - b.x); - }, - - angleWith: function (b) { - return this.angleWithSep(b.x, b.y); - }, - - // Find the angle of the two vectors, solving the formula for the cross product a x b = |a||b|sin(θ) for θ. - angleWithSep: function (x, y) { - return Math.atan2( - this.x * y - this.y * x, - this.x * x + this.y * y); - }, - - _matMult: function (m) { - var x = m[0] * this.x + m[1] * this.y, - y = m[2] * this.x + m[3] * this.y; - this.x = x; - this.y = y; - return this; - }, - - _add: function (p) { - this.x += p.x; - this.y += p.y; - return this; - }, - - _sub: function (p) { - this.x -= p.x; - this.y -= p.y; - return this; - }, - - _mult: function (k) { - this.x *= k; - this.y *= k; - return this; - }, - - _div: function (k) { - this.x /= k; - this.y /= k; - return this; - }, - - _unit: function () { - this._div(this.mag()); - return this; - }, - - _perp: function () { - var y = this.y; - this.y = this.x; - this.x = -y; - return this; - }, - - _rotate: function (angle) { - var cos = Math.cos(angle), - sin = Math.sin(angle), - x = cos * this.x - sin * this.y, - y = sin * this.x + cos * this.y; - this.x = x; - this.y = y; - return this; - }, - - _round: function () { - this.x = Math.round(this.x); - this.y = Math.round(this.y); - return this; - } -}; - -// constructs Point from an array if necessary -Point.convert = function (a) { - if (a instanceof Point) { - return a; - } - if (Array.isArray(a)) { - return new Point(a[0], a[1]); - } - return a; -}; - -export default Point; \ No newline at end of file From 88fc3485b4c921f1e571ddd9823ef845d05afa7c Mon Sep 17 00:00:00 2001 From: Sam Schurter Date: Mon, 13 Feb 2023 16:19:00 -0600 Subject: [PATCH 06/11] BMAPS-1695 BMAPS-1696 (#6) * updates html files * fixes ESLint config * adds google maps types * updates html files * rewrite feature and layer complete * mvtSource rewritten * updates HTML files * fixes tests --- .eslintrc.js => .eslintrc.cjs | 1 + .gitignore | 24 +- dist/vector-tiles-google-maps.js | 1455 ----------------- dist/vector-tiles-google-maps.min.js | 1 - examples/basic.html | 45 +- examples/cache.html | 44 +- examples/click.html | 43 +- examples/custom-draw.html | 50 +- examples/filter.html | 44 +- examples/hover.html | 44 +- examples/index.html | 28 - examples/layers.html | 44 +- examples/point-linestring-polygon.html | 42 +- examples/preselected-features.html | 53 +- examples/sectores-parcels.html | 58 - examples/spanish-parcels.html | 72 - examples/style-filter-layer.html | 46 +- examples/styles-feature.html | 44 +- examples/styles.css | 17 +- examples/styles.html | 46 +- index.html | 44 + lib/drawing.js | 91 ++ lib/geometry.js | 74 + main.js | 18 + package-lock.json | 744 ++++++++- package.json | 9 +- src/MVTFeature.js | 304 ++-- src/MVTLayer.js | 321 ++-- src/MVTSource.js | 841 ++++++---- tests/MVTFeature.spec.js | 157 +- tests/MVTLayer.spec.js | 77 +- tests/MVTSource.spec.js | 37 +- tests/common-mocks.js | 59 +- vector-tiles-google-maps/.gitignore | 24 - vector-tiles-google-maps/index.html | 9 - vector-tiles-google-maps/main.js | 3 - vector-tiles-google-maps/package-lock.json | 890 ---------- vector-tiles-google-maps/package.json | 13 - .../vite.config.js => vite.config.js | 13 +- 39 files changed, 2459 insertions(+), 3470 deletions(-) rename .eslintrc.js => .eslintrc.cjs (97%) delete mode 100644 dist/vector-tiles-google-maps.js delete mode 100644 dist/vector-tiles-google-maps.min.js delete mode 100644 examples/index.html delete mode 100644 examples/sectores-parcels.html delete mode 100644 examples/spanish-parcels.html create mode 100644 index.html create mode 100644 lib/drawing.js create mode 100644 lib/geometry.js create mode 100644 main.js delete mode 100644 vector-tiles-google-maps/.gitignore delete mode 100644 vector-tiles-google-maps/index.html delete mode 100644 vector-tiles-google-maps/main.js delete mode 100644 vector-tiles-google-maps/package-lock.json delete mode 100644 vector-tiles-google-maps/package.json rename vector-tiles-google-maps/vite.config.js => vite.config.js (52%) diff --git a/.eslintrc.js b/.eslintrc.cjs similarity index 97% rename from .eslintrc.js rename to .eslintrc.cjs index 1484d15..ed72b9e 100644 --- a/.eslintrc.js +++ b/.eslintrc.cjs @@ -4,6 +4,7 @@ module.exports = { 'jest': true, 'browser': true, 'node': true, + 'es6': true, }, extends: [ 'eslint:recommended', diff --git a/.gitignore b/.gitignore index 413d431..251ce6d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,23 @@ -.DS_Store +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + node_modules -/dist \ No newline at end of file +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/dist/vector-tiles-google-maps.js b/dist/vector-tiles-google-maps.js deleted file mode 100644 index 21236db..0000000 --- a/dist/vector-tiles-google-maps.js +++ /dev/null @@ -1,1455 +0,0 @@ -function VectorTile(buffer, end) { - this.layers = {}; - this._buffer = buffer; - end = end || buffer.length; - - while (buffer.pos < end) { - var val = buffer.readVarint(), - tag = val >> 3; - - if (tag == 3) { - var layer = this._readLayer(); - if (layer.length) { - this.layers[layer.name] = layer; - } - } else { - buffer.skip(val); - } - } - this.parseGeometries(); -} - -VectorTile.prototype._readLayer = function () { - var buffer = this._buffer, - bytes = buffer.readVarint(), - end = buffer.pos + bytes, - layer = new VectorTileLayer(buffer, end); - - buffer.pos = end; - return layer; -}; - -VectorTile.prototype.parseGeometries = function () { - for (var key in this.layers) { - var layer = this.layers[key]; - layer.parsedFeatures = []; - var featuresLength = layer._features.length; - for (var i = 0, len = featuresLength; i < len; i++) { - var feature = layer.feature(i); - feature.coordinates = feature.loadGeometry(); - layer.parsedFeatures.push(feature); - } - } -} -function VectorTileFeature(buffer, end, extent, keys, values) { - this.properties = {}; - - // Public - this.extent = extent; - this.type = 0; - - // Private - this._buffer = buffer; - this._geometry = -1; - - end = end || buffer.length; - - while (buffer.pos < end) { - var val = buffer.readVarint(), - tag = val >> 3; - - if (tag == 1) { - this._id = buffer.readVarint(); - } else if (tag == 2) { - var tagLen = buffer.readVarint(), - tagEnd = buffer.pos + tagLen; - - while (buffer.pos < tagEnd) { - var key = keys[buffer.readVarint()]; - var value = values[buffer.readVarint()]; - this.properties[key] = value; - } - } else if (tag == 3) { - this.type = buffer.readVarint(); - } else if (tag == 4) { - this._geometry = buffer.pos; - buffer.skip(val); - } else { - buffer.skip(val); - } - } -} - -VectorTileFeature.types = ['Unknown', 'Point', 'LineString', 'Polygon']; - -VectorTileFeature.prototype.loadGeometry = function () { - var buffer = this._buffer; - buffer.pos = this._geometry; - - var bytes = buffer.readVarint(), - end = buffer.pos + bytes, - cmd = 1, - length = 0, - x = 0, - y = 0, - lines = [], - line; - - while (buffer.pos < end) { - if (!length) { - var cmd_length = buffer.readVarint(); - cmd = cmd_length & 0x7; - length = cmd_length >> 3; - } - - length--; - - if (cmd === 1 || cmd === 2) { - x += buffer.readSVarint(); - y += buffer.readSVarint(); - - if (cmd === 1) { - // moveTo - if (line) { - lines.push(line); - } - line = []; - } - - line.push(new Point(x, y)); - } else if (cmd === 7) { - // closePolygon - line.push(line[0].clone()); - } else { - throw new Error('unknown command ' + cmd); - } - } - - if (line) lines.push(line); - - return lines; -}; - -VectorTileFeature.prototype.bbox = function () { - var buffer = this._buffer; - buffer.pos = this._geometry; - - var bytes = buffer.readVarint(), - end = buffer.pos + bytes, - - cmd = 1, - length = 0, - x = 0, - y = 0, - x1 = Infinity, - x2 = -Infinity, - y1 = Infinity, - y2 = -Infinity; - - while (buffer.pos < end) { - if (!length) { - var cmd_length = buffer.readVarint(); - cmd = cmd_length & 0x7; - length = cmd_length >> 3; - } - - length--; - - if (cmd === 1 || cmd === 2) { - x += buffer.readSVarint(); - y += buffer.readSVarint(); - if (x < x1) x1 = x; - if (x > x2) x2 = x; - if (y < y1) y1 = y; - if (y > y2) y2 = y; - } else if (cmd !== 7) { - throw new Error('unknown command ' + cmd); - } - } - - return [x1, y1, x2, y2]; -}; -function VectorTileLayer(buffer, end) { - // Public - this.version = 1; - this.name = null; - this.extent = 4096; - this.length = 0; - - // Private - this._buffer = buffer; - this._keys = []; - this._values = []; - this._features = []; - - var val, tag; - - end = end || buffer.length; - - while (buffer.pos < end) { - val = buffer.readVarint(); - tag = val >> 3; - - if (tag === 15) { - this.version = buffer.readVarint(); - } else if (tag === 1) { - this.name = buffer.readString(); - } else if (tag === 5) { - this.extent = buffer.readVarint(); - } else if (tag === 2) { - this.length++; - this._features.push(buffer.pos); - buffer.skip(val); - } else if (tag === 3) { - this._keys.push(buffer.readString()); - } else if (tag === 4) { - this._values.push(this.readFeatureValue()); - } else { - buffer.skip(val); - } - } -} - -VectorTileLayer.prototype.readFeatureValue = function () { - var buffer = this._buffer, - value = null, - bytes = buffer.readVarint(), - end = buffer.pos + bytes, - val, tag; - - while (buffer.pos < end) { - val = buffer.readVarint(); - tag = val >> 3; - - if (tag == 1) { - value = buffer.readString(); - } else if (tag == 2) { - //throw new Error('read float'); - value = buffer.readFloat(); - } else if (tag == 3) { - value = buffer.readDouble(); - } else if (tag == 4) { - value = buffer.readVarint(); - } else if (tag == 5) { - //throw new Error('read uint'); - value = buffer.readVarint(); - } else if (tag == 6) { - value = buffer.readSVarint(); - } else if (tag == 7) { - value = Boolean(buffer.readVarint()); - } else { - buffer.skip(val); - } - } - - return value; -}; - -// return feature `i` from this layer as a `VectorTileFeature` -VectorTileLayer.prototype.feature = function (i) { - if (i < 0 || i >= this._features.length) throw new Error('feature index out of bounds'); - - this._buffer.pos = this._features[i]; - var end = this._buffer.readVarint() + this._buffer.pos; - - return new VectorTileFeature(this._buffer, end, this.extent, this._keys, this._values); -}; -function Point(x, y) { - this.x = x; - this.y = y; -} - -Point.prototype = { - clone: function () { return new Point(this.x, this.y); }, - - add: function (p) { return this.clone()._add(p); }, - sub: function (p) { return this.clone()._sub(p); }, - mult: function (k) { return this.clone()._mult(k); }, - div: function (k) { return this.clone()._div(k); }, - rotate: function (a) { return this.clone()._rotate(a); }, - matMult: function (m) { return this.clone()._matMult(m); }, - unit: function () { return this.clone()._unit(); }, - perp: function () { return this.clone()._perp(); }, - round: function () { return this.clone()._round(); }, - - mag: function () { - return Math.sqrt(this.x * this.x + this.y * this.y); - }, - - equals: function (p) { - return this.x === p.x && - this.y === p.y; - }, - - dist: function (p) { - return Math.sqrt(this.distSqr(p)); - }, - - distSqr: function (p) { - var dx = p.x - this.x, - dy = p.y - this.y; - return dx * dx + dy * dy; - }, - - angle: function () { - return Math.atan2(this.y, this.x); - }, - - angleTo: function (b) { - return Math.atan2(this.y - b.y, this.x - b.x); - }, - - angleWith: function (b) { - return this.angleWithSep(b.x, b.y); - }, - - // Find the angle of the two vectors, solving the formula for the cross product a x b = |a||b|sin(θ) for θ. - angleWithSep: function (x, y) { - return Math.atan2( - this.x * y - this.y * x, - this.x * x + this.y * y); - }, - - _matMult: function (m) { - var x = m[0] * this.x + m[1] * this.y, - y = m[2] * this.x + m[3] * this.y; - this.x = x; - this.y = y; - return this; - }, - - _add: function (p) { - this.x += p.x; - this.y += p.y; - return this; - }, - - _sub: function (p) { - this.x -= p.x; - this.y -= p.y; - return this; - }, - - _mult: function (k) { - this.x *= k; - this.y *= k; - return this; - }, - - _div: function (k) { - this.x /= k; - this.y /= k; - return this; - }, - - _unit: function () { - this._div(this.mag()); - return this; - }, - - _perp: function () { - var y = this.y; - this.y = this.x; - this.x = -y; - return this; - }, - - _rotate: function (angle) { - var cos = Math.cos(angle), - sin = Math.sin(angle), - x = cos * this.x - sin * this.y, - y = sin * this.x + cos * this.y; - this.x = x; - this.y = y; - return this; - }, - - _round: function () { - this.x = Math.round(this.x); - this.y = Math.round(this.y); - return this; - } -}; - -// constructs Point from an array if necessary -Point.convert = function (a) { - if (a instanceof Point) { - return a; - } - if (Array.isArray(a)) { - return new Point(a[0], a[1]); - } - return a; -}; -MERCATOR = { - fromLatLngToPoint: function (latLng) { - var siny = Math.min(Math.max(Math.sin(latLng.lat() * (Math.PI / 180)), - -.9999), - .9999); - return { - x: 128 + latLng.lng() * (256 / 360), - y: 128 + 0.5 * Math.log((1 + siny) / (1 - siny)) * -(256 / (2 * Math.PI)) - }; - }, - - fromPointToLatLng: function (point) { - return { - lat: (2 * Math.atan(Math.exp((point.y - 128) / -(256 / (2 * Math.PI)))) - - Math.PI / 2) / (Math.PI / 180), - lng: (point.x - 128) / (256 / 360) - }; - }, - - getTileAtLatLng: function (latLng, zoom) { - var t = Math.pow(2, zoom), - s = 256 / t, - p = this.fromLatLngToPoint(latLng); - return { - x: Math.floor(p.x / s), - y: Math.floor(p.y / s), - z: zoom - }; - }, - - getTileBounds: function (tile) { - tile = this.normalizeTile(tile); - var t = Math.pow(2, tile.z), - s = 256 / t, - sw = { - x: tile.x * s, - y: (tile.y * s) + s - }, - ne = { - x: tile.x * s + s, - y: (tile.y * s) - }; - return { - sw: this.fromPointToLatLng(sw), - ne: this.fromPointToLatLng(ne) - } - }, - - normalizeTile: function (tile) { - var t = Math.pow(2, tile.z); - tile.x = ((tile.x % t) + t) % t; - tile.y = ((tile.y % t) + t) % t; - return tile; - }, - - fromLatLngToPixels: function (map, latLng) { - var bounds = map.getBounds(); - var ne = bounds.getNorthEast(); - var sw = bounds.getSouthWest(); - var topRight = map.getProjection().fromLatLngToPoint(ne); - var bottomLeft = map.getProjection().fromLatLngToPoint(sw); - var scale = Math.pow(2, map.getZoom()); - var worldPoint = map.getProjection().fromLatLngToPoint(latLng); - return { - x: (worldPoint.x - bottomLeft.x) * scale, - y: (worldPoint.y - topRight.y) * scale - } - }, - - fromLatLngToTilePoint: function (map, evt) { - var zoom = map.getZoom(); - var tile = this.getTileAtLatLng(evt.latLng, zoom); - var tileBounds = this.getTileBounds(tile); - var tileSwLatLng = new google.maps.LatLng(tileBounds.sw); - var tileNeLatLng = new google.maps.LatLng(tileBounds.ne); - var tileSwPixels = this.fromLatLngToPixels(map, tileSwLatLng); - var tileNePixels = this.fromLatLngToPixels(map, tileNeLatLng); - return { - x: evt.pixel.x - tileSwPixels.x, - y: evt.pixel.y - tileNePixels.y - } - }, - - // todo: sometimes it does not work properly - isPointInPolygon: function (point, polygon) { - if (polygon && polygon.length) { - for (var c = false, i = -1, l = polygon.length, j = l - 1; ++i < l; j = i) { - ((polygon[i].y <= point.y && point.y < polygon[j].y) || (polygon[j].y <= point.y && point.y < polygon[i].y)) - && (point.x < (polygon[j].x - polygon[i].x) * (point.y - polygon[i].y) / (polygon[j].y - polygon[i].y) + polygon[i].x) - && (c = !c); - } - return c; - } - }, - - in_circle: function (center_x, center_y, radius, x, y) { - var square_dist = Math.pow((center_x - x), 2) + Math.pow((center_y - y), 2); - return square_dist <= Math.pow(radius, 2); - }, - - getDistanceFromLine: function (point, line) { - var minDistance = Number.POSITIVE_INFINITY; - if (line && line.length > 1) { - for (var i = 0, l = line.length - 1; i < l; i++) { - var distance = this.projectPointOnLineSegment(point, line[i], line[i + 1]); - if (distance <= minDistance) { - minDistance = distance; - } - } - } - return minDistance; - }, - - projectPointOnLineSegment: function (point, r0, r1) { - var x = point.x; - var y = point.y; - var x1 = r0.x; - var y1 = r0.y; - var x2 = r1.x; - var y2 = r1.y; - - var A = x - x1; - var B = y - y1; - var C = x2 - x1; - var D = y2 - y1; - - var dot = A * C + B * D; - var len_sq = C * C + D * D; - var param = -1; - if (len_sq != 0) //in case of 0 length line - param = dot / len_sq; - - var xx, yy; - - if (param < 0) { - xx = x1; - yy = y1; - } - else if (param > 1) { - xx = x2; - yy = y2; - } - else { - xx = x1 + param * C; - yy = y1 + param * D; - } - - var dx = x - xx; - var dy = y - yy; - return Math.sqrt(dx * dx + dy * dy); - } -} -/* - * Created by Jes�s Barrio on 04/2021 - */ - -class MVTFeature { - constructor(options) { - this.mVTSource = options.mVTSource; - this.selected = options.selected; - this.featureId = options.featureId; - this.tiles = []; - this.style = options.style; - this.type = options.vectorTileFeature.type; - this.properties = options.vectorTileFeature.properties; - this.addTileFeature(options.vectorTileFeature, options.tileContext); - this._draw = options.customDraw || this.defaultDraw; - - if (this.selected) { - this.select(); - } - } - - addTileFeature(vectorTileFeature, tileContext) { - this.tiles[tileContext.id] = { - vectorTileFeature: vectorTileFeature, - divisor: vectorTileFeature.extent / tileContext.tileSize, - context2d: false, - paths2d: false - }; - } - - getTiles() { - return this.tiles; - } - - getTile(tileContext) { - return this.tiles[tileContext.id]; - } - - setStyle(style) { - this.style = style; - } - - redrawTiles() { - var zoom = this.mVTSource.map.getZoom(); - for (var id in this.tiles) { - this.mVTSource.deleteTileDrawn(id); - var idObject = this.mVTSource.getTileObject(id); - if (idObject.zoom == zoom) { - this.mVTSource.redrawTile(id); - } - } - } - - toggle() { - if (this.selected) { - this.deselect(); - } else { - this.select(); - } - } - - select() { - this.selected = true; - this.mVTSource.featureSelected(this); - this.redrawTiles(); - } - - deselect() { - this.selected = false; - this.mVTSource.featureDeselected(this); - this.redrawTiles(); - } - - setSelected(selected) { - this.selected = selected; - } - - draw(tileContext) { - var tile = this.tiles[tileContext.id]; - var style = this.style; - if (this.selected && this.style.selected) { - style = this.style.selected; - } - - this._draw(tileContext, tile, style, this); - } - - defaultDraw(tileContext, tile, style) { - switch (this.type) { - case 1: //Point - this.drawPoint(tileContext, tile, style); - break; - - case 2: //LineString - this.drawLineString(tileContext, tile, style); - break; - - case 3: //Polygon - this.drawPolygon(tileContext, tile, style); - break; - } - } - - drawPoint(tileContext, tile, style) { - var coordinates = tile.vectorTileFeature.coordinates[0][0]; - var point = this.getPoint(coordinates, tileContext, tile.divisor); - var radius = style.radius || 3; - var context2d = this.getContext2d(tileContext.canvas, style); - context2d.beginPath(); - context2d.arc(point.x, point.y, radius, 0, Math.PI * 2); - context2d.closePath(); - context2d.fill(); - context2d.stroke(); - } - - drawLineString(tileContext, tile, style) { - tile.context2d = this.getContext2d(tileContext.canvas, style); - this.drawCoordinates(tileContext, tile); - tile.context2d.stroke(tile.paths2d); - } - - drawPolygon(tileContext, tile, style) { - tile.context2d = this.getContext2d(tileContext.canvas, style); - this.drawCoordinates(tileContext, tile); - tile.paths2d.closePath(); - - if (style.fillStyle) { - tile.context2d.fill(tile.paths2d); - } - if (style.strokeStyle) { - tile.context2d.stroke(tile.paths2d); - } - } - - drawCoordinates(tileContext, tile) { - var coordinates = tile.vectorTileFeature.coordinates; - tile.paths2d = new Path2D(); - for (var i = 0, length1 = coordinates.length; i < length1; i++) { - var coordinate = coordinates[i]; - let path2 = new Path2D(); - for (var j = 0, length2 = coordinate.length; j < length2; j++) { - var point = this.getPoint(coordinate[j], tileContext, tile.divisor); - if (j == 0) { - path2.moveTo(point.x, point.y); - } - else { - path2.lineTo(point.x, point.y); - } - } - tile.paths2d.addPath(path2); - } - } - - getPaths(tileContext) { - var paths = []; - var tile = this.tiles[tileContext.id]; - var coordinates = tile.vectorTileFeature.coordinates; - for (var i = 0, length1 = coordinates.length; i < length1; i++) { - var path = []; - var coordinate = coordinates[i]; - for (var j = 0, length2 = coordinate.length; j < length2; j++) { - var point = this.getPoint(coordinate[j], tileContext, tile.divisor); - path.push(point); - } - if (path.length > 0) { - paths.push(path); - } - } - return paths; - } - - getContext2d(canvas, style) { - var context2d = canvas.getContext('2d'); - for (var key in style) { - if (key === 'selected') { - continue; - } - context2d[key] = style[key]; - } - return context2d; - } - - getPoint(coords, tileContext, divisor) { - var point = { - x: coords.x / divisor, - y: coords.y / divisor - }; - - if (tileContext.parentId) { - point = this._getOverzoomedPoint(point, tileContext); - } - return point; - } - - _getOverzoomedPoint(point, tileContext) { - var parentTile = this.mVTSource.getTileObject(tileContext.parentId); - var currentTile = this.mVTSource.getTileObject(tileContext.id); - var zoomDistance = currentTile.zoom - parentTile.zoom; - - const scale = Math.pow(2, zoomDistance); - - let xScale = point.x * scale; - let yScale = point.y * scale; - - let xtileOffset = currentTile.x % scale; - let ytileOffset = currentTile.y % scale; - - point.x = xScale - (xtileOffset * tileContext.tileSize); - point.y = yScale - (ytileOffset * tileContext.tileSize); - - return point; - } - - isPointInPath(point, tileContext) { - var tile = this.getTile(tileContext); - var context2d = tile.context2d; - var paths2d = tile.paths2d; - if (!context2d || !paths2d) { - return false; - } - return context2d.isPointInPath(paths2d, point.x, point.y) - } -} -/* - * Created by Jes�s Barrio on 04/2021 - */ - -class MVTLayer { - constructor(options) { - this._lineClickTolerance = 2; - this._getIDForLayerFeature = options.getIDForLayerFeature; - this.style = options.style; - this.name = options.name; - this._filter = options.filter || false; - this._customDraw = options.customDraw || false; - this._canvasAndMVTFeatures = []; - this._mVTFeatures = []; - } - - parseVectorTileFeatures(mVTSource, vectorTileFeatures, tileContext) { - this._canvasAndMVTFeatures[tileContext.id] = { - canvas: tileContext.canvas, - features: [] - } - for (var i = 0, length = vectorTileFeatures.length; i < length; i++) { - var vectorTileFeature = vectorTileFeatures[i]; - this._parseVectorTileFeature(mVTSource, vectorTileFeature, tileContext, i); - } - this.drawTile(tileContext); - } - - _parseVectorTileFeature(mVTSource, vectorTileFeature, tileContext, i) { - if (this._filter && typeof this._filter === 'function') { - if (this._filter(vectorTileFeature, tileContext) === false) { - return; - } - } - - var style = this.getStyle(vectorTileFeature); - var featureId = this._getIDForLayerFeature(vectorTileFeature) || i; - var mVTFeature = this._mVTFeatures[featureId]; - if (!mVTFeature) { - var selected = mVTSource.isFeatureSelected(featureId); - var options = { - mVTSource: mVTSource, - vectorTileFeature: vectorTileFeature, - tileContext: tileContext, - style: style, - selected: selected, - featureId: featureId, - customDraw: this._customDraw - } - mVTFeature = new MVTFeature(options); - this._mVTFeatures[featureId] = mVTFeature; - } else { - mVTFeature.setStyle(style); - mVTFeature.addTileFeature(vectorTileFeature, tileContext); - } - this._canvasAndMVTFeatures[tileContext.id].features.push(mVTFeature); - } - - drawTile(tileContext) { - var mVTFeatures = this._canvasAndMVTFeatures[tileContext.id].features; - if (!mVTFeatures) return; - var selectedFeatures = []; - for (var i = 0, length = mVTFeatures.length; i < length; i++) { - var mVTFeature = mVTFeatures[i]; - if (mVTFeature.selected) { - selectedFeatures.push(mVTFeature); - } else { - mVTFeature.draw(tileContext); - } - } - for (var i = 0, length = selectedFeatures.length; i < length; i++) { - selectedFeatures[i].draw(tileContext); - } - } - - getCanvas(id) { - return this._canvasAndMVTFeatures[id].canvas; - } - - getStyle(feature) { - if (typeof this.style === 'function') { - return this.style(feature); - } - return this.style; - } - - setStyle(style) { - this.style = style; - for (var featureId in this._mVTFeatures) { - this._mVTFeatures[featureId].setStyle(style); - } - } - - setSelected(featureId) { - if (this._mVTFeatures[featureId] !== undefined) { - this._mVTFeatures[featureId].select(); - } - } - - setFilter(filter) { - this._filter = filter; - } - - handleClickEvent(event, mVTSource) { - var canvasAndFeatures = this._canvasAndMVTFeatures[event.tileContext.id]; - if (!canvasAndFeatures) return event; - var canvas = canvasAndFeatures.canvas; - var mVTFeatures = canvasAndFeatures.features; - - if (!canvas || !mVTFeatures) { - return event; - } - event.feature = this._handleClickEvent(event, mVTFeatures, mVTSource); - return event; - } - - _handleClickEvent(event, mVTFeatures, mVTSource) { - this.selectedFeature = null; - - var tileContextId = event.tileContext.id; - var currentSelectedFeaturesInTile = mVTSource.getSelectedFeaturesInTile(tileContextId); - this._handleClickFeatures(event, currentSelectedFeaturesInTile); - - if (this.selectedFeature != null) { - return this.selectedFeature; - } - - this._handleClickFeatures(event, mVTFeatures); - if (this.selectedFeature != null) { - return this.selectedFeature; - } - - return this.selectedFeature; - } - - _handleClickFeatures(event, mVTFeatures) { - this.minDistance = Number.POSITIVE_INFINITY; - - for (var i = mVTFeatures.length - 1; i >= 0; i--) { - var mVTFeature = mVTFeatures[i]; - this._handleClickFeature(event, mVTFeature); - if (this.selectedFeature != null) { - return this.selectedFeature; - } - } - } - - _handleClickFeature(event, mVTFeature) { - switch (mVTFeature.type) { - case 3:// polygon - this._handleClickFeaturePolygon(event, mVTFeature); - break; - default: { - this._handleClickFeatureDefault(event, mVTFeature); - break; - } - } - } - - _handleClickFeaturePolygon(event, mVTFeature) { - if (mVTFeature.isPointInPath(event.tilePoint, event.tileContext)) { - this.selectedFeature = mVTFeature; - this.minDistance = 0; - } - } - - _handleClickFeatureDefault(event, mVTFeature) { - var paths = mVTFeature.getPaths(event.tileContext); - for (var j = paths.length - 1; j >= 0; j--) { - var path = paths[j]; - switch (mVTFeature.type) { - case 1: // Point - if (MERCATOR.in_circle(path[0].x, path[0].y, mVTFeature.style.radius, event.tilePoint.x, event.tilePoint.y)) { - this.selectedFeature = mVTFeature; - this.minDistance = 0; - } - break; - case 2: // LineString - var distance = MERCATOR.getDistanceFromLine(event.tilePoint, path); - var thickness = (mVTFeature.selected && mVTFeature.style.selected ? mVTFeature.style.selected.lineWidth : mVTFeature.style.lineWidth); - if (distance < thickness / 2 + this._lineClickTolerance && distance < this.minDistance) { - this.selectedFeature = mVTFeature; - this.minDistance = distance; - } - break; - } - if (this.minDistance == 0) { - return this.selectedFeature; - } - } - } -}; -/* - * Created by Jes�s Barrio on 04/2021 - */ - -class MVTSource { - constructor(map, options) { - var self = this; - this.map = map; - this._url = options.url || ""; //Url TO Vector Tile Source, - this._sourceMaxZoom = options.sourceMaxZoom || false; // Source maxzoom to enable overzoom - this._debug = options.debug || false; // Draw tiles lines and ids - this.getIDForLayerFeature = options.getIDForLayerFeature || function (feature) { - return feature.properties.id || feature.properties.Id || feature.properties.ID; - }; - this._visibleLayers = options.visibleLayers || false; // List of visible layers - this._xhrHeaders = options.xhrHeaders || {}; // Headers added to every url request - this._clickableLayers = options.clickableLayers || false; // List of layers that are clickable - this._filter = options.filter || false; // Filter features - this._cache = options.cache || false; // Load tiles in cache to avoid duplicated requests - this._tileSize = options.tileSize || 256; // Default tile size - this.tileSize = new google.maps.Size(this._tileSize, this._tileSize); - this.style = options.style || function (feature) { - var style = {}; - switch (feature.type) { - case 1: //'Point' - style.fillStyle = 'rgba(49,79,79,1)'; - style.radius = 5; - style.selected = { - fillStyle: 'rgba(255,255,0,0.5)', - radius: 6 - } - break; - case 2: //'LineString' - style.strokeStyle = 'rgba(136, 86, 167, 1)'; - style.lineWidth = 3; - style.selected = { - strokeStyle: 'rgba(255,25,0,0.5)', - lineWidth: 4 - } - break; - case 3: //'Polygon' - style.fillStyle = 'rgba(188, 189, 220, 0.5)'; - style.strokeStyle = 'rgba(136, 86, 167, 1)'; - style.lineWidth = 1; - style.selected = { - fillStyle: 'rgba(255,140,0,0.3)', - strokeStyle: 'rgba(255,140,0,1)', - lineWidth: 2 - } - break; - } - return style; - }; - this._customDraw = options.customDraw || false; - - this.mVTLayers = []; //Keep a list of the layers contained in the PBFs - this._tilesDrawn = []; // List of tiles drawn (when cache enabled) - this._visibleTiles = []; // tiles currently in the viewport - this._selectedFeatures = []; // list of selected features - if (options.selectedFeatures) { - this.setSelectedFeatures(options.selectedFeatures); - } - - this.map.addListener("zoom_changed", () => { - self._zoomChanged(); - }); - } - - getTile(coord, zoom, ownerDocument) { - var tileContext = this.drawTile(coord, zoom, ownerDocument); - this._setVisibleTile(tileContext); - return tileContext.canvas; - } - - releaseTile(canvas) { - //this._deleteVisibleTile(canvas.id); - } - - _zoomChanged() { - this._resetVisibleTiles(); - if (!this._cache) { - this._resetMVTLayers(); - } - } - - _resetMVTLayers() { - this.mVTLayers = []; - } - - _deleteVisibleTile(id) { - delete this._visibleTiles[id]; - } - - _resetVisibleTiles() { - this._visibleTiles = []; - } - - _setVisibleTile(tileContext) { - this._visibleTiles[tileContext.id] = tileContext; - } - - drawTile(coord, zoom, ownerDocument) { - var id = this.getTileId(zoom, coord.x, coord.y); - var tileContext = this._tilesDrawn[id]; - if (tileContext) { - return tileContext; - } - - tileContext = this._createTileContext(coord, zoom, ownerDocument); - this._xhrRequest(tileContext); - return tileContext; - } - - _createTileContext(coord, zoom, ownerDocument) { - var id = this.getTileId(zoom, coord.x, coord.y); - var canvas = this._createCanvas(ownerDocument, id); - var parentId = this._getParentId(id); - - return { - id: id, - canvas: canvas, - zoom: zoom, - tileSize: this._tileSize, - parentId: parentId - }; - } - - _getParentId(id) { - var parentId = false; - if (this._sourceMaxZoom) { - var tile = this.getTileObject(id); - if (tile.zoom > this._sourceMaxZoom) { - var zoomDistance = tile.zoom - this._sourceMaxZoom; - var zoom = tile.zoom - zoomDistance; - var x = tile.x >> zoomDistance; - var y = tile.y >> zoomDistance; - parentId = this.getTileId(zoom, x, y); - } - } - return parentId; - } - - _createCanvas(ownerDocument, id) { - const canvas = ownerDocument.createElement("canvas"); - canvas.width = this._tileSize; - canvas.height = this._tileSize; - canvas.id = id; - return canvas; - } - - getTileId(zoom, x, y) { - return [zoom, x, y].join(":"); - } - - getTileObject(id) { - var values = id.split(":"); - return { - zoom: values[0], - x: values[1], - y: values[2] - } - } - - _xhrRequest(tileContext) { - var self = this; - - var id = tileContext.parentId || tileContext.id; - var tile = this.getTileObject(id); - - var src = this._url - .replace("{z}", tile.zoom) - .replace("{x}", tile.x) - .replace("{y}", tile.y); - - var xmlHttpRequest = new XMLHttpRequest(); - xmlHttpRequest.onload = function () { - if (xmlHttpRequest.status == "200" && xmlHttpRequest.response) { - return self._xhrResponseOk(tileContext, xmlHttpRequest.response) - } - self._drawDebugInfo(tileContext); - }; - xmlHttpRequest.open('GET', src, true); - for (var header in this._xhrHeaders) { - xmlHttpRequest.setRequestHeader(header, this._xhrHeaders[header]); - } - xmlHttpRequest.responseType = 'arraybuffer'; - xmlHttpRequest.send(); - } - - _xhrResponseOk(tileContext, response) { - if (this.map.getZoom() != tileContext.zoom) { - return; - } - var uint8Array = new Uint8Array(response); - var pbf = new Pbf(uint8Array); - var vectorTile = new VectorTile(pbf); - this._drawVectorTile(vectorTile, tileContext); - } - - _setTileDrawn(tileContext) { - if (!this._cache) return; - this._tilesDrawn[tileContext.id] = tileContext; - } - - deleteTileDrawn(id) { - delete this._tilesDrawn[id]; - } - - _resetTileDrawn() { - this._tilesDrawn = []; - } - - _drawVectorTile(vectorTile, tileContext) { - if (this._visibleLayers) { - for (var i = 0, length = this._visibleLayers.length; i < length; i++) { - var key = this._visibleLayers[i]; - if (vectorTile.layers[key]) { - var vectorTileLayer = vectorTile.layers[key]; - this._drawVectorTileLayer(vectorTileLayer, key, tileContext); - } - } - } else { - for (var key in vectorTile.layers) { - var vectorTileLayer = vectorTile.layers[key]; - this._drawVectorTileLayer(vectorTileLayer, key, tileContext); - } - } - tileContext.vectorTile = vectorTile; - this._drawDebugInfo(tileContext); - this._setTileDrawn(tileContext); - } - - _drawVectorTileLayer(vectorTileLayer, key, tileContext) { - if (!this.mVTLayers[key]) { - this.mVTLayers[key] = this._createMVTLayer(key); - } - var mVTLayer = this.mVTLayers[key]; - mVTLayer.parseVectorTileFeatures(this, vectorTileLayer.parsedFeatures, tileContext); - } - - _createMVTLayer(key) { - var options = { - getIDForLayerFeature: this.getIDForLayerFeature, - filter: this._filter, - style: this.style, - name: key, - customDraw: this._customDraw - }; - return new MVTLayer(options); - } - - _drawDebugInfo(tileContext) { - if (!this._debug) return; - var tile = this.getTileObject(tileContext.id) - var width = this._tileSize; - var height = this._tileSize; - var context2d = tileContext.canvas.getContext('2d'); - context2d.strokeStyle = '#000000'; - context2d.fillStyle = '#FFFF00'; - context2d.strokeRect(0, 0, width, height); - context2d.font = "12px Arial"; - context2d.fillRect(0, 0, 5, 5); - context2d.fillRect(0, height - 5, 5, 5); - context2d.fillRect(width - 5, 0, 5, 5); - context2d.fillRect(width - 5, height - 5, 5, 5); - context2d.fillRect(width / 2 - 5, height / 2 - 5, 10, 10); - context2d.strokeText(tileContext.zoom + ' ' + tile.x + ' ' + tile.y, width / 2 - 30, height / 2 - 10); - } - - onClick(event, callbackFunction, options) { - this._multipleSelection = (options && options.multipleSelection) || false; - options = this._getMouseOptions(options, false); - this._mouseEvent(event, callbackFunction, options); - } - - onMouseHover(event, callbackFunction, options) { - this._multipleSelection = false; - options = this._getMouseOptions(options, true); - this._mouseEvent(event, callbackFunction, options); - } - - _getMouseOptions(options, mouseHover) { - return { - mouseHover: mouseHover, - setSelected: options.setSelected || false, - toggleSelection: (options.toggleSelection === undefined || options.toggleSelection), - limitToFirstVisibleLayer: options.limitToFirstVisibleLayer || false, - delay: options.delay || 0 - } - } - - _mouseEvent(event, callbackFunction, options) { - if (!event.pixel || !event.latLng) return; - - if (options.delay == 0) { - return this._mouseEventContinue(event, callbackFunction, options); - } - - this.event = event; - var me = this; - setTimeout(function () { - if (event != me.event) return; - me._mouseEventContinue(me.event, callbackFunction, options); - }, options.delay, event); - - - } - _mouseEventContinue(event, callbackFunction, options) { - callbackFunction = callbackFunction || function () { }; - var limitToFirstVisibleLayer = options.limitToFirstVisibleLayer || false; - var zoom = this.map.getZoom(); - var tile = MERCATOR.getTileAtLatLng(event.latLng, zoom); - var id = this.getTileId(tile.z, tile.x, tile.y); - var tileContext = this._visibleTiles[id]; - if (!tileContext) { - return; - } - event.tileContext = tileContext; - event.tilePoint = MERCATOR.fromLatLngToTilePoint(this.map, event); - - var clickableLayers = this._clickableLayers || Object.keys(this.mVTLayers) || []; - for (var i = clickableLayers.length - 1; i >= 0; i--) { - var key = clickableLayers[i]; - var layer = this.mVTLayers[key]; - if (layer) { - var event = layer.handleClickEvent(event, this); - this._mouseSelectedFeature(event, callbackFunction, options); - if (limitToFirstVisibleLayer && event.feature) { - break; - } - } - } - } - - _mouseSelectedFeature(event, callbackFunction, options) { - if (options.setSelected) { - var feature = event.feature; - if (feature) { - if (options.mouseHover) { - if (!feature.selected) { - feature.select(); - } - } - else { - if (options.toggleSelection) { - feature.toggle(); - } - else { - if (!feature.selected) { - feature.select(); - } - } - } - } - else { - if (options.mouseHover) { - this.deselectAllFeatures(); - } - } - } - callbackFunction(event); - } - - deselectAllFeatures() { - var zoom = this.map.getZoom(); - var tilesToRedraw = []; - for (var featureId in this._selectedFeatures) { - var mVTFeature = this._selectedFeatures[featureId]; - if (!mVTFeature) continue; - mVTFeature.setSelected(false); - var tiles = mVTFeature.getTiles(); - for (var id in tiles) { - this.deleteTileDrawn(id); - var idObject = this.getTileObject(id); - if (idObject.zoom == zoom) { - tilesToRedraw[id] = true; - } - } - } - this.redrawTiles(tilesToRedraw); - this._selectedFeatures = []; - } - - featureSelected(mVTFeature) { - if (!this._multipleSelection) { - this.deselectAllFeatures(); - } - this._selectedFeatures[mVTFeature.featureId] = mVTFeature; - } - - featureDeselected(mvtFeature) { - delete this._selectedFeatures[mvtFeature.featureId]; - } - - setSelectedFeatures(featuresIds) { - if (featuresIds.length > 1) { - this._multipleSelection = true; - } - this.deselectAllFeatures(); - for (var i = 0, length = featuresIds.length; i < length; i++) { - var featureId = featuresIds[i]; - this._selectedFeatures[featureId] = false; - for (var key in this.mVTLayers) { - this.mVTLayers[key].setSelected(featureId); - } - } - } - - isFeatureSelected(featureId) { - return this._selectedFeatures[featureId] != undefined; - } - - getSelectedFeatures() { - var selectedFeatures = []; - for (var featureId in this._selectedFeatures) { - selectedFeatures.push(this._selectedFeatures[featureId]); - } - return selectedFeatures; - } - - getSelectedFeaturesInTile(tileContextId) { - var selectedFeatures = []; - for (var featureId in this._selectedFeatures) { - var selectedFeature = this._selectedFeatures[featureId]; - for (var tile in selectedFeature.tiles) { - if (tile == tileContextId) { - selectedFeatures.push(selectedFeature); - } - } - } - return selectedFeatures; - } - - setFilter(filter, redrawTiles) { - redrawTiles = (redrawTiles === undefined || redrawTiles); - this._filter = filter; - for (var key in this.mVTLayers) { - this.mVTLayers[key].setFilter(filter); - } - if (redrawTiles) { - this.redrawAllTiles(); - } - } - - setStyle(style, redrawTiles) { - redrawTiles = (redrawTiles === undefined || redrawTiles); - this.style = style - for (var key in this.mVTLayers) { - this.mVTLayers[key].setStyle(style); - } - - if (redrawTiles) { - this.redrawAllTiles(); - } - } - - setVisibleLayers(visibleLayers, redrawTiles) { - redrawTiles = (redrawTiles === undefined || redrawTiles); - this._visibleLayers = visibleLayers; - if (redrawTiles) { - this.redrawAllTiles(); - } - } - - getVisibleLayers() { - return this._visibleLayers; - } - - setClickableLayers(clickableLayers) { - this._clickableLayers = clickableLayers; - } - - redrawAllTiles() { - this._resetTileDrawn(); - this.redrawTiles(this._visibleTiles); - } - - redrawTiles(tiles) { - for (var id in tiles) { - this.redrawTile(id); - } - } - - redrawTile(id) { - this.deleteTileDrawn(id); - var tileContext = this._visibleTiles[id]; - if (!tileContext || !tileContext.vectorTile) return; - this.clearTile(tileContext.canvas); - this._drawVectorTile(tileContext.vectorTile, tileContext); - } - - clearTile(canvas) { - var context = canvas.getContext('2d'); - context.clearRect(0, 0, canvas.width, canvas.height); - } - - setUrl(url, redrawTiles) { - redrawTiles = (redrawTiles === undefined || redrawTiles); - this._url = url; - this._resetMVTLayers(); - if (redrawTiles) { - this.redrawAllTiles(); - } - } -} \ No newline at end of file diff --git a/dist/vector-tiles-google-maps.min.js b/dist/vector-tiles-google-maps.min.js deleted file mode 100644 index 3738d52..0000000 --- a/dist/vector-tiles-google-maps.min.js +++ /dev/null @@ -1 +0,0 @@ -function VectorTile(n,t){var r,u,i;for(this.layers={},this._buffer=n,t=t||n.length;n.pos>3,u==3?(i=this._readLayer(),i.length&&(this.layers[i.name]=i)):n.skip(r);this.parseGeometries()}function VectorTileFeature(n,t,i,r,u){var e,f,o,s,h,c;for(this.properties={},this.extent=i,this.type=0,this._buffer=n,this._geometry=-1,t=t||n.length;n.pos>3,f==1)this._id=n.readVarint();else if(f==2)for(o=n.readVarint(),s=n.pos+o;n.pos>3,i===15?this.version=n.readVarint():i===1?this.name=n.readString():i===5?this.extent=n.readVarint():i===2?(this.length++,this._features.push(n.pos),n.skip(r)):i===3?this._keys.push(n.readString()):i===4?this._values.push(this.readFeatureValue()):n.skip(r)}function Point(n,t){this.x=n;this.y=t}!function(n){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=n();else if("function"==typeof define&&define.amd)define([],n);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this;t.Pbf=n()}}(function(){return function n(t,i,r){function u(f,o){var h,c,s;if(!i[f]){if(!t[f]){if(h="function"==typeof require&&require,!o&&h)return h(f,!0);if(e)return e(f,!0);c=new Error("Cannot find module '"+f+"'");throw c.code="MODULE_NOT_FOUND",c;}s=i[f]={exports:{}};t[f][0].call(s.exports,function(n){var i=t[f][1][n];return u(i?i:n)},s,s.exports,n,t,i,r)}return i[f].exports}for(var e="function"==typeof require&&require,f=0;f>4,r<128)||(r=e[i.pos++],f|=(127&r)<<3,r<128)||(r=e[i.pos++],f|=(127&r)<<10,r<128)||(r=e[i.pos++],f|=(127&r)<<17,r<128)||(r=e[i.pos++],f|=(127&r)<<24,r<128)||(r=e[i.pos++],f|=(1&r)<<31,r<128))return u(n,f,t);throw new Error("Expected varint not more than 10 bytes");}function r(n){return n.type===i.Bytes?n.readVarint()+n.pos:n.pos+1}function u(n,t,i){return i?4294967296*t+(n>>>0):4294967296*(t>>>0)+(n>>>0)}function v(n,t){var i,r;if(n>=0?(i=n%4294967296|0,r=n/4294967296|0):(i=~(-n%4294967296),r=~(-n/4294967296),4294967295^i?i=i+1|0:(i=0,r=r+1|0)),n>=0x10000000000000000||n<-0x10000000000000000)throw new Error("Given varint doesn't fit into 10 bytes");t.realloc(10);y(i,r,t);p(r,t)}function y(n,t,i){i.buf[i.pos++]=127&n|128;n>>>=7;i.buf[i.pos++]=127&n|128;n>>>=7;i.buf[i.pos++]=127&n|128;n>>>=7;i.buf[i.pos++]=127&n|128;n>>>=7;i.buf[i.pos]=127&n}function p(n,t){var i=(7&n)<<4;t.buf[t.pos++]|=i|((n>>>=3)?128:0);n&&(t.buf[t.pos++]=127&n|((n>>>=7)?128:0),n&&(t.buf[t.pos++]=127&n|((n>>>=7)?128:0),n&&(t.buf[t.pos++]=127&n|((n>>>=7)?128:0),n&&(t.buf[t.pos++]=127&n|((n>>>=7)?128:0),n&&(t.buf[t.pos++]=127&n)))))}function c(n,t,i){var u=t<=16383?1:t<=2097151?2:t<=268435455?3:Math.ceil(Math.log(t)/(7*Math.LN2)),r;for(i.realloc(u),r=i.pos-1;r>=n;r--)i.buf[r+u]=i.buf[r]}function w(n,t){for(var i=0;i>>8;n[i+2]=t>>>16;n[i+3]=t>>>24}function l(n,t){return(n[t]|n[t+1]<<8|n[t+2]<<16)+(n[t+3]<<24)}function ut(n,t,i){for(var f,s,c,h="",u=t;u239?4:e>223?3:e>191?2:1;if(u+o>i)break;1===o?e<128&&(r=e):2===o?(f=n[u+1],128==(192&f)&&(r=(31&e)<<6|63&f,r<=127&&(r=null))):3===o?(f=n[u+1],s=n[u+2],128==(192&f)&&128==(192&s)&&(r=(15&e)<<12|(63&f)<<6|63&s,(r<=2047||r>=55296&&r<=57343)&&(r=null))):4===o&&(f=n[u+1],s=n[u+2],c=n[u+3],128==(192&f)&&128==(192&s)&&128==(192&c)&&(r=(15&e)<<18|(63&f)<<12|(63&s)<<6|63&c,(r<=65535||r>=1114112)&&(r=null)));null===r?(r=65533,o=1):r>65535&&(r-=65536,h+=String.fromCharCode(r>>>10&1023|55296),r=56320|1023&r);h+=String.fromCharCode(r);u+=o}return h}function ft(n,t,i){for(var r,u,f=0;f55295&&r<57344){if(!u){r>56319||f+1===t.length?(n[i++]=239,n[i++]=191,n[i++]=189):u=r;continue}if(r<56320){n[i++]=239;n[i++]=191;n[i++]=189;u=r;continue}r=u-55296<<10|r-56320|65536;u=null}else u&&(n[i++]=239,n[i++]=191,n[i++]=189,u=null);r<128?n[i++]=r:(r<2048?n[i++]=r>>6|192:(r<65536?n[i++]=r>>12|224:(n[i++]=r>>18|240,n[i++]=r>>12&63|128),n[i++]=r>>6&63|128),n[i++]=63&r|128)}return i}var e,s,h;t.exports=i;e=n("ieee754");i.Varint=0;i.Fixed64=1;i.Bytes=2;i.Fixed32=5;s=4294967296;h=1/s;i.prototype={destroy:function(){this.buf=null},readFields:function(n,t,i){for(i=i||this.length;this.pos>3,f=this.pos;this.type=7&r;n(u,t,this);this.pos===f&&this.skip(r)}return t},readMessage:function(n,t){return this.readFields(n,t,this.readVarint()+this.pos)},readFixed32:function(){var n=o(this.buf,this.pos);return this.pos+=4,n},readSFixed32:function(){var n=l(this.buf,this.pos);return this.pos+=4,n},readFixed64:function(){var n=o(this.buf,this.pos)+o(this.buf,this.pos+4)*s;return this.pos+=8,n},readSFixed64:function(){var n=o(this.buf,this.pos)+l(this.buf,this.pos+4)*s;return this.pos+=8,n},readFloat:function(){var n=e.read(this.buf,this.pos,!0,23,4);return this.pos+=4,n},readDouble:function(){var n=e.read(this.buf,this.pos,!0,52,8);return this.pos+=8,n},readVarint:function(n){var i,t,r=this.buf;return t=r[this.pos++],i=127&t,t<128?i:(t=r[this.pos++],i|=(127&t)<<7,t<128?i:(t=r[this.pos++],i|=(127&t)<<14,t<128?i:(t=r[this.pos++],i|=(127&t)<<21,t<128?i:(t=r[this.pos],i|=(15&t)<<28,a(i,n,this)))))},readVarint64:function(){return this.readVarint(!0)},readSVarint:function(){var n=this.readVarint();return n%2==1?(n+1)/-2:n/2},readBoolean:function(){return Boolean(this.readVarint())},readString:function(){var n=this.readVarint()+this.pos,t=ut(this.buf,this.pos,n);return this.pos=n,t},readBytes:function(){var n=this.readVarint()+this.pos,t=this.buf.subarray(this.pos,n);return this.pos=n,t},readPackedVarint:function(n,t){var i=r(this);for(n=n||[];this.pos127;);else if(t===i.Bytes)this.pos=this.readVarint()+this.pos;else if(t===i.Fixed32)this.pos+=4;else{if(t!==i.Fixed64)throw new Error("Unimplemented type: "+t);this.pos+=8}},writeTag:function(n,t){this.writeVarint(n<<3|t)},realloc:function(n){for(var i,t=this.length||16;t268435455||n<0?void v(n,this):(this.realloc(4),this.buf[this.pos++]=127&n|(n>127?128:0),void(n<=127||(this.buf[this.pos++]=127&(n>>>=7)|(n>127?128:0),n<=127||(this.buf[this.pos++]=127&(n>>>=7)|(n>127?128:0),n<=127||(this.buf[this.pos++]=n>>>7&127)))))},writeSVarint:function(n){this.writeVarint(n<0?2*-n-1:2*n)},writeBoolean:function(n){this.writeVarint(Boolean(n))},writeString:function(n){var i,t;n=String(n);this.realloc(4*n.length);this.pos++;i=this.pos;this.pos=ft(this.buf,n,this.pos);t=this.pos-i;t>=128&&c(i,t,this);this.pos=i-1;this.writeVarint(t);this.pos+=t},writeFloat:function(n){this.realloc(4);e.write(this.buf,n,this.pos,!0,23,4);this.pos+=4},writeDouble:function(n){this.realloc(8);e.write(this.buf,n,this.pos,!0,52,8);this.pos+=8},writeBytes:function(n){var i=n.length,t;for(this.writeVarint(i),this.realloc(i),t=0;t=128&&c(r,i,this);this.pos=r-1;this.writeVarint(i);this.pos+=i},writeMessage:function(n,t,r){this.writeTag(n,i.Bytes);this.writeRawMessage(t,r)},writePackedVarint:function(n,t){this.writeMessage(n,w,t)},writePackedSVarint:function(n,t){this.writeMessage(n,b,t)},writePackedBoolean:function(n,t){this.writeMessage(n,g,t)},writePackedFloat:function(n,t){this.writeMessage(n,k,t)},writePackedDouble:function(n,t){this.writeMessage(n,d,t)},writePackedFixed32:function(n,t){this.writeMessage(n,nt,t)},writePackedSFixed32:function(n,t){this.writeMessage(n,tt,t)},writePackedFixed64:function(n,t){this.writeMessage(n,it,t)},writePackedSFixed64:function(n,t){this.writeMessage(n,rt,t)},writeBytesField:function(n,t){this.writeTag(n,i.Bytes);this.writeBytes(t)},writeFixed32Field:function(n,t){this.writeTag(n,i.Fixed32);this.writeFixed32(t)},writeSFixed32Field:function(n,t){this.writeTag(n,i.Fixed32);this.writeSFixed32(t)},writeFixed64Field:function(n,t){this.writeTag(n,i.Fixed64);this.writeFixed64(t)},writeSFixed64Field:function(n,t){this.writeTag(n,i.Fixed64);this.writeSFixed64(t)},writeVarintField:function(n,t){this.writeTag(n,i.Varint);this.writeVarint(t)},writeSVarintField:function(n,t){this.writeTag(n,i.Varint);this.writeSVarint(t)},writeStringField:function(n,t){this.writeTag(n,i.Bytes);this.writeString(t)},writeFloatField:function(n,t){this.writeTag(n,i.Fixed32);this.writeFloat(t)},writeDoubleField:function(n,t){this.writeTag(n,i.Fixed64);this.writeDouble(t)},writeBooleanField:function(n,t){this.writeVarintField(n,Boolean(t))}}},{ieee754:2}],2:[function(n,t,i){i.read=function(n,t,i,r,u){var f,o,l=8*u-r-1,a=(1<>1,e=-7,s=i?u-1:0,c=i?-1:1,h=n[t+s];for(s+=c,f=h&(1<<-e)-1,h>>=-e,e+=l;e>0;f=256*f+n[t+s],s+=c,e-=8);for(o=f&(1<<-e)-1,f>>=-e,e+=r;e>0;o=256*o+n[t+s],s+=c,e-=8);if(0===f)f=1-v;else{if(f===a)return o?NaN:(h?-1:1)*(1/0);o+=Math.pow(2,r);f-=v}return(h?-1:1)*o*Math.pow(2,f-r)};i.write=function(n,t,i,r,u,f){var e,o,s,l=8*f-u-1,a=(1<>1,y=23===u?Math.pow(2,-24)-Math.pow(2,-77):0,c=r?0:f-1,v=r?1:-1,p=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(o=isNaN(t)?1:0,e=a):(e=Math.floor(Math.log(t)/Math.LN2),t*(s=Math.pow(2,-e))<1&&(e--,s*=2),t+=e+h>=1?y/s:y*Math.pow(2,1-h),t*s>=2&&(e++,s/=2),e+h>=a?(o=0,e=a):e+h>=1?(o=(t*s-1)*Math.pow(2,u),e+=h):(o=t*Math.pow(2,h-1)*Math.pow(2,u),e=0));u>=8;n[i+c]=255&o,c+=v,o/=256,u-=8);for(e=e<0;n[i+c]=255&e,c+=v,e/=256,l-=8);n[i+c-v]|=128*p}},{}]},{},[1])(1)});VectorTile.prototype._readLayer=function(){var n=this._buffer,i=n.readVarint(),t=n.pos+i,r=new VectorTileLayer(n,t);return n.pos=t,r};VectorTile.prototype.parseGeometries=function(){var r,n,u,t,f,i;for(r in this.layers)for(n=this.layers[r],n.parsedFeatures=[],u=n._features.length,t=0,f=u;t>3),r--,i===1||i===2)e+=t.readSVarint(),o+=t.readSVarint(),i===1&&(n&&u.push(n),n=[]),n.push(new Point(e,o));else if(i===7)n.push(n[0].clone());else throw new Error("unknown command "+i);return n&&u.push(n),u};VectorTileFeature.prototype.bbox=function(){var n=this._buffer,h;n.pos=this._geometry;for(var c=n.readVarint(),l=n.pos+c,t=1,u=0,i=0,r=0,f=Infinity,e=-Infinity,o=Infinity,s=-Infinity;n.pos>3),u--,t===1||t===2)i+=n.readSVarint(),r+=n.readSVarint(),ie&&(e=i),rs&&(s=r);else if(t!==7)throw new Error("unknown command "+t);return[f,o,e,s]};VectorTileLayer.prototype.readFeatureValue=function(){for(var n=this._buffer,t=null,u=n.readVarint(),f=n.pos+u,r,i;n.pos>3,i==1?t=n.readString():i==2?t=n.readFloat():i==3?t=n.readDouble():i==4?t=n.readVarint():i==5?t=n.readVarint():i==6?t=n.readSVarint():i==7?t=Boolean(n.readVarint()):n.skip(r);return t};VectorTileLayer.prototype.feature=function(n){if(n<0||n>=this._features.length)throw new Error("feature index out of bounds");this._buffer.pos=this._features[n];var t=this._buffer.readVarint()+this._buffer.pos;return new VectorTileFeature(this._buffer,t,this.extent,this._keys,this._values)};Point.prototype={clone:function(){return new Point(this.x,this.y)},add:function(n){return this.clone()._add(n)},sub:function(n){return this.clone()._sub(n)},mult:function(n){return this.clone()._mult(n)},div:function(n){return this.clone()._div(n)},rotate:function(n){return this.clone()._rotate(n)},matMult:function(n){return this.clone()._matMult(n)},unit:function(){return this.clone()._unit()},perp:function(){return this.clone()._perp()},round:function(){return this.clone()._round()},mag:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},equals:function(n){return this.x===n.x&&this.y===n.y},dist:function(n){return Math.sqrt(this.distSqr(n))},distSqr:function(n){var t=n.x-this.x,i=n.y-this.y;return t*t+i*i},angle:function(){return Math.atan2(this.y,this.x)},angleTo:function(n){return Math.atan2(this.y-n.y,this.x-n.x)},angleWith:function(n){return this.angleWithSep(n.x,n.y)},angleWithSep:function(n,t){return Math.atan2(this.x*t-this.y*n,this.x*n+this.y*t)},_matMult:function(n){var t=n[0]*this.x+n[1]*this.y,i=n[2]*this.x+n[3]*this.y;return this.x=t,this.y=i,this},_add:function(n){return this.x+=n.x,this.y+=n.y,this},_sub:function(n){return this.x-=n.x,this.y-=n.y,this},_mult:function(n){return this.x*=n,this.y*=n,this},_div:function(n){return this.x/=n,this.y/=n,this},_unit:function(){return this._div(this.mag()),this},_perp:function(){var n=this.y;return this.y=this.x,this.x=-n,this},_rotate:function(n){var t=Math.cos(n),i=Math.sin(n),r=t*this.x-i*this.y,u=i*this.x+t*this.y;return this.x=r,this.y=u,this},_round:function(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this}};Point.convert=function(n){return n instanceof Point?n:Array.isArray(n)?new Point(n[0],n[1]):n};MERCATOR={fromLatLngToPoint:function(n){var t=Math.min(Math.max(Math.sin(n.lat()*(Math.PI/180)),-.9999),.9999);return{x:128+n.lng()*(256/360),y:128+.5*Math.log((1+t)/(1-t))*-(128/Math.PI)}},fromPointToLatLng:function(n){return{lat:(2*Math.atan(Math.exp((n.y-128)/-(128/Math.PI)))-Math.PI/2)/(Math.PI/180),lng:(n.x-128)/(256/360)}},getTileAtLatLng:function(n,t){var u=Math.pow(2,t),i=256/u,r=this.fromLatLngToPoint(n);return{x:Math.floor(r.x/i),y:Math.floor(r.y/i),z:t}},getTileBounds:function(n){n=this.normalizeTile(n);var i=Math.pow(2,n.z),t=256/i,r={x:n.x*t,y:n.y*t+t},u={x:n.x*t+t,y:n.y*t};return{sw:this.fromPointToLatLng(r),ne:this.fromPointToLatLng(u)}},normalizeTile:function(n){var t=Math.pow(2,n.z);return n.x=(n.x%t+t)%t,n.y=(n.y%t+t)%t,n},fromLatLngToPixels:function(n,t){var i=n.getBounds(),f=i.getNorthEast(),e=i.getSouthWest(),o=n.getProjection().fromLatLngToPoint(f),s=n.getProjection().fromLatLngToPoint(e),r=Math.pow(2,n.getZoom()),u=n.getProjection().fromLatLngToPoint(t);return{x:(u.x-s.x)*r,y:(u.y-o.y)*r}},fromLatLngToTilePoint:function(n,t){var r=n.getZoom(),u=this.getTileAtLatLng(t.latLng,r),i=this.getTileBounds(u),f=new google.maps.LatLng(i.sw),e=new google.maps.LatLng(i.ne),o=this.fromLatLngToPixels(n,f),s=this.fromLatLngToPixels(n,e);return{x:t.pixel.x-o.x,y:t.pixel.y-s.y}},isPointInPolygon:function(n,t){if(t&&t.length){for(var u=!1,i=-1,f=t.length,r=f-1;++i1)for(i=0,f=t.length-1;i1?(s=y,h=p):(s=u+r*e,h=f+r*o),c=a-s,l=v-h,Math.sqrt(c*c+l*l)}};class MVTFeature{constructor(n){this.mVTSource=n.mVTSource;this.selected=n.selected;this.featureId=n.featureId;this.tiles=[];this.style=n.style;this.type=n.vectorTileFeature.type;this.properties=n.vectorTileFeature.properties;this.addTileFeature(n.vectorTileFeature,n.tileContext);this._draw=n.customDraw||this.defaultDraw;this.selected&&this.select()}addTileFeature(n,t){this.tiles[t.id]={vectorTileFeature:n,divisor:n.extent/t.tileSize,context2d:!1,paths2d:!1}}getTiles(){return this.tiles}getTile(n){return this.tiles[n.id]}setStyle(n){this.style=n}redrawTiles(){var i=this.mVTSource.map.getZoom(),n,t;for(n in this.tiles)this.mVTSource.deleteTileDrawn(n),t=this.mVTSource.getTileObject(n),t.zoom==i&&this.mVTSource.redrawTile(n)}toggle(){this.selected?this.deselect():this.select()}select(){this.selected=!0;this.mVTSource.featureSelected(this);this.redrawTiles()}deselect(){this.selected=!1;this.mVTSource.featureDeselected(this);this.redrawTiles()}setSelected(n){this.selected=n}draw(n){var i=this.tiles[n.id],t=this.style;this.selected&&this.style.selected&&(t=this.style.selected);this._draw(n,i,t,this)}defaultDraw(n,t,i){switch(this.type){case 1:this.drawPoint(n,t,i);break;case 2:this.drawLineString(n,t,i);break;case 3:this.drawPolygon(n,t,i)}}drawPoint(n,t,i){var f=t.vectorTileFeature.coordinates[0][0],u=this.getPoint(f,n,t.divisor),e=i.radius||3,r=this.getContext2d(n.canvas,i);r.beginPath();r.arc(u.x,u.y,e,0,Math.PI*2);r.closePath();r.fill();r.stroke()}drawLineString(n,t,i){t.context2d=this.getContext2d(n.canvas,i);this.drawCoordinates(n,t);t.context2d.stroke(t.paths2d)}drawPolygon(n,t,i){t.context2d=this.getContext2d(n.canvas,i);this.drawCoordinates(n,t);t.paths2d.closePath();i.fillStyle&&t.context2d.fill(t.paths2d);i.strokeStyle&&t.context2d.stroke(t.paths2d)}drawCoordinates(n,t){var e=t.vectorTileFeature.coordinates,u,o,f,i,s,r;for(t.paths2d=new Path2D,u=0,o=e.length;u0&&f.push(t)}return f}getContext2d(n,t){var r=n.getContext("2d");for(var i in t)i!=="selected"&&(r[i]=t[i]);return r}getPoint(n,t,i){var r={x:n.x/i,y:n.y/i};return t.parentId&&(r=this._getOverzoomedPoint(r,t)),r}_getOverzoomedPoint(n,t){var u=this.mVTSource.getTileObject(t.parentId),r=this.mVTSource.getTileObject(t.id),f=r.zoom-u.zoom;const i=Math.pow(2,f);let e=n.x*i,o=n.y*i,s=r.x%i,h=r.y%i;return n.x=e-s*t.tileSize,n.y=o-h*t.tileSize,n}isPointInPath(n,t){var i=this.getTile(t),r=i.context2d,u=i.paths2d;return!r||!u?!1:r.isPointInPath(u,n.x,n.y)}}class MVTLayer{constructor(n){this._lineClickTolerance=2;this._getIDForLayerFeature=n.getIDForLayerFeature;this.style=n.style;this.name=n.name;this._filter=n.filter||!1;this._customDraw=n.customDraw||!1;this._canvasAndMVTFeatures=[];this._mVTFeatures=[]}parseVectorTileFeatures(n,t,i){var r,u,f;for(this._canvasAndMVTFeatures[i.id]={canvas:i.canvas,features:[]},r=0,u=t.length;r=0;i--)if(r=t[i],this._handleClickFeature(n,r),this.selectedFeature!=null)return this.selectedFeature}_handleClickFeature(n,t){switch(t.type){case 3:this._handleClickFeaturePolygon(n,t);break;default:this._handleClickFeatureDefault(n,t)}}_handleClickFeaturePolygon(n,t){t.isPointInPath(n.tilePoint,n.tileContext)&&(this.selectedFeature=t,this.minDistance=0)}_handleClickFeatureDefault(n,t){for(var i,r,e,f=t.getPaths(n.tileContext),u=f.length-1;u>=0;u--){i=f[u];switch(t.type){case 1:MERCATOR.in_circle(i[0].x,i[0].y,t.style.radius,n.tilePoint.x,n.tilePoint.y)&&(this.selectedFeature=t,this.minDistance=0);break;case 2:r=MERCATOR.getDistanceFromLine(n.tilePoint,i);e=t.selected&&t.style.selected?t.style.selected.lineWidth:t.style.lineWidth;r{i._zoomChanged()})}getTile(n,t,i){var r=this.drawTile(n,t,i);return this._setVisibleTile(r),r.canvas}releaseTile(){}_zoomChanged(){this._resetVisibleTiles();this._cache||this._resetMVTLayers()}_resetMVTLayers(){this.mVTLayers=[]}_deleteVisibleTile(n){delete this._visibleTiles[n]}_resetVisibleTiles(){this._visibleTiles=[]}_setVisibleTile(n){this._visibleTiles[n.id]=n}drawTile(n,t,i){var u=this.getTileId(t,n.x,n.y),r=this._tilesDrawn[u];return r?r:(r=this._createTileContext(n,t,i),this._xhrRequest(r),r)}_createTileContext(n,t,i){var r=this.getTileId(t,n.x,n.y),u=this._createCanvas(i,r),f=this._getParentId(r);return{id:r,canvas:u,zoom:t,tileSize:this._tileSize,parentId:f}}_getParentId(n){var r=!1,t;if(this._sourceMaxZoom&&(t=this.getTileObject(n),t.zoom>this._sourceMaxZoom)){var i=t.zoom-this._sourceMaxZoom,u=t.zoom-i,f=t.x>>i,e=t.y>>i;r=this.getTileId(u,f,e)}return r}_createCanvas(n,t){const i=n.createElement("canvas");return i.width=this._tileSize,i.height=this._tileSize,i.id=t,i}getTileId(n,t,i){return[n,t,i].join(":")}getTileObject(n){var t=n.split(":");return{zoom:t[0],x:t[1],y:t[2]}}_xhrRequest(n){var u=this,f=n.parentId||n.id,i=this.getTileObject(f),e=this._url.replace("{z}",i.zoom).replace("{x}",i.x).replace("{y}",i.y),t=new XMLHttpRequest,r;t.onload=function(){if(t.status=="200"&&t.response)return u._xhrResponseOk(n,t.response);u._drawDebugInfo(n)};t.open("GET",e,!0);for(r in this._xhrHeaders)t.setRequestHeader(r,this._xhrHeaders[r]);t.responseType="arraybuffer";t.send()}_xhrResponseOk(n,t){if(this.map.getZoom()==n.zoom){var i=new Uint8Array(t),r=new Pbf(i),u=new VectorTile(r);this._drawVectorTile(u,n)}}_setTileDrawn(n){this._cache&&(this._tilesDrawn[n.id]=n)}deleteTileDrawn(n){delete this._tilesDrawn[n]}_resetTileDrawn(){this._tilesDrawn=[]}_drawVectorTile(n,t){var r,f,i,u;if(this._visibleLayers)for(r=0,f=this._visibleLayers.length;r=0;r--)if(s=f[r],e=this.mVTLayers[s],e&&(n=e.handleClickEvent(n,this),this._mouseSelectedFeature(n,t,i),h&&n.feature))break}_mouseSelectedFeature(n,t,i){if(i.setSelected){var r=n.feature;r?i.mouseHover?r.selected||r.select():i.toggleSelection?r.toggle():r.selected||r.select():i.mouseHover&&this.deselectAllFeatures()}t(n)}deselectAllFeatures(){var e=this.map.getZoom(),i=[],r,n,u,t,f;for(r in this._selectedFeatures)if(n=this._selectedFeatures[r],n){n.setSelected(!1);u=n.getTiles();for(t in u)this.deleteTileDrawn(t),f=this.getTileObject(t),f.zoom==e&&(i[t]=!0)}this.redrawTiles(i);this._selectedFeatures=[]}featureSelected(n){this._multipleSelection||this.deselectAllFeatures();this._selectedFeatures[n.featureId]=n}featureDeselected(n){delete this._selectedFeatures[n.featureId]}setSelectedFeatures(n){var t,r,i,u;for(n.length>1&&(this._multipleSelection=!0),this.deselectAllFeatures(),t=0,r=n.length;t
+
+

+ You need to set an API key to use Google Maps. +

+
@@ -17,16 +22,21 @@

Basic

Basic example loading vector tiles in Google Maps. Debug mode enabled.

+
+ + + +
- - - - \ No newline at end of file diff --git a/examples/cache.html b/examples/cache.html index 05003bc..f48d2e2 100644 --- a/examples/cache.html +++ b/examples/cache.html @@ -9,6 +9,11 @@
+
+

+ You need to set an API key to use Google Maps. +

+
@@ -17,15 +22,20 @@

Cache enabled

Tiles are stored in memory after being loaded first time.

+
+ + + +
- - - \ No newline at end of file diff --git a/examples/click.html b/examples/click.html index c3054fd..6d9656e 100644 --- a/examples/click.html +++ b/examples/click.html @@ -9,6 +9,11 @@
+
+

+ You need to set an API key to use Google Maps. +

+
@@ -21,16 +26,21 @@

Click

    +
    + + + +
    - - - \ No newline at end of file diff --git a/examples/custom-draw.html b/examples/custom-draw.html index 9e8ff3a..e721bdd 100644 --- a/examples/custom-draw.html +++ b/examples/custom-draw.html @@ -9,6 +9,12 @@
    +
    +

    + You need to set an API key to use Google Maps. +

    +
    +
    @@ -17,11 +23,17 @@

    Custom Draw

    Custom draw function for each feature. In the example, points are drawed as triangles.

    +
    + + + +
    - - - \ No newline at end of file diff --git a/examples/filter.html b/examples/filter.html index a943781..2363e39 100644 --- a/examples/filter.html +++ b/examples/filter.html @@ -9,6 +9,11 @@
    +
    +

    + You need to set an API key to use Google Maps. +

    +
    @@ -21,20 +26,26 @@

    Filter

    +
    + + + +
    - - - \ No newline at end of file diff --git a/examples/hover.html b/examples/hover.html index 6ae38c1..79526a1 100644 --- a/examples/hover.html +++ b/examples/hover.html @@ -9,6 +9,11 @@
    +
    +

    + You need to set an API key to use Google Maps. +

    +
    @@ -21,16 +26,21 @@

    Hover

    +
    + + + +
    - - - \ No newline at end of file diff --git a/examples/index.html b/examples/index.html deleted file mode 100644 index 004c878..0000000 --- a/examples/index.html +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - Examples - - -

    Examples

    -
      -
    1. Basic - Basic loading vector tiles with debug enabled.
    2. -
    3. Cache - Cache enabled.
    4. -
    5. Click - Click to select one or multiple features.
    6. -
    7. Custom draw - Custom draw function for each feature.
    8. -
    9. Filter - Filter features by it properties.
    10. -
    11. Hover - On mouse hover event.
    12. -
    13. Layers - Add remove vector tiles layers.
    14. -
    15. Point, linestring and polygon - Show all type of geometries.
    16. -
    17. Preselected features - Set features as selected before loading.
    18. -
    19. Sectores parcels
    20. -
    21. Spanish parcels
    22. -
    23. Style filter and layer - Update the style, filter and visible layers simultaneously.
    24. -
    25. Styles feature - Style based on feature properties.
    26. -
    27. Styles - Change style dynamically.
    28. -
    - - \ No newline at end of file diff --git a/examples/layers.html b/examples/layers.html index 5403dee..767c18d 100644 --- a/examples/layers.html +++ b/examples/layers.html @@ -9,6 +9,11 @@
    +
    +

    + You need to set an API key to use Google Maps. +

    +
    @@ -25,18 +30,23 @@

    Layers


    +
    + + + +
    - - - \ No newline at end of file diff --git a/examples/point-linestring-polygon.html b/examples/point-linestring-polygon.html index 6672e67..b1398b9 100644 --- a/examples/point-linestring-polygon.html +++ b/examples/point-linestring-polygon.html @@ -9,6 +9,11 @@
    +
    +

    + You need to set an API key to use Google Maps. +

    +
    @@ -17,11 +22,16 @@

    Point, linestring and polygon

    This example loads the types of geometries.

    +
    + + + +
    - - - + + window.LoadGoogleMapSDK = function LoadGoogleMapSDK() { + var apiKey = document.getElementById("apiKey").value; + // save the API key in local storage + localStorage.setItem("apiKey", apiKey); + // do not load the SDK if the API key is empty + if (!apiKey) return; + // do not load the SDK if it is already loaded + if (window.google && window.google.maps) return; + var script = document.createElement("script"); + script.src = "https://maps.googleapis.com/maps/api/js?key=" + apiKey + "&callback=InitGoogleMap&libraries=&v=weekly"; + script.defer = true; + document.head.appendChild(script); + document.getElementById("noKey").style.display = "none"; + } + + // try to get the API key from local storage + var apiKey = localStorage.getItem("apiKey"); + if (apiKey) { + document.getElementById("apiKey").value = apiKey; + LoadGoogleMapSDK(); + } + \ No newline at end of file diff --git a/examples/preselected-features.html b/examples/preselected-features.html index fc8d4f1..5eccd40 100644 --- a/examples/preselected-features.html +++ b/examples/preselected-features.html @@ -9,6 +9,11 @@
    +
    +

    + You need to set an API key to use Google Maps. +

    +
    @@ -23,18 +28,23 @@

    Preselected features

    +
    + + + +
    - - - + + window.LoadGoogleMapSDK = function LoadGoogleMapSDK() { + var apiKey = document.getElementById("apiKey").value; + // save the API key in local storage + localStorage.setItem("apiKey", apiKey); + // do not load the SDK if the API key is empty + if (!apiKey) return; + // do not load the SDK if it is already loaded + if (window.google && window.google.maps) return; + var script = document.createElement("script"); + script.src = "https://maps.googleapis.com/maps/api/js?key=" + apiKey + "&callback=InitGoogleMap&libraries=&v=weekly"; + script.defer = true; + document.head.appendChild(script); + document.getElementById("noKey").style.display = "none"; + } + + // try to get the API key from local storage + var apiKey = localStorage.getItem("apiKey"); + if (apiKey) { + document.getElementById("apiKey").value = apiKey; + LoadGoogleMapSDK(); + } + \ No newline at end of file diff --git a/examples/sectores-parcels.html b/examples/sectores-parcels.html deleted file mode 100644 index ae527e1..0000000 --- a/examples/sectores-parcels.html +++ /dev/null @@ -1,58 +0,0 @@ - - - - Basic - - - - - -
    -
    -
    -
    -
    -

    Basic

    -

    - Basic example loading vector tiles in Google Maps. Debug mode enabled. -

    -
    -
    - - - - - - \ No newline at end of file diff --git a/examples/spanish-parcels.html b/examples/spanish-parcels.html deleted file mode 100644 index e8cd7fc..0000000 --- a/examples/spanish-parcels.html +++ /dev/null @@ -1,72 +0,0 @@ - - - - Spanish Parcels - - - - - -
    - - - - - \ No newline at end of file diff --git a/examples/style-filter-layer.html b/examples/style-filter-layer.html index 8f72836..e3d3d98 100644 --- a/examples/style-filter-layer.html +++ b/examples/style-filter-layer.html @@ -9,6 +9,11 @@
    +
    +

    + You need to set an API key to use Google Maps. +

    +
    @@ -25,18 +30,23 @@

    Style filter and layer


    +
    + + + +
    - - - \ No newline at end of file diff --git a/examples/styles-feature.html b/examples/styles-feature.html index fbf7e03..d10f658 100644 --- a/examples/styles-feature.html +++ b/examples/styles-feature.html @@ -9,6 +9,11 @@
    +
    +

    + You need to set an API key to use Google Maps. +

    +
    @@ -17,16 +22,21 @@

    Styles feature

    Styles based on feature property.

    +
    + + + +
    - - - \ No newline at end of file diff --git a/examples/styles.css b/examples/styles.css index 38067da..de80273 100644 --- a/examples/styles.css +++ b/examples/styles.css @@ -7,7 +7,9 @@ position: absolute; left: 0; width: 80%; - height: 100% + height: 100%; + background-color: #bcbcbc; + box-shadow: 0 0 5px #00000091; } .container-right { @@ -16,6 +18,7 @@ width: 20%; height: 100%; line-height:18pt; + border-left: 1px solid #646464; } #map { @@ -25,6 +28,18 @@ width: 100%; } +#noKey { + position: absolute; + top: 0; + bottom: 0; + width: 100%; + background-color: #00000091; + color: #ffffff; + text-align: center; + font-size: 24pt; + line-height: 100%; +} + .container-right > div { padding: 12pt; } \ No newline at end of file diff --git a/examples/styles.html b/examples/styles.html index 5621928..ef3ef16 100644 --- a/examples/styles.html +++ b/examples/styles.html @@ -9,6 +9,11 @@
    +
    +

    + You need to set an API key to use Google Maps. +

    +
    @@ -50,17 +55,22 @@

    Styles

    +
    + + + +
    - - - \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..8f822e6 --- /dev/null +++ b/index.html @@ -0,0 +1,44 @@ + + + + + + + Examples + + +

    Examples

    +
      +
    1. Basic - Basic loading vector tiles with debug enabled.
    2. +
    3. Cache - Cache enabled.
    4. +
    5. Click - Click to select one or multiple features.
    6. +
    7. Custom draw - Custom draw function for each feature.
    8. +
    9. Filter - Filter features by it properties.
    10. +
    11. Hover - On mouse hover event.
    12. +
    13. Layers - Add remove vector tiles layers.
    14. +
    15. Point, linestring and polygon - Show all type of geometries.
    16. +
    17. Preselected features - Set features as selected before loading.
    18. +
    19. Style filter and layer - Update the style, filter and visible layers simultaneously.
    20. +
    21. Styles feature - Style based on feature properties.
    22. +
    23. Styles - Change style dynamically.
    24. +
    +

    Set API Key

    +

    You must use a valid Google Maps API key. If you do not have one, you can get one here.

    +
    + + + +
    + + + \ No newline at end of file diff --git a/lib/drawing.js b/lib/drawing.js new file mode 100644 index 0000000..25d24a4 --- /dev/null +++ b/lib/drawing.js @@ -0,0 +1,91 @@ +import {getPoint} from './geometry'; + +/** + * Accepts a canvas and optionally applies styles from a StyleOptions object before returning the context2d for + * drawing. + * @param {HTMLCanvasElement} canvas + * @param {StyleOptions} [style={}] + * @return {CanvasRenderingContext2D} + */ +const getContext2d = (canvas, style = {}) => { + const context2d = canvas.getContext('2d'); + for (const key in style) { + if (key === 'selected') continue; + context2d[key] = style[key]; + } + return context2d; +}; + +/** + * Builds a line along all the paths in the geometry and adds each to the tile's paths2d without closing the path + * or drawing the stroke + * @param {TileContext} tileContext + * @param {FeatureTile} tile + * @return {Path2D} + */ +const drawGeometry = (tileContext, tile) => { + const geometry = tile.vectorTileFeature.loadGeometry(); + geometry.forEach((path) => { + const path2d = new Path2D(); + path.forEach((rawPoint, i) => { + const p = getPoint(rawPoint, tileContext, tile.divisor); + const operation = i === 0 ? 'moveTo' : 'lineTo'; // if this is the first point, move to it without drawing + path2d[operation](p.x, p.y); + }); + tile.paths2d.addPath(path2d); + }); + return tile.paths2d; +}; + +/** + * @param {TileContext} tileContext + * @param {FeatureTile} tile + * @param {StyleOptions} style + */ +const drawPoint = (tileContext, tile, style) => { + const coordinates = tile.vectorTileFeature.loadGeometry()[0][0]; + const point = getPoint(coordinates, tileContext, tile.divisor); + const radius = style.radius || 3; + const context2d = getContext2d(tileContext.canvas, style); + context2d.beginPath(); + context2d.arc(point.x, point.y, radius, 0, Math.PI * 2); + context2d.closePath(); + context2d.fill(); + context2d.stroke(); +}; + +/** + * @param {TileContext} tileContext + * @param {FeatureTile} tile + * @param {StyleOptions} style + */ +const drawLineString = (tileContext, tile, style) => { + const context2d = getContext2d(tileContext.canvas, style); + context2d.stroke(drawGeometry(tileContext, tile)); +}; + +/** + * @param {TileContext} tileContext + * @param {FeatureTile} tile + * @param {StyleOptions} style + */ +const drawPolygon = (tileContext, tile, style) => { + const paths = drawGeometry(tileContext, tile); + paths.closePath(); + + const context2d = getContext2d(tileContext.canvas, style); + if (style.fillStyle) { + context2d.fill(paths); + } + if (style.strokeStyle) { + context2d.stroke(paths); + } +}; + +export { + getContext2d, + drawGeometry, + drawPoint, + drawLineString, + drawPolygon, +}; diff --git a/lib/geometry.js b/lib/geometry.js new file mode 100644 index 0000000..5a40009 --- /dev/null +++ b/lib/geometry.js @@ -0,0 +1,74 @@ + +/** + * @param {number} zoom + * @param {number} x + * @param {number} y + * @return {string} + */ +const getTileString = (zoom, x, y) => [zoom, x, y].join(':'); + +/** + * @param {string} id Tile id in format 'zoom:x:y' + * @return {{zoom: number, x: number, y: number}} + */ +const getTileFromString = (id) => { + try { + const [zoom, x, y] = id.split(':'); + return { + zoom: Number(zoom), + x: Number(x), + y: Number(y), + }; + } catch (e) { + console.error('Error parsing tile id', id); + return {zoom: 0, x: 0, y: 0}; + } +}; + +/** + * @param {google.maps.Point} point + * @param {TileContext} tileContext + * @return {google.maps.Point} + */ +const getOverZoomedPoint = (point, tileContext) => { + const parentTile = getTileFromString(tileContext.parentId); + const currentTile = getTileFromString(tileContext.id); + const zoomDistance = currentTile.zoom - parentTile.zoom; + + const scale = Math.pow(2, zoomDistance); + + const xScale = point.x * scale; + const yScale = point.y * scale; + + const xTileOffset = currentTile.x % scale; + const yTileOffset = currentTile.y % scale; + + const newPoint = new window.google.maps.Point( + xScale - (xTileOffset * tileContext.tileSize), + yScale - (yTileOffset * tileContext.tileSize), + ); + + return newPoint; +}; + +/** + * Scales a point to the current tile + * @param {google.maps.Point} coords + * @param {TileContext} tileContext + * @param {Number} [divisor=1] + * @return {google.maps.Point} + */ +const getPoint = (coords, tileContext, divisor = 1) => { + const point = new window.google.maps.Point(coords.x / divisor, coords.y / divisor); + + if (tileContext.parentId) { + return getOverZoomedPoint(point, tileContext); + } + return point; +}; + +export { + getPoint, + getTileFromString, + getTileString, +}; diff --git a/main.js b/main.js new file mode 100644 index 0000000..521638c --- /dev/null +++ b/main.js @@ -0,0 +1,18 @@ +import {MVTSource} from './src/MVTSource.js'; +import {MVTFeature} from './src/MVTFeature.js'; +import {MVTLayer} from './src/MVTLayer.js'; +import {getContext2d} from './lib/drawing.js'; +import {getPoint, getTileFromString, getTileString} from './lib/geometry.js'; + + +export { + MVTSource, + getTileFromString, + getTileString, + + MVTFeature, + getPoint, + getContext2d, + + MVTLayer, +}; diff --git a/package-lock.json b/package-lock.json index 3ec6bd0..b928dba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,11 +14,13 @@ }, "devDependencies": { "@googlemaps/jest-mocks": "2.7.5", + "@types/google.maps": "^3.51.1", "eslint": "^8.32.0", "eslint-config-google": "^0.14.0", "eslint-plugin-jest": "^27.2.1", "jest": "^29.4.0", - "jest-environment-jsdom": "^29.4.0" + "jest-environment-jsdom": "^29.4.0", + "vite": "^4.1.1" } }, "node_modules/@ampproject/remapping": { @@ -633,6 +635,358 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "node_modules/@esbuild/android-arm": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.16.17.tgz", + "integrity": "sha512-N9x1CMXVhtWEAMS7pNNONyA14f71VPQN9Cnavj1XQh6T7bskqiLLrSca4O0Vr8Wdcga943eThxnVp3JLnBMYtw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.16.17.tgz", + "integrity": "sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.16.17.tgz", + "integrity": "sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.16.17.tgz", + "integrity": "sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.16.17.tgz", + "integrity": "sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.16.17.tgz", + "integrity": "sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.16.17.tgz", + "integrity": "sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.16.17.tgz", + "integrity": "sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.16.17.tgz", + "integrity": "sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.16.17.tgz", + "integrity": "sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.16.17.tgz", + "integrity": "sha512-dTzNnQwembNDhd654cA4QhbS9uDdXC3TKqMJjgOWsC0yNCbpzfWoXdZvp0mY7HU6nzk5E0zpRGGx3qoQg8T2DQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.16.17.tgz", + "integrity": "sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.16.17.tgz", + "integrity": "sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.16.17.tgz", + "integrity": "sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.16.17.tgz", + "integrity": "sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.16.17.tgz", + "integrity": "sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.16.17.tgz", + "integrity": "sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.16.17.tgz", + "integrity": "sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.16.17.tgz", + "integrity": "sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.16.17.tgz", + "integrity": "sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.16.17.tgz", + "integrity": "sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.16.17.tgz", + "integrity": "sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@eslint/eslintrc": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", @@ -1250,6 +1604,12 @@ "@babel/types": "^7.3.0" } }, + "node_modules/@types/google.maps": { + "version": "3.51.1", + "resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.51.1.tgz", + "integrity": "sha512-Wtl6PUL26jEbC1NBqJi7uoyYZo1/I3EDCd9pZk9EN6ZDvKaO28M5+nIQGyYomzvkMpMHnfywpTzalhwr76/oAg==", + "dev": true + }, "node_modules/@types/graceful-fs": { "version": "4.1.6", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", @@ -2144,6 +2504,43 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/esbuild": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.16.17.tgz", + "integrity": "sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.16.17", + "@esbuild/android-arm64": "0.16.17", + "@esbuild/android-x64": "0.16.17", + "@esbuild/darwin-arm64": "0.16.17", + "@esbuild/darwin-x64": "0.16.17", + "@esbuild/freebsd-arm64": "0.16.17", + "@esbuild/freebsd-x64": "0.16.17", + "@esbuild/linux-arm": "0.16.17", + "@esbuild/linux-arm64": "0.16.17", + "@esbuild/linux-ia32": "0.16.17", + "@esbuild/linux-loong64": "0.16.17", + "@esbuild/linux-mips64el": "0.16.17", + "@esbuild/linux-ppc64": "0.16.17", + "@esbuild/linux-riscv64": "0.16.17", + "@esbuild/linux-s390x": "0.16.17", + "@esbuild/linux-x64": "0.16.17", + "@esbuild/netbsd-x64": "0.16.17", + "@esbuild/openbsd-x64": "0.16.17", + "@esbuild/sunos-x64": "0.16.17", + "@esbuild/win32-arm64": "0.16.17", + "@esbuild/win32-ia32": "0.16.17", + "@esbuild/win32-x64": "0.16.17" + } + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -4006,6 +4403,18 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "node_modules/nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "dev": true, + "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", @@ -4318,6 +4727,30 @@ "node": ">=8" } }, + "node_modules/postcss": { + "version": "8.4.21", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", + "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + } + ], + "dependencies": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -4534,6 +4967,22 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rollup": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.15.0.tgz", + "integrity": "sha512-F9hrCAhnp5/zx/7HYmftvsNBkMfLfk/dXUh73hPSM2E3CRgap65orDNJbLetoiUFwSAk6iHPLvBrZ5iHYvzqsg==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=14.18.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -4659,6 +5108,15 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-support": { "version": "0.5.13", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", @@ -5011,6 +5469,55 @@ "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", "dev": true }, + "node_modules/vite": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.1.1.tgz", + "integrity": "sha512-LM9WWea8vsxhr782r9ntg+bhSFS06FJgCvvB0+8hf8UWtvaiDagKYWXndjfX6kGl74keHJUcpzrQliDXZlF5yg==", + "dev": true, + "dependencies": { + "esbuild": "^0.16.14", + "postcss": "^8.4.21", + "resolve": "^1.22.1", + "rollup": "^3.10.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + }, + "peerDependencies": { + "@types/node": ">= 14", + "less": "*", + "sass": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, "node_modules/w3c-xmlserializer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", @@ -5692,6 +6199,160 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "@esbuild/android-arm": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.16.17.tgz", + "integrity": "sha512-N9x1CMXVhtWEAMS7pNNONyA14f71VPQN9Cnavj1XQh6T7bskqiLLrSca4O0Vr8Wdcga943eThxnVp3JLnBMYtw==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.16.17.tgz", + "integrity": "sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg==", + "dev": true, + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.16.17.tgz", + "integrity": "sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.16.17.tgz", + "integrity": "sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.16.17.tgz", + "integrity": "sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.16.17.tgz", + "integrity": "sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.16.17.tgz", + "integrity": "sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.16.17.tgz", + "integrity": "sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.16.17.tgz", + "integrity": "sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.16.17.tgz", + "integrity": "sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.16.17.tgz", + "integrity": "sha512-dTzNnQwembNDhd654cA4QhbS9uDdXC3TKqMJjgOWsC0yNCbpzfWoXdZvp0mY7HU6nzk5E0zpRGGx3qoQg8T2DQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.16.17.tgz", + "integrity": "sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.16.17.tgz", + "integrity": "sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g==", + "dev": true, + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.16.17.tgz", + "integrity": "sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw==", + "dev": true, + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.16.17.tgz", + "integrity": "sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w==", + "dev": true, + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.16.17.tgz", + "integrity": "sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw==", + "dev": true, + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.16.17.tgz", + "integrity": "sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.16.17.tgz", + "integrity": "sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg==", + "dev": true, + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.16.17.tgz", + "integrity": "sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw==", + "dev": true, + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.16.17.tgz", + "integrity": "sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw==", + "dev": true, + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.16.17.tgz", + "integrity": "sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig==", + "dev": true, + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.16.17.tgz", + "integrity": "sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==", + "dev": true, + "optional": true + }, "@eslint/eslintrc": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", @@ -6189,6 +6850,12 @@ "@babel/types": "^7.3.0" } }, + "@types/google.maps": { + "version": "3.51.1", + "resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.51.1.tgz", + "integrity": "sha512-Wtl6PUL26jEbC1NBqJi7uoyYZo1/I3EDCd9pZk9EN6ZDvKaO28M5+nIQGyYomzvkMpMHnfywpTzalhwr76/oAg==", + "dev": true + }, "@types/graceful-fs": { "version": "4.1.6", "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz", @@ -6858,6 +7525,36 @@ "is-arrayish": "^0.2.1" } }, + "esbuild": { + "version": "0.16.17", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.16.17.tgz", + "integrity": "sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==", + "dev": true, + "requires": { + "@esbuild/android-arm": "0.16.17", + "@esbuild/android-arm64": "0.16.17", + "@esbuild/android-x64": "0.16.17", + "@esbuild/darwin-arm64": "0.16.17", + "@esbuild/darwin-x64": "0.16.17", + "@esbuild/freebsd-arm64": "0.16.17", + "@esbuild/freebsd-x64": "0.16.17", + "@esbuild/linux-arm": "0.16.17", + "@esbuild/linux-arm64": "0.16.17", + "@esbuild/linux-ia32": "0.16.17", + "@esbuild/linux-loong64": "0.16.17", + "@esbuild/linux-mips64el": "0.16.17", + "@esbuild/linux-ppc64": "0.16.17", + "@esbuild/linux-riscv64": "0.16.17", + "@esbuild/linux-s390x": "0.16.17", + "@esbuild/linux-x64": "0.16.17", + "@esbuild/netbsd-x64": "0.16.17", + "@esbuild/openbsd-x64": "0.16.17", + "@esbuild/sunos-x64": "0.16.17", + "@esbuild/win32-arm64": "0.16.17", + "@esbuild/win32-ia32": "0.16.17", + "@esbuild/win32-x64": "0.16.17" + } + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -8236,6 +8933,12 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, + "nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "dev": true + }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -8466,6 +9169,17 @@ } } }, + "postcss": { + "version": "8.4.21", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", + "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", + "dev": true, + "requires": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + } + }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -8617,6 +9331,15 @@ "glob": "^7.1.3" } }, + "rollup": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.15.0.tgz", + "integrity": "sha512-F9hrCAhnp5/zx/7HYmftvsNBkMfLfk/dXUh73hPSM2E3CRgap65orDNJbLetoiUFwSAk6iHPLvBrZ5iHYvzqsg==", + "dev": true, + "requires": { + "fsevents": "~2.3.2" + } + }, "run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -8706,6 +9429,12 @@ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, + "source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "dev": true + }, "source-map-support": { "version": "0.5.13", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", @@ -8964,6 +9693,19 @@ } } }, + "vite": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-4.1.1.tgz", + "integrity": "sha512-LM9WWea8vsxhr782r9ntg+bhSFS06FJgCvvB0+8hf8UWtvaiDagKYWXndjfX6kGl74keHJUcpzrQliDXZlF5yg==", + "dev": true, + "requires": { + "esbuild": "^0.16.14", + "fsevents": "~2.3.2", + "postcss": "^8.4.21", + "resolve": "^1.22.1", + "rollup": "^3.10.0" + } + }, "w3c-xmlserializer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", diff --git a/package.json b/package.json index abaf8eb..adde634 100644 --- a/package.json +++ b/package.json @@ -5,15 +5,20 @@ "license": "MIT", "type": "module", "scripts": { - "test": "NODE_OPTIONS=--experimental-vm-modules jest" + "test": "NODE_OPTIONS=--experimental-vm-modules jest", + "dev": "vite", + "build": "vite build", + "preview": "vite preview" }, "devDependencies": { "@googlemaps/jest-mocks": "2.7.5", + "@types/google.maps": "^3.51.1", "eslint": "^8.32.0", "eslint-config-google": "^0.14.0", "eslint-plugin-jest": "^27.2.1", "jest": "^29.4.0", - "jest-environment-jsdom": "^29.4.0" + "jest-environment-jsdom": "^29.4.0", + "vite": "^4.1.1" }, "moduleNameMapper": { "^@/(.*)$": "/src/$1" diff --git a/src/MVTFeature.js b/src/MVTFeature.js index d4d9d82..da1ca69 100644 --- a/src/MVTFeature.js +++ b/src/MVTFeature.js @@ -2,221 +2,171 @@ * Created by Jes�s Barrio on 04/2021 */ -export class MVTFeature { - constructor(options) { +import {getTileFromString, getPoint} from '../lib/geometry.js'; +import {drawPoint, drawPolygon, drawLineString, getContext2d} from '../lib/drawing.js'; + +/** + * @typedef {import('./MVTSource').MVTSource} MVTSource + * @typedef {import('./MVTSource').TileContext} TileContext + * @typedef {import('./MVTSource').StyleOptions} StyleOptions + * @typedef {import('./MVTSource').drawFn} drawFn + * + * @typedef {import('@mapbox/vector-tile').VectorTileFeature} VectorTileFeature + */ + +/** + * @typedef {object} MVTFeatureOptions + * @property {MVTSource} mVTSource + * @property {boolean} selected Indicates if these feature has ben selected and should be using the "selected" styles + * @property {string} featureId The feature id + * @property {StyleOptions} style + * @property {VectorTileFeature} vectorTileFeature + * @property {TileContext} tileContext + * @property {drawFn} customDraw + */ + +/** + * @typedef {object} FeatureTile + * @property {VectorTileFeature} vectorTileFeature + * @property {number} divisor + * @property {Path2D} paths2d + */ + +const getDefaultDraw = (/** @type {1|2|3} */type) => { + /** + * Default draw method handles drawing points, linestrings and polygons using the built in draw methods which + * use the currently applied style. + * @param {TileContext} tileContext + * @param {FeatureTile} tile + * @param {StyleOptions} style + */ + const defaultDraw = (tileContext, tile, style) => { + const drawFns = { + 1: drawPoint, + 2: drawLineString, + 3: drawPolygon, + }; + drawFns[type]?.(tileContext, tile, style); + }; + return defaultDraw; +}; + +class MVTFeature { + /** + * @param {MVTFeatureOptions} options + */ + constructor(options = {}) { + /** @type {MVTSource} */ this.mVTSource = options.mVTSource; + /** @type {boolean} Indicates if these feature has ben selected and should be using the "selected" styles */ this.selected = options.selected; + /** @type {string} The feature id */ this.featureId = options.featureId; - this.tiles = []; + /** @type {StyleOptions} */ this.style = options.style; + /** @type {1|2|3} */ this.type = options.vectorTileFeature.type; + /** @type {object} */ this.properties = options.vectorTileFeature.properties; - this.addTileFeature(options.vectorTileFeature, options.tileContext); - this._draw = options.customDraw || this.defaultDraw; + /** @type {drawFn} */ + this._draw = options.customDraw || getDefaultDraw(this.type); + + /** @type {Record} */ + this.tiles = {}; + + this.addTileFeature(options.vectorTileFeature, options.tileContext); if (this.selected) { - this.select(); + this.setSelected(true); } } + /** + * @param {VectorTileFeature} vectorTileFeature + * @param {TileContext} tileContext + */ addTileFeature(vectorTileFeature, tileContext) { this.tiles[tileContext.id] = { vectorTileFeature: vectorTileFeature, divisor: vectorTileFeature.extent / tileContext.tileSize, - context2d: false, - paths2d: false, + paths2d: new Path2D(), }; } - getTiles() { - return this.tiles; - } - - getTile(tileContext) { - return this.tiles[tileContext.id]; - } - - setStyle(style) { - this.style = style; - } - + /** + * Redraw all the tiles that this feature is in. Used to apply styling changes + */ redrawTiles() { - const zoom = this.mVTSource.map.getZoom(); - for (const id in this.tiles) { - this.mVTSource.deleteTileDrawn(id); - const idObject = this.mVTSource.getTileObject(id); - if (idObject.zoom == zoom) { - this.mVTSource.redrawTile(id); - } - } + const mapZoom = this.mVTSource.map.getZoom(); + Object.keys(this.tiles).forEach((tileId) => { + if (getTileFromString(tileId).zoom !== mapZoom) return; + this.mVTSource.redrawTile(tileId); + }); } - toggle() { - if (this.selected) { - this.deselect(); + /** + * Set this feature as selected or not. The feature will be redrawn with the correct style + * @param {boolean} selected + */ + setSelected(selected) { + this.selected = selected; + if (selected) { + this.mVTSource.featureSelected(this); } else { - this.select(); + this.mVTSource.featureDeselected(this); } - } - - select() { - this.selected = true; - this.mVTSource.featureSelected(this); - this.redrawTiles(); - } - - deselect() { - this.selected = false; - this.mVTSource.featureDeselected(this); this.redrawTiles(); } - setSelected(selected) { - this.selected = selected; - } - + /** + * Draws the given tile using the correct style based on selected state + * @param {TileContext} tileContext + */ draw(tileContext) { - const tile = this.tiles[tileContext.id]; - let style = this.style; - if (this.selected && this.style.selected) { - style = this.style.selected; - } - - this._draw(tileContext, tile, style, this); - } - - defaultDraw(tileContext, tile, style) { - switch (this.type) { - case 1: // Point - this.drawPoint(tileContext, tile, style); - break; - - case 2: // LineString - this.drawLineString(tileContext, tile, style); - break; - - case 3: // Polygon - this.drawPolygon(tileContext, tile, style); - break; - } - } - - drawPoint(tileContext, tile, style) { - const coordinates = tile.vectorTileFeature.coordinates[0][0]; - const point = this.getPoint(coordinates, tileContext, tile.divisor); - const radius = style.radius || 3; - const context2d = this.getContext2d(tileContext.canvas, style); - context2d.beginPath(); - context2d.arc(point.x, point.y, radius, 0, Math.PI * 2); - context2d.closePath(); - context2d.fill(); - context2d.stroke(); - } - - drawLineString(tileContext, tile, style) { - tile.context2d = this.getContext2d(tileContext.canvas, style); - this.drawCoordinates(tileContext, tile); - tile.context2d.stroke(tile.paths2d); - } - - drawPolygon(tileContext, tile, style) { - tile.context2d = this.getContext2d(tileContext.canvas, style); - this.drawCoordinates(tileContext, tile); - tile.paths2d.closePath(); - - if (style.fillStyle) { - tile.context2d.fill(tile.paths2d); - } - if (style.strokeStyle) { - tile.context2d.stroke(tile.paths2d); - } - } - - drawCoordinates(tileContext, tile) { - const coordinates = tile.vectorTileFeature.coordinates; - tile.paths2d = new Path2D(); - for (let i = 0, length1 = coordinates.length; i < length1; i++) { - const coordinate = coordinates[i]; - const path2 = new Path2D(); - for (let j = 0, length2 = coordinate.length; j < length2; j++) { - const point = this.getPoint(coordinate[j], tileContext, tile.divisor); - if (j == 0) { - path2.moveTo(point.x, point.y); - } else { - path2.lineTo(point.x, point.y); - } - } - tile.paths2d.addPath(path2); - } + // if this feature has been selected and a selected style is available, use that style. Otherwise use the default + const style = this.selected && this.style.selected ? this.style.selected : this.style; + this._draw(tileContext, this.tiles[tileContext.id], style, this); } + /** + * Returns the scaled paths for this feature + * @param {TileContext} tileContext + * @return {Array>} + */ getPaths(tileContext) { + /** @type {Array>} */ const paths = []; const tile = this.tiles[tileContext.id]; - const coordinates = tile.vectorTileFeature.coordinates; - for (let i = 0, length1 = coordinates.length; i < length1; i++) { - const path = []; - const coordinate = coordinates[i]; - for (let j = 0, length2 = coordinate.length; j < length2; j++) { - const point = this.getPoint(coordinate[j], tileContext, tile.divisor); - path.push(point); + const geometry = tile.vectorTileFeature.loadGeometry(); + geometry.forEach((path) => { + /** @type {Array} */ + const scaledPath = []; + path.forEach((rawPoint) => { + scaledPath.push(getPoint(rawPoint, tileContext, tile.divisor)); + }); + if (scaledPath.length > 0) { + paths.push(scaledPath); } - if (path.length > 0) { - paths.push(path); - } - } + }); return paths; } - getContext2d(canvas, style) { - const context2d = canvas.getContext('2d'); - for (const key in style) { - if (key === 'selected') { - continue; - } - context2d[key] = style[key]; - } - return context2d; - } - - getPoint(coords, tileContext, divisor) { - let point = { - x: coords.x / divisor, - y: coords.y / divisor, - }; - - if (tileContext.parentId) { // TODO likely a bug: needs to check for nullish value, not falsy - point = this._getOverzoomedPoint(point, tileContext); - } - return point; - } - - _getOverzoomedPoint(point, tileContext) { - const parentTile = this.mVTSource.getTileObject(tileContext.parentId); - const currentTile = this.mVTSource.getTileObject(tileContext.id); - const zoomDistance = currentTile.zoom - parentTile.zoom; - - const scale = Math.pow(2, zoomDistance); - - const xScale = point.x * scale; - const yScale = point.y * scale; - - const xtileOffset = currentTile.x % scale; - const ytileOffset = currentTile.y % scale; - - point.x = xScale - (xtileOffset * tileContext.tileSize); - point.y = yScale - (ytileOffset * tileContext.tileSize); - - return point; - } - + /** + * Returns whether or not a given point exists in any path in the feature + * @param {Point} point + * @param {TileContext} tileContext + * @return {boolean} + */ isPointInPath(point, tileContext) { - const tile = this.getTile(tileContext); - const context2d = tile.context2d; - const paths2d = tile.paths2d; - if (!context2d || !paths2d) { + const tile = this.tiles[tileContext.id]; + const context2d = getContext2d(tileContext.canvas); + if (!context2d || !tile.paths2d) { return false; } - return context2d.isPointInPath(paths2d, point.x, point.y); + return context2d.isPointInPath(tile.paths2d, point.x, point.y); } } + +export { + MVTFeature, +}; diff --git a/src/MVTLayer.js b/src/MVTLayer.js index 5cfcd42..84f8661 100644 --- a/src/MVTLayer.js +++ b/src/MVTLayer.js @@ -4,194 +4,245 @@ import {MVTFeature} from './MVTFeature.js'; import * as MERCATOR from '../lib/mercator/Mercator.js'; -export default class MVTLayer { - constructor(options) { - this._lineClickTolerance = 2; +/** + * @typedef {import('@mapbox/vector-tile').VectorTileLayer} VectorTileLayer + * @typedef {import('@mapbox/vector-tile').VectorTileFeature} VectorTileFeature + * + * @typedef {import('./MVTSource').TileContext} TileContext + * @typedef {import('./MVTSource').MVTSource} MVTSource + * @typedef {import('./MVTSource').StyleOptions} StyleOptions + * @typedef {import('./MVTSource').featureIdFn} featureIdFn + * @typedef {import('./MVTSource').styleFn} styleFn + * @typedef {import('./MVTSource').filterFn} filterFn + * @typedef {import('./MVTSource').drawFn} drawFn + * @typedef {import('./MVTFeature').MVTFeatureOptions} MVTFeatureOptions + * + * @typedef {object} MVTLayerOptions + * @property {string} name + * @property {styleFn|StyleOptions} style + * @property {featureIdFn} getIDForLayerFeature + * @property {filterFn} filter + * @property {drawFn} customDraw + * + * @typedef {object} TileEvent + * @property {TileContext} tileContext + * @property {MVTFeature} feature + * @property {google.maps.Point} tilePoint + * + * @typedef {google.maps.MapMouseEvent&TileEvent} TileMapMouseEvent + */ + +class MVTLayer { + /** + * @param {MVTLayerOptions} options + */ + constructor(options = {}) { + /** @type {featureIdFn} */ this._getIDForLayerFeature = options.getIDForLayerFeature; + /** @type {styleFn|StyleOptions} */ this.style = options.style; + /** @type {string} */ this.name = options.name; + /** @type {filterFn} */ this._filter = options.filter || false; - this._customDraw = options.customDraw || false; + /** @type {number} */ + this._lineClickTolerance = 2; + /** @type {Record}>} */ this._canvasAndMVTFeatures = []; + /** @type {Record} */ this._mVTFeatures = []; + /** @type {drawFn} */ + this._customDraw = options.customDraw || false; } - parseVectorTileFeatures(mVTSource, vectorTileFeatures, tileContext) { - this._canvasAndMVTFeatures[tileContext.id] = { - canvas: tileContext.canvas, - features: [], - }; - for (let i = 0, length = vectorTileFeatures.length; i < length; i++) { - const vectorTileFeature = vectorTileFeatures[i]; - this._parseVectorTileFeature(mVTSource, vectorTileFeature, tileContext, i); + /** + * @param {MVTSource} mVTSource + * @param {VectorTileLayer} vectorTileLayer + * @param {TileContext} tileContext + */ + parseVectorTileFeatures(mVTSource, vectorTileLayer, tileContext) { + this._canvasAndMVTFeatures[tileContext.id] = {canvas: tileContext.canvas, features: []}; + for (let i = 0; i < vectorTileLayer.length; i++) { + this._parseVectorTileFeature(mVTSource, vectorTileLayer.feature(i), tileContext, i); } this.drawTile(tileContext); } - _parseVectorTileFeature(mVTSource, vectorTileFeature, tileContext, i) { - if (this._filter && typeof this._filter === 'function') { - if (this._filter(vectorTileFeature, tileContext) === false) { - return; - } - } - - const style = this.getStyle(vectorTileFeature); - // TODO likely bug: should probably be checking for nullish, not falsy. - const featureId = this._getIDForLayerFeature(vectorTileFeature) || i; - let mVTFeature = this._mVTFeatures[featureId]; - if (!mVTFeature) { - const selected = mVTSource.isFeatureSelected(featureId); - const options = { - mVTSource: mVTSource, - vectorTileFeature: vectorTileFeature, - tileContext: tileContext, - style: style, - selected: selected, - featureId: featureId, - customDraw: this._customDraw, - }; - mVTFeature = new MVTFeature(options); - this._mVTFeatures[featureId] = mVTFeature; - } else { - mVTFeature.setStyle(style); + /** + * @param {MVTSource} mVTSource + * @param {VectorTileFeature} vectorTileFeature + * @param {TileContext} tileContext + * @param {number} index + */ + _parseVectorTileFeature(mVTSource, vectorTileFeature, tileContext, index) { + // if the filter has been defined and returns false, skip the feature + if (this._filter && typeof this._filter === 'function' && !this._filter(vectorTileFeature, tileContext)) return; + + const featureId = this._getIDForLayerFeature(vectorTileFeature) ?? index; + const mVTFeature = this._mVTFeatures[featureId]; + + // if the feature has already been seen, update the style and add the new geometry. + if (mVTFeature) { + mVTFeature.style = this.getStyle(vectorTileFeature); mVTFeature.addTileFeature(vectorTileFeature, tileContext); + this._canvasAndMVTFeatures[tileContext.id].features.push(mVTFeature); + return; } - this._canvasAndMVTFeatures[tileContext.id].features.push(mVTFeature); + + // if the feature has not been seen, create a new MVTFeature + const newFeature = new MVTFeature({ + mVTSource, + vectorTileFeature, + tileContext, + style: this.getStyle(vectorTileFeature), + selected: mVTSource.isFeatureSelected(featureId), + featureId, + customDraw: this._customDraw, + }); + this._mVTFeatures[featureId] = newFeature; + this._canvasAndMVTFeatures[tileContext.id].features.push(newFeature); } + /** + * draws all the non-selected features first, then the selected features to ensure they appear on top. + * @param {TileContext} tileContext + */ drawTile(tileContext) { const mVTFeatures = this._canvasAndMVTFeatures[tileContext.id].features; if (!mVTFeatures) return; - const selectedFeatures = []; - for (var i = 0, length = mVTFeatures.length; i < length; i++) { - const mVTFeature = mVTFeatures[i]; - if (mVTFeature.selected) { - selectedFeatures.push(mVTFeature); - } else { - mVTFeature.draw(tileContext); - } - } - for (var i = 0, length = selectedFeatures.length; i < length; i++) { - selectedFeatures[i].draw(tileContext); - } - } - - getCanvas(id) { - return this._canvasAndMVTFeatures[id].canvas; + mVTFeatures.filter((mVTFeature) => !mVTFeature.selected).forEach((mVTFeature) => mVTFeature.draw(tileContext)); + mVTFeatures.filter((mVTFeature) => mVTFeature.selected).forEach((mVTFeature) => mVTFeature.draw(tileContext)); } + /** + * @param {VectorTileFeature} feature + * @return {StyleOptions} + */ getStyle(feature) { - if (typeof this.style === 'function') { - return this.style(feature); - } - return this.style; + return (typeof this.style === 'function') ? this.style(feature) : this.style; } + /** + * updates the style for all features in the layer + * @param {styleFn|StyleOptions} style + */ setStyle(style) { this.style = style; - for (const featureId in this._mVTFeatures) { - this._mVTFeatures[featureId].setStyle(style); - } + Object.values(this._mVTFeatures).forEach((mVTFeature) => mVTFeature.style = style); } + /** + * Set the given feature as selected + * @param {string} featureId + */ setSelected(featureId) { - if (this._mVTFeatures[featureId] !== undefined) { - this._mVTFeatures[featureId].select(); - } + if (this._mVTFeatures[featureId] === undefined) return; + this._mVTFeatures[featureId].setSelected(true); } + /** + * Set the filter function for the layer + * @param {filterFn} filter + */ setFilter(filter) { this._filter = filter; } + /** + * Attaches the clicked feature to the event if it exists + * @param {TileMapMouseEvent} event + * @param {MVTSource} mVTSource + * @return {TileMapMouseEvent} + */ handleClickEvent(event, mVTSource) { const canvasAndFeatures = this._canvasAndMVTFeatures[event.tileContext.id]; - if (!canvasAndFeatures) return event; - const canvas = canvasAndFeatures.canvas; - const mVTFeatures = canvasAndFeatures.features; - - if (!canvas || !mVTFeatures) { - return event; - } - event.feature = this._handleClickEvent(event, mVTFeatures, mVTSource); + // if the tile has not been parsed yet, pass the event through + if (!canvasAndFeatures?.canvas || !canvasAndFeatures?.features) return event; + // if the tile has been parsed, attach the feature to the event + event.feature = this._handleClickEvent(event, canvasAndFeatures.features, mVTSource); return event; } + /** + * First searches for a clicked feature in the currently selected features in the tile, then searches for a clicked + * feature in all features in the tile. Returns the first feature that is found to be clicked. + * @param {TileMapMouseEvent} event + * @param {Array} mVTFeatures + * @param {MVTSource} mVTSource + * @return {MVTFeature} + */ _handleClickEvent(event, mVTFeatures, mVTSource) { - this.selectedFeature = null; - - const tileContextId = event.tileContext.id; - const currentSelectedFeaturesInTile = mVTSource.getSelectedFeaturesInTile(tileContextId); - this._handleClickFeatures(event, currentSelectedFeaturesInTile); - - if (this.selectedFeature != null) { - return this.selectedFeature; - } - - this._handleClickFeatures(event, mVTFeatures); - if (this.selectedFeature != null) { - return this.selectedFeature; - } - - return this.selectedFeature; + const currentSelectedFeaturesInTile = mVTSource.getSelectedFeaturesInTile(event?.tileContext?.id); + const feature = this._handleClickFeatures(event, currentSelectedFeaturesInTile); + return feature ? feature : this._handleClickFeatures(event, mVTFeatures); } + /** + * Returns the first feature that is found to be clicked + * @param {TileMapMouseEvent} event + * @param {Array} mVTFeatures + * @return {MVTFeature} + */ _handleClickFeatures(event, mVTFeatures) { - this.minDistance = Number.POSITIVE_INFINITY; - - for (let i = mVTFeatures.length - 1; i >= 0; i--) { - const mVTFeature = mVTFeatures[i]; - this._handleClickFeature(event, mVTFeature); - if (this.selectedFeature != null) { - return this.selectedFeature; - } - } + return mVTFeatures.find((mVTFeature) => this._handleClickFeature(event, mVTFeature)); } + /** + * Dispatches to the appropriate handler based on the feature type and returns the result + * @param {TileMapMouseEvent} event + * @param {MVTFeature} mVTFeature + * @return {boolean} + */ _handleClickFeature(event, mVTFeature) { - switch (mVTFeature.type) { - case 3:// polygon - this._handleClickFeaturePolygon(event, mVTFeature); - break; - default: { - this._handleClickFeatureDefault(event, mVTFeature); - break; - } - } + return ({ + 3: this._handleClickFeaturePolygon, + 2: this._handleClickFeatureLineString, + 1: this._handleClickFeaturePoint, + })[mVTFeature.type]?.(event, mVTFeature); } + /** + * Returns true if the clicked point is within the polygon feature + * @param {TileMapMouseEvent} event + * @param {MVTFeature} mVTFeature + * @return {boolean} + */ _handleClickFeaturePolygon(event, mVTFeature) { - if (mVTFeature.isPointInPath(event.tilePoint, event.tileContext)) { - this.selectedFeature = mVTFeature; - this.minDistance = 0; - } + return mVTFeature.isPointInPath(event.tilePoint, event.tileContext); } - _handleClickFeatureDefault(event, mVTFeature) { - const paths = mVTFeature.getPaths(event.tileContext); - for (let j = paths.length - 1; j >= 0; j--) { - const path = paths[j]; - switch (mVTFeature.type) { - case 1: // Point - if (MERCATOR.inCircle(path[0].x, path[0].y, mVTFeature.style.radius, event.tilePoint.x, event.tilePoint.y)) { - this.selectedFeature = mVTFeature; - this.minDistance = 0; - } - break; - case 2: // LineString - var distance = MERCATOR.getDistanceFromLine(event.tilePoint, path); - var thickness = (mVTFeature.selected && mVTFeature.style.selected ? mVTFeature.style.selected.lineWidth : mVTFeature.style.lineWidth); - if (distance < thickness / 2 + this._lineClickTolerance && distance < this.minDistance) { - this.selectedFeature = mVTFeature; - this.minDistance = distance; - } - break; - } - if (this.minDistance == 0) { - return this.selectedFeature; - } + /** + * Returns true if the clicked point is within the radius of the Point feature + * @param {TileMapMouseEvent} event + * @param {MVTFeature} mVTFeature + * @return {boolean} + */ + _handleClickFeaturePoint(event, mVTFeature) { + return mVTFeature.getPaths(event.tileContext).some((path) => { + return MERCATOR.inCircle(path[0].x, path[0].y, mVTFeature.style.radius, event.tilePoint.x, event.tilePoint.y); + }); + } + + /** + * Returns true if the click event is within the line width and tolerance of any of the line segments + * @param {TileMapMouseEvent} event + * @param {MVTFeature} mVTFeature + * @return {boolean} + */ + _handleClickFeatureLineString(event, mVTFeature) { + let minDistance = Number.POSITIVE_INFINITY; + let lineWidth = mVTFeature.style.lineWidth; + if (mVTFeature.selected && mVTFeature.style.selected) { + lineWidth = mVTFeature.style.selected.lineWidth; } + mVTFeature.getPaths(event.tileContext).forEach((path) => { + const distance = MERCATOR.getDistanceFromLine(event.tilePoint, path); + if (distance < minDistance) { + minDistance = distance; + } + }); + return minDistance < lineWidth / 2 + this._lineClickTolerance; } } -export {MVTLayer} \ No newline at end of file +export {MVTLayer}; diff --git a/src/MVTSource.js b/src/MVTSource.js index dad4af3..964bd20 100644 --- a/src/MVTSource.js +++ b/src/MVTSource.js @@ -1,365 +1,493 @@ /* * Created by Jes�s Barrio on 04/2021 */ + +// eslint-disable-next-line spaced-comment +/// + import Pbf from 'pbf'; import {VectorTile} from '@mapbox/vector-tile'; import * as MERCATOR from '../lib/mercator/Mercator.js'; -import MVTLayer from './MVTLayer.js'; -export class MVTSource { - constructor(map, options) { - const self = this; - this.map = map; - this._url = options.url || ''; // Url TO Vector Tile Source, - this._sourceMaxZoom = options.sourceMaxZoom || false; // Source maxzoom to enable overzoom - this._debug = options.debug || false; // Draw tiles lines and ids - this.getIDForLayerFeature = options.getIDForLayerFeature || function(feature) { - return feature.properties.id || feature.properties.Id || feature.properties.ID; - }; - this._visibleLayers = options.visibleLayers || false; // List of visible layers - this._xhrHeaders = options.xhrHeaders || {}; // Headers added to every url request - this._clickableLayers = options.clickableLayers || false; // List of layers that are clickable - this._filter = options.filter || false; // Filter features - this._cache = options.cache || false; // Load tiles in cache to avoid duplicated requests - this._tileSize = options.tileSize || 256; // Default tile size - this.tileSize = new google.maps.Size(this._tileSize, this._tileSize); - this.style = options.style || function(feature) { - const style = {}; - switch (feature.type) { - case 1: // 'Point' - style.fillStyle = 'rgba(49,79,79,1)'; - style.radius = 5; - style.selected = { - fillStyle: 'rgba(255,255,0,0.5)', - radius: 6, - }; - break; - case 2: // 'LineString' - style.strokeStyle = 'rgba(136, 86, 167, 1)'; - style.lineWidth = 3; - style.selected = { - strokeStyle: 'rgba(255,25,0,0.5)', - lineWidth: 4, - }; - break; - case 3: // 'Polygon' - style.fillStyle = 'rgba(188, 189, 220, 0.5)'; - style.strokeStyle = 'rgba(136, 86, 167, 1)'; - style.lineWidth = 1; - style.selected = { - fillStyle: 'rgba(255,140,0,0.3)', - strokeStyle: 'rgba(255,140,0,1)', - lineWidth: 2, - }; - break; - } - return style; - }; - this._customDraw = options.customDraw || false; +import {MVTLayer} from './MVTLayer.js'; +import {getTileFromString, getTileString} from '../lib/geometry.js'; + +/** + * @typedef {import('@mapbox/vector-tile').VectorTileLayer} VectorTileLayer + * @typedef {import('@mapbox/vector-tile').VectorTileFeature} VectorTileFeature + * @typedef {import('./MVTFeature').FeatureTile} FeatureTile + * @typedef {import('./MVTFeature').MVTFeature} MVTFeature + * @typedef {import('./MVTLayer').TileMapMouseEvent} TileMapMouseEvent + */ - this.mVTLayers = []; // Keep a list of the layers contained in the PBFs - this._tilesDrawn = []; // List of tiles drawn (when cache enabled) - this._visibleTiles = []; // tiles currently in the viewport - this._selectedFeatures = []; // list of selected features - if (options.selectedFeatures) { - this.setSelectedFeatures(options.selectedFeatures); - } +/** + * @callback featureIdFn - A function that returns a unique id for a feature + * @param {VectorTileFeature} feature + * @return {string|number} + * + * @callback styleFn - A function that returns a style for a feature + * @param {VectorTileFeature} feature + * @return {StyleOptions} + * + * @callback drawFn - A function that returns a style for a feature + * @param {TileContext} tileContext + * @param {FeatureTile} tile + * @param {StyleOptions} style + * @return {void} + * + * @callback filterFn - A function that returns a style for a feature + * @param {VectorTileFeature} feature + * @param {TileContext} context + * @return {boolean} + */ - this.map.addListener('zoom_changed', () => { - self._zoomChanged(); - }); - } +/** + * @typedef {Object} MVTSourceOptions + * @property {string} [url] Url to Vector Tile Source + * @property {number} [sourceMaxZoom] Source max zoom to enable over zoom + * @property {boolean} [debug] Draw tiles lines and ids + * @property {boolean} [cache=false] Load tiles in cache to avoid duplicated requests + * @property {number} [tileSize=256] Tile size + * @property {Array} [visibleLayers] List of visible layers + * @property {Array} [clickableLayers] List of layers that are clickable + * @property {Array} [selectedFeatures] List of selected features + * @property {featureIdFn} [getIDForLayerFeature] Function to get id for layer feature + * @property {styleFn} [style] Styling function + * @property {filterFn} [filter] Filter function + * @property {drawFn} [customDraw] Custom draw function +*/ + +/** + * @typedef {Object} TileContext + * @property {string} id Tile id in format 'zoom:x:y' + * @property {HTMLCanvasElement} canvas Canvas element for drawing tile + * @property {number} zoom Zoom level this tile belongs to + * @property {number} tileSize Tile size + * @property {string} parentId Parent tile id in format 'zoom:x:y' + * @property {VectorTile} [vectorTile] + */ - getTile(coord, zoom, ownerDocument) { - const tileContext = this.drawTile(coord, zoom, ownerDocument); - this._setVisibleTile(tileContext); - return tileContext.canvas; - } +/** + * @typedef {Object} StyleOptions + * @property {string} fillStyle Fill color + * @property {string} strokeStyle Stroke color + * @property {number} lineWidth Stroke width + * @property {number} radius Point radius + * @property {StyleOptions} selected Selected style + */ - releaseTile(canvas) { - // this._deleteVisibleTile(canvas.id); - } +/** + * @typedef {Object} ClickHandlerOptions + * @property {boolean} [limitToFirstVisibleLayer=false] Trigger events only to the first visible layer + * @property {boolean} [multipleSelection=false] Multiple feature selection + * @property {boolean} [setSelected=false] Set feature selected style + * @property {boolean} [toggleSelection=true] Toggle feature selected style + * @property {number} [delay=0] If new event is triggered before delay, old event will be ignored. Used to avoid + * overload on mousemove event + */ - _zoomChanged() { - this._resetVisibleTiles(); - if (!this._cache) { - this._resetMVTLayers(); +/** + * Returns a fully populated ClickHandlerOptions object, merging the default values with the provided options + * @param {ClickHandlerOptions} [options] + * @return {ClickHandlerOptions} + * @private + */ +const getMouseOptions = (options={}) => { + return { + setSelected: options.setSelected || false, + toggleSelection: (options.toggleSelection === undefined || options.toggleSelection), + limitToFirstVisibleLayer: options.limitToFirstVisibleLayer || false, + delay: options.delay || 0, + multipleSelection: options.multipleSelection || false, + }; +}; + +/** + * Returns the default styling function + * @param {VectorTileFeature} feature + * @return {StyleOptions} + * @private + */ +const defaultStyleFn = function(feature) { + return { + 1: { // Point + fillStyle: 'rgba(49,79,79,1)', + radius: 5, + selected: { + fillStyle: 'rgba(255,255,0,0.5)', + radius: 6, + }, + }, + 2: { // LineString + strokeStyle: 'rgba(136, 86, 167, 1)', + lineWidth: 3, + selected: { + strokeStyle: 'rgba(255,25,0,0.5)', + lineWidth: 4, + }, + }, + 3: { // Polygon + fillStyle: 'rgba(188, 189, 220, 0.5)', + strokeStyle: 'rgba(136, 86, 167, 1)', + lineWidth: 1, + selected: { + fillStyle: 'rgba(255,140,0,0.3)', + strokeStyle: 'rgba(255,140,0,1)', + lineWidth: 2, + }, + }, + }[feature.type] || {}; +}; + +/** + * @param {VectorTileFeature} feature + * @return {string|number} + * @private + */ +const defaultFeatureIdFn = function(feature) { + return feature?.properties?.id || feature?.properties?.Id || feature?.properties?.ID; +}; + +/** + * @param {string} tileId + * @param {number} maxZoom + * @return {string} Parent tile id + * @private + */ +const getParentId = (tileId, maxZoom) => { + if (!maxZoom) return ''; + const tile = getTileFromString(tileId); + if (!(tile.zoom > maxZoom)) return ''; + const zoomDistance = tile.zoom - maxZoom; + const zoom = tile.zoom - zoomDistance; + const x = tile.x >> zoomDistance; + const y = tile.y >> zoomDistance; + return getTileString(zoom, x, y); +}; + +/** + * @param {Document} ownerDocument + * @param {string} tileId + * @param {number} tileSize + * @return {HTMLCanvasElement} + * @private + */ +const createCanvas = (ownerDocument, tileId, tileSize) => { + const canvas = ownerDocument.createElement('canvas'); + canvas.width = tileSize; + canvas.height = tileSize; + canvas.id = tileId; + return canvas; +}; + +/** + * MVTSource is a class to load and draw Vector Tiles from a source. + * @class + * @implements {google.maps.MapType} + */ +class MVTSource { + /** + * @param {google.maps.Map} map + * @param {MVTSourceOptions} options + */ + constructor(map, options = {}) { + // Private properties + /** @type {string} Url to Vector Tile Source */ + this._url = options.url || ''; + /** @type {number} Source max zoom to enable over zoom */ + this._sourceMaxZoom = options.sourceMaxZoom ?? null; + /** @type {boolean} Draw tiles lines and ids */ + this._debug = options.debug || false; + /** @type {Array} List of visible layers */ + this._visibleLayers = options.visibleLayers || null; + /** @type {Array} List of layers that are clickable */ + this._clickableLayers = options.clickableLayers || null; + /** @type {boolean} Load tiles in cache to avoid duplicated requests */ + this._cache = options.cache || false; + /** @type {number} Default tile size */ + this._tileSize = options.tileSize || 256; + /** @type {filterFn} filter function to allow/deny features */ + this._filter = options.filter || false; // Filter features + /** @type {Record} Additional headers to add when requesting tiles from the server */ + this._xhrHeaders = options.xhrHeaders || {}; // Headers added to every url request + /** @type {drawFn} */ + this._customDraw = options.customDraw || null; + /** @type {boolean} Allow multiple selection */ + this._multipleSelection = options.multipleSelection || false; + + /** @type {Record} List of tiles drawn. Only populated when cache enabled */ + this._tilesDrawn = {}; + /** @type {Record} List of tiles currently in the viewport */ + this._visibleTiles = {}; // tiles currently in the viewport. Reset on zoom_changed, populated on getTile + /** @type {Record} List of selected features */ + this._selectedFeatures = {}; // list of selected features + + // Public properties + /** @type {google.maps.Map} */ + this.map = map; + /** @type {featureIdFn} Function to get id for layer feature */ + this.getIDForLayerFeature = options.getIDForLayerFeature || defaultFeatureIdFn; + /** @type {google.maps.Size} */ + this.tileSize = new window.google.maps.Size(this._tileSize, this._tileSize); + /** @type {styleFn|StyleOptions} */ + this.style = options.style || defaultStyleFn; + /** @type {Record} Keep a list of the layers contained in the PBFs */ + this.mVTLayers = {}; + + // Init + if (options.selectedFeatures) { + this.setSelectedFeatures(options.selectedFeatures); } + this.map.addListener('zoom_changed', () => { + this._visibleTiles = {}; + if (!this._cache) { + this.mVTLayers = {}; + } + }); } - _resetMVTLayers() { - this.mVTLayers = []; - } - - _deleteVisibleTile(id) { - delete this._visibleTiles[id]; - } - - _resetVisibleTiles() { - this._visibleTiles = []; - } - - _setVisibleTile(tileContext) { + /** + * Invoked by the Google Maps API as part of the MapType interface. + * Returns a tile for the given tile coordinate (x, y) and zoom level. This tile will be appended to the given + * ownerDocument. Not available for base map types. + * @param {google.maps.Point} tileCoord + * @param {number} zoom + * @param {Document} ownerDocument + * @return {Element} + */ + getTile(tileCoord, zoom, ownerDocument) { + const tileContext = this.drawTile(tileCoord, zoom, ownerDocument); this._visibleTiles[tileContext.id] = tileContext; + return tileContext.canvas; } + /** + * Invoked by the Google Maps API as part of the MapType interface. + * Releases the given tile, performing any necessary cleanup. The provided tile will have already been removed from + * the document. Optional. + * @param {Element} tile + */ + releaseTile(tile) {} + + /** + * @param {google.maps.Point} coord + * @param {number} zoom + * @param {Document} ownerDocument + * @return {TileContext} + */ drawTile(coord, zoom, ownerDocument) { - const id = this.getTileId(zoom, coord.x, coord.y); - let tileContext = this._tilesDrawn[id]; - if (tileContext) { - return tileContext; + const id = getTileString(zoom, coord.x, coord.y); + if (this._tilesDrawn[id]) { + return this._tilesDrawn[id]; } - - tileContext = this._createTileContext(coord, zoom, ownerDocument); - this._xhrRequest(tileContext); - return tileContext; - } - - _createTileContext(coord, zoom, ownerDocument) { - const id = this.getTileId(zoom, coord.x, coord.y); - const canvas = this._createCanvas(ownerDocument, id); - const parentId = this._getParentId(id); - - return { - id: id, - canvas: canvas, - zoom: zoom, + const canvas = createCanvas(ownerDocument, id, this._tileSize); + const parentId = getParentId(id, this._sourceMaxZoom); + const tileContext = { + id, + canvas, + zoom, tileSize: this._tileSize, - parentId: parentId, - }; - } - - _getParentId(id) { - let parentId = false; - if (this._sourceMaxZoom) { - const tile = this.getTileObject(id); - if (tile.zoom > this._sourceMaxZoom) { - const zoomDistance = tile.zoom - this._sourceMaxZoom; - const zoom = tile.zoom - zoomDistance; - const x = tile.x >> zoomDistance; - const y = tile.y >> zoomDistance; - parentId = this.getTileId(zoom, x, y); - } - } - return parentId; - } - - _createCanvas(ownerDocument, id) { - const canvas = ownerDocument.createElement('canvas'); - canvas.width = this._tileSize; - canvas.height = this._tileSize; - canvas.id = id; - return canvas; - } - - getTileId(zoom, x, y) { - return [zoom, x, y].join(':'); - } - - getTileObject(id) { - const values = id.split(':'); - return { - zoom: values[0], - x: values[1], - y: values[2], + parentId, }; + this._fetchTile(tileContext); + return tileContext; } - _xhrRequest(tileContext) { - const self = this; - + /** + * @param {TileContext} tileContext + */ + async _fetchTile(tileContext) { const id = tileContext.parentId || tileContext.id; - const tile = this.getTileObject(id); - - const src = this._url - .replace('{z}', tile.zoom) - .replace('{x}', tile.x) - .replace('{y}', tile.y); - - const xmlHttpRequest = new XMLHttpRequest(); - xmlHttpRequest.onload = function() { - if (xmlHttpRequest.status == '200' && xmlHttpRequest.response) { - return self._xhrResponseOk(tileContext, xmlHttpRequest.response); - } - self._drawDebugInfo(tileContext); - }; - xmlHttpRequest.open('GET', src, true); - for (const header in this._xhrHeaders) { - xmlHttpRequest.setRequestHeader(header, this._xhrHeaders[header]); + const tile = getTileFromString(id); + + const src = this._url.replace('{z}', tile.zoom).replace('{x}', tile.x).replace('{y}', tile.y); + /** @type {Response} */ + let response; + try { + response = await fetch(src, { + headers: this._xhrHeaders, + }); + } catch (error) { + console.error(new Error(`Error fetching tile ${src}`), error); } - xmlHttpRequest.responseType = 'arraybuffer'; - xmlHttpRequest.send(); - } + if (response.ok) { + // If the zoom has changed since the request was made, don't draw the tile + if (this.map.getZoom() != tileContext.zoom) return; - _xhrResponseOk(tileContext, response) { - if (this.map.getZoom() != tileContext.zoom) { - return; - } - const uint8Array = new Uint8Array(response); - const pbf = new Pbf(uint8Array); - const vectorTile = new VectorTile(pbf); - // This is copied from the code originally found in VectorTile.js - // It is necessary to actually load the geometry of each feature before they can be drawn - for (var key in vectorTile.layers) { - var layer = vectorTile.layers[key]; - layer.parsedFeatures = []; - var featuresLength = layer._features.length; - for (var i = 0, len = featuresLength; i < len; i++) { - var feature = layer.feature(i); - feature.coordinates = feature.loadGeometry(); - layer.parsedFeatures.push(feature); - } - vectorTile.layers[key] = layer; + const arrayBuffer = await response.arrayBuffer(); + const vectorTile = new VectorTile((new Pbf((new Uint8Array(arrayBuffer))))); + this._drawVectorTile(vectorTile, tileContext); } - this._drawVectorTile(vectorTile, tileContext); - } - - _setTileDrawn(tileContext) { - if (!this._cache) return; - this._tilesDrawn[tileContext.id] = tileContext; - } - - deleteTileDrawn(id) { - delete this._tilesDrawn[id]; - } - - _resetTileDrawn() { - this._tilesDrawn = []; + this._drawDebugInfo(tileContext); } + /** + * @param {VectorTile} vectorTile + * @param {TileContext} tileContext + */ _drawVectorTile(vectorTile, tileContext) { - if (this._visibleLayers) { - for (let i = 0, length = this._visibleLayers.length; i < length; i++) { - var key = this._visibleLayers[i]; - if (vectorTile.layers[key]) { - var vectorTileLayer = vectorTile.layers[key]; - this._drawVectorTileLayer(vectorTileLayer, key, tileContext); - } - } - } else { - for (var key in vectorTile.layers) { - var vectorTileLayer = vectorTile.layers[key]; - this._drawVectorTileLayer(vectorTileLayer, key, tileContext); - } - } + // If the user has specified a list of layers to draw, only draw those layers + const layers = this._visibleLayers ? this._visibleLayers : Object.keys(vectorTile.layers); + layers.forEach((key) => { + if (!vectorTile.layers[key]) return; // If the user has specified a layer that doesn't exist, skip it + this._drawVectorTileLayer(vectorTile.layers[key], key, tileContext); + }); + tileContext.vectorTile = vectorTile; - this._drawDebugInfo(tileContext); - this._setTileDrawn(tileContext); + if (!this._cache) return; + // If cache is enabled, store the TileContext in the cache + this._tilesDrawn[tileContext.id] = tileContext; } - _drawVectorTileLayer(vectorTileLayer, key, tileContext) { - if (!this.mVTLayers[key]) { - this.mVTLayers[key] = this._createMVTLayer(key); + /** + * @param {VectorTileLayer} vectorTileLayer + * @param {string} name + * @param {TileContext} tileContext + */ + _drawVectorTileLayer(vectorTileLayer, name, tileContext) { + if (!this.mVTLayers[name]) { + this.mVTLayers[name] = this._createMVTLayer(name); } - const mVTLayer = this.mVTLayers[key]; - mVTLayer.parseVectorTileFeatures(this, vectorTileLayer.parsedFeatures, tileContext); + const mVTLayer = this.mVTLayers[name]; + mVTLayer.parseVectorTileFeatures(this, vectorTileLayer, tileContext); } - _createMVTLayer(key) { + /** + * Creates a new MVTLayer instance + * @param {string} name name of the layer + * @return {MVTLayer} MVTLayer instance + */ + _createMVTLayer(name) { const options = { getIDForLayerFeature: this.getIDForLayerFeature, - filter: this._filter, style: this.style, - name: key, + name, + filter: this._filter, customDraw: this._customDraw, }; return new MVTLayer(options); } + /** + * @param {TileContext} tileContext + */ _drawDebugInfo(tileContext) { if (!this._debug) return; - const tile = this.getTileObject(tileContext.id); + const tile = getTileFromString(tileContext.id); const width = this._tileSize; const height = this._tileSize; const context2d = tileContext.canvas.getContext('2d'); context2d.strokeStyle = '#000000'; context2d.fillStyle = '#FFFF00'; - context2d.strokeRect(0, 0, width, height); context2d.font = '12px Arial'; - context2d.fillRect(0, 0, 5, 5); - context2d.fillRect(0, height - 5, 5, 5); - context2d.fillRect(width - 5, 0, 5, 5); - context2d.fillRect(width - 5, height - 5, 5, 5); - context2d.fillRect(width / 2 - 5, height / 2 - 5, 10, 10); - context2d.strokeText(tileContext.zoom + ' ' + tile.x + ' ' + tile.y, width / 2 - 30, height / 2 - 10); + context2d.strokeRect(0, 0, width, height); // outer border + context2d.fillRect(0, 0, 5, 5); // top left corner marker + context2d.fillRect(0, height - 5, 5, 5); // bottom left corner marker + context2d.fillRect(width - 5, 0, 5, 5); // top right corner marker + context2d.fillRect(width - 5, height - 5, 5, 5); // bottom right corner marker + context2d.fillRect(width / 2 - 5, height / 2 - 5, 10, 10); // center marker + context2d.strokeText(`Z: ${tileContext.zoom} X: ${tile.x} Y: ${tile.y}`, 10, 20); + if (tileContext.vectorTile) { + context2d.strokeText(`Layers: ${Object.keys(tileContext.vectorTile.layers).length}`, 10, 20 + 15); + Object.entries(tileContext.vectorTile.layers).forEach(([key, layer], index) => { + context2d.strokeText(`${key}: ${layer.length}`, 10, 20 + 15 + (index + 1) * 15); + }); + } } + /** + * Wrap a mouse click event with a callback function + * @param {google.maps.MapMouseEvent} event + * @param {(event: TileMapMouseEvent)} callbackFunction + * @param {ClickHandlerOptions} options + */ onClick(event, callbackFunction, options) { this._multipleSelection = (options && options.multipleSelection) || false; - options = this._getMouseOptions(options, false); + options = getMouseOptions(options); + options.mouseHover = false; this._mouseEvent(event, callbackFunction, options); } + /** + * Wrap a mouse hover event with a callback function + * @param {google.maps.MapMouseEvent} event + * @param {(event: TileMapMouseEvent)} callbackFunction + * @param {ClickHandlerOptions} options + */ onMouseHover(event, callbackFunction, options) { this._multipleSelection = false; - options = this._getMouseOptions(options, true); + options = getMouseOptions(options); + options.mouseHover = true; this._mouseEvent(event, callbackFunction, options); } - _getMouseOptions(options, mouseHover) { - return { - mouseHover: mouseHover, - setSelected: options.setSelected || false, - toggleSelection: (options.toggleSelection === undefined || options.toggleSelection), - limitToFirstVisibleLayer: options.limitToFirstVisibleLayer || false, - delay: options.delay || 0, - }; - } - + /** + * @param {google.maps.MapMouseEvent} event + * @param {(event: TileMapMouseEvent)} callbackFunction + * @param {ClickHandlerOptions} options + */ _mouseEvent(event, callbackFunction, options) { - if (!event.pixel || !event.latLng) return; - - if (options.delay == 0) { - return this._mouseEventContinue(event, callbackFunction, options); + // If the received event does not have a latLng, it is not a valid event + if (!event.latLng) { + console.warn('Invalid event received. Expected latLng to be defined.', event); + return; } - this.event = event; - const me = this; - setTimeout(function() { - if (event != me.event) return; - me._mouseEventContinue(me.event, callbackFunction, options); - }, options.delay, event); - } - _mouseEventContinue(event, callbackFunction, options) { - callbackFunction = callbackFunction || function() { }; - const limitToFirstVisibleLayer = options.limitToFirstVisibleLayer || false; - const zoom = this.map.getZoom(); - const tile = MERCATOR.getTileAtLatLng(event.latLng, zoom); - const id = this.getTileId(tile.z, tile.x, tile.y); - const tileContext = this._visibleTiles[id]; - if (!tileContext) { + if (options.delay == 0) { + this._mouseEventContinue(event, callbackFunction, options); return; } - event.tileContext = tileContext; - event.tilePoint = MERCATOR.fromLatLngToTilePoint(this.map, event); - - const clickableLayers = this._clickableLayers || Object.keys(this.mVTLayers) || []; - for (let i = clickableLayers.length - 1; i >= 0; i--) { - const key = clickableLayers[i]; - const layer = this.mVTLayers[key]; - if (layer) { - var event = layer.handleClickEvent(event, this); - this._mouseSelectedFeature(event, callbackFunction, options); - if (limitToFirstVisibleLayer && event.feature) { - break; - } - } + + setTimeout(() => this._mouseEventContinue(event, callbackFunction, options), options.delay); + } + + /** + * @param {google.maps.MapMouseEvent} event + * @param {(event: TileMapMouseEvent)} [callbackFunction=()=>{}] + * @param {ClickHandlerOptions} options + */ + _mouseEventContinue(event, callbackFunction = ()=>{}, options) { + const tile = MERCATOR.getTileAtLatLng(event.latLng, this.map.getZoom()); + const tileId = getTileString(tile.z, tile.x, tile.y); + const tileContext = this._visibleTiles[tileId]; + if (!tileContext) return; + + const tilePoint = MERCATOR.fromLatLngToTilePoint(this.map, event); + /** @type {TileMapMouseEvent} */ + const newEvent = { + ...event, + tileContext, + tilePoint: new window.google.maps.Point(tilePoint.x, tilePoint.y), + }; + + // if specific layers have been defined as clickable, only check those + for (const layerName of (this._clickableLayers || Object.keys(this.mVTLayers))) { + const layer = this.mVTLayers[layerName]; + if (!layer) continue; + layer.handleClickEvent(newEvent, this); + this._mouseSelectedFeature(newEvent, callbackFunction, options); + if (options.limitToFirstVisibleLayer) break; } } + /** + * @param {TileMapMouseEvent} event + * @param {(event: TileMapMouseEvent)} callbackFunction + * @param {ClickHandlerOptions} options + */ _mouseSelectedFeature(event, callbackFunction, options) { if (options.setSelected) { const feature = event.feature; if (feature) { if (options.mouseHover) { if (!feature.selected) { - feature.select(); + feature.setSelected(true); } } else { if (options.toggleSelection) { - feature.toggle(); + feature.setSelected(!feature.selected); } else { if (!feature.selected) { - feature.select(); + feature.setSelected(true); } } } @@ -374,24 +502,25 @@ export class MVTSource { deselectAllFeatures() { const zoom = this.map.getZoom(); + /** @type {Array} */ const tilesToRedraw = []; - for (const featureId in this._selectedFeatures) { - const mVTFeature = this._selectedFeatures[featureId]; - if (!mVTFeature) continue; + Object.entries(this._selectedFeatures).forEach(([featureId, mVTFeature]) => { + if (!mVTFeature) return; mVTFeature.setSelected(false); - const tiles = mVTFeature.getTiles(); - for (const id in tiles) { - this.deleteTileDrawn(id); - const idObject = this.getTileObject(id); - if (idObject.zoom == zoom) { - tilesToRedraw[id] = true; + Object.entries(mVTFeature.tiles).forEach(([tileId, tile]) => { + delete this._tilesDrawn[tileId]; + if (getTileFromString(tileId).zoom == zoom) { + tilesToRedraw.push(tileId); } - } - } + }); + }); this.redrawTiles(tilesToRedraw); - this._selectedFeatures = []; + this._selectedFeatures = {}; } + /** + * @param {MVTFeature} mVTFeature + */ featureSelected(mVTFeature) { if (!this._multipleSelection) { this.deselectAllFeatures(); @@ -399,118 +528,158 @@ export class MVTSource { this._selectedFeatures[mVTFeature.featureId] = mVTFeature; } + /** + * @param {MVTFeature} mvtFeature + */ featureDeselected(mvtFeature) { delete this._selectedFeatures[mvtFeature.featureId]; } + /** + * @param {Array} featuresIds + */ setSelectedFeatures(featuresIds) { if (featuresIds.length > 1) { this._multipleSelection = true; } this.deselectAllFeatures(); - for (let i = 0, length = featuresIds.length; i < length; i++) { - const featureId = featuresIds[i]; + featuresIds.forEach((featureId) => { + // HACK: this may be called before layers are loaded, but we need to keep track of the selected features for + // rendering when they are loaded this._selectedFeatures[featureId] = false; - for (const key in this.mVTLayers) { - this.mVTLayers[key].setSelected(featureId); - } - } + Object.values(this.mVTLayers).forEach((layer) => { + layer.setSelected(featureId); + }); + }); } + /** + * @param {string} featureId + * @return {boolean} + */ isFeatureSelected(featureId) { return this._selectedFeatures[featureId] != undefined; } + /** + * @return {Array} + */ getSelectedFeatures() { - const selectedFeatures = []; - for (const featureId in this._selectedFeatures) { - selectedFeatures.push(this._selectedFeatures[featureId]); - } - return selectedFeatures; + return Object.values(this._selectedFeatures); } + /** + * @param {string} tileContextId tile id in the format 'zoom:x:y' + * @return {Array} + */ getSelectedFeaturesInTile(tileContextId) { + /** @type {Array} */ const selectedFeatures = []; - for (const featureId in this._selectedFeatures) { - const selectedFeature = this._selectedFeatures[featureId]; - for (const tile in selectedFeature.tiles) { - if (tile == tileContextId) { - selectedFeatures.push(selectedFeature); - } + Object.values(this._selectedFeatures).forEach((selectedFeature) => { + if (selectedFeature.tiles[tileContextId]) { + selectedFeatures.push(selectedFeature); } - } + }); return selectedFeatures; } - setFilter(filter, redrawTiles) { - redrawTiles = (redrawTiles === undefined || redrawTiles); + /** + * @param {filterFn} filter + * @param {boolean} [redrawTiles=true] + */ + setFilter(filter, redrawTiles = true) { this._filter = filter; - for (const key in this.mVTLayers) { - this.mVTLayers[key].setFilter(filter); - } + Object.values(this.mVTLayers).forEach((layer) => layer.setFilter(filter)); if (redrawTiles) { this.redrawAllTiles(); } } - setStyle(style, redrawTiles) { - redrawTiles = (redrawTiles === undefined || redrawTiles); + /** + * @param {styleFn|StyleOptions} style + * @param {boolean} [redrawTiles=true] + */ + setStyle(style, redrawTiles = true) { this.style = style; - for (const key in this.mVTLayers) { - this.mVTLayers[key].setStyle(style); - } - + Object.values(this.mVTLayers).forEach((layer) => layer.setStyle(style)); if (redrawTiles) { this.redrawAllTiles(); } } - setVisibleLayers(visibleLayers, redrawTiles) { - redrawTiles = (redrawTiles === undefined || redrawTiles); - this._visibleLayers = visibleLayers; + /** + * @param {Array} visibleLayers + * @param {boolean} [redrawTiles=true] + */ + setVisibleLayers(visibleLayers, redrawTiles = true) { + this._visibleLayers = visibleLayers || null; if (redrawTiles) { this.redrawAllTiles(); } } + /** + * @return {Array} + */ getVisibleLayers() { return this._visibleLayers; } + /** + * @param {Array} clickableLayers + */ setClickableLayers(clickableLayers) { - this._clickableLayers = clickableLayers; + this._clickableLayers = clickableLayers || null; } + /** + * Redraw all visible tiles + */ redrawAllTiles() { - this._resetTileDrawn(); - this.redrawTiles(this._visibleTiles); + this._tilesDrawn = {}; + this.redrawTiles(Object.keys(this._visibleTiles)); } - redrawTiles(tiles) { - for (const id in tiles) { - this.redrawTile(id); - } + /** + * Redraw the tiles specified by ab array of tile ids + * @param {Array} tiles + */ + redrawTiles(tiles = []) { + tiles.forEach((id) => this.redrawTile(id)); } + /** + * Redraw the tile specified by the tile id + * @param {string} id + */ redrawTile(id) { - this.deleteTileDrawn(id); + delete this._tilesDrawn[id]; const tileContext = this._visibleTiles[id]; if (!tileContext || !tileContext.vectorTile) return; this.clearTile(tileContext.canvas); this._drawVectorTile(tileContext.vectorTile, tileContext); } + /** + * @param {HTMLCanvasElement} canvas + */ clearTile(canvas) { - const context = canvas.getContext('2d'); - context.clearRect(0, 0, canvas.width, canvas.height); + canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height); } - setUrl(url, redrawTiles) { - redrawTiles = (redrawTiles === undefined || redrawTiles); + /** + * @param {string} url url of the MVT source + * @param {boolean} [redrawTiles=true] + */ + setUrl(url, redrawTiles = true) { this._url = url; - this._resetMVTLayers(); + this.mVTLayers = {}; if (redrawTiles) { this.redrawAllTiles(); } } } + +export { + MVTSource, +}; diff --git a/tests/MVTFeature.spec.js b/tests/MVTFeature.spec.js index 27e6782..c6f9cbb 100644 --- a/tests/MVTFeature.spec.js +++ b/tests/MVTFeature.spec.js @@ -1,7 +1,23 @@ -import {MVTFeature} from '@/MVTFeature.js'; -import {mockMVTSource, mockVectorTileFeatures, mockCanvas, mockContext} from './common-mocks'; +import {jest} from '@jest/globals'; +import {mockMVTSource, mockVectorTileLayers, mockCanvas, mockContext} from './common-mocks'; +import {initialize, Point} from '@googlemaps/jest-mocks'; +initialize(); -const mockVectorTileFeature = mockVectorTileFeatures[0]; +import {drawPoint, drawLineString, drawPolygon, drawGeometry, getContext2d} from '../lib/drawing.js'; +import {getPoint} from '../lib/geometry'; + +jest.unstable_mockModule('../lib/drawing.js', () => ({ + drawPoint: jest.fn(), + drawLineString: jest.fn(), + drawPolygon: jest.fn(), + getContext2d: jest.fn(), +})); + + +const {drawPoint: mockDrawPoint, drawLineString: mockDrawLineString, drawPolygon: mockDrawPolygon} = await import('../lib/drawing.js'); +const {MVTFeature} = await import('@/MVTFeature.js'); + +const mockVectorTileFeature = mockVectorTileLayers[0].feature(0); // This mocks Path2D of the Canvas API. const mockAddPath = jest.fn(); @@ -9,7 +25,6 @@ const mockMoveTo = jest.fn(); const mockLineTo = jest.fn(); class Path2D { constructor() { - this.addPath = mockAddPath; this.moveTo = mockMoveTo; this.lineTo = mockLineTo; } @@ -21,6 +36,7 @@ const mockTile = { vectorTileFeature: mockVectorTileFeature, paths2d: { closePath: jest.fn(), + addPath: mockAddPath, }, }; const mockTileContext = { @@ -63,7 +79,7 @@ describe('MVTFeature', () => { it('starts with one tile', () => { const mVTFeature = new MVTFeature(mockOptions()); - expect(mVTFeature.tiles).toHaveLength(1); + expect(Object.keys(mVTFeature.tiles)).toHaveLength(1); }); it('if selected, calls mVTSource.featureSelected with this feature', () => { const mVTFeature = new MVTFeature(mockOptions()); @@ -86,40 +102,32 @@ describe('MVTFeature', () => { expect(mVTFeature.tiles[0]).toStrictEqual({ vectorTileFeature: mockVectorTileFeature, divisor: 16, - context2d: false, - paths2d: false, + paths2d: expect.any(Path2D), }); }); - it('creates a sparse `tiles` array if indices are skipped', () => { + it('populates the `tiles` object', () => { const context = {id: 100, tileSize: 2}; const mVTFeature = new MVTFeature(mockOptions()); mVTFeature.addTileFeature(mockVectorTileFeature, context); - expect(mVTFeature.tiles).toHaveLength(101); + expect(Object.keys(mVTFeature.tiles)).toHaveLength(2); // There will be two tiles (one from constructor, one from this test's call) expect(Object.values(mVTFeature.tiles)).toHaveLength(2); }); }); describe('redrawTiles', () => { + /** @type {MVTFeature} */ let mVTFeature; beforeEach(() => { mVTFeature = new MVTFeature(mockOptions()); // Add six tiles for testing for (let i = 1; i < 7; i++) { - mVTFeature.addTileFeature(mockVectorTileFeature, {...mockTileContext, id: i}); - } - }); - it('calls MVTSource.deleteTileDrawn for all tiles', () => { - mVTFeature.redrawTiles(); - - for (let i = 0; i < 7; i++) { - // It's called with the numbers as strings. - expect(mockMVTSource.deleteTileDrawn).toHaveBeenCalledWith(i.toString()); + mVTFeature.addTileFeature(mockVectorTileFeature, {...mockTileContext, id: `${i > 3 ? '13' : '10'}:${i}:0`}); } }); it('calls MVTSource.redrawTile only for tiles at current zoom', () => { - const expectedRedrawn = ['3', '5']; - const expectedNotRedrawn = ['0', '1', '2', '4', '6']; + const expectedRedrawn = ['13:4:0', '13:5:0', '13:6:0']; + const expectedNotRedrawn = ['10:1:0', '10:2:0', '10:3:0', '0']; mVTFeature.redrawTiles(); @@ -136,7 +144,7 @@ describe('MVTFeature', () => { const mVTFeature = new MVTFeature({...mockOptions(), selected: true}); jest.clearAllMocks(); - mVTFeature.toggle(); + mVTFeature.setSelected(!mVTFeature.selected); expect(mockMVTSource.featureDeselected).toHaveBeenCalledWith(mVTFeature); expect(mockMVTSource.featureSelected).not.toHaveBeenCalled(); @@ -145,7 +153,7 @@ describe('MVTFeature', () => { const mVTFeature = new MVTFeature({...mockOptions(), selected: false}); jest.clearAllMocks(); - mVTFeature.toggle(); + mVTFeature.setSelected(!mVTFeature.selected); expect(mockMVTSource.featureSelected).toHaveBeenCalledWith(mVTFeature); expect(mockMVTSource.featureDeselected).not.toHaveBeenCalled(); @@ -158,15 +166,6 @@ describe('MVTFeature', () => { expect(mVTFeature.selected).toBe(false); }); - it.each([true, false])('when setting to %s, does not call MVTSource methods', (value) => { - const mVTFeature = new MVTFeature({...mockOptions(), selected: !value}); - jest.clearAllMocks(); - - mVTFeature.setSelected(value); - - expect(mockMVTSource.featureSelected).not.toHaveBeenCalled(); - expect(mockMVTSource.featureDeselected).not.toHaveBeenCalled(); - }); }); describe('draw', () => { it('calls the draw function with expected non-style arguments', () => { @@ -210,29 +209,26 @@ describe('MVTFeature', () => { }); describe('defaultDraw', () => { it.each([ - {name: 'Point', type: 1, delegatee: 'drawPoint'}, - {name: 'LineString', type: 2, delegatee: 'drawLineString'}, - {name: 'Polygon', type: 3, delegatee: 'drawPolygon'}, + {name: 'Point', type: 1, delegatee: mockDrawPoint}, + {name: 'LineString', type: 2, delegatee: mockDrawLineString}, + {name: 'Polygon', type: 3, delegatee: mockDrawPolygon}, ])('when called with type $type ($name), delegates to $delegatee', ({type, delegatee}) => { + const options = mockOptions(); + delete options.customDraw; const mVTFeature = new MVTFeature({ - ...mockOptions(), + ...options, vectorTileFeature: {...mockVectorTileFeature, type}, }); - mVTFeature.drawPoint = jest.fn(); - mVTFeature.drawLineString = jest.fn(); - mVTFeature.drawPolygon = jest.fn(); - const mockTile = 'foo'; jest.clearAllMocks(); - mVTFeature.defaultDraw(mockTileContext, mockTile, mockStyle); + mVTFeature.draw(mockTileContext); - expect(mVTFeature[delegatee]).toHaveBeenCalledWith(mockTileContext, mockTile, mockStyle); + expect(delegatee).toHaveBeenCalledWith(mockTileContext, mVTFeature.tiles[mockTileContext.id], mockStyle); }); }); describe('drawPoint', () => { it('calls the 2D canvas context functions as expected', () => { - new MVTFeature(mockOptions()) - .drawPoint(mockTileContext, mockTile, mockStyle); + drawPoint(mockTileContext, mockTile, mockStyle); expect(mockCanvas.getContext).toHaveBeenCalledWith('2d'); expect(mockContext().beginPath).toHaveBeenCalled(); @@ -242,8 +238,7 @@ describe('MVTFeature', () => { expect(mockContext().arc).toHaveBeenCalledWith(0.0625, 0.125, mockStyle.radius, 0, Math.PI * 2); }); it('calls the 2D canvas context with a radius of 3 by default', () => { - new MVTFeature(mockOptions()) - .drawPoint(mockTileContext, mockTile, {...mockStyle, radius: undefined}); + drawPoint(mockTileContext, mockTile, {...mockStyle, radius: undefined}); expect(mockContext().arc).toHaveBeenCalledWith( expect.anything(), expect.anything(), 3, expect.anything(), expect.anything(), @@ -251,36 +246,25 @@ describe('MVTFeature', () => { }); }); describe('drawLineString', () => { - let mVTFeature; beforeEach(() => { - mVTFeature = new MVTFeature(mockOptions()); - mVTFeature.drawCoordinates = jest.fn(); jest.clearAllMocks(); - mVTFeature.drawLineString(mockTileContext, mockTile, mockStyle); - }); - it('calls this.drawCoordinates with expected arguments', () => { - expect(mVTFeature.drawCoordinates).toHaveBeenCalledWith(mockTileContext, mockTile); + drawLineString(mockTileContext, mockTile, mockStyle); }); it('calls the 2D canvas context functions as expected', () => { expect(mockCanvas.getContext).toHaveBeenCalledWith('2d'); + mockTile.vectorTileFeature.loadGeometry().forEach((path, i) => { + expect(mockTile.paths2d.addPath).toHaveBeenNthCalledWith(i + 1, expect.any(Path2D)); + }); expect(mockContext().stroke).toHaveBeenCalledWith(mockTile.paths2d); }); }); describe('drawPolygon', () => { - let mVTFeature; beforeEach(() => { - mVTFeature = new MVTFeature(mockOptions()); - mVTFeature.drawCoordinates = jest.fn(); jest.clearAllMocks(); }); - it('calls this.drawCoordinates with expected arguments', () => { - mVTFeature.drawPolygon(mockTileContext, mockTile, mockStyle); - - expect(mVTFeature.drawCoordinates).toHaveBeenCalledWith(mockTileContext, mockTile); - }); it('calls closePath on the tile\'s paths2d', () => { - mVTFeature.drawPolygon(mockTileContext, mockTile, mockStyle); + drawPolygon(mockTileContext, mockTile, mockStyle); expect(mockTile.paths2d.closePath).toHaveBeenCalled(); }); @@ -289,25 +273,23 @@ describe('MVTFeature', () => { {fnName: 'stroke', propName: 'strokeStyle'}, ]; it.each(testConditions)('calls $fnName if style.$propName is true', ({fnName, propName}) => { - mVTFeature.drawPolygon(mockTileContext, mockTile, {...mockStyle, [propName]: true}); + drawPolygon(mockTileContext, mockTile, {...mockStyle, [propName]: true}); expect(mockContext()[fnName]).toHaveBeenCalledWith(mockTile.paths2d); }); it.each(testConditions)('doesn\'t call $fnName if style.$propName is false', ({fnName, propName}) => { - mVTFeature.drawPolygon(mockTileContext, mockTile, {...mockStyle, [propName]: false}); + drawPolygon(mockTileContext, mockTile, {...mockStyle, [propName]: false}); expect(mockContext()[fnName]).not.toHaveBeenCalled(); }); }); - describe('drawCoordinates', () => { + describe('drawGeometry', () => { let tileCopy; beforeEach(() => { - // Necessary because drawCoordinates mutates the tile. + // Necessary because drawGeometry mutates the tile. tileCopy = {...mockTile}; - const mVTFeature = new MVTFeature(mockOptions()); jest.clearAllMocks(); - - mVTFeature.drawCoordinates(mockTileContext, tileCopy); + drawGeometry(mockTileContext, tileCopy); }); it('calls Path2D.moveTo with the point from first coordinates of each set', () => { expect(mockMoveTo).toHaveBeenNthCalledWith(1, 0.0625, 0.125); @@ -323,57 +305,54 @@ describe('MVTFeature', () => { it('calls Path2D.addPath with the created Path2D', () => { expect(mockAddPath).toHaveBeenCalledWith(expect.any(Path2D)); }); - it('replaces the tile\'s Path2D with a new one', () => { - expect(mockTile.paths2d).not.toBe(tileCopy.paths2d); - }); }); describe('getPaths', () => { it('returns expected array', () => { const result = new MVTFeature(mockOptions()).getPaths(mockTileContext); expect(result).toStrictEqual([ - [ - {x: 0.0625, y: 0.125}, {x: 0.125, y: 0.0625}, - ], - [ - {x: -0.125, y: 0.1875}, {x: 0, y: 0.1875}, {x: 0.1875, y: 0.1875}, - ], + expect.arrayContaining([ + expect.objectContaining({x: 0.0625, y: 0.125}), + expect.objectContaining({x: 0.125, y: 0.0625}), + ]), + expect.arrayContaining([ + expect.objectContaining({x: -0.125, y: 0.1875}), + expect.objectContaining({x: 0, y: 0.1875}), + expect.objectContaining({x: 0.1875, y: 0.1875}), + ]), ]); }); }); describe('getContext2d', () => { it('retrieves the 2D context from the canvas', () => { - const mVTFeature = new MVTFeature(mockOptions()); - - mVTFeature.getContext2d(mockCanvas, mockStyle); + getContext2d(mockCanvas, mockStyle); expect(mockCanvas.getContext).toHaveBeenCalledWith('2d'); }); it('returns an object with expected properties copied from style', () => { - const mVTFeature = new MVTFeature(mockOptions()); const testStyleProps = {fooProp: 'foo', barProp: 'bar'}; - const result = mVTFeature.getContext2d(mockCanvas, {...mockStyle, ...testStyleProps}); + const result = getContext2d(mockCanvas, {...mockStyle, ...testStyleProps}); expect(result).toStrictEqual(expect.objectContaining(testStyleProps)); }); it('does not copy `selected` from style to return value', () => { - const mVTFeature = new MVTFeature(mockOptions()); - - const result = mVTFeature.getContext2d(mockCanvas, {...mockStyle, selected: 'baz'}); + const result = getContext2d(mockCanvas, {...mockStyle, selected: 'baz'}); expect(result.selected).not.toBe('baz'); }); }); describe('getPoint', () => { it('returns expected value', () => { const testCoords = {x: 97, y: 15}; - const result = new MVTFeature(mockOptions()).getPoint( + const result = getPoint( testCoords, - {...mockTileContext, id: 2, parentId: 1}, - 4, + {...mockTileContext, id: '2:0:0', parentId: '1:0:0'}, + 2, ); - expect(result).toStrictEqual({x: 93, y: 7}); + expect(result).toBeInstanceOf(Point); + expect(result.x).toBe(97); + expect(result.y).toBe(15); }); }); }); diff --git a/tests/MVTLayer.spec.js b/tests/MVTLayer.spec.js index 726337d..65bdc20 100644 --- a/tests/MVTLayer.spec.js +++ b/tests/MVTLayer.spec.js @@ -1,19 +1,33 @@ -import {MVTLayer} from '@/MVTLayer.js'; +import {jest} from '@jest/globals'; +// import {MVTLayer} from '@/MVTLayer.js'; import {MVTFeature} from '@/MVTFeature.js'; -import {mockMVTSource, mockTileContext, mockVectorTileFeatures} from './common-mocks.js'; +import {mockMVTSource, mockTileContext, mockVectorTileLayers} from './common-mocks.js'; -// TODO jest.mock does not seem to work at all like it does in Beyond Maps and I have -// no idea why. The MVTFeature class does _not_ get mocked by this line. -jest.mock('@/MVTFeature.js'); - -const mockStyle = jest.fn(() => 'style return'); +const mockStyle = {mock: 'style'}; const mockDrawFn = jest.fn(); +jest.unstable_mockModule('@/MVTFeature.js', () => { + return { + MVTFeature: jest.fn().mockImplementation((options) => { + return new MVTFeature(options); + }), + }; +}); +const {MVTFeature: mockMVTFeature} = await import('@/MVTFeature.js'); +const {MVTLayer} = await import('@/MVTLayer.js'); + +class Path2D { + constructor() {} +} +global.Path2D = Path2D; + +const mockStyleFn = jest.fn(() => mockStyle); + const mockOptions = () =>{ let nextId = 123; return { getIDForLayerFeature: jest.fn(() => nextId++), - style: mockStyle, + style: mockStyleFn, name: 'Mock Name', filter: jest.fn(() => true), customDraw: mockDrawFn, @@ -37,24 +51,23 @@ describe('MVTLayer', () => { describe('Constructing MVTFeature', () => { it('calls the MVTFeature constructor with expected options', () => { const mVTLayer = new MVTLayer(mockOptions()); - mVTLayer.parseVectorTileFeatures(mockMVTSource, mockVectorTileFeatures.slice(0, 1), mockTileContext); - - // TODO this expect won't work until jest.mock() works. - // expect(MVTFeature).toHaveBeenCalledWith(expect.objectContaining({ - // mVTSource: mockMVTSource, - // vectorTileFeature: mockVectorTileFeatures[0], - // tileContext: mockTileContext, - // style: mockStyle, - // selected: false, // from MVTSource.isFeatureSelected - // featureId: 123, - // customDraw: mockDrawFn, - // })); + mVTLayer.parseVectorTileFeatures(mockMVTSource, mockVectorTileLayers[0], mockTileContext); + + expect(mockMVTFeature).toHaveBeenCalledWith(expect.objectContaining({ + mVTSource: mockMVTSource, + vectorTileFeature: expect.any(Object), // mapbox VectorTileFeature + tileContext: mockTileContext, + style: mockStyle, + selected: false, // from MVTSource.isFeatureSelected + featureId: 123, + customDraw: mockDrawFn, + })); expect(mVTLayer._mVTFeatures[123]).toStrictEqual(expect.any(MVTFeature)); }); it('creates one MVTFeature per VectorTileFeature supplied', () => { const mVTLayer = new MVTLayer(mockOptions()); - mVTLayer.parseVectorTileFeatures(mockMVTSource, mockVectorTileFeatures, mockTileContext); + mVTLayer.parseVectorTileFeatures(mockMVTSource, mockVectorTileLayers[1], mockTileContext); expect(mVTLayer._mVTFeatures[123]).toStrictEqual(expect.any(MVTFeature)); expect(mVTLayer._mVTFeatures[124]).toStrictEqual(expect.any(MVTFeature)); @@ -62,7 +75,7 @@ describe('MVTLayer', () => { }); it('if the getIDForLayerFeature function returns nothing, autoincrements MVTFeature IDs', () => { const mVTLayer = new MVTLayer({...mockOptions(), getIDForLayerFeature: jest.fn()}); - mVTLayer.parseVectorTileFeatures(mockMVTSource, mockVectorTileFeatures, mockTileContext); + mVTLayer.parseVectorTileFeatures(mockMVTSource, mockVectorTileLayers[1], mockTileContext); expect(mVTLayer._mVTFeatures[0]).toStrictEqual(expect.any(MVTFeature)); expect(mVTLayer._mVTFeatures[1]).toStrictEqual(expect.any(MVTFeature)); @@ -70,7 +83,7 @@ describe('MVTLayer', () => { }); it('does not add a MVTFeature if filter returns false', () => { const mVTLayer = new MVTLayer({...mockOptions(), filter: jest.fn(() => false)}); - mVTLayer.parseVectorTileFeatures(mockMVTSource, mockVectorTileFeatures, mockTileContext); + mVTLayer.parseVectorTileFeatures(mockMVTSource, mockVectorTileLayers[1], mockTileContext); expect(mVTLayer._mVTFeatures).toHaveLength(0); }); @@ -78,7 +91,7 @@ describe('MVTLayer', () => { const mVTLayer = new MVTLayer(mockOptions()); mVTLayer.drawTile = jest.fn(); - mVTLayer.parseVectorTileFeatures(mockMVTSource, mockVectorTileFeatures, mockTileContext); + mVTLayer.parseVectorTileFeatures(mockMVTSource, mockVectorTileLayers[0], mockTileContext); expect(mVTLayer.drawTile).toHaveBeenCalledWith(mockTileContext); }); @@ -88,7 +101,7 @@ describe('MVTLayer', () => { let features; beforeEach(() => { mVTLayer = new MVTLayer(mockOptions()); - mVTLayer.parseVectorTileFeatures(mockMVTSource, mockVectorTileFeatures, mockTileContext); + mVTLayer.parseVectorTileFeatures(mockMVTSource, mockVectorTileLayers[1], mockTileContext); features = mVTLayer._mVTFeatures; features.forEach((f) => f.draw = jest.fn()); jest.clearAllMocks(); @@ -124,13 +137,13 @@ describe('MVTLayer', () => { const mockFeature = {}; const result = new MVTLayer(mockOptions()).getStyle(mockFeature); - expect(mockStyle).toHaveBeenCalledWith(mockFeature); - expect(result).toBe('style return'); + expect(mockStyleFn).toHaveBeenCalledWith(mockFeature); + expect(result).toBe(mockStyle); }); it('if MVTLayer\'s style is not a function, return it', () => { const result = new MVTLayer({...mockOptions(), style: 'not a function'}).getStyle({}); - expect(mockStyle).not.toHaveBeenCalled(); + expect(mockStyleFn).not.toHaveBeenCalled(); expect(result).toBe('not a function'); }); }); @@ -138,19 +151,17 @@ describe('MVTLayer', () => { let mVTLayer; beforeEach(() => { mVTLayer = new MVTLayer(mockOptions()); - mVTLayer.parseVectorTileFeatures(mockMVTSource, mockVectorTileFeatures, mockTileContext); + mVTLayer.parseVectorTileFeatures(mockMVTSource, mockVectorTileLayers[0], mockTileContext); }); it('sets the MVTLayer\'s style property', () => { mVTLayer.setStyle('new style'); expect(mVTLayer.style).toBe('new style'); }); - it('calls setStyle on each feature', () => { - mVTLayer._mVTFeatures.forEach((f) => f.setStyle = jest.fn()); - + it('sets the style on each feature', () => { mVTLayer.setStyle('new style'); - mVTLayer._mVTFeatures.forEach(({setStyle}) => expect(setStyle).toHaveBeenCalledWith('new style')); + mVTLayer._mVTFeatures.forEach(({style}) => expect(style).toBe('new style')); }); }); }); diff --git a/tests/MVTSource.spec.js b/tests/MVTSource.spec.js index 4aa7341..f6b6c7a 100644 --- a/tests/MVTSource.spec.js +++ b/tests/MVTSource.spec.js @@ -1,18 +1,9 @@ import {MVTSource} from '@/MVTSource'; import {mockMap, mockCanvas, mockContext} from './common-mocks'; +import {initialize, Size} from '@googlemaps/jest-mocks'; +import {getTileFromString, getTileString} from '../lib/geometry'; -// TODO various functions access 'google' as a global. Refactor to use imports instead. -class Size { - constructor(size1, size2) { - this.size1 = size1; - this.size2 = size2; - } -} -global.google = { - maps: { - Size, - }, -}; +initialize(); const mockMVTFeature = { featureId: 8, @@ -56,8 +47,8 @@ describe('MVTSource', () => { expect(mVTSource.getIDForLayerFeature).toBe(options.getIDForLayerFeature); expect(mVTSource.tileSize).toStrictEqual(expect.any(Size)); - expect(mVTSource.tileSize.size1).toBe(options.tileSize); - expect(mVTSource.tileSize.size2).toBe(options.tileSize); + expect(mVTSource.tileSize.width).toBe(options.tileSize); + expect(mVTSource.tileSize.height).toBe(options.tileSize); }); // TODO something for setSelectedFeatures it('registers a zoom_changed listener on the map', () => { @@ -67,25 +58,21 @@ describe('MVTSource', () => { expect(map.addListener).toHaveBeenCalledWith('zoom_changed', expect.any(Function)); }); }); - describe('getTileId', () => { + describe('getTileString', () => { it('returns expected id', () => { const zoom = 10; const x = 18; const y = 28; - const mVTSource = new MVTSource(mockMap(), mockOptions()); - - expect(mVTSource.getTileId(zoom, x, y)).toBe('10:18:28'); + expect(getTileString(zoom, x, y)).toBe('10:18:28'); }); }); - describe('getTileObject', () => { + describe('getTileFromString', () => { it('returns expected object', () => { const id = '8:55:143'; - const mVTSource = new MVTSource(mockMap(), mockOptions()); - - expect(mVTSource.getTileObject(id)).toStrictEqual({ - zoom: '8', - x: '55', - y: '143', + expect(getTileFromString(id)).toStrictEqual({ + zoom: 8, + x: 55, + y: 143, }); }); }); diff --git a/tests/common-mocks.js b/tests/common-mocks.js index 544e53b..a5a35a5 100644 --- a/tests/common-mocks.js +++ b/tests/common-mocks.js @@ -37,30 +37,53 @@ export const mockMVTSource = { redrawTile: jest.fn(), map: mockMap(), }; +/** + * @typedef {import('@mapbox/vector-tile').VectorTileLayer} VectorTileLayer + * @typedef {import('@mapbox/vector-tile').VectorTileFeature} VectorTileFeature + */ -export const mockVectorTileFeatures = [ +/** @type {VectorTileFeature} */ +const mockVectorTileFeature1 = { + type: 1, + extent: 64, + properties: 'mock vector tile props', + loadGeometry: jest.fn(() => [ + [ + {x: 1, y: 2}, {x: 2, y: 1}, + ], + [ + {x: -2, y: 3}, {x: 0, y: 3}, {x: 3, y: 3}, + ], + ]), +}; + +/** @type {VectorTileFeature} */ +const mockVectorTileFeature2 = { + type: 2, + extent: 32, + properties: 'mock props', + loadGeometry: jest.fn(() => [ + [ + {x: 0, y: 0}, {x: 3, y: 1}, {x: 5, y: -2}, + ], + ]), +}; + +/** @type {Array { + return mockVectorTileFeature1; + }), }, { extent: 32, - type: 2, - properties: 'mock props', - coordinates: [ - [{x: 0, y: 0}, {x: 3, y: 1}, {x: 5, y: -2}], - ], + length: 2, + feature: jest.fn((i) => { + return mockVectorTileFeature2; + }), }, ]; diff --git a/vector-tiles-google-maps/.gitignore b/vector-tiles-google-maps/.gitignore deleted file mode 100644 index a547bf3..0000000 --- a/vector-tiles-google-maps/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -pnpm-debug.log* -lerna-debug.log* - -node_modules -dist -dist-ssr -*.local - -# Editor directories and files -.vscode/* -!.vscode/extensions.json -.idea -.DS_Store -*.suo -*.ntvs* -*.njsproj -*.sln -*.sw? diff --git a/vector-tiles-google-maps/index.html b/vector-tiles-google-maps/index.html deleted file mode 100644 index c6b5c90..0000000 --- a/vector-tiles-google-maps/index.html +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/vector-tiles-google-maps/main.js b/vector-tiles-google-maps/main.js deleted file mode 100644 index 567f2db..0000000 --- a/vector-tiles-google-maps/main.js +++ /dev/null @@ -1,3 +0,0 @@ -import {MVTSource} from '../src/MVTSource.js'; - -window.MVTSource = MVTSource; \ No newline at end of file diff --git a/vector-tiles-google-maps/package-lock.json b/vector-tiles-google-maps/package-lock.json deleted file mode 100644 index 1578c18..0000000 --- a/vector-tiles-google-maps/package-lock.json +++ /dev/null @@ -1,890 +0,0 @@ -{ - "name": "vector-tiles-google-maps", - "version": "0.0.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "vector-tiles-google-maps", - "version": "0.0.0", - "devDependencies": { - "vite": "^4.1.0" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.16.17.tgz", - "integrity": "sha512-N9x1CMXVhtWEAMS7pNNONyA14f71VPQN9Cnavj1XQh6T7bskqiLLrSca4O0Vr8Wdcga943eThxnVp3JLnBMYtw==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.16.17.tgz", - "integrity": "sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.16.17.tgz", - "integrity": "sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.16.17.tgz", - "integrity": "sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.16.17.tgz", - "integrity": "sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.16.17.tgz", - "integrity": "sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.16.17.tgz", - "integrity": "sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.16.17.tgz", - "integrity": "sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.16.17.tgz", - "integrity": "sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.16.17.tgz", - "integrity": "sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.16.17.tgz", - "integrity": "sha512-dTzNnQwembNDhd654cA4QhbS9uDdXC3TKqMJjgOWsC0yNCbpzfWoXdZvp0mY7HU6nzk5E0zpRGGx3qoQg8T2DQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.16.17.tgz", - "integrity": "sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.16.17.tgz", - "integrity": "sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.16.17.tgz", - "integrity": "sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.16.17.tgz", - "integrity": "sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.16.17.tgz", - "integrity": "sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.16.17.tgz", - "integrity": "sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.16.17.tgz", - "integrity": "sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.16.17.tgz", - "integrity": "sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.16.17.tgz", - "integrity": "sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.16.17.tgz", - "integrity": "sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.16.17.tgz", - "integrity": "sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/esbuild": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.16.17.tgz", - "integrity": "sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/android-arm": "0.16.17", - "@esbuild/android-arm64": "0.16.17", - "@esbuild/android-x64": "0.16.17", - "@esbuild/darwin-arm64": "0.16.17", - "@esbuild/darwin-x64": "0.16.17", - "@esbuild/freebsd-arm64": "0.16.17", - "@esbuild/freebsd-x64": "0.16.17", - "@esbuild/linux-arm": "0.16.17", - "@esbuild/linux-arm64": "0.16.17", - "@esbuild/linux-ia32": "0.16.17", - "@esbuild/linux-loong64": "0.16.17", - "@esbuild/linux-mips64el": "0.16.17", - "@esbuild/linux-ppc64": "0.16.17", - "@esbuild/linux-riscv64": "0.16.17", - "@esbuild/linux-s390x": "0.16.17", - "@esbuild/linux-x64": "0.16.17", - "@esbuild/netbsd-x64": "0.16.17", - "@esbuild/openbsd-x64": "0.16.17", - "@esbuild/sunos-x64": "0.16.17", - "@esbuild/win32-arm64": "0.16.17", - "@esbuild/win32-ia32": "0.16.17", - "@esbuild/win32-x64": "0.16.17" - } - }, - "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/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", - "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "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/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "node_modules/postcss": { - "version": "8.4.21", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", - "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - } - ], - "dependencies": { - "nanoid": "^3.3.4", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dev": true, - "dependencies": { - "is-core-module": "^2.9.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/rollup": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.14.0.tgz", - "integrity": "sha512-o23sdgCLcLSe3zIplT9nQ1+r97okuaiR+vmAPZPTDYB7/f3tgWIYNyiQveMsZwshBT0is4eGax/HH83Q7CG+/Q==", - "dev": true, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=14.18.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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/vite": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.1.1.tgz", - "integrity": "sha512-LM9WWea8vsxhr782r9ntg+bhSFS06FJgCvvB0+8hf8UWtvaiDagKYWXndjfX6kGl74keHJUcpzrQliDXZlF5yg==", - "dev": true, - "dependencies": { - "esbuild": "^0.16.14", - "postcss": "^8.4.21", - "resolve": "^1.22.1", - "rollup": "^3.10.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - }, - "peerDependencies": { - "@types/node": ">= 14", - "less": "*", - "sass": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "sass": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - } - }, - "dependencies": { - "@esbuild/android-arm": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.16.17.tgz", - "integrity": "sha512-N9x1CMXVhtWEAMS7pNNONyA14f71VPQN9Cnavj1XQh6T7bskqiLLrSca4O0Vr8Wdcga943eThxnVp3JLnBMYtw==", - "dev": true, - "optional": true - }, - "@esbuild/android-arm64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.16.17.tgz", - "integrity": "sha512-MIGl6p5sc3RDTLLkYL1MyL8BMRN4tLMRCn+yRJJmEDvYZ2M7tmAf80hx1kbNEUX2KJ50RRtxZ4JHLvCfuB6kBg==", - "dev": true, - "optional": true - }, - "@esbuild/android-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.16.17.tgz", - "integrity": "sha512-a3kTv3m0Ghh4z1DaFEuEDfz3OLONKuFvI4Xqczqx4BqLyuFaFkuaG4j2MtA6fuWEFeC5x9IvqnX7drmRq/fyAQ==", - "dev": true, - "optional": true - }, - "@esbuild/darwin-arm64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.16.17.tgz", - "integrity": "sha512-/2agbUEfmxWHi9ARTX6OQ/KgXnOWfsNlTeLcoV7HSuSTv63E4DqtAc+2XqGw1KHxKMHGZgbVCZge7HXWX9Vn+w==", - "dev": true, - "optional": true - }, - "@esbuild/darwin-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.16.17.tgz", - "integrity": "sha512-2By45OBHulkd9Svy5IOCZt376Aa2oOkiE9QWUK9fe6Tb+WDr8hXL3dpqi+DeLiMed8tVXspzsTAvd0jUl96wmg==", - "dev": true, - "optional": true - }, - "@esbuild/freebsd-arm64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.16.17.tgz", - "integrity": "sha512-mt+cxZe1tVx489VTb4mBAOo2aKSnJ33L9fr25JXpqQqzbUIw/yzIzi+NHwAXK2qYV1lEFp4OoVeThGjUbmWmdw==", - "dev": true, - "optional": true - }, - "@esbuild/freebsd-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.16.17.tgz", - "integrity": "sha512-8ScTdNJl5idAKjH8zGAsN7RuWcyHG3BAvMNpKOBaqqR7EbUhhVHOqXRdL7oZvz8WNHL2pr5+eIT5c65kA6NHug==", - "dev": true, - "optional": true - }, - "@esbuild/linux-arm": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.16.17.tgz", - "integrity": "sha512-iihzrWbD4gIT7j3caMzKb/RsFFHCwqqbrbH9SqUSRrdXkXaygSZCZg1FybsZz57Ju7N/SHEgPyaR0LZ8Zbe9gQ==", - "dev": true, - "optional": true - }, - "@esbuild/linux-arm64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.16.17.tgz", - "integrity": "sha512-7S8gJnSlqKGVJunnMCrXHU9Q8Q/tQIxk/xL8BqAP64wchPCTzuM6W3Ra8cIa1HIflAvDnNOt2jaL17vaW+1V0g==", - "dev": true, - "optional": true - }, - "@esbuild/linux-ia32": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.16.17.tgz", - "integrity": "sha512-kiX69+wcPAdgl3Lonh1VI7MBr16nktEvOfViszBSxygRQqSpzv7BffMKRPMFwzeJGPxcio0pdD3kYQGpqQ2SSg==", - "dev": true, - "optional": true - }, - "@esbuild/linux-loong64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.16.17.tgz", - "integrity": "sha512-dTzNnQwembNDhd654cA4QhbS9uDdXC3TKqMJjgOWsC0yNCbpzfWoXdZvp0mY7HU6nzk5E0zpRGGx3qoQg8T2DQ==", - "dev": true, - "optional": true - }, - "@esbuild/linux-mips64el": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.16.17.tgz", - "integrity": "sha512-ezbDkp2nDl0PfIUn0CsQ30kxfcLTlcx4Foz2kYv8qdC6ia2oX5Q3E/8m6lq84Dj/6b0FrkgD582fJMIfHhJfSw==", - "dev": true, - "optional": true - }, - "@esbuild/linux-ppc64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.16.17.tgz", - "integrity": "sha512-dzS678gYD1lJsW73zrFhDApLVdM3cUF2MvAa1D8K8KtcSKdLBPP4zZSLy6LFZ0jYqQdQ29bjAHJDgz0rVbLB3g==", - "dev": true, - "optional": true - }, - "@esbuild/linux-riscv64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.16.17.tgz", - "integrity": "sha512-ylNlVsxuFjZK8DQtNUwiMskh6nT0vI7kYl/4fZgV1llP5d6+HIeL/vmmm3jpuoo8+NuXjQVZxmKuhDApK0/cKw==", - "dev": true, - "optional": true - }, - "@esbuild/linux-s390x": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.16.17.tgz", - "integrity": "sha512-gzy7nUTO4UA4oZ2wAMXPNBGTzZFP7mss3aKR2hH+/4UUkCOyqmjXiKpzGrY2TlEUhbbejzXVKKGazYcQTZWA/w==", - "dev": true, - "optional": true - }, - "@esbuild/linux-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.16.17.tgz", - "integrity": "sha512-mdPjPxfnmoqhgpiEArqi4egmBAMYvaObgn4poorpUaqmvzzbvqbowRllQ+ZgzGVMGKaPkqUmPDOOFQRUFDmeUw==", - "dev": true, - "optional": true - }, - "@esbuild/netbsd-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.16.17.tgz", - "integrity": "sha512-/PzmzD/zyAeTUsduZa32bn0ORug+Jd1EGGAUJvqfeixoEISYpGnAezN6lnJoskauoai0Jrs+XSyvDhppCPoKOA==", - "dev": true, - "optional": true - }, - "@esbuild/openbsd-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.16.17.tgz", - "integrity": "sha512-2yaWJhvxGEz2RiftSk0UObqJa/b+rIAjnODJgv2GbGGpRwAfpgzyrg1WLK8rqA24mfZa9GvpjLcBBg8JHkoodg==", - "dev": true, - "optional": true - }, - "@esbuild/sunos-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.16.17.tgz", - "integrity": "sha512-xtVUiev38tN0R3g8VhRfN7Zl42YCJvyBhRKw1RJjwE1d2emWTVToPLNEQj/5Qxc6lVFATDiy6LjVHYhIPrLxzw==", - "dev": true, - "optional": true - }, - "@esbuild/win32-arm64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.16.17.tgz", - "integrity": "sha512-ga8+JqBDHY4b6fQAmOgtJJue36scANy4l/rL97W+0wYmijhxKetzZdKOJI7olaBaMhWt8Pac2McJdZLxXWUEQw==", - "dev": true, - "optional": true - }, - "@esbuild/win32-ia32": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.16.17.tgz", - "integrity": "sha512-WnsKaf46uSSF/sZhwnqE4L/F89AYNMiD4YtEcYekBt9Q7nj0DiId2XH2Ng2PHM54qi5oPrQ8luuzGszqi/veig==", - "dev": true, - "optional": true - }, - "@esbuild/win32-x64": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.16.17.tgz", - "integrity": "sha512-y+EHuSchhL7FjHgvQL/0fnnFmO4T1bhvWANX6gcnqTjtnKWbTvUMCpGnv2+t+31d7RzyEAYAd4u2fnIhHL6N/Q==", - "dev": true, - "optional": true - }, - "esbuild": { - "version": "0.16.17", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.16.17.tgz", - "integrity": "sha512-G8LEkV0XzDMNwXKgM0Jwu3nY3lSTwSGY6XbxM9cr9+s0T/qSV1q1JVPBGzm3dcjhCic9+emZDmMffkwgPeOeLg==", - "dev": true, - "requires": { - "@esbuild/android-arm": "0.16.17", - "@esbuild/android-arm64": "0.16.17", - "@esbuild/android-x64": "0.16.17", - "@esbuild/darwin-arm64": "0.16.17", - "@esbuild/darwin-x64": "0.16.17", - "@esbuild/freebsd-arm64": "0.16.17", - "@esbuild/freebsd-x64": "0.16.17", - "@esbuild/linux-arm": "0.16.17", - "@esbuild/linux-arm64": "0.16.17", - "@esbuild/linux-ia32": "0.16.17", - "@esbuild/linux-loong64": "0.16.17", - "@esbuild/linux-mips64el": "0.16.17", - "@esbuild/linux-ppc64": "0.16.17", - "@esbuild/linux-riscv64": "0.16.17", - "@esbuild/linux-s390x": "0.16.17", - "@esbuild/linux-x64": "0.16.17", - "@esbuild/netbsd-x64": "0.16.17", - "@esbuild/openbsd-x64": "0.16.17", - "@esbuild/sunos-x64": "0.16.17", - "@esbuild/win32-arm64": "0.16.17", - "@esbuild/win32-ia32": "0.16.17", - "@esbuild/win32-x64": "0.16.17" - } - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", - "dev": true - }, - "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 - }, - "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "postcss": { - "version": "8.4.21", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", - "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", - "dev": true, - "requires": { - "nanoid": "^3.3.4", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - } - }, - "resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dev": true, - "requires": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "rollup": { - "version": "3.14.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.14.0.tgz", - "integrity": "sha512-o23sdgCLcLSe3zIplT9nQ1+r97okuaiR+vmAPZPTDYB7/f3tgWIYNyiQveMsZwshBT0is4eGax/HH83Q7CG+/Q==", - "dev": true, - "requires": { - "fsevents": "~2.3.2" - } - }, - "source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", - "dev": true - }, - "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 - }, - "vite": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.1.1.tgz", - "integrity": "sha512-LM9WWea8vsxhr782r9ntg+bhSFS06FJgCvvB0+8hf8UWtvaiDagKYWXndjfX6kGl74keHJUcpzrQliDXZlF5yg==", - "dev": true, - "requires": { - "esbuild": "^0.16.14", - "fsevents": "~2.3.2", - "postcss": "^8.4.21", - "resolve": "^1.22.1", - "rollup": "^3.10.0" - } - } - } -} diff --git a/vector-tiles-google-maps/package.json b/vector-tiles-google-maps/package.json deleted file mode 100644 index 3f328f2..0000000 --- a/vector-tiles-google-maps/package.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "vector-tiles-google-maps", - "private": true, - "version": "0.0.0", - "scripts": { - "dev": "vite", - "build": "vite build", - "preview": "vite preview" - }, - "devDependencies": { - "vite": "^4.1.0" - } -} \ No newline at end of file diff --git a/vector-tiles-google-maps/vite.config.js b/vite.config.js similarity index 52% rename from vector-tiles-google-maps/vite.config.js rename to vite.config.js index 23f7249..d49ccaf 100644 --- a/vector-tiles-google-maps/vite.config.js +++ b/vite.config.js @@ -1,4 +1,4 @@ -import { defineConfig } from "vite" +import {defineConfig} from 'vite'; export default defineConfig({ build: { @@ -6,8 +6,9 @@ export default defineConfig({ output: { entryFileNames: `assets/[name].js`, chunkFileNames: `assets/[name].js`, - assetFileNames: `assets/[name].[ext]` - } - } - } -}) \ No newline at end of file + assetFileNames: `assets/[name].[ext]`, + sourcemapBaseUrl: `http://localhost`, + }, + }, + }, +}); From 2c761c2f8148eb09b71501c24ac789903f206587 Mon Sep 17 00:00:00 2001 From: Brian Roden <32974706+Bobbyjuba@users.noreply.github.com> Date: Thu, 16 Feb 2023 14:17:38 -0600 Subject: [PATCH 07/11] BMAPS-1691 Converted Mercator.js to ES6 and added JSDocs documentation (#7) * Converted Mercator.js to ES6; added JSDocs documentation * Added GitHub PR template * Adjusted wording from numeric to literal to be more clear * Code review feedback --- .github/PULL_REQUEST_TEMPLATE.md | 28 ++++ lib/geometry.js | 8 +- lib/mercator.js | 256 +++++++++++++++++++++++++++++++ lib/mercator/Mercator.js | 152 ------------------ src/MVTLayer.js | 6 +- src/MVTSource.js | 6 +- tests/Mercator.spec.js | 2 +- 7 files changed, 298 insertions(+), 160 deletions(-) create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 lib/mercator.js delete mode 100644 lib/mercator/Mercator.js diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..c4ae61a --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,28 @@ +## Issue Link + +[[project acronym]-XXX](https://northpoint-development.atlassian.net/browse/[project acronym]-XXX) + +## Description + + +## Tests + + +## Screenshots + + +## Checklist + +ALWAYS +- [ ] My pull request title matches the following format: [project acronym]-### - [concise title] + (Ex. 'BMAPS-123 Updated Pull Request Template') +- [ ] I added/updated tests for the changes I made. (Or I have explained why I have not) +- [ ] I have run `npm audit fix` (Maybe multiple times) until all vulnerabilities that can be automatically fixed are fixed. If there are vulnerabilties that will need to be fixed manually, I have created a ticket to do so. + +ALMOST ALWAYS +- [ ] I added or updated documentation/README + +SOMETIMES +- [ ] (If this PR ends in a 0) I have scheduled a team code review + +[best_practices]:https://gist.github.com/robertpainsi/b632364184e70900af4ab688decf6f53 \ No newline at end of file diff --git a/lib/geometry.js b/lib/geometry.js index 5a40009..a64610c 100644 --- a/lib/geometry.js +++ b/lib/geometry.js @@ -1,3 +1,9 @@ +/** + * @typedef {Object} TileLocation + * @property {Number} x + * @property {Number} y + * @property {Number} z + */ /** * @param {number} zoom @@ -9,7 +15,7 @@ const getTileString = (zoom, x, y) => [zoom, x, y].join(':'); /** * @param {string} id Tile id in format 'zoom:x:y' - * @return {{zoom: number, x: number, y: number}} + * @return {TileLocation} */ const getTileFromString = (id) => { try { diff --git a/lib/mercator.js b/lib/mercator.js new file mode 100644 index 0000000..7f25f24 --- /dev/null +++ b/lib/mercator.js @@ -0,0 +1,256 @@ +/** + * @typedef {Object} TileLocation + * @property {Number} x + * @property {Number} y + * @property {Number} z + */ + +/** + * @typedef {Object} TileBounds + * @property {google.maps.LatLngLiteral} sw + * @property {google.maps.LatLngLiteral} ne + */ + +/** + * Convert a `LatLng` Google Maps object to a `Point` object. + * @param {google.maps.LatLng} latLng + * @return {google.maps.Point} + */ +const fromLatLngToPoint = (latLng) => { + const siny = Math.min(Math.max(Math.sin(latLng.lat() * (Math.PI / 180)), -.9999), .9999); + + return { + x: 128 + latLng.lng() * (256 / 360), + y: 128 + 0.5 * Math.log((1 + siny) / (1 - siny)) * -(256 / (2 * Math.PI)), + }; +}; + +/** + * Converts a `Point` object to a `LatLng` literal object. + * @param {google.maps.Point} point + * @return {google.maps.LatLngLiteral} + */ +const fromPointToLatLng = (point) => { + const lat = (2 * Math.atan(Math.exp((point.y - 128) / -(256 / (2 * Math.PI)))) - Math.PI / 2) / (Math.PI / 180); + const lng = (point.x - 128) / (256 / 360); + + return { + lat: lat, + lng: lng, + }; +}; + +/** + * Returns a `TileLocation` object given a `LatLng` Google Maps object and a specified `zoom`. + * @param {google.maps.LatLng} latLng + * @param {Number} zoom + * @return {TileLocation} + */ +const getTileAtLatLng = (latLng, zoom) => { + const t = Math.pow(2, zoom); + const s = 256 / t; + const p = fromLatLngToPoint(latLng); + + return { + x: Math.floor(p.x / s), + y: Math.floor(p.y / s), + z: zoom, + }; +}; + +/** + * Returns a `TileBounds` object containing the Northeast and Southwest edges of a `TileLocation`. + * @param {TileLocation} tile + * @return {TileBounds} + */ +const getTileBounds = (tile) => { + tile = normalizeTile(tile); + const t = Math.pow(2, tile.z); + const s = 256 / t; + const sw = { + x: tile.x * s, + y: (tile.y * s) + s, + }; + const ne = { + x: tile.x * s + s, + y: (tile.y * s), + }; + + return { + sw: fromPointToLatLng(sw), + ne: fromPointToLatLng(ne), + }; +}; + +/** + * Normalizes the `x` and `y` of a `TileLocation` object. + * @param {TileLocation} tile + * @return {TileLocation} + */ +const normalizeTile = (tile) => { + const t = Math.pow(2, tile.z); + tile.x = ((tile.x % t) + t) % t; + tile.y = ((tile.y % t) + t) % t; + + return tile; +}; + +/** + * Converts a `LatLng` Google Maps object from coordinates on a `map` to pixels on screen. + * @param {google.maps.Map} map + * @param {google.maps.LatLng} latLng + * @return {google.maps.Point} + */ +const fromLatLngToPixels = (map, latLng) => { + const bounds = map.getBounds(); + const ne = bounds.getNorthEast(); + const sw = bounds.getSouthWest(); + const topRight = map.getProjection().fromLatLngToPoint(ne); + const bottomLeft = map.getProjection().fromLatLngToPoint(sw); + const scale = Math.pow(2, map.getZoom()); + const worldPoint = map.getProjection().fromLatLngToPoint(latLng); + + return { + x: (worldPoint.x - bottomLeft.x) * scale, + y: (worldPoint.y - topRight.y) * scale, + }; +}; + +/** + * Converts a `LatLng` literal object, provided through `evt`, to a `Point`. + * @param {google.maps.Map} map + * @param {google.maps.MapMouseEvent} evt + * @return {google.maps.Point} + */ +const fromLatLngToTilePoint = (map, evt) => { + const zoom = map.getZoom(); + const tile = getTileAtLatLng(evt.latLng, zoom); + const tileBounds = getTileBounds(tile); + const tileSwLatLng = new google.maps.LatLng(tileBounds.sw); + const tileNeLatLng = new google.maps.LatLng(tileBounds.ne); + const tileSwPixels = fromLatLngToPixels(map, tileSwLatLng); + const tileNePixels = fromLatLngToPixels(map, tileNeLatLng); + + return { + x: evt.pixel.x - tileSwPixels.x, + y: evt.pixel.y - tileNePixels.y, + }; +}; + +/** + * Checks if a provided `point` is within a `polygon`. + * @param {google.maps.Point} point + * @param {google.maps.Point[]} polygon + * @return {Boolean} + */ +const isPointInPolygon = (point, polygon) => { + if (polygon && polygon.length) { + // Loop counters/conditionals + let c = false; + const l = polygon.length; + let j = l - 1; + + for (let i = -1; ++i < l; j = i) { + ((polygon[i].y <= point.y && point.y < polygon[j].y) || (polygon[j].y <= point.y && point.y < polygon[i].y)) && + (point.x < (polygon[j].x - polygon[i].x) * (point.y - polygon[i].y) / + (polygon[j].y - polygon[i].y) + polygon[i].x) && (c = !c); + } + + return c; + } +}; + +/** + * Checks if a given `x` and `y` are inside a circle. + * @param {Number} centerX x-coordinate for the cirlce's center + * @param {Number} centerY y-coordinate for the circle's center + * @param {Number} radius The radius of the circle + * @param {Number} x + * @param {Number} y + * @return {Boolean} + */ +const inCircle = (centerX, centerY, radius, x, y) => { + const squareDist = Math.pow((centerX - x), 2) + Math.pow((centerY - y), 2); + return squareDist <= Math.pow(radius, 2); +}; + +/** + * Returns the distance a point is from a line. + * @param {google.maps.Point} point + * @param {google.maps.Point[]} line + * @return {Number} + */ +const getDistanceFromLine = (point, line) => { + let minDistance = Number.POSITIVE_INFINITY; + + if (line && line.length > 1) { + for (let i = 0, l = line.length -1; i < l; i++) { + const distance = projectPointOnLineSegment(point, line[i], line[i + 1]); + minDistance = Math.min(distance, minDistance); + } + } + + return minDistance; +}; + +/** + * Returns the projection of a point onto a segment of a line. + * @param {google.maps.Point} point + * @param {google.maps.Point} r0 + * @param {google.maps.Point} r1 + * @return {Number} + */ +const projectPointOnLineSegment = (point, r0, r1) => { + const x = point.x; + const y = point.y; + const x1 = r0.x; + const y1 = r0.y; + const x2 = r1.x; + const y2 = r1.y; + + const A = x - x1; + const B = y - y1; + const C = x2 - x1; + const D = y2 - y1; + + const dot = A * C + B * D; + const lenSq = C * C + D * D; + let param = -1; + + if (lenSq !== 0) { + param = dot / lenSq; + } + + let xx; + let yy; + + if (param < 0) { + xx = x1; + yy = y1; + } else if (param > 1) { + xx = x2; + yy = y2; + } else { + xx = x1 + param * C; + yy = y1 + param * D; + } + + const dx = x - xx; + const dy = y - yy; + + return Math.sqrt(dx * dx + dy * dy); +}; + +export { + fromLatLngToPoint, + fromPointToLatLng, + getTileAtLatLng, + getTileBounds, + normalizeTile, + fromLatLngToPixels, + fromLatLngToTilePoint, + isPointInPolygon, + inCircle, + getDistanceFromLine, + projectPointOnLineSegment, +}; diff --git a/lib/mercator/Mercator.js b/lib/mercator/Mercator.js deleted file mode 100644 index 904e28a..0000000 --- a/lib/mercator/Mercator.js +++ /dev/null @@ -1,152 +0,0 @@ -export function fromLatLngToPoint(latLng) { - const siny = Math.min(Math.max(Math.sin(latLng.lat() * (Math.PI / 180)), - -.9999), - .9999); - return { - x: 128 + latLng.lng() * (256 / 360), - y: 128 + 0.5 * Math.log((1 + siny) / (1 - siny)) * -(256 / (2 * Math.PI)), - }; -} - -export function fromPointToLatLng(point) { - return { - lat: (2 * Math.atan(Math.exp((point.y - 128) / -(256 / (2 * Math.PI)))) - - Math.PI / 2) / (Math.PI / 180), - lng: (point.x - 128) / (256 / 360), - }; -} - -export function getTileAtLatLng(latLng, zoom) { - const t = Math.pow(2, zoom); - const s = 256 / t; - const p = fromLatLngToPoint(latLng); - return { - x: Math.floor(p.x / s), - y: Math.floor(p.y / s), - z: zoom, - }; -} - -export function getTileBounds(tile) { - tile = normalizeTile(tile); - const t = Math.pow(2, tile.z); - const s = 256 / t; - const sw = { - x: tile.x * s, - y: (tile.y * s) + s, - }; - const ne = { - x: tile.x * s + s, - y: (tile.y * s), - }; - return { - sw: fromPointToLatLng(sw), - ne: fromPointToLatLng(ne), - }; -} - -export function normalizeTile(tile) { - const t = Math.pow(2, tile.z); - tile.x = ((tile.x % t) + t) % t; - tile.y = ((tile.y % t) + t) % t; - return tile; -} - -export function fromLatLngToPixels(map, latLng) { - const bounds = map.getBounds(); - const ne = bounds.getNorthEast(); - const sw = bounds.getSouthWest(); - const topRight = map.getProjection().fromLatLngToPoint(ne); - const bottomLeft = map.getProjection().fromLatLngToPoint(sw); - const scale = Math.pow(2, map.getZoom()); - const worldPoint = map.getProjection().fromLatLngToPoint(latLng); - return { - x: (worldPoint.x - bottomLeft.x) * scale, - y: (worldPoint.y - topRight.y) * scale, - }; -} - -export function fromLatLngToTilePoint(map, evt) { - const zoom = map.getZoom(); - const tile = getTileAtLatLng(evt.latLng, zoom); - const tileBounds = getTileBounds(tile); - const tileSwLatLng = new google.maps.LatLng(tileBounds.sw); - const tileNeLatLng = new google.maps.LatLng(tileBounds.ne); - const tileSwPixels = fromLatLngToPixels(map, tileSwLatLng); - const tileNePixels = fromLatLngToPixels(map, tileNeLatLng); - return { - x: evt.pixel.x - tileSwPixels.x, - y: evt.pixel.y - tileNePixels.y, - }; -} - -// todo: sometimes it does not work properly -export function isPointInPolygon(point, polygon) { - if (polygon && polygon.length) { - // TODO refactor to use let instead of nasty var function scope to access c outside loop - for (var c = false, i = -1, l = polygon.length, j = l - 1; ++i < l; j = i) { - ((polygon[i].y <= point.y && point.y < polygon[j].y) || (polygon[j].y <= point.y && point.y < polygon[i].y)) && - (point.x < (polygon[j].x - polygon[i].x) * (point.y - polygon[i].y) / - (polygon[j].y - polygon[i].y) + polygon[i].x) && - (c = !c); - } - return c; - } -} - -export function inCircle(centerX, centerY, radius, x, y) { - const squareDist = Math.pow((centerX - x), 2) + Math.pow((centerY - y), 2); - return squareDist <= Math.pow(radius, 2); -} - -export function getDistanceFromLine(point, line) { - let minDistance = Number.POSITIVE_INFINITY; - if (line && line.length > 1) { - for (let i = 0, l = line.length - 1; i < l; i++) { - const distance = projectPointOnLineSegment(point, line[i], line[i + 1]); - if (distance <= minDistance) { - minDistance = distance; - } - } - } - return minDistance; -} - -export function projectPointOnLineSegment(point, r0, r1) { - const x = point.x; - const y = point.y; - const x1 = r0.x; - const y1 = r0.y; - const x2 = r1.x; - const y2 = r1.y; - - const A = x - x1; - const B = y - y1; - const C = x2 - x1; - const D = y2 - y1; - - const dot = A * C + B * D; - const lenSq = C * C + D * D; - let param = -1; - if (lenSq != 0) // in case of 0 length line - { - param = dot / lenSq; - } - - let xx; let yy; - - if (param < 0) { - xx = x1; - yy = y1; - } else if (param > 1) { - xx = x2; - yy = y2; - } else { - xx = x1 + param * C; - yy = y1 + param * D; - } - - const dx = x - xx; - const dy = y - yy; - return Math.sqrt(dx * dx + dy * dy); -} diff --git a/src/MVTLayer.js b/src/MVTLayer.js index 84f8661..35d65df 100644 --- a/src/MVTLayer.js +++ b/src/MVTLayer.js @@ -2,7 +2,7 @@ * Created by Jes�s Barrio on 04/2021 */ import {MVTFeature} from './MVTFeature.js'; -import * as MERCATOR from '../lib/mercator/Mercator.js'; +import {inCircle, getDistanceFromLine} from '../lib/mercator.js'; /** * @typedef {import('@mapbox/vector-tile').VectorTileLayer} VectorTileLayer @@ -219,7 +219,7 @@ class MVTLayer { */ _handleClickFeaturePoint(event, mVTFeature) { return mVTFeature.getPaths(event.tileContext).some((path) => { - return MERCATOR.inCircle(path[0].x, path[0].y, mVTFeature.style.radius, event.tilePoint.x, event.tilePoint.y); + return inCircle(path[0].x, path[0].y, mVTFeature.style.radius, event.tilePoint.x, event.tilePoint.y); }); } @@ -236,7 +236,7 @@ class MVTLayer { lineWidth = mVTFeature.style.selected.lineWidth; } mVTFeature.getPaths(event.tileContext).forEach((path) => { - const distance = MERCATOR.getDistanceFromLine(event.tilePoint, path); + const distance = getDistanceFromLine(event.tilePoint, path); if (distance < minDistance) { minDistance = distance; } diff --git a/src/MVTSource.js b/src/MVTSource.js index 964bd20..fab5eee 100644 --- a/src/MVTSource.js +++ b/src/MVTSource.js @@ -7,7 +7,7 @@ import Pbf from 'pbf'; import {VectorTile} from '@mapbox/vector-tile'; -import * as MERCATOR from '../lib/mercator/Mercator.js'; +import {getTileAtLatLng, fromLatLngToTilePoint} from '../lib/mercator.js'; import {MVTLayer} from './MVTLayer.js'; import {getTileFromString, getTileString} from '../lib/geometry.js'; @@ -446,12 +446,12 @@ class MVTSource { * @param {ClickHandlerOptions} options */ _mouseEventContinue(event, callbackFunction = ()=>{}, options) { - const tile = MERCATOR.getTileAtLatLng(event.latLng, this.map.getZoom()); + const tile = getTileAtLatLng(event.latLng, this.map.getZoom()); const tileId = getTileString(tile.z, tile.x, tile.y); const tileContext = this._visibleTiles[tileId]; if (!tileContext) return; - const tilePoint = MERCATOR.fromLatLngToTilePoint(this.map, event); + const tilePoint = fromLatLngToTilePoint(this.map, event); /** @type {TileMapMouseEvent} */ const newEvent = { ...event, diff --git a/tests/Mercator.spec.js b/tests/Mercator.spec.js index 0e1c29f..a435052 100644 --- a/tests/Mercator.spec.js +++ b/tests/Mercator.spec.js @@ -11,7 +11,7 @@ import { isPointInPolygon, normalizeTile, projectPointOnLineSegment, -} from '../lib/mercator/Mercator.js'; +} from '../lib/mercator.js'; initialize(); From bc7c905b74b9e2bd6064852173bc0dffdd52c2f2 Mon Sep 17 00:00:00 2001 From: camden-obertop <52179320+camden-obertop@users.noreply.github.com> Date: Mon, 20 Feb 2023 14:15:56 -0600 Subject: [PATCH 08/11] BMAPS-1772 Added urlGenerator to MVTSource options (#8) * Added urlGenerator to MVTSource options * Added underscore * Simplified try catch separation --- src/MVTSource.js | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/src/MVTSource.js b/src/MVTSource.js index fab5eee..8bf2c80 100644 --- a/src/MVTSource.js +++ b/src/MVTSource.js @@ -43,6 +43,7 @@ import {getTileFromString, getTileString} from '../lib/geometry.js'; /** * @typedef {Object} MVTSourceOptions * @property {string} [url] Url to Vector Tile Source + * @property {Function} [urlGenerator] Function for generating vector tile source url * @property {number} [sourceMaxZoom] Source max zoom to enable over zoom * @property {boolean} [debug] Draw tiles lines and ids * @property {boolean} [cache=false] Load tiles in cache to avoid duplicated requests @@ -193,6 +194,8 @@ class MVTSource { // Private properties /** @type {string} Url to Vector Tile Source */ this._url = options.url || ''; + /** @type {Function} function for generating tile source url */ + this._urlGenerator = options.urlGenerator || null; /** @type {number} Source max zoom to enable over zoom */ this._sourceMaxZoom = options.sourceMaxZoom ?? null; /** @type {boolean} Draw tiles lines and ids */ @@ -296,10 +299,21 @@ class MVTSource { * @param {TileContext} tileContext */ async _fetchTile(tileContext) { + // Draw debug tile info before trying to get tile data so that if errors occur, the debug info still draws + this._drawDebugInfo(tileContext); + + // Get the tile from the id const id = tileContext.parentId || tileContext.id; const tile = getTileFromString(id); - const src = this._url.replace('{z}', tile.zoom).replace('{x}', tile.x).replace('{y}', tile.y); + // Create the source url with the urlGenerator function if it exists, else replace {z} {y} and {x} + let src; + if (this._urlGenerator) { + src = this._urlGenerator(tile.zoom, tile.x, tile.y); + } else { + src = this._url.replace('{z}', tile.zoom).replace('{x}', tile.x).replace('{y}', tile.y); + } + /** @type {Response} */ let response; try { @@ -313,11 +327,16 @@ class MVTSource { // If the zoom has changed since the request was made, don't draw the tile if (this.map.getZoom() != tileContext.zoom) return; - const arrayBuffer = await response.arrayBuffer(); - const vectorTile = new VectorTile((new Pbf((new Uint8Array(arrayBuffer))))); - this._drawVectorTile(vectorTile, tileContext); + // Create a vector tile instance and draw it + try { + const arrayBuffer = await response.arrayBuffer(); + const vectorTile = new VectorTile(new Pbf(new Uint8Array(arrayBuffer))); + this._drawVectorTile(vectorTile, tileContext); + } catch (error) { + console.error('Error occurred while creating/drawing vector tile:', error); + return; + } } - this._drawDebugInfo(tileContext); } /** From f3773d65a6929b8593316a58c75bbcb535571ad6 Mon Sep 17 00:00:00 2001 From: camden-obertop <52179320+camden-obertop@users.noreply.github.com> Date: Tue, 21 Feb 2023 16:09:09 -0600 Subject: [PATCH 09/11] BMAPS-1772 v2 - Reworked url implementation (#9) * Added urlGenerator to MVTSource options * Added underscore * Simplified try catch separation * Made changes to url --- src/MVTSource.js | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/src/MVTSource.js b/src/MVTSource.js index 8bf2c80..b73468f 100644 --- a/src/MVTSource.js +++ b/src/MVTSource.js @@ -20,6 +20,12 @@ import {getTileFromString, getTileString} from '../lib/geometry.js'; */ /** + * @callback urlFn - A function that generates a url + * @param {number} zoom - the zoom level on the map + * @param {number} x - the x position of the tile + * @param {number} y - the y position of the tile + * @return {string} - A url for fetching a tile + * * @callback featureIdFn - A function that returns a unique id for a feature * @param {VectorTileFeature} feature * @return {string|number} @@ -42,8 +48,7 @@ import {getTileFromString, getTileString} from '../lib/geometry.js'; /** * @typedef {Object} MVTSourceOptions - * @property {string} [url] Url to Vector Tile Source - * @property {Function} [urlGenerator] Function for generating vector tile source url + * @property {(string|urlFn)} [url] Url to Vector Tile Source * @property {number} [sourceMaxZoom] Source max zoom to enable over zoom * @property {boolean} [debug] Draw tiles lines and ids * @property {boolean} [cache=false] Load tiles in cache to avoid duplicated requests @@ -192,10 +197,8 @@ class MVTSource { */ constructor(map, options = {}) { // Private properties - /** @type {string} Url to Vector Tile Source */ - this._url = options.url || ''; - /** @type {Function} function for generating tile source url */ - this._urlGenerator = options.urlGenerator || null; + /** @type {(string|urlFn)} Url to Vector Tile Source */ + this._url = options.url || null; /** @type {number} Source max zoom to enable over zoom */ this._sourceMaxZoom = options.sourceMaxZoom ?? null; /** @type {boolean} Draw tiles lines and ids */ @@ -306,22 +309,24 @@ class MVTSource { const id = tileContext.parentId || tileContext.id; const tile = getTileFromString(id); - // Create the source url with the urlGenerator function if it exists, else replace {z} {y} and {x} - let src; - if (this._urlGenerator) { - src = this._urlGenerator(tile.zoom, tile.x, tile.y); - } else { - src = this._url.replace('{z}', tile.zoom).replace('{x}', tile.x).replace('{y}', tile.y); - } - /** @type {Response} */ let response; + /** @type {string} */ + let src; try { + // If this._url is a function general the url with it, else replace {z} {y} and {x} in a string + if (typeof this._url === 'function') { + src = this._url(tile.zoom, tile.x, tile.y); + } else { + src = this._url.replace('{z}', tile.zoom).replace('{x}', tile.x).replace('{y}', tile.y); + } + // Fetch the response response = await fetch(src, { headers: this._xhrHeaders, }); } catch (error) { - console.error(new Error(`Error fetching tile ${src}`), error); + console.error(`Error fetching tile at source '${src}': ${error}`); + return; } if (response.ok) { // If the zoom has changed since the request was made, don't draw the tile From dcd1fd44d78770b8f57bb13a0182c6e795ae1a01 Mon Sep 17 00:00:00 2001 From: camden-obertop <52179320+camden-obertop@users.noreply.github.com> Date: Mon, 27 Feb 2023 11:24:29 -0600 Subject: [PATCH 10/11] BMAPS--1773 Add color styling to sublayers (#10) * Update this repo to reflect bmaps * deleted files accidentally added --- src/MVTLayer.js | 2 +- src/MVTSource.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/MVTLayer.js b/src/MVTLayer.js index 35d65df..897a92f 100644 --- a/src/MVTLayer.js +++ b/src/MVTLayer.js @@ -119,7 +119,7 @@ class MVTLayer { * @return {StyleOptions} */ getStyle(feature) { - return (typeof this.style === 'function') ? this.style(feature) : this.style; + return (typeof this.style === 'function') ? this.style(feature, this.name) : this.style; } /** diff --git a/src/MVTSource.js b/src/MVTSource.js index b73468f..e9bfd4f 100644 --- a/src/MVTSource.js +++ b/src/MVTSource.js @@ -32,6 +32,7 @@ import {getTileFromString, getTileString} from '../lib/geometry.js'; * * @callback styleFn - A function that returns a style for a feature * @param {VectorTileFeature} feature + * @param {string} name * @return {StyleOptions} * * @callback drawFn - A function that returns a style for a feature From 3ec5b4fd5ca3a3311930b990bdd5b6a510aa7a51 Mon Sep 17 00:00:00 2001 From: swilliams-northpointkc Date: Tue, 7 Mar 2023 12:13:25 -0600 Subject: [PATCH 11/11] Remove NPD-specific code diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index c4ae61a..0000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,28 +0,0 @@ -## Issue Link - -[[project acronym]-XXX](https://northpoint-development.atlassian.net/browse/[project acronym]-XXX) - -## Description - - -## Tests - - -## Screenshots - - -## Checklist - -ALWAYS -- [ ] My pull request title matches the following format: [project acronym]-### - [concise title] - (Ex. 'BMAPS-123 Updated Pull Request Template') -- [ ] I added/updated tests for the changes I made. (Or I have explained why I have not) -- [ ] I have run `npm audit fix` (Maybe multiple times) until all vulnerabilities that can be automatically fixed are fixed. If there are vulnerabilties that will need to be fixed manually, I have created a ticket to do so. - -ALMOST ALWAYS -- [ ] I added or updated documentation/README - -SOMETIMES -- [ ] (If this PR ends in a 0) I have scheduled a team code review - -[best_practices]:https://gist.github.com/robertpainsi/b632364184e70900af4ab688decf6f53 \ No newline at end of file diff --git a/vector-tiles-google-maps/dist/assets/index.js b/vector-tiles-google-maps/dist/assets/index.js new file mode 100644 index 0000000..a383735 --- /dev/null +++ b/vector-tiles-google-maps/dist/assets/index.js @@ -0,0 +1 @@ +(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))s(r);new MutationObserver(r=>{for(const n of r)if(n.type==="childList")for(const o of n.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&s(o)}).observe(document,{childList:!0,subtree:!0});function i(r){const n={};return r.integrity&&(n.integrity=r.integrity),r.referrerpolicy&&(n.referrerPolicy=r.referrerpolicy),r.crossorigin==="use-credentials"?n.credentials="include":r.crossorigin==="anonymous"?n.credentials="omit":n.credentials="same-origin",n}function s(r){if(r.ep)return;r.ep=!0;const n=i(r);fetch(r.href,n)}})();var P={};/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh */P.read=function(e,t,i,s,r){var n,o,a=r*8-s-1,h=(1<>1,l=-7,d=i?r-1:0,f=i?-1:1,x=e[t+d];for(d+=f,n=x&(1<<-l)-1,x>>=-l,l+=a;l>0;n=n*256+e[t+d],d+=f,l-=8);for(o=n&(1<<-l)-1,n>>=-l,l+=s;l>0;o=o*256+e[t+d],d+=f,l-=8);if(n===0)n=1-u;else{if(n===h)return o?NaN:(x?-1:1)*(1/0);o=o+Math.pow(2,s),n=n-u}return(x?-1:1)*o*Math.pow(2,n-s)};P.write=function(e,t,i,s,r,n){var o,a,h,u=n*8-r-1,l=(1<>1,f=r===23?Math.pow(2,-24)-Math.pow(2,-77):0,x=s?0:n-1,y=s?1:-1,w=t<0||t===0&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(a=isNaN(t)?1:0,o=l):(o=Math.floor(Math.log(t)/Math.LN2),t*(h=Math.pow(2,-o))<1&&(o--,h*=2),o+d>=1?t+=f/h:t+=f*Math.pow(2,1-d),t*h>=2&&(o++,h/=2),o+d>=l?(a=0,o=l):o+d>=1?(a=(t*h-1)*Math.pow(2,r),o=o+d):(a=t*Math.pow(2,d-1)*Math.pow(2,r),o=0));r>=8;e[i+x]=a&255,x+=y,a/=256,r-=8);for(o=o<0;e[i+x]=o&255,x+=y,o/=256,u-=8);e[i+x-y]|=w*128};var O=c,V=P;function c(e){this.buf=ArrayBuffer.isView&&ArrayBuffer.isView(e)?e:new Uint8Array(e||0),this.pos=0,this.type=0,this.length=this.buf.length}c.Varint=0;c.Fixed64=1;c.Bytes=2;c.Fixed32=5;var M=(1<<16)*(1<<16),D=1/M,N=12,C=typeof TextDecoder>"u"?null:new TextDecoder("utf8");c.prototype={destroy:function(){this.buf=null},readFields:function(e,t,i){for(i=i||this.length;this.pos>3,n=this.pos;this.type=s&7,e(r,t,this),this.pos===n&&this.skip(s)}return t},readMessage:function(e,t){return this.readFields(e,t,this.readVarint()+this.pos)},readFixed32:function(){var e=S(this.buf,this.pos);return this.pos+=4,e},readSFixed32:function(){var e=B(this.buf,this.pos);return this.pos+=4,e},readFixed64:function(){var e=S(this.buf,this.pos)+S(this.buf,this.pos+4)*M;return this.pos+=8,e},readSFixed64:function(){var e=S(this.buf,this.pos)+B(this.buf,this.pos+4)*M;return this.pos+=8,e},readFloat:function(){var e=V.read(this.buf,this.pos,!0,23,4);return this.pos+=4,e},readDouble:function(){var e=V.read(this.buf,this.pos,!0,52,8);return this.pos+=8,e},readVarint:function(e){var t=this.buf,i,s;return s=t[this.pos++],i=s&127,s<128||(s=t[this.pos++],i|=(s&127)<<7,s<128)||(s=t[this.pos++],i|=(s&127)<<14,s<128)||(s=t[this.pos++],i|=(s&127)<<21,s<128)?i:(s=t[this.pos],i|=(s&15)<<28,R(i,e,this))},readVarint64:function(){return this.readVarint(!0)},readSVarint:function(){var e=this.readVarint();return e%2===1?(e+1)/-2:e/2},readBoolean:function(){return Boolean(this.readVarint())},readString:function(){var e=this.readVarint()+this.pos,t=this.pos;return this.pos=e,e-t>=N&&C?tt(this.buf,t,e):Q(this.buf,t,e)},readBytes:function(){var e=this.readVarint()+this.pos,t=this.buf.subarray(this.pos,e);return this.pos=e,t},readPackedVarint:function(e,t){if(this.type!==c.Bytes)return e.push(this.readVarint(t));var i=g(this);for(e=e||[];this.pos127;);else if(t===c.Bytes)this.pos=this.readVarint()+this.pos;else if(t===c.Fixed32)this.pos+=4;else if(t===c.Fixed64)this.pos+=8;else throw new Error("Unimplemented type: "+t)},writeTag:function(e,t){this.writeVarint(e<<3|t)},realloc:function(e){for(var t=this.length||16;t268435455||e<0){j(e,this);return}this.realloc(4),this.buf[this.pos++]=e&127|(e>127?128:0),!(e<=127)&&(this.buf[this.pos++]=(e>>>=7)&127|(e>127?128:0),!(e<=127)&&(this.buf[this.pos++]=(e>>>=7)&127|(e>127?128:0),!(e<=127)&&(this.buf[this.pos++]=e>>>7&127)))},writeSVarint:function(e){this.writeVarint(e<0?-e*2-1:e*2)},writeBoolean:function(e){this.writeVarint(Boolean(e))},writeString:function(e){e=String(e),this.realloc(e.length*4),this.pos++;var t=this.pos;this.pos=et(this.buf,e,this.pos);var i=this.pos-t;i>=128&&I(t,i,this),this.pos=t-1,this.writeVarint(i),this.pos+=i},writeFloat:function(e){this.realloc(4),V.write(this.buf,e,this.pos,!0,23,4),this.pos+=4},writeDouble:function(e){this.realloc(8),V.write(this.buf,e,this.pos,!0,52,8),this.pos+=8},writeBytes:function(e){var t=e.length;this.writeVarint(t),this.realloc(t);for(var i=0;i=128&&I(i,s,this),this.pos=i-1,this.writeVarint(s),this.pos+=s},writeMessage:function(e,t,i){this.writeTag(e,c.Bytes),this.writeRawMessage(t,i)},writePackedVarint:function(e,t){t.length&&this.writeMessage(e,U,t)},writePackedSVarint:function(e,t){t.length&&this.writeMessage(e,W,t)},writePackedBoolean:function(e,t){t.length&&this.writeMessage(e,$,t)},writePackedFloat:function(e,t){t.length&&this.writeMessage(e,q,t)},writePackedDouble:function(e,t){t.length&&this.writeMessage(e,G,t)},writePackedFixed32:function(e,t){t.length&&this.writeMessage(e,X,t)},writePackedSFixed32:function(e,t){t.length&&this.writeMessage(e,Y,t)},writePackedFixed64:function(e,t){t.length&&this.writeMessage(e,J,t)},writePackedSFixed64:function(e,t){t.length&&this.writeMessage(e,K,t)},writeBytesField:function(e,t){this.writeTag(e,c.Bytes),this.writeBytes(t)},writeFixed32Field:function(e,t){this.writeTag(e,c.Fixed32),this.writeFixed32(t)},writeSFixed32Field:function(e,t){this.writeTag(e,c.Fixed32),this.writeSFixed32(t)},writeFixed64Field:function(e,t){this.writeTag(e,c.Fixed64),this.writeFixed64(t)},writeSFixed64Field:function(e,t){this.writeTag(e,c.Fixed64),this.writeSFixed64(t)},writeVarintField:function(e,t){this.writeTag(e,c.Varint),this.writeVarint(t)},writeSVarintField:function(e,t){this.writeTag(e,c.Varint),this.writeSVarint(t)},writeStringField:function(e,t){this.writeTag(e,c.Bytes),this.writeString(t)},writeFloatField:function(e,t){this.writeTag(e,c.Fixed32),this.writeFloat(t)},writeDoubleField:function(e,t){this.writeTag(e,c.Fixed64),this.writeDouble(t)},writeBooleanField:function(e,t){this.writeVarintField(e,Boolean(t))}};function R(e,t,i){var s=i.buf,r,n;if(n=s[i.pos++],r=(n&112)>>4,n<128||(n=s[i.pos++],r|=(n&127)<<3,n<128)||(n=s[i.pos++],r|=(n&127)<<10,n<128)||(n=s[i.pos++],r|=(n&127)<<17,n<128)||(n=s[i.pos++],r|=(n&127)<<24,n<128)||(n=s[i.pos++],r|=(n&1)<<31,n<128))return _(e,r,t);throw new Error("Expected varint not more than 10 bytes")}function g(e){return e.type===c.Bytes?e.readVarint()+e.pos:e.pos+1}function _(e,t,i){return i?t*4294967296+(e>>>0):(t>>>0)*4294967296+(e>>>0)}function j(e,t){var i,s;if(e>=0?(i=e%4294967296|0,s=e/4294967296|0):(i=~(-e%4294967296),s=~(-e/4294967296),i^4294967295?i=i+1|0:(i=0,s=s+1|0)),e>=18446744073709552e3||e<-18446744073709552e3)throw new Error("Given varint doesn't fit into 10 bytes");t.realloc(10),H(i,s,t),Z(s,t)}function H(e,t,i){i.buf[i.pos++]=e&127|128,e>>>=7,i.buf[i.pos++]=e&127|128,e>>>=7,i.buf[i.pos++]=e&127|128,e>>>=7,i.buf[i.pos++]=e&127|128,e>>>=7,i.buf[i.pos]=e&127}function Z(e,t){var i=(e&7)<<4;t.buf[t.pos++]|=i|((e>>>=3)?128:0),e&&(t.buf[t.pos++]=e&127|((e>>>=7)?128:0),e&&(t.buf[t.pos++]=e&127|((e>>>=7)?128:0),e&&(t.buf[t.pos++]=e&127|((e>>>=7)?128:0),e&&(t.buf[t.pos++]=e&127|((e>>>=7)?128:0),e&&(t.buf[t.pos++]=e&127)))))}function I(e,t,i){var s=t<=16383?1:t<=2097151?2:t<=268435455?3:Math.floor(Math.log(t)/(Math.LN2*7));i.realloc(s);for(var r=i.pos-1;r>=e;r--)i.buf[r+s]=i.buf[r]}function U(e,t){for(var i=0;i>>8,e[i+2]=t>>>16,e[i+3]=t>>>24}function B(e,t){return(e[t]|e[t+1]<<8|e[t+2]<<16)+(e[t+3]<<24)}function Q(e,t,i){for(var s="",r=t;r239?4:n>223?3:n>191?2:1;if(r+a>i)break;var h,u,l;a===1?n<128&&(o=n):a===2?(h=e[r+1],(h&192)===128&&(o=(n&31)<<6|h&63,o<=127&&(o=null))):a===3?(h=e[r+1],u=e[r+2],(h&192)===128&&(u&192)===128&&(o=(n&15)<<12|(h&63)<<6|u&63,(o<=2047||o>=55296&&o<=57343)&&(o=null))):a===4&&(h=e[r+1],u=e[r+2],l=e[r+3],(h&192)===128&&(u&192)===128&&(l&192)===128&&(o=(n&15)<<18|(h&63)<<12|(u&63)<<6|l&63,(o<=65535||o>=1114112)&&(o=null))),o===null?(o=65533,a=1):o>65535&&(o-=65536,s+=String.fromCharCode(o>>>10&1023|55296),o=56320|o&1023),s+=String.fromCharCode(o),r+=a}return s}function tt(e,t,i){return C.decode(e.subarray(t,i))}function et(e,t,i){for(var s=0,r,n;s55295&&r<57344)if(n)if(r<56320){e[i++]=239,e[i++]=191,e[i++]=189,n=r;continue}else r=n-55296<<10|r-56320|65536,n=null;else{r>56319||s+1===t.length?(e[i++]=239,e[i++]=191,e[i++]=189):n=r;continue}else n&&(e[i++]=239,e[i++]=191,e[i++]=189,n=null);r<128?e[i++]=r:(r<2048?e[i++]=r>>6|192:(r<65536?e[i++]=r>>12|224:(e[i++]=r>>18|240,e[i++]=r>>12&63|128),e[i++]=r>>6&63|128),e[i++]=r&63|128)}return i}var it=T;function T(e,t){this.x=e,this.y=t}T.prototype={clone:function(){return new T(this.x,this.y)},add:function(e){return this.clone()._add(e)},sub:function(e){return this.clone()._sub(e)},multByPoint:function(e){return this.clone()._multByPoint(e)},divByPoint:function(e){return this.clone()._divByPoint(e)},mult:function(e){return this.clone()._mult(e)},div:function(e){return this.clone()._div(e)},rotate:function(e){return this.clone()._rotate(e)},rotateAround:function(e,t){return this.clone()._rotateAround(e,t)},matMult:function(e){return this.clone()._matMult(e)},unit:function(){return this.clone()._unit()},perp:function(){return this.clone()._perp()},round:function(){return this.clone()._round()},mag:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},equals:function(e){return this.x===e.x&&this.y===e.y},dist:function(e){return Math.sqrt(this.distSqr(e))},distSqr:function(e){var t=e.x-this.x,i=e.y-this.y;return t*t+i*i},angle:function(){return Math.atan2(this.y,this.x)},angleTo:function(e){return Math.atan2(this.y-e.y,this.x-e.x)},angleWith:function(e){return this.angleWithSep(e.x,e.y)},angleWithSep:function(e,t){return Math.atan2(this.x*t-this.y*e,this.x*e+this.y*t)},_matMult:function(e){var t=e[0]*this.x+e[1]*this.y,i=e[2]*this.x+e[3]*this.y;return this.x=t,this.y=i,this},_add:function(e){return this.x+=e.x,this.y+=e.y,this},_sub:function(e){return this.x-=e.x,this.y-=e.y,this},_mult:function(e){return this.x*=e,this.y*=e,this},_div:function(e){return this.x/=e,this.y/=e,this},_multByPoint:function(e){return this.x*=e.x,this.y*=e.y,this},_divByPoint:function(e){return this.x/=e.x,this.y/=e.y,this},_unit:function(){return this._div(this.mag()),this},_perp:function(){var e=this.y;return this.y=this.x,this.x=-e,this},_rotate:function(e){var t=Math.cos(e),i=Math.sin(e),s=t*this.x-i*this.y,r=i*this.x+t*this.y;return this.x=s,this.y=r,this},_rotateAround:function(e,t){var i=Math.cos(e),s=Math.sin(e),r=t.x+i*(this.x-t.x)-s*(this.y-t.y),n=t.y+s*(this.x-t.x)+i*(this.y-t.y);return this.x=r,this.y=n,this},_round:function(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this}};T.convert=function(e){return e instanceof T?e:Array.isArray(e)?new T(e[0],e[1]):e};var st=it,rt=m;function m(e,t,i,s,r){this.properties={},this.extent=i,this.type=0,this._pbf=e,this._geometry=-1,this._keys=s,this._values=r,e.readFields(nt,this,t)}function nt(e,t,i){e==1?t.id=i.readVarint():e==2?ot(i,t):e==3?t.type=i.readVarint():e==4&&(t._geometry=i.pos)}function ot(e,t){for(var i=e.readVarint()+e.pos;e.pos>3}if(s--,i===1||i===2)r+=e.readSVarint(),n+=e.readSVarint(),i===1&&(a&&o.push(a),a=[]),a.push(new st(r,n));else if(i===7)a&&a.push(a[0].clone());else throw new Error("unknown command "+i)}return a&&o.push(a),o};m.prototype.bbox=function(){var e=this._pbf;e.pos=this._geometry;for(var t=e.readVarint()+e.pos,i=1,s=0,r=0,n=0,o=1/0,a=-1/0,h=1/0,u=-1/0;e.pos>3}if(s--,i===1||i===2)r+=e.readSVarint(),n+=e.readSVarint(),ra&&(a=r),nu&&(u=n);else if(i!==7)throw new Error("unknown command "+i)}return[o,h,a,u]};m.prototype.toGeoJSON=function(e,t,i){var s=this.extent*Math.pow(2,i),r=this.extent*e,n=this.extent*t,o=this.loadGeometry(),a=m.types[this.type],h,u;function l(x){for(var y=0;y>3;t=s===1?e.readString():s===2?e.readFloat():s===3?e.readDouble():s===4?e.readVarint64():s===5?e.readVarint():s===6?e.readSVarint():s===7?e.readBoolean():null}return t}E.prototype.feature=function(e){if(e<0||e>=this._features.length)throw new Error("feature index out of bounds");this._pbf.pos=this._features[e];var t=this._pbf.readVarint()+this._pbf.pos;return new lt(this._pbf,t,this.extent,this._keys,this._values)};var ft=ut,xt=yt;function yt(e,t){this.layers=e.readFields(wt,{},t)}function wt(e,t,i){if(e===3){var s=new ft(i,i.readVarint()+i.pos);s.length&&(t[s.name]=s)}}var gt=xt;function Ft(e){const t=Math.min(Math.max(Math.sin(e.lat()*(Math.PI/180)),-.9999),.9999);return{x:128+e.lng()*(256/360),y:128+.5*Math.log((1+t)/(1-t))*-(256/(2*Math.PI))}}function b(e){return{lat:(2*Math.atan(Math.exp((e.y-128)/-(256/(2*Math.PI))))-Math.PI/2)/(Math.PI/180),lng:(e.x-128)/(256/360)}}function A(e,t){const s=256/Math.pow(2,t),r=Ft(e);return{x:Math.floor(r.x/s),y:Math.floor(r.y/s),z:t}}function _t(e){e=pt(e);const i=256/Math.pow(2,e.z),s={x:e.x*i,y:e.y*i+i},r={x:e.x*i+i,y:e.y*i};return{sw:b(s),ne:b(r)}}function pt(e){const t=Math.pow(2,e.z);return e.x=(e.x%t+t)%t,e.y=(e.y%t+t)%t,e}function z(e,t){const i=e.getBounds(),s=i.getNorthEast(),r=i.getSouthWest(),n=e.getProjection().fromLatLngToPoint(s),o=e.getProjection().fromLatLngToPoint(r),a=Math.pow(2,e.getZoom()),h=e.getProjection().fromLatLngToPoint(t);return{x:(h.x-o.x)*a,y:(h.y-n.y)*a}}function Tt(e,t){const i=e.getZoom(),s=A(t.latLng,i),r=_t(s),n=new google.maps.LatLng(r.sw),o=new google.maps.LatLng(r.ne),a=z(e,n),h=z(e,o);return{x:t.pixel.x-a.x,y:t.pixel.y-h.y}}function mt(e,t,i,s,r){return Math.pow(e-s,2)+Math.pow(t-r,2)<=Math.pow(i,2)}function vt(e,t){let i=Number.POSITIVE_INFINITY;if(t&&t.length>1)for(let s=0,r=t.length-1;s1?(F=a,v=h):(F=n+w*d,v=o+w*f);const L=s-F,k=r-v;return Math.sqrt(L*L+k*k)}class St{constructor(t){this.mVTSource=t.mVTSource,this.selected=t.selected,this.featureId=t.featureId,this.tiles=[],this.style=t.style,this.type=t.vectorTileFeature.type,this.properties=t.vectorTileFeature.properties,this.addTileFeature(t.vectorTileFeature,t.tileContext),this._draw=t.customDraw||this.defaultDraw,this.selected&&this.select()}addTileFeature(t,i){this.tiles[i.id]={vectorTileFeature:t,divisor:t.extent/i.tileSize,context2d:!1,paths2d:!1}}getTiles(){return this.tiles}getTile(t){return this.tiles[t.id]}setStyle(t){this.style=t}redrawTiles(){const t=this.mVTSource.map.getZoom();for(const i in this.tiles)this.mVTSource.deleteTileDrawn(i),this.mVTSource.getTileObject(i).zoom==t&&this.mVTSource.redrawTile(i)}toggle(){this.selected?this.deselect():this.select()}select(){this.selected=!0,this.mVTSource.featureSelected(this),this.redrawTiles()}deselect(){this.selected=!1,this.mVTSource.featureDeselected(this),this.redrawTiles()}setSelected(t){this.selected=t}draw(t){const i=this.tiles[t.id];let s=this.style;this.selected&&this.style.selected&&(s=this.style.selected),this._draw(t,i,s,this)}defaultDraw(t,i,s){switch(this.type){case 1:this.drawPoint(t,i,s);break;case 2:this.drawLineString(t,i,s);break;case 3:this.drawPolygon(t,i,s);break}}drawPoint(t,i,s){const r=i.vectorTileFeature.coordinates[0][0],n=this.getPoint(r,t,i.divisor),o=s.radius||3,a=this.getContext2d(t.canvas,s);a.beginPath(),a.arc(n.x,n.y,o,0,Math.PI*2),a.closePath(),a.fill(),a.stroke()}drawLineString(t,i,s){i.context2d=this.getContext2d(t.canvas,s),this.drawCoordinates(t,i),i.context2d.stroke(i.paths2d)}drawPolygon(t,i,s){i.context2d=this.getContext2d(t.canvas,s),this.drawCoordinates(t,i),i.paths2d.closePath(),s.fillStyle&&i.context2d.fill(i.paths2d),s.strokeStyle&&i.context2d.stroke(i.paths2d)}drawCoordinates(t,i){const s=i.vectorTileFeature.coordinates;i.paths2d=new Path2D;for(let r=0,n=s.length;r0&&i.push(a)}return i}getContext2d(t,i){const s=t.getContext("2d");for(const r in i)r!=="selected"&&(s[r]=i[r]);return s}getPoint(t,i,s){let r={x:t.x/s,y:t.y/s};return i.parentId&&(r=this._getOverzoomedPoint(r,i)),r}_getOverzoomedPoint(t,i){const s=this.mVTSource.getTileObject(i.parentId),r=this.mVTSource.getTileObject(i.id),n=r.zoom-s.zoom,o=Math.pow(2,n),a=t.x*o,h=t.y*o,u=r.x%o,l=r.y%o;return t.x=a-u*i.tileSize,t.y=h-l*i.tileSize,t}isPointInPath(t,i){const s=this.getTile(i),r=s.context2d,n=s.paths2d;return!r||!n?!1:r.isPointInPath(n,t.x,t.y)}}class Mt{constructor(t){this._lineClickTolerance=2,this._getIDForLayerFeature=t.getIDForLayerFeature,this.style=t.style,this.name=t.name,this._filter=t.filter||!1,this._customDraw=t.customDraw||!1,this._canvasAndMVTFeatures=[],this._mVTFeatures=[]}parseVectorTileFeatures(t,i,s){this._canvasAndMVTFeatures[s.id]={canvas:s.canvas,features:[]};for(let r=0,n=i.length;r=0;s--){const r=i[s];if(this._handleClickFeature(t,r),this.selectedFeature!=null)return this.selectedFeature}}_handleClickFeature(t,i){switch(i.type){case 3:this._handleClickFeaturePolygon(t,i);break;default:{this._handleClickFeatureDefault(t,i);break}}}_handleClickFeaturePolygon(t,i){i.isPointInPath(t.tilePoint,t.tileContext)&&(this.selectedFeature=i,this.minDistance=0)}_handleClickFeatureDefault(t,i){const s=i.getPaths(t.tileContext);for(let o=s.length-1;o>=0;o--){const a=s[o];switch(i.type){case 1:mt(a[0].x,a[0].y,i.style.radius,t.tilePoint.x,t.tilePoint.y)&&(this.selectedFeature=i,this.minDistance=0);break;case 2:var r=vt(t.tilePoint,a),n=i.selected&&i.style.selected?i.style.selected.lineWidth:i.style.lineWidth;r{s._zoomChanged()})}getTile(t,i,s){const r=this.drawTile(t,i,s);return this._setVisibleTile(r),r.canvas}releaseTile(t){}_zoomChanged(){this._resetVisibleTiles(),this._cache||this._resetMVTLayers()}_resetMVTLayers(){this.mVTLayers=[]}_deleteVisibleTile(t){delete this._visibleTiles[t]}_resetVisibleTiles(){this._visibleTiles=[]}_setVisibleTile(t){this._visibleTiles[t.id]=t}drawTile(t,i,s){const r=this.getTileId(i,t.x,t.y);let n=this._tilesDrawn[r];return n||(n=this._createTileContext(t,i,s),this._xhrRequest(n),n)}_createTileContext(t,i,s){const r=this.getTileId(i,t.x,t.y),n=this._createCanvas(s,r),o=this._getParentId(r);return{id:r,canvas:n,zoom:i,tileSize:this._tileSize,parentId:o}}_getParentId(t){let i=!1;if(this._sourceMaxZoom){const s=this.getTileObject(t);if(s.zoom>this._sourceMaxZoom){const r=s.zoom-this._sourceMaxZoom,n=s.zoom-r,o=s.x>>r,a=s.y>>r;i=this.getTileId(n,o,a)}}return i}_createCanvas(t,i){const s=t.createElement("canvas");return s.width=this._tileSize,s.height=this._tileSize,s.id=i,s}getTileId(t,i,s){return[t,i,s].join(":")}getTileObject(t){const i=t.split(":");return{zoom:i[0],x:i[1],y:i[2]}}_xhrRequest(t){const i=this,s=t.parentId||t.id,r=this.getTileObject(s),n=this._url.replace("{z}",r.zoom).replace("{x}",r.x).replace("{y}",r.y),o=new XMLHttpRequest;o.onload=function(){if(o.status=="200"&&o.response)return i._xhrResponseOk(t,o.response);i._drawDebugInfo(t)},o.open("GET",n,!0);for(const a in this._xhrHeaders)o.setRequestHeader(a,this._xhrHeaders[a]);o.responseType="arraybuffer",o.send()}_xhrResponseOk(t,i){if(this.map.getZoom()!=t.zoom)return;const s=new Uint8Array(i),r=new O(s),n=new gt(r);for(var o in n.layers){var a=n.layers[o];a.parsedFeatures=[];for(var h=a._features.length,u=0,l=h;u=0;l--){const d=u[l],f=this.mVTLayers[d];if(f){var t=f.handleClickEvent(t,this);if(this._mouseSelectedFeature(t,i,s),r&&t.feature)break}}}_mouseSelectedFeature(t,i,s){if(s.setSelected){const r=t.feature;r?s.mouseHover?r.selected||r.select():s.toggleSelection?r.toggle():r.selected||r.select():s.mouseHover&&this.deselectAllFeatures()}i(t)}deselectAllFeatures(){const t=this.map.getZoom(),i=[];for(const s in this._selectedFeatures){const r=this._selectedFeatures[s];if(!r)continue;r.setSelected(!1);const n=r.getTiles();for(const o in n)this.deleteTileDrawn(o),this.getTileObject(o).zoom==t&&(i[o]=!0)}this.redrawTiles(i),this._selectedFeatures=[]}featureSelected(t){this._multipleSelection||this.deselectAllFeatures(),this._selectedFeatures[t.featureId]=t}featureDeselected(t){delete this._selectedFeatures[t.featureId]}setSelectedFeatures(t){t.length>1&&(this._multipleSelection=!0),this.deselectAllFeatures();for(let i=0,s=t.length;i + + + + + + + + \ No newline at end of file --- .github/PULL_REQUEST_TEMPLATE.md | 28 ------------------- vector-tiles-google-maps/dist/assets/index.js | 1 + vector-tiles-google-maps/dist/index.html | 10 +++++++ 3 files changed, 11 insertions(+), 28 deletions(-) delete mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 vector-tiles-google-maps/dist/assets/index.js create mode 100644 vector-tiles-google-maps/dist/index.html diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index c4ae61a..0000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,28 +0,0 @@ -## Issue Link - -[[project acronym]-XXX](https://northpoint-development.atlassian.net/browse/[project acronym]-XXX) - -## Description - - -## Tests - - -## Screenshots - - -## Checklist - -ALWAYS -- [ ] My pull request title matches the following format: [project acronym]-### - [concise title] - (Ex. 'BMAPS-123 Updated Pull Request Template') -- [ ] I added/updated tests for the changes I made. (Or I have explained why I have not) -- [ ] I have run `npm audit fix` (Maybe multiple times) until all vulnerabilities that can be automatically fixed are fixed. If there are vulnerabilties that will need to be fixed manually, I have created a ticket to do so. - -ALMOST ALWAYS -- [ ] I added or updated documentation/README - -SOMETIMES -- [ ] (If this PR ends in a 0) I have scheduled a team code review - -[best_practices]:https://gist.github.com/robertpainsi/b632364184e70900af4ab688decf6f53 \ No newline at end of file diff --git a/vector-tiles-google-maps/dist/assets/index.js b/vector-tiles-google-maps/dist/assets/index.js new file mode 100644 index 0000000..a383735 --- /dev/null +++ b/vector-tiles-google-maps/dist/assets/index.js @@ -0,0 +1 @@ +(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))s(r);new MutationObserver(r=>{for(const n of r)if(n.type==="childList")for(const o of n.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&s(o)}).observe(document,{childList:!0,subtree:!0});function i(r){const n={};return r.integrity&&(n.integrity=r.integrity),r.referrerpolicy&&(n.referrerPolicy=r.referrerpolicy),r.crossorigin==="use-credentials"?n.credentials="include":r.crossorigin==="anonymous"?n.credentials="omit":n.credentials="same-origin",n}function s(r){if(r.ep)return;r.ep=!0;const n=i(r);fetch(r.href,n)}})();var P={};/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh */P.read=function(e,t,i,s,r){var n,o,a=r*8-s-1,h=(1<>1,l=-7,d=i?r-1:0,f=i?-1:1,x=e[t+d];for(d+=f,n=x&(1<<-l)-1,x>>=-l,l+=a;l>0;n=n*256+e[t+d],d+=f,l-=8);for(o=n&(1<<-l)-1,n>>=-l,l+=s;l>0;o=o*256+e[t+d],d+=f,l-=8);if(n===0)n=1-u;else{if(n===h)return o?NaN:(x?-1:1)*(1/0);o=o+Math.pow(2,s),n=n-u}return(x?-1:1)*o*Math.pow(2,n-s)};P.write=function(e,t,i,s,r,n){var o,a,h,u=n*8-r-1,l=(1<>1,f=r===23?Math.pow(2,-24)-Math.pow(2,-77):0,x=s?0:n-1,y=s?1:-1,w=t<0||t===0&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(a=isNaN(t)?1:0,o=l):(o=Math.floor(Math.log(t)/Math.LN2),t*(h=Math.pow(2,-o))<1&&(o--,h*=2),o+d>=1?t+=f/h:t+=f*Math.pow(2,1-d),t*h>=2&&(o++,h/=2),o+d>=l?(a=0,o=l):o+d>=1?(a=(t*h-1)*Math.pow(2,r),o=o+d):(a=t*Math.pow(2,d-1)*Math.pow(2,r),o=0));r>=8;e[i+x]=a&255,x+=y,a/=256,r-=8);for(o=o<0;e[i+x]=o&255,x+=y,o/=256,u-=8);e[i+x-y]|=w*128};var O=c,V=P;function c(e){this.buf=ArrayBuffer.isView&&ArrayBuffer.isView(e)?e:new Uint8Array(e||0),this.pos=0,this.type=0,this.length=this.buf.length}c.Varint=0;c.Fixed64=1;c.Bytes=2;c.Fixed32=5;var M=(1<<16)*(1<<16),D=1/M,N=12,C=typeof TextDecoder>"u"?null:new TextDecoder("utf8");c.prototype={destroy:function(){this.buf=null},readFields:function(e,t,i){for(i=i||this.length;this.pos>3,n=this.pos;this.type=s&7,e(r,t,this),this.pos===n&&this.skip(s)}return t},readMessage:function(e,t){return this.readFields(e,t,this.readVarint()+this.pos)},readFixed32:function(){var e=S(this.buf,this.pos);return this.pos+=4,e},readSFixed32:function(){var e=B(this.buf,this.pos);return this.pos+=4,e},readFixed64:function(){var e=S(this.buf,this.pos)+S(this.buf,this.pos+4)*M;return this.pos+=8,e},readSFixed64:function(){var e=S(this.buf,this.pos)+B(this.buf,this.pos+4)*M;return this.pos+=8,e},readFloat:function(){var e=V.read(this.buf,this.pos,!0,23,4);return this.pos+=4,e},readDouble:function(){var e=V.read(this.buf,this.pos,!0,52,8);return this.pos+=8,e},readVarint:function(e){var t=this.buf,i,s;return s=t[this.pos++],i=s&127,s<128||(s=t[this.pos++],i|=(s&127)<<7,s<128)||(s=t[this.pos++],i|=(s&127)<<14,s<128)||(s=t[this.pos++],i|=(s&127)<<21,s<128)?i:(s=t[this.pos],i|=(s&15)<<28,R(i,e,this))},readVarint64:function(){return this.readVarint(!0)},readSVarint:function(){var e=this.readVarint();return e%2===1?(e+1)/-2:e/2},readBoolean:function(){return Boolean(this.readVarint())},readString:function(){var e=this.readVarint()+this.pos,t=this.pos;return this.pos=e,e-t>=N&&C?tt(this.buf,t,e):Q(this.buf,t,e)},readBytes:function(){var e=this.readVarint()+this.pos,t=this.buf.subarray(this.pos,e);return this.pos=e,t},readPackedVarint:function(e,t){if(this.type!==c.Bytes)return e.push(this.readVarint(t));var i=g(this);for(e=e||[];this.pos127;);else if(t===c.Bytes)this.pos=this.readVarint()+this.pos;else if(t===c.Fixed32)this.pos+=4;else if(t===c.Fixed64)this.pos+=8;else throw new Error("Unimplemented type: "+t)},writeTag:function(e,t){this.writeVarint(e<<3|t)},realloc:function(e){for(var t=this.length||16;t268435455||e<0){j(e,this);return}this.realloc(4),this.buf[this.pos++]=e&127|(e>127?128:0),!(e<=127)&&(this.buf[this.pos++]=(e>>>=7)&127|(e>127?128:0),!(e<=127)&&(this.buf[this.pos++]=(e>>>=7)&127|(e>127?128:0),!(e<=127)&&(this.buf[this.pos++]=e>>>7&127)))},writeSVarint:function(e){this.writeVarint(e<0?-e*2-1:e*2)},writeBoolean:function(e){this.writeVarint(Boolean(e))},writeString:function(e){e=String(e),this.realloc(e.length*4),this.pos++;var t=this.pos;this.pos=et(this.buf,e,this.pos);var i=this.pos-t;i>=128&&I(t,i,this),this.pos=t-1,this.writeVarint(i),this.pos+=i},writeFloat:function(e){this.realloc(4),V.write(this.buf,e,this.pos,!0,23,4),this.pos+=4},writeDouble:function(e){this.realloc(8),V.write(this.buf,e,this.pos,!0,52,8),this.pos+=8},writeBytes:function(e){var t=e.length;this.writeVarint(t),this.realloc(t);for(var i=0;i=128&&I(i,s,this),this.pos=i-1,this.writeVarint(s),this.pos+=s},writeMessage:function(e,t,i){this.writeTag(e,c.Bytes),this.writeRawMessage(t,i)},writePackedVarint:function(e,t){t.length&&this.writeMessage(e,U,t)},writePackedSVarint:function(e,t){t.length&&this.writeMessage(e,W,t)},writePackedBoolean:function(e,t){t.length&&this.writeMessage(e,$,t)},writePackedFloat:function(e,t){t.length&&this.writeMessage(e,q,t)},writePackedDouble:function(e,t){t.length&&this.writeMessage(e,G,t)},writePackedFixed32:function(e,t){t.length&&this.writeMessage(e,X,t)},writePackedSFixed32:function(e,t){t.length&&this.writeMessage(e,Y,t)},writePackedFixed64:function(e,t){t.length&&this.writeMessage(e,J,t)},writePackedSFixed64:function(e,t){t.length&&this.writeMessage(e,K,t)},writeBytesField:function(e,t){this.writeTag(e,c.Bytes),this.writeBytes(t)},writeFixed32Field:function(e,t){this.writeTag(e,c.Fixed32),this.writeFixed32(t)},writeSFixed32Field:function(e,t){this.writeTag(e,c.Fixed32),this.writeSFixed32(t)},writeFixed64Field:function(e,t){this.writeTag(e,c.Fixed64),this.writeFixed64(t)},writeSFixed64Field:function(e,t){this.writeTag(e,c.Fixed64),this.writeSFixed64(t)},writeVarintField:function(e,t){this.writeTag(e,c.Varint),this.writeVarint(t)},writeSVarintField:function(e,t){this.writeTag(e,c.Varint),this.writeSVarint(t)},writeStringField:function(e,t){this.writeTag(e,c.Bytes),this.writeString(t)},writeFloatField:function(e,t){this.writeTag(e,c.Fixed32),this.writeFloat(t)},writeDoubleField:function(e,t){this.writeTag(e,c.Fixed64),this.writeDouble(t)},writeBooleanField:function(e,t){this.writeVarintField(e,Boolean(t))}};function R(e,t,i){var s=i.buf,r,n;if(n=s[i.pos++],r=(n&112)>>4,n<128||(n=s[i.pos++],r|=(n&127)<<3,n<128)||(n=s[i.pos++],r|=(n&127)<<10,n<128)||(n=s[i.pos++],r|=(n&127)<<17,n<128)||(n=s[i.pos++],r|=(n&127)<<24,n<128)||(n=s[i.pos++],r|=(n&1)<<31,n<128))return _(e,r,t);throw new Error("Expected varint not more than 10 bytes")}function g(e){return e.type===c.Bytes?e.readVarint()+e.pos:e.pos+1}function _(e,t,i){return i?t*4294967296+(e>>>0):(t>>>0)*4294967296+(e>>>0)}function j(e,t){var i,s;if(e>=0?(i=e%4294967296|0,s=e/4294967296|0):(i=~(-e%4294967296),s=~(-e/4294967296),i^4294967295?i=i+1|0:(i=0,s=s+1|0)),e>=18446744073709552e3||e<-18446744073709552e3)throw new Error("Given varint doesn't fit into 10 bytes");t.realloc(10),H(i,s,t),Z(s,t)}function H(e,t,i){i.buf[i.pos++]=e&127|128,e>>>=7,i.buf[i.pos++]=e&127|128,e>>>=7,i.buf[i.pos++]=e&127|128,e>>>=7,i.buf[i.pos++]=e&127|128,e>>>=7,i.buf[i.pos]=e&127}function Z(e,t){var i=(e&7)<<4;t.buf[t.pos++]|=i|((e>>>=3)?128:0),e&&(t.buf[t.pos++]=e&127|((e>>>=7)?128:0),e&&(t.buf[t.pos++]=e&127|((e>>>=7)?128:0),e&&(t.buf[t.pos++]=e&127|((e>>>=7)?128:0),e&&(t.buf[t.pos++]=e&127|((e>>>=7)?128:0),e&&(t.buf[t.pos++]=e&127)))))}function I(e,t,i){var s=t<=16383?1:t<=2097151?2:t<=268435455?3:Math.floor(Math.log(t)/(Math.LN2*7));i.realloc(s);for(var r=i.pos-1;r>=e;r--)i.buf[r+s]=i.buf[r]}function U(e,t){for(var i=0;i>>8,e[i+2]=t>>>16,e[i+3]=t>>>24}function B(e,t){return(e[t]|e[t+1]<<8|e[t+2]<<16)+(e[t+3]<<24)}function Q(e,t,i){for(var s="",r=t;r239?4:n>223?3:n>191?2:1;if(r+a>i)break;var h,u,l;a===1?n<128&&(o=n):a===2?(h=e[r+1],(h&192)===128&&(o=(n&31)<<6|h&63,o<=127&&(o=null))):a===3?(h=e[r+1],u=e[r+2],(h&192)===128&&(u&192)===128&&(o=(n&15)<<12|(h&63)<<6|u&63,(o<=2047||o>=55296&&o<=57343)&&(o=null))):a===4&&(h=e[r+1],u=e[r+2],l=e[r+3],(h&192)===128&&(u&192)===128&&(l&192)===128&&(o=(n&15)<<18|(h&63)<<12|(u&63)<<6|l&63,(o<=65535||o>=1114112)&&(o=null))),o===null?(o=65533,a=1):o>65535&&(o-=65536,s+=String.fromCharCode(o>>>10&1023|55296),o=56320|o&1023),s+=String.fromCharCode(o),r+=a}return s}function tt(e,t,i){return C.decode(e.subarray(t,i))}function et(e,t,i){for(var s=0,r,n;s55295&&r<57344)if(n)if(r<56320){e[i++]=239,e[i++]=191,e[i++]=189,n=r;continue}else r=n-55296<<10|r-56320|65536,n=null;else{r>56319||s+1===t.length?(e[i++]=239,e[i++]=191,e[i++]=189):n=r;continue}else n&&(e[i++]=239,e[i++]=191,e[i++]=189,n=null);r<128?e[i++]=r:(r<2048?e[i++]=r>>6|192:(r<65536?e[i++]=r>>12|224:(e[i++]=r>>18|240,e[i++]=r>>12&63|128),e[i++]=r>>6&63|128),e[i++]=r&63|128)}return i}var it=T;function T(e,t){this.x=e,this.y=t}T.prototype={clone:function(){return new T(this.x,this.y)},add:function(e){return this.clone()._add(e)},sub:function(e){return this.clone()._sub(e)},multByPoint:function(e){return this.clone()._multByPoint(e)},divByPoint:function(e){return this.clone()._divByPoint(e)},mult:function(e){return this.clone()._mult(e)},div:function(e){return this.clone()._div(e)},rotate:function(e){return this.clone()._rotate(e)},rotateAround:function(e,t){return this.clone()._rotateAround(e,t)},matMult:function(e){return this.clone()._matMult(e)},unit:function(){return this.clone()._unit()},perp:function(){return this.clone()._perp()},round:function(){return this.clone()._round()},mag:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},equals:function(e){return this.x===e.x&&this.y===e.y},dist:function(e){return Math.sqrt(this.distSqr(e))},distSqr:function(e){var t=e.x-this.x,i=e.y-this.y;return t*t+i*i},angle:function(){return Math.atan2(this.y,this.x)},angleTo:function(e){return Math.atan2(this.y-e.y,this.x-e.x)},angleWith:function(e){return this.angleWithSep(e.x,e.y)},angleWithSep:function(e,t){return Math.atan2(this.x*t-this.y*e,this.x*e+this.y*t)},_matMult:function(e){var t=e[0]*this.x+e[1]*this.y,i=e[2]*this.x+e[3]*this.y;return this.x=t,this.y=i,this},_add:function(e){return this.x+=e.x,this.y+=e.y,this},_sub:function(e){return this.x-=e.x,this.y-=e.y,this},_mult:function(e){return this.x*=e,this.y*=e,this},_div:function(e){return this.x/=e,this.y/=e,this},_multByPoint:function(e){return this.x*=e.x,this.y*=e.y,this},_divByPoint:function(e){return this.x/=e.x,this.y/=e.y,this},_unit:function(){return this._div(this.mag()),this},_perp:function(){var e=this.y;return this.y=this.x,this.x=-e,this},_rotate:function(e){var t=Math.cos(e),i=Math.sin(e),s=t*this.x-i*this.y,r=i*this.x+t*this.y;return this.x=s,this.y=r,this},_rotateAround:function(e,t){var i=Math.cos(e),s=Math.sin(e),r=t.x+i*(this.x-t.x)-s*(this.y-t.y),n=t.y+s*(this.x-t.x)+i*(this.y-t.y);return this.x=r,this.y=n,this},_round:function(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this}};T.convert=function(e){return e instanceof T?e:Array.isArray(e)?new T(e[0],e[1]):e};var st=it,rt=m;function m(e,t,i,s,r){this.properties={},this.extent=i,this.type=0,this._pbf=e,this._geometry=-1,this._keys=s,this._values=r,e.readFields(nt,this,t)}function nt(e,t,i){e==1?t.id=i.readVarint():e==2?ot(i,t):e==3?t.type=i.readVarint():e==4&&(t._geometry=i.pos)}function ot(e,t){for(var i=e.readVarint()+e.pos;e.pos>3}if(s--,i===1||i===2)r+=e.readSVarint(),n+=e.readSVarint(),i===1&&(a&&o.push(a),a=[]),a.push(new st(r,n));else if(i===7)a&&a.push(a[0].clone());else throw new Error("unknown command "+i)}return a&&o.push(a),o};m.prototype.bbox=function(){var e=this._pbf;e.pos=this._geometry;for(var t=e.readVarint()+e.pos,i=1,s=0,r=0,n=0,o=1/0,a=-1/0,h=1/0,u=-1/0;e.pos>3}if(s--,i===1||i===2)r+=e.readSVarint(),n+=e.readSVarint(),ra&&(a=r),nu&&(u=n);else if(i!==7)throw new Error("unknown command "+i)}return[o,h,a,u]};m.prototype.toGeoJSON=function(e,t,i){var s=this.extent*Math.pow(2,i),r=this.extent*e,n=this.extent*t,o=this.loadGeometry(),a=m.types[this.type],h,u;function l(x){for(var y=0;y>3;t=s===1?e.readString():s===2?e.readFloat():s===3?e.readDouble():s===4?e.readVarint64():s===5?e.readVarint():s===6?e.readSVarint():s===7?e.readBoolean():null}return t}E.prototype.feature=function(e){if(e<0||e>=this._features.length)throw new Error("feature index out of bounds");this._pbf.pos=this._features[e];var t=this._pbf.readVarint()+this._pbf.pos;return new lt(this._pbf,t,this.extent,this._keys,this._values)};var ft=ut,xt=yt;function yt(e,t){this.layers=e.readFields(wt,{},t)}function wt(e,t,i){if(e===3){var s=new ft(i,i.readVarint()+i.pos);s.length&&(t[s.name]=s)}}var gt=xt;function Ft(e){const t=Math.min(Math.max(Math.sin(e.lat()*(Math.PI/180)),-.9999),.9999);return{x:128+e.lng()*(256/360),y:128+.5*Math.log((1+t)/(1-t))*-(256/(2*Math.PI))}}function b(e){return{lat:(2*Math.atan(Math.exp((e.y-128)/-(256/(2*Math.PI))))-Math.PI/2)/(Math.PI/180),lng:(e.x-128)/(256/360)}}function A(e,t){const s=256/Math.pow(2,t),r=Ft(e);return{x:Math.floor(r.x/s),y:Math.floor(r.y/s),z:t}}function _t(e){e=pt(e);const i=256/Math.pow(2,e.z),s={x:e.x*i,y:e.y*i+i},r={x:e.x*i+i,y:e.y*i};return{sw:b(s),ne:b(r)}}function pt(e){const t=Math.pow(2,e.z);return e.x=(e.x%t+t)%t,e.y=(e.y%t+t)%t,e}function z(e,t){const i=e.getBounds(),s=i.getNorthEast(),r=i.getSouthWest(),n=e.getProjection().fromLatLngToPoint(s),o=e.getProjection().fromLatLngToPoint(r),a=Math.pow(2,e.getZoom()),h=e.getProjection().fromLatLngToPoint(t);return{x:(h.x-o.x)*a,y:(h.y-n.y)*a}}function Tt(e,t){const i=e.getZoom(),s=A(t.latLng,i),r=_t(s),n=new google.maps.LatLng(r.sw),o=new google.maps.LatLng(r.ne),a=z(e,n),h=z(e,o);return{x:t.pixel.x-a.x,y:t.pixel.y-h.y}}function mt(e,t,i,s,r){return Math.pow(e-s,2)+Math.pow(t-r,2)<=Math.pow(i,2)}function vt(e,t){let i=Number.POSITIVE_INFINITY;if(t&&t.length>1)for(let s=0,r=t.length-1;s1?(F=a,v=h):(F=n+w*d,v=o+w*f);const L=s-F,k=r-v;return Math.sqrt(L*L+k*k)}class St{constructor(t){this.mVTSource=t.mVTSource,this.selected=t.selected,this.featureId=t.featureId,this.tiles=[],this.style=t.style,this.type=t.vectorTileFeature.type,this.properties=t.vectorTileFeature.properties,this.addTileFeature(t.vectorTileFeature,t.tileContext),this._draw=t.customDraw||this.defaultDraw,this.selected&&this.select()}addTileFeature(t,i){this.tiles[i.id]={vectorTileFeature:t,divisor:t.extent/i.tileSize,context2d:!1,paths2d:!1}}getTiles(){return this.tiles}getTile(t){return this.tiles[t.id]}setStyle(t){this.style=t}redrawTiles(){const t=this.mVTSource.map.getZoom();for(const i in this.tiles)this.mVTSource.deleteTileDrawn(i),this.mVTSource.getTileObject(i).zoom==t&&this.mVTSource.redrawTile(i)}toggle(){this.selected?this.deselect():this.select()}select(){this.selected=!0,this.mVTSource.featureSelected(this),this.redrawTiles()}deselect(){this.selected=!1,this.mVTSource.featureDeselected(this),this.redrawTiles()}setSelected(t){this.selected=t}draw(t){const i=this.tiles[t.id];let s=this.style;this.selected&&this.style.selected&&(s=this.style.selected),this._draw(t,i,s,this)}defaultDraw(t,i,s){switch(this.type){case 1:this.drawPoint(t,i,s);break;case 2:this.drawLineString(t,i,s);break;case 3:this.drawPolygon(t,i,s);break}}drawPoint(t,i,s){const r=i.vectorTileFeature.coordinates[0][0],n=this.getPoint(r,t,i.divisor),o=s.radius||3,a=this.getContext2d(t.canvas,s);a.beginPath(),a.arc(n.x,n.y,o,0,Math.PI*2),a.closePath(),a.fill(),a.stroke()}drawLineString(t,i,s){i.context2d=this.getContext2d(t.canvas,s),this.drawCoordinates(t,i),i.context2d.stroke(i.paths2d)}drawPolygon(t,i,s){i.context2d=this.getContext2d(t.canvas,s),this.drawCoordinates(t,i),i.paths2d.closePath(),s.fillStyle&&i.context2d.fill(i.paths2d),s.strokeStyle&&i.context2d.stroke(i.paths2d)}drawCoordinates(t,i){const s=i.vectorTileFeature.coordinates;i.paths2d=new Path2D;for(let r=0,n=s.length;r0&&i.push(a)}return i}getContext2d(t,i){const s=t.getContext("2d");for(const r in i)r!=="selected"&&(s[r]=i[r]);return s}getPoint(t,i,s){let r={x:t.x/s,y:t.y/s};return i.parentId&&(r=this._getOverzoomedPoint(r,i)),r}_getOverzoomedPoint(t,i){const s=this.mVTSource.getTileObject(i.parentId),r=this.mVTSource.getTileObject(i.id),n=r.zoom-s.zoom,o=Math.pow(2,n),a=t.x*o,h=t.y*o,u=r.x%o,l=r.y%o;return t.x=a-u*i.tileSize,t.y=h-l*i.tileSize,t}isPointInPath(t,i){const s=this.getTile(i),r=s.context2d,n=s.paths2d;return!r||!n?!1:r.isPointInPath(n,t.x,t.y)}}class Mt{constructor(t){this._lineClickTolerance=2,this._getIDForLayerFeature=t.getIDForLayerFeature,this.style=t.style,this.name=t.name,this._filter=t.filter||!1,this._customDraw=t.customDraw||!1,this._canvasAndMVTFeatures=[],this._mVTFeatures=[]}parseVectorTileFeatures(t,i,s){this._canvasAndMVTFeatures[s.id]={canvas:s.canvas,features:[]};for(let r=0,n=i.length;r=0;s--){const r=i[s];if(this._handleClickFeature(t,r),this.selectedFeature!=null)return this.selectedFeature}}_handleClickFeature(t,i){switch(i.type){case 3:this._handleClickFeaturePolygon(t,i);break;default:{this._handleClickFeatureDefault(t,i);break}}}_handleClickFeaturePolygon(t,i){i.isPointInPath(t.tilePoint,t.tileContext)&&(this.selectedFeature=i,this.minDistance=0)}_handleClickFeatureDefault(t,i){const s=i.getPaths(t.tileContext);for(let o=s.length-1;o>=0;o--){const a=s[o];switch(i.type){case 1:mt(a[0].x,a[0].y,i.style.radius,t.tilePoint.x,t.tilePoint.y)&&(this.selectedFeature=i,this.minDistance=0);break;case 2:var r=vt(t.tilePoint,a),n=i.selected&&i.style.selected?i.style.selected.lineWidth:i.style.lineWidth;r{s._zoomChanged()})}getTile(t,i,s){const r=this.drawTile(t,i,s);return this._setVisibleTile(r),r.canvas}releaseTile(t){}_zoomChanged(){this._resetVisibleTiles(),this._cache||this._resetMVTLayers()}_resetMVTLayers(){this.mVTLayers=[]}_deleteVisibleTile(t){delete this._visibleTiles[t]}_resetVisibleTiles(){this._visibleTiles=[]}_setVisibleTile(t){this._visibleTiles[t.id]=t}drawTile(t,i,s){const r=this.getTileId(i,t.x,t.y);let n=this._tilesDrawn[r];return n||(n=this._createTileContext(t,i,s),this._xhrRequest(n),n)}_createTileContext(t,i,s){const r=this.getTileId(i,t.x,t.y),n=this._createCanvas(s,r),o=this._getParentId(r);return{id:r,canvas:n,zoom:i,tileSize:this._tileSize,parentId:o}}_getParentId(t){let i=!1;if(this._sourceMaxZoom){const s=this.getTileObject(t);if(s.zoom>this._sourceMaxZoom){const r=s.zoom-this._sourceMaxZoom,n=s.zoom-r,o=s.x>>r,a=s.y>>r;i=this.getTileId(n,o,a)}}return i}_createCanvas(t,i){const s=t.createElement("canvas");return s.width=this._tileSize,s.height=this._tileSize,s.id=i,s}getTileId(t,i,s){return[t,i,s].join(":")}getTileObject(t){const i=t.split(":");return{zoom:i[0],x:i[1],y:i[2]}}_xhrRequest(t){const i=this,s=t.parentId||t.id,r=this.getTileObject(s),n=this._url.replace("{z}",r.zoom).replace("{x}",r.x).replace("{y}",r.y),o=new XMLHttpRequest;o.onload=function(){if(o.status=="200"&&o.response)return i._xhrResponseOk(t,o.response);i._drawDebugInfo(t)},o.open("GET",n,!0);for(const a in this._xhrHeaders)o.setRequestHeader(a,this._xhrHeaders[a]);o.responseType="arraybuffer",o.send()}_xhrResponseOk(t,i){if(this.map.getZoom()!=t.zoom)return;const s=new Uint8Array(i),r=new O(s),n=new gt(r);for(var o in n.layers){var a=n.layers[o];a.parsedFeatures=[];for(var h=a._features.length,u=0,l=h;u=0;l--){const d=u[l],f=this.mVTLayers[d];if(f){var t=f.handleClickEvent(t,this);if(this._mouseSelectedFeature(t,i,s),r&&t.feature)break}}}_mouseSelectedFeature(t,i,s){if(s.setSelected){const r=t.feature;r?s.mouseHover?r.selected||r.select():s.toggleSelection?r.toggle():r.selected||r.select():s.mouseHover&&this.deselectAllFeatures()}i(t)}deselectAllFeatures(){const t=this.map.getZoom(),i=[];for(const s in this._selectedFeatures){const r=this._selectedFeatures[s];if(!r)continue;r.setSelected(!1);const n=r.getTiles();for(const o in n)this.deleteTileDrawn(o),this.getTileObject(o).zoom==t&&(i[o]=!0)}this.redrawTiles(i),this._selectedFeatures=[]}featureSelected(t){this._multipleSelection||this.deselectAllFeatures(),this._selectedFeatures[t.featureId]=t}featureDeselected(t){delete this._selectedFeatures[t.featureId]}setSelectedFeatures(t){t.length>1&&(this._multipleSelection=!0),this.deselectAllFeatures();for(let i=0,s=t.length;i + + + + + + + + \ No newline at end of file