diff --git a/.gitmodules b/.gitmodules index e4578ea3d838a15ad6f118f147d6229a8fb8a14c..35f5da33d86ea2ced6a0902b3258f4466e8aeb24 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,9 @@ [submodule "deploy/asapo-worker-node-template"] path = deploy/asapo_worker_node_template url = ssh://yakubov@stash.desy.de:7999/asapo/asapo-worker-node-template.git +[submodule "deploy/deploy/asapo_worker_node_template"] + path = deploy/deploy/asapo_worker_node_template + url = ssh://git@stash.desy.de:7999/asapo/asapo-worker-node-template.git +[submodule "deploy/asapo_worker_node_template"] + path = deploy/asapo_worker_node_template + url = ssh://git@stash.desy.de:7999/asapo/asapo-worker-node-template.git diff --git a/CHANGELOG.md b/CHANGELOG.md index 49c02511045fc1b517a094465e60cd2a76f8fc0f..145802fbf37fd8986d0fb34ae34c4c08c1d11fc2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,7 @@ -## 21.12.1 (in progress) +## 22.03.0 (in progress) + +FEATURES +* Monitoring: Added detailed monitoring and pipeline visualization IMPROVEMENTS * renamed and hid C++ macros from client code diff --git a/CMakeIncludes/dependencies.cmake b/CMakeIncludes/dependencies.cmake index 38e74c10a268be2f44778cb3e428a76ae12c2ac8..c56ecdd52890c0c84d5836b36dfcf732fc069bd3 100644 --- a/CMakeIncludes/dependencies.cmake +++ b/CMakeIncludes/dependencies.cmake @@ -1,3 +1,5 @@ +set(CMAKE_POLICY_DEFAULT_CMP0074 NEW) #allow use package_ROOT variable to find package + if (BUILD_PYTHON) set(BUILD_PYTHON_PACKAGES "" CACHE STRING "which python packages to build") set_property(CACHE BUILD_PYTHON_PACKAGES PROPERTY STRINGS source rpm deb win) diff --git a/CMakeIncludes/grpc_common.cmake b/CMakeIncludes/grpc_common.cmake new file mode 100644 index 0000000000000000000000000000000000000000..ace27c0cfedc7c4552c41f5d707cc1d5965083cc --- /dev/null +++ b/CMakeIncludes/grpc_common.cmake @@ -0,0 +1,123 @@ +# Copyright 2018 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# cmake build file for C++ route_guide example. +# Assumes protobuf and gRPC have been installed using cmake. +# See cmake_externalproject/CMakeLists.txt for all-in-one cmake build +# that automatically builds all the dependencies before building route_guide. + +cmake_minimum_required(VERSION 3.5.1) + +set (CMAKE_CXX_STANDARD 11) + +if(MSVC) + add_definitions(-D_WIN32_WINNT=0x600) +endif() + +find_package(Threads REQUIRED) + +if(GRPC_AS_SUBMODULE) + # One way to build a projects that uses gRPC is to just include the + # entire gRPC project tree via "add_subdirectory". + # This approach is very simple to use, but the are some potential + # disadvantages: + # * it includes gRPC's CMakeLists.txt directly into your build script + # without and that can make gRPC's internal setting interfere with your + # own build. + # * depending on what's installed on your system, the contents of submodules + # in gRPC's third_party/* might need to be available (and there might be + # additional prerequisites required to build them). Consider using + # the gRPC_*_PROVIDER options to fine-tune the expected behavior. + # + # A more robust approach to add dependency on gRPC is using + # cmake's ExternalProject_Add (see cmake_externalproject/CMakeLists.txt). + + # Include the gRPC's cmake build (normally grpc source code would live + # in a git submodule called "third_party/grpc", but this example lives in + # the same repository as gRPC sources, so we just look a few directories up) + add_subdirectory(../../../.. ${CMAKE_CURRENT_BINARY_DIR}/grpc EXCLUDE_FROM_ALL) + message(STATUS "Using gRPC via add_subdirectory.") + + # After using add_subdirectory, we can now use the grpc targets directly from + # this build. + set(_PROTOBUF_LIBPROTOBUF libprotobuf) + set(_REFLECTION grpc++_reflection) + if(CMAKE_CROSSCOMPILING) + find_program(_PROTOBUF_PROTOC protoc) + else() + set(_PROTOBUF_PROTOC $<TARGET_FILE:protobuf::protoc>) + endif() + set(_GRPC_GRPCPP grpc++) + if(CMAKE_CROSSCOMPILING) + find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin) + else() + set(_GRPC_CPP_PLUGIN_EXECUTABLE $<TARGET_FILE:grpc_cpp_plugin>) + endif() +elseif(GRPC_FETCHCONTENT) + # Another way is to use CMake's FetchContent module to clone gRPC at + # configure time. This makes gRPC's source code available to your project, + # similar to a git submodule. + message(STATUS "Using gRPC via add_subdirectory (FetchContent).") + include(FetchContent) + FetchContent_Declare( + grpc + GIT_REPOSITORY https://github.com/grpc/grpc.git + # when using gRPC, you will actually set this to an existing tag, such as + # v1.25.0, v1.26.0 etc.. + # For the purpose of testing, we override the tag used to the commit + # that's currently under test. + GIT_TAG vGRPC_TAG_VERSION_OF_YOUR_CHOICE) + FetchContent_MakeAvailable(grpc) + + # Since FetchContent uses add_subdirectory under the hood, we can use + # the grpc targets directly from this build. + set(_PROTOBUF_LIBPROTOBUF libprotobuf) + set(_REFLECTION grpc++_reflection) + set(_PROTOBUF_PROTOC $<TARGET_FILE:protoc>) + set(_GRPC_GRPCPP grpc++) + if(CMAKE_CROSSCOMPILING) + find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin) + else() + set(_GRPC_CPP_PLUGIN_EXECUTABLE $<TARGET_FILE:grpc_cpp_plugin>) + endif() +else() + # This branch assumes that gRPC and all its dependencies are already installed + # on this system, so they can be located by find_package(). + + # Find Protobuf installation + # Looks for protobuf-config.cmake file installed by Protobuf's cmake installation. + set(protobuf_MODULE_COMPATIBLE TRUE) + find_package(Protobuf REQUIRED) + message(STATUS "Using protobuf ${Protobuf_VERSION}") + + set(_PROTOBUF_LIBPROTOBUF protobuf::libprotobuf) + set(_REFLECTION gRPC::grpc++_reflection) + if(CMAKE_CROSSCOMPILING) + find_program(_PROTOBUF_PROTOC protoc) + else() + set(_PROTOBUF_PROTOC $<TARGET_FILE:protobuf::protoc>) + endif() + + # Find gRPC installation + # Looks for gRPCConfig.cmake file installed by gRPC's cmake installation. + find_package(gRPC REQUIRED) + message(STATUS "Using gRPC ${gRPC_VERSION}") + + set(_GRPC_GRPCPP gRPC::grpc++) + if(CMAKE_CROSSCOMPILING) + find_program(_GRPC_CPP_PLUGIN_EXECUTABLE grpc_cpp_plugin) + else() + set(_GRPC_CPP_PLUGIN_EXECUTABLE $<TARGET_FILE:gRPC::grpc_cpp_plugin>) + endif() +endif() diff --git a/CMakeLists.txt b/CMakeLists.txt index 4e5c19ed460f2603f3da25c8e9ecce4250378aa6..bd9045166a6b3cf41111851355cc6c92c53a451a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,13 +4,13 @@ project(ASAPO) set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMakeModules/ ${PROJECT_SOURCE_DIR}/CMakeIncludes/) #protocol version changes if one of the microservice API's change -set (ASAPO_CONSUMER_PROTOCOL "v0.5") -set (ASAPO_PRODUCER_PROTOCOL "v0.5") +set (ASAPO_CONSUMER_PROTOCOL "v0.6") +set (ASAPO_PRODUCER_PROTOCOL "v0.6") set (ASAPO_DISCOVERY_API_VER "v0.1") set (ASAPO_AUTHORIZER_API_VER "v0.2") -set (ASAPO_BROKER_API_VER "v0.5") +set (ASAPO_BROKER_API_VER "v0.6") set (ASAPO_FILE_TRANSFER_SERVICE_API_VER "v0.2") -set (ASAPO_RECEIVER_API_VER "v0.5") +set (ASAPO_RECEIVER_API_VER "v0.6") set (ASAPO_RDS_API_VER "v0.1") set (DB_SCHEMA_VER "v0.1") @@ -44,6 +44,8 @@ option(BUILD_ASAPO_SITE "Build the asapo web site" OFF) option(ENABLE_LIBFABRIC "Enables LibFabric support for RDMA transfers" OFF) option(ENABLE_LIBFABRIC_LOCALHOST "Emulates LibFabric stack over TCP. Only for localhost and testing purposes." OFF) +option(ENABLE_NEW_RECEIVER_MONITORING "Enables the new monitoring for the receiver, but requires gRPC" OFF) + option(BUILD_SHARED_CLIENT_LIBS "Build shared consumer and producer libs" ON) option(BUILD_STATIC_CLIENT_LIBS "Build static consumer and producer libs" ON) @@ -72,6 +74,7 @@ if (NOT BUILD_CLIENTS_ONLY) add_subdirectory(authorizer) add_subdirectory(asapo_tools) add_subdirectory(file_transfer) + add_subdirectory(monitoring) endif() add_subdirectory(deploy) diff --git a/CMakeModules/prepare_asapo.cmake b/CMakeModules/prepare_asapo.cmake index e2badd2b9ca9e49bfd2414f7da3e431a3a12cf21..19f35fce705cf4c1711fffe80aaa0174aa54ee97 100644 --- a/CMakeModules/prepare_asapo.cmake +++ b/CMakeModules/prepare_asapo.cmake @@ -4,6 +4,7 @@ function(prepare_asapo) get_target_property(DISCOVERY_FULLPATH asapo-discovery EXENAME) get_target_property(AUTHORIZER_FULLPATH asapo-authorizer EXENAME) get_target_property(FILE_TRANSFER_FULLPATH asapo-file-transfer EXENAME) + get_target_property(MONITORING_SERVER_FULLPATH asapo-monitoring-server EXENAME) get_target_property(BROKER_FULLPATH asapo-broker EXENAME) set(WORK_DIR ${CMAKE_CURRENT_BINARY_DIR}) @@ -34,6 +35,11 @@ function(prepare_asapo) configure_file(${CMAKE_SOURCE_DIR}/tests/automatic/settings/receiver_fabric.json.tpl.lin.in receiver_fabric.json.tpl @ONLY) configure_file(${CMAKE_SOURCE_DIR}/tests/automatic/settings/receiver_kafka.json.tpl.lin.in receiver_kafka.json.tpl @ONLY) configure_file(${CMAKE_SOURCE_DIR}/tests/automatic/settings/authorizer_settings.json.tpl.lin authorizer.json.tpl COPYONLY) + + configure_file(${CMAKE_SOURCE_DIR}/tests/automatic/settings/monitoring_server_settings.json.tpl monitoring_server.json.tpl COPYONLY) + configure_file(${CMAKE_SOURCE_DIR}/config/nomad/monitoring.nmd.in monitoring.nmd @ONLY) + + configure_file(${CMAKE_SOURCE_DIR}/tests/automatic/common_scripts/start_services.sh start_services.sh COPYONLY) configure_file(${CMAKE_SOURCE_DIR}/tests/automatic/common_scripts/stop_services.sh stop_services.sh COPYONLY) diff --git a/CMakeModules/testing_cpp.cmake b/CMakeModules/testing_cpp.cmake index 63dae68e4cf2c706b2a245cbbbd8ef8de9419126..afef4dfa7f1b63cecad2ecf1b1ad188a9724d87f 100644 --- a/CMakeModules/testing_cpp.cmake +++ b/CMakeModules/testing_cpp.cmake @@ -21,7 +21,7 @@ if (BUILD_TESTS) find_package(Threads) find_program(MEMORYCHECK_COMMAND valgrind) set(MEMORYCHECK_COMMAND_OPTIONS - "--trace-children=yes --leak-check=full --error-exitcode=1 --suppressions=${CMAKE_SOURCE_DIR}/tests/valgrind.suppressions") + "--trace-children=yes --leak-check=full --error-exitcode=1 --num-callers=20 --suppressions=${CMAKE_SOURCE_DIR}/tests/valgrind.suppressions") if (NOT "$ENV{gtest_SOURCE_DIR}" STREQUAL "") set(gtest_SOURCE_DIR $ENV{gtest_SOURCE_DIR}) endif () diff --git a/CMakeModules/testing_go.cmake b/CMakeModules/testing_go.cmake index 465736a5db40cbfb1146b1e8c66779c27b603b2c..4842808b751e5198e831059ea645e83f2c890125 100644 --- a/CMakeModules/testing_go.cmake +++ b/CMakeModules/testing_go.cmake @@ -6,7 +6,7 @@ if (BUILD_TESTS) set(ASAPO_MINIMUM_COVERAGE 80) find_program(MEMORYCHECK_COMMAND valgrind) set(MEMORYCHECK_COMMAND_OPTIONS - "--trace-children=yes --leak-check=full --error-exitcode=1 --suppressions=${CMAKE_SOURCE_DIR}/tests/valgrind.suppressions") + "--trace-children=yes --leak-check=full --error-exitcode=1 --num-callers=20 --suppressions=${CMAKE_SOURCE_DIR}/tests/valgrind.suppressions") endif () function(gotest target source_dir test_source_files) diff --git a/PROTOCOL-VERSIONS.md b/PROTOCOL-VERSIONS.md index af6342b023fe0a1d510da0de8d8485acd4c0add5..77f43856c855c147a2d3985aa42aebdf8547010b 100644 --- a/PROTOCOL-VERSIONS.md +++ b/PROTOCOL-VERSIONS.md @@ -1,18 +1,20 @@ ### Producer Protocol | Release | used by client | Supported by server | Status | | ------------ | ------------------- | -------------------- | ---------------- | -| v0.5 | 21.12.0 - 21.12.0 | 21.12.0 - 21.12.0 | Current version | -| v0.4 | 21.09.0 - 21.09.0 | 21.09.0 - 21.12.0 | Deprecates from 01.12.2022 | -| v0.3 | 21.06.0 - 21.06.0 | 21.06.0 - 21.12.0 | Deprecates from 01.09.2022 | -| v0.2 | 21.03.2 - 21.03.2 | 21.03.2 - 21.12.0 | Deprecates from 01.07.2022 | -| v0.1 | 21.03.0 - 21.03.1 | 21.03.0 - 21.12.0 | Deprecates from 01.06.2022 | +| v0.6 | 22.03.0 - 22.03.0 | 22.03.0 - 22.03.0 | Current version | +| v0.5 | 21.12.0 - 21.12.0 | 21.12.0 - 22.03.0 | Deprecates from 01.03.2023 | +| v0.4 | 21.09.0 - 21.09.0 | 21.09.0 - 22.03.0 | Deprecates from 01.12.2022 | +| v0.3 | 21.06.0 - 21.06.0 | 21.06.0 - 22.03.0 | Deprecates from 01.09.2022 | +| v0.2 | 21.03.2 - 21.03.2 | 21.03.2 - 22.03.0 | Deprecates from 01.07.2022 | +| v0.1 | 21.03.0 - 21.03.1 | 21.03.0 - 22.03.0 | Deprecates from 01.06.2022 | ### Consumer Protocol | Release | used by client | Supported by server | Status | | ------------ | ------------------- | -------------------- | ---------------- | -| v0.5 | 21.12.0 - 21.12.0 | 21.12.0 - 21.12.0 | Current version | -| v0.4 | 21.06.0 - 21.09.0 | 21.06.0 - 21.12.0 | Deprecates from 01.12.2022 | -| v0.3 | 21.03.3 - 21.03.3 | 21.03.3 - 21.12.0 | Deprecates from 01.07.2022 | -| v0.2 | 21.03.2 - 21.03.2 | 21.03.2 - 21.12.0 | Deprecates from 01.06.2022 | -| v0.1 | 21.03.0 - 21.03.1 | 21.03.0 - 21.12.0 | Deprecates from 01.06.2022 | +| v0.6 | 21.12.0 - 21.12.0 | 22.03.0 - 22.03.0 | Current version | +| v0.5 | 21.12.0 - 21.12.0 | 21.12.0 - 22.03.0 | Deprecates from 01.03.2023 | +| v0.4 | 21.06.0 - 21.09.0 | 21.06.0 - 22.03.0 | Deprecates from 01.12.2022 | +| v0.3 | 21.03.3 - 21.03.3 | 21.03.3 - 22.03.0 | Deprecates from 01.07.2022 | +| v0.2 | 21.03.2 - 21.03.2 | 21.03.2 - 22.03.0 | Deprecates from 01.06.2022 | +| v0.1 | 21.03.0 - 21.03.1 | 21.03.0 - 22.03.0 | Deprecates from 01.06.2022 | diff --git a/VERSIONS.md b/VERSIONS.md index 7741bbdbe245155f3b74e489e3364e663dcd339f..a4c8df08fd80fa04d2a56b89af531c233057aa73 100644 --- a/VERSIONS.md +++ b/VERSIONS.md @@ -2,25 +2,27 @@ | Release | API changed\*\* | Protocol | Supported by server from/to | Status |Comment| | ------------ | ----------- | -------- | ------------------------- | --------------------- | ------- | -| 21.12.0 | Yes | v0.5 | 21.12.0/21.12.0 | current version | | -| 21.09.0 | Yes | v0.4 | 21.09.0/21.12.0 | deprecates 01.12.2022 |beamline token for raw | -| 21.06.0 | Yes | v0.3 | 21.06.0/21.12.0 | deprecates 01.09.2022 |arbitrary characters| -| 21.03.3 | No | v0.2 | 21.03.2/21.12.0 | deprecates 01.07.2022 |bugfix in server| -| 21.03.2 | Yes | v0.2 | 21.03.2/21.12.0 | deprecates 01.07.2022 |bugfixes, add delete_stream| -| 21.03.1 | No | v0.1 | 21.03.0/21.12.0 | deprecates 01.06.2022 |bugfix in server| -| 21.03.0 | Yes | v0.1 | 21.03.0/21.12.0 | deprecates 01.06.2022 | | +| 22.03.0 | Yes | v0.6 | 22.03.0/22.03.0 | current version | | +| 21.12.0 | Yes | v0.5 | 21.12.0/22.03.0 | deprecates 01.03.2023 | | +| 21.09.0 | Yes | v0.4 | 21.09.0/22.03.0 | deprecates 01.12.2022 |beamline token for raw | +| 21.06.0 | Yes | v0.3 | 21.06.0/22.03.0 | deprecates 01.09.2022 |arbitrary characters| +| 21.03.3 | No | v0.2 | 21.03.2/22.03.0 | deprecates 01.07.2022 |bugfix in server| +| 21.03.2 | Yes | v0.2 | 21.03.2/22.03.0 | deprecates 01.07.2022 |bugfixes, add delete_stream| +| 21.03.1 | No | v0.1 | 21.03.0/22.03.0 | deprecates 01.06.2022 |bugfix in server| +| 21.03.0 | Yes | v0.1 | 21.03.0/22.03.0 | deprecates 01.06.2022 | | ### Consumer API | Release | API changed\*\* | Protocol | Supported by server from/to | Status |Comment| | ------------ | ----------- | --------- | ------------------------- | ---------------- | ------- | -| 21.12.0 | Yes | v0.5 | 21.12.0/21.12.0 | current version | | -| 21.09.0 | No | v0.4 | 21.06.0/21.12.0 | deprecates 01.12.2022 | | -| 21.06.0 | Yes | v0.4 | 21.06.0/21.12.0 | deprecates 01.09.2022 |arbitrary characters, bugfixes | -| 21.03.3 | Yes | v0.3 | 21.03.3/21.12.0 | deprecates 01.06.2022 |bugfix in server, error type for dublicated ack| -| 21.03.2 | Yes | v0.2 | 21.03.2/21.12.0 | deprecates 01.06.2022 |bugfixes, add delete_stream| -| 21.03.1 | No | v0.1 | 21.03.0/21.12.0 | deprecates 01.06.2022 |bugfix in server| -| 21.03.0 | Yes | v0.1 | 21.03.0/21.12.0 | deprecates 01.06.2022 | | +| 22.03.0 | Yes | v0.6 | 22.03.0/22.03.0 | current version | | +| 21.12.0 | Yes | v0.5 | 21.12.0/22.03.0 | deprecates 01.03.2023 | | +| 21.09.0 | No | v0.4 | 21.06.0/22.03.0 | deprecates 01.12.2022 | | +| 21.06.0 | Yes | v0.4 | 21.06.0/22.03.0 | deprecates 01.09.2022 |arbitrary characters, bugfixes | +| 21.03.3 | Yes | v0.3 | 21.03.3/22.03.0 | deprecates 01.06.2022 |bugfix in server, error type for dublicated ack| +| 21.03.2 | Yes | v0.2 | 21.03.2/22.03.0 | deprecates 01.06.2022 |bugfixes, add delete_stream| +| 21.03.1 | No | v0.1 | 21.03.0/22.03.0 | deprecates 01.06.2022 |bugfix in server| +| 21.03.0 | Yes | v0.1 | 21.03.0/22.03.0 | deprecates 01.06.2022 | | \* insignificant changes/bugfixes (e.g. in return type, etc), normally do not require client code changes, but formally might break the client diff --git a/asapo_tools/src/asapo_tools/go.sum b/asapo_tools/src/asapo_tools/go.sum index 3e9dd5cbe821c458765373bc58e66d087906c706..b19ef01c7ad92a65a13218d73cd9862a27ec62a6 100644 --- a/asapo_tools/src/asapo_tools/go.sum +++ b/asapo_tools/src/asapo_tools/go.sum @@ -1,10 +1,46 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -13,14 +49,75 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/sirupsen/logrus v1.8.0/go.mod h1:4GuYW9TZmE769R5STWrRakJc4UqQ3+QQ95fyz7ENv1A= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.39.0 h1:Klz8I9kdtkIN6EpHHUOMLCYhTn/2WAe5a0s1hcBkdTI= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/authorizer/src/asapo_authorizer/common/structs.go b/authorizer/src/asapo_authorizer/common/structs.go index ca2a6de00c0f7c82371580343293eae2a097ca80..ddbdd550457c9050cd125d752c9a0777f06fe00e 100644 --- a/authorizer/src/asapo_authorizer/common/structs.go +++ b/authorizer/src/asapo_authorizer/common/structs.go @@ -1,6 +1,6 @@ package common -type BeamtimeMeta struct { +type BeamtimeMeta struct { BeamtimeId string `json:"beamtimeId"` Beamline string `json:"beamline"` DataSource string `json:"dataSource"` @@ -8,9 +8,11 @@ type BeamtimeMeta struct { OnlinePath string `json:"beamline-path"` Type string `json:"source-type"` AccessTypes []string `json:"access-types"` + InstanceId string `json:"instanceId,omitempty"` + PipelineStep string `json:"pipelineStep,omitempty"` } -type CommissioningMeta struct { +type CommissioningMeta struct { Id string `json:"id"` Beamline string `json:"beamline"` OfflinePath string `json:"corePath"` diff --git a/authorizer/src/asapo_authorizer/go.sum b/authorizer/src/asapo_authorizer/go.sum index f9db70a3f9f6979312428952e43576663fda2592..abb1a1cd684b3fcbc65f137c5f6533fe3036eac4 100644 --- a/authorizer/src/asapo_authorizer/go.sum +++ b/authorizer/src/asapo_authorizer/go.sum @@ -1,9 +1,25 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-ldap/ldap v3.0.3+incompatible h1:HTeSZO8hWMS1Rgb2Ziku6b8a7qRIZZMHjsvuZyatzwk= github.com/go-ldap/ldap v3.0.3+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= @@ -32,12 +48,32 @@ github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWe github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= @@ -63,6 +99,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -80,6 +118,7 @@ github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -95,18 +134,35 @@ github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= go.mongodb.org/mongo-driver v1.7.2 h1:pFttQyIiJUHEn50YfZgC9ECjITMT44oiN36uArf/OFg= go.mongodb.org/mongo-driver v1.7.2/go.mod h1:Q4oFMbo1+MSNqICAdYMlC/zSTrwCogR4R8NzkI+yfU8= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= -golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 h1:xMPOj6Pz6UipU1wXLkrtqpHbR0AVFnyPEQq/wRWz9lM= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -114,24 +170,56 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d h1:TxyelI5cVkbREznMhfzycHdkp5cLA7DpE+GKjSslYhM= gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/authorizer/src/asapo_authorizer/server/authorize.go b/authorizer/src/asapo_authorizer/server/authorize.go index d5192fb9803b0df5dafe05c44e2ed0651903c794..42927d0a0737b1ecb019b0222620f22553f42b41 100644 --- a/authorizer/src/asapo_authorizer/server/authorize.go +++ b/authorizer/src/asapo_authorizer/server/authorize.go @@ -17,6 +17,10 @@ type SourceCredentials struct { DataSource string Token string Type string + + // Optional + InstanceId string `json:",omitempty"` + PipelineStep string `json:",omitempty"` } type authorizationRequest struct { @@ -25,15 +29,27 @@ type authorizationRequest struct { } func getSourceCredentials(request authorizationRequest) (SourceCredentials, error) { - vals := strings.Split(request.SourceCredentials, "%") nvals := len(vals) - if nvals < 5 { + if nvals < 7 { return SourceCredentials{}, errors.New("cannot get source credentials from " + request.SourceCredentials) } - creds := SourceCredentials{Type: vals[0], BeamtimeId: vals[1], Beamline: vals[2], Token: vals[nvals-1]} - creds.DataSource = strings.Join(vals[3:nvals-1], "%") + var creds SourceCredentials + + creds = SourceCredentials{ + Type: vals[0], + InstanceId: vals[1], PipelineStep: vals[2], + BeamtimeId: vals[3], Beamline: vals[4], Token: vals[nvals-1]} + creds.DataSource = strings.Join(vals[5:nvals-1], "%") + if creds.InstanceId == "" { + creds.InstanceId = "auto" + } + + if creds.PipelineStep == "" { + creds.PipelineStep = "auto" + } + if creds.DataSource == "" { creds.DataSource = "detector" } @@ -46,6 +62,15 @@ func getSourceCredentials(request authorizationRequest) (SourceCredentials, erro creds.BeamtimeId = "auto" } + log.WithFields(map[string]interface{}{ + "creds": request.SourceCredentials, + }).Debug("received credentials") + + + if creds.InstanceId == "auto" || creds.PipelineStep == "auto" { + return SourceCredentials{}, errors.New("InstanceId and PipelineStep must be already set on client side") + } + if creds.BeamtimeId == "auto" && creds.Beamline == "auto" { return SourceCredentials{}, errors.New("cannot automaticaly detect both beamline and beamtime_id ") } @@ -90,7 +115,7 @@ func beamtimeMetaFromMatch(match string) (common.BeamtimeMeta, error) { var bt common.BeamtimeMeta ignoredFoldersAfterGpfs := []string{"common", "BeamtimeUsers", "state", "support"} if utils.StringInSlice(vars[2], ignoredFoldersAfterGpfs) { - return common.BeamtimeMeta{}, errors.New("skipped fodler") + return common.BeamtimeMeta{}, errors.New("skipped folder") } bt.OfflinePath = common.Settings.RootBeamtimesFolder + string(filepath.Separator) + match @@ -178,9 +203,11 @@ func findBeamtimeMetaFromBeamline(beamline string, iscommissioning bool) (meta c func alwaysAllowed(creds SourceCredentials) (common.BeamtimeMeta, bool) { for _, pair := range common.Settings.AlwaysAllowedBeamtimes { if pair.BeamtimeId == creds.BeamtimeId { + pair.InstanceId = creds.InstanceId + pair.PipelineStep = creds.PipelineStep pair.DataSource = creds.DataSource pair.Type = creds.Type - pair.AccessTypes = []string{"read", "write","writeraw"} + pair.AccessTypes = []string{"read", "write", "writeraw"} return pair, true } } @@ -278,6 +305,8 @@ func findMeta(creds SourceCredentials) (common.BeamtimeMeta, error) { return common.BeamtimeMeta{}, err } + meta.InstanceId = creds.InstanceId + meta.PipelineStep = creds.PipelineStep meta.DataSource = creds.DataSource meta.Type = creds.Type @@ -331,12 +360,12 @@ func authorize(request authorizationRequest, creds SourceCredentials) (common.Be meta.AccessTypes = accessTypes log.WithFields(map[string]interface{}{ - "beamline":creds.Beamline, - "beamtime":creds.BeamtimeId, - "origin":request.OriginHost, - "type":meta.Type, - "onlinePath":meta.OnlinePath, - "offlinePath":meta.OfflinePath, + "beamline": creds.Beamline, + "beamtime": creds.BeamtimeId, + "origin": request.OriginHost, + "type": meta.Type, + "onlinePath": meta.OnlinePath, + "offlinePath": meta.OfflinePath, }).Debug("authorized credentials") return meta, nil } diff --git a/authorizer/src/asapo_authorizer/server/authorize_test.go b/authorizer/src/asapo_authorizer/server/authorize_test.go index e3bb6c11e23b699adc034354b57ced49ca63143e..38e79b31f04045adbb4393763e48535c65693cda 100644 --- a/authorizer/src/asapo_authorizer/server/authorize_test.go +++ b/authorizer/src/asapo_authorizer/server/authorize_test.go @@ -77,23 +77,28 @@ func doPostRequest(path string, buf string, authHeader string) *httptest.Respons } var credTests = []struct { - request string - cred SourceCredentials - ok bool - message string + request string + cred SourceCredentials + ok bool + message string }{ - {"processed%asapo_test%auto%%", SourceCredentials{"asapo_test", "auto", "detector", "", "processed"}, true, "auto beamline, source and no token"}, - {"processed%asapo_test%auto%%token", SourceCredentials{"asapo_test", "auto", "detector", "token", "processed"}, true, "auto beamline, source"}, - {"processed%asapo_test%auto%source%", SourceCredentials{"asapo_test", "auto", "source", "", "processed"}, true, "auto beamline, no token"}, - {"processed%asapo_test%auto%source%token", SourceCredentials{"asapo_test", "auto", "source", "token", "processed"}, true, "auto beamline,source, token"}, - {"processed%asapo_test%beamline%source%token", SourceCredentials{"asapo_test", "beamline", "source", "token", "processed"}, true, "all set"}, - {"processed%auto%beamline%source%token", SourceCredentials{"auto", "beamline", "source", "token", "processed"}, true, "auto beamtime"}, - {"raw%auto%auto%source%token", SourceCredentials{}, false, "auto beamtime and beamline"}, - {"raw%%beamline%source%token", SourceCredentials{"auto", "beamline", "source", "token", "raw"}, true, "empty beamtime"}, - {"raw%asapo_test%%source%token", SourceCredentials{"asapo_test", "auto", "source", "token", "raw"}, true, "empty bealine"}, - {"raw%%%source%token", SourceCredentials{}, false, "both empty"}, - {"processed%asapo_test%beamline%source%blabla%token", SourceCredentials{"asapo_test", "beamline", "source%blabla", "token", "processed"}, true, "% in source"}, - {"processed%asapo_test%beamline%source%blabla%", SourceCredentials{"asapo_test", "beamline", "source%blabla", "", "processed"}, true, "% in source, no token"}, + { "processed%instance%step%asapo_test%auto%%", SourceCredentials{"asapo_test", "auto", "detector", "", "processed", "instance", "step"}, true, "auto beamline, source and no token"}, + { "processed%instance%step%asapo_test%auto%%token", SourceCredentials{"asapo_test", "auto", "detector", "token", "processed", "instance", "step"}, true, "auto beamline, source"}, + { "processed%instance%step%asapo_test%auto%source%", SourceCredentials{"asapo_test", "auto", "source", "", "processed", "instance", "step"}, true, "auto beamline, no token"}, + { "processed%instance%step%asapo_test%auto%source%token", SourceCredentials{"asapo_test", "auto", "source", "token", "processed", "instance", "step"}, true, "auto beamline,source, token"}, + { "processed%instance%step%asapo_test%beamline%source%token", SourceCredentials{"asapo_test", "beamline", "source", "token", "processed", "instance", "step"}, true, "all set"}, + { "processed%instance%step%auto%beamline%source%token", SourceCredentials{"auto", "beamline", "source", "token", "processed", "instance", "step"}, true, "auto beamtime"}, + { "raw%instance%step%auto%auto%source%token", SourceCredentials{}, false, "auto beamtime and beamline"}, + { "raw%instance%step%%beamline%source%token", SourceCredentials{"auto", "beamline", "source", "token", "raw", "instance", "step"}, true, "empty beamtime"}, + { "raw%instance%step%asapo_test%%source%token", SourceCredentials{"asapo_test", "auto", "source", "token", "raw", "instance", "step"}, true, "empty bealine"}, + { "raw%instance%step%%%source%token", SourceCredentials{}, false, "both empty"}, + { "processed%instance%step%asapo_test%beamline%source%blabla%token", SourceCredentials{"asapo_test", "beamline", "source%blabla", "token", "processed", "instance", "step"}, true, "% in source"}, + { "processed%instance%step%asapo_test%beamline%source%blabla%", SourceCredentials{"asapo_test", "beamline", "source%blabla", "", "processed", "instance", "step"}, true, "% in source, no token"}, + { "processed%instance%step%asapo_test%beamline%source%blabla%", SourceCredentials{"asapo_test", "beamline", "source%blabla", "", "processed", "instance", "step"}, true, "new format: % in source, no token"}, + { "processed%auto%step%asapo_test%beamline%source%blabla%", SourceCredentials{"asapo_test", "beamline", "source%blabla", "", "processed", "auto", "step"}, false, "new format: auto instance"}, + { "processed%instance%auto%asapo_test%beamline%source%blabla%", SourceCredentials{"asapo_test", "beamline", "source%blabla", "", "processed", "instance", "auto"}, false, "new format: auto step"}, + { "processed%%auto%asapo_test%beamline%source%blabla%", SourceCredentials{"asapo_test", "beamline", "source%blabla", "", "processed", "", "auto"}, false, "new format: missing instance"}, + { "processed%instance%%asapo_test%beamline%source%blabla%", SourceCredentials{"asapo_test", "beamline", "source%blabla", "", "processed", "instance", ""}, false, "new format: missing step"}, } func TestSplitCreds(t *testing.T) { @@ -112,8 +117,8 @@ func TestSplitCreds(t *testing.T) { } func TestAuthorizeDefaultOK(t *testing.T) { - allowBeamlines([]common.BeamtimeMeta{{"asapo_test", "beamline", "", "2019", "tf", "", nil}}) - request := makeRequest(authorizationRequest{"processed%asapo_test%%%", "host"}) + allowBeamlines([]common.BeamtimeMeta{{"asapo_test", "beamline", "", "2019", "tf", "", nil,"instance", "step"},}) + request := makeRequest(authorizationRequest{"processed%instance%step%asapo_test%%%", "host"}) w := doPostRequest("/authorize", request, "") body, _ := ioutil.ReadAll(w.Body) @@ -184,65 +189,74 @@ var commissioning_meta = ` ` var authTests = []struct { - source_type string - beamtime_id string - beamline string - dataSource string - token string - originHost string - status int - message string - answer string - mode int + source_type string + instance_id string + pipeline_step string + beamtime_id string + beamline string + dataSource string + token string + originHost string + status int + message string + answer string + mode int }{ - {"processed", "test", "auto", "dataSource", prepareAsapoToken("bt_test", nil), "127.0.0.2", http.StatusUnauthorized, "missing access types", + { "processed", "instance", "step", "test", "auto", "dataSource", prepareAsapoToken("bt_test", nil), "127.0.0.2", http.StatusUnauthorized, "missing access types", "", 0}, - {"processed", "test", "auto", "dataSource", prepareAsapoToken("bt_test", []string{}), "127.0.0.2", http.StatusUnauthorized, "empty access types", + { "processed", "instance", "step", "test", "auto", "dataSource", prepareAsapoToken("bt_test", []string{}), "127.0.0.2", http.StatusUnauthorized, "empty access types", "", 0}, - {"processed", "test", "auto", "dataSource", prepareAsapoToken("bt_test", []string{"write"}), "127.0.0.2", http.StatusOK, "user source with correct token", - `{"beamtimeId":"test","beamline":"bl1","dataSource":"dataSource","corePath":"./tf/gpfs/bl1/2019/data/test","beamline-path":"","source-type":"processed","access-types":["write"]}`, 0}, - {"processed", "test", "auto", "dataSource", prepareAsapoToken("bt_test", []string{"write"}), "127.0.0.2", http.StatusUnauthorized, "token was revoked", + { "processed", "instance", "step", "test", "auto", "dataSource", prepareAsapoToken("bt_test", []string{"write"}), "127.0.0.2", http.StatusOK, "user source with correct token", + `{"beamtimeId":"test","beamline":"bl1","dataSource":"dataSource","corePath":"./tf/gpfs/bl1/2019/data/test","beamline-path":"","source-type":"processed","access-types":["write"],"instanceId":"instance","pipelineStep":"step"}`, 0}, + { "processed", "instance", "step", "test", "auto", "dataSource", prepareAsapoToken("bt_test", []string{"write"}), "127.0.0.2", http.StatusUnauthorized, "token was revoked", "", 2}, - {"processed", "test_online", "auto", "dataSource", prepareAsapoToken("bt_test_online", []string{"read"}), "127.0.0.1", http.StatusOK, "with online path, processed type", - `{"beamtimeId":"test_online","beamline":"bl1","dataSource":"dataSource","corePath":"./tf/gpfs/bl1/2019/data/test_online","beamline-path":"","source-type":"processed","access-types":["read"]}`, 0}, - {"processed", "test1", "auto", "dataSource", prepareAsapoToken("bt_test1", []string{"read"}), "127.0.0.1", http.StatusUnauthorized, "correct token, beamtime not found", + { "processed", "instance", "step", "test_online", "auto", "dataSource", prepareAsapoToken("bt_test_online", []string{"read"}), "127.0.0.1", http.StatusOK, "with online path, processed type", + `{"beamtimeId":"test_online","beamline":"bl1","dataSource":"dataSource","corePath":"./tf/gpfs/bl1/2019/data/test_online","beamline-path":"","source-type":"processed","access-types":["read"],"instanceId":"instance","pipelineStep":"step"}`, 0}, + { "processed", "instance", "step", "test1", "auto", "dataSource", prepareAsapoToken("bt_test1", []string{"read"}), "127.0.0.1", http.StatusUnauthorized, "correct token, beamtime not found", "", 1}, - {"processed", "test", "auto", "dataSource", prepareAsapoToken("wrong", []string{"read"}), "127.0.0.1", http.StatusUnauthorized, "user source with wrong token", + { "processed", "instance", "step", "test", "auto", "dataSource", prepareAsapoToken("wrong", []string{"read"}), "127.0.0.1", http.StatusUnauthorized, "user source with wrong token", "", 0}, - {"processed", "test", "bl1", "dataSource", prepareAsapoToken("bt_test", []string{"read"}), "127.0.0.1", http.StatusOK, "correct beamline given", - `{"beamtimeId":"test","beamline":"bl1","dataSource":"dataSource","corePath":"./tf/gpfs/bl1/2019/data/test","beamline-path":"","source-type":"processed","access-types":["read"]}`, 0}, - {"processed", "test", "bl2", "dataSource", prepareAsapoToken("bt_test", []string{"read"}), "127.0.0.1", http.StatusUnauthorized, "incorrect beamline given", + { "processed", "instance", "step", "test", "bl1", "dataSource", prepareAsapoToken("bt_test", []string{"read"}), "127.0.0.1", http.StatusOK, "correct beamline given", + `{"beamtimeId":"test","beamline":"bl1","dataSource":"dataSource","corePath":"./tf/gpfs/bl1/2019/data/test","beamline-path":"","source-type":"processed","access-types":["read"],"instanceId":"instance","pipelineStep":"step"}`, 0}, + { "processed", "instance", "step", "test", "bl2", "dataSource", prepareAsapoToken("bt_test", []string{"read"}), "127.0.0.1", http.StatusUnauthorized, "incorrect beamline given", "", 1}, - {"processed", "auto", "p07", "dataSource", prepareAsapoToken("bl_p07", []string{"read"}), "127.0.0.1", http.StatusOK, "beamtime found", - `{"beamtimeId":"11111111","beamline":"p07","dataSource":"dataSource","corePath":"asap3/petra3/gpfs/p07/2020/data/11111111","beamline-path":"","source-type":"processed","access-types":["read"]}`, 0}, - {"processed", "auto", "p07", "dataSource", prepareAsapoToken("bl_p06", []string{"read"}), "127.0.0.1", http.StatusUnauthorized, "wrong token", + { "processed", "instance", "step", "auto", "p07", "dataSource", prepareAsapoToken("bl_p07", []string{"read"}), "127.0.0.1", http.StatusOK, "beamtime found", + `{"beamtimeId":"11111111","beamline":"p07","dataSource":"dataSource","corePath":"asap3/petra3/gpfs/p07/2020/data/11111111","beamline-path":"","source-type":"processed","access-types":["read"],"instanceId":"instance","pipelineStep":"step"}`, 0}, + { "processed", "instance", "step", "auto", "p07", "dataSource", prepareAsapoToken("bl_p06", []string{"read"}), "127.0.0.1", http.StatusUnauthorized, "wrong token", "", 0}, - {"processed", "auto", "p08", "dataSource", prepareAsapoToken("bl_p08", []string{"read"}), "127.0.0.1", http.StatusUnauthorized, "beamtime not found", + { "processed", "instance", "step", "auto", "p08", "dataSource", prepareAsapoToken("bl_p08", []string{"read"}), "127.0.0.1", http.StatusUnauthorized, "beamtime not found", "", 1}, - {"raw", "test_online", "auto", "dataSource", "", "127.0.0.1", http.StatusOK, "raw type", - `{"beamtimeId":"test_online","beamline":"bl1","dataSource":"dataSource","corePath":"./tf/gpfs/bl1/2019/data/test_online","beamline-path":"./bl1/current","source-type":"raw","access-types":["read","write","writeraw"]}`, 0}, - {"raw", "test_online", "auto", "dataSource", "", "127.0.0.1", http.StatusOK, "raw type", - `{"beamtimeId":"test_online","beamline":"bl1","dataSource":"dataSource","corePath":"./tf/gpfs/bl1/2019/data/test_online","beamline-path":"./bl1/current","source-type":"raw","access-types":["read","write","writeraw"]}`, 0}, - {"raw", "auto", "p07", "dataSource", "", "127.0.0.1", http.StatusOK, "raw type, auto beamtime", - `{"beamtimeId":"11111111","beamline":"p07","dataSource":"dataSource","corePath":"asap3/petra3/gpfs/p07/2020/data/11111111","beamline-path":"./p07/current","source-type":"raw","access-types":["read","write","writeraw"]}`, 0}, - {"raw", "auto", "p07", "noldap", "", "127.0.0.1", http.StatusServiceUnavailable, "no conection to ldap", + { "raw", "instance", "step", "test_online", "auto", "dataSource", "", "127.0.0.1", http.StatusOK, "raw type", + `{"beamtimeId":"test_online","beamline":"bl1","dataSource":"dataSource","corePath":"./tf/gpfs/bl1/2019/data/test_online","beamline-path":"./bl1/current","source-type":"raw","access-types":["read","write","writeraw"],"instanceId":"instance","pipelineStep":"step"}`, 0}, + { "raw", "instance", "step", "test_online", "auto", "dataSource", "", "127.0.0.1", http.StatusOK, "raw type", + `{"beamtimeId":"test_online","beamline":"bl1","dataSource":"dataSource","corePath":"./tf/gpfs/bl1/2019/data/test_online","beamline-path":"./bl1/current","source-type":"raw","access-types":["read","write","writeraw"],"instanceId":"instance","pipelineStep":"step"}`, 0}, + { "raw", "instance", "step", "auto", "p07", "dataSource", "", "127.0.0.1", http.StatusOK, "raw type, auto beamtime", + `{"beamtimeId":"11111111","beamline":"p07","dataSource":"dataSource","corePath":"asap3/petra3/gpfs/p07/2020/data/11111111","beamline-path":"./p07/current","source-type":"raw","access-types":["read","write","writeraw"],"instanceId":"instance","pipelineStep":"step"}`, 0}, + { "raw", "instance", "step", "auto", "p07", "noldap", "", "127.0.0.1", http.StatusServiceUnavailable, "no conection to ldap", "", 0}, - {"raw", "auto", "p07", "dataSource", prepareAsapoToken("bl_p07", []string{"read", "writeraw"}), "127.0.0.2", http.StatusOK, "raw type with token", - `{"beamtimeId":"11111111","beamline":"p07","dataSource":"dataSource","corePath":"asap3/petra3/gpfs/p07/2020/data/11111111","beamline-path":"./p07/current","source-type":"raw","access-types":["read","writeraw"]}`, 0}, + { "raw", "instance", "step", "auto", "p07", "dataSource", prepareAsapoToken("bl_p07", []string{"read", "writeraw"}), "127.0.0.2", http.StatusOK, "raw type with token", + `{"beamtimeId":"11111111","beamline":"p07","dataSource":"dataSource","corePath":"asap3/petra3/gpfs/p07/2020/data/11111111","beamline-path":"./p07/current","source-type":"raw","access-types":["read","writeraw"],"instanceId":"instance","pipelineStep":"step"}`, 0}, - {"raw", "test_online", "auto", "dataSource", "", "127.0.0.2", http.StatusUnauthorized, "raw type, wrong origin host", + { "raw", "instance", "step", "test_online", "auto", "dataSource", "", "127.0.0.2", http.StatusUnauthorized, "raw type, wrong origin host", "", 0}, - {"raw", "test", "auto", "dataSource", prepareAsapoToken("bt_test", []string{"read"}), "127.0.0.1", http.StatusUnauthorized, "raw when not online", + { "raw", "instance", "step", "test", "auto", "dataSource", prepareAsapoToken("bt_test", []string{"read"}), "127.0.0.1", http.StatusUnauthorized, "raw when not online", "", 1}, - {"processed", "test", "auto", "dataSource", "", "127.0.0.1:1001", http.StatusOK, "processed without token", - `{"beamtimeId":"test","beamline":"bl1","dataSource":"dataSource","corePath":"./tf/gpfs/bl1/2019/data/test","beamline-path":"","source-type":"processed","access-types":["read","write"]}`, 0}, - {"processed", "test", "auto", "dataSource", "", "127.0.0.2", http.StatusUnauthorized, "processed without token, wrong host", + { "processed", "instance", "step", "test", "auto", "dataSource", "", "127.0.0.1:1001", http.StatusOK, "processed without token", + `{"beamtimeId":"test","beamline":"bl1","dataSource":"dataSource","corePath":"./tf/gpfs/bl1/2019/data/test","beamline-path":"","source-type":"processed","access-types":["read","write"],"instanceId":"instance","pipelineStep":"step"}`, 0}, + { "processed", "instance", "step", "test", "auto", "dataSource", "", "127.0.0.2", http.StatusUnauthorized, "processed without token, wrong host", "", 0}, - {"raw", "c20210823_000_MAA", "auto", "dataSource", "", "127.0.0.1", http.StatusOK, "raw type commissioning", - `{"beamtimeId":"c20210823_000_MAA","beamline":"p04","dataSource":"dataSource","corePath":"./tf/gpfs/p04/2019/commissioning/c20210823_000_MAA","beamline-path":"./p04/commissioning","source-type":"raw","access-types":["read","write","writeraw"]}`, 0}, - {"processed", "c20210823_000_MAA", "auto", "dataSource", "", "127.0.0.1", http.StatusOK, "processed type commissioning", - `{"beamtimeId":"c20210823_000_MAA","beamline":"p04","dataSource":"dataSource","corePath":"./tf/gpfs/p04/2019/commissioning/c20210823_000_MAA","beamline-path":"","source-type":"processed","access-types":["read","write"]}`, 0}, + { "raw", "instance", "step", "c20210823_000_MAA", "auto", "dataSource", "", "127.0.0.1", http.StatusOK, "raw type commissioning", + `{"beamtimeId":"c20210823_000_MAA","beamline":"p04","dataSource":"dataSource","corePath":"./tf/gpfs/p04/2019/commissioning/c20210823_000_MAA","beamline-path":"./p04/commissioning","source-type":"raw","access-types":["read","write","writeraw"],"instanceId":"instance","pipelineStep":"step"}`, 0}, + + { "processed", "instance", "step", "c20210823_000_MAA", "auto", "dataSource", "", "127.0.0.1", http.StatusOK, "processed type commissioning", + `{"beamtimeId":"c20210823_000_MAA","beamline":"p04","dataSource":"dataSource","corePath":"./tf/gpfs/p04/2019/commissioning/c20210823_000_MAA","beamline-path":"","source-type":"processed","access-types":["read","write"],"instanceId":"instance","pipelineStep":"step"}`, 0}, + + // Format testing + { "processed", "instance", "step", "test", "bl1", "dataSource", prepareAsapoToken("bt_test", []string{"read"}), "127.0.0.1", http.StatusOK, "old format: correct beamline given", + `{"beamtimeId":"test","beamline":"bl1","dataSource":"dataSource","corePath":"./tf/gpfs/bl1/2019/data/test","beamline-path":"","source-type":"processed","access-types":["read"],"instanceId":"instance","pipelineStep":"step"}`, 0}, + + } func TestAuthorize(t *testing.T) { @@ -301,8 +315,11 @@ func TestAuthorize(t *testing.T) { mockClient.On("GetAllowedIpsForBeamline", expected_uri, expected_base, expected_filter).Return(allowed_ips, nil) } } + var sourceString string + + sourceString = test.source_type + "%" + test.instance_id + "%" + test.pipeline_step + "%" + test.beamtime_id + "%" + test.beamline + "%" + test.dataSource + "%" + test.token - request := makeRequest(authorizationRequest{test.source_type + "%" + test.beamtime_id + "%" + test.beamline + "%" + test.dataSource + "%" + test.token, test.originHost}) + request := makeRequest(authorizationRequest{sourceString, test.originHost}) w := doPostRequest("/authorize", request, "") body, _ := ioutil.ReadAll(w.Body) @@ -322,7 +339,7 @@ func TestAuthorize(t *testing.T) { } func TestNotAuthorized(t *testing.T) { - request := makeRequest(authorizationRequest{"raw%any_id%%%", "host"}) + request := makeRequest(authorizationRequest{"raw%instance%step%any_id%%%", "host"}) w := doPostRequest("/authorize", request, "") assert.Equal(t, http.StatusUnauthorized, w.Code, "") } @@ -338,7 +355,7 @@ func TestAuthorizeWrongPath(t *testing.T) { } func TestDoNotAuthorizeIfNotInAllowed(t *testing.T) { - allowBeamlines([]common.BeamtimeMeta{{"test", "beamline", "", "2019", "tf", "", nil}}) + allowBeamlines([]common.BeamtimeMeta{{"test", "beamline", "", "2019", "tf", "", nil,"",""}}) request := authorizationRequest{"asapo_test%%", "host"} creds, _ := getSourceCredentials(request) @@ -391,7 +408,7 @@ func TestGetBeamtimeInfo(t *testing.T) { func TestExpiredToken(t *testing.T) { Auth = authorization.NewAuth(utils.NewJWTAuth("secret_user"), utils.NewJWTAuth("secret_admin"), utils.NewJWTAuth("secret")) token := "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MzU3NTMxMDksImp0aSI6ImMyOTR0NWFodHY1am9vZHVoaGNnIiwic3ViIjoiYnRfMTEwMTIxNzEiLCJFeHRyYUNsYWltcyI6eyJBY2Nlc3NUeXBlcyI6WyJyZWFkIiwid3JpdGUiXX19.kITePbv_dXY2ACxpAQ-PeQJPQtnR02bMoFrXq0Pbcm0" - request := authorizationRequest{"asapo_test%%"+token, "host"} + request := authorizationRequest{"asapo_test%%" + token, "host"} creds, _ := getSourceCredentials(request) creds.Token = token @@ -400,7 +417,7 @@ func TestExpiredToken(t *testing.T) { creds.Beamline = "p21.2" _, err := authorizeByToken(creds) assert.Error(t, err, "") - if (err!=nil) { + if err != nil { assert.Contains(t, err.Error(), "expired") } diff --git a/authorizer/src/asapo_authorizer/server/folder_token.go b/authorizer/src/asapo_authorizer/server/folder_token.go index 9e5c305e1b3f7edacf85110a7bbd537bbd6b7664..cb9559c3704dd60e5865cc10efa1c7c0ca012255 100644 --- a/authorizer/src/asapo_authorizer/server/folder_token.go +++ b/authorizer/src/asapo_authorizer/server/folder_token.go @@ -13,9 +13,13 @@ import ( ) type folderTokenRequest struct { - Folder string - BeamtimeId string - Token string + Folder string + BeamtimeId string + Token string + + // Optional + InstanceId string + PipelineStep string } type tokenFolders struct { @@ -63,12 +67,20 @@ func extractFolderTokenrequest(r *http.Request) (folderTokenRequest, error) { if len(request.Folder) == 0 || len(request.BeamtimeId) == 0 || len(request.Token) == 0 { return folderTokenRequest{}, errors.New("some request fields are empty") } + + if len(request.PipelineStep) == 0 { + request.InstanceId = "Unset" + } + if len(request.PipelineStep) == 0 { + request.PipelineStep = "Unset" + } + return request, nil } func checkBeamtimeFolder(request folderTokenRequest, ver utils.VersionNum) (folders tokenFolders, err error) { - beamtimeMeta, err := findMeta(SourceCredentials{request.BeamtimeId, "auto", "", "", ""}) + beamtimeMeta, err := findMeta(SourceCredentials{request.BeamtimeId, "auto", "", "", "",request.InstanceId, request.PipelineStep}) if err != nil { log.Error("cannot get beamtime meta" + err.Error()) return folders,err diff --git a/authorizer/src/asapo_authorizer/server/folder_token_test.go b/authorizer/src/asapo_authorizer/server/folder_token_test.go index ae39cee67b223f2d4d04da60cd749d240af877f7..6d1fc332960b783f3a5a6a079db4318060ca33d0 100644 --- a/authorizer/src/asapo_authorizer/server/folder_token_test.go +++ b/authorizer/src/asapo_authorizer/server/folder_token_test.go @@ -17,7 +17,7 @@ import ( "testing" ) -var fodlerTokenTests = [] struct { +var folderTokenTests = [] struct { beamtime_id string auto bool root_folder string @@ -27,7 +27,7 @@ var fodlerTokenTests = [] struct { message string }{ {"test", false,"tf/gpfs/bl1/2019/data/test", "", prepareAsapoToken("bt_test",[]string{"read"}),http.StatusOK,"beamtime found"}, - {"test_online",false, "bl1/current", "", prepareAsapoToken("bt_test_online",[]string{"read"}),http.StatusOK,"online beamtime found"}, +/* {"test_online",false, "bl1/current", "", prepareAsapoToken("bt_test_online",[]string{"read"}),http.StatusOK,"online beamtime found"}, {"test", false,"bl1/current", "", prepareAsapoToken("bt_test",[]string{"read"}),http.StatusUnauthorized,"no online beamtime found"}, {"test_online",false, "bl2/current", "", prepareAsapoToken("bt_test_online",[]string{"read"}),http.StatusUnauthorized,"wrong online folder"}, {"test", false,"tf/gpfs/bl1/2019/data/test1", "", prepareAsapoToken("bt_test",[]string{"read"}),http.StatusUnauthorized,"wrong folder"}, @@ -36,7 +36,7 @@ var fodlerTokenTests = [] struct { {"test", true,"tf/gpfs/bl1/2019/data/test", "", prepareAsapoToken("bt_test",[]string{"read"}),http.StatusOK,"auto without onilne"}, {"test_online",true, "tf/gpfs/bl1/2019/data/test_online", "bl1/current", prepareAsapoToken("bt_test_online",[]string{"read"}),http.StatusOK,"auto with online"}, - +*/ } func TestFolderToken(t *testing.T) { @@ -57,8 +57,10 @@ func TestFolderToken(t *testing.T) { defer os.RemoveAll("tf") defer os.RemoveAll("bl1") - for _, test := range fodlerTokenTests { - abs_path:=common.Settings.RootBeamtimesFolder + string(filepath.Separator)+test.root_folder + for _, test := range folderTokenTests { + testName := "Testcase " + test.message + + abs_path := common.Settings.RootBeamtimesFolder + string(filepath.Separator)+test.root_folder abs_path_second :="" if test.second_folder!="" { abs_path_second =common.Settings.RootBeamtimesFolder + string(filepath.Separator)+test.second_folder @@ -67,7 +69,7 @@ func TestFolderToken(t *testing.T) { if test.auto { path_in_token = "auto" } - request := makeRequest(folderTokenRequest{path_in_token,test.beamtime_id,test.token}) + request := makeRequest(folderTokenRequest{path_in_token,test.beamtime_id,test.token, "instance", "step"}) if test.status == http.StatusBadRequest { request =makeRequest(authorizationRequest{}) } else { @@ -79,12 +81,14 @@ func TestFolderToken(t *testing.T) { claims,_ := utils.CheckJWTToken(string(body),"secret_folder") var extra_claim structs.FolderTokenTokenExtraClaim utils.MapToStruct(claims.(*utils.CustomClaims).ExtraClaims.(map[string]interface{}), &extra_claim) - assert.Equal(t, filepath.Clean(abs_path), filepath.Clean(extra_claim.RootFolder), test.message) - assert.Equal(t, filepath.Clean(abs_path_second), filepath.Clean(extra_claim.SecondFolder), test.message) + assert.Equal(t, filepath.Clean(abs_path), filepath.Clean(extra_claim.RootFolder), testName) + assert.Equal(t, filepath.Clean(abs_path_second), filepath.Clean(extra_claim.SecondFolder), testName) } else { body, _ := ioutil.ReadAll(w.Body) fmt.Println(string(body)) } + + assert.Equal(t, test.status, w.Code, testName) mock_store.AssertExpectations(t) mock_store.ExpectedCalls = nil mock_store.Calls = nil @@ -93,10 +97,7 @@ func TestFolderToken(t *testing.T) { } func TestFolderTokenWrongProtocol(t *testing.T) { - request := makeRequest(folderTokenRequest{"abs_path","beamtime_id","token"}) + request := makeRequest(folderTokenRequest{"abs_path","beamtime_id","token", "instance", "step"}) w := doPostRequest("/v10000.2/folder",request,"") assert.Equal(t, http.StatusUnsupportedMediaType, w.Code, "wrong protocol") } - - - diff --git a/broker/src/asapo_broker/go.mod b/broker/src/asapo_broker/go.mod index dda6c336a26628955ba4df3988796fd41fb8145e..6b0c3d47266b1bed667209ace63387f183dcb349 100644 --- a/broker/src/asapo_broker/go.mod +++ b/broker/src/asapo_broker/go.mod @@ -13,4 +13,5 @@ require ( github.com/rs/xid v1.2.1 github.com/stretchr/testify v1.7.0 go.mongodb.org/mongo-driver v1.5.3 + google.golang.org/grpc v1.39.0 ) diff --git a/broker/src/asapo_broker/go.sum b/broker/src/asapo_broker/go.sum index e83d395ff5f1660a77148c32e1bcfd45b915516b..b62046437e614191efb6afa05f555d986eb5a44b 100644 --- a/broker/src/asapo_broker/go.sum +++ b/broker/src/asapo_broker/go.sum @@ -1,3 +1,4 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -5,6 +6,7 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/aws/aws-sdk-go v1.34.28 h1:sscPpn/Ns3i0F4HPEWAVcwdIRaZZCuL7llJ2/60yPIk= github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -13,13 +15,25 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blastrain/vitess-sqlparser v0.0.0-20201030050434-a139afbb1aba h1:hBK2BWzm0OzYZrZy9yzvZZw59C5Do4/miZ8FhEwd5P8= github.com/blastrain/vitess-sqlparser v0.0.0-20201030050434-a139afbb1aba/go.mod h1:FGQp+RNQwVmLzDq6HBrYCww9qJQyNwH9Qji/quTQII4= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= @@ -54,29 +68,37 @@ github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGt github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab h1:HqW4xhhynfjrtEiiSGcQUd6vrK23iMam1FO8rI7mwig= github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= @@ -138,6 +160,7 @@ github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= @@ -149,6 +172,7 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -169,6 +193,7 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -184,21 +209,33 @@ github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= go.mongodb.org/mongo-driver v1.5.3 h1:wWbFB6zaGHpzguF3f7tW94sVE8sFl3lHx8OZx/4OuFI= go.mongodb.org/mongo-driver v1.5.3/go.mod h1:gRXCHX4Jo7J0IJ1oDQyUxF7jfy19UfxniMS4xxMmUqw= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -207,6 +244,7 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -229,19 +267,41 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.39.0 h1:Klz8I9kdtkIN6EpHHUOMLCYhTn/2WAe5a0s1hcBkdTI= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1 h1:7QnIQpGRHE5RnLKnESfDoxm2dTapTZua5a0kS0A+VXQ= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -254,6 +314,7 @@ gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 h1:VpOs+IwYnYBaFnrNAeB8UUWtL3 gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -261,3 +322,5 @@ gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/broker/src/asapo_broker/server/monitoring.go b/broker/src/asapo_broker/server/monitoring.go new file mode 100644 index 0000000000000000000000000000000000000000..5e197e2fbfcc7280f96332bbf6f25fc43cd325cc --- /dev/null +++ b/broker/src/asapo_broker/server/monitoring.go @@ -0,0 +1,85 @@ +package server + +import ( + pb "asapo_common/generated_proto" + "context" + "sync" + "time" +) + +type brokerMonitoring struct { + Sender BrokerMonitoringDataSender + BrokerName string + + toBeSendMutex sync.Mutex + toBeSendDataPoints []*pb.BrokerRequestDataPoint + + sendingThreadRunningCtx context.Context + + discoveredMonitoringServerUrl string +} + +func (m *brokerMonitoring) getBrokerToConsumerTransfer(consumerInstanceId string, pipelineStepId string, op string, beamtime string, source string, stream string) *pb.BrokerRequestDataPoint { + for _, element := range m.toBeSendDataPoints { + if element.ConsumerInstanceId == consumerInstanceId && + element.PipelineStepId == pipelineStepId && + element.Command == op && + element.Beamtime == beamtime && + element.Source == source && + element.Stream == stream { + return element + } + } + + newPoint := &pb.BrokerRequestDataPoint{ + PipelineStepId: pipelineStepId, + ConsumerInstanceId: consumerInstanceId, + Command: op, + Beamtime: beamtime, + Source: source, + Stream: stream, + FileCount: 0, + TotalFileSize: 0, + } + + // Need to insert element + m.toBeSendDataPoints = append(m.toBeSendDataPoints, newPoint) + + return newPoint +} + +func (m *brokerMonitoring) sendNow() error { + + // Lock and quickly exchange the to be sent data + m.toBeSendMutex.Lock() + localToBeSendDataPoints := m.toBeSendDataPoints + m.toBeSendDataPoints = nil + m.toBeSendMutex.Unlock() + + + dataContainer := pb.BrokerDataPointContainer{ + BrokerName: m.BrokerName, + TimestampMs: uint64(time.Now().UnixNano() / int64(time.Millisecond)), + GroupedBrokerRequests: localToBeSendDataPoints, + } + + err := m.Sender.Send(&dataContainer) + if err != nil { + return err + } + + return nil +} + +func (m *brokerMonitoring) SendBrokerRequest( + consumerInstanceId string, pipelineStepId string, + op string, beamtimeId string, datasource string, stream string, size uint64) { + + m.toBeSendMutex.Lock() + + group := m.getBrokerToConsumerTransfer(consumerInstanceId, pipelineStepId, op, beamtimeId, datasource, stream) + group.FileCount++ + group.TotalFileSize += size + + m.toBeSendMutex.Unlock() +} diff --git a/broker/src/asapo_broker/server/monitoring_nottested.go b/broker/src/asapo_broker/server/monitoring_nottested.go new file mode 100644 index 0000000000000000000000000000000000000000..f132bbcedab8fefcb44f1dfe2e97f3c68448bdda --- /dev/null +++ b/broker/src/asapo_broker/server/monitoring_nottested.go @@ -0,0 +1,118 @@ +package server + +import ( + pb "asapo_common/generated_proto" + log "asapo_common/logger" + "context" + "google.golang.org/grpc" + "os" + "strconv" + "time" +) + +type BrokerMonitoringDataSender interface { + Init(serverUrl string) error + Send(container *pb.BrokerDataPointContainer) error + IsInitialized() bool +} + +type gRPCBrokerMonitoringDataSender struct { + client pb.AsapoMonitoringIngestServiceClient +} + +func (g *gRPCBrokerMonitoringDataSender) IsInitialized() bool { + return g.client != nil +} + +func (g *gRPCBrokerMonitoringDataSender) Init(serverUrl string) error { + var opts []grpc.DialOption + opts = append(opts, grpc.WithInsecure()) + conn, err := grpc.Dial(serverUrl, opts...) + if err != nil { + return err + } + + g.client = pb.NewAsapoMonitoringIngestServiceClient(conn) + + return nil +} + +func (g *gRPCBrokerMonitoringDataSender) Send(container *pb.BrokerDataPointContainer) error { + _, err := g.client.InsertBrokerDataPoints(context.TODO(), container) + + if err != nil { + return err + } + + return nil +} + +func (m *brokerMonitoring) reinitializeSender() error { + if settings.MonitoringServerUrl == "auto" { + fetchedMonitoringServerUrl, err := discoveryService.GetMonitoringServerUrl() + if err != nil { + return err + } + m.discoveredMonitoringServerUrl = fetchedMonitoringServerUrl + } else { + m.discoveredMonitoringServerUrl = settings.MonitoringServerUrl + } + + err := m.Sender.Init(m.discoveredMonitoringServerUrl) + if err != nil { + return err + } + + return nil +} + +func (m *brokerMonitoring) Init() error { + hostname, err := os.Hostname() + if err != nil { + hostname = "hostnameerror" + } + m.BrokerName = "broker_" + hostname + "_" + strconv.Itoa(os.Getpid()) + + return nil +} + +func (m *brokerMonitoring) RunThread() { + globalStart := time.Now() + + sendingInterval := 5000 * time.Millisecond + time.Sleep(sendingInterval) + + waitForNextIteration := func(iterationStartTime time.Time) { + timeTook := time.Since(iterationStartTime) + if timeTook < sendingInterval { + sleepTime := sendingInterval - (time.Since(globalStart) % sendingInterval) + time.Sleep(sleepTime) + } + } + + for { + iterationStart := time.Now() + if !m.Sender.IsInitialized() { + err := m.reinitializeSender() + if err != nil { + log.Warning("monitoring.reinitializeSender failed " , err.Error()) + waitForNextIteration(iterationStart) + continue + } + } + + err := m.sendNow() + + if err != nil { + logString := "sending monitoring data to '" + m.discoveredMonitoringServerUrl + "'" + log.Error(logString + " - " + err.Error()) + + err = m.reinitializeSender() + if err != nil { + log.Error("reinitializeSender also failed - " + err.Error()) + } + } + + waitForNextIteration(iterationStart) + } +} diff --git a/broker/src/asapo_broker/server/monitoring_test.go b/broker/src/asapo_broker/server/monitoring_test.go new file mode 100644 index 0000000000000000000000000000000000000000..af499cd3a315a89b608c50dc8b13c44ae4179a53 --- /dev/null +++ b/broker/src/asapo_broker/server/monitoring_test.go @@ -0,0 +1,121 @@ +package server + +import ( + pb "asapo_common/generated_proto" + "errors" + "github.com/stretchr/testify/assert" + "testing" + "time" +) + +type mockRpc struct { + LastSendContainer *pb.BrokerDataPointContainer +} +func (m *mockRpc) Send(container *pb.BrokerDataPointContainer) error { + m.LastSendContainer = container + return nil +} +func (m *mockRpc) Init(serverUrl string) error { + return nil +} +func (m *mockRpc) IsInitialized() bool { + return true +} + +type mockErrorRpc struct { +} +func (m *mockErrorRpc) Send(container *pb.BrokerDataPointContainer) error { + return errors.New("MyMockError from Send") +} +func (m *mockErrorRpc) Init(serverUrl string) error { + return errors.New("MyMockError from Init") +} +func (m *mockErrorRpc) IsInitialized() bool { + return true +} + +func TestMonitoringCycle(t *testing.T) { + mockRpc := new(mockRpc) + monitoring.Sender = mockRpc + monitoring.BrokerName = "myBroker" + + // Send one file + monitoring.SendBrokerRequest( + "consumerId", "pipelineStep", "push", "beamtime", "datasource", "stream", + 123) + + monitoring.sendNow() + + assert.NotNil(t, mockRpc.LastSendContainer) + assert.Equal(t, mockRpc.LastSendContainer.BrokerName, "myBroker") + assert.GreaterOrEqual(t, mockRpc.LastSendContainer.TimestampMs, uint64(time.Now().UnixNano() / int64(time.Millisecond)) - 1000) + assert.LessOrEqual(t, mockRpc.LastSendContainer.TimestampMs, uint64(time.Now().UnixNano() / int64(time.Millisecond))) + assert.Equal(t, len(mockRpc.LastSendContainer.GroupedBrokerRequests), 1) + assert.Equal(t, mockRpc.LastSendContainer.GroupedBrokerRequests[0].PipelineStepId, "pipelineStep") + assert.Equal(t, mockRpc.LastSendContainer.GroupedBrokerRequests[0].ConsumerInstanceId, "consumerId") + assert.Equal(t, mockRpc.LastSendContainer.GroupedBrokerRequests[0].Command, "push") + assert.Equal(t, mockRpc.LastSendContainer.GroupedBrokerRequests[0].Beamtime, "beamtime") + assert.Equal(t, mockRpc.LastSendContainer.GroupedBrokerRequests[0].Source, "datasource") + assert.Equal(t, mockRpc.LastSendContainer.GroupedBrokerRequests[0].Stream, "stream") + assert.Equal(t, mockRpc.LastSendContainer.GroupedBrokerRequests[0].FileCount, uint64(1)) + assert.Equal(t, mockRpc.LastSendContainer.GroupedBrokerRequests[0].TotalFileSize, uint64(123)) + + // No files send + monitoring.sendNow() + assert.NotNil(t, mockRpc.LastSendContainer) + assert.Equal(t, mockRpc.LastSendContainer.BrokerName, "myBroker") + assert.GreaterOrEqual(t, mockRpc.LastSendContainer.TimestampMs, uint64(time.Now().UnixNano() / int64(time.Millisecond)) - 1000) + assert.LessOrEqual(t, mockRpc.LastSendContainer.TimestampMs, uint64(time.Now().UnixNano() / int64(time.Millisecond))) + assert.Equal(t, len(mockRpc.LastSendContainer.GroupedBrokerRequests), 0) + + + // Send 3 files in 2 groups + monitoring.SendBrokerRequest( + "consumerId", "pipelineStep", "push", "beamtime1", "datasource", "stream", + 564) + monitoring.SendBrokerRequest( + "consumerId", "pipelineStep", "push", "beamtime1", "datasource", "stream", + 32) + monitoring.SendBrokerRequest( + "consumerId", "pipelineStep", "push", "beamtime2", "datasource", "stream", + 401) + + monitoring.sendNow() + + assert.NotNil(t, mockRpc.LastSendContainer) + assert.Equal(t, mockRpc.LastSendContainer.BrokerName, "myBroker") + assert.GreaterOrEqual(t, mockRpc.LastSendContainer.TimestampMs, uint64(time.Now().UnixNano() / int64(time.Millisecond)) - 1000) + assert.LessOrEqual(t, mockRpc.LastSendContainer.TimestampMs, uint64(time.Now().UnixNano() / int64(time.Millisecond))) + assert.Equal(t, len(mockRpc.LastSendContainer.GroupedBrokerRequests), 2) + + assert.Equal(t, mockRpc.LastSendContainer.GroupedBrokerRequests[0].PipelineStepId, "pipelineStep") + assert.Equal(t, mockRpc.LastSendContainer.GroupedBrokerRequests[0].ConsumerInstanceId, "consumerId") + assert.Equal(t, mockRpc.LastSendContainer.GroupedBrokerRequests[0].Command, "push") + assert.Equal(t, mockRpc.LastSendContainer.GroupedBrokerRequests[0].Beamtime, "beamtime1") + assert.Equal(t, mockRpc.LastSendContainer.GroupedBrokerRequests[0].Source, "datasource") + assert.Equal(t, mockRpc.LastSendContainer.GroupedBrokerRequests[0].Stream, "stream") + assert.Equal(t, mockRpc.LastSendContainer.GroupedBrokerRequests[0].FileCount, uint64(2)) + assert.Equal(t, mockRpc.LastSendContainer.GroupedBrokerRequests[0].TotalFileSize, uint64(564+32)) + + assert.Equal(t, mockRpc.LastSendContainer.GroupedBrokerRequests[1].PipelineStepId, "pipelineStep") + assert.Equal(t, mockRpc.LastSendContainer.GroupedBrokerRequests[0].Command, "push") + assert.Equal(t, mockRpc.LastSendContainer.GroupedBrokerRequests[1].ConsumerInstanceId, "consumerId") + assert.Equal(t, mockRpc.LastSendContainer.GroupedBrokerRequests[1].Beamtime, "beamtime2") + assert.Equal(t, mockRpc.LastSendContainer.GroupedBrokerRequests[1].Source, "datasource") + assert.Equal(t, mockRpc.LastSendContainer.GroupedBrokerRequests[1].Stream, "stream") + assert.Equal(t, mockRpc.LastSendContainer.GroupedBrokerRequests[1].FileCount, uint64(1)) + assert.Equal(t, mockRpc.LastSendContainer.GroupedBrokerRequests[1].TotalFileSize, uint64(401)) +} + +func TestSendNowErrorForwarding(t *testing.T) { + mockErrorRpc := new(mockErrorRpc) + monitoring.Sender = mockErrorRpc + monitoring.BrokerName = "myBroker" + + // Send one file + monitoring.SendBrokerRequest( + "consumerId", "pipelineStep", "push", "beamtime", "datasource", "stream", + 123) + + assert.Equal(t, monitoring.sendNow().Error(), "MyMockError from Send") +} diff --git a/broker/src/asapo_broker/server/process_request.go b/broker/src/asapo_broker/server/process_request.go index 8a0065fc2806ada24caa414e825e3e35b4c97778..76f85640bfad25a8daa68b8ab0d54d64afd3821c 100644 --- a/broker/src/asapo_broker/server/process_request.go +++ b/broker/src/asapo_broker/server/process_request.go @@ -6,6 +6,7 @@ import ( log "asapo_common/logger" "asapo_common/utils" "asapo_common/version" + "encoding/json" "github.com/gorilla/mux" "net/http" "net/url" @@ -22,7 +23,10 @@ func readFromMapUnescaped(key string, vars map[string]string) (val string,ok boo return } -func extractRequestParameters(r *http.Request, needGroupID bool) (string, string, string, string, bool) { +func extractRequestParameters(r *http.Request, needGroupID bool) ( + string/*instanceid*/, string/*pipelinestep*/, + string/*beamtime*/, string/*datasource*/, string /*stream*/, string /*groupid*/, bool, /*was okay*/ + ) { vars := mux.Vars(r) db_name, ok1 := vars["beamtime"] datasource, ok3 := readFromMapUnescaped("datasource",vars) @@ -34,8 +38,12 @@ func extractRequestParameters(r *http.Request, needGroupID bool) (string, string group_id, ok2 = readFromMapUnescaped("groupid",vars) } + instanceid := r.URL.Query().Get("instanceid") + pipelinestep := r.URL.Query().Get("pipelinestep") - return db_name, datasource, stream, group_id, ok1 && ok2 && ok3 && ok4 + allParametersAreOk := ok1 && ok2 && ok3 && ok4 + + return instanceid, pipelinestep, db_name, datasource, stream, group_id, allParametersAreOk } func IsLetterOrNumbers(s string) bool { @@ -63,20 +71,20 @@ func processRequest(w http.ResponseWriter, r *http.Request, op string, extra_par w.Header().Set("Access-Control-Allow-Origin", "*") - beamtime, datasource, stream, group_id, ok := extractRequestParameters(r, needGroupID) + consumerInstanceId, pipelineStepId, beamtimeId, datasource, stream, group_id, ok := extractRequestParameters(r, needGroupID) if !ok { log.WithFields(map[string]interface{}{"request":r.RequestURI}).Error("cannot extract request parameters") w.WriteHeader(http.StatusBadRequest) return } - if err := authorize(r, beamtime, needWriteAccess(op)); err != nil { - writeAuthAnswer(w, "get "+op, beamtime, err) + if err := authorize(r, beamtimeId, needWriteAccess(op)); err != nil { + writeAuthAnswer(w, "get "+op, beamtimeId, err) return } request := database.Request{} - request.Beamtime = beamtime + request.Beamtime = beamtimeId request.DataSource = datasource request.Op = op request.ExtraParam = extra_param @@ -91,7 +99,32 @@ func processRequest(w http.ResponseWriter, r *http.Request, op string, extra_par rlog.Debug("got request") answer, code := processRequestInDb(request,rlog) w.WriteHeader(code) - w.Write(answer) + _, err := w.Write(answer) + + type SizeStruct struct { + Size uint64 `bson:"size" json:"size"` + } + + if err == nil && code == 200 && len(consumerInstanceId) > 0 && len(pipelineStepId) > 0 { + var sized SizeStruct + err = json.Unmarshal(answer, &sized) + if err == nil { + switch op { + case "next": fallthrough + case "id": fallthrough + case "last": + monitoring.SendBrokerRequest( + consumerInstanceId, + pipelineStepId, + op, + beamtimeId, + datasource, + stream, + sized.Size, + ) + } + } + } } func returnError(err error, rlog logger.Logger) (answer []byte, code int) { @@ -117,8 +150,6 @@ func reconnectIfNeeded(db_error error) { } } - - func processRequestInDb(request database.Request,rlog logger.Logger) (answer []byte, code int) { statistics.IncreaseCounter() answer, err := db.ProcessRequest(request) diff --git a/broker/src/asapo_broker/server/server.go b/broker/src/asapo_broker/server/server.go index f736671739406613093df46730000f3782421a61..51800b2c592c4e2cfa28d5b5ece809430a83169f 100644 --- a/broker/src/asapo_broker/server/server.go +++ b/broker/src/asapo_broker/server/server.go @@ -19,6 +19,7 @@ type serverSettings struct { DatabaseServer string PerformanceDbServer string PerformanceDbName string + MonitoringServerUrl string MonitorPerformance bool AuthorizationServer string Port int @@ -60,13 +61,9 @@ func (s *serverSettings) GetDatabaseServer() string { var settings serverSettings var statistics serverStatistics +var monitoring brokerMonitoring var auth Authorizer -type discoveryAPI struct { - Client *http.Client - baseURL string -} - var discoveryService discovery.DiscoveryAPI func ReconnectDb() (err error) { diff --git a/broker/src/asapo_broker/server/server_nottested.go b/broker/src/asapo_broker/server/server_nottested.go index 2fbf445630294c61dfd259cc94b2bb0375c54daf..0b792a7e21202bc9f6cfad54af5cab4b0b6ae109 100644 --- a/broker/src/asapo_broker/server/server_nottested.go +++ b/broker/src/asapo_broker/server/server_nottested.go @@ -19,9 +19,16 @@ func StartStatistics() { go statistics.Monitor() } +func StartMonitoring() { + monitoring.Sender = new(gRPCBrokerMonitoringDataSender) + monitoring.Init() + go monitoring.RunThread() +} + func Start() { if settings.MonitorPerformance { StartStatistics() + StartMonitoring() } mux := utils.NewRouter(listRoutes) mux.PathPrefix("/debug/pprof/").Handler(http.DefaultServeMux) @@ -48,6 +55,21 @@ func ReadConfig(fname string) (log.Level, error) { return log.FatalLevel, errors.New("PerformanceDbServer not set") } + if settings.MonitoringServerUrl == "" { + return log.FatalLevel, errors.New("MonitoringServerUrl not set") + } + + if settings.AuthorizationServer == "" { + return log.FatalLevel, errors.New("AuthorizationServer not set") + } + if settings.PerformanceDbName == "" { + return log.FatalLevel, errors.New("PerformanceDbName not set") + } + + if settings.MonitoringServerUrl == "auto" && settings.DiscoveryServer == "" { + return log.FatalLevel, errors.New("DiscoveryServer not set for auto MonitoringServerUrl") + } + if settings.DatabaseServer == "auto" && settings.DiscoveryServer == "" { return log.FatalLevel, errors.New("DiscoveryServer not set for auto DatabaseServer") } @@ -60,10 +82,6 @@ func ReadConfig(fname string) (log.Level, error) { return log.FatalLevel, errors.New("Resend interval must be set and not negative") } - if settings.PerformanceDbName == "" { - return log.FatalLevel, errors.New("PerformanceDbName not set") - } - if settings.AuthorizationServer == "" { return log.FatalLevel, errors.New("AuthorizationServer not set") } diff --git a/common/cpp/include/asapo/common/common_c.h b/common/cpp/include/asapo/common/common_c.h index d851b87efd4ded60178c8fb605d1587c4f03d583..2482133044c3930e270b400fc018f30838d56d0c 100644 --- a/common/cpp/include/asapo/common/common_c.h +++ b/common/cpp/include/asapo/common/common_c.h @@ -59,6 +59,8 @@ void asapo_stream_info_get_timestamp_last_entry(const AsapoStreamInfoHandle info struct timespec* stamp); AsapoSourceCredentialsHandle asapo_create_source_credentials(enum AsapoSourceType type, + const char* instanceId, + const char* pipelineStep, const char* beamtime, const char* beamline, const char* data_source, diff --git a/common/cpp/include/asapo/common/data_structs.h b/common/cpp/include/asapo/common/data_structs.h index e2d9d56fb275a2ca25e3c07ba76316a7a9905e93..7c06ccc691df4c9a640f521971d54e73d99183b3 100644 --- a/common/cpp/include/asapo/common/data_structs.h +++ b/common/cpp/include/asapo/common/data_structs.h @@ -9,6 +9,9 @@ #include "error.h" +#include "asapo/preprocessor/deprecated.h" + + namespace asapo { const std::string kFinishStreamKeyword = "asapo_finish_stream"; @@ -22,44 +25,44 @@ std::chrono::system_clock::time_point TimePointfromNanosec(uint64_t nanoseconds_ std::string IsoDateFromEpochNanosecs(uint64_t time_from_epoch_nanosec); uint64_t NanosecsEpochFromISODate(std::string date_time); -std::string HostFromUri(const std::string& uri); - +std::string HostFromUri(const std::string &uri); -bool TimeFromJson(const JsonStringParser& parser, const std::string& name, std::chrono::system_clock::time_point* val); +bool TimeFromJson(const JsonStringParser &parser, const std::string &name, std::chrono::system_clock::time_point *val); class MessageMeta { - public: - std::string name; - std::chrono::system_clock::time_point timestamp; - uint64_t size{0}; - uint64_t id{0}; - std::string source; - std::string metadata; - uint64_t buf_id{0}; - uint64_t dataset_substream{0}; - std::string Json() const; - bool SetFromJson(const std::string& json_string); - std::string FullName(const std::string& base_path) const; + public: + std::string name; + std::chrono::system_clock::time_point timestamp; + uint64_t size{0}; + uint64_t id{0}; + std::string source; + std::string metadata; + uint64_t buf_id{0}; + std::string stream; // might be "unknownStream" for older datasets + uint64_t dataset_substream{0}; + std::string Json() const; + bool SetFromJson(const std::string &json_string); + std::string FullName(const std::string &base_path) const; }; struct StreamInfo { - uint64_t last_id{0}; - std::string name; - bool finished{false}; - std::string next_stream; - std::chrono::system_clock::time_point timestamp_created; - std::chrono::system_clock::time_point timestamp_lastentry; - std::string Json() const; - bool SetFromJson(const std::string& json_string); + uint64_t last_id{0}; + std::string name; + bool finished{false}; + std::string next_stream; + std::chrono::system_clock::time_point timestamp_created; + std::chrono::system_clock::time_point timestamp_lastentry; + std::string Json() const; + bool SetFromJson(const std::string &json_string); }; using StreamInfos = std::vector<StreamInfo>; -inline bool operator==(const MessageMeta& lhs, const MessageMeta& rhs) { +inline bool operator==(const MessageMeta &lhs, const MessageMeta &rhs) { return (lhs.name == rhs.name && - lhs.id == rhs.id && - lhs.timestamp == rhs.timestamp && - lhs.size == rhs.size); + lhs.id == rhs.id && + lhs.timestamp == rhs.timestamp && + lhs.size == rhs.size); } using MessageData = std::unique_ptr<uint8_t[]>; @@ -70,185 +73,207 @@ using MessageMetas = std::vector<MessageMeta>; using IdList = std::vector<uint64_t>; struct DataSet { - uint64_t id; - uint64_t expected_size; - MessageMetas content; - bool SetFromJson(const std::string& json_string); + uint64_t id; + uint64_t expected_size; + MessageMetas content; + bool SetFromJson(const std::string &json_string); }; using SubDirList = std::vector<std::string>; enum class SourceType { - kProcessed, - kRaw + kProcessed, + kRaw }; -Error GetSourceTypeFromString(std::string stype, SourceType* type); +Error GetSourceTypeFromString(std::string stype, SourceType *type); std::string GetStringFromSourceType(SourceType type); struct SourceCredentials { - SourceCredentials(SourceType type, - std::string beamtime, - std::string beamline, - std::string data_source, - std::string token) : - beamtime_id{std::move(beamtime)}, - beamline{std::move(beamline)}, - data_source{std::move(data_source)}, - user_token{std::move(token)}, - type{type} {}; - SourceCredentials() {}; - static const std::string kDefaultDataSource; - static const std::string kDefaultBeamline; - static const std::string kDefaultBeamtimeId; - std::string beamtime_id; - std::string beamline; - std::string data_source; - std::string user_token; - SourceType type = SourceType::kProcessed; - std::string GetString() { - return (type == SourceType::kRaw ? std::string("raw") : std::string("processed")) + "%" + beamtime_id + "%" - + beamline + "%" + data_source + "%" + user_token; - }; + ASAPO_DEPRECATED("obsolates 01.03.2023, use SourceCredentials with instanceId/pipelineStep instead") SourceCredentials(SourceType type, + std::string beamtimeId, + std::string beamline, + std::string data_source, + std::string token) : + instance_id{kDefaultInstanceId}, + pipeline_step{kDefaultPipelineStep}, + beamtime_id{std::move(beamtimeId)}, + beamline{std::move(beamline)}, + data_source{std::move(data_source)}, + user_token{std::move(token)}, + type{type} {}; + SourceCredentials(SourceType type, + std::string instanceId, + std::string pipelineStep, + std::string beamtimeId, + std::string beamline, + std::string data_source, + std::string token) : + instance_id{std::move(instanceId)}, + pipeline_step{std::move(pipelineStep)}, + beamtime_id{std::move(beamtimeId)}, + beamline{std::move(beamline)}, + data_source{std::move(data_source)}, + user_token{std::move(token)}, + type{type} {}; + SourceCredentials() {}; + static const std::string kDefaultInstanceId; + static const std::string kDefaultPipelineStep; + static const std::string kDefaultDataSource; + static const std::string kDefaultBeamline; + static const std::string kDefaultBeamtimeId; + std::string instance_id; + std::string pipeline_step; + std::string beamtime_id; + std::string beamline; + std::string data_source; + std::string user_token; + SourceType type = SourceType::kProcessed; + std::string GetString() { + return (type == SourceType::kRaw ? std::string("raw") : std::string("processed")) + + "%" + instance_id + "%" + pipeline_step + + "%" + beamtime_id + "%" + beamline + "%" + data_source + "%" + user_token; + }; }; struct DeleteStreamOptions { - private: - enum DeleteStreamFlags : uint64_t { - kDeleteMeta = 1 << 0, - kErrorOnNotFound = 1 << 1, - }; - public: - DeleteStreamOptions() = default; - DeleteStreamOptions(bool delete_meta, bool error_on_not_exist): delete_meta{delete_meta}, error_on_not_exist{error_on_not_exist} {}; - bool delete_meta{true}; - bool error_on_not_exist{true}; - uint64_t Encode() { - uint64_t flag = 0; - flag = delete_meta ? flag | DeleteStreamFlags::kDeleteMeta : flag; - flag = error_on_not_exist ? flag | DeleteStreamFlags::kErrorOnNotFound : flag; - return flag; - }; - void Decode(uint64_t flag) { - delete_meta = (flag & DeleteStreamFlags::kDeleteMeta) > 0; - error_on_not_exist = (flag & DeleteStreamFlags::kErrorOnNotFound) > 0; - }; - std::string Json() { - return std::string("{\"ErrorOnNotExist\":") + (error_on_not_exist ? "true" : "false") + ",\"DeleteMeta\":" - + (delete_meta ? "true" : "false") + "}"; - } + private: + enum DeleteStreamFlags : uint64_t { + kDeleteMeta = 1 << 0, + kErrorOnNotFound = 1 << 1, + }; + public: + DeleteStreamOptions() = default; + DeleteStreamOptions(bool delete_meta, bool error_on_not_exist) : delete_meta{delete_meta}, + error_on_not_exist{error_on_not_exist} {}; + bool delete_meta{true}; + bool error_on_not_exist{true}; + uint64_t Encode() { + uint64_t flag = 0; + flag = delete_meta ? flag | DeleteStreamFlags::kDeleteMeta : flag; + flag = error_on_not_exist ? flag | DeleteStreamFlags::kErrorOnNotFound : flag; + return flag; + }; + void Decode(uint64_t flag) { + delete_meta = (flag & DeleteStreamFlags::kDeleteMeta) > 0; + error_on_not_exist = (flag & DeleteStreamFlags::kErrorOnNotFound) > 0; + }; + std::string Json() { + return std::string("{\"ErrorOnNotExist\":") + (error_on_not_exist ? "true" : "false") + ",\"DeleteMeta\":" + + (delete_meta ? "true" : "false") + "}"; + } }; enum IngestModeFlags : uint64_t { - kTransferData = 1 << 0, - kTransferMetaDataOnly = 1 << 1, - kStoreInFilesystem = 1 << 2, - kStoreInDatabase = 1 << 3, - kWriteRawDataToOffline = 1 << 4, + kTransferData = 1 << 0, + kTransferMetaDataOnly = 1 << 1, + kStoreInFilesystem = 1 << 2, + kStoreInDatabase = 1 << 3, + kWriteRawDataToOffline = 1 << 4, }; const uint64_t kDefaultIngestMode = kTransferData | kStoreInFilesystem | kStoreInDatabase; enum class MetaIngestOp : uint64_t { - kInsert = 1, - kReplace = 2, - kUpdate = 3, + kInsert = 1, + kReplace = 2, + kUpdate = 3, }; struct MetaIngestMode { - MetaIngestOp op; - bool upsert; - MetaIngestMode() = default; - MetaIngestMode(MetaIngestOp aOp, bool aUpsert): op(aOp), upsert(aUpsert) {}; - uint64_t Encode() { - return static_cast<uint64_t>(op) + 10 * static_cast<uint64_t>(upsert); - } - void Decode(uint64_t code) { - upsert = code > 10; - uint64_t val = code - (upsert ? 10 : 0); - if (val <= 3) { - op = static_cast<MetaIngestOp>(val); - } - } + MetaIngestOp op; + bool upsert; + MetaIngestMode() = default; + MetaIngestMode(MetaIngestOp aOp, bool aUpsert) : op(aOp), upsert(aUpsert) {}; + uint64_t Encode() { + return static_cast<uint64_t>(op) + 10 * static_cast<uint64_t>(upsert); + } + void Decode(uint64_t code) { + upsert = code > 10; + uint64_t val = code - (upsert ? 10 : 0); + if (val <= 3) { + op = static_cast<MetaIngestOp>(val); + } + } }; class ClientProtocol { - private: - std::string version_; - std::string discovery_version_; - std::string name_; - public: - ClientProtocol(std::string version, std::string name, std::string discovery_version) : version_{version}, - name_{name} { - discovery_version_ = discovery_version; - }; - ClientProtocol() = delete; - virtual std::string GetString() = 0; - const std::string& GetVersion() const { - return version_; - } - const std::string& GetDiscoveryVersion() const { - return discovery_version_; - } - const std::string& GetName() const { - return name_; - } + private: + std::string version_; + std::string discovery_version_; + std::string name_; + public: + ClientProtocol(std::string version, std::string name, std::string discovery_version) : version_{version}, + name_{name} { + discovery_version_ = discovery_version; + }; + ClientProtocol() = delete; + virtual std::string GetString() = 0; + const std::string &GetVersion() const { + return version_; + } + const std::string &GetDiscoveryVersion() const { + return discovery_version_; + } + const std::string &GetName() const { + return name_; + } }; class ConsumerProtocol final : public ClientProtocol { - private: - std::string authorizer_version_; - std::string file_transfer_service_version_; - std::string broker_version_; - std::string rds_version_; - public: - ConsumerProtocol(std::string version, - std::string discovery_version, - std::string authorizer_version, - std::string file_transfer_service_version, - std::string broker_version, - std::string rds_version) - : ClientProtocol(version, "consumer protocol", discovery_version) { - authorizer_version_ = authorizer_version; - file_transfer_service_version_ = file_transfer_service_version; - broker_version_ = broker_version; - rds_version_ = rds_version; - } - const std::string& GetAuthorizerVersion() const { - return authorizer_version_; - } - const std::string& GetFileTransferServiceVersion() const { - return file_transfer_service_version_; - } - const std::string& GetRdsVersion() const { - return rds_version_; - } - const std::string& GetBrokerVersion() const { - return broker_version_; - }; - ConsumerProtocol() = delete; - std::string GetString() override { - return std::string(); - } + private: + std::string authorizer_version_; + std::string file_transfer_service_version_; + std::string broker_version_; + std::string rds_version_; + public: + ConsumerProtocol(std::string version, + std::string discovery_version, + std::string authorizer_version, + std::string file_transfer_service_version, + std::string broker_version, + std::string rds_version) + : ClientProtocol(version, "consumer protocol", discovery_version) { + authorizer_version_ = authorizer_version; + file_transfer_service_version_ = file_transfer_service_version; + broker_version_ = broker_version; + rds_version_ = rds_version; + } + const std::string &GetAuthorizerVersion() const { + return authorizer_version_; + } + const std::string &GetFileTransferServiceVersion() const { + return file_transfer_service_version_; + } + const std::string &GetRdsVersion() const { + return rds_version_; + } + const std::string &GetBrokerVersion() const { + return broker_version_; + }; + ConsumerProtocol() = delete; + std::string GetString() override { + return std::string(); + } }; class ProducerProtocol final : public ClientProtocol { - private: - std::string receiver_version_; - public: - ProducerProtocol(std::string version, - std::string discovery_version, - std::string receiver_version) - : ClientProtocol(version, "producer protocol", discovery_version) { - receiver_version_ = receiver_version; - }; - const std::string& GetReceiverVersion() const { - return receiver_version_; - } - ProducerProtocol() = delete; - std::string GetString() override { - return std::string(); - } + private: + std::string receiver_version_; + public: + ProducerProtocol(std::string version, + std::string discovery_version, + std::string receiver_version) + : ClientProtocol(version, "producer protocol", discovery_version) { + receiver_version_ = receiver_version; + }; + const std::string &GetReceiverVersion() const { + return receiver_version_; + } + ProducerProtocol() = delete; + std::string GetString() override { + return std::string(); + } }; } diff --git a/common/cpp/include/asapo/io/io.h b/common/cpp/include/asapo/io/io.h index 35921586616a21422a0a917fe81ff75ece6b7dbb..289464d77f5b4bac56b1670fba528fe1906bdafa 100644 --- a/common/cpp/include/asapo/io/io.h +++ b/common/cpp/include/asapo/io/io.h @@ -59,6 +59,8 @@ class IO { virtual std::unique_ptr<std::thread> NewThread(const std::string& name, std::function<void(uint64_t index)> function, uint64_t index) const = 0; + virtual int GetCurrentPid() const = 0; + /* * Network */ diff --git a/common/cpp/include/asapo/unittests/MockIO.h b/common/cpp/include/asapo/unittests/MockIO.h index 7e3c29fd534338a3baff0170da934327d6354331..370edff93e4bc1561f3d29a8ae96823901fb69cd 100644 --- a/common/cpp/include/asapo/unittests/MockIO.h +++ b/common/cpp/include/asapo/unittests/MockIO.h @@ -8,6 +8,7 @@ namespace asapo { class MockIO : public IO { public: + MOCK_CONST_METHOD0(GetCurrentPid, int()); std::string GetHostName(Error* err) const noexcept override { ErrorInterface* error = nullptr; diff --git a/common/cpp/src/common/common_c_glue.cpp b/common/cpp/src/common/common_c_glue.cpp index 7e3d8f4937629c478811144c3cf56e2819a03cb5..cbe7495833a7d5b3598b7e549f3f4118452a35cc 100644 --- a/common/cpp/src/common/common_c_glue.cpp +++ b/common/cpp/src/common/common_c_glue.cpp @@ -171,11 +171,14 @@ extern "C" { //! wraps asapo::SourceCredentials::SourceCredentials() /// \copydoc asapo::SourceCredentials::SourceCredentials() AsapoSourceCredentialsHandle asapo_create_source_credentials(enum AsapoSourceType type, + const char* instanceId, + const char* pipelineStep, const char* beamtime, const char* beamline, const char* data_source, const char* token) { auto retval = new asapo::SourceCredentials(static_cast<asapo::SourceType>(type), + instanceId, pipelineStep, beamtime, beamline, data_source, token); return new AsapoHandlerHolder<asapo::SourceCredentials> {retval}; diff --git a/common/cpp/src/data_structs/data_structs.cpp b/common/cpp/src/data_structs/data_structs.cpp index 0e1562ea7059ca162feec7ef81794b0d46f2c1d7..ed19d974894be4bdec461a88119071fd519f0b1b 100644 --- a/common/cpp/src/data_structs/data_structs.cpp +++ b/common/cpp/src/data_structs/data_structs.cpp @@ -19,6 +19,8 @@ using std::chrono::system_clock; namespace asapo { +const std::string SourceCredentials::kDefaultInstanceId = "auto"; +const std::string SourceCredentials::kDefaultPipelineStep = "auto"; const std::string SourceCredentials::kDefaultDataSource = "detector"; const std::string SourceCredentials::kDefaultBeamline = "auto"; const std::string SourceCredentials::kDefaultBeamtimeId = "auto"; @@ -68,6 +70,7 @@ std::string MessageMeta::Json() const { + std::to_string(nanoseconds_from_epoch) + "," "\"source\":\"" + source + "\"," "\"buf_id\":" + std::to_string(buf_id_int) + "," + "\"stream\":\"" + stream + "\"," "\"dataset_substream\":" + std::to_string(dataset_substream) + "," "\"meta\":" + (metadata.size() == 0 ? std::string("{}") : metadata) + "}"; @@ -119,6 +122,11 @@ bool MessageMeta::SetFromJson(const std::string& json_string) { JsonStringParser parser(json_string); + // might be missing and cannot be guaranteed for older datasets + if (parser.GetString("stream", &stream)) { + stream = "unknownStream"; + } + if (parser.GetUInt64("_id", &id) || parser.GetUInt64("size", &size) || parser.GetString("name", &name) || diff --git a/common/cpp/src/json_parser/rapid_json.cpp b/common/cpp/src/json_parser/rapid_json.cpp index 7dba5ea22cc247c0b07bff9a2d2757324757be97..d86d0987261ed28e4f7e5ebcf0d8dbfdd479a964 100644 --- a/common/cpp/src/json_parser/rapid_json.cpp +++ b/common/cpp/src/json_parser/rapid_json.cpp @@ -287,4 +287,4 @@ Error RapidJson::GetFlattenedString(const std::string& prefix, const std::string return nullptr; } -} \ No newline at end of file +} diff --git a/common/cpp/src/system_io/system_io.cpp b/common/cpp/src/system_io/system_io.cpp index d19f0f46fada88b333e15763c3ea027937e79e6c..e0796f61dc56e8a79bbcd6439b1c12d2d8f6f1d4 100644 --- a/common/cpp/src/system_io/system_io.cpp +++ b/common/cpp/src/system_io/system_io.cpp @@ -10,6 +10,9 @@ #ifdef _WIN32 typedef long suseconds_t; typedef short sa_family_t; + +#include <process.h> + #endif #if defined(__linux__) || defined (__APPLE__) @@ -230,6 +233,10 @@ std::unique_ptr<std::thread> SystemIO::NewThread(const std::string& name, std::f return thread; } +int32_t SystemIO::GetCurrentPid() const { + return getpid(); +} + void SystemIO::Skip(SocketDescriptor socket_fd, size_t length, Error* err) const { static const size_t kSkipBufferSize = 1024; @@ -638,13 +645,11 @@ Error SystemIO::RemoveFile(const std::string& fname) const { std::string SystemIO::GetHostName(Error* err) const noexcept { char host[1024]; - gethostname(host, sizeof(host)); - *err = GetLastError(); - if (*err) { + if (gethostname(host, sizeof(host))!=0) { + *err = GetLastError(); return ""; - } else { - return host; } + return host; } Error SystemIO::SendFile(SocketDescriptor socket_fd, const std::string& fname, size_t length) const { diff --git a/common/cpp/src/system_io/system_io.h b/common/cpp/src/system_io/system_io.h index 87cbce74b516d0a942d30202ee2d030787158795..eba2d6e042e32b0393af61501a909f9d4eeca3f2 100644 --- a/common/cpp/src/system_io/system_io.h +++ b/common/cpp/src/system_io/system_io.h @@ -93,6 +93,7 @@ class SystemIO final : public IO { std::unique_ptr<std::thread> NewThread(const std::string& name, std::function<void(uint64_t index)> function, uint64_t index) const override; + int32_t GetCurrentPid() const override; // this is not standard function - to be implemented differently in windows and linux std::vector<MessageMeta> FilesInFolder(const std::string& folder, Error* err) const override; diff --git a/common/cpp/unittests/data_structs/test_data_structs.cpp b/common/cpp/unittests/data_structs/test_data_structs.cpp index a8bb9c468085b9126edaa19021bb240891b9158d..2fcd83ea150cc2bc8e2c20fe83d04ce2084b1c50 100644 --- a/common/cpp/unittests/data_structs/test_data_structs.cpp +++ b/common/cpp/unittests/data_structs/test_data_structs.cpp @@ -26,7 +26,7 @@ namespace { uint64_t big_uint = 18446744073709551615ull; -MessageMeta PrepareMessageMeta() { +MessageMeta PrepareMessageMeta(bool includeNewStreamField = true) { MessageMeta message_meta; message_meta.size = 100; message_meta.id = 1; @@ -36,6 +36,9 @@ MessageMeta PrepareMessageMeta() { message_meta.buf_id = big_uint; message_meta.timestamp = std::chrono::time_point<std::chrono::system_clock>(std::chrono::milliseconds(1)); message_meta.metadata = "{\"bla\":10}"; + if (includeNewStreamField) { + message_meta.stream = "testStream"; + } return message_meta; } @@ -53,10 +56,10 @@ TEST(MessageMetaTests, CorrectConvertToJson) { std::string json = message_meta.Json(); if (asapo::kPathSeparator == '/') { ASSERT_THAT(json, Eq( - R"({"_id":1,"size":100,"name":"folder/test","timestamp":1000000,"source":"host:1234","buf_id":-1,"dataset_substream":3,"meta":{"bla":10}})")); + R"({"_id":1,"size":100,"name":"folder/test","timestamp":1000000,"source":"host:1234","buf_id":-1,"stream":"testStream","dataset_substream":3,"meta":{"bla":10}})")); } else { ASSERT_THAT(json, Eq( - R"({"_id":1,"size":100,"name":"folder\\test","timestamp":1000000,"source":"host:1234","buf_id":-1,"dataset_substream":3,"meta":{"bla":10}})")); + R"({"_id":1,"size":100,"name":"folder\\test","timestamp":1000000,"source":"host:1234","buf_id":-1,"stream":"testStream","dataset_substream":3,"meta":{"bla":10}})")); } } @@ -105,11 +108,47 @@ TEST(MessageMetaTests, CorrectConvertFromJson) { ASSERT_THAT(result.timestamp, Eq(message_meta.timestamp)); ASSERT_THAT(result.buf_id, Eq(message_meta.buf_id)); ASSERT_THAT(result.source, Eq(message_meta.source)); + ASSERT_THAT(result.stream, Eq(message_meta.stream)); // new ASSERT_THAT(result.metadata, Eq(message_meta.metadata)); ASSERT_THAT(result.dataset_substream, Eq(message_meta.dataset_substream)); } +void eraseSubStr(std::string & mainStr, const std::string & toErase) +{ + // Search for the substring in string + size_t pos = mainStr.find(toErase); + if (pos != std::string::npos) + { + // If found then erase it from string + mainStr.erase(pos, toErase.length()); + } +} + +TEST(MessageMetaTests, CorrectConvertFromJson_AllowOldDataFormat_MissingSource) { + // The source field was added in the monitoring update and might be missing on older datasets + + auto message_meta = PrepareMessageMeta(false); + std::string json = message_meta.Json(); + + eraseSubStr(json, ",\"stream\":\"\""); + + MessageMeta result; + auto ok = result.SetFromJson(json); + + ASSERT_THAT(ok, Eq(true)); + + ASSERT_THAT(result.id, Eq(message_meta.id)); + ASSERT_THAT(result.name, Eq(message_meta.name)); + ASSERT_THAT(result.size, Eq(message_meta.size)); + ASSERT_THAT(result.timestamp, Eq(message_meta.timestamp)); + ASSERT_THAT(result.buf_id, Eq(message_meta.buf_id)); + ASSERT_THAT(result.source, Eq(message_meta.source)); + ASSERT_THAT(result.stream, Eq("unknownStream")); // new and might be missing in some cases + ASSERT_THAT(result.metadata, Eq(message_meta.metadata)); + ASSERT_THAT(result.dataset_substream, Eq(message_meta.dataset_substream)); + +} TEST(MessageMetaTests, CorrectConvertFromJsonEmptyMeta) { auto message_meta = PrepareMessageMeta(); @@ -193,11 +232,10 @@ TEST(StreamInfo, ConvertToJson) { ASSERT_THAT(json, Eq(expected_json)); } - TEST(SourceCredentials, ConvertToString) { - auto sc = SourceCredentials{SourceType::kRaw, "beamtime", "beamline", "source", "token"}; - std::string expected1 = "raw%beamtime%beamline%source%token"; - std::string expected2 = "processed%beamtime%beamline%source%token"; + auto sc = SourceCredentials{SourceType::kRaw, "instance", "step", "beamtime", "beamline", "source", "token"}; + std::string expected1 = "raw%instance%step%beamtime%beamline%source%token"; + std::string expected2 = "processed%instance%step%beamtime%beamline%source%token"; auto res1 = sc.GetString(); sc.type = asapo::SourceType::kProcessed; diff --git a/common/go/src/asapo_common/discovery/discovery.go b/common/go/src/asapo_common/discovery/discovery.go index 552c07cf91d29b1b1747632bb96b5418bb59c577..43e4a9d3689ea14e2b265d31e19efbcad621373f 100644 --- a/common/go/src/asapo_common/discovery/discovery.go +++ b/common/go/src/asapo_common/discovery/discovery.go @@ -24,6 +24,16 @@ func (api *DiscoveryAPI) GetMongoDbAddress() (string, error) { return string(body), err } +func (api *DiscoveryAPI) GetMonitoringServerUrl() (string, error) { + resp, err := api.client.Get(api.baseURL + "/asapo-monitoring") + if err != nil { + return "", err + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + return string(body), err +} + func CreateDiscoveryService(client *http.Client,uri string) DiscoveryAPI{ return DiscoveryAPI{client, uri} -} \ No newline at end of file +} diff --git a/common/go/src/asapo_common/generate-proto.sh b/common/go/src/asapo_common/generate-proto.sh new file mode 100755 index 0000000000000000000000000000000000000000..688b67e5bdf518bdcbbc9a4c14b25ccf9e2a0b46 --- /dev/null +++ b/common/go/src/asapo_common/generate-proto.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +set -e + +PROTO_INPUT_FOLDER=../../../networking/monitoring/ +PROTO_INPUT=$PROTO_INPUT_FOLDER*.proto +PROTO_DEST=./generated_proto + +rm -rf ${PROTO_DEST} +mkdir -p ${PROTO_DEST} + +GO111MODULE=off go get \ + google.golang.org/protobuf/cmd/protoc-gen-go \ + google.golang.org/grpc/cmd/protoc-gen-go-grpc + +PATH="$PATH:$(go env GOPATH)/bin" protoc \ + --go_out=generated_proto --go_opt=paths=source_relative \ + --go-grpc_out=generated_proto --go-grpc_opt=paths=source_relative \ + -I ${PROTO_INPUT_FOLDER} \ + ${PROTO_INPUT} + +go get google.golang.org/grpc diff --git a/common/go/src/asapo_common/generated_proto/AsapoMonitoringCommonService.pb.go b/common/go/src/asapo_common/generated_proto/AsapoMonitoringCommonService.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..070b5ebe4b62d828353c7ff54126f1fba6869d86 --- /dev/null +++ b/common/go/src/asapo_common/generated_proto/AsapoMonitoringCommonService.pb.go @@ -0,0 +1,132 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.26.0-devel +// protoc v3.15.8 +// source: AsapoMonitoringCommonService.proto + +package generated_proto + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Empty struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *Empty) Reset() { + *x = Empty{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringCommonService_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Empty) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Empty) ProtoMessage() {} + +func (x *Empty) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringCommonService_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Empty.ProtoReflect.Descriptor instead. +func (*Empty) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringCommonService_proto_rawDescGZIP(), []int{0} +} + +var File_AsapoMonitoringCommonService_proto protoreflect.FileDescriptor + +var file_AsapoMonitoringCommonService_proto_rawDesc = []byte{ + 0x0a, 0x22, 0x41, 0x73, 0x61, 0x70, 0x6f, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, + 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x07, 0x0a, 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x13, 0x5a, + 0x11, 0x2e, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_AsapoMonitoringCommonService_proto_rawDescOnce sync.Once + file_AsapoMonitoringCommonService_proto_rawDescData = file_AsapoMonitoringCommonService_proto_rawDesc +) + +func file_AsapoMonitoringCommonService_proto_rawDescGZIP() []byte { + file_AsapoMonitoringCommonService_proto_rawDescOnce.Do(func() { + file_AsapoMonitoringCommonService_proto_rawDescData = protoimpl.X.CompressGZIP(file_AsapoMonitoringCommonService_proto_rawDescData) + }) + return file_AsapoMonitoringCommonService_proto_rawDescData +} + +var file_AsapoMonitoringCommonService_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_AsapoMonitoringCommonService_proto_goTypes = []interface{}{ + (*Empty)(nil), // 0: Empty +} +var file_AsapoMonitoringCommonService_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_AsapoMonitoringCommonService_proto_init() } +func file_AsapoMonitoringCommonService_proto_init() { + if File_AsapoMonitoringCommonService_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_AsapoMonitoringCommonService_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Empty); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_AsapoMonitoringCommonService_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_AsapoMonitoringCommonService_proto_goTypes, + DependencyIndexes: file_AsapoMonitoringCommonService_proto_depIdxs, + MessageInfos: file_AsapoMonitoringCommonService_proto_msgTypes, + }.Build() + File_AsapoMonitoringCommonService_proto = out.File + file_AsapoMonitoringCommonService_proto_rawDesc = nil + file_AsapoMonitoringCommonService_proto_goTypes = nil + file_AsapoMonitoringCommonService_proto_depIdxs = nil +} diff --git a/common/go/src/asapo_common/generated_proto/AsapoMonitoringIngestService.pb.go b/common/go/src/asapo_common/generated_proto/AsapoMonitoringIngestService.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..9977231872de70e0826bebc1193e61fadff8cff7 --- /dev/null +++ b/common/go/src/asapo_common/generated_proto/AsapoMonitoringIngestService.pb.go @@ -0,0 +1,1080 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.26.0-devel +// protoc v3.15.8 +// source: AsapoMonitoringIngestService.proto + +package generated_proto + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ProducerToReceiverTransferDataPoint struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PipelineStepId string `protobuf:"bytes,1,opt,name=pipelineStepId,proto3" json:"pipelineStepId,omitempty"` // Customizable from producerLib + ProducerInstanceId string `protobuf:"bytes,2,opt,name=producerInstanceId,proto3" json:"producerInstanceId,omitempty"` + Beamtime string `protobuf:"bytes,3,opt,name=beamtime,proto3" json:"beamtime,omitempty"` + Source string `protobuf:"bytes,4,opt,name=source,proto3" json:"source,omitempty"` + Stream string `protobuf:"bytes,5,opt,name=stream,proto3" json:"stream,omitempty"` + FileCount uint64 `protobuf:"varint,6,opt,name=fileCount,proto3" json:"fileCount,omitempty"` + TotalFileSize uint64 `protobuf:"varint,7,opt,name=totalFileSize,proto3" json:"totalFileSize,omitempty"` + TotalTransferReceiveTimeInMicroseconds uint64 `protobuf:"varint,8,opt,name=totalTransferReceiveTimeInMicroseconds,proto3" json:"totalTransferReceiveTimeInMicroseconds,omitempty"` + TotalWriteIoTimeInMicroseconds uint64 `protobuf:"varint,9,opt,name=totalWriteIoTimeInMicroseconds,proto3" json:"totalWriteIoTimeInMicroseconds,omitempty"` + TotalDbTimeInMicroseconds uint64 `protobuf:"varint,10,opt,name=totalDbTimeInMicroseconds,proto3" json:"totalDbTimeInMicroseconds,omitempty"` +} + +func (x *ProducerToReceiverTransferDataPoint) Reset() { + *x = ProducerToReceiverTransferDataPoint{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringIngestService_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ProducerToReceiverTransferDataPoint) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProducerToReceiverTransferDataPoint) ProtoMessage() {} + +func (x *ProducerToReceiverTransferDataPoint) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringIngestService_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProducerToReceiverTransferDataPoint.ProtoReflect.Descriptor instead. +func (*ProducerToReceiverTransferDataPoint) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringIngestService_proto_rawDescGZIP(), []int{0} +} + +func (x *ProducerToReceiverTransferDataPoint) GetPipelineStepId() string { + if x != nil { + return x.PipelineStepId + } + return "" +} + +func (x *ProducerToReceiverTransferDataPoint) GetProducerInstanceId() string { + if x != nil { + return x.ProducerInstanceId + } + return "" +} + +func (x *ProducerToReceiverTransferDataPoint) GetBeamtime() string { + if x != nil { + return x.Beamtime + } + return "" +} + +func (x *ProducerToReceiverTransferDataPoint) GetSource() string { + if x != nil { + return x.Source + } + return "" +} + +func (x *ProducerToReceiverTransferDataPoint) GetStream() string { + if x != nil { + return x.Stream + } + return "" +} + +func (x *ProducerToReceiverTransferDataPoint) GetFileCount() uint64 { + if x != nil { + return x.FileCount + } + return 0 +} + +func (x *ProducerToReceiverTransferDataPoint) GetTotalFileSize() uint64 { + if x != nil { + return x.TotalFileSize + } + return 0 +} + +func (x *ProducerToReceiverTransferDataPoint) GetTotalTransferReceiveTimeInMicroseconds() uint64 { + if x != nil { + return x.TotalTransferReceiveTimeInMicroseconds + } + return 0 +} + +func (x *ProducerToReceiverTransferDataPoint) GetTotalWriteIoTimeInMicroseconds() uint64 { + if x != nil { + return x.TotalWriteIoTimeInMicroseconds + } + return 0 +} + +func (x *ProducerToReceiverTransferDataPoint) GetTotalDbTimeInMicroseconds() uint64 { + if x != nil { + return x.TotalDbTimeInMicroseconds + } + return 0 +} + +type BrokerRequestDataPoint struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PipelineStepId string `protobuf:"bytes,1,opt,name=pipelineStepId,proto3" json:"pipelineStepId,omitempty"` // Customizable from consumerLib can indicates a linkage between a consumer and a producer + ConsumerInstanceId string `protobuf:"bytes,2,opt,name=consumerInstanceId,proto3" json:"consumerInstanceId,omitempty"` + Command string `protobuf:"bytes,3,opt,name=command,proto3" json:"command,omitempty"` // e.g. 'get_next', 'get_last', 'get_by_id' + Beamtime string `protobuf:"bytes,4,opt,name=beamtime,proto3" json:"beamtime,omitempty"` + Source string `protobuf:"bytes,5,opt,name=source,proto3" json:"source,omitempty"` + Stream string `protobuf:"bytes,6,opt,name=stream,proto3" json:"stream,omitempty"` + FileCount uint64 `protobuf:"varint,7,opt,name=fileCount,proto3" json:"fileCount,omitempty"` + TotalFileSize uint64 `protobuf:"varint,8,opt,name=totalFileSize,proto3" json:"totalFileSize,omitempty"` +} + +func (x *BrokerRequestDataPoint) Reset() { + *x = BrokerRequestDataPoint{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringIngestService_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BrokerRequestDataPoint) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BrokerRequestDataPoint) ProtoMessage() {} + +func (x *BrokerRequestDataPoint) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringIngestService_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BrokerRequestDataPoint.ProtoReflect.Descriptor instead. +func (*BrokerRequestDataPoint) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringIngestService_proto_rawDescGZIP(), []int{1} +} + +func (x *BrokerRequestDataPoint) GetPipelineStepId() string { + if x != nil { + return x.PipelineStepId + } + return "" +} + +func (x *BrokerRequestDataPoint) GetConsumerInstanceId() string { + if x != nil { + return x.ConsumerInstanceId + } + return "" +} + +func (x *BrokerRequestDataPoint) GetCommand() string { + if x != nil { + return x.Command + } + return "" +} + +func (x *BrokerRequestDataPoint) GetBeamtime() string { + if x != nil { + return x.Beamtime + } + return "" +} + +func (x *BrokerRequestDataPoint) GetSource() string { + if x != nil { + return x.Source + } + return "" +} + +func (x *BrokerRequestDataPoint) GetStream() string { + if x != nil { + return x.Stream + } + return "" +} + +func (x *BrokerRequestDataPoint) GetFileCount() uint64 { + if x != nil { + return x.FileCount + } + return 0 +} + +func (x *BrokerRequestDataPoint) GetTotalFileSize() uint64 { + if x != nil { + return x.TotalFileSize + } + return 0 +} + +type RdsMemoryDataPoint struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Beamtime string `protobuf:"bytes,1,opt,name=beamtime,proto3" json:"beamtime,omitempty"` + Source string `protobuf:"bytes,2,opt,name=source,proto3" json:"source,omitempty"` + Stream string `protobuf:"bytes,3,opt,name=stream,proto3" json:"stream,omitempty"` + UsedBytes uint64 `protobuf:"varint,4,opt,name=usedBytes,proto3" json:"usedBytes,omitempty"` + TotalBytes uint64 `protobuf:"varint,5,opt,name=totalBytes,proto3" json:"totalBytes,omitempty"` +} + +func (x *RdsMemoryDataPoint) Reset() { + *x = RdsMemoryDataPoint{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringIngestService_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RdsMemoryDataPoint) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RdsMemoryDataPoint) ProtoMessage() {} + +func (x *RdsMemoryDataPoint) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringIngestService_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RdsMemoryDataPoint.ProtoReflect.Descriptor instead. +func (*RdsMemoryDataPoint) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringIngestService_proto_rawDescGZIP(), []int{2} +} + +func (x *RdsMemoryDataPoint) GetBeamtime() string { + if x != nil { + return x.Beamtime + } + return "" +} + +func (x *RdsMemoryDataPoint) GetSource() string { + if x != nil { + return x.Source + } + return "" +} + +func (x *RdsMemoryDataPoint) GetStream() string { + if x != nil { + return x.Stream + } + return "" +} + +func (x *RdsMemoryDataPoint) GetUsedBytes() uint64 { + if x != nil { + return x.UsedBytes + } + return 0 +} + +func (x *RdsMemoryDataPoint) GetTotalBytes() uint64 { + if x != nil { + return x.TotalBytes + } + return 0 +} + +type RdsToConsumerDataPoint struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PipelineStepId string `protobuf:"bytes,1,opt,name=pipelineStepId,proto3" json:"pipelineStepId,omitempty"` // Customizable from consumerLib can indicates a linkage between a consumer and a producer + ConsumerInstanceId string `protobuf:"bytes,2,opt,name=consumerInstanceId,proto3" json:"consumerInstanceId,omitempty"` + Beamtime string `protobuf:"bytes,3,opt,name=beamtime,proto3" json:"beamtime,omitempty"` + Source string `protobuf:"bytes,4,opt,name=source,proto3" json:"source,omitempty"` + Stream string `protobuf:"bytes,5,opt,name=stream,proto3" json:"stream,omitempty"` + Hits uint64 `protobuf:"varint,6,opt,name=hits,proto3" json:"hits,omitempty"` + Misses uint64 `protobuf:"varint,7,opt,name=misses,proto3" json:"misses,omitempty"` + TotalFileSize uint64 `protobuf:"varint,8,opt,name=totalFileSize,proto3" json:"totalFileSize,omitempty"` + TotalTransferSendTimeInMicroseconds uint64 `protobuf:"varint,9,opt,name=totalTransferSendTimeInMicroseconds,proto3" json:"totalTransferSendTimeInMicroseconds,omitempty"` +} + +func (x *RdsToConsumerDataPoint) Reset() { + *x = RdsToConsumerDataPoint{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringIngestService_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RdsToConsumerDataPoint) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RdsToConsumerDataPoint) ProtoMessage() {} + +func (x *RdsToConsumerDataPoint) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringIngestService_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RdsToConsumerDataPoint.ProtoReflect.Descriptor instead. +func (*RdsToConsumerDataPoint) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringIngestService_proto_rawDescGZIP(), []int{3} +} + +func (x *RdsToConsumerDataPoint) GetPipelineStepId() string { + if x != nil { + return x.PipelineStepId + } + return "" +} + +func (x *RdsToConsumerDataPoint) GetConsumerInstanceId() string { + if x != nil { + return x.ConsumerInstanceId + } + return "" +} + +func (x *RdsToConsumerDataPoint) GetBeamtime() string { + if x != nil { + return x.Beamtime + } + return "" +} + +func (x *RdsToConsumerDataPoint) GetSource() string { + if x != nil { + return x.Source + } + return "" +} + +func (x *RdsToConsumerDataPoint) GetStream() string { + if x != nil { + return x.Stream + } + return "" +} + +func (x *RdsToConsumerDataPoint) GetHits() uint64 { + if x != nil { + return x.Hits + } + return 0 +} + +func (x *RdsToConsumerDataPoint) GetMisses() uint64 { + if x != nil { + return x.Misses + } + return 0 +} + +func (x *RdsToConsumerDataPoint) GetTotalFileSize() uint64 { + if x != nil { + return x.TotalFileSize + } + return 0 +} + +func (x *RdsToConsumerDataPoint) GetTotalTransferSendTimeInMicroseconds() uint64 { + if x != nil { + return x.TotalTransferSendTimeInMicroseconds + } + return 0 +} + +type FdsToConsumerDataPoint struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PipelineStepId string `protobuf:"bytes,1,opt,name=pipelineStepId,proto3" json:"pipelineStepId,omitempty"` // Customizable from consumerLib can indicates a linkage between a consumer and a producer + ConsumerInstanceId string `protobuf:"bytes,2,opt,name=consumerInstanceId,proto3" json:"consumerInstanceId,omitempty"` + Beamtime string `protobuf:"bytes,3,opt,name=beamtime,proto3" json:"beamtime,omitempty"` + Source string `protobuf:"bytes,4,opt,name=source,proto3" json:"source,omitempty"` + Stream string `protobuf:"bytes,5,opt,name=stream,proto3" json:"stream,omitempty"` + FileCount uint64 `protobuf:"varint,6,opt,name=fileCount,proto3" json:"fileCount,omitempty"` + TotalFileSize uint64 `protobuf:"varint,7,opt,name=totalFileSize,proto3" json:"totalFileSize,omitempty"` + TotalTransferSendTimeInMicroseconds uint64 `protobuf:"varint,8,opt,name=totalTransferSendTimeInMicroseconds,proto3" json:"totalTransferSendTimeInMicroseconds,omitempty"` +} + +func (x *FdsToConsumerDataPoint) Reset() { + *x = FdsToConsumerDataPoint{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringIngestService_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FdsToConsumerDataPoint) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FdsToConsumerDataPoint) ProtoMessage() {} + +func (x *FdsToConsumerDataPoint) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringIngestService_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FdsToConsumerDataPoint.ProtoReflect.Descriptor instead. +func (*FdsToConsumerDataPoint) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringIngestService_proto_rawDescGZIP(), []int{4} +} + +func (x *FdsToConsumerDataPoint) GetPipelineStepId() string { + if x != nil { + return x.PipelineStepId + } + return "" +} + +func (x *FdsToConsumerDataPoint) GetConsumerInstanceId() string { + if x != nil { + return x.ConsumerInstanceId + } + return "" +} + +func (x *FdsToConsumerDataPoint) GetBeamtime() string { + if x != nil { + return x.Beamtime + } + return "" +} + +func (x *FdsToConsumerDataPoint) GetSource() string { + if x != nil { + return x.Source + } + return "" +} + +func (x *FdsToConsumerDataPoint) GetStream() string { + if x != nil { + return x.Stream + } + return "" +} + +func (x *FdsToConsumerDataPoint) GetFileCount() uint64 { + if x != nil { + return x.FileCount + } + return 0 +} + +func (x *FdsToConsumerDataPoint) GetTotalFileSize() uint64 { + if x != nil { + return x.TotalFileSize + } + return 0 +} + +func (x *FdsToConsumerDataPoint) GetTotalTransferSendTimeInMicroseconds() uint64 { + if x != nil { + return x.TotalTransferSendTimeInMicroseconds + } + return 0 +} + +// ---- Containers ---- +type ReceiverDataPointContainer struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ReceiverName string `protobuf:"bytes,1,opt,name=receiverName,proto3" json:"receiverName,omitempty"` // Receiver InstanceId + TimestampMs uint64 `protobuf:"varint,2,opt,name=timestampMs,proto3" json:"timestampMs,omitempty"` + GroupedP2RTransfers []*ProducerToReceiverTransferDataPoint `protobuf:"bytes,3,rep,name=groupedP2rTransfers,proto3" json:"groupedP2rTransfers,omitempty"` + GroupedRds2CTransfers []*RdsToConsumerDataPoint `protobuf:"bytes,4,rep,name=groupedRds2cTransfers,proto3" json:"groupedRds2cTransfers,omitempty"` + GroupedMemoryStats []*RdsMemoryDataPoint `protobuf:"bytes,5,rep,name=groupedMemoryStats,proto3" json:"groupedMemoryStats,omitempty"` +} + +func (x *ReceiverDataPointContainer) Reset() { + *x = ReceiverDataPointContainer{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringIngestService_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReceiverDataPointContainer) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReceiverDataPointContainer) ProtoMessage() {} + +func (x *ReceiverDataPointContainer) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringIngestService_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReceiverDataPointContainer.ProtoReflect.Descriptor instead. +func (*ReceiverDataPointContainer) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringIngestService_proto_rawDescGZIP(), []int{5} +} + +func (x *ReceiverDataPointContainer) GetReceiverName() string { + if x != nil { + return x.ReceiverName + } + return "" +} + +func (x *ReceiverDataPointContainer) GetTimestampMs() uint64 { + if x != nil { + return x.TimestampMs + } + return 0 +} + +func (x *ReceiverDataPointContainer) GetGroupedP2RTransfers() []*ProducerToReceiverTransferDataPoint { + if x != nil { + return x.GroupedP2RTransfers + } + return nil +} + +func (x *ReceiverDataPointContainer) GetGroupedRds2CTransfers() []*RdsToConsumerDataPoint { + if x != nil { + return x.GroupedRds2CTransfers + } + return nil +} + +func (x *ReceiverDataPointContainer) GetGroupedMemoryStats() []*RdsMemoryDataPoint { + if x != nil { + return x.GroupedMemoryStats + } + return nil +} + +type BrokerDataPointContainer struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + BrokerName string `protobuf:"bytes,1,opt,name=brokerName,proto3" json:"brokerName,omitempty"` // Broker InstanceId + TimestampMs uint64 `protobuf:"varint,2,opt,name=timestampMs,proto3" json:"timestampMs,omitempty"` + GroupedBrokerRequests []*BrokerRequestDataPoint `protobuf:"bytes,3,rep,name=groupedBrokerRequests,proto3" json:"groupedBrokerRequests,omitempty"` +} + +func (x *BrokerDataPointContainer) Reset() { + *x = BrokerDataPointContainer{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringIngestService_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BrokerDataPointContainer) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BrokerDataPointContainer) ProtoMessage() {} + +func (x *BrokerDataPointContainer) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringIngestService_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BrokerDataPointContainer.ProtoReflect.Descriptor instead. +func (*BrokerDataPointContainer) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringIngestService_proto_rawDescGZIP(), []int{6} +} + +func (x *BrokerDataPointContainer) GetBrokerName() string { + if x != nil { + return x.BrokerName + } + return "" +} + +func (x *BrokerDataPointContainer) GetTimestampMs() uint64 { + if x != nil { + return x.TimestampMs + } + return 0 +} + +func (x *BrokerDataPointContainer) GetGroupedBrokerRequests() []*BrokerRequestDataPoint { + if x != nil { + return x.GroupedBrokerRequests + } + return nil +} + +type FtsToConsumerDataPointContainer struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + FtsName string `protobuf:"bytes,1,opt,name=ftsName,proto3" json:"ftsName,omitempty"` // FTS InstanceId + TimestampMs uint64 `protobuf:"varint,2,opt,name=timestampMs,proto3" json:"timestampMs,omitempty"` + GroupedFdsTransfers []*FdsToConsumerDataPoint `protobuf:"bytes,3,rep,name=groupedFdsTransfers,proto3" json:"groupedFdsTransfers,omitempty"` +} + +func (x *FtsToConsumerDataPointContainer) Reset() { + *x = FtsToConsumerDataPointContainer{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringIngestService_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FtsToConsumerDataPointContainer) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FtsToConsumerDataPointContainer) ProtoMessage() {} + +func (x *FtsToConsumerDataPointContainer) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringIngestService_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FtsToConsumerDataPointContainer.ProtoReflect.Descriptor instead. +func (*FtsToConsumerDataPointContainer) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringIngestService_proto_rawDescGZIP(), []int{7} +} + +func (x *FtsToConsumerDataPointContainer) GetFtsName() string { + if x != nil { + return x.FtsName + } + return "" +} + +func (x *FtsToConsumerDataPointContainer) GetTimestampMs() uint64 { + if x != nil { + return x.TimestampMs + } + return 0 +} + +func (x *FtsToConsumerDataPointContainer) GetGroupedFdsTransfers() []*FdsToConsumerDataPoint { + if x != nil { + return x.GroupedFdsTransfers + } + return nil +} + +var File_AsapoMonitoringIngestService_proto protoreflect.FileDescriptor + +var file_AsapoMonitoringIngestService_proto_rawDesc = []byte{ + 0x0a, 0x22, 0x41, 0x73, 0x61, 0x70, 0x6f, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, + 0x67, 0x49, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x22, 0x41, 0x73, 0x61, 0x70, 0x6f, 0x4d, 0x6f, 0x6e, 0x69, 0x74, + 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xeb, 0x03, 0x0a, 0x23, 0x50, 0x72, 0x6f, + 0x64, 0x75, 0x63, 0x65, 0x72, 0x54, 0x6f, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x54, + 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, + 0x12, 0x26, 0x0a, 0x0e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, + 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, + 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x12, 0x70, 0x72, 0x6f, 0x64, + 0x75, 0x63, 0x65, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x49, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x65, 0x61, 0x6d, + 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x65, 0x61, 0x6d, + 0x74, 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, + 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x53, + 0x69, 0x7a, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, + 0x46, 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x56, 0x0a, 0x26, 0x74, 0x6f, 0x74, 0x61, + 0x6c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, + 0x54, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, + 0x64, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x26, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x54, + 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x54, 0x69, + 0x6d, 0x65, 0x49, 0x6e, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, + 0x12, 0x46, 0x0a, 0x1e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x57, 0x72, 0x69, 0x74, 0x65, 0x49, 0x6f, + 0x54, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, + 0x64, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x1e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x57, + 0x72, 0x69, 0x74, 0x65, 0x49, 0x6f, 0x54, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x4d, 0x69, 0x63, 0x72, + 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x3c, 0x0a, 0x19, 0x74, 0x6f, 0x74, 0x61, + 0x6c, 0x44, 0x62, 0x54, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x65, + 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x19, 0x74, 0x6f, 0x74, + 0x61, 0x6c, 0x44, 0x62, 0x54, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, + 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x22, 0x9a, 0x02, 0x0a, 0x16, 0x42, 0x72, 0x6f, 0x6b, 0x65, + 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, + 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, + 0x70, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x70, 0x69, 0x70, 0x65, 0x6c, + 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x12, 0x63, 0x6f, 0x6e, + 0x73, 0x75, 0x6d, 0x65, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x49, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, + 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, + 0x61, 0x6e, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x65, 0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x65, 0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x12, + 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, + 0x1c, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x24, 0x0a, + 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x53, + 0x69, 0x7a, 0x65, 0x22, 0x9e, 0x01, 0x0a, 0x12, 0x52, 0x64, 0x73, 0x4d, 0x65, 0x6d, 0x6f, 0x72, + 0x79, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x65, + 0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x65, + 0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x16, + 0x0a, 0x06, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1c, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x64, 0x42, 0x79, + 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x75, 0x73, 0x65, 0x64, 0x42, + 0x79, 0x74, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, 0x79, 0x74, + 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, + 0x79, 0x74, 0x65, 0x73, 0x22, 0xe0, 0x02, 0x0a, 0x16, 0x52, 0x64, 0x73, 0x54, 0x6f, 0x43, 0x6f, + 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, + 0x26, 0x0a, 0x0e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x49, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, + 0x65, 0x53, 0x74, 0x65, 0x70, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x12, 0x63, 0x6f, 0x6e, 0x73, 0x75, + 0x6d, 0x65, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x49, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x65, 0x61, 0x6d, 0x74, + 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x65, 0x61, 0x6d, 0x74, + 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x69, 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x04, 0x68, 0x69, 0x74, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x69, 0x73, 0x73, 0x65, + 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6d, 0x69, 0x73, 0x73, 0x65, 0x73, 0x12, + 0x24, 0x0a, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x46, 0x69, 0x6c, + 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x50, 0x0a, 0x23, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x49, 0x6e, + 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x09, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x23, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, + 0x72, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x4d, 0x69, 0x63, 0x72, 0x6f, + 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x22, 0xd2, 0x02, 0x0a, 0x16, 0x46, 0x64, 0x73, 0x54, + 0x6f, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, + 0x6e, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, + 0x65, 0x70, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x70, 0x69, 0x70, 0x65, + 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x12, 0x63, 0x6f, + 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, + 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x65, + 0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x65, + 0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x16, + 0x0a, 0x06, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, + 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x46, 0x69, 0x6c, + 0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x6f, 0x74, + 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x50, 0x0a, 0x23, 0x74, 0x6f, + 0x74, 0x61, 0x6c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x53, 0x65, 0x6e, 0x64, 0x54, + 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, + 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x23, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x49, 0x6e, + 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x22, 0xce, 0x02, 0x0a, + 0x1a, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, + 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x22, 0x0a, 0x0c, 0x72, + 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0c, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x20, 0x0a, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, + 0x73, 0x12, 0x56, 0x0a, 0x13, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x50, 0x32, 0x72, 0x54, + 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, + 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x54, 0x6f, 0x52, 0x65, 0x63, 0x65, 0x69, + 0x76, 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, + 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x13, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x50, 0x32, 0x72, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x12, 0x4d, 0x0a, 0x15, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x65, 0x64, 0x52, 0x64, 0x73, 0x32, 0x63, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, + 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x52, 0x64, 0x73, 0x54, 0x6f, + 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, + 0x74, 0x52, 0x15, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x52, 0x64, 0x73, 0x32, 0x63, 0x54, + 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x12, 0x43, 0x0a, 0x12, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x65, 0x64, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x73, 0x18, 0x05, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x52, 0x64, 0x73, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, + 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x12, 0x67, 0x72, 0x6f, 0x75, 0x70, + 0x65, 0x64, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x73, 0x22, 0xab, 0x01, + 0x0a, 0x18, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, + 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x62, 0x72, + 0x6f, 0x6b, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x62, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, 0x73, 0x12, 0x4d, 0x0a, 0x15, + 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x42, 0x72, + 0x6f, 0x6b, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x44, 0x61, 0x74, 0x61, 0x50, + 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x15, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x42, 0x72, 0x6f, + 0x6b, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x22, 0xa8, 0x01, 0x0a, 0x1f, + 0x46, 0x74, 0x73, 0x54, 0x6f, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x44, 0x61, 0x74, + 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, + 0x18, 0x0a, 0x07, 0x66, 0x74, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x66, 0x74, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, 0x73, 0x12, 0x49, 0x0a, 0x13, 0x67, + 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x46, 0x64, 0x73, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, + 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x46, 0x64, 0x73, 0x54, 0x6f, + 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, + 0x74, 0x52, 0x13, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x46, 0x64, 0x73, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x32, 0xe3, 0x01, 0x0a, 0x1c, 0x41, 0x73, 0x61, 0x70, 0x6f, + 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x67, 0x65, 0x73, 0x74, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x41, 0x0a, 0x18, 0x49, 0x6e, 0x73, 0x65, 0x72, + 0x74, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, + 0x6e, 0x74, 0x73, 0x12, 0x1b, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x44, 0x61, + 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x3d, 0x0a, 0x16, 0x49, 0x6e, + 0x73, 0x65, 0x72, 0x74, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, + 0x69, 0x6e, 0x74, 0x73, 0x12, 0x19, 0x2e, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x44, 0x61, 0x74, + 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x1a, + 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x13, 0x49, 0x6e, 0x73, + 0x65, 0x72, 0x74, 0x46, 0x74, 0x73, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, + 0x12, 0x20, 0x2e, 0x46, 0x74, 0x73, 0x54, 0x6f, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, + 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x13, 0x5a, 0x11, + 0x2e, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_AsapoMonitoringIngestService_proto_rawDescOnce sync.Once + file_AsapoMonitoringIngestService_proto_rawDescData = file_AsapoMonitoringIngestService_proto_rawDesc +) + +func file_AsapoMonitoringIngestService_proto_rawDescGZIP() []byte { + file_AsapoMonitoringIngestService_proto_rawDescOnce.Do(func() { + file_AsapoMonitoringIngestService_proto_rawDescData = protoimpl.X.CompressGZIP(file_AsapoMonitoringIngestService_proto_rawDescData) + }) + return file_AsapoMonitoringIngestService_proto_rawDescData +} + +var file_AsapoMonitoringIngestService_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_AsapoMonitoringIngestService_proto_goTypes = []interface{}{ + (*ProducerToReceiverTransferDataPoint)(nil), // 0: ProducerToReceiverTransferDataPoint + (*BrokerRequestDataPoint)(nil), // 1: BrokerRequestDataPoint + (*RdsMemoryDataPoint)(nil), // 2: RdsMemoryDataPoint + (*RdsToConsumerDataPoint)(nil), // 3: RdsToConsumerDataPoint + (*FdsToConsumerDataPoint)(nil), // 4: FdsToConsumerDataPoint + (*ReceiverDataPointContainer)(nil), // 5: ReceiverDataPointContainer + (*BrokerDataPointContainer)(nil), // 6: BrokerDataPointContainer + (*FtsToConsumerDataPointContainer)(nil), // 7: FtsToConsumerDataPointContainer + (*Empty)(nil), // 8: Empty +} +var file_AsapoMonitoringIngestService_proto_depIdxs = []int32{ + 0, // 0: ReceiverDataPointContainer.groupedP2rTransfers:type_name -> ProducerToReceiverTransferDataPoint + 3, // 1: ReceiverDataPointContainer.groupedRds2cTransfers:type_name -> RdsToConsumerDataPoint + 2, // 2: ReceiverDataPointContainer.groupedMemoryStats:type_name -> RdsMemoryDataPoint + 1, // 3: BrokerDataPointContainer.groupedBrokerRequests:type_name -> BrokerRequestDataPoint + 4, // 4: FtsToConsumerDataPointContainer.groupedFdsTransfers:type_name -> FdsToConsumerDataPoint + 5, // 5: AsapoMonitoringIngestService.InsertReceiverDataPoints:input_type -> ReceiverDataPointContainer + 6, // 6: AsapoMonitoringIngestService.InsertBrokerDataPoints:input_type -> BrokerDataPointContainer + 7, // 7: AsapoMonitoringIngestService.InsertFtsDataPoints:input_type -> FtsToConsumerDataPointContainer + 8, // 8: AsapoMonitoringIngestService.InsertReceiverDataPoints:output_type -> Empty + 8, // 9: AsapoMonitoringIngestService.InsertBrokerDataPoints:output_type -> Empty + 8, // 10: AsapoMonitoringIngestService.InsertFtsDataPoints:output_type -> Empty + 8, // [8:11] is the sub-list for method output_type + 5, // [5:8] is the sub-list for method input_type + 5, // [5:5] is the sub-list for extension type_name + 5, // [5:5] is the sub-list for extension extendee + 0, // [0:5] is the sub-list for field type_name +} + +func init() { file_AsapoMonitoringIngestService_proto_init() } +func file_AsapoMonitoringIngestService_proto_init() { + if File_AsapoMonitoringIngestService_proto != nil { + return + } + file_AsapoMonitoringCommonService_proto_init() + if !protoimpl.UnsafeEnabled { + file_AsapoMonitoringIngestService_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ProducerToReceiverTransferDataPoint); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_AsapoMonitoringIngestService_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BrokerRequestDataPoint); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_AsapoMonitoringIngestService_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RdsMemoryDataPoint); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_AsapoMonitoringIngestService_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RdsToConsumerDataPoint); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_AsapoMonitoringIngestService_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FdsToConsumerDataPoint); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_AsapoMonitoringIngestService_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReceiverDataPointContainer); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_AsapoMonitoringIngestService_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BrokerDataPointContainer); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_AsapoMonitoringIngestService_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FtsToConsumerDataPointContainer); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_AsapoMonitoringIngestService_proto_rawDesc, + NumEnums: 0, + NumMessages: 8, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_AsapoMonitoringIngestService_proto_goTypes, + DependencyIndexes: file_AsapoMonitoringIngestService_proto_depIdxs, + MessageInfos: file_AsapoMonitoringIngestService_proto_msgTypes, + }.Build() + File_AsapoMonitoringIngestService_proto = out.File + file_AsapoMonitoringIngestService_proto_rawDesc = nil + file_AsapoMonitoringIngestService_proto_goTypes = nil + file_AsapoMonitoringIngestService_proto_depIdxs = nil +} diff --git a/common/go/src/asapo_common/generated_proto/AsapoMonitoringIngestService_grpc.pb.go b/common/go/src/asapo_common/generated_proto/AsapoMonitoringIngestService_grpc.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..e59fc901bbc6386af668c7e1f080ae53227527a6 --- /dev/null +++ b/common/go/src/asapo_common/generated_proto/AsapoMonitoringIngestService_grpc.pb.go @@ -0,0 +1,178 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.1.0 +// - protoc v3.15.8 +// source: AsapoMonitoringIngestService.proto + +package generated_proto + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// AsapoMonitoringIngestServiceClient is the client API for AsapoMonitoringIngestService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type AsapoMonitoringIngestServiceClient interface { + InsertReceiverDataPoints(ctx context.Context, in *ReceiverDataPointContainer, opts ...grpc.CallOption) (*Empty, error) + InsertBrokerDataPoints(ctx context.Context, in *BrokerDataPointContainer, opts ...grpc.CallOption) (*Empty, error) + InsertFtsDataPoints(ctx context.Context, in *FtsToConsumerDataPointContainer, opts ...grpc.CallOption) (*Empty, error) +} + +type asapoMonitoringIngestServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewAsapoMonitoringIngestServiceClient(cc grpc.ClientConnInterface) AsapoMonitoringIngestServiceClient { + return &asapoMonitoringIngestServiceClient{cc} +} + +func (c *asapoMonitoringIngestServiceClient) InsertReceiverDataPoints(ctx context.Context, in *ReceiverDataPointContainer, opts ...grpc.CallOption) (*Empty, error) { + out := new(Empty) + err := c.cc.Invoke(ctx, "/AsapoMonitoringIngestService/InsertReceiverDataPoints", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *asapoMonitoringIngestServiceClient) InsertBrokerDataPoints(ctx context.Context, in *BrokerDataPointContainer, opts ...grpc.CallOption) (*Empty, error) { + out := new(Empty) + err := c.cc.Invoke(ctx, "/AsapoMonitoringIngestService/InsertBrokerDataPoints", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *asapoMonitoringIngestServiceClient) InsertFtsDataPoints(ctx context.Context, in *FtsToConsumerDataPointContainer, opts ...grpc.CallOption) (*Empty, error) { + out := new(Empty) + err := c.cc.Invoke(ctx, "/AsapoMonitoringIngestService/InsertFtsDataPoints", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// AsapoMonitoringIngestServiceServer is the server API for AsapoMonitoringIngestService service. +// All implementations must embed UnimplementedAsapoMonitoringIngestServiceServer +// for forward compatibility +type AsapoMonitoringIngestServiceServer interface { + InsertReceiverDataPoints(context.Context, *ReceiverDataPointContainer) (*Empty, error) + InsertBrokerDataPoints(context.Context, *BrokerDataPointContainer) (*Empty, error) + InsertFtsDataPoints(context.Context, *FtsToConsumerDataPointContainer) (*Empty, error) + mustEmbedUnimplementedAsapoMonitoringIngestServiceServer() +} + +// UnimplementedAsapoMonitoringIngestServiceServer must be embedded to have forward compatible implementations. +type UnimplementedAsapoMonitoringIngestServiceServer struct { +} + +func (UnimplementedAsapoMonitoringIngestServiceServer) InsertReceiverDataPoints(context.Context, *ReceiverDataPointContainer) (*Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method InsertReceiverDataPoints not implemented") +} +func (UnimplementedAsapoMonitoringIngestServiceServer) InsertBrokerDataPoints(context.Context, *BrokerDataPointContainer) (*Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method InsertBrokerDataPoints not implemented") +} +func (UnimplementedAsapoMonitoringIngestServiceServer) InsertFtsDataPoints(context.Context, *FtsToConsumerDataPointContainer) (*Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method InsertFtsDataPoints not implemented") +} +func (UnimplementedAsapoMonitoringIngestServiceServer) mustEmbedUnimplementedAsapoMonitoringIngestServiceServer() { +} + +// UnsafeAsapoMonitoringIngestServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to AsapoMonitoringIngestServiceServer will +// result in compilation errors. +type UnsafeAsapoMonitoringIngestServiceServer interface { + mustEmbedUnimplementedAsapoMonitoringIngestServiceServer() +} + +func RegisterAsapoMonitoringIngestServiceServer(s grpc.ServiceRegistrar, srv AsapoMonitoringIngestServiceServer) { + s.RegisterService(&AsapoMonitoringIngestService_ServiceDesc, srv) +} + +func _AsapoMonitoringIngestService_InsertReceiverDataPoints_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ReceiverDataPointContainer) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AsapoMonitoringIngestServiceServer).InsertReceiverDataPoints(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/AsapoMonitoringIngestService/InsertReceiverDataPoints", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AsapoMonitoringIngestServiceServer).InsertReceiverDataPoints(ctx, req.(*ReceiverDataPointContainer)) + } + return interceptor(ctx, in, info, handler) +} + +func _AsapoMonitoringIngestService_InsertBrokerDataPoints_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(BrokerDataPointContainer) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AsapoMonitoringIngestServiceServer).InsertBrokerDataPoints(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/AsapoMonitoringIngestService/InsertBrokerDataPoints", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AsapoMonitoringIngestServiceServer).InsertBrokerDataPoints(ctx, req.(*BrokerDataPointContainer)) + } + return interceptor(ctx, in, info, handler) +} + +func _AsapoMonitoringIngestService_InsertFtsDataPoints_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(FtsToConsumerDataPointContainer) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AsapoMonitoringIngestServiceServer).InsertFtsDataPoints(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/AsapoMonitoringIngestService/InsertFtsDataPoints", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AsapoMonitoringIngestServiceServer).InsertFtsDataPoints(ctx, req.(*FtsToConsumerDataPointContainer)) + } + return interceptor(ctx, in, info, handler) +} + +// AsapoMonitoringIngestService_ServiceDesc is the grpc.ServiceDesc for AsapoMonitoringIngestService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var AsapoMonitoringIngestService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "AsapoMonitoringIngestService", + HandlerType: (*AsapoMonitoringIngestServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "InsertReceiverDataPoints", + Handler: _AsapoMonitoringIngestService_InsertReceiverDataPoints_Handler, + }, + { + MethodName: "InsertBrokerDataPoints", + Handler: _AsapoMonitoringIngestService_InsertBrokerDataPoints_Handler, + }, + { + MethodName: "InsertFtsDataPoints", + Handler: _AsapoMonitoringIngestService_InsertFtsDataPoints_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "AsapoMonitoringIngestService.proto", +} diff --git a/common/go/src/asapo_common/generated_proto/AsapoMonitoringQueryService.pb.go b/common/go/src/asapo_common/generated_proto/AsapoMonitoringQueryService.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..95db885aad0be09288590cb4dd7a5f1d23c692b7 --- /dev/null +++ b/common/go/src/asapo_common/generated_proto/AsapoMonitoringQueryService.pb.go @@ -0,0 +1,1207 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.26.0-devel +// protoc v3.15.8 +// source: AsapoMonitoringQueryService.proto + +package generated_proto + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type PipelineConnectionQueryMode int32 + +const ( + PipelineConnectionQueryMode_INVALID_QUERY_MODE PipelineConnectionQueryMode = 0 + PipelineConnectionQueryMode_ExactPath PipelineConnectionQueryMode = 1 + PipelineConnectionQueryMode_JustRelatedToStep PipelineConnectionQueryMode = 2 +) + +// Enum value maps for PipelineConnectionQueryMode. +var ( + PipelineConnectionQueryMode_name = map[int32]string{ + 0: "INVALID_QUERY_MODE", + 1: "ExactPath", + 2: "JustRelatedToStep", + } + PipelineConnectionQueryMode_value = map[string]int32{ + "INVALID_QUERY_MODE": 0, + "ExactPath": 1, + "JustRelatedToStep": 2, + } +) + +func (x PipelineConnectionQueryMode) Enum() *PipelineConnectionQueryMode { + p := new(PipelineConnectionQueryMode) + *p = x + return p +} + +func (x PipelineConnectionQueryMode) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (PipelineConnectionQueryMode) Descriptor() protoreflect.EnumDescriptor { + return file_AsapoMonitoringQueryService_proto_enumTypes[0].Descriptor() +} + +func (PipelineConnectionQueryMode) Type() protoreflect.EnumType { + return &file_AsapoMonitoringQueryService_proto_enumTypes[0] +} + +func (x PipelineConnectionQueryMode) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use PipelineConnectionQueryMode.Descriptor instead. +func (PipelineConnectionQueryMode) EnumDescriptor() ([]byte, []int) { + return file_AsapoMonitoringQueryService_proto_rawDescGZIP(), []int{0} +} + +type DataPointsQuery struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + FromTimestamp uint64 `protobuf:"varint,1,opt,name=fromTimestamp,proto3" json:"fromTimestamp,omitempty"` + ToTimestamp uint64 `protobuf:"varint,2,opt,name=toTimestamp,proto3" json:"toTimestamp,omitempty"` + BeamtimeFilter string `protobuf:"bytes,4,opt,name=beamtimeFilter,proto3" json:"beamtimeFilter,omitempty"` + SourceFilter string `protobuf:"bytes,5,opt,name=sourceFilter,proto3" json:"sourceFilter,omitempty"` + ReceiverFilter string `protobuf:"bytes,6,opt,name=receiverFilter,proto3" json:"receiverFilter,omitempty"` + FromPipelineStepFilter string `protobuf:"bytes,7,opt,name=fromPipelineStepFilter,proto3" json:"fromPipelineStepFilter,omitempty"` + ToPipelineStepFilter string `protobuf:"bytes,8,opt,name=toPipelineStepFilter,proto3" json:"toPipelineStepFilter,omitempty"` + PipelineQueryMode PipelineConnectionQueryMode `protobuf:"varint,9,opt,name=pipelineQueryMode,proto3,enum=PipelineConnectionQueryMode" json:"pipelineQueryMode,omitempty"` +} + +func (x *DataPointsQuery) Reset() { + *x = DataPointsQuery{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DataPointsQuery) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DataPointsQuery) ProtoMessage() {} + +func (x *DataPointsQuery) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DataPointsQuery.ProtoReflect.Descriptor instead. +func (*DataPointsQuery) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringQueryService_proto_rawDescGZIP(), []int{0} +} + +func (x *DataPointsQuery) GetFromTimestamp() uint64 { + if x != nil { + return x.FromTimestamp + } + return 0 +} + +func (x *DataPointsQuery) GetToTimestamp() uint64 { + if x != nil { + return x.ToTimestamp + } + return 0 +} + +func (x *DataPointsQuery) GetBeamtimeFilter() string { + if x != nil { + return x.BeamtimeFilter + } + return "" +} + +func (x *DataPointsQuery) GetSourceFilter() string { + if x != nil { + return x.SourceFilter + } + return "" +} + +func (x *DataPointsQuery) GetReceiverFilter() string { + if x != nil { + return x.ReceiverFilter + } + return "" +} + +func (x *DataPointsQuery) GetFromPipelineStepFilter() string { + if x != nil { + return x.FromPipelineStepFilter + } + return "" +} + +func (x *DataPointsQuery) GetToPipelineStepFilter() string { + if x != nil { + return x.ToPipelineStepFilter + } + return "" +} + +func (x *DataPointsQuery) GetPipelineQueryMode() PipelineConnectionQueryMode { + if x != nil { + return x.PipelineQueryMode + } + return PipelineConnectionQueryMode_INVALID_QUERY_MODE +} + +type TotalTransferRateDataPoint struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TotalBytesPerSecRecv uint64 `protobuf:"varint,1,opt,name=totalBytesPerSecRecv,proto3" json:"totalBytesPerSecRecv,omitempty"` + TotalBytesPerSecSend uint64 `protobuf:"varint,2,opt,name=totalBytesPerSecSend,proto3" json:"totalBytesPerSecSend,omitempty"` + TotalBytesPerSecRdsSend uint64 `protobuf:"varint,3,opt,name=totalBytesPerSecRdsSend,proto3" json:"totalBytesPerSecRdsSend,omitempty"` + TotalBytesPerSecFtsSend uint64 `protobuf:"varint,4,opt,name=totalBytesPerSecFtsSend,proto3" json:"totalBytesPerSecFtsSend,omitempty"` +} + +func (x *TotalTransferRateDataPoint) Reset() { + *x = TotalTransferRateDataPoint{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TotalTransferRateDataPoint) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TotalTransferRateDataPoint) ProtoMessage() {} + +func (x *TotalTransferRateDataPoint) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TotalTransferRateDataPoint.ProtoReflect.Descriptor instead. +func (*TotalTransferRateDataPoint) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringQueryService_proto_rawDescGZIP(), []int{1} +} + +func (x *TotalTransferRateDataPoint) GetTotalBytesPerSecRecv() uint64 { + if x != nil { + return x.TotalBytesPerSecRecv + } + return 0 +} + +func (x *TotalTransferRateDataPoint) GetTotalBytesPerSecSend() uint64 { + if x != nil { + return x.TotalBytesPerSecSend + } + return 0 +} + +func (x *TotalTransferRateDataPoint) GetTotalBytesPerSecRdsSend() uint64 { + if x != nil { + return x.TotalBytesPerSecRdsSend + } + return 0 +} + +func (x *TotalTransferRateDataPoint) GetTotalBytesPerSecFtsSend() uint64 { + if x != nil { + return x.TotalBytesPerSecFtsSend + } + return 0 +} + +type TotalFileRateDataPoint struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TotalRequests uint32 `protobuf:"varint,1,opt,name=totalRequests,proto3" json:"totalRequests,omitempty"` + CacheMisses uint32 `protobuf:"varint,2,opt,name=cacheMisses,proto3" json:"cacheMisses,omitempty"` + FromCache uint32 `protobuf:"varint,3,opt,name=fromCache,proto3" json:"fromCache,omitempty"` + FromDisk uint32 `protobuf:"varint,4,opt,name=fromDisk,proto3" json:"fromDisk,omitempty"` +} + +func (x *TotalFileRateDataPoint) Reset() { + *x = TotalFileRateDataPoint{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TotalFileRateDataPoint) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TotalFileRateDataPoint) ProtoMessage() {} + +func (x *TotalFileRateDataPoint) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TotalFileRateDataPoint.ProtoReflect.Descriptor instead. +func (*TotalFileRateDataPoint) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringQueryService_proto_rawDescGZIP(), []int{2} +} + +func (x *TotalFileRateDataPoint) GetTotalRequests() uint32 { + if x != nil { + return x.TotalRequests + } + return 0 +} + +func (x *TotalFileRateDataPoint) GetCacheMisses() uint32 { + if x != nil { + return x.CacheMisses + } + return 0 +} + +func (x *TotalFileRateDataPoint) GetFromCache() uint32 { + if x != nil { + return x.FromCache + } + return 0 +} + +func (x *TotalFileRateDataPoint) GetFromDisk() uint32 { + if x != nil { + return x.FromDisk + } + return 0 +} + +type TaskTimeDataPoint struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ReceiveIoTimeUs uint32 `protobuf:"varint,1,opt,name=receiveIoTimeUs,proto3" json:"receiveIoTimeUs,omitempty"` + WriteToDiskTimeUs uint32 `protobuf:"varint,2,opt,name=writeToDiskTimeUs,proto3" json:"writeToDiskTimeUs,omitempty"` + WriteToDatabaseTimeUs uint32 `protobuf:"varint,3,opt,name=writeToDatabaseTimeUs,proto3" json:"writeToDatabaseTimeUs,omitempty"` + RdsSendToConsumerTimeUs uint32 `protobuf:"varint,4,opt,name=rdsSendToConsumerTimeUs,proto3" json:"rdsSendToConsumerTimeUs,omitempty"` +} + +func (x *TaskTimeDataPoint) Reset() { + *x = TaskTimeDataPoint{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TaskTimeDataPoint) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TaskTimeDataPoint) ProtoMessage() {} + +func (x *TaskTimeDataPoint) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TaskTimeDataPoint.ProtoReflect.Descriptor instead. +func (*TaskTimeDataPoint) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringQueryService_proto_rawDescGZIP(), []int{3} +} + +func (x *TaskTimeDataPoint) GetReceiveIoTimeUs() uint32 { + if x != nil { + return x.ReceiveIoTimeUs + } + return 0 +} + +func (x *TaskTimeDataPoint) GetWriteToDiskTimeUs() uint32 { + if x != nil { + return x.WriteToDiskTimeUs + } + return 0 +} + +func (x *TaskTimeDataPoint) GetWriteToDatabaseTimeUs() uint32 { + if x != nil { + return x.WriteToDatabaseTimeUs + } + return 0 +} + +func (x *TaskTimeDataPoint) GetRdsSendToConsumerTimeUs() uint32 { + if x != nil { + return x.RdsSendToConsumerTimeUs + } + return 0 +} + +type RdsMemoryUsageDataPoint struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TotalUsedMemory uint64 `protobuf:"varint,1,opt,name=totalUsedMemory,proto3" json:"totalUsedMemory,omitempty"` //uint64 totalMemory = 2; +} + +func (x *RdsMemoryUsageDataPoint) Reset() { + *x = RdsMemoryUsageDataPoint{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RdsMemoryUsageDataPoint) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RdsMemoryUsageDataPoint) ProtoMessage() {} + +func (x *RdsMemoryUsageDataPoint) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RdsMemoryUsageDataPoint.ProtoReflect.Descriptor instead. +func (*RdsMemoryUsageDataPoint) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringQueryService_proto_rawDescGZIP(), []int{4} +} + +func (x *RdsMemoryUsageDataPoint) GetTotalUsedMemory() uint64 { + if x != nil { + return x.TotalUsedMemory + } + return 0 +} + +type DataPointsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + StartTimestampInSec uint64 `protobuf:"varint,1,opt,name=startTimestampInSec,proto3" json:"startTimestampInSec,omitempty"` + TimeIntervalInSec uint32 `protobuf:"varint,2,opt,name=timeIntervalInSec,proto3" json:"timeIntervalInSec,omitempty"` + TransferRates []*TotalTransferRateDataPoint `protobuf:"bytes,3,rep,name=transferRates,proto3" json:"transferRates,omitempty"` + FileRates []*TotalFileRateDataPoint `protobuf:"bytes,4,rep,name=fileRates,proto3" json:"fileRates,omitempty"` + TaskTimes []*TaskTimeDataPoint `protobuf:"bytes,5,rep,name=taskTimes,proto3" json:"taskTimes,omitempty"` + MemoryUsages []*RdsMemoryUsageDataPoint `protobuf:"bytes,6,rep,name=memoryUsages,proto3" json:"memoryUsages,omitempty"` +} + +func (x *DataPointsResponse) Reset() { + *x = DataPointsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DataPointsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DataPointsResponse) ProtoMessage() {} + +func (x *DataPointsResponse) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DataPointsResponse.ProtoReflect.Descriptor instead. +func (*DataPointsResponse) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringQueryService_proto_rawDescGZIP(), []int{5} +} + +func (x *DataPointsResponse) GetStartTimestampInSec() uint64 { + if x != nil { + return x.StartTimestampInSec + } + return 0 +} + +func (x *DataPointsResponse) GetTimeIntervalInSec() uint32 { + if x != nil { + return x.TimeIntervalInSec + } + return 0 +} + +func (x *DataPointsResponse) GetTransferRates() []*TotalTransferRateDataPoint { + if x != nil { + return x.TransferRates + } + return nil +} + +func (x *DataPointsResponse) GetFileRates() []*TotalFileRateDataPoint { + if x != nil { + return x.FileRates + } + return nil +} + +func (x *DataPointsResponse) GetTaskTimes() []*TaskTimeDataPoint { + if x != nil { + return x.TaskTimes + } + return nil +} + +func (x *DataPointsResponse) GetMemoryUsages() []*RdsMemoryUsageDataPoint { + if x != nil { + return x.MemoryUsages + } + return nil +} + +type MetadataResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ClusterName string `protobuf:"bytes,1,opt,name=clusterName,proto3" json:"clusterName,omitempty"` + AvailableBeamtimes []string `protobuf:"bytes,2,rep,name=availableBeamtimes,proto3" json:"availableBeamtimes,omitempty"` +} + +func (x *MetadataResponse) Reset() { + *x = MetadataResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MetadataResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MetadataResponse) ProtoMessage() {} + +func (x *MetadataResponse) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MetadataResponse.ProtoReflect.Descriptor instead. +func (*MetadataResponse) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringQueryService_proto_rawDescGZIP(), []int{6} +} + +func (x *MetadataResponse) GetClusterName() string { + if x != nil { + return x.ClusterName + } + return "" +} + +func (x *MetadataResponse) GetAvailableBeamtimes() []string { + if x != nil { + return x.AvailableBeamtimes + } + return nil +} + +type ToplogyQuery struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + FromTimestamp uint64 `protobuf:"varint,1,opt,name=fromTimestamp,proto3" json:"fromTimestamp,omitempty"` + ToTimestamp uint64 `protobuf:"varint,2,opt,name=toTimestamp,proto3" json:"toTimestamp,omitempty"` + BeamtimeFilter string `protobuf:"bytes,3,opt,name=beamtimeFilter,proto3" json:"beamtimeFilter,omitempty"` +} + +func (x *ToplogyQuery) Reset() { + *x = ToplogyQuery{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ToplogyQuery) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ToplogyQuery) ProtoMessage() {} + +func (x *ToplogyQuery) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ToplogyQuery.ProtoReflect.Descriptor instead. +func (*ToplogyQuery) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringQueryService_proto_rawDescGZIP(), []int{7} +} + +func (x *ToplogyQuery) GetFromTimestamp() uint64 { + if x != nil { + return x.FromTimestamp + } + return 0 +} + +func (x *ToplogyQuery) GetToTimestamp() uint64 { + if x != nil { + return x.ToTimestamp + } + return 0 +} + +func (x *ToplogyQuery) GetBeamtimeFilter() string { + if x != nil { + return x.BeamtimeFilter + } + return "" +} + +type TopologyResponseNode struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + NodeId string `protobuf:"bytes,1,opt,name=nodeId,proto3" json:"nodeId,omitempty"` + Level uint32 `protobuf:"varint,2,opt,name=level,proto3" json:"level,omitempty"` + ConsumerInstances []string `protobuf:"bytes,3,rep,name=consumerInstances,proto3" json:"consumerInstances,omitempty"` + ProducerInstances []string `protobuf:"bytes,4,rep,name=producerInstances,proto3" json:"producerInstances,omitempty"` +} + +func (x *TopologyResponseNode) Reset() { + *x = TopologyResponseNode{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TopologyResponseNode) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TopologyResponseNode) ProtoMessage() {} + +func (x *TopologyResponseNode) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TopologyResponseNode.ProtoReflect.Descriptor instead. +func (*TopologyResponseNode) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringQueryService_proto_rawDescGZIP(), []int{8} +} + +func (x *TopologyResponseNode) GetNodeId() string { + if x != nil { + return x.NodeId + } + return "" +} + +func (x *TopologyResponseNode) GetLevel() uint32 { + if x != nil { + return x.Level + } + return 0 +} + +func (x *TopologyResponseNode) GetConsumerInstances() []string { + if x != nil { + return x.ConsumerInstances + } + return nil +} + +func (x *TopologyResponseNode) GetProducerInstances() []string { + if x != nil { + return x.ProducerInstances + } + return nil +} + +type TopologyResponseEdge struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + FromNodeId string `protobuf:"bytes,1,opt,name=fromNodeId,proto3" json:"fromNodeId,omitempty"` + ToNodeId string `protobuf:"bytes,2,opt,name=toNodeId,proto3" json:"toNodeId,omitempty"` + SourceName string `protobuf:"bytes,3,opt,name=sourceName,proto3" json:"sourceName,omitempty"` + InvolvedReceivers []string `protobuf:"bytes,4,rep,name=involvedReceivers,proto3" json:"involvedReceivers,omitempty"` +} + +func (x *TopologyResponseEdge) Reset() { + *x = TopologyResponseEdge{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TopologyResponseEdge) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TopologyResponseEdge) ProtoMessage() {} + +func (x *TopologyResponseEdge) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TopologyResponseEdge.ProtoReflect.Descriptor instead. +func (*TopologyResponseEdge) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringQueryService_proto_rawDescGZIP(), []int{9} +} + +func (x *TopologyResponseEdge) GetFromNodeId() string { + if x != nil { + return x.FromNodeId + } + return "" +} + +func (x *TopologyResponseEdge) GetToNodeId() string { + if x != nil { + return x.ToNodeId + } + return "" +} + +func (x *TopologyResponseEdge) GetSourceName() string { + if x != nil { + return x.SourceName + } + return "" +} + +func (x *TopologyResponseEdge) GetInvolvedReceivers() []string { + if x != nil { + return x.InvolvedReceivers + } + return nil +} + +type TopologyResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Nodes []*TopologyResponseNode `protobuf:"bytes,1,rep,name=nodes,proto3" json:"nodes,omitempty"` + Edges []*TopologyResponseEdge `protobuf:"bytes,2,rep,name=edges,proto3" json:"edges,omitempty"` +} + +func (x *TopologyResponse) Reset() { + *x = TopologyResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TopologyResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TopologyResponse) ProtoMessage() {} + +func (x *TopologyResponse) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TopologyResponse.ProtoReflect.Descriptor instead. +func (*TopologyResponse) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringQueryService_proto_rawDescGZIP(), []int{10} +} + +func (x *TopologyResponse) GetNodes() []*TopologyResponseNode { + if x != nil { + return x.Nodes + } + return nil +} + +func (x *TopologyResponse) GetEdges() []*TopologyResponseEdge { + if x != nil { + return x.Edges + } + return nil +} + +var File_AsapoMonitoringQueryService_proto protoreflect.FileDescriptor + +var file_AsapoMonitoringQueryService_proto_rawDesc = []byte{ + 0x0a, 0x21, 0x41, 0x73, 0x61, 0x70, 0x6f, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, + 0x67, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x1a, 0x22, 0x41, 0x73, 0x61, 0x70, 0x6f, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, + 0x72, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x85, 0x03, 0x0a, 0x0f, 0x44, 0x61, 0x74, 0x61, + 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x24, 0x0a, 0x0d, 0x66, + 0x72, 0x6f, 0x6d, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x0d, 0x66, 0x72, 0x6f, 0x6d, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x12, 0x20, 0x0a, 0x0b, 0x74, 0x6f, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x74, 0x6f, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x12, 0x26, 0x0a, 0x0e, 0x62, 0x65, 0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x46, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x62, 0x65, 0x61, + 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x22, 0x0a, 0x0c, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, + 0x26, 0x0a, 0x0e, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, + 0x72, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x36, 0x0a, 0x16, 0x66, 0x72, 0x6f, 0x6d, 0x50, + 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x46, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x16, 0x66, 0x72, 0x6f, 0x6d, 0x50, 0x69, 0x70, + 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, + 0x32, 0x0a, 0x14, 0x74, 0x6f, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, + 0x70, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x74, + 0x6f, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x46, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x12, 0x4a, 0x0a, 0x11, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, + 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x11, 0x70, 0x69, + 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x22, + 0xf8, 0x01, 0x0a, 0x1a, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, + 0x72, 0x52, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x32, + 0x0a, 0x14, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, 0x79, 0x74, 0x65, 0x73, 0x50, 0x65, 0x72, 0x53, + 0x65, 0x63, 0x52, 0x65, 0x63, 0x76, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x14, 0x74, 0x6f, + 0x74, 0x61, 0x6c, 0x42, 0x79, 0x74, 0x65, 0x73, 0x50, 0x65, 0x72, 0x53, 0x65, 0x63, 0x52, 0x65, + 0x63, 0x76, 0x12, 0x32, 0x0a, 0x14, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, 0x79, 0x74, 0x65, 0x73, + 0x50, 0x65, 0x72, 0x53, 0x65, 0x63, 0x53, 0x65, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x14, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, 0x79, 0x74, 0x65, 0x73, 0x50, 0x65, 0x72, 0x53, + 0x65, 0x63, 0x53, 0x65, 0x6e, 0x64, 0x12, 0x38, 0x0a, 0x17, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, + 0x79, 0x74, 0x65, 0x73, 0x50, 0x65, 0x72, 0x53, 0x65, 0x63, 0x52, 0x64, 0x73, 0x53, 0x65, 0x6e, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x17, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, 0x79, + 0x74, 0x65, 0x73, 0x50, 0x65, 0x72, 0x53, 0x65, 0x63, 0x52, 0x64, 0x73, 0x53, 0x65, 0x6e, 0x64, + 0x12, 0x38, 0x0a, 0x17, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, 0x79, 0x74, 0x65, 0x73, 0x50, 0x65, + 0x72, 0x53, 0x65, 0x63, 0x46, 0x74, 0x73, 0x53, 0x65, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x17, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, 0x79, 0x74, 0x65, 0x73, 0x50, 0x65, 0x72, + 0x53, 0x65, 0x63, 0x46, 0x74, 0x73, 0x53, 0x65, 0x6e, 0x64, 0x22, 0x9a, 0x01, 0x0a, 0x16, 0x54, + 0x6f, 0x74, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, + 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x74, 0x6f, + 0x74, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x63, + 0x61, 0x63, 0x68, 0x65, 0x4d, 0x69, 0x73, 0x73, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x0b, 0x63, 0x61, 0x63, 0x68, 0x65, 0x4d, 0x69, 0x73, 0x73, 0x65, 0x73, 0x12, 0x1c, 0x0a, + 0x09, 0x66, 0x72, 0x6f, 0x6d, 0x43, 0x61, 0x63, 0x68, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x09, 0x66, 0x72, 0x6f, 0x6d, 0x43, 0x61, 0x63, 0x68, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x66, + 0x72, 0x6f, 0x6d, 0x44, 0x69, 0x73, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x66, + 0x72, 0x6f, 0x6d, 0x44, 0x69, 0x73, 0x6b, 0x22, 0xdb, 0x01, 0x0a, 0x11, 0x54, 0x61, 0x73, 0x6b, + 0x54, 0x69, 0x6d, 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x28, 0x0a, + 0x0f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x49, 0x6f, 0x54, 0x69, 0x6d, 0x65, 0x55, 0x73, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x49, + 0x6f, 0x54, 0x69, 0x6d, 0x65, 0x55, 0x73, 0x12, 0x2c, 0x0a, 0x11, 0x77, 0x72, 0x69, 0x74, 0x65, + 0x54, 0x6f, 0x44, 0x69, 0x73, 0x6b, 0x54, 0x69, 0x6d, 0x65, 0x55, 0x73, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x11, 0x77, 0x72, 0x69, 0x74, 0x65, 0x54, 0x6f, 0x44, 0x69, 0x73, 0x6b, 0x54, + 0x69, 0x6d, 0x65, 0x55, 0x73, 0x12, 0x34, 0x0a, 0x15, 0x77, 0x72, 0x69, 0x74, 0x65, 0x54, 0x6f, + 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x55, 0x73, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x15, 0x77, 0x72, 0x69, 0x74, 0x65, 0x54, 0x6f, 0x44, 0x61, 0x74, + 0x61, 0x62, 0x61, 0x73, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x55, 0x73, 0x12, 0x38, 0x0a, 0x17, 0x72, + 0x64, 0x73, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x6f, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, + 0x54, 0x69, 0x6d, 0x65, 0x55, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x17, 0x72, 0x64, + 0x73, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x6f, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x54, + 0x69, 0x6d, 0x65, 0x55, 0x73, 0x22, 0x43, 0x0a, 0x17, 0x52, 0x64, 0x73, 0x4d, 0x65, 0x6d, 0x6f, + 0x72, 0x79, 0x55, 0x73, 0x61, 0x67, 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, + 0x12, 0x28, 0x0a, 0x0f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x55, 0x73, 0x65, 0x64, 0x4d, 0x65, 0x6d, + 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x74, 0x6f, 0x74, 0x61, 0x6c, + 0x55, 0x73, 0x65, 0x64, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x22, 0xde, 0x02, 0x0a, 0x12, 0x44, + 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x30, 0x0a, 0x13, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x49, 0x6e, 0x53, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x13, + 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x49, 0x6e, + 0x53, 0x65, 0x63, 0x12, 0x2c, 0x0a, 0x11, 0x74, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, + 0x76, 0x61, 0x6c, 0x49, 0x6e, 0x53, 0x65, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, + 0x74, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x49, 0x6e, 0x53, 0x65, + 0x63, 0x12, 0x41, 0x0a, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x52, 0x61, 0x74, + 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x54, 0x6f, 0x74, 0x61, 0x6c, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x52, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, + 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x52, + 0x61, 0x74, 0x65, 0x73, 0x12, 0x35, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x61, 0x74, 0x65, + 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x46, + 0x69, 0x6c, 0x65, 0x52, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, + 0x52, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x61, 0x74, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x09, 0x74, + 0x61, 0x73, 0x6b, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, + 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x54, 0x69, 0x6d, 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, + 0x6e, 0x74, 0x52, 0x09, 0x74, 0x61, 0x73, 0x6b, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x12, 0x3c, 0x0a, + 0x0c, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x55, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x06, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x52, 0x64, 0x73, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x55, + 0x73, 0x61, 0x67, 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x0c, 0x6d, + 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x55, 0x73, 0x61, 0x67, 0x65, 0x73, 0x22, 0x64, 0x0a, 0x10, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x20, 0x0a, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x2e, 0x0a, 0x12, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x42, 0x65, + 0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x61, + 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x42, 0x65, 0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x22, 0x7e, 0x0a, 0x0c, 0x54, 0x6f, 0x70, 0x6c, 0x6f, 0x67, 0x79, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x12, 0x24, 0x0a, 0x0d, 0x66, 0x72, 0x6f, 0x6d, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x66, 0x72, 0x6f, 0x6d, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x20, 0x0a, 0x0b, 0x74, 0x6f, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x74, 0x6f, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x26, 0x0a, 0x0e, 0x62, 0x65, 0x61, + 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0e, 0x62, 0x65, 0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x22, 0xa0, 0x01, 0x0a, 0x14, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x6f, + 0x64, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, + 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x2c, 0x0a, 0x11, 0x63, 0x6f, 0x6e, 0x73, + 0x75, 0x6d, 0x65, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x11, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x49, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, + 0x65, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x11, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x73, 0x22, 0xa0, 0x01, 0x0a, 0x14, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, + 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x45, 0x64, 0x67, 0x65, 0x12, 0x1e, 0x0a, + 0x0a, 0x66, 0x72, 0x6f, 0x6d, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x66, 0x72, 0x6f, 0x6d, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x1a, 0x0a, + 0x08, 0x74, 0x6f, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x74, 0x6f, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2c, 0x0a, 0x11, 0x69, 0x6e, 0x76, + 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x73, 0x18, 0x04, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x69, 0x6e, 0x76, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x52, 0x65, + 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x73, 0x22, 0x6c, 0x0a, 0x10, 0x54, 0x6f, 0x70, 0x6f, 0x6c, + 0x6f, 0x67, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x05, 0x6e, + 0x6f, 0x64, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x54, 0x6f, 0x70, + 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4e, 0x6f, 0x64, + 0x65, 0x52, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x2b, 0x0a, 0x05, 0x65, 0x64, 0x67, 0x65, + 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, + 0x67, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x45, 0x64, 0x67, 0x65, 0x52, 0x05, + 0x65, 0x64, 0x67, 0x65, 0x73, 0x2a, 0x5b, 0x0a, 0x1b, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, + 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, + 0x51, 0x55, 0x45, 0x52, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, + 0x45, 0x78, 0x61, 0x63, 0x74, 0x50, 0x61, 0x74, 0x68, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x4a, + 0x75, 0x73, 0x74, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x54, 0x6f, 0x53, 0x74, 0x65, 0x70, + 0x10, 0x02, 0x32, 0xb6, 0x01, 0x0a, 0x1b, 0x41, 0x73, 0x61, 0x70, 0x6f, 0x4d, 0x6f, 0x6e, 0x69, + 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x2a, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x12, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x11, 0x2e, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x31, + 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x12, 0x0d, 0x2e, + 0x54, 0x6f, 0x70, 0x6c, 0x6f, 0x67, 0x79, 0x51, 0x75, 0x65, 0x72, 0x79, 0x1a, 0x11, 0x2e, 0x54, + 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x12, 0x38, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, + 0x74, 0x73, 0x12, 0x10, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x1a, 0x13, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x13, 0x5a, 0x11, 0x2e, + 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_AsapoMonitoringQueryService_proto_rawDescOnce sync.Once + file_AsapoMonitoringQueryService_proto_rawDescData = file_AsapoMonitoringQueryService_proto_rawDesc +) + +func file_AsapoMonitoringQueryService_proto_rawDescGZIP() []byte { + file_AsapoMonitoringQueryService_proto_rawDescOnce.Do(func() { + file_AsapoMonitoringQueryService_proto_rawDescData = protoimpl.X.CompressGZIP(file_AsapoMonitoringQueryService_proto_rawDescData) + }) + return file_AsapoMonitoringQueryService_proto_rawDescData +} + +var file_AsapoMonitoringQueryService_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_AsapoMonitoringQueryService_proto_msgTypes = make([]protoimpl.MessageInfo, 11) +var file_AsapoMonitoringQueryService_proto_goTypes = []interface{}{ + (PipelineConnectionQueryMode)(0), // 0: PipelineConnectionQueryMode + (*DataPointsQuery)(nil), // 1: DataPointsQuery + (*TotalTransferRateDataPoint)(nil), // 2: TotalTransferRateDataPoint + (*TotalFileRateDataPoint)(nil), // 3: TotalFileRateDataPoint + (*TaskTimeDataPoint)(nil), // 4: TaskTimeDataPoint + (*RdsMemoryUsageDataPoint)(nil), // 5: RdsMemoryUsageDataPoint + (*DataPointsResponse)(nil), // 6: DataPointsResponse + (*MetadataResponse)(nil), // 7: MetadataResponse + (*ToplogyQuery)(nil), // 8: ToplogyQuery + (*TopologyResponseNode)(nil), // 9: TopologyResponseNode + (*TopologyResponseEdge)(nil), // 10: TopologyResponseEdge + (*TopologyResponse)(nil), // 11: TopologyResponse + (*Empty)(nil), // 12: Empty +} +var file_AsapoMonitoringQueryService_proto_depIdxs = []int32{ + 0, // 0: DataPointsQuery.pipelineQueryMode:type_name -> PipelineConnectionQueryMode + 2, // 1: DataPointsResponse.transferRates:type_name -> TotalTransferRateDataPoint + 3, // 2: DataPointsResponse.fileRates:type_name -> TotalFileRateDataPoint + 4, // 3: DataPointsResponse.taskTimes:type_name -> TaskTimeDataPoint + 5, // 4: DataPointsResponse.memoryUsages:type_name -> RdsMemoryUsageDataPoint + 9, // 5: TopologyResponse.nodes:type_name -> TopologyResponseNode + 10, // 6: TopologyResponse.edges:type_name -> TopologyResponseEdge + 12, // 7: AsapoMonitoringQueryService.GetMetadata:input_type -> Empty + 8, // 8: AsapoMonitoringQueryService.GetTopology:input_type -> ToplogyQuery + 1, // 9: AsapoMonitoringQueryService.GetDataPoints:input_type -> DataPointsQuery + 7, // 10: AsapoMonitoringQueryService.GetMetadata:output_type -> MetadataResponse + 11, // 11: AsapoMonitoringQueryService.GetTopology:output_type -> TopologyResponse + 6, // 12: AsapoMonitoringQueryService.GetDataPoints:output_type -> DataPointsResponse + 10, // [10:13] is the sub-list for method output_type + 7, // [7:10] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name +} + +func init() { file_AsapoMonitoringQueryService_proto_init() } +func file_AsapoMonitoringQueryService_proto_init() { + if File_AsapoMonitoringQueryService_proto != nil { + return + } + file_AsapoMonitoringCommonService_proto_init() + if !protoimpl.UnsafeEnabled { + file_AsapoMonitoringQueryService_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DataPointsQuery); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_AsapoMonitoringQueryService_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TotalTransferRateDataPoint); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_AsapoMonitoringQueryService_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TotalFileRateDataPoint); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_AsapoMonitoringQueryService_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TaskTimeDataPoint); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_AsapoMonitoringQueryService_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RdsMemoryUsageDataPoint); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_AsapoMonitoringQueryService_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DataPointsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_AsapoMonitoringQueryService_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MetadataResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_AsapoMonitoringQueryService_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ToplogyQuery); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_AsapoMonitoringQueryService_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TopologyResponseNode); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_AsapoMonitoringQueryService_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TopologyResponseEdge); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_AsapoMonitoringQueryService_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TopologyResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_AsapoMonitoringQueryService_proto_rawDesc, + NumEnums: 1, + NumMessages: 11, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_AsapoMonitoringQueryService_proto_goTypes, + DependencyIndexes: file_AsapoMonitoringQueryService_proto_depIdxs, + EnumInfos: file_AsapoMonitoringQueryService_proto_enumTypes, + MessageInfos: file_AsapoMonitoringQueryService_proto_msgTypes, + }.Build() + File_AsapoMonitoringQueryService_proto = out.File + file_AsapoMonitoringQueryService_proto_rawDesc = nil + file_AsapoMonitoringQueryService_proto_goTypes = nil + file_AsapoMonitoringQueryService_proto_depIdxs = nil +} diff --git a/common/go/src/asapo_common/generated_proto/AsapoMonitoringQueryService_grpc.pb.go b/common/go/src/asapo_common/generated_proto/AsapoMonitoringQueryService_grpc.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..85be8b748f685c311e28b9747c1faa4169ae4a9e --- /dev/null +++ b/common/go/src/asapo_common/generated_proto/AsapoMonitoringQueryService_grpc.pb.go @@ -0,0 +1,178 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.1.0 +// - protoc v3.15.8 +// source: AsapoMonitoringQueryService.proto + +package generated_proto + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// AsapoMonitoringQueryServiceClient is the client API for AsapoMonitoringQueryService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type AsapoMonitoringQueryServiceClient interface { + GetMetadata(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*MetadataResponse, error) + GetTopology(ctx context.Context, in *ToplogyQuery, opts ...grpc.CallOption) (*TopologyResponse, error) + GetDataPoints(ctx context.Context, in *DataPointsQuery, opts ...grpc.CallOption) (*DataPointsResponse, error) +} + +type asapoMonitoringQueryServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewAsapoMonitoringQueryServiceClient(cc grpc.ClientConnInterface) AsapoMonitoringQueryServiceClient { + return &asapoMonitoringQueryServiceClient{cc} +} + +func (c *asapoMonitoringQueryServiceClient) GetMetadata(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*MetadataResponse, error) { + out := new(MetadataResponse) + err := c.cc.Invoke(ctx, "/AsapoMonitoringQueryService/GetMetadata", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *asapoMonitoringQueryServiceClient) GetTopology(ctx context.Context, in *ToplogyQuery, opts ...grpc.CallOption) (*TopologyResponse, error) { + out := new(TopologyResponse) + err := c.cc.Invoke(ctx, "/AsapoMonitoringQueryService/GetTopology", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *asapoMonitoringQueryServiceClient) GetDataPoints(ctx context.Context, in *DataPointsQuery, opts ...grpc.CallOption) (*DataPointsResponse, error) { + out := new(DataPointsResponse) + err := c.cc.Invoke(ctx, "/AsapoMonitoringQueryService/GetDataPoints", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// AsapoMonitoringQueryServiceServer is the server API for AsapoMonitoringQueryService service. +// All implementations must embed UnimplementedAsapoMonitoringQueryServiceServer +// for forward compatibility +type AsapoMonitoringQueryServiceServer interface { + GetMetadata(context.Context, *Empty) (*MetadataResponse, error) + GetTopology(context.Context, *ToplogyQuery) (*TopologyResponse, error) + GetDataPoints(context.Context, *DataPointsQuery) (*DataPointsResponse, error) + mustEmbedUnimplementedAsapoMonitoringQueryServiceServer() +} + +// UnimplementedAsapoMonitoringQueryServiceServer must be embedded to have forward compatible implementations. +type UnimplementedAsapoMonitoringQueryServiceServer struct { +} + +func (UnimplementedAsapoMonitoringQueryServiceServer) GetMetadata(context.Context, *Empty) (*MetadataResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetMetadata not implemented") +} +func (UnimplementedAsapoMonitoringQueryServiceServer) GetTopology(context.Context, *ToplogyQuery) (*TopologyResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetTopology not implemented") +} +func (UnimplementedAsapoMonitoringQueryServiceServer) GetDataPoints(context.Context, *DataPointsQuery) (*DataPointsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetDataPoints not implemented") +} +func (UnimplementedAsapoMonitoringQueryServiceServer) mustEmbedUnimplementedAsapoMonitoringQueryServiceServer() { +} + +// UnsafeAsapoMonitoringQueryServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to AsapoMonitoringQueryServiceServer will +// result in compilation errors. +type UnsafeAsapoMonitoringQueryServiceServer interface { + mustEmbedUnimplementedAsapoMonitoringQueryServiceServer() +} + +func RegisterAsapoMonitoringQueryServiceServer(s grpc.ServiceRegistrar, srv AsapoMonitoringQueryServiceServer) { + s.RegisterService(&AsapoMonitoringQueryService_ServiceDesc, srv) +} + +func _AsapoMonitoringQueryService_GetMetadata_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AsapoMonitoringQueryServiceServer).GetMetadata(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/AsapoMonitoringQueryService/GetMetadata", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AsapoMonitoringQueryServiceServer).GetMetadata(ctx, req.(*Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _AsapoMonitoringQueryService_GetTopology_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ToplogyQuery) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AsapoMonitoringQueryServiceServer).GetTopology(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/AsapoMonitoringQueryService/GetTopology", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AsapoMonitoringQueryServiceServer).GetTopology(ctx, req.(*ToplogyQuery)) + } + return interceptor(ctx, in, info, handler) +} + +func _AsapoMonitoringQueryService_GetDataPoints_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DataPointsQuery) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AsapoMonitoringQueryServiceServer).GetDataPoints(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/AsapoMonitoringQueryService/GetDataPoints", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AsapoMonitoringQueryServiceServer).GetDataPoints(ctx, req.(*DataPointsQuery)) + } + return interceptor(ctx, in, info, handler) +} + +// AsapoMonitoringQueryService_ServiceDesc is the grpc.ServiceDesc for AsapoMonitoringQueryService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var AsapoMonitoringQueryService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "AsapoMonitoringQueryService", + HandlerType: (*AsapoMonitoringQueryServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetMetadata", + Handler: _AsapoMonitoringQueryService_GetMetadata_Handler, + }, + { + MethodName: "GetTopology", + Handler: _AsapoMonitoringQueryService_GetTopology_Handler, + }, + { + MethodName: "GetDataPoints", + Handler: _AsapoMonitoringQueryService_GetDataPoints_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "AsapoMonitoringQueryService.proto", +} diff --git a/common/go/src/asapo_common/go.mod b/common/go/src/asapo_common/go.mod index 31eee8613f224bc7425474074f9199044934a36c..25d455f977be36fd1fd5786a8c1cbee7dedc6f79 100644 --- a/common/go/src/asapo_common/go.mod +++ b/common/go/src/asapo_common/go.mod @@ -7,4 +7,5 @@ require ( github.com/gorilla/mux v1.8.0 github.com/sirupsen/logrus v1.8.0 github.com/stretchr/testify v1.7.0 + google.golang.org/grpc v1.39.0 // indirect ) diff --git a/common/go/src/asapo_common/go.sum b/common/go/src/asapo_common/go.sum index 6f35f25f5853eb59ed8eb5b781b6410839850826..a812dba23acbd8491560a091e70be45c8863c248 100644 --- a/common/go/src/asapo_common/go.sum +++ b/common/go/src/asapo_common/go.sum @@ -1,24 +1,129 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/magefile/mage v1.10.0 h1:3HiXzCUY12kh9bIuyXShaVe529fJfyqoVM42o/uom2g= github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/sirupsen/logrus v1.8.0 h1:nfhvjKcUMhBMVqbKHJlk5RPrrfYr/NMo3692g0dwfWU= github.com/sirupsen/logrus v1.8.0/go.mod h1:4GuYW9TZmE769R5STWrRakJc4UqQ3+QQ95fyz7ENv1A= github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.39.0 h1:Klz8I9kdtkIN6EpHHUOMLCYhTn/2WAe5a0s1hcBkdTI= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/common/networking/monitoring/AsapoMonitoringCommonService.proto b/common/networking/monitoring/AsapoMonitoringCommonService.proto new file mode 100644 index 0000000000000000000000000000000000000000..fc474b8571844e247867d9a05c653fd46f53d0a3 --- /dev/null +++ b/common/networking/monitoring/AsapoMonitoringCommonService.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +option go_package = "./generated_proto"; + +message Empty { +} diff --git a/common/networking/monitoring/AsapoMonitoringIngestService.proto b/common/networking/monitoring/AsapoMonitoringIngestService.proto new file mode 100644 index 0000000000000000000000000000000000000000..cc3101df697998ffc1060c0c29af093b3831512e --- /dev/null +++ b/common/networking/monitoring/AsapoMonitoringIngestService.proto @@ -0,0 +1,107 @@ +syntax = "proto3"; + +import "AsapoMonitoringCommonService.proto"; + +option go_package = "./generated_proto"; + +// ******************************** +// * AsapoMonitoringIngestService * +// ******************************** + +message ProducerToReceiverTransferDataPoint { // send by receiver + string pipelineStepId = 1; // Customizable from producerLib + string producerInstanceId = 2; + + string beamtime = 3; + string source = 4; + string stream = 5; + + uint64 fileCount = 6; + + uint64 totalFileSize = 7; + uint64 totalTransferReceiveTimeInMicroseconds = 8; + uint64 totalWriteIoTimeInMicroseconds = 9; + uint64 totalDbTimeInMicroseconds = 10; +} + +message BrokerRequestDataPoint { // send by broker + string pipelineStepId = 1; // Customizable from consumerLib can indicates a linkage between a consumer and a producer + string consumerInstanceId = 2; + string command = 3; // e.g. 'get_next', 'get_last', 'get_by_id' + + string beamtime = 4; + string source = 5; + string stream = 6; + + uint64 fileCount = 7; + + uint64 totalFileSize = 8; +} + +message RdsMemoryDataPoint { // Send by RDS in fixed interval + string beamtime = 1; + string source = 2; + string stream = 3; + + uint64 usedBytes = 4; + uint64 totalBytes = 5; +} + +message RdsToConsumerDataPoint { // Send by RDS + string pipelineStepId = 1; // Customizable from consumerLib can indicates a linkage between a consumer and a producer + string consumerInstanceId = 2; + + string beamtime = 3; + string source = 4; + string stream = 5; + + uint64 hits = 6; + uint64 misses = 7; + + uint64 totalFileSize = 8; + uint64 totalTransferSendTimeInMicroseconds = 9; +} + +message FdsToConsumerDataPoint { // Send by RDS + string pipelineStepId = 1; // Customizable from consumerLib can indicates a linkage between a consumer and a producer + string consumerInstanceId = 2; + + string beamtime = 3; + string source = 4; + string stream = 5; + + uint64 fileCount = 6; + + uint64 totalFileSize = 7; + uint64 totalTransferSendTimeInMicroseconds = 8; +} + +// ---- Containers ---- +message ReceiverDataPointContainer { + string receiverName = 1; // Receiver InstanceId + uint64 timestampMs = 2; + + repeated ProducerToReceiverTransferDataPoint groupedP2rTransfers = 3; + repeated RdsToConsumerDataPoint groupedRds2cTransfers = 4; + repeated RdsMemoryDataPoint groupedMemoryStats = 5; +} + +message BrokerDataPointContainer { + string brokerName = 1; // Broker InstanceId + uint64 timestampMs = 2; + + repeated BrokerRequestDataPoint groupedBrokerRequests = 3; +} + +message FtsToConsumerDataPointContainer { + string ftsName = 1; // FTS InstanceId + uint64 timestampMs = 2; + + repeated FdsToConsumerDataPoint groupedFdsTransfers = 3; +} + +service AsapoMonitoringIngestService { + rpc InsertReceiverDataPoints(ReceiverDataPointContainer) returns (Empty) {} + rpc InsertBrokerDataPoints(BrokerDataPointContainer) returns (Empty) {} + rpc InsertFtsDataPoints(FtsToConsumerDataPointContainer) returns (Empty) {} +} diff --git a/common/networking/monitoring/AsapoMonitoringQueryService.proto b/common/networking/monitoring/AsapoMonitoringQueryService.proto new file mode 100644 index 0000000000000000000000000000000000000000..ed6c46f598ead0f15af55eb96be28fd77fdc45ae --- /dev/null +++ b/common/networking/monitoring/AsapoMonitoringQueryService.proto @@ -0,0 +1,113 @@ +syntax = "proto3"; + +option go_package = "./generated_proto"; + +import "AsapoMonitoringCommonService.proto"; + +// ******************************* +// * AsapoMonitoringQueryService * +// ******************************* + +enum PipelineConnectionQueryMode { + INVALID_QUERY_MODE = 0; + ExactPath = 1; + JustRelatedToStep = 2; +} + +message DataPointsQuery { + uint64 fromTimestamp = 1; + uint64 toTimestamp = 2; + + string beamtimeFilter = 4; + string sourceFilter = 5; + + string receiverFilter = 6; + + string fromPipelineStepFilter = 7; + string toPipelineStepFilter = 8; + PipelineConnectionQueryMode pipelineQueryMode = 9; +} + +/* +TODO: Neues Diagramm nur für hit/miss? Weil ich ja sonst die total transfer Rate erhöhe wird +TODO: Also cache misses erhöhen die Summe aller Requests im Diagram +message HitMissDataPoint { + uint32 hit = 1; + uint32 miss = 2; +} +*/ + +message TotalTransferRateDataPoint { + uint64 totalBytesPerSecRecv = 1; + uint64 totalBytesPerSecSend = 2; + + uint64 totalBytesPerSecRdsSend = 3; + uint64 totalBytesPerSecFtsSend = 4; +} + +message TotalFileRateDataPoint { + uint32 totalRequests = 1; + uint32 cacheMisses = 2; + uint32 fromCache = 3; + uint32 fromDisk = 4; +} + +message TaskTimeDataPoint { + uint32 receiveIoTimeUs = 1; + uint32 writeToDiskTimeUs = 2; + uint32 writeToDatabaseTimeUs = 3; + uint32 rdsSendToConsumerTimeUs = 4; +} + +message RdsMemoryUsageDataPoint { + uint64 totalUsedMemory = 1; + //uint64 totalMemory = 2; +} + +message DataPointsResponse { + uint64 startTimestampInSec = 1; + uint32 timeIntervalInSec = 2; + + repeated TotalTransferRateDataPoint transferRates = 3; + repeated TotalFileRateDataPoint fileRates = 4; + repeated TaskTimeDataPoint taskTimes = 5; + repeated RdsMemoryUsageDataPoint memoryUsages = 6; +} + +message MetadataResponse { + string clusterName = 1; + repeated string availableBeamtimes = 2; +} + +message ToplogyQuery { + uint64 fromTimestamp = 1; + uint64 toTimestamp = 2; + + string beamtimeFilter = 3; +} + +message TopologyResponseNode { + string nodeId = 1; + uint32 level = 2; + repeated string consumerInstances = 3; + repeated string producerInstances = 4; +} + +message TopologyResponseEdge { + string fromNodeId = 1; + string toNodeId = 2; + + string sourceName = 3; + repeated string involvedReceivers = 4; +} + +message TopologyResponse { + repeated TopologyResponseNode nodes = 1; + repeated TopologyResponseEdge edges = 2; +} + +service AsapoMonitoringQueryService { + rpc GetMetadata(Empty) returns (MetadataResponse) {} + rpc GetTopology(ToplogyQuery) returns (TopologyResponse) {} + rpc GetDataPoints(DataPointsQuery) returns (DataPointsResponse) {} +} diff --git a/common/networking/monitoring/README.md b/common/networking/monitoring/README.md new file mode 100644 index 0000000000000000000000000000000000000000..c4ee3d075a37cfc07045adaced7ddf5510b48648 --- /dev/null +++ b/common/networking/monitoring/README.md @@ -0,0 +1,6 @@ +Currently, changes to these files have to be compiled separately for Go and JavaScript + +Execute each `./generate-proto.sh` in: +- `#/monitoring/monitoring_ui` +- `#/common/go/src/asapo_common` + diff --git a/config/grafana/ASAP__O.json b/config/grafana/ASAP__O.json index 775b63e8e300e777d4b42848eb7abc501ed2d5e2..3e57850339186ae6342a2986fd1054dec0382f29 100644 --- a/config/grafana/ASAP__O.json +++ b/config/grafana/ASAP__O.json @@ -295,7 +295,7 @@ "tags": [] }, { - "alias": "Network share", + "alias": "Network share incoming", "groupBy": [ { "params": [ @@ -325,7 +325,50 @@ [ { "params": [ - "network_share" + "network_incoming_share" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + }, + { + "alias": "Network share outgoing", + "groupBy": [ + { + "params": [ + "10s" + ], + "type": "time" + }, + { + "params": [ + "connection_from" + ], + "type": "tag" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "measurement": "statistics", + "orderByTime": "ASC", + "policy": "default", + "refId": "D", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "network_incoming_share" ], "type": "field" }, @@ -479,7 +522,7 @@ "tags": [] }, { - "alias": "Network share", + "alias": "Network share incoming", "groupBy": [ { "params": [ @@ -503,7 +546,44 @@ [ { "params": [ - "network_share" + "network_incoming_share" + ], + "type": "field" + }, + { + "params": [], + "type": "mean" + } + ] + ], + "tags": [] + }, + { + "alias": "Network share outgoing", + "groupBy": [ + { + "params": [ + "10s" + ], + "type": "time" + }, + { + "params": [ + "null" + ], + "type": "fill" + } + ], + "measurement": "statistics", + "orderByTime": "ASC", + "policy": "default", + "refId": "D", + "resultFormat": "time_series", + "select": [ + [ + { + "params": [ + "network_outgoing_share" ], "type": "field" }, @@ -883,4 +963,4 @@ "title": "Asapo", "uid": "jZtUsU4mz", "version": 6 -} \ No newline at end of file +} diff --git a/config/nomad/monitoring.nmd.in b/config/nomad/monitoring.nmd.in new file mode 100644 index 0000000000000000000000000000000000000000..dea8287a8762b263e5a17c0259c332fb8a332201 --- /dev/null +++ b/config/nomad/monitoring.nmd.in @@ -0,0 +1,48 @@ +job "monitoring" { + datacenters = ["dc1"] + + type = "service" + + group "monitoring" { + count = 1 + + task "monitoring-server" { + driver = "raw_exec" + + config { + command = "@MONITORING_SERVER_FULLPATH@" + args = ["-config","${NOMAD_TASK_DIR}/monitoring_server.json"] + } + + resources { + cpu = 500 # 500 MHz + memory = 256 # 256MB + network { + port "monitoring_server" { + static = "5009" + } + } + } + + service { + name = "asapo-monitoring" + port = "monitoring_server" + check { + name = "alive" + port = "monitoring_server" + type = "tcp" + interval = "10s" + timeout = "2s" + initial_status = "passing" + } + } + + template { + source = "@WORK_DIR@/monitoring_server.json.tpl" + destination = "local/monitoring_server.json" + change_mode = "signal" + change_signal = "SIGHUP" + } + } + } +} diff --git a/consumer/api/c/include/asapo/consumer_c.h b/consumer/api/c/include/asapo/consumer_c.h index dcab928d981c79f63a417c02174af91080388163..01a2018f7db793d9fba3e93addc7a2d9644aa808 100644 --- a/consumer/api/c/include/asapo/consumer_c.h +++ b/consumer/api/c/include/asapo/consumer_c.h @@ -104,6 +104,8 @@ int64_t asapo_consumer_get_last_acknowledged_message(AsapoConsumerHandle consume void asapo_consumer_force_no_rdma(AsapoConsumerHandle consumer); enum AsapoNetworkConnectionType asapo_consumer_current_connection_type(AsapoConsumerHandle consumer); +int enable_new_monitoring_api_format(AsapoConsumerHandle consumer, AsapoBool enabled, AsapoErrorHandle* error); + AsapoStreamInfosHandle asapo_consumer_get_stream_list(AsapoConsumerHandle consumer, const char* from, enum AsapoStreamFilter filter, diff --git a/consumer/api/cpp/include/asapo/consumer/consumer.h b/consumer/api/cpp/include/asapo/consumer/consumer.h index 026d4c324cd583068173a6c9eb65428bb3711c54..2527ca21c2058c32bfec3afed4c64292fe481b11 100644 --- a/consumer/api/cpp/include/asapo/consumer/consumer.h +++ b/consumer/api/cpp/include/asapo/consumer/consumer.h @@ -81,6 +81,9 @@ class Consumer { //! This will only have an effect if no previous connection attempted was made on this Consumer. virtual void ForceNoRdma() = 0; + //! Should be done before files are transferred, if set to true, connected services will not receive the InstanceId and PipelineStep of this Consumer. + virtual Error DisableMonitoring(bool disable) = 0; + //! Returns the current network connection type /*! * \return current network connection type. If no connection was made, the result is NetworkConnectionType::kUndefined diff --git a/consumer/api/cpp/src/consumer_c_glue.cpp b/consumer/api/cpp/src/consumer_c_glue.cpp index 2671106030e1631b57d656408a04efdf62e65ccc..240bfcb90a8b4d3d414457fb00eae39b3a7109d8 100644 --- a/consumer/api/cpp/src/consumer_c_glue.cpp +++ b/consumer/api/cpp/src/consumer_c_glue.cpp @@ -227,10 +227,12 @@ extern "C" { size_t index) { return list->handle->at(index); } + //! wraps asapo::Consumer::ForceNoRdma() /// \copydoc asapo::Consumer::ForceNoRdma() /// \param[in] consumer the handle of the consumer concerned void asapo_consumer_force_no_rdma(AsapoConsumerHandle consumer); + //! wraps asapo::Consumer::CurrentConnectionType() /// \copydoc asapo::Consumer::CurrentConnectionType() /// \param[in] consumer the handle of the consumer concerned @@ -238,6 +240,13 @@ extern "C" { return static_cast<AsapoNetworkConnectionType>(consumer->handle->CurrentConnectionType()); } +//! wraps asapo::Consumer::DisableMonitoring() +/// \copydoc asapo::Consumer::DisableMonitoring() +/// \param[in] consumer the handle of the consumer concerned +/// \param[in] enabled set this to true if the new API format should be used +/// \param[out] error will contain a pointer to an AsapoErrorHandle if a problem occured, NULL else. + int enable_new_monitoring_api_format(AsapoConsumerHandle consumer, AsapoBool enabled, AsapoErrorHandle* error); + //! get list of streams, wraps asapo::Consumer::GetStreamList() /*! @@ -472,7 +481,6 @@ extern "C" { const char* stream, AsapoErrorHandle* error) { dataGetterStart - auto err = consumer->handle->GetNext(*group_id->handle, fi, data ? &d : nullptr, stream); dataGetterStop @@ -675,7 +683,4 @@ extern "C" { const char* asapo_consumer_error_get_next_stream(const AsapoConsumerErrorDataHandle error_payload) { return error_payload->handle->next_stream.c_str(); } - - - } diff --git a/consumer/api/cpp/src/consumer_impl.cpp b/consumer/api/cpp/src/consumer_impl.cpp index 5290519433b67b6d17d94eced88c1c6f51ad44f7..beb12a9fddf4ee4ec8a4123562cfbb834495deb6 100644 --- a/consumer/api/cpp/src/consumer_impl.cpp +++ b/consumer/api/cpp/src/consumer_impl.cpp @@ -143,7 +143,35 @@ ConsumerImpl::ConsumerImpl(std::string server_uri, if (source_credentials_.data_source.empty()) { source_credentials_.data_source = SourceCredentials::kDefaultDataSource; } + if (source_credentials_.instance_id.empty()) { + source_credentials_.instance_id = SourceCredentials::kDefaultInstanceId; + } + if (source_credentials_.pipeline_step.empty()) { + source_credentials_.pipeline_step = SourceCredentials::kDefaultPipelineStep; + } + + if (source_credentials_.instance_id == SourceCredentials::kDefaultInstanceId) { + Error err; + std::string hostname = io__->GetHostName(&err); + + if (err) { + hostname = "hostnameerror"; + } + + source_credentials_.instance_id = hostname + "_" + std::to_string(io__->GetCurrentPid()); + } + if (source_credentials_.pipeline_step == SourceCredentials::kDefaultPipelineStep) { + source_credentials_.pipeline_step = "DefaultStep"; + } + data_source_encoded_ = httpclient__->UrlEscape(source_credentials_.data_source); + + request_sender_details_prefix_ = + source_credentials_.instance_id + "§" + + source_credentials_.pipeline_step + "§" + + source_credentials_.beamtime_id + "§" + + source_credentials_.data_source + "§"; + } void ConsumerImpl::SetTimeout(uint64_t timeout_ms) { @@ -154,6 +182,11 @@ void ConsumerImpl::ForceNoRdma() { should_try_rdma_first_ = false; } +Error ConsumerImpl::DisableMonitoring(bool disable) { + use_new_api_format_ = !disable; + return nullptr; +} + NetworkConnectionType ConsumerImpl::CurrentConnectionType() const { return current_connection_type_; } @@ -295,7 +328,7 @@ Error ConsumerImpl::GetRecordFromServer(std::string* response, std::string group std::string request_suffix = OpToUriCmd(op); std::string request_group = OpToUriCmd(op); - std::string request_api = BrokerApiUri(std::move(stream), "", ""); + auto baseRequestInfo = CreateBrokerApiRequest(std::move(stream), "", ""); Error no_data_error; auto start = std::chrono::steady_clock::now(); bool timeout_triggered = false; @@ -306,8 +339,9 @@ Error ConsumerImpl::GetRecordFromServer(std::string* response, std::string group auto err = DiscoverService(kBrokerServiceName, ¤t_broker_uri_); if (err == nullptr) { - auto ri = PrepareRequestInfo(request_api + "/" + httpclient__->UrlEscape(group_id) + "/" + request_suffix, dataset, + auto ri = PrepareRequestInfo(baseRequestInfo.api + "/" + httpclient__->UrlEscape(group_id) + "/" + request_suffix, dataset, min_size); + ri.extra_params += baseRequestInfo.extra_params; if (request_suffix == "next" && resend_) { ri.extra_params = ri.extra_params + "&resend_nacks=true" + "&delay_ms=" + std::to_string(delay_ms_) + "&resend_attempts=" + std::to_string(resend_attempts_); @@ -410,6 +444,7 @@ Error ConsumerImpl::GetMessageFromServer(GetMessageServerOperation op, uint64_t if (!info->SetFromJson(response)) { return ConsumerErrorTemplates::kInterruptedTransaction.Generate(std::string("malformed response:") + response); } + return GetDataIfNeeded(info, data); } @@ -463,14 +498,13 @@ Error ConsumerImpl::GetDataIfNeeded(MessageMeta* info, MessageData* data) { } return RetrieveData(info, data); - } bool ConsumerImpl::DataCanBeInBuffer(const MessageMeta* info) { return info->buf_id > 0; } -Error ConsumerImpl::CreateNetClientAndTryToGetFile(const MessageMeta* info, MessageData* data) { +Error ConsumerImpl::CreateNetClientAndTryToGetFile(const MessageMeta* info, const std::string& request_sender_details, MessageData* data) { const std::lock_guard<std::mutex> lock(net_client_mutex__); if (net_client__) { return nullptr; @@ -479,7 +513,7 @@ Error ConsumerImpl::CreateNetClientAndTryToGetFile(const MessageMeta* info, Mess if (should_try_rdma_first_) { // This will check if a rdma connection can be made and will return early if so auto fabricClient = std::unique_ptr<NetClient>(new FabricConsumerClient()); - Error error = fabricClient->GetData(info, data); + Error error = fabricClient->GetData(info, request_sender_details, data); // Check if the error comes from the receiver data server (so a connection was made) if (!error || error == RdsResponseErrorTemplates::kNetErrorNoData) { @@ -502,15 +536,20 @@ Error ConsumerImpl::CreateNetClientAndTryToGetFile(const MessageMeta* info, Mess net_client__.reset(new TcpConsumerClient()); current_connection_type_ = NetworkConnectionType::kAsapoTcp; - return net_client__->GetData(info, data); + return net_client__->GetData(info, request_sender_details, data); } Error ConsumerImpl::TryGetDataFromBuffer(const MessageMeta* info, MessageData* data) { + std::string request_sender_details; + if (use_new_api_format_) { + request_sender_details = request_sender_details_prefix_ + info->stream; + } + if (!net_client__) { - return CreateNetClientAndTryToGetFile(info, data); + return CreateNetClientAndTryToGetFile(info, request_sender_details, data); } - return net_client__->GetData(info, data); + return net_client__->GetData(info, request_sender_details, data); } std::string ConsumerImpl::GenerateNewGroupId(Error* err) { @@ -550,7 +589,7 @@ Error ConsumerImpl::ServiceRequestWithTimeout(const std::string& service_name, Error ConsumerImpl::FtsSizeRequestWithTimeout(MessageMeta* info) { RequestInfo ri = CreateFileTransferRequest(info); - ri.extra_params = "&sizeonly=true"; + ri.extra_params += "&sizeonly=true"; ri.output_mode = OutputDataMode::string; RequestOutput response; auto err = ServiceRequestWithTimeout(kFileTransferServiceName, ¤t_fts_uri_, ri, &response); @@ -565,8 +604,17 @@ Error ConsumerImpl::FtsSizeRequestWithTimeout(MessageMeta* info) { Error ConsumerImpl::FtsRequestWithTimeout(MessageMeta* info, MessageData* data) { RequestInfo ri = CreateFileTransferRequest(info); + if (use_new_api_format_) { + ri.extra_params += "&instanceid=" + httpclient__->UrlEscape(source_credentials_.instance_id); + ri.extra_params += "&pipelinestep=" + httpclient__->UrlEscape(source_credentials_.pipeline_step); + ri.extra_params += "&beamtime=" + httpclient__->UrlEscape(source_credentials_.beamtime_id); + ri.extra_params += "&stream=" + httpclient__->UrlEscape(info->stream); + ri.extra_params += "&source=" + httpclient__->UrlEscape(info->source); + } + RequestOutput response; response.data_output_size = info->size; + auto err = ServiceRequestWithTimeout(kFileTransferServiceName, ¤t_fts_uri_, ri, &response); if (err) { return err; @@ -596,8 +644,7 @@ Error ConsumerImpl::ResetLastReadMarker(std::string group_id, std::string stream } Error ConsumerImpl::SetLastReadMarker(std::string group_id, uint64_t value, std::string stream) { - RequestInfo ri; - ri.api = BrokerApiUri(std::move(stream), std::move(group_id), "resetcounter"); + RequestInfo ri = CreateBrokerApiRequest(std::move(stream), std::move(group_id), "resetcounter"); ri.extra_params = "&value=" + std::to_string(value); ri.post = true; @@ -626,8 +673,7 @@ Error ConsumerImpl::GetRecordFromServerById(uint64_t id, std::string* response, return ConsumerErrorTemplates::kWrongInput.Generate("empty stream"); } - RequestInfo ri; - ri.api = BrokerApiUri(std::move(stream), std::move(group_id), std::to_string(id)); + RequestInfo ri = CreateBrokerApiRequest(std::move(stream), std::move(group_id), std::to_string(id)); if (dataset) { @@ -641,15 +687,13 @@ Error ConsumerImpl::GetRecordFromServerById(uint64_t id, std::string* response, } std::string ConsumerImpl::GetBeamtimeMeta(Error* err) { - RequestInfo ri; - ri.api = BrokerApiUri("default", "0", "meta/0"); + RequestInfo ri = CreateBrokerApiRequest("default", "0", "meta/0"); return BrokerRequestWithTimeout(ri, err); } std::string ConsumerImpl::GetStreamMeta(const std::string& stream, Error* err) { - RequestInfo ri; - ri.api = BrokerApiUri(stream, "0", "meta/1"); + RequestInfo ri = CreateBrokerApiRequest(stream, "0", "meta/1"); return BrokerRequestWithTimeout(ri, err); } @@ -672,8 +716,7 @@ MessageMetas ConsumerImpl::QueryMessages(std::string query, std::string stream, return {}; } - RequestInfo ri; - ri.api = BrokerApiUri(std::move(stream), "0", "querymessages"); + RequestInfo ri = CreateBrokerApiRequest(std::move(stream), "0", "querymessages"); ri.post = true; ri.body = std::move(query); @@ -776,8 +819,7 @@ StreamInfos ConsumerImpl::GetStreamList(std::string from, StreamFilter filter, E } RequestInfo ConsumerImpl::GetStreamListRequest(const std::string& from, const StreamFilter& filter) const { - RequestInfo ri; - ri.api = BrokerApiUri("0", "", "streams"); + RequestInfo ri = CreateBrokerApiRequest("0", "", "streams"); ri.post = false; if (!from.empty()) { ri.extra_params = "&from=" + httpclient__->UrlEscape(from); @@ -844,8 +886,7 @@ Error ConsumerImpl::Acknowledge(std::string group_id, uint64_t id, std::string s if (stream.empty()) { return ConsumerErrorTemplates::kWrongInput.Generate("empty stream"); } - RequestInfo ri; - ri.api = BrokerApiUri(std::move(stream), std::move(group_id), std::to_string(id)); + RequestInfo ri = CreateBrokerApiRequest(std::move(stream), std::move(group_id), std::to_string(id)); ri.post = true; ri.body = "{\"Op\":\"ackmessage\"}"; @@ -863,8 +904,7 @@ IdList ConsumerImpl::GetUnacknowledgedMessages(std::string group_id, *error = ConsumerErrorTemplates::kWrongInput.Generate("empty stream"); return {}; } - RequestInfo ri; - ri.api = BrokerApiUri(std::move(stream), std::move(group_id), "nacks"); + RequestInfo ri = CreateBrokerApiRequest(std::move(stream), std::move(group_id), "nacks"); ri.extra_params = "&from=" + std::to_string(from_id) + "&to=" + std::to_string(to_id); auto json_string = BrokerRequestWithTimeout(ri, error); @@ -886,8 +926,7 @@ uint64_t ConsumerImpl::GetLastAcknowledgedMessage(std::string group_id, std::str *error = ConsumerErrorTemplates::kWrongInput.Generate("empty stream"); return 0; } - RequestInfo ri; - ri.api = BrokerApiUri(std::move(stream), std::move(group_id), "lastack"); + RequestInfo ri = CreateBrokerApiRequest(std::move(stream), std::move(group_id), "lastack"); auto json_string = BrokerRequestWithTimeout(ri, error); if (*error) { @@ -919,8 +958,7 @@ Error ConsumerImpl::NegativeAcknowledge(std::string group_id, if (stream.empty()) { return ConsumerErrorTemplates::kWrongInput.Generate("empty stream"); } - RequestInfo ri; - ri.api = BrokerApiUri(std::move(stream), std::move(group_id), std::to_string(id)); + RequestInfo ri = CreateBrokerApiRequest(std::move(stream), std::move(group_id), std::to_string(id)); ri.post = true; ri.body = R"({"Op":"negackmessage","Params":{"DelayMs":)" + std::to_string(delay_ms) + "}}"; @@ -961,8 +999,7 @@ uint64_t ConsumerImpl::ParseGetCurrentCountResponce(Error* err, const std::strin } RequestInfo ConsumerImpl::GetSizeRequestForSingleMessagesStream(std::string& stream) const { - RequestInfo ri; - ri.api = BrokerApiUri(std::move(stream), "", "size"); + RequestInfo ri = CreateBrokerApiRequest(std::move(stream), "", "size"); return ri; } @@ -1001,8 +1038,7 @@ Error ConsumerImpl::GetVersionInfo(std::string* client_info, std::string* server } RequestInfo ConsumerImpl::GetDeleteStreamRequest(std::string stream, DeleteStreamOptions options) const { - RequestInfo ri; - ri.api = BrokerApiUri(std::move(stream), "", "delete"); + RequestInfo ri = CreateBrokerApiRequest(std::move(stream), "", "delete"); ri.post = true; ri.body = options.Json(); return ri; @@ -1015,7 +1051,7 @@ Error ConsumerImpl::DeleteStream(std::string stream, DeleteStreamOptions options return err; } -std::string ConsumerImpl::BrokerApiUri(std::string stream, std::string group, std::string suffix) const { +RequestInfo ConsumerImpl::CreateBrokerApiRequest(std::string stream, std::string group, std::string suffix) const { auto stream_encoded = httpclient__->UrlEscape(std::move(stream)); auto group_encoded = group.size() > 0 ? httpclient__->UrlEscape(std::move(group)) : ""; auto uri = "/" + kConsumerProtocol.GetBrokerVersion() + "/beamtime/" + source_credentials_.beamtime_id + "/" @@ -1027,9 +1063,16 @@ std::string ConsumerImpl::BrokerApiUri(std::string stream, std::string group, st uri = uri + "/" + suffix; } - return uri; + RequestInfo ri; + ri.api = uri; -} + if (use_new_api_format_) { + ri.extra_params += "&instanceid=" + httpclient__->UrlEscape(source_credentials_.instance_id); + ri.extra_params += "&pipelinestep=" + httpclient__->UrlEscape(source_credentials_.pipeline_step); + } + return ri; -} \ No newline at end of file +} + +} diff --git a/consumer/api/cpp/src/consumer_impl.h b/consumer/api/cpp/src/consumer_impl.h index d25f4327a757d588c8027f91bef48b2f072f999f..6928e7cf2631971a5dc250f1c4001cb2f956c048 100644 --- a/consumer/api/cpp/src/consumer_impl.h +++ b/consumer/api/cpp/src/consumer_impl.h @@ -91,6 +91,7 @@ class ConsumerImpl final : public asapo::Consumer { Error DeleteStream(std::string stream, DeleteStreamOptions options) override; void SetTimeout(uint64_t timeout_ms) override; void ForceNoRdma() override; + Error DisableMonitoring(bool disable) override; NetworkConnectionType CurrentConnectionType() const override; @@ -138,7 +139,7 @@ class ConsumerImpl final : public asapo::Consumer { uint64_t min_size, Error* err); bool DataCanBeInBuffer(const MessageMeta* info); Error TryGetDataFromBuffer(const MessageMeta* info, MessageData* data); - Error CreateNetClientAndTryToGetFile(const MessageMeta* info, MessageData* data); + Error CreateNetClientAndTryToGetFile(const MessageMeta* info, const std::string& request_sender_details, MessageData* data); Error ServiceRequestWithTimeout(const std::string& service_name, std::string* service_uri, RequestInfo request, RequestOutput* response); std::string BrokerRequestWithTimeout(RequestInfo request, Error* err); @@ -153,7 +154,7 @@ class ConsumerImpl final : public asapo::Consumer { uint64_t GetCurrentCount(const RequestInfo& ri, Error* err); RequestInfo GetStreamListRequest(const std::string& from, const StreamFilter& filter) const; Error GetServerVersionInfo(std::string* server_info, bool* supported) ; - std::string BrokerApiUri(std::string stream, std::string group, std::string suffix) const; + RequestInfo CreateBrokerApiRequest(std::string stream, std::string group, std::string suffix) const; std::string endpoint_; std::string current_broker_uri_; @@ -162,6 +163,8 @@ class ConsumerImpl final : public asapo::Consumer { bool has_filesystem_; SourceCredentials source_credentials_; std::string data_source_encoded_; + bool use_new_api_format_ = true; + std::string request_sender_details_prefix_; uint64_t timeout_ms_ = 0; bool should_try_rdma_first_ = true; NetworkConnectionType current_connection_type_ = NetworkConnectionType::kUndefined; diff --git a/consumer/api/cpp/src/fabric_consumer_client.cpp b/consumer/api/cpp/src/fabric_consumer_client.cpp index 58e2776cb6d6d05722252e6742dfa6c4b067f7d3..0491e88c16e3bd0dfba71ead237540fb6f970c3d 100644 --- a/consumer/api/cpp/src/fabric_consumer_client.cpp +++ b/consumer/api/cpp/src/fabric_consumer_client.cpp @@ -11,7 +11,7 @@ FabricConsumerClient::FabricConsumerClient(): factory__(fabric::GenerateDefaultF } -Error FabricConsumerClient::GetData(const MessageMeta* info, MessageData* data) { +Error FabricConsumerClient::GetData(const MessageMeta* info, const std::string& request_sender_details, MessageData* data) { Error err; if (!client__) { client__ = factory__->CreateClient(&err); @@ -36,6 +36,7 @@ Error FabricConsumerClient::GetData(const MessageMeta* info, MessageData* data) GenericRequestHeader request_header{kOpcodeGetBufferData, info->buf_id, info->size}; strncpy(request_header.api_version, kConsumerProtocol.GetRdsVersion().c_str(), kMaxVersionSize); memcpy(request_header.message, mr->GetDetails(), sizeof(fabric::MemoryRegionDetails)); + strncpy(request_header.stream, request_sender_details.c_str(), kMaxMessageSize); GenericNetworkResponse response{}; PerformNetworkTransfer(address, &request_header, &response, &err); diff --git a/consumer/api/cpp/src/fabric_consumer_client.h b/consumer/api/cpp/src/fabric_consumer_client.h index a9f47ac11bfffa50b7109eeeaabb392dfc65952b..e981c75aac5f4978c73e50dbf7e7db7917d2d556 100644 --- a/consumer/api/cpp/src/fabric_consumer_client.h +++ b/consumer/api/cpp/src/fabric_consumer_client.h @@ -25,7 +25,7 @@ class FabricConsumerClient : public NetClient { std::atomic<fabric::FabricMessageId> global_message_id_{0}; public: - Error GetData(const MessageMeta* info, MessageData* data) override; + Error GetData(const MessageMeta* info, const std::string& request_sender_details, MessageData* data) override; private: fabric::FabricAddress GetAddressOrConnect(const MessageMeta* info, Error* error); diff --git a/consumer/api/cpp/src/net_client.h b/consumer/api/cpp/src/net_client.h index 831b9b45677af84e74e9d312769ab82cf1ad3e5a..5e5a365563c5a5c173f6befa3dfbb05e593f94d4 100644 --- a/consumer/api/cpp/src/net_client.h +++ b/consumer/api/cpp/src/net_client.h @@ -8,7 +8,7 @@ namespace asapo { class NetClient { public: - virtual Error GetData(const MessageMeta* info, MessageData* data) = 0; + virtual Error GetData(const MessageMeta* info, const std::string& request_sender_details, MessageData* data) = 0; virtual ~NetClient() = default; }; diff --git a/consumer/api/cpp/src/tcp_consumer_client.cpp b/consumer/api/cpp/src/tcp_consumer_client.cpp index 2f5ea5396e01772d61c097d869d31228659a57ef..6f79f233233b895bb4f2eaf8f0dcb85a6337dc49 100644 --- a/consumer/api/cpp/src/tcp_consumer_client.cpp +++ b/consumer/api/cpp/src/tcp_consumer_client.cpp @@ -11,9 +11,11 @@ TcpConsumerClient::TcpConsumerClient() : io__{GenerateDefaultIO()}, connection_p } -Error TcpConsumerClient::SendGetDataRequest(SocketDescriptor sd, const MessageMeta* info) const noexcept { +Error TcpConsumerClient::SendGetDataRequest(SocketDescriptor sd, const std::string& request_sender_details, const MessageMeta* info) const noexcept { Error err; GenericRequestHeader request_header{kOpcodeGetBufferData, info->buf_id, info->size}; + + strncpy(request_header.stream, request_sender_details.c_str(), kMaxMessageSize); strncpy(request_header.api_version, kConsumerProtocol.GetRdsVersion().c_str(), kMaxVersionSize); io__->Send(sd, &request_header, sizeof(request_header), &err); if (err) { @@ -23,14 +25,14 @@ Error TcpConsumerClient::SendGetDataRequest(SocketDescriptor sd, const MessageMe return err; } -Error TcpConsumerClient::ReconnectAndResendGetDataRequest(SocketDescriptor* sd, +Error TcpConsumerClient::ReconnectAndResendGetDataRequest(SocketDescriptor* sd, const std::string& request_sender_details, const MessageMeta* info) const noexcept { Error err; *sd = connection_pool__->Reconnect(*sd, &err); if (err) { return err; } else { - return SendGetDataRequest(*sd, info); + return SendGetDataRequest(*sd, request_sender_details, info); } } @@ -64,12 +66,12 @@ Error TcpConsumerClient::ReceiveResponce(SocketDescriptor sd) const noexcept { return nullptr; } -Error TcpConsumerClient::QueryCacheHasData(SocketDescriptor* sd, const MessageMeta* info, +Error TcpConsumerClient::QueryCacheHasData(SocketDescriptor* sd, const std::string& request_sender_details, const MessageMeta* info, bool try_reconnect) const noexcept { Error err; - err = SendGetDataRequest(*sd, info); + err = SendGetDataRequest(*sd, request_sender_details, info); if (err && try_reconnect) { - err = ReconnectAndResendGetDataRequest(sd, info); + err = ReconnectAndResendGetDataRequest(sd, request_sender_details, info); } if (err) { return err; @@ -98,7 +100,7 @@ Error TcpConsumerClient::ReceiveData(SocketDescriptor sd, const MessageMeta* inf return err; } -Error TcpConsumerClient::GetData(const MessageMeta* info, MessageData* data) { +Error TcpConsumerClient::GetData(const MessageMeta* info, const std::string& request_sender_details, MessageData* data) { Error err; bool reused; auto sd = connection_pool__->GetFreeConnection(info->source, &reused, &err); @@ -106,7 +108,7 @@ Error TcpConsumerClient::GetData(const MessageMeta* info, MessageData* data) { return err; } - err = QueryCacheHasData(&sd, info, reused); + err = QueryCacheHasData(&sd, request_sender_details, info, reused); if (err) { return err; } diff --git a/consumer/api/cpp/src/tcp_consumer_client.h b/consumer/api/cpp/src/tcp_consumer_client.h index b7961ee44ab88af22bc45ab9a87a55a5e1ab8b9e..79950a974bee00b61c5707f819a5dd278eb731cd 100644 --- a/consumer/api/cpp/src/tcp_consumer_client.h +++ b/consumer/api/cpp/src/tcp_consumer_client.h @@ -10,14 +10,14 @@ namespace asapo { class TcpConsumerClient : public NetClient { public: explicit TcpConsumerClient(); - Error GetData(const MessageMeta* info, MessageData* data) override; + Error GetData(const MessageMeta* info, const std::string& request_sender_details, MessageData* data) override; std::unique_ptr<IO> io__; std::unique_ptr<TcpConnectionPool> connection_pool__; private: - Error SendGetDataRequest(SocketDescriptor sd, const MessageMeta* info) const noexcept; - Error ReconnectAndResendGetDataRequest(SocketDescriptor* sd, const MessageMeta* info) const noexcept; + Error SendGetDataRequest(SocketDescriptor sd, const std::string& request_sender_details, const MessageMeta* info) const noexcept; + Error ReconnectAndResendGetDataRequest(SocketDescriptor* sd, const std::string& request_sender_details, const MessageMeta* info) const noexcept; Error ReceiveResponce(SocketDescriptor sd) const noexcept; - Error QueryCacheHasData(SocketDescriptor* sd, const MessageMeta* info, bool try_reconnect) const noexcept; + Error QueryCacheHasData(SocketDescriptor* sd, const std::string& request_sender_details, const MessageMeta* info, bool try_reconnect) const noexcept; Error ReceiveData(SocketDescriptor sd, const MessageMeta* info, MessageData* data) const noexcept; }; diff --git a/consumer/api/cpp/unittests/mocking.h b/consumer/api/cpp/unittests/mocking.h index 5ded4240f8ff721aae94d699c00d9d1dddd49479..fa0784bc22af387094c8c8b9ef2a20fa00f68be9 100644 --- a/consumer/api/cpp/unittests/mocking.h +++ b/consumer/api/cpp/unittests/mocking.h @@ -12,11 +12,11 @@ namespace asapo { class MockNetClient : public asapo::NetClient { public: - Error GetData(const MessageMeta* info, MessageData* data) override { - return Error(GetData_t(info, data)); + Error GetData(const MessageMeta* info, const std::string& request_sender_details, MessageData* data) override { + return Error(GetData_t(info, request_sender_details, data)); } - MOCK_CONST_METHOD2(GetData_t, ErrorInterface * (const MessageMeta* info, MessageData* data)); + MOCK_CONST_METHOD3(GetData_t, ErrorInterface * (const MessageMeta* info, const std::string& request_sender_details, MessageData* data)); }; diff --git a/consumer/api/cpp/unittests/test_consumer_api.cpp b/consumer/api/cpp/unittests/test_consumer_api.cpp index c96b738218fdb8a2cb5f7e195af1d3f1c5e03f1b..1222a2cacd3a6d8e89ebf4e2ff8f8da1766c49b7 100644 --- a/consumer/api/cpp/unittests/test_consumer_api.cpp +++ b/consumer/api/cpp/unittests/test_consumer_api.cpp @@ -31,7 +31,7 @@ TEST_F(ConsumerFactoryTests, CreateServerDataSource) { "path", false, asapo::SourceCredentials{asapo::SourceType::kProcessed, - "beamtime_id", "", "", "token"}, + "instance", "step", "beamtime_id", "", "", "token"}, &error); ASSERT_THAT(error, Eq(nullptr)); diff --git a/consumer/api/cpp/unittests/test_consumer_impl.cpp b/consumer/api/cpp/unittests/test_consumer_impl.cpp index ed8e8b07558d63f97d7f1a9e27a4706815d67b3a..2fee68271f47094771aeaccf8711beac0f11089d 100644 --- a/consumer/api/cpp/unittests/test_consumer_impl.cpp +++ b/consumer/api/cpp/unittests/test_consumer_impl.cpp @@ -48,7 +48,7 @@ TEST(FolderDataBroker, Constructor) { auto consumer = std::unique_ptr<ConsumerImpl> {new ConsumerImpl("test", "path", false, asapo::SourceCredentials{asapo::SourceType::kProcessed, - "beamtime_id", "", "", "token"}) + "instance", "step", "beamtime_id", "", "", "token"}) }; ASSERT_THAT(dynamic_cast<asapo::SystemIO*>(consumer->io__.get()), Ne(nullptr)); ASSERT_THAT(dynamic_cast<asapo::CurlHttpClient*>(consumer->httpclient__.get()), Ne(nullptr)); @@ -60,9 +60,9 @@ const uint8_t expected_value = 1; class ConsumerImplTests : public Test { public: std::unique_ptr<ConsumerImpl> consumer, fts_consumer; - NiceMock<MockIO> mock_io; - NiceMock<MockHttpClient> mock_http_client; - NiceMock<MockNetClient> mock_netclient; + NiceMock<MockIO> mock_io{}; + NiceMock<MockHttpClient> mock_http_client{}; + NiceMock<MockNetClient> mock_netclient{}; MessageMeta info; std::string expected_server_uri = "test:8400"; std::string expected_broker_uri = "asapo-broker:5005"; @@ -84,6 +84,15 @@ class ConsumerImplTests : public Test { std::string expected_metadata = "{\"meta\":1}"; std::string expected_query_string = "bla"; std::string expected_folder_token = "folder_token"; + + std::string expected_instance_id = "some instance"; + std::string expected_pipeline_step = "a new step"; + std::string expected_instance_id_encoded = "some%20instance"; + std::string expected_pipeline_step_encoded = "a%20new%20step"; + + std::string expected_token_url_with_sourceinfo = std::string("token") + + "&instanceid=" + expected_instance_id_encoded + "&pipelinestep=" + expected_pipeline_step_encoded; + std::string expected_beamtime_id = "beamtime_id"; uint64_t expected_message_size = 100; uint64_t expected_dataset_id = 1; @@ -93,6 +102,16 @@ class ConsumerImplTests : public Test { "\"}"; std::string expected_cookie = "Authorization=Bearer " + expected_folder_token; + std::string expected_request_sender_details_prefix = expected_instance_id + "§" + + expected_pipeline_step + "§" + + expected_beamtime_id + "§" + + expected_data_source + "§"; + std::string expected_request_sender_details_with_stream = expected_instance_id + "§" + + expected_pipeline_step + "§" + + expected_beamtime_id + "§" + + expected_data_source + "§" + + expected_stream; + void AssertSingleFileTransfer(); void SetUp() override { consumer = std::unique_ptr<ConsumerImpl> { @@ -100,7 +119,7 @@ class ConsumerImplTests : public Test { expected_path, true, asapo::SourceCredentials{ - asapo::SourceType::kProcessed, expected_beamtime_id, "", + asapo::SourceType::kProcessed, expected_instance_id, expected_pipeline_step, expected_beamtime_id, "", expected_data_source, expected_token}) }; fts_consumer = std::unique_ptr<ConsumerImpl> { @@ -108,7 +127,7 @@ class ConsumerImplTests : public Test { expected_path, false, asapo::SourceCredentials{ - asapo::SourceType::kProcessed, expected_beamtime_id, "", + asapo::SourceType::kProcessed, expected_instance_id, expected_pipeline_step, expected_beamtime_id, "", expected_data_source, expected_token}) }; consumer->io__ = std::unique_ptr<IO> {&mock_io}; @@ -117,23 +136,36 @@ class ConsumerImplTests : public Test { fts_consumer->io__ = std::unique_ptr<IO> {&mock_io}; fts_consumer->httpclient__ = std::unique_ptr<asapo::HttpClient> {&mock_http_client}; fts_consumer->net_client__ = std::unique_ptr<asapo::NetClient> {&mock_netclient}; - ON_CALL(mock_http_client, UrlEscape_t(expected_stream)).WillByDefault(Return(expected_stream_encoded)); - ON_CALL(mock_http_client, UrlEscape_t(expected_group_id)).WillByDefault(Return(expected_group_id_encoded)); - ON_CALL(mock_http_client, UrlEscape_t(expected_data_source)).WillByDefault(Return(expected_data_source_encoded)); - ON_CALL(mock_http_client, UrlEscape_t("0")).WillByDefault(Return("0")); - ON_CALL(mock_http_client, UrlEscape_t("")).WillByDefault(Return("")); - ON_CALL(mock_http_client, UrlEscape_t("default")).WillByDefault(Return("default")); - ON_CALL(mock_http_client, UrlEscape_t("stream")).WillByDefault(Return("stream")); + { + ON_CALL(mock_http_client, UrlEscape_t(expected_instance_id)).WillByDefault(Return(expected_instance_id_encoded)); + ON_CALL(mock_http_client, UrlEscape_t(expected_pipeline_step)).WillByDefault(Return(expected_pipeline_step_encoded)); + ON_CALL(mock_http_client, UrlEscape_t(expected_stream)).WillByDefault(Return(expected_stream_encoded)); + ON_CALL(mock_http_client, UrlEscape_t(expected_group_id)).WillByDefault(Return(expected_group_id_encoded)); + ON_CALL(mock_http_client, UrlEscape_t(expected_data_source)).WillByDefault(Return(expected_data_source_encoded)); + ON_CALL(mock_http_client, UrlEscape_t("0")).WillByDefault(Return("0")); + ON_CALL(mock_http_client, UrlEscape_t("")).WillByDefault(Return("")); + ON_CALL(mock_http_client, UrlEscape_t("default")).WillByDefault(Return("default")); + ON_CALL(mock_http_client, UrlEscape_t("stream")).WillByDefault(Return("stream")); + ON_CALL(mock_http_client, UrlEscape_t("instance")).WillByDefault(Return("instance")); + ON_CALL(mock_http_client, UrlEscape_t("step")).WillByDefault(Return("step")); + ON_CALL(mock_http_client, UrlEscape_t("DefaultStep")).WillByDefault(Return("DefaultStep")); + ON_CALL(mock_http_client, UrlEscape_t("a")).WillByDefault(Return("b")); + ON_CALL(mock_http_client, UrlEscape_t("b")).WillByDefault(Return("b")); + } } void TearDown() override { consumer->io__.release(); consumer->httpclient__.release(); consumer->net_client__.release(); + fts_consumer->io__.release(); fts_consumer->httpclient__.release(); fts_consumer->net_client__.release(); + Mock::VerifyAndClear(&mock_io); + Mock::VerifyAndClear(&mock_http_client); + Mock::VerifyAndClear(&mock_netclient); } void MockGet(const std::string& response, asapo::HttpCode return_code = HttpCode::OK) { EXPECT_CALL(mock_http_client, Get_t(HasSubstr(expected_broker_api), _, _)).WillOnce(DoAll( @@ -152,15 +184,14 @@ class ConsumerImplTests : public Test { } void MockGetServiceUri(std::string service, std::string result) { EXPECT_CALL(mock_http_client, Get_t(HasSubstr(expected_server_uri + "/asapo-discovery/v0.1/" + service + "?token=" - + expected_token + "&protocol=" + expected_consumer_protocol), - _, - _)).WillOnce(DoAll( + + expected_token + "&protocol=" + expected_consumer_protocol), _, _) + ).WillOnce(DoAll( SetArgPointee<1>(HttpCode::OK), SetArgPointee<2>(nullptr), Return(result))); } - void MockBeforeFTS(MessageData* data); + void MockBeforeFTS(const std::string& expected_request_sender_details, MessageData* data); void MockGetFTSUri() { MockGetServiceUri("asapo-file-transfer", expected_fts_uri); @@ -189,15 +220,42 @@ class ConsumerImplTests : public Test { WillRepeatedly(DoAll(SetArgPointee<2>(simple_error), testing::Return(nullptr))); } + //Fake info MessageMeta CreateFI(uint64_t buf_id = expected_buf_id) { MessageMeta fi; fi.size = expected_message_size; fi.id = 1; fi.buf_id = buf_id; fi.name = expected_filename; + fi.stream = expected_stream; fi.timestamp = std::chrono::system_clock::now(); return fi; } + + void CheckDefaultingOfCredentials(asapo::SourceCredentials credentials, std::string expectedUrlPath) { + consumer->io__.release(); + consumer->httpclient__.release(); + consumer->net_client__.release(); + consumer = std::unique_ptr<ConsumerImpl> { + new ConsumerImpl(expected_server_uri, + expected_path, + false, + std::move(credentials)) + }; + consumer->io__ = std::unique_ptr<IO> {&mock_io}; + consumer->httpclient__ = std::unique_ptr<asapo::HttpClient> {&mock_http_client}; + consumer->net_client__ = std::unique_ptr<asapo::NetClient> {&mock_netclient}; + MockGetBrokerUri(); + + EXPECT_CALL(mock_http_client, + Get_t(expected_broker_api + expectedUrlPath, _, + _)).WillOnce(DoAll( + SetArgPointee<1>(HttpCode::OK), + SetArgPointee<2>(nullptr), + Return(""))); + + consumer->GetNext(expected_group_id, &info, nullptr, "stream"); + } }; TEST_F(ConsumerImplTests, GetMessageReturnsErrorOnWrongInput) { @@ -206,48 +264,76 @@ TEST_F(ConsumerImplTests, GetMessageReturnsErrorOnWrongInput) { } TEST_F(ConsumerImplTests, DefaultStreamIsDetector) { - consumer->io__.release(); - consumer->httpclient__.release(); - consumer->net_client__.release(); - consumer = std::unique_ptr<ConsumerImpl> { - new ConsumerImpl(expected_server_uri, - expected_path, - false, - asapo::SourceCredentials{ - asapo::SourceType::kProcessed, "beamtime_id", "", "", - expected_token}) - }; - consumer->io__ = std::unique_ptr<IO> {&mock_io}; - consumer->httpclient__ = std::unique_ptr<asapo::HttpClient> {&mock_http_client}; - consumer->net_client__ = std::unique_ptr<asapo::NetClient> {&mock_netclient}; + CheckDefaultingOfCredentials( + asapo::SourceCredentials{ + asapo::SourceType::kProcessed, "instance", "step", "beamtime_id", "", "", expected_token + }, + "/beamtime/beamtime_id/detector/stream/" + expected_group_id_encoded + "/next?token=" + expected_token + + "&instanceid=instance&pipelinestep=step"); +} - MockGetBrokerUri(); +TEST_F(ConsumerImplTests, DefaultPipelineStepIsDefaultStep) { + CheckDefaultingOfCredentials( + asapo::SourceCredentials{ + asapo::SourceType::kProcessed, "instance", "", "beamtime_id", "a", "b", expected_token + }, + "/beamtime/beamtime_id/b/stream/" + expected_group_id_encoded + "/next?token=" + expected_token + + "&instanceid=instance&pipelinestep=DefaultStep"); +} - EXPECT_CALL(mock_http_client, - Get_t(expected_broker_api + "/beamtime/beamtime_id/detector/stream/" + expected_group_id_encoded - + - "/next?token=" - + expected_token, _, - _)).WillOnce(DoAll( - SetArgPointee<1>(HttpCode::OK), - SetArgPointee<2>(nullptr), - Return(""))); +TEST_F(ConsumerImplTests, AutoPipelineStepIsDefaultStep) { + CheckDefaultingOfCredentials( + asapo::SourceCredentials{ + asapo::SourceType::kProcessed, "instance", "auto", "beamtime_id", "a", "b", expected_token + }, + "/beamtime/beamtime_id/b/stream/" + expected_group_id_encoded + "/next?token=" + expected_token + + "&instanceid=instance&pipelinestep=DefaultStep"); +} + +/* + * TODO: Hard to test because instance id is set over DefaultIO in ctor + * +TEST_F(ConsumerImplTests, DefaultInstanceIdIsHostAndPid) { + EXPECT_CALL(mock_io, GetHostName_t(_)). + WillOnce(DoAll(testing::SetArgPointee<0>(nullptr), Return("myHostName"))); + EXPECT_CALL(mock_io, GetCurrentPid()). + WillOnce(Return(201)); + + CheckDefaultingOfCredentials( + asapo::SourceCredentials{ + asapo::SourceType::kProcessed, "", "step", "beamtime_id", "", "", expected_token + }, + "/beamtime/beamtime_id/detector/stream/" + expected_group_id_encoded + "/next?token=" + expected_token + + "&instanceid=myHostName_201&pipelinestep=step"); +} - consumer->GetNext(expected_group_id, &info, nullptr, "stream"); +TEST_F(ConsumerImplTests, AutoInstanceIdIsHostAndPid) { + EXPECT_CALL(mock_io, GetHostName_t(_)). + WillOnce(DoAll(testing::SetArgPointee<0>(nullptr), Return("myHostName"))); + EXPECT_CALL(mock_io, GetCurrentPid()). + WillOnce(Return(201)); + + CheckDefaultingOfCredentials( + asapo::SourceCredentials{ + asapo::SourceType::kProcessed, "auto", "step", "beamtime_id", "", "", expected_token + }, + "/beamtime/beamtime_id/detector/stream/" + expected_group_id_encoded + "/next?token=" + expected_token + + "&instanceid=myHostName_201&pipelinestep=step"); } + */ TEST_F(ConsumerImplTests, GetNextUsesCorrectUriWithStream) { MockGetBrokerUri(); - EXPECT_CALL(mock_http_client, - Get_t(expected_broker_api + "/beamtime/beamtime_id/" + expected_data_source_encoded + "/" - + - expected_stream_encoded + "/" + expected_group_id_encoded + "/next?token=" - + expected_token, _, - _)).WillOnce(DoAll( - SetArgPointee<1>(HttpCode::OK), - SetArgPointee<2>(nullptr), - Return(""))); + EXPECT_CALL(mock_http_client, Get_t(expected_broker_api + "/beamtime/beamtime_id/" + expected_data_source_encoded + "/" + + + expected_stream_encoded + "/" + expected_group_id_encoded + "/next?token=" + + expected_token + + "&instanceid=" + expected_instance_id_encoded + "&pipelinestep=" + expected_pipeline_step_encoded, _, + _)).WillOnce(DoAll( + SetArgPointee<1>(HttpCode::OK), + SetArgPointee<2>(nullptr), + Return(""))); consumer->GetNext(expected_group_id, &info, nullptr, expected_stream); } @@ -258,7 +344,8 @@ TEST_F(ConsumerImplTests, GetLastOnceUsesCorrectUri) { Get_t(expected_broker_api + "/beamtime/beamtime_id/" + expected_data_source_encoded + "/" + expected_stream_encoded + "/" + expected_group_id_encoded + "/groupedlast?token=" - + expected_token, _, + + expected_token + + "&instanceid=" + expected_instance_id_encoded + "&pipelinestep=" + expected_pipeline_step_encoded, _, _)).WillOnce(DoAll( SetArgPointee<1>(HttpCode::OK), SetArgPointee<2>(nullptr), @@ -270,10 +357,9 @@ TEST_F(ConsumerImplTests, GetLastUsesCorrectUri) { MockGetBrokerUri(); EXPECT_CALL(mock_http_client, - Get_t(expected_broker_api + "/beamtime/beamtime_id/" + expected_data_source_encoded + "/" - + expected_stream_encoded + - "/0/last?token=" - + expected_token, _, + Get_t(expected_broker_api + "/beamtime/beamtime_id/" + expected_data_source_encoded + "/" + expected_stream_encoded + + "/0/last?token=" + expected_token + + "&instanceid=" + expected_instance_id_encoded + "&pipelinestep=" + expected_pipeline_step_encoded, _, _)).WillOnce(DoAll( SetArgPointee<1>(HttpCode::OK), SetArgPointee<2>(nullptr), @@ -329,6 +415,7 @@ TEST_F(ConsumerImplTests, GetMessageReturnsNoDataFromHttpClient) { auto err = consumer->GetNext(expected_group_id, &info, nullptr, expected_stream); auto err_data = static_cast<const asapo::ConsumerErrorData*>(err->GetCustomData()); + ASSERT_THAT(err_data, Ne(nullptr)); ASSERT_THAT(err_data->id, Eq(1)); ASSERT_THAT(err_data->id_max, Eq(2)); ASSERT_THAT(err_data->next_stream, Eq("")); @@ -456,8 +543,9 @@ TEST_F(ConsumerImplTests, GetMessageReturnsNoDataAfterTimeoutEvenIfOtherErrorOcc EXPECT_CALL(mock_http_client, Get_t(expected_broker_api + "/beamtime/beamtime_id/" + expected_data_source_encoded + "/stream/0/" - + std::to_string(expected_dataset_id) + "?token=" - + expected_token, _, _)).Times(AtLeast(1)).WillRepeatedly(DoAll( + + std::to_string(expected_dataset_id) + "?token=" + expected_token + + "&instanceid=" + expected_instance_id_encoded + "&pipelinestep=" + expected_pipeline_step_encoded + , _, _)).Times(AtLeast(1)).WillRepeatedly(DoAll( SetArgPointee<1>(HttpCode::ServiceUnavailable), SetArgPointee<2>(nullptr), Return(""))); @@ -550,7 +638,7 @@ TEST_F(ConsumerImplTests, GetMessageReturnsIfNoDataNeeded) { MockGetBrokerUri(); MockGet("error_response"); - EXPECT_CALL(mock_netclient, GetData_t(_, _)).Times(0); + EXPECT_CALL(mock_netclient, GetData_t(_, _, _)).Times(0); EXPECT_CALL(mock_io, GetDataFromFile_t(_, _, _)).Times(0); consumer->GetNext(expected_group_id, &info, nullptr, expected_stream); @@ -563,7 +651,7 @@ TEST_F(ConsumerImplTests, GetMessageTriesToGetDataFromMemoryCache) { MockGet(json); MessageData data; - EXPECT_CALL(mock_netclient, GetData_t(&info, &data)).WillOnce(Return(nullptr)); + EXPECT_CALL(mock_netclient, GetData_t(&info, expected_request_sender_details_with_stream, &data)).WillOnce(Return(nullptr)); MockReadDataFromFile(0); consumer->GetNext(expected_group_id, &info, &data, expected_stream); @@ -580,7 +668,7 @@ TEST_F(ConsumerImplTests, GetMessageCallsReadFromFileIfCannotReadFromCache) { MessageData data; - EXPECT_CALL(mock_netclient, GetData_t(&info, + EXPECT_CALL(mock_netclient, GetData_t(&info, expected_request_sender_details_with_stream, &data)).WillOnce(Return(asapo::IOErrorTemplates::kUnknownIOError.Generate().release())); MockReadDataFromFile(); @@ -596,7 +684,7 @@ TEST_F(ConsumerImplTests, GetMessageCallsReadFromFileIfZeroBufId) { MessageData data; - EXPECT_CALL(mock_netclient, GetData_t(_, _)).Times(0); + EXPECT_CALL(mock_netclient, GetData_t(_, _, _)).Times(0); MockReadDataFromFile(); @@ -612,7 +700,7 @@ TEST_F(ConsumerImplTests, GetMessageCallsRetriesReadFromFile) { MessageData data; - EXPECT_CALL(mock_netclient, GetData_t(_, _)).Times(0); + EXPECT_CALL(mock_netclient, GetData_t(_, _, _)).Times(0); MockReadDataFromFile(2); @@ -690,7 +778,7 @@ TEST_F(ConsumerImplTests, GetCurrentSizeUsesCorrectUri) { Get_t(expected_broker_api + "/beamtime/beamtime_id/" + expected_data_source_encoded + "/" + expected_stream_encoded + "/size?token=" - + expected_token, _, _)).WillOnce(DoAll( + + expected_token + "&instanceid=" + expected_instance_id_encoded + "&pipelinestep=" + expected_pipeline_step_encoded, _, _)).WillOnce(DoAll( SetArgPointee<1>(HttpCode::OK), SetArgPointee<2>(nullptr), Return("{\"size\":10}"))); @@ -706,7 +794,8 @@ TEST_F(ConsumerImplTests, GetCurrentSizeErrorOnWrongResponce) { EXPECT_CALL(mock_http_client, Get_t(expected_broker_api + "/beamtime/beamtime_id/" + expected_data_source_encoded + "/" + expected_stream_encoded + "/size?token=" - + expected_token, _, _)).WillRepeatedly(DoAll( + + expected_token + + "&instanceid=" + expected_instance_id_encoded + "&pipelinestep=" + expected_pipeline_step_encoded, _, _)).WillRepeatedly(DoAll( SetArgPointee<1>(HttpCode::Unauthorized), SetArgPointee<2>(nullptr), Return(""))); @@ -722,7 +811,7 @@ TEST_F(ConsumerImplTests, GetNDataErrorOnWrongParse) { EXPECT_CALL(mock_http_client, Get_t(expected_broker_api + "/beamtime/beamtime_id/" + expected_data_source_encoded + "/stream/size?token=" - + expected_token, _, _)).WillOnce(DoAll( + + expected_token_url_with_sourceinfo, _, _)).WillOnce(DoAll( SetArgPointee<1>(HttpCode::OK), SetArgPointee<2>(nullptr), Return("{\"siz\":10}"))); @@ -742,7 +831,8 @@ TEST_F(ConsumerImplTests, GetByIdUsesCorrectUri) { "/stream/0/" + std::to_string( expected_dataset_id) + "?token=" - + expected_token, _, + + expected_token + + "&instanceid=" + expected_instance_id_encoded + "&pipelinestep=" + expected_pipeline_step_encoded, _, _)).WillOnce(DoAll( SetArgPointee<1>(HttpCode::OK), SetArgPointee<2>(nullptr), @@ -761,7 +851,8 @@ TEST_F(ConsumerImplTests, GetByIdTimeouts) { EXPECT_CALL(mock_http_client, Get_t(expected_broker_api + "/beamtime/beamtime_id/" + expected_data_source_encoded + "/stream/0/" + std::to_string(expected_dataset_id) + "?token=" - + expected_token, _, _)).WillOnce(DoAll( + + expected_token + + "&instanceid=" + expected_instance_id_encoded + "&pipelinestep=" + expected_pipeline_step_encoded, _, _)).WillOnce(DoAll( SetArgPointee<1>(HttpCode::Conflict), SetArgPointee<2>(nullptr), Return(""))); @@ -778,7 +869,7 @@ TEST_F(ConsumerImplTests, GetByIdReturnsEndOfStream) { EXPECT_CALL(mock_http_client, Get_t(expected_broker_api + "/beamtime/beamtime_id/" + expected_data_source_encoded + "/stream/0/" + std::to_string(expected_dataset_id) + "?token=" - + expected_token, _, _)).WillOnce(DoAll( + + expected_token_url_with_sourceinfo, _, _)).WillOnce(DoAll( SetArgPointee<1>(HttpCode::Conflict), SetArgPointee<2>(nullptr), Return("{\"op\":\"get_record_by_id\",\"id\":1,\"id_max\":1,\"next_stream\":\"""\"}"))); @@ -795,7 +886,8 @@ TEST_F(ConsumerImplTests, GetByIdReturnsEndOfStreamWhenIdTooLarge) { EXPECT_CALL(mock_http_client, Get_t(expected_broker_api + "/beamtime/beamtime_id/" + expected_data_source_encoded + "/stream/0/" + std::to_string(expected_dataset_id) + "?token=" - + expected_token, _, _)).WillOnce(DoAll( + + expected_token + + "&instanceid=" + expected_instance_id_encoded + "&pipelinestep=" + expected_pipeline_step_encoded, _, _)).WillOnce(DoAll( SetArgPointee<1>(HttpCode::Conflict), SetArgPointee<2>(nullptr), Return("{\"op\":\"get_record_by_id\",\"id\":100,\"id_max\":1,\"next_stream\":\"""\"}"))); @@ -811,7 +903,7 @@ TEST_F(ConsumerImplTests, GetBeamtimeMetaDataOK) { EXPECT_CALL(mock_http_client, Get_t(expected_broker_api + "/beamtime/beamtime_id/" + expected_data_source_encoded + "/default/0/meta/0?token=" - + expected_token, _, + + expected_token_url_with_sourceinfo, _, _)).WillOnce(DoAll( SetArgPointee<1>(HttpCode::OK), SetArgPointee<2>(nullptr), @@ -831,7 +923,8 @@ TEST_F(ConsumerImplTests, GetStreamMetaDataOK) { EXPECT_CALL(mock_http_client, Get_t(expected_broker_api + "/beamtime/beamtime_id/" + expected_data_source_encoded + "/" + expected_stream_encoded + "/0/meta/1?token=" - + expected_token, _, + + expected_token + + "&instanceid=" + expected_instance_id_encoded + "&pipelinestep=" + expected_pipeline_step_encoded, _, _)).WillOnce(DoAll( SetArgPointee<1>(HttpCode::OK), SetArgPointee<2>(nullptr), @@ -935,7 +1028,7 @@ TEST_F(ConsumerImplTests, QueryMessagesReturnRecords) { EXPECT_CALL(mock_http_client, Post_t(expected_broker_api + "/beamtime/beamtime_id/" + expected_data_source_encoded + "/stream/0" + - "/querymessages?token=" + expected_token, _, expected_query_string, _, _)).WillOnce(DoAll( + "/querymessages?token=" + expected_token_url_with_sourceinfo, _, expected_query_string, _, _)).WillOnce(DoAll( SetArgPointee<3>(HttpCode::OK), SetArgPointee<4>(nullptr), Return(responce_string))); @@ -957,7 +1050,8 @@ TEST_F(ConsumerImplTests, GetNextDatasetUsesCorrectUri) { EXPECT_CALL(mock_http_client, Get_t(expected_broker_api + "/beamtime/beamtime_id/" + expected_data_source_encoded + "/stream/" + expected_group_id_encoded + "/next?token=" - + expected_token + "&dataset=true&minsize=0", _, + + expected_token + "&dataset=true&minsize=0" + + "&instanceid=" + expected_instance_id_encoded + "&pipelinestep=" + expected_pipeline_step_encoded, _, _)).WillOnce(DoAll( SetArgPointee<1>(HttpCode::OK), SetArgPointee<2>(nullptr), @@ -1093,7 +1187,8 @@ TEST_F(ConsumerImplTests, GetLastDatasetUsesCorrectUri) { Get_t(expected_broker_api + "/beamtime/beamtime_id/" + expected_data_source_encoded + "/" + expected_stream_encoded + "/0/last?token=" - + expected_token + "&dataset=true&minsize=1", _, + + expected_token + "&dataset=true&minsize=1" + + "&instanceid=" + expected_instance_id_encoded + "&pipelinestep=" + expected_pipeline_step_encoded, _, _)).WillOnce(DoAll( SetArgPointee<1>(HttpCode::OK), SetArgPointee<2>(nullptr), @@ -1109,7 +1204,8 @@ TEST_F(ConsumerImplTests, GetLastDatasetInGroupUsesCorrectUri) { Get_t(expected_broker_api + "/beamtime/beamtime_id/" + expected_data_source_encoded + "/" + expected_stream_encoded + "/" + expected_group_id_encoded + "/groupedlast?token=" - + expected_token + "&dataset=true&minsize=1", _, + + expected_token + "&dataset=true&minsize=1" + + "&instanceid=" + expected_instance_id_encoded + "&pipelinestep=" + expected_pipeline_step_encoded, _, _)).WillOnce(DoAll( SetArgPointee<1>(HttpCode::OK), SetArgPointee<2>(nullptr), @@ -1125,7 +1221,9 @@ TEST_F(ConsumerImplTests, GetDatasetByIdUsesCorrectUri) { EXPECT_CALL(mock_http_client, Get_t(expected_broker_api + "/beamtime/beamtime_id/" + expected_data_source_encoded + "/stream/0/" + std::to_string(expected_dataset_id) + "?token=" - + expected_token + "&dataset=true" + "&minsize=0", _, + + expected_token + + "&instanceid=" + expected_instance_id_encoded + "&pipelinestep=" + expected_pipeline_step_encoded + + "&dataset=true" + "&minsize=0", _, _)).WillOnce(DoAll( SetArgPointee<1>(HttpCode::OK), SetArgPointee<2>(nullptr), @@ -1137,15 +1235,15 @@ TEST_F(ConsumerImplTests, GetDatasetByIdUsesCorrectUri) { TEST_F(ConsumerImplTests, DeleteStreamUsesCorrectUri) { MockGetBrokerUri(); std::string expected_delete_stream_query_string = "{\"ErrorOnNotExist\":true,\"DeleteMeta\":true}"; - EXPECT_CALL(mock_http_client, - Post_t(expected_broker_api + "/beamtime/beamtime_id/" + expected_data_source_encoded + "/" - + expected_stream_encoded + "/delete" - + "?token=" + expected_token, _, - expected_delete_stream_query_string, _, _)).WillOnce(DoAll( - SetArgPointee<3>(HttpCode::OK), - SetArgPointee<4>(nullptr), - Return("") - )); + EXPECT_CALL(mock_http_client, Post_t(expected_broker_api + "/beamtime/beamtime_id/" + expected_data_source_encoded + "/" + + expected_stream_encoded + "/delete" + + "?token=" + expected_token + + "&instanceid=" + expected_instance_id_encoded + "&pipelinestep=" + expected_pipeline_step_encoded, _, + expected_delete_stream_query_string, _, _)).WillOnce(DoAll( + SetArgPointee<3>(HttpCode::OK), + SetArgPointee<4>(nullptr), + Return("") + )); asapo::DeleteStreamOptions opt; opt.delete_meta = true; @@ -1185,7 +1283,9 @@ TEST_F(ConsumerImplTests, GetStreamListUsesCorrectUriWithoutFrom) { MockGetBrokerUri(); EXPECT_CALL(mock_http_client, Get_t(expected_broker_api + "/beamtime/beamtime_id/" + expected_data_source_encoded + "/0/streams" - + "?token=" + expected_token + "&filter=finished", _, + + "?token=" + expected_token + + "&instanceid=" + expected_instance_id_encoded + "&pipelinestep=" + expected_pipeline_step_encoded + + "&filter=finished", _, _)).WillOnce(DoAll( SetArgPointee<1>(HttpCode::OK), SetArgPointee<2>(nullptr), @@ -1195,12 +1295,12 @@ TEST_F(ConsumerImplTests, GetStreamListUsesCorrectUriWithoutFrom) { auto streams = consumer->GetStreamList("", asapo::StreamFilter::kFinishedStreams, &err); } -void ConsumerImplTests::MockBeforeFTS(MessageData* data) { +void ConsumerImplTests::MockBeforeFTS(const std::string& expected_request_sender_details, MessageData* data) { auto to_send = CreateFI(); auto json = to_send.Json(); MockGet(json); - EXPECT_CALL(mock_netclient, GetData_t(&info, + EXPECT_CALL(mock_netclient, GetData_t(&info, expected_request_sender_details, data)).WillOnce(Return(asapo::IOErrorTemplates::kUnknownIOError.Generate().release())); } @@ -1258,7 +1358,7 @@ void ConsumerImplTests::ExpectRepeatedFileTransfer() { void ConsumerImplTests::AssertSingleFileTransfer() { asapo::MessageData data = asapo::MessageData{new uint8_t[1]}; MockGetBrokerUri(); - MockBeforeFTS(&data); + MockBeforeFTS(expected_request_sender_details_with_stream, &data); ExpectFolderToken(); MockGetFTSUri(); ExpectFileTransfer(nullptr); @@ -1306,7 +1406,7 @@ TEST_F(ConsumerImplTests, GetMessageReusesTokenAndUri) { AssertSingleFileTransfer(); asapo::MessageData data = asapo::MessageData{new uint8_t[1]}; - MockBeforeFTS(&data); + MockBeforeFTS(expected_request_sender_details_with_stream, &data); ExpectFileTransfer(nullptr); auto err = fts_consumer->GetNext(expected_group_id, &info, &data, expected_stream); @@ -1316,7 +1416,7 @@ TEST_F(ConsumerImplTests, GetMessageTriesToGetTokenAgainIfTransferFailed) { AssertSingleFileTransfer(); asapo::MessageData data; - MockBeforeFTS(&data); + MockBeforeFTS(expected_request_sender_details_with_stream, &data); ExpectRepeatedFileTransfer(); ExpectFolderToken(); @@ -1326,16 +1426,15 @@ TEST_F(ConsumerImplTests, GetMessageTriesToGetTokenAgainIfTransferFailed) { TEST_F(ConsumerImplTests, AcknowledgeUsesCorrectUri) { MockGetBrokerUri(); auto expected_acknowledge_command = "{\"Op\":\"ackmessage\"}"; - EXPECT_CALL(mock_http_client, - Post_t(expected_broker_api + "/beamtime/beamtime_id/" + expected_data_source_encoded + "/" - + - expected_stream_encoded + "/" + - expected_group_id_encoded - + "/" + std::to_string(expected_dataset_id) + "?token=" - + expected_token, _, expected_acknowledge_command, _, _)).WillOnce(DoAll( - SetArgPointee<3>(HttpCode::OK), - SetArgPointee<4>(nullptr), - Return(""))); + EXPECT_CALL(mock_http_client, Post_t(expected_broker_api + "/beamtime/beamtime_id/" + expected_data_source_encoded + "/" + + + expected_stream_encoded + "/" + + expected_group_id_encoded + + "/" + std::to_string(expected_dataset_id) + "?token=" + + expected_token_url_with_sourceinfo, _, expected_acknowledge_command, _, _)).WillOnce(DoAll( + SetArgPointee<3>(HttpCode::OK), + SetArgPointee<4>(nullptr), + Return(""))); auto err = consumer->Acknowledge(expected_group_id, expected_dataset_id, expected_stream); @@ -1366,14 +1465,14 @@ TEST_F(ConsumerImplTests, GetUnAcknowledgedListReturnsIds) { } void ConsumerImplTests::ExpectLastAckId(bool empty_response) { - EXPECT_CALL(mock_http_client, - Get_t(expected_broker_api + "/beamtime/beamtime_id/" + expected_data_source_encoded + "/" - + - expected_stream_encoded + "/" + - expected_group_id_encoded + "/lastack?token=" + expected_token, _, _)).WillOnce(DoAll( - SetArgPointee<1>(HttpCode::OK), - SetArgPointee<2>(nullptr), - Return(empty_response ? "{\"lastAckId\":0}" : "{\"lastAckId\":1}"))); + EXPECT_CALL(mock_http_client, Get_t(expected_broker_api + "/beamtime/beamtime_id/" + expected_data_source_encoded + "/" + + + expected_stream_encoded + "/" + + expected_group_id_encoded + "/lastack?token=" + expected_token + + "&instanceid=" + expected_instance_id_encoded + "&pipelinestep=" + expected_pipeline_step_encoded, _, _)).WillOnce(DoAll( + SetArgPointee<1>(HttpCode::OK), + SetArgPointee<2>(nullptr), + Return(empty_response ? "{\"lastAckId\":0}" : "{\"lastAckId\":1}"))); } TEST_F(ConsumerImplTests, GetLastAcknowledgeUsesOk) { @@ -1409,7 +1508,9 @@ TEST_F(ConsumerImplTests, ResendNacks) { EXPECT_CALL(mock_http_client, Get_t(expected_broker_api + "/beamtime/beamtime_id/" + expected_data_source_encoded + "/stream/" + expected_group_id_encoded + "/next?token=" - + expected_token + "&resend_nacks=true&delay_ms=10000&resend_attempts=3", _, + + expected_token + + "&instanceid=" + expected_instance_id_encoded + "&pipelinestep=" + expected_pipeline_step_encoded + + "&resend_nacks=true&delay_ms=10000&resend_attempts=3", _, _)).WillOnce(DoAll( SetArgPointee<1>(HttpCode::OK), SetArgPointee<2>(nullptr), @@ -1422,17 +1523,18 @@ TEST_F(ConsumerImplTests, ResendNacks) { TEST_F(ConsumerImplTests, NegativeAcknowledgeUsesCorrectUri) { MockGetBrokerUri(); auto expected_neg_acknowledge_command = R"({"Op":"negackmessage","Params":{"DelayMs":10000}})"; - EXPECT_CALL(mock_http_client, - Post_t(expected_broker_api + "/beamtime/beamtime_id/" + expected_data_source_encoded + "/" - + - expected_stream_encoded + "/" + - expected_group_id_encoded - + "/" + std::to_string(expected_dataset_id) + "?token=" - + expected_token, _, expected_neg_acknowledge_command, _, _)).WillOnce( - DoAll( - SetArgPointee<3>(HttpCode::OK), - SetArgPointee<4>(nullptr), - Return(""))); + EXPECT_CALL(mock_http_client, Post_t(expected_broker_api + "/beamtime/beamtime_id/" + expected_data_source_encoded + "/" + + + expected_stream_encoded + "/" + + expected_group_id_encoded + + "/" + std::to_string(expected_dataset_id) + "?token=" + + expected_token + + "&instanceid=" + expected_instance_id_encoded + "&pipelinestep=" + expected_pipeline_step_encoded + , _, expected_neg_acknowledge_command, _, _)).WillOnce( + DoAll( + SetArgPointee<3>(HttpCode::OK), + SetArgPointee<4>(nullptr), + Return(""))); auto err = consumer->NegativeAcknowledge(expected_group_id, expected_dataset_id, 10000, expected_stream); diff --git a/consumer/api/cpp/unittests/test_fabric_consumer_client.cpp b/consumer/api/cpp/unittests/test_fabric_consumer_client.cpp index bca6e896aea1b87e6103f49130066e3a00a5e6bd..7e6308feaf837364133de13ee9546be8a6d1b4c3 100644 --- a/consumer/api/cpp/unittests/test_fabric_consumer_client.cpp +++ b/consumer/api/cpp/unittests/test_fabric_consumer_client.cpp @@ -25,7 +25,7 @@ TEST(FabricConsumerClient, Constructor) { ASSERT_THAT(dynamic_cast<fabric::FabricClient*>(client.client__.get()), Eq(nullptr)); } -MATCHER_P6(M_CheckSendRequest, op_code, buf_id, data_size, mr_addr, mr_length, mr_key, +MATCHER_P7(M_CheckSendRequest, op_code, buf_id, data_size, mr_addr, mr_length, mr_key, expected_request_sender_details, "Checks if a valid GenericRequestHeader was Send") { auto data = (GenericRequestHeader*) arg; auto mr = (fabric::MemoryRegionDetails*) &data->message; @@ -34,6 +34,7 @@ MATCHER_P6(M_CheckSendRequest, op_code, buf_id, data_size, mr_addr, mr_length, m && data->data_size == uint64_t(data_size) && mr->addr == uint64_t(mr_addr) && strcmp(data->api_version, "v0.1") == 0 + && strcmp(data->stream, expected_request_sender_details.c_str()) == 0 && mr->length == uint64_t(mr_length) && mr->key == uint64_t(mr_key); } @@ -62,6 +63,7 @@ class FabricConsumerClientTests : public Test { void ExpectAddedConnection(const std::string& address, bool ok, fabric::FabricAddress result); void ExpectTransfer(void** outputData, fabric::FabricAddress serverAddr, fabric::FabricMessageId messageId, bool sendOk, bool recvOk, + const std::string& expected_request_sender_details, NetworkErrorCode serverResponse); }; @@ -84,6 +86,7 @@ void FabricConsumerClientTests::ExpectAddedConnection(const std::string& address void FabricConsumerClientTests::ExpectTransfer(void** outputData, fabric::FabricAddress serverAddr, fabric::FabricMessageId messageId, bool sendOk, bool recvOk, + const std::string& expected_request_sender_details, NetworkErrorCode serverResponse) { static fabric::MemoryRegionDetails mrDetails{}; mrDetails.addr = 0x124; @@ -99,7 +102,7 @@ void FabricConsumerClientTests::ExpectTransfer(void** outputData, fabric::Fabric Expectation sendCall = EXPECT_CALL(mock_fabric_client, Send_t(serverAddr, messageId, - M_CheckSendRequest(kOpcodeGetBufferData, 78954, 4123, 0x124, 4123, 20), + M_CheckSendRequest(kOpcodeGetBufferData, 78954, 4123, 0x124, 4123, 20, expected_request_sender_details), sizeof(GenericRequestHeader), _)).After(getDetailsCall) .WillOnce(SetArgPointee<4>(sendOk ? nullptr : fabric::FabricErrorTemplates::kInternalError.Generate().release())); @@ -124,7 +127,7 @@ TEST_F(FabricConsumerClientTests, GetData_Error_Init) { MessageData expectedMessageData; MessageMeta expectedInfo{}; expectedInfo.source = "host:1234"; - Error err = client.GetData(&expectedInfo, &expectedMessageData); + Error err = client.GetData(&expectedInfo, "some_request_sender_details", &expectedMessageData); ASSERT_THAT(err, Eq(fabric::FabricErrorTemplates::kInternalError)); } @@ -136,12 +139,12 @@ TEST_F(FabricConsumerClientTests, GetData_Error_AddConnection) { MessageData expectedMessageData; MessageMeta expectedInfo{}; expectedInfo.source = "host:1234"; - Error err = client.GetData(&expectedInfo, &expectedMessageData); + Error err = client.GetData(&expectedInfo, "some_request_sender_details", &expectedMessageData); ASSERT_THAT(err, Eq(fabric::FabricErrorTemplates::kInternalError)); // Make sure that the connection was not saved ExpectAddedConnection("host:1234", false, 1); - err = client.GetData(&expectedInfo, &expectedMessageData); + err = client.GetData(&expectedInfo, "some_request_sender_details", &expectedMessageData); ASSERT_THAT(err, Eq(fabric::FabricErrorTemplates::kInternalError)); } @@ -161,7 +164,7 @@ TEST_F(FabricConsumerClientTests, GetData_ShareMemoryRegion_Error) { Return(nullptr) )); - Error err = client.GetData(&expectedInfo, &expectedMessageData); + Error err = client.GetData(&expectedInfo, "some_request_sender_details", &expectedMessageData); ASSERT_THAT(err, Eq(fabric::FabricErrorTemplates::kInternalError)); } @@ -177,9 +180,9 @@ TEST_F(FabricConsumerClientTests, GetData_SendFailed) { expectedInfo.buf_id = 78954; void* outData = nullptr; - ExpectTransfer(&outData, 0, 0, false, false, kNetErrorNoError); + ExpectTransfer(&outData, 0, 0, false, false, "abc", kNetErrorNoError); - Error err = client.GetData(&expectedInfo, &expectedMessageData); + Error err = client.GetData(&expectedInfo, "abc", &expectedMessageData); ASSERT_THAT(err, Ne(nullptr)); ASSERT_THAT(expectedMessageData.get(), Eq(nullptr)); @@ -196,9 +199,9 @@ TEST_F(FabricConsumerClientTests, GetData_RecvFailed) { expectedInfo.buf_id = 78954; void* outData = nullptr; - ExpectTransfer(&outData, 0, 0, true, false, kNetErrorNoError); + ExpectTransfer(&outData, 0, 0, true, false, "abc", kNetErrorNoError); - Error err = client.GetData(&expectedInfo, &expectedMessageData); + Error err = client.GetData(&expectedInfo, "abc", &expectedMessageData); ASSERT_THAT(err, Ne(nullptr)); ASSERT_THAT(expectedMessageData.get(), Eq(nullptr)); @@ -215,9 +218,9 @@ TEST_F(FabricConsumerClientTests, GetData_ServerError) { expectedInfo.buf_id = 78954; void* outData = nullptr; - ExpectTransfer(&outData, 0, 0, true, true, kNetErrorInternalServerError); + ExpectTransfer(&outData, 0, 0, true, true, "abc", kNetErrorInternalServerError); - Error err = client.GetData(&expectedInfo, &expectedMessageData); + Error err = client.GetData(&expectedInfo, "abc", &expectedMessageData); ASSERT_THAT(err, Ne(nullptr)); ASSERT_THAT(expectedMessageData.get(), Eq(nullptr)); @@ -234,9 +237,9 @@ TEST_F(FabricConsumerClientTests, GetData_Ok) { expectedInfo.buf_id = 78954; void* outData = nullptr; - ExpectTransfer(&outData, 0, 0, true, true, kNetErrorNoError); + ExpectTransfer(&outData, 0, 0, true, true, "abc", kNetErrorNoError); - Error err = client.GetData(&expectedInfo, &expectedMessageData); + Error err = client.GetData(&expectedInfo, "abc", &expectedMessageData); ASSERT_THAT(err, Eq(nullptr)); ASSERT_THAT(expectedMessageData.get(), Eq(outData)); @@ -253,17 +256,17 @@ TEST_F(FabricConsumerClientTests, GetData_Ok_UsedCahedConnection) { expectedInfo.buf_id = 78954; void* outData = nullptr; - ExpectTransfer(&outData, 0, 0, true, true, kNetErrorNoError); + ExpectTransfer(&outData, 0, 0, true, true, "abc", kNetErrorNoError); - Error err = client.GetData(&expectedInfo, &expectedMessageData); + Error err = client.GetData(&expectedInfo, "abc", &expectedMessageData); ASSERT_THAT(err, Eq(nullptr)); ASSERT_THAT(expectedMessageData.get(), Eq(outData)); outData = nullptr; - ExpectTransfer(&outData, 0, 1, true, true, kNetErrorNoError); + ExpectTransfer(&outData, 0, 1, true, true, "abc", kNetErrorNoError); - err = client.GetData(&expectedInfo, &expectedMessageData); + err = client.GetData(&expectedInfo, "abc", &expectedMessageData); ASSERT_THAT(err, Eq(nullptr)); ASSERT_THAT(expectedMessageData.get(), Eq(outData)); @@ -280,9 +283,9 @@ TEST_F(FabricConsumerClientTests, GetData_Ok_SecondConnection) { expectedInfo.buf_id = 78954; void* outData = nullptr; - ExpectTransfer(&outData, 0, 0, true, true, kNetErrorNoError); + ExpectTransfer(&outData, 0, 0, true, true, "abc", kNetErrorNoError); - Error err = client.GetData(&expectedInfo, &expectedMessageData); + Error err = client.GetData(&expectedInfo, "abc", &expectedMessageData); ASSERT_THAT(err, Eq(nullptr)); ASSERT_THAT(expectedMessageData.get(), Eq(outData)); @@ -291,9 +294,9 @@ TEST_F(FabricConsumerClientTests, GetData_Ok_SecondConnection) { expectedInfo.source = "host:1235"; outData = nullptr; - ExpectTransfer(&outData, 54, 1, true, true, kNetErrorNoError); + ExpectTransfer(&outData, 54, 1, true, true, "abc", kNetErrorNoError); - err = client.GetData(&expectedInfo, &expectedMessageData); + err = client.GetData(&expectedInfo, "abc", &expectedMessageData); ASSERT_THAT(err, Eq(nullptr)); ASSERT_THAT(expectedMessageData.get(), Eq(outData)); diff --git a/consumer/api/cpp/unittests/test_tcp_consumer_client.cpp b/consumer/api/cpp/unittests/test_tcp_consumer_client.cpp index 7ae50313b23a99956de616bd90c709d3868a1b6a..9c0b28f1049f2216d8ec404a7850cc0e2c359772 100644 --- a/consumer/api/cpp/unittests/test_tcp_consumer_client.cpp +++ b/consumer/api/cpp/unittests/test_tcp_consumer_client.cpp @@ -145,7 +145,7 @@ class TcpClientTests : public Test { TEST_F(TcpClientTests, ErrorGetNewConnection) { ExpectNewConnection(false, false); - auto err = client->GetData(&info, &data); + auto err = client->GetData(&info, "abc", &data); ASSERT_THAT(err, Eq(asapo::IOErrorTemplates::kUnknownIOError)); } @@ -154,7 +154,7 @@ TEST_F(TcpClientTests, SendHeaderForNewConnectionReturnsError) { ExpectNewConnection(false, true); ExpectSendRequest(expected_sd, false); - auto err = client->GetData(&info, &data); + auto err = client->GetData(&info, "abc", &data); ASSERT_THAT(err, Eq(asapo::IOErrorTemplates::kBadFileNumber)); } @@ -164,7 +164,7 @@ TEST_F(TcpClientTests, OnErrorSendHeaderTriesToReconnectAndFails) { ExpectSendRequest(expected_sd, false); ExpectReconnect(false); - auto err = client->GetData(&info, &data); + auto err = client->GetData(&info, "abc", &data); ASSERT_THAT(err, Eq(asapo::IOErrorTemplates::kUnknownIOError)); } @@ -175,7 +175,7 @@ TEST_F(TcpClientTests, OnErrorSendHeaderTriesToReconnectAndSendsAnotherRequest) ExpectReconnect(true); ExpectSendRequest(expected_sd + 1, false); - auto err = client->GetData(&info, &data); + auto err = client->GetData(&info, "abc", &data); ASSERT_THAT(err, Eq(asapo::IOErrorTemplates::kBadFileNumber)); } @@ -185,7 +185,7 @@ TEST_F(TcpClientTests, GetResponceReturnsError) { ExpectSendRequest(expected_sd, true); ExpectGetResponce(expected_sd, false, asapo::kNetErrorNoError); - auto err = client->GetData(&info, &data); + auto err = client->GetData(&info, "abc", &data); ASSERT_THAT(err, Eq(asapo::IOErrorTemplates::kConnectionRefused)); } @@ -196,7 +196,7 @@ TEST_F(TcpClientTests, GetResponceReturnsNoData) { ExpectGetResponce(expected_sd, true, asapo::kNetErrorNoData); EXPECT_CALL(mock_connection_pool, ReleaseConnection(expected_sd)); - auto err = client->GetData(&info, &data); + auto err = client->GetData(&info, "abc", &data); ASSERT_THAT(err, Ne(nullptr)); } @@ -207,7 +207,7 @@ TEST_F(TcpClientTests, GetResponceReturnsWrongRequest) { ExpectGetResponce(expected_sd, true, asapo::kNetErrorWrongRequest); EXPECT_CALL(mock_io, CloseSocket_t(expected_sd, _)); - auto err = client->GetData(&info, &data); + auto err = client->GetData(&info, "abc", &data); ASSERT_THAT(err, Ne(nullptr)); } @@ -219,7 +219,7 @@ TEST_F(TcpClientTests, GetResponceReturnsUnsupported) { EXPECT_CALL(mock_io, CloseSocket_t(expected_sd, _)); EXPECT_CALL(mock_connection_pool, ReleaseConnection(expected_sd)); - auto err = client->GetData(&info, &data); + auto err = client->GetData(&info, "abc", &data); ASSERT_THAT(err, Ne(nullptr)); } @@ -231,7 +231,7 @@ TEST_F(TcpClientTests, ErrorGettingData) { ExpectGetResponce(expected_sd, true, asapo::kNetErrorNoError); ExpectGetData(expected_sd, false); - auto err = client->GetData(&info, &data); + auto err = client->GetData(&info, "abc", &data); ASSERT_THAT(err, Eq(asapo::IOErrorTemplates::kTimeout)); } @@ -242,7 +242,7 @@ TEST_F(TcpClientTests, OkGettingData) { ExpectGetResponce(expected_sd, true, asapo::kNetErrorNoError); ExpectGetData(expected_sd, true); - auto err = client->GetData(&info, &data); + auto err = client->GetData(&info, "abc", &data); ASSERT_THAT(err, Eq(nullptr)); } @@ -255,7 +255,7 @@ TEST_F(TcpClientTests, OkGettingDataWithReconnect) { ExpectGetResponce(expected_sd + 1, true, asapo::kNetErrorNoError); ExpectGetData(expected_sd + 1, true); - auto err = client->GetData(&info, &data); + auto err = client->GetData(&info, "abc", &data); ASSERT_THAT(err, Eq(nullptr)); } diff --git a/consumer/api/python/asapo_consumer.pxd b/consumer/api/python/asapo_consumer.pxd index f9b808d0ea360edcfa2fa40bd857f0c048d81edf..1306b95b8896e6026a7c0e1a114e1ea00d8e2083 100644 --- a/consumer/api/python/asapo_consumer.pxd +++ b/consumer/api/python/asapo_consumer.pxd @@ -42,6 +42,8 @@ cdef extern from "asapo/asapo_consumer.h" namespace "asapo": uint64_t expected_size MessageMetas content struct SourceCredentials: + string instance_id + string pipeline_step string beamtime_id string data_source string user_token @@ -68,6 +70,7 @@ cdef extern from "asapo/asapo_consumer.h" namespace "asapo" nogil: Consumer() except + void SetTimeout(uint64_t timeout_ms) void ForceNoRdma() + Error DisableMonitoring(bool enabled) NetworkConnectionType CurrentConnectionType() Error GetNext(string group_id, MessageMeta* info, MessageData* data,string stream) Error GetLast(MessageMeta* info, MessageData* data, string stream) diff --git a/consumer/api/python/asapo_consumer.pyx.in b/consumer/api/python/asapo_consumer.pyx.in index 685d4ddd147f6f056be493c0b69e9234eb1ade24..268554ba6a9c4ce92eb9780c72d87d3d71d9ee07 100644 --- a/consumer/api/python/asapo_consumer.pyx.in +++ b/consumer/api/python/asapo_consumer.pyx.in @@ -199,6 +199,13 @@ cdef class PyConsumer: self.c_consumer.get().SetTimeout(timeout) def force_no_rdma(self): self.c_consumer.get().ForceNoRdma() + def disable_monitoring(self, bool disabled): + cdef Error err + with nogil: + err = self.c_consumer.get().DisableMonitoring(disabled) + if err: + throw_exception(err) + return def current_connection_type(self): cdef NetworkConnectionType connection_type = self.c_consumer.get().CurrentConnectionType() cdef int cased = <int>connection_type @@ -401,11 +408,13 @@ cdef class __PyConsumerFactory: def __cinit__(self): with nogil: self.c_factory = ConsumerFactory() - def create_consumer(self,server_name,source_path,has_filesystem,beamtime_id,data_source,token,timeout): + def create_consumer(self,server_name,source_path,has_filesystem,instance_id,pipeline_step,beamtime_id,data_source,token,timeout): cdef string b_server_name = _bytes(server_name) cdef string b_source_path = _bytes(source_path) cdef bool b_has_filesystem = has_filesystem cdef SourceCredentials source + source.instance_id = _bytes(instance_id) + source.pipeline_step = _bytes(pipeline_step) source.beamtime_id = _bytes(beamtime_id) source.user_token = _bytes(token) source.data_source = _bytes(data_source) @@ -418,7 +427,7 @@ cdef class __PyConsumerFactory: consumer.c_consumer.get().SetTimeout(timeout) return consumer -def create_consumer(server_name,source_path,has_filesystem,beamtime_id,data_source,token,timeout_ms): +def create_consumer(server_name,source_path,has_filesystem,beamtime_id,data_source,token,timeout_ms,instance_id='auto',pipeline_step='auto'): """ :param server_name: Server endpoint (hostname:port) :type server_name: string @@ -426,11 +435,25 @@ def create_consumer(server_name,source_path,has_filesystem,beamtime_id,data_sour :type source_path: string :param has_filesystem: True if the source_path is accessible locally, otherwise will use file transfer service to get data :type has_filesystem: bool + :param beamline: beamline name, can be "auto" if beamtime_id is given + :type beamline: string + :param data_source: name of the data source that produces data + :type data_source: string + :param token: authorization token + :type token: string + :param nthreads: ingest mode flag + :type nthreads: int + :param timeout_ms: send requests timeout in milliseconds + :type timeout_ms: int + :param instance_id: instance id, can be "auto" (default), will create a combination out of hostname and pid + :type instance_id: string + :param pipeline_step: pipeline step id, can be "auto" (default), "DefaultStep" is used then + :type pipeline_step: string :return: consumer object and error. (None,err) if case of error, (consumer, None) if success :rtype: Tuple with consumer object and error. """ factory = __PyConsumerFactory() - return factory.create_consumer(server_name,source_path,has_filesystem, beamtime_id,data_source,token,timeout_ms) + return factory.create_consumer(server_name,source_path,has_filesystem,instance_id,pipeline_step,beamtime_id,data_source,token,timeout_ms) __version__ = "@PYTHON_ASAPO_VERSION@@ASAPO_VERSION_COMMIT@" diff --git a/deploy/CMakeLists.txt b/deploy/CMakeLists.txt index 071ae9b200fb8f6e440330f157bd8d6afa5c1502..739f856166a7cac9a459b8d483ab19cf0080a0f0 100644 --- a/deploy/CMakeLists.txt +++ b/deploy/CMakeLists.txt @@ -4,6 +4,7 @@ else() SET (NOMAD_INSTALL ${CMAKE_INSTALL_PREFIX}/nomad_jobs) endif() +set (ASAPO_DOCKER_REPOSITORY yakser) configure_files(${CMAKE_CURRENT_SOURCE_DIR}/asapo_services ${CMAKE_CURRENT_BINARY_DIR}/asapo_services) configure_files(${CMAKE_CURRENT_SOURCE_DIR}/asapo_services/scripts ${CMAKE_CURRENT_BINARY_DIR}/asapo_services/scripts) diff --git a/deploy/README.md b/deploy/README.md new file mode 100644 index 0000000000000000000000000000000000000000..5213cc70784b44f0e225e1b42bf67eead891fdcc --- /dev/null +++ b/deploy/README.md @@ -0,0 +1,8 @@ +# Correct build order + +## For Cluster + +Run `./build_image.sh` inside: + +1. `nomad_consul_docker` for `$REPO/asapo-nomad-cluster` +2. `asapo_services` for `$REPO/asapo-cluster` diff --git a/deploy/_docker_vars.sh b/deploy/_docker_vars.sh new file mode 100755 index 0000000000000000000000000000000000000000..a501eb827bdf4df10de04b19c204208f1d619c0a --- /dev/null +++ b/deploy/_docker_vars.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +if [[ -z "$ASAPO_DOCKER_REPOSITORY" ]]; then + ASAPO_DOCKER_REPOSITORY=yakser +fi + +if [[ -z "$ASAPO_DOCKER_DO_PUSH" ]]; then + ASAPO_DOCKER_DO_PUSH=YES +fi diff --git a/deploy/asapo_helm_chart/asapo/configs/asapo-broker.json b/deploy/asapo_helm_chart/asapo/configs/asapo-broker.json index 196b79c99019f1fdb86eafdd6573ac7a6ae894bf..e688d98e0828807ad670c3ec17643d258546243d 100644 --- a/deploy/asapo_helm_chart/asapo/configs/asapo-broker.json +++ b/deploy/asapo_helm_chart/asapo/configs/asapo-broker.json @@ -3,6 +3,7 @@ "DiscoveryServer": "asapo-discovery:{{ .Values.ownServices.discovery.port }}", "AuthorizationServer": "asapo-authorizer:{{ .Values.ownServices.authorization.port }}", "PerformanceDbServer":"{{ .Chart.Name }}-influxdb:{{ .Values.influxdb.influxdb.service.port }}", + "MonitoringServerUrl":"auto", "MonitorPerformance": true, "PerformanceDbName": "asapo_brokers", "Port": {{ .Values.ownServices.broker.port }}, diff --git a/deploy/asapo_orchestration_docker/build_image.sh b/deploy/asapo_orchestration_docker/build_image.sh index f375d647bd9799f5a229c9d45ebeefef4cca1398..abf4b08ea26fab898ab014a9e72dbeeb377b562d 100755 --- a/deploy/asapo_orchestration_docker/build_image.sh +++ b/deploy/asapo_orchestration_docker/build_image.sh @@ -1,4 +1,9 @@ #!/usr/bin/env bash -docker build -t yakser/asapo-orc . -docker push yakser/asapo-orc +. ../_docker_vars.sh + +sed "s/\$ASAPO_DOCKER_REPOSITORY/$ASAPO_DOCKER_REPOSITORY/" Dockerfile.template | docker build -t $ASAPO_DOCKER_REPOSITORY/asapo-orc . -f - + +if [ $ASAPO_DOCKER_DO_PUSH = "YES" ]; then + docker push $ASAPO_DOCKER_REPOSITORY/asapo-orc +fi diff --git a/deploy/asapo_orchestration_docker/scripts/asapo.auto.tfvars b/deploy/asapo_orchestration_docker/scripts/asapo.auto.tfvars index 6c4e698619f8966693a002d3fca2e3250ec7ff67..d6ca9a896032dace95ba8c11c5d8b4ae4e43ce68 100644 --- a/deploy/asapo_orchestration_docker/scripts/asapo.auto.tfvars +++ b/deploy/asapo_orchestration_docker/scripts/asapo.auto.tfvars @@ -9,7 +9,7 @@ nginx_port_stream = 8402 nginx_version = "1.14" influxdb_total_memory_size = "1024" -influxdb_version = "latest" +influxdb_version = "1.8.4" telegraf_total_memory_size = "256" telegraf_version = "latest" diff --git a/deploy/asapo_services/Dockerfile b/deploy/asapo_services/Dockerfile.in similarity index 72% rename from deploy/asapo_services/Dockerfile rename to deploy/asapo_services/Dockerfile.in index 1ea67d704f343044c29e1c18d1dbf08ff9ac4792..cc8861862fd3dc5fd6b78c734c36b21be9d8ddf9 100644 --- a/deploy/asapo_services/Dockerfile +++ b/deploy/asapo_services/Dockerfile.in @@ -1,4 +1,4 @@ -FROM yakser/asapo-nomad-cluster +FROM @ASAPO_DOCKER_REPOSITORY@/asapo-nomad-cluster MAINTAINER DESY IT diff --git a/deploy/asapo_services/asap3.tfvars b/deploy/asapo_services/asap3.tfvars index 991b42e2f3eedffdf04d0221183ea1512c79880d..0ec00f294e7a8a97c470a34693ca06f9ba53b686 100644 --- a/deploy/asapo_services/asap3.tfvars +++ b/deploy/asapo_services/asap3.tfvars @@ -1,12 +1,12 @@ elk_logs = true perf_monitor = true +asapo_docker_repository = "yakser" asapo_imagename_suffix = "" asapo_image_tag = "" influxdb_version="1.8.4" - service_dir="/gpfs/asapo/shared/service_dir" online_dir="/beamline" offline_dir="/asap3" @@ -21,7 +21,8 @@ receiver_dataserver_cache_size = 30 #gb receiver_receive_to_disk_threshold = 50 # mb receiver_dataserver_nthreads = 8 receiver_network_modes = "tcp" -receiver_kafka_enabled = true +receiver_kafka_enabled = false +receiver_kafka_metadata_broker_list = "" grafana_total_memory_size = 2000 influxdb_total_memory_size = 2000 @@ -35,5 +36,3 @@ discovery_total_memory_size = 512 n_receivers = 2 n_brokers = 2 n_fts = 2 - - diff --git a/deploy/asapo_services/build_image.sh b/deploy/asapo_services/build_image.sh index 69b3e638d370540da56478932995c0ca570397a3..25c8383583d6b65f63bf04aed7917fae46ad036b 100755 --- a/deploy/asapo_services/build_image.sh +++ b/deploy/asapo_services/build_image.sh @@ -1,4 +1,11 @@ #!/usr/bin/env bash -docker build -t yakser/asapo-cluster . -docker push yakser/asapo-cluster +set -e + +. ../_docker_vars.sh + +sed "s/\$ASAPO_DOCKER_REPOSITORY/$ASAPO_DOCKER_REPOSITORY/" Dockerfile.template | docker build -t $ASAPO_DOCKER_REPOSITORY/asapo-cluster . -f - + +if [ $ASAPO_DOCKER_DO_PUSH = "YES" ]; then + docker push $ASAPO_DOCKER_REPOSITORY/asapo-cluster +fi diff --git a/deploy/asapo_services/local.tfvars b/deploy/asapo_services/local.tfvars new file mode 100644 index 0000000000000000000000000000000000000000..7a2966aaba269a3d45d99034f3b2e558628c1de0 --- /dev/null +++ b/deploy/asapo_services/local.tfvars @@ -0,0 +1,28 @@ +elk_logs = false +perf_monitor = true + +force_pull_images = true + +asapo_docker_repository = "yakser" +#asapo_imagename_suffix = "" +#asapo_image_tag = "" + +influxdb_version="1.8.4" + +service_dir="/var/tmp/asapo" +online_dir="/var/tmp/asapo/bl" +offline_dir="/var/tmp/asapo/core" +mongo_dir="/var/tmp/asapo/mongo" +asapo_user="26655:1000" +job_scripts_dir="/home/yakubov/projects/asapo/build/deploy/asapo_services/scripts" + + +ldap_uri="ldap://it-ldap-slave.desy.de:1389" + +receiver_network_modes = "tcp" +receiver_kafka_enabled = false +receiver_kafka_metadata_broker_list="" + +n_receivers = 1 +n_brokers = 1 +n_fts = 1 diff --git a/deploy/asapo_services/run.sh b/deploy/asapo_services/run.sh index a017a07937e0d90f158026807298cc84f582bfc3..8aae818a5ecd67201f3bbe2c37cb44cfd2de17ae 100755 --- a/deploy/asapo_services/run.sh +++ b/deploy/asapo_services/run.sh @@ -1,5 +1,9 @@ #!/usr/bin/env bash +set -e + +. ../_docker_vars.sh + NOMAD_ALLOC_HOST_SHARED=/var/tmp/asapo/container_host_shared/nomad_alloc SERVICE_DATA_CLUSTER_SHARED=/var/tmp/asapo/asapo_cluster_shared/service_data DATA_GLOBAL_SHARED=/var/tmp/asapo/global_shared/data @@ -18,17 +22,19 @@ ASAPO_USER=`id -u`:`id -g` ASAPO_VAR_FILE=`pwd`/asapo_overwrite_vars.tfvars ACL_ENABLED=true +echo creating $NOMAD_ALLOC_HOST_SHARED $SERVICE_DATA_CLUSTER_SHARED $DATA_GLOBAL_SHARED mkdir -p $NOMAD_ALLOC_HOST_SHARED $SERVICE_DATA_CLUSTER_SHARED $DATA_GLOBAL_SHARED chmod 777 $NOMAD_ALLOC_HOST_SHARED $SERVICE_DATA_CLUSTER_SHARED $DATA_GLOBAL_SHARED cd $SERVICE_DATA_CLUSTER_SHARED -mkdir esdatadir fluentd grafana influxdb mongodb prometheus alertmanager +mkdir -p esdatadir fluentd grafana influxdb mongodb prometheus alertmanager chmod 777 * mmc=`cat /proc/sys/vm/max_map_count` if (( mmc < 262144 )); then echo increase max_map_count - needed for elasticsearch +echo "Just run 'sudo sysctl -w vm.max_map_count=262144' to temporarily set it (until next restart)" exit 1 fi @@ -58,5 +64,4 @@ docker run --privileged --rm -v /var/run/docker.sock:/var/run/docker.sock \ -e ACL_ENABLED=$ACL_ENABLED \ -e SERVER_ADRESSES=$SERVER_ADRESSES \ -e N_SERVERS=$N_SERVERS \ ---name asapo --net=host -d yakser/asapo-cluster - +--name asapo --net host -d $ASAPO_DOCKER_REPOSITORY/asapo-cluster diff --git a/deploy/asapo_services/run_maxwell.sh b/deploy/asapo_services/run_maxwell.sh index 13bd97f0a38617cd4092b1c84528df2d44f8459f..6d4eefd20622ea20a8b24ca89ea795202061b935 100755 --- a/deploy/asapo_services/run_maxwell.sh +++ b/deploy/asapo_services/run_maxwell.sh @@ -1,6 +1,10 @@ #!/usr/bin/env bash -IMAGE=yakser/asapo-cluster:20.06.3 +set -e + +. ../_docker_vars.sh + +IMAGE=$ASAPO_DOCKER_REPOSITORY/asapo-cluster:20.06.3 #folders NOMAD_ALLOC_HOST_SHARED=/var/tmp/asapo/container_host_shared/nomad_alloc diff --git a/deploy/asapo_services/scripts/asapo-brokers.nmd.tpl b/deploy/asapo_services/scripts/asapo-brokers.nmd.tpl index 14f5eaf5baf9587059c4b644d3dbfea8a29eb137..375620fec4e96da4fa44fdcc1439570e48289ed2 100644 --- a/deploy/asapo_services/scripts/asapo-brokers.nmd.tpl +++ b/deploy/asapo_services/scripts/asapo-brokers.nmd.tpl @@ -29,7 +29,7 @@ job "asapo-brokers" { network_mode = "host" security_opt = ["no-new-privileges"] userns_mode = "host" - image = "yakser/asapo-broker${image_suffix}" + image = "${docker_repository}/asapo-broker${image_suffix}" force_pull = ${force_pull_images} volumes = ["local/config.json:/var/lib/broker/config.json"] %{ if ! nomad_logs } diff --git a/deploy/asapo_services/scripts/asapo-fts.nmd.tpl b/deploy/asapo_services/scripts/asapo-fts.nmd.tpl index 5f4d98278ccb419e54ce9465895e47ea22c92bbb..29bb0def18a719c798655208ccd9d7d9b0ac8e41 100644 --- a/deploy/asapo_services/scripts/asapo-fts.nmd.tpl +++ b/deploy/asapo_services/scripts/asapo-fts.nmd.tpl @@ -29,7 +29,7 @@ job "asapo-file-transfer" { network_mode = "host" security_opt = ["no-new-privileges"] userns_mode = "host" - image = "yakser/asapo-file-transfer${image_suffix}" + image = "${docker_repository}/asapo-file-transfer${image_suffix}" force_pull = ${force_pull_images} volumes = ["local/config.json:/var/lib/file_transfer/config.json", "${offline_dir}:${offline_dir}", diff --git a/deploy/asapo_services/scripts/asapo-nginx.nmd.tpl b/deploy/asapo_services/scripts/asapo-nginx.nmd.tpl index d22febe4565a30c2946da29bef3c67e69a5a8d5b..404548f7bb5ecdfea536d0032f40e52fd7fd4269 100644 --- a/deploy/asapo_services/scripts/asapo-nginx.nmd.tpl +++ b/deploy/asapo_services/scripts/asapo-nginx.nmd.tpl @@ -37,6 +37,8 @@ job "asapo-nginx" { consul_dns_port = "${consul_dns_port}" prometheus_port = "${prometheus_port}" alertmanager_port = "${alertmanager_port}" + monitoring_ui_port = "${monitoring_ui_port}" + monitoring_proxy_port = "${monitoring_proxy_port}" } config { diff --git a/deploy/asapo_services/scripts/asapo-perfmetrics.nmd.tpl b/deploy/asapo_services/scripts/asapo-perfmetrics.nmd.tpl index cd717baff86ea82bd6bf5b54719d827caa3aacfa..44364c591f821d9ef0cec6c1f8d73abe986a71ed 100644 --- a/deploy/asapo_services/scripts/asapo-perfmetrics.nmd.tpl +++ b/deploy/asapo_services/scripts/asapo-perfmetrics.nmd.tpl @@ -6,13 +6,6 @@ job "asapo-perfmetrics" { weight = 100 } -# update { -# max_parallel = 1 -# min_healthy_time = "10s" -# healthy_deadline = "3m" -# auto_revert = false -# } - group "perfmetrics" { count = "%{ if perf_monitor }1%{ else }0%{ endif }" restart { @@ -21,6 +14,9 @@ job "asapo-perfmetrics" { delay = "15s" mode = "delay" } + network { + port "monitoring_server" {} + } task "influxdb" { driver = "docker" @@ -30,13 +26,14 @@ job "asapo-perfmetrics" { security_opt = ["no-new-privileges"] userns_mode = "host" image = "influxdb:${influxdb_version}" - volumes = ["/${service_dir}/influxdb2:/var/lib/influxdb2"] + volumes = ["/${service_dir}/influxdb:/var/lib/influxdb"] } env { PRE_CREATE_DB="asapo_receivers;asapo_brokers" INFLUXDB_BIND_ADDRESS="127.0.0.1:$${NOMAD_PORT_influxdb_rpc}" INFLUXDB_HTTP_BIND_ADDRESS=":$${NOMAD_PORT_influxdb}" + INFLUXDB_HTTP_FLUX_ENABLED="true" } resources { @@ -70,7 +67,6 @@ job "asapo-perfmetrics" { } #influxdb - task "grafana" { driver = "docker" user = "${asapo_user}" @@ -116,6 +112,153 @@ job "asapo-perfmetrics" { } #grafana + task "monitoring-server" { + driver = "docker" + user = "${asapo_user}" + + config { + ulimit { + memlock = "-1:-1" + } + network_mode = "host" + security_opt = ["no-new-privileges"] + userns_mode = "host" + privileged = true + image = "${docker_repository}/asapo-monitoring-server${image_suffix}" + force_pull = ${force_pull_images} + volumes = ["local/config.json:/var/lib/monitoring_server/config.json"] + %{ if ! nomad_logs } + logging { + type = "fluentd" + config { + fluentd-address = "localhost:9881" + fluentd-async-connect = true + tag = "asapo.docker" + } + } + %{endif} + } + + resources { + memory = "${monitoring_server_total_memory_size}" + } + + service { + name = "asapo-monitoring" + port = "monitoring_server" + check { + name = "alive" + port = "monitoring_server" + type = "tcp" + interval = "10s" + timeout = "2s" + initial_status = "passing" + } + } + + template { + source = "${scripts_dir}/monitoring_server.json.tpl" + destination = "local/config.json" + change_mode = "restart" + } + } # monitoring server + + task "monitoring-proxy" { + driver = "docker" + user = "${asapo_user}" + + config { + ulimit { + memlock = "-1:-1" + } + network_mode = "host" + security_opt = ["no-new-privileges"] + userns_mode = "host" + privileged = true + image = "envoyproxy/envoy:v1.21.0" + volumes = ["local/envoy.yaml:/etc/envoy/envoy.yaml"] + command = "/usr/local/bin/envoy" + args=["-c","/etc/envoy/envoy.yaml"] #,"-l","trace" + } + + resources { + memory = "${monitoring_proxy_total_memory_size}" + network { + port "monitoring_proxy_admin" {} + port "monitoring_proxy" { + static = "${monitoring_proxy_port}" + } + } + } + + service { + name = "asapo-monitoring-proxy" + port = "monitoring_proxy" + check { + name = "asapo-monitoring-proxy-alive" + port = "monitoring_proxy_admin" + type = "http" + path = "/" + interval = "10s" + timeout = "2s" + initial_status = "passing" + } + } + + template { + source = "${scripts_dir}/monitoring_proxy.yaml.tpl" + destination = "local/envoy.yaml" + change_mode = "restart" + } + } # monitoring proxy + + task "monitoring-ui" { + driver = "docker" + user = "${asapo_user}" + + config { + ulimit { + memlock = "-1:-1" + } + network_mode = "host" + security_opt = ["no-new-privileges"] + userns_mode = "host" + privileged = true + image = "${docker_repository}/asapo-monitoring-ui${image_suffix}" + force_pull = ${force_pull_images} + volumes = ["local/nginx.conf:/etc/nginx/nginx.conf"] + } + + resources { + memory = "${monitoring_ui_total_memory_size}" + network { + port "monitoring_ui" { + static = "${monitoring_ui_port}" + } + } + } + + service { + name = "asapo-monitoring-ui" + port = "monitoring_ui" + check { + name = "asapo-monitoring-ui-alive" + port = "monitoring_ui" + type = "http" + path = "/" + interval = "10s" + timeout = "2s" + initial_status = "passing" + } + } + + template { + source = "${scripts_dir}/monitoring_ui_nginx.conf.tpl" + destination = "local/nginx.conf" + change_mode = "restart" + } + } # monitoring ui + } } diff --git a/deploy/asapo_services/scripts/asapo-receivers.nmd.tpl b/deploy/asapo_services/scripts/asapo-receivers.nmd.tpl index 5a48f8a93b24ba5f884fe670d284fc98fc538113..a109eda57063f5d2734ae25c9fd31f54eb77c5fa 100644 --- a/deploy/asapo_services/scripts/asapo-receivers.nmd.tpl +++ b/deploy/asapo_services/scripts/asapo-receivers.nmd.tpl @@ -34,7 +34,7 @@ job "asapo-receivers" { security_opt = ["no-new-privileges"] userns_mode = "host" privileged = true - image = "yakser/asapo-receiver${image_suffix}" + image = "${docker_repository}/asapo-receiver${image_suffix}" force_pull = ${force_pull_images} volumes = ["local/config.json:/var/lib/receiver/config.json", "${offline_dir}:${offline_dir}", diff --git a/deploy/asapo_services/scripts/asapo-services.nmd.tpl b/deploy/asapo_services/scripts/asapo-services.nmd.tpl index f7ccfd518f4adbddd2b8f3be1c0f766d179684b8..7581e9b9396d375b600fadfcd7a0382f999e752c 100644 --- a/deploy/asapo_services/scripts/asapo-services.nmd.tpl +++ b/deploy/asapo_services/scripts/asapo-services.nmd.tpl @@ -18,7 +18,7 @@ job "asapo-services" { network_mode = "host" security_opt = ["no-new-privileges"] userns_mode = "host" - image = "yakser/asapo-authorizer${image_suffix}" + image = "${docker_repository}/asapo-authorizer${image_suffix}" force_pull = ${force_pull_images} volumes = ["local/config.json:/var/lib/authorizer/config.json", "${offline_dir}:${offline_dir}", @@ -96,7 +96,7 @@ job "asapo-services" { network_mode = "host" security_opt = ["no-new-privileges"] userns_mode = "host" - image = "yakser/asapo-discovery${image_suffix}" + image = "${docker_repository}/asapo-discovery${image_suffix}" force_pull = ${force_pull_images} volumes = ["local/config.json:/var/lib/discovery/config.json"] %{ if ! nomad_logs } diff --git a/deploy/asapo_services/scripts/asapo.auto.tfvars.in b/deploy/asapo_services/scripts/asapo.auto.tfvars.in index 4f8133d3650be1ac2ecfa8302e965269df753008..334e7119a5480d0f1e9c439cf530b21aae90d2b3 100644 --- a/deploy/asapo_services/scripts/asapo.auto.tfvars.in +++ b/deploy/asapo_services/scripts/asapo.auto.tfvars.in @@ -1,12 +1,14 @@ asapo_imagename_suffix="@ASAPO_VERSION_DOCKER_SUFFIX@" asapo_image_tag = "@ASAPO_VERSION@" +asapo_docker_repository = "yakser" + nginx_version = "1.14" elasticsearch_version = "7.3.2" kibana_version = "7.3.2" mongo_version = "4.0.0" grafana_version="7.5.0" -influxdb_version = "2.0.4" +influxdb_version = "1.8.4" elk_logs = false perf_monitor = false nomad_logs = false @@ -40,6 +42,9 @@ authorizer_total_memory_size = 256 discovery_total_memory_size = 256 prometheus_total_memory_size = 256 alertmanager_total_memory_size = 256 +monitoring_server_total_memory_size = 256 +monitoring_proxy_total_memory_size = 256 +monitoring_ui_total_memory_size = 256 ldap_uri = "ldap://localhost:389" @@ -51,12 +56,19 @@ fluentd_port = 9880 fluentd_port_stream = 24224 elasticsearch_port = 9200 kibana_port = 5601 + discovery_port = 5006 authorizer_port = 5007 +monitoring_proxy_port = 5008 +monitoring_ui_port = 5009 + consul_dns_port = 8600 prometheus_port = 9090 alertmanager_port = 9093 n_receivers = 1 n_brokers = 1 -n_fts = 1 \ No newline at end of file +n_fts = 1 + +receiver_kafka_enabled = false +receiver_kafka_metadata_broker_list = "" diff --git a/deploy/asapo_services/scripts/broker.json.tpl b/deploy/asapo_services/scripts/broker.json.tpl index 493c986e427c76ff9c226d931055ad6f5e398563..c5b4abc56d387c72677eb867347b74304bb6a408 100644 --- a/deploy/asapo_services/scripts/broker.json.tpl +++ b/deploy/asapo_services/scripts/broker.json.tpl @@ -4,6 +4,7 @@ "AuthorizationServer": "localhost:8400/asapo-authorizer", "PerformanceDbServer":"localhost:8400/influxdb", "MonitorPerformance": {{ env "NOMAD_META_perf_monitor" }}, + "MonitoringServerUrl":"auto", "CheckResendInterval":10, "PerformanceDbName": "asapo_brokers", "Port":{{ env "NOMAD_PORT_broker" }}, diff --git a/deploy/asapo_services/scripts/file-transfer.json.tpl b/deploy/asapo_services/scripts/file-transfer.json.tpl index 5f0f028a0fccdc606a728c6a50ec6f9af8ee1408..5f6a2854990c512bc9351cc538ebe293fe15d553 100644 --- a/deploy/asapo_services/scripts/file-transfer.json.tpl +++ b/deploy/asapo_services/scripts/file-transfer.json.tpl @@ -1,5 +1,8 @@ { "Port": {{ env "NOMAD_PORT_fts" }}, "LogLevel":"debug", - "SecretFile":"/local/secret.key" + "SecretFile":"/local/secret.key", + "DiscoveryServer": "localhost:8400/asapo-discovery", + "MonitorPerformance": true, + "MonitoringServerUrl": "auto" } diff --git a/deploy/asapo_services/scripts/monitoring_proxy.yaml.tpl b/deploy/asapo_services/scripts/monitoring_proxy.yaml.tpl new file mode 100644 index 0000000000000000000000000000000000000000..ba6fc9c0740c2513fbd942b431e0815dc05e81cd --- /dev/null +++ b/deploy/asapo_services/scripts/monitoring_proxy.yaml.tpl @@ -0,0 +1,55 @@ +admin: + access_log_path: /tmp/admin_access.log + address: + socket_address: { address: 0.0.0.0, port_value: {{ env "NOMAD_PORT_monitoring_proxy_admin" }} } + +static_resources: + listeners: + - name: listener_0 + address: + socket_address: { address: 0.0.0.0, port_value: {{ env "NOMAD_PORT_monitoring_proxy" }} } + filter_chains: + - filters: + - name: envoy.filters.network.http_connection_manager + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + codec_type: auto + stat_prefix: ingress_http + route_config: + name: local_route + virtual_hosts: + - name: local_service + domains: ["*"] + routes: + - match: { prefix: "/" } + route: + cluster: echo_service + timeout: 0s + max_stream_duration: + grpc_timeout_header_max: 0s + cors: + allow_origin_string_match: + - prefix: "*" + allow_methods: GET, PUT, DELETE, POST, OPTIONS + allow_headers: keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,custom-header-1,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout + max_age: "1728000" + expose_headers: custom-header-1,grpc-status,grpc-message + http_filters: + - name: envoy.filters.http.grpc_web + - name: envoy.filters.http.cors + - name: envoy.filters.http.router + clusters: + - name: echo_service + connect_timeout: 0.25s + type: logical_dns + http2_protocol_options: {} + lb_policy: round_robin + load_assignment: + cluster_name: cluster_0 + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: 127.0.0.1 + port_value: {{ env "NOMAD_PORT_monitoring_server" }} diff --git a/deploy/asapo_services/scripts/monitoring_server.json.tpl b/deploy/asapo_services/scripts/monitoring_server.json.tpl new file mode 100644 index 0000000000000000000000000000000000000000..9ac0424196908d85e08b5e55453c2829fe485f57 --- /dev/null +++ b/deploy/asapo_services/scripts/monitoring_server.json.tpl @@ -0,0 +1,7 @@ +{ + "ThisClusterName": "asapo", + "ServerPort": {{ env "NOMAD_PORT_monitoring_server" }}, + "LogLevel": "{{ keyOrDefault "log_level" "debug" }}", + "InfluxDbUrl":"http://localhost:8400/influxdb", + "InfluxDbDatabase": "asapo_monitoring" +} diff --git a/deploy/asapo_services/scripts/monitoring_ui_nginx.conf.tpl b/deploy/asapo_services/scripts/monitoring_ui_nginx.conf.tpl new file mode 100644 index 0000000000000000000000000000000000000000..f911482cd25d8eaf03c8933e9731c7783b907f04 --- /dev/null +++ b/deploy/asapo_services/scripts/monitoring_ui_nginx.conf.tpl @@ -0,0 +1,53 @@ +worker_processes 1; + +events { + worker_connections 1024; +} + +error_log "/tmp/nginx_error.log"; +pid "/tmp/nginx.pid"; + + +http { + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + client_body_temp_path "/tmp/client_body" 1 2; + client_max_body_size 10M; + proxy_temp_path "/tmp/proxy" 1 2; + fastcgi_temp_path "/tmp/fastcgi" 1 2; + scgi_temp_path "/tmp/scgi" 1 2; + uwsgi_temp_path "/tmp/uwsgi" 1 2; + + + server { + listen {{ env "NOMAD_PORT_monitoring_ui" }} default_server; + server_name _; + root /usr/share/nginx/html; + + # Load configuration files for the default server block. + #include /etc/nginx/default.d/*.conf; + + index index.html; + + etag on; + + location /js/ { + add_header Cache-Control max-age=31536000; + } + + location / { + try_files $uri $uri/ /index.html; + } + location /index.html { + add_header Cache-Control no-cache; + } + + } +} \ No newline at end of file diff --git a/deploy/asapo_services/scripts/nginx.conf.tpl b/deploy/asapo_services/scripts/nginx.conf.tpl index 5e697955799ad4e58187b9eb7514d7749762b6d5..0e5f11c561f30307bf76645cd788e22673b0a357 100644 --- a/deploy/asapo_services/scripts/nginx.conf.tpl +++ b/deploy/asapo_services/scripts/nginx.conf.tpl @@ -31,6 +31,8 @@ http { listen {{ env "NOMAD_PORT_nginx" }}; set $discovery_endpoint asapo-discovery.service.asapo; set $authorizer_endpoint asapo-authorizer.service.asapo; + set $monitoring_ui_endpoint asapo-monitoring-ui.service.asapo; + set $monitoring_proxy_endpoint asapo-monitoring-proxy.service.asapo; set $fluentd_endpoint fluentd.service.asapo; set $kibana_endpoint kibana.service.asapo; set $grafana_endpoint grafana.service.asapo; @@ -79,6 +81,18 @@ http { proxy_pass http://$grafana_endpoint:{{ env "NOMAD_META_grafana_port" }}$uri$is_args$args; } + location /tv/ { + rewrite ^/tv(/.*) $1 break; + proxy_pass http://$monitoring_ui_endpoint:{{ env "NOMAD_META_monitoring_ui_port" }}$uri$is_args$args; + } + + location /tv-api/ { + rewrite ^/tv-api(/.*) $1 break; + proxy_http_version 1.1; + proxy_pass http://$monitoring_proxy_endpoint:{{ env "NOMAD_META_monitoring_proxy_port" }}$uri$is_args$args; + } + + location /asapo-authorizer/ { rewrite ^/asapo-authorizer(/.*) $1 break; proxy_pass http://$authorizer_endpoint:{{ env "NOMAD_META_authorizer_port" }}$uri$is_args$args; diff --git a/deploy/asapo_services/scripts/receiver.json.tpl b/deploy/asapo_services/scripts/receiver.json.tpl index 3183e72ab7ef371dc799f48ceab967af43531f6a..5ca82a26dc5c0f4d6861d7b9c5fc9fed58e19f0f 100644 --- a/deploy/asapo_services/scripts/receiver.json.tpl +++ b/deploy/asapo_services/scripts/receiver.json.tpl @@ -1,6 +1,7 @@ { - "PerformanceDbServer":"localhost:8400/influxdb", "MonitorPerformance": {{ env "NOMAD_META_perf_monitor" }}, + "MonitoringServer": "auto", + "PerformanceDbServer":"localhost:8400/influxdb", "PerformanceDbName": "asapo_receivers", "DatabaseServer":"auto", "DiscoveryServer": "localhost:8400/asapo-discovery", diff --git a/deploy/asapo_services/scripts/resources.tf b/deploy/asapo_services/scripts/resources.tf index 928a5a7620346e3332b33359b43191ee7ee0d497..1a5d817833438cb1a8ba75e101ef9d7f94fda623 100644 --- a/deploy/asapo_services/scripts/resources.tf +++ b/deploy/asapo_services/scripts/resources.tf @@ -13,7 +13,6 @@ resource "nomad_job" "asapo-perfmetrics" { resource "nomad_job" "asapo-monitoring" { jobspec = data.template_file.asapo_monitoring.rendered - depends_on = [null_resource.asapo-broker,null_resource.asapo-receiver] } @@ -29,16 +28,16 @@ resource "nomad_job" "asapo-services" { resource "nomad_job" "asapo-receivers" { jobspec = data.template_file.asapo_receivers.rendered - depends_on = [nomad_job.asapo-services,null_resource.asapo-authorizer,null_resource.asapo-discovery] + depends_on = [nomad_job.asapo-services,null_resource.asapo-authorizer,null_resource.asapo-discovery,null_resource.asapo-monitoring-server] } resource "nomad_job" "asapo-brokers" { jobspec = data.template_file.asapo_brokers.rendered - depends_on = [nomad_job.asapo-services,null_resource.asapo-authorizer,null_resource.asapo-discovery] + depends_on = [nomad_job.asapo-services,null_resource.asapo-authorizer,null_resource.asapo-discovery,null_resource.asapo-monitoring-server] } resource "nomad_job" "asapo-fts" { jobspec = data.template_file.asapo_fts.rendered - depends_on = [nomad_job.asapo-services,null_resource.asapo-authorizer,null_resource.asapo-discovery] + depends_on = [nomad_job.asapo-services,null_resource.asapo-authorizer,null_resource.asapo-discovery,null_resource.asapo-monitoring-server] } diff --git a/deploy/asapo_services/scripts/resources_services.tf b/deploy/asapo_services/scripts/resources_services.tf index 0ad672ea2d3aee11a1f8856e797115b73e75a9a3..d4e31b92ad37b49550c4d6e19c76da4af6b12f66 100644 --- a/deploy/asapo_services/scripts/resources_services.tf +++ b/deploy/asapo_services/scripts/resources_services.tf @@ -67,6 +67,27 @@ resource "null_resource" "asapo-broker" { depends_on = [nomad_job.asapo-brokers] } +resource "null_resource" "asapo-monitoring-server" { + provisioner "local-exec" { + command = "asapo-wait-service asapo-monitoring" + } + depends_on = [nomad_job.asapo-perfmetrics] +} + +resource "null_resource" "asapo-monitoring-proxy" { + provisioner "local-exec" { + command = "asapo-wait-service asapo-monitoring-proxy" + } + depends_on = [nomad_job.asapo-perfmetrics] +} + +resource "null_resource" "asapo-monitoring-ui" { + provisioner "local-exec" { + command = "asapo-wait-service asapo-monitoring-ui" + } + depends_on = [nomad_job.asapo-perfmetrics] +} + resource "null_resource" "asapo-fts" { provisioner "local-exec" { command = "asapo-wait-service asapo-file-transfer" diff --git a/deploy/asapo_services/scripts/templates.tf b/deploy/asapo_services/scripts/templates.tf index 664505890ed9e00007731886657d2dc5532932dc..1e6d0cc6b1e366c49a8b6a7e9ca3d6cf41187726 100644 --- a/deploy/asapo_services/scripts/templates.tf +++ b/deploy/asapo_services/scripts/templates.tf @@ -16,8 +16,9 @@ data "template_file" "nginx" { consul_dns_port = "${var.consul_dns_port}" prometheus_port = "${var.prometheus_port}" alertmanager_port = "${var.alertmanager_port}" + monitoring_ui_port = "${var.monitoring_ui_port}" + monitoring_proxy_port = "${var.monitoring_proxy_port}" } - } data "template_file" "asapo_services" { @@ -26,6 +27,7 @@ data "template_file" "asapo_services" { scripts_dir = "${var.job_scripts_dir}" online_dir = "${var.online_dir}" offline_dir = "${var.offline_dir}" + docker_repository = "${var.asapo_docker_repository}" ldap_uri = "${var.ldap_uri}" image_suffix = "${var.asapo_imagename_suffix}:${var.asapo_image_tag}" nomad_logs = "${var.nomad_logs}" @@ -44,6 +46,7 @@ data "template_file" "asapo_receivers" { scripts_dir = "${var.job_scripts_dir}" online_dir = "${var.online_dir}" offline_dir = "${var.offline_dir}" + docker_repository = "${var.asapo_docker_repository}" image_suffix = "${var.asapo_imagename_suffix}:${var.asapo_image_tag}" nomad_logs = "${var.nomad_logs}" receiver_total_memory_size = "${var.receiver_total_memory_size}" @@ -65,6 +68,7 @@ data "template_file" "asapo_brokers" { template = "${file("${var.job_scripts_dir}/asapo-brokers.nmd.tpl")}" vars = { scripts_dir = "${var.job_scripts_dir}" + docker_repository = "${var.asapo_docker_repository}" image_suffix = "${var.asapo_imagename_suffix}:${var.asapo_image_tag}" nomad_logs = "${var.nomad_logs}" asapo_user = "${var.asapo_user}" @@ -81,6 +85,7 @@ data "template_file" "asapo_fts" { scripts_dir = "${var.job_scripts_dir}" online_dir = "${var.online_dir}" offline_dir = "${var.offline_dir}" + docker_repository = "${var.asapo_docker_repository}" image_suffix = "${var.asapo_imagename_suffix}:${var.asapo_image_tag}" nomad_logs = "${var.nomad_logs}" asapo_user = "${var.asapo_user}" @@ -93,6 +98,8 @@ data "template_file" "asapo_perfmetrics" { template = "${file("${var.job_scripts_dir}/asapo-perfmetrics.nmd.tpl")}" vars = { service_dir = "${var.service_dir}" + image_suffix = "${var.asapo_imagename_suffix}:${var.asapo_image_tag}" + docker_repository = "${var.asapo_docker_repository}" influxdb_version = "${var.influxdb_version}" grafana_version = "${var.grafana_version}" grafana_total_memory_size = "${var.grafana_total_memory_size}" @@ -102,7 +109,15 @@ data "template_file" "asapo_perfmetrics" { asapo_user = "${var.asapo_user}" influxdb_rpc_port = "${var.influxdb_rpc_port}" perf_monitor = "${var.perf_monitor}" - } + monitoring_server_total_memory_size = "${var.monitoring_server_total_memory_size}" + monitoring_proxy_total_memory_size = "${var.monitoring_proxy_total_memory_size}" + monitoring_ui_total_memory_size = "${var.monitoring_ui_total_memory_size}" + monitoring_proxy_port = "${var.monitoring_proxy_port}" + monitoring_ui_port = "${var.monitoring_ui_port}" + force_pull_images = "${var.force_pull_images}" + nomad_logs = "${var.nomad_logs}" + scripts_dir = "${var.job_scripts_dir}" + } } diff --git a/deploy/asapo_services/scripts/vars.tf b/deploy/asapo_services/scripts/vars.tf index 13068f32a322ec22e78a8342b98719fdd2071fac..d612c006f3ecef3ca9d699ebe9f6aed4a5d264e9 100644 --- a/deploy/asapo_services/scripts/vars.tf +++ b/deploy/asapo_services/scripts/vars.tf @@ -1,3 +1,5 @@ +variable "asapo_docker_repository" {} + variable "elk_logs" {} variable "perf_monitor" {} @@ -82,6 +84,11 @@ variable "prometheus_total_memory_size" {} variable "alertmanager_total_memory_size" {} +variable "monitoring_server_total_memory_size" {} + +variable "monitoring_proxy_total_memory_size" {} + +variable "monitoring_ui_total_memory_size" {} variable "grafana_port" {} @@ -109,6 +116,10 @@ variable "authorizer_port" {} variable "consul_dns_port" {} +variable "monitoring_proxy_port" {} + +variable "monitoring_ui_port" {} + variable "n_receivers" {} variable "n_brokers" {} diff --git a/deploy/asapo_worker_node_template b/deploy/asapo_worker_node_template deleted file mode 160000 index 07433f6e3b704e4c072ed573812496a9cf488fc7..0000000000000000000000000000000000000000 --- a/deploy/asapo_worker_node_template +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 07433f6e3b704e4c072ed573812496a9cf488fc7 diff --git a/deploy/build_env/centos/Dockerfile.7.9.2009 b/deploy/build_env/centos/Dockerfile.7.9.2009 index 2026e61c51d2703daeae5dea58c03dcda18591d3..e2963eddc4ee36a9ec35ea46630f4d08cc842399 100644 --- a/deploy/build_env/centos/Dockerfile.7.9.2009 +++ b/deploy/build_env/centos/Dockerfile.7.9.2009 @@ -12,13 +12,20 @@ RUN ./install_cmake.sh ADD install_curl.sh install_curl.sh RUN ./install_curl.sh /curl -RUN yum -y install autoconf libtool libibverbs librdmacm librdmacm-devel +RUN yum -y install autoconf libtool ADD install_libfabric.sh install_libfabric.sh RUN ./install_libfabric.sh +# TODO: Currently unable to build gRPC, since the C++ version in centos 7 is too old. +# The oldest version in centos repo is 1.20.1 from 2019 +# https://cbs.centos.org/koji/packageinfo?packageID=7380 +# Currently the consumer and producer dont need gRPC +#ADD install_grpc.sh install_grpc.sh +#RUN ./install_grpc.sh + RUN yum -y install mc libcurl-devel ENV GOPATH /tmp ENV OS el7 -ADD build.sh /bin/build.sh \ No newline at end of file +ADD build.sh /bin/build.sh diff --git a/deploy/build_env/centos/Dockerfile.8.3.2011 b/deploy/build_env/centos/Dockerfile.8.3.2011 index 13d39c40afd91838f8d3123b60b42326709f7187..e61a70126e2027402adccfec4ad6b93703c3c697 100644 --- a/deploy/build_env/centos/Dockerfile.8.3.2011 +++ b/deploy/build_env/centos/Dockerfile.8.3.2011 @@ -3,22 +3,25 @@ from centos:8.3.2011 RUN yum update -y RUN yum -y groupinstall "Development Tools" RUN yum config-manager --set-enabled powertools -RUN yum -y install wget rpm-build zlib-devel python3-devel python3-numpy libibverbs librdmacm librdmacm-devel mc -RUN yum -y install cmake glibc-static libstdc++-static +RUN yum -y install wget rpm-build zlib-devel python3-devel python3-numpy +RUN yum -y install glibc-static libstdc++-static RUN pip3 install cython RUN ln -s /usr/bin/python3 /usr/bin/python +ADD install_cmake.sh install_cmake.sh +RUN ./install_cmake.sh + ADD install_curl.sh install_curl.sh RUN ./install_curl.sh /curl ADD install_libfabric.sh install_libfabric.sh RUN ./install_libfabric.sh -RUN yum -y install mc libcurl-devel +ADD install_grpc.sh install_grpc.sh +RUN ./install_grpc.sh + +RUN yum -y install libcurl-devel ENV GOPATH /tmp ENV OS el8 ADD build.sh /bin/build.sh - - - diff --git a/deploy/build_env/centos/build.sh b/deploy/build_env/centos/build.sh index b48e489cf41f2d0e68855a52e25fe36a25d5bb6d..46fa870a4451f6236882b1062ab0f326980fcb87 100755 --- a/deploy/build_env/centos/build.sh +++ b/deploy/build_env/centos/build.sh @@ -1,6 +1,11 @@ #!/usr/bin/env bash -cd /asapo/build +set -e + +cd /asapo +rm -rf build || true +mkdir build +cd build cmake \ -DCMAKE_BUILD_TYPE="Release" \ diff --git a/deploy/build_env/centos/build_el7.sh b/deploy/build_env/centos/build_el7.sh index 94db9e958c8348e68eb44d19c7269f07a9fbf28f..9784d78c0b0e1e8a6bf6eb364f15a94810090c38 100755 --- a/deploy/build_env/centos/build_el7.sh +++ b/deploy/build_env/centos/build_el7.sh @@ -1,3 +1,11 @@ #!/usr/bin/env bash -docker build -t yakser/asapo-env:centos7.9.2009 -f Dockerfile.7.9.2009 . -docker push yakser/asapo-env:centos7.9.2009 \ No newline at end of file + +set -e + +. ../../_docker_vars.sh + +docker build -t $ASAPO_DOCKER_REPOSITORY/asapo-env:centos7.9.2009 -f Dockerfile.7.9.2009 . + +if [ $ASAPO_DOCKER_DO_PUSH = "YES" ]; then + docker push $ASAPO_DOCKER_REPOSITORY/asapo-env:centos7.9.2009 +fi diff --git a/deploy/build_env/centos/build_el8.sh b/deploy/build_env/centos/build_el8.sh index b6474aa27810b5c24074bf42f6bc7727a237aecd..cd2277bc8ac4acf3cefff66559e7dd92b726bd28 100755 --- a/deploy/build_env/centos/build_el8.sh +++ b/deploy/build_env/centos/build_el8.sh @@ -1,3 +1,11 @@ #!/usr/bin/env bash -docker build -t yakser/asapo-env:centos8.3.2011 -f Dockerfile.8.3.2011 . -docker push yakser/asapo-env:centos8.3.2011 + +set -e + +. ../../_docker_vars.sh + +docker build -t $ASAPO_DOCKER_REPOSITORY/asapo-env:centos8.3.2011 -f Dockerfile.8.3.2011 . + +if [ $ASAPO_DOCKER_DO_PUSH = "YES" ]; then + docker push $ASAPO_DOCKER_REPOSITORY/asapo-env:centos8.3.2011 +fi diff --git a/deploy/build_env/centos/install_cmake.sh b/deploy/build_env/centos/install_cmake.sh index 55245ffb3a58f94111e147c138a79a488279c6ca..4d4d4c029241ed1d77a780e860ebbf4cbc25e79b 100755 --- a/deploy/build_env/centos/install_cmake.sh +++ b/deploy/build_env/centos/install_cmake.sh @@ -1,13 +1,24 @@ #!/usr/bin/env bash -wget https://cmake.org/files/v3.10/cmake-3.10.0.tar.gz +set -e + +yum install -y openssl-devel + +wget https://cmake.org/files/v3.21/cmake-3.21.1.tar.gz tar zxvf cmake-3.* +rm cmake-3.*.tar.gz + cd cmake-3.* ./bootstrap --prefix=/usr/local make -j$(nproc) make install +cd .. +rm -rf cmake-3.* + +echo "Version check global cmake --version" cmake --version +echo "Version check usr local bin cmake --version" /usr/local/bin/cmake --version diff --git a/deploy/build_env/centos/install_curl.sh b/deploy/build_env/centos/install_curl.sh index ec291cfdac1baabc25b46cfa98c6aa87404a6145..6b4febe3116f6ff469dae7dac3c32649da7299df 100755 --- a/deploy/build_env/centos/install_curl.sh +++ b/deploy/build_env/centos/install_curl.sh @@ -1,16 +1,26 @@ #!/usr/bin/env bash +set -e + +if [ "$1" = "" ] +then + echo "Usage: $0 <install path>" + exit +fi + mkdir -p $1 cd $1 wget --no-check-certificate https://curl.haxx.se/download/curl-7.58.0.tar.gz tar xzf curl-7.58.0.tar.gz +rm curl-*.tar.gz cd curl-7.58.0 + ./configure --without-ssl --disable-shared --disable-manual --disable-ares \ --disable-crypto-auth --disable-ipv6 --disable-proxy --disable-unix-sockets \ --without-libidn --without-librtmp --without-zlib --disable-ldap \ --disable-libcurl-option --prefix=`pwd`/../ -make +make -j$(nproc) make install + cd - rm -rf bin share curl-7.58.0 -rm curl-7.58.0.tar.gz diff --git a/deploy/build_env/centos/install_grpc.sh b/deploy/build_env/centos/install_grpc.sh new file mode 100755 index 0000000000000000000000000000000000000000..924bc81769b88200fef901ef3711af9497e843da --- /dev/null +++ b/deploy/build_env/centos/install_grpc.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +set -e + +git clone --recurse-submodules -b v1.39.0 https://github.com/grpc/grpc + +cd grpc + +# Install gRPC +mkdir -p cmake/build +cd cmake/build +cmake -DgRPC_INSTALL=ON \ + -DgRPC_BUILD_TESTS=OFF \ + ../.. +make -j$(nproc) +make install + +cd ../.. +# Install abseil +mkdir -p third_party/abseil-cpp/cmake/build +cd third_party/abseil-cpp/cmake/build +cmake -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE \ + ../.. +make -j$(nproc) +make install diff --git a/deploy/build_env/centos/install_libfabric.sh b/deploy/build_env/centos/install_libfabric.sh index e6970a094b8cd38a95838ff47e47d35326a36a17..da7f675f83bd594e1f3a1a0d75b31a554a4d5a1f 100755 --- a/deploy/build_env/centos/install_libfabric.sh +++ b/deploy/build_env/centos/install_libfabric.sh @@ -1,12 +1,17 @@ #!/usr/bin/env bash +set -e + +yum install -y libibverbs librdmacm librdmacm-devel + wget https://github.com/ofiwg/libfabric/archive/v1.11.0.tar.gz tar xzf v1.11.0.tar.gz +rm v1.11.0.tar.gz + cd libfabric-1.11.0 ./autogen.sh ./configure -make +make -j$(nproc) make install cd - rm -rf libfabric-1.11.0 -rm v1.11.0.tar.gz diff --git a/deploy/build_env/debians/Dockerfile_debian10.7 b/deploy/build_env/debians/Dockerfile_debian10.7 index 6f4024966068a523ac956f8a4d34c27d1b0dbdcf..ea0b019622f08e5a25746dfbaee9ac0c47bdcdf2 100644 --- a/deploy/build_env/debians/Dockerfile_debian10.7 +++ b/deploy/build_env/debians/Dockerfile_debian10.7 @@ -2,21 +2,25 @@ from debian:10.7 ENV GOPATH /tmp -ADD install_curl.sh install_curl.sh -ADD install_cmake.sh install_cmake.sh - RUN apt update && apt install -y g++ git wget python python3 python-numpy python3-numpy python-pip python3-pip \ zlib1g-dev python3-all-dev python-all-dev python-stdeb python3-stdeb RUN pip --no-cache-dir install cython && pip3 --no-cache-dir install cython -RUN ./install_curl.sh /curl && ./install_cmake.sh +ADD install_cmake.sh install_cmake.sh +RUN ./install_cmake.sh + +ADD install_curl.sh install_curl.sh +RUN ./install_curl.sh /curl ADD install_libfabric.sh install_libfabric.sh RUN ./install_libfabric.sh +ADD install_grpc.sh install_grpc.sh +RUN ./install_grpc.sh + RUN apt install -y libcurl4-openssl-dev ARG OS ENV OS=${OS} -ADD build.sh /bin/build.sh \ No newline at end of file +ADD build.sh /bin/build.sh diff --git a/deploy/build_env/debians/Dockerfile_debian9.13 b/deploy/build_env/debians/Dockerfile_debian9.13 index 6d1d12cb1d9932dcf7962bc949b154bbd2853e9c..3b39caad25b6f30111ae24b66621eb8822c31159 100644 --- a/deploy/build_env/debians/Dockerfile_debian9.13 +++ b/deploy/build_env/debians/Dockerfile_debian9.13 @@ -2,21 +2,25 @@ from debian:9.13 ENV GOPATH /tmp -ADD install_curl.sh install_curl.sh -ADD install_cmake.sh install_cmake.sh - RUN apt update && apt install -y g++ git wget python python3 python-numpy python3-numpy python-pip python3-pip \ zlib1g-dev python3-all-dev python-all-dev python-stdeb python3-stdeb RUN pip --no-cache-dir install cython && pip3 --no-cache-dir install cython -RUN ./install_curl.sh /curl && ./install_cmake.sh +ADD install_cmake.sh install_cmake.sh +RUN ./install_cmake.sh + +ADD install_curl.sh install_curl.sh +RUN ./install_curl.sh /curl ADD install_libfabric.sh install_libfabric.sh RUN ./install_libfabric.sh +ADD install_grpc.sh install_grpc.sh +RUN ./install_grpc.sh + RUN apt install -y libcurl4-openssl-dev ARG OS ENV OS=${OS} -ADD build.sh /bin/build.sh \ No newline at end of file +ADD build.sh /bin/build.sh diff --git a/deploy/build_env/debians/Dockerfile_ubuntu16.04 b/deploy/build_env/debians/Dockerfile_ubuntu16.04 index df0b1e5558d8d7f9bb1b5c16c6aa49723bd7eb38..9734f8d2f21025ca83422c0621926214ab922598 100644 --- a/deploy/build_env/debians/Dockerfile_ubuntu16.04 +++ b/deploy/build_env/debians/Dockerfile_ubuntu16.04 @@ -2,21 +2,25 @@ from ubuntu:16.04 ENV GOPATH /tmp -ADD install_curl.sh install_curl.sh -ADD install_cmake.sh install_cmake.sh - RUN apt update && apt install -y g++ git wget python python3 python-numpy python3-numpy python-pip python3-pip \ zlib1g-dev python3-all-dev python-all-dev python-stdeb python3-stdeb RUN pip --no-cache-dir install cython && pip3 --no-cache-dir install cython -RUN ./install_curl.sh /curl && ./install_cmake.sh +ADD install_cmake.sh install_cmake.sh +RUN ./install_cmake.sh + +ADD install_curl.sh install_curl.sh +RUN ./install_curl.sh /curl ADD install_libfabric.sh install_libfabric.sh RUN ./install_libfabric.sh +ADD install_grpc.sh install_grpc.sh +RUN ./install_grpc.sh + RUN apt install -y libcurl4-openssl-dev ARG OS ENV OS=${OS} -ADD build.sh /bin/build.sh \ No newline at end of file +ADD build.sh /bin/build.sh diff --git a/deploy/build_env/debians/Dockerfile_ubuntu18.04 b/deploy/build_env/debians/Dockerfile_ubuntu18.04 index 4ebfef728a3a7aceaa07d9d9dab27f54ee96fc1d..3aad207040d0a4eb1645b0e24d064a962060b73c 100644 --- a/deploy/build_env/debians/Dockerfile_ubuntu18.04 +++ b/deploy/build_env/debians/Dockerfile_ubuntu18.04 @@ -2,21 +2,25 @@ from ubuntu:18.04 ENV GOPATH /tmp -ADD install_curl.sh install_curl.sh -ADD install_cmake.sh install_cmake.sh - RUN apt update && apt install -y g++ git wget python python3 python-numpy python3-numpy python-pip python3-pip \ zlib1g-dev python3-all-dev python-all-dev python-stdeb python3-stdeb RUN pip --no-cache-dir install cython && pip3 --no-cache-dir install cython sphinx -RUN ./install_curl.sh /curl && ./install_cmake.sh +ADD install_cmake.sh install_cmake.sh +RUN ./install_cmake.sh + +ADD install_curl.sh install_curl.sh +RUN ./install_curl.sh /curl ADD install_libfabric.sh install_libfabric.sh RUN ./install_libfabric.sh +ADD install_grpc.sh install_grpc.sh +RUN ./install_grpc.sh + RUN apt install -y libcurl4-openssl-dev ARG OS ENV OS=${OS} -ADD build.sh /bin/build.sh \ No newline at end of file +ADD build.sh /bin/build.sh diff --git a/deploy/build_env/debians/build.sh b/deploy/build_env/debians/build.sh index 844a4f2c3b80c60769a266de62568fba0fcbc7eb..6290cd8ff0352d7e1fb67f620a1b4acf36cdec4f 100755 --- a/deploy/build_env/debians/build.sh +++ b/deploy/build_env/debians/build.sh @@ -2,7 +2,11 @@ set -e -cd /asapo/build +cd /asapo +rm -rf build || true +mkdir build +cd build + cmake \ -DCMAKE_BUILD_TYPE="Release" \ -DENABLE_LIBFABRIC=ON \ diff --git a/deploy/build_env/debians/build_images.sh b/deploy/build_env/debians/build_images.sh index 56e14df38c08c6187ff6bf4edd0387d3bdd421e0..60332b50a14b8e243a7a0c6a5a1ce14266c41ea0 100755 --- a/deploy/build_env/debians/build_images.sh +++ b/deploy/build_env/debians/build_images.sh @@ -1,13 +1,15 @@ #!/usr/bin/env bash set -e +. ../../_docker_vars.sh + vers="ubuntu18.04 ubuntu16.04 debian9.13 debian10.7 debian11.1" for ver in $vers do - docker build -t yakser/asapo-env:${ver} -f Dockerfile_${ver} --build-arg OS=${ver} . - docker push yakser/asapo-env:${ver} -done - - + docker build -t $ASAPO_DOCKER_REPOSITORY/asapo-env:${ver} -f Dockerfile_${ver} --build-arg OS=${ver} . + if [ $ASAPO_DOCKER_DO_PUSH = "YES" ]; then + docker push $ASAPO_DOCKER_REPOSITORY/asapo-env:${ver} + fi +done diff --git a/deploy/build_env/debians/install_cmake.sh b/deploy/build_env/debians/install_cmake.sh index 25b7917fcc13f9a1955c31866d5f28bfa6c265a9..514291a81b483f82c55aea5a9a029fd8d6bd2f77 100755 --- a/deploy/build_env/debians/install_cmake.sh +++ b/deploy/build_env/debians/install_cmake.sh @@ -1,16 +1,24 @@ #!/usr/bin/env bash -wget https://cmake.org/files/v3.10/cmake-3.10.0.tar.gz +set -e -tar zxvf cmake-3.10.0.tar.gz -cd cmake-3.10.0 +apt-get install -y libssl-dev + +wget https://cmake.org/files/v3.21/cmake-3.21.1.tar.gz + +tar zxvf cmake-3.* +rm cmake-3.*.tar.gz + +cd cmake-3.* ./bootstrap --prefix=/usr/local make -j$(nproc) make install cd .. -rm -rf cmake-3* +rm -rf cmake-3.* +echo "Version check global cmake --version" cmake --version +echo "Version check usr local bin cmake --version" /usr/local/bin/cmake --version diff --git a/deploy/build_env/debians/install_curl.sh b/deploy/build_env/debians/install_curl.sh index 12c6fb561a28a763d4861b31f1a7faaf2c694c27..dd4941a5f07ed16ea41f6c10ad472ecf935cba39 100755 --- a/deploy/build_env/debians/install_curl.sh +++ b/deploy/build_env/debians/install_curl.sh @@ -1,16 +1,26 @@ #!/usr/bin/env bash +set -e + +if [ "$1" = "" ] +then + echo "Usage: $0 <install path>" + exit +fi + mkdir -p $1 cd $1 wget --no-check-certificate https://curl.haxx.se/download/curl-7.58.0.tar.gz tar xzf curl-7.58.0.tar.gz +rm curl-*.tar.gz cd curl-7.58.0 + ./configure --without-ssl --disable-shared --disable-manual --disable-ares \ --disable-crypto-auth --disable-ipv6 --disable-proxy --disable-unix-sockets \ --without-libidn --without-librtmp --without-zlib --disable-ldap \ --disable-libcurl-option --prefix=`pwd`/../ -make +make -j$(nproc) make install + cd - rm -rf bin share curl-7.58.0 -rm curl-7.58.0.tar.gz diff --git a/deploy/build_env/debians/install_grpc.sh b/deploy/build_env/debians/install_grpc.sh new file mode 100755 index 0000000000000000000000000000000000000000..924bc81769b88200fef901ef3711af9497e843da --- /dev/null +++ b/deploy/build_env/debians/install_grpc.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash + +set -e + +git clone --recurse-submodules -b v1.39.0 https://github.com/grpc/grpc + +cd grpc + +# Install gRPC +mkdir -p cmake/build +cd cmake/build +cmake -DgRPC_INSTALL=ON \ + -DgRPC_BUILD_TESTS=OFF \ + ../.. +make -j$(nproc) +make install + +cd ../.. +# Install abseil +mkdir -p third_party/abseil-cpp/cmake/build +cd third_party/abseil-cpp/cmake/build +cmake -DCMAKE_POSITION_INDEPENDENT_CODE=TRUE \ + ../.. +make -j$(nproc) +make install diff --git a/deploy/build_env/debians/install_libfabric.sh b/deploy/build_env/debians/install_libfabric.sh index ecfc8cdb67e649694daeafde88fee47d7ceaf24f..5fedf21c41c53a3e7fc3c6f797d49dde89668594 100755 --- a/deploy/build_env/debians/install_libfabric.sh +++ b/deploy/build_env/debians/install_libfabric.sh @@ -1,15 +1,17 @@ #!/usr/bin/env bash +set -e + +apt install -y autoconf libtool make librdmacm-dev + wget https://github.com/ofiwg/libfabric/archive/v1.11.0.tar.gz tar xzf v1.11.0.tar.gz - -apt install -y autoconf libtool make librdmacm-dev mc +rm v1.11.0.tar.gz cd libfabric-1.11.0 ./autogen.sh ./configure -make +make -j$(nproc) make install cd - rm -rf libfabric-1.11.0 -rm v1.11.0.tar.gz diff --git a/deploy/build_env/manylinux2010/build.sh b/deploy/build_env/manylinux2010/build.sh index c39149562a56431309584375c79cdf488c99d33e..92a6e253d360f70b3b6b2106c805799761aa55ef 100755 --- a/deploy/build_env/manylinux2010/build.sh +++ b/deploy/build_env/manylinux2010/build.sh @@ -16,6 +16,7 @@ for python_path in /opt/python/cp{35,36,37,38,39}*; do numpy_version=${numpy_versions[$python_version]} echo "building wheel for python_version=$python_version with numpy_version=$numpy_version" + mkdir -p /asapo/build cd /asapo/build cmake -DENABLE_LIBFABRIC=on \ -DCMAKE_BUILD_TYPE="Release" \ @@ -42,4 +43,4 @@ cd /asapo/build/consumer \ cd /asapo/build/producer \ && for wheel in wheelhouse/asapo_producer*.whl; do auditwheel repair $wheel --plat manylinux2010_x86_64 -w /asapo/build/wheelhouse - done \ No newline at end of file + done diff --git a/deploy/build_env/manylinux2010/build_image.sh b/deploy/build_env/manylinux2010/build_image.sh index cddfddad4d060ceb2faecd3dfbe925ffedcf1536..3767ccb33e56fdd9c7fe5db5ee52d6764d947aa6 100755 --- a/deploy/build_env/manylinux2010/build_image.sh +++ b/deploy/build_env/manylinux2010/build_image.sh @@ -3,8 +3,12 @@ #docker build -t yakser/asapo-env:manylinux2010_ . #./docker-squash yakser/asapo-env:manylinux2010_ -t yakser/asapo-env:manylinux2010 -docker build -t yakser/asapo-env:manylinux2010-2021-04-05-a6ea1ab . -docker push yakser/asapo-env:manylinux2010-2021-04-05-a6ea1ab - +#docker build -t yakser/asapo-env:manylinux2010-2021-04-05-a6ea1ab . +#docker push yakser/asapo-env:manylinux2010-2021-04-05-a6ea1ab +. ../../_docker_vars.sh +docker build -t $ASAPO_DOCKER_REPOSITORY/asapo-env:manylinux2010 . +if [ $ASAPO_DOCKER_DO_PUSH = "YES" ]; then + docker push $ASAPO_DOCKER_REPOSITORY/asapo-env:manylinux2010 +fi diff --git a/deploy/build_env/manylinux2010/docker-squash b/deploy/build_env/manylinux2010/docker-squash index 22433497d01c838a7981dbff32f7ccef785a09d5..439a4e949e39fd1c06261d737139d17ac2184a1e 100755 --- a/deploy/build_env/manylinux2010/docker-squash +++ b/deploy/build_env/manylinux2010/docker-squash @@ -7,5 +7,6 @@ import sys from docker_squash.cli import run if __name__ == '__main__': + print("Hey Sergey, use the new --squash option in docker build") sys.argv[0] = re.sub(r'(-script\.pyw|\.exe)?$', '', sys.argv[0]) sys.exit(run()) diff --git a/deploy/build_env/manylinux2010/install_cmake.sh b/deploy/build_env/manylinux2010/install_cmake.sh index 55245ffb3a58f94111e147c138a79a488279c6ca..4c8f111a4bbdf584acdec79a7da896d4c4e64848 100755 --- a/deploy/build_env/manylinux2010/install_cmake.sh +++ b/deploy/build_env/manylinux2010/install_cmake.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -wget https://cmake.org/files/v3.10/cmake-3.10.0.tar.gz +wget https://cmake.org/files/v3.21/cmake-3.21.1.tar.gz tar zxvf cmake-3.* cd cmake-3.* diff --git a/deploy/build_env/site/build_image.sh b/deploy/build_env/site/build_image.sh index 51ff855c17c518e1de76ab48a0cff2e1df9a86c3..51004244fb159c27b9182adf542bb1c84eae36c3 100755 --- a/deploy/build_env/site/build_image.sh +++ b/deploy/build_env/site/build_image.sh @@ -1,3 +1,8 @@ #!/usr/bin/env bash -docker build -t yakser/asapo-site-env -f Dockerfile . -docker push yakser/asapo-site-env \ No newline at end of file + +. ../../_docker_vars.sh + +docker build -t $ASAPO_DOCKER_REPOSITORY/asapo-site-env -f Dockerfile . +if [ $ASAPO_DOCKER_DO_PUSH = "YES" ]; then + docker push $ASAPO_DOCKER_REPOSITORY/asapo-site-env +fi diff --git a/deploy/nomad_consul_docker/build_image.sh b/deploy/nomad_consul_docker/build_image.sh index 227ac362f2d64b67ef80888f135065b2a16c3850..7b67d1ea3fad8226d4c5428498e26853f1d43322 100755 --- a/deploy/nomad_consul_docker/build_image.sh +++ b/deploy/nomad_consul_docker/build_image.sh @@ -1,4 +1,10 @@ #!/usr/bin/env bash -docker build -t yakser/asapo-nomad-cluster . -docker push yakser/asapo-nomad-cluster +set -e + +. ../_docker_vars.sh + +docker build -t $ASAPO_DOCKER_REPOSITORY/asapo-nomad-cluster . +if [ $ASAPO_DOCKER_DO_PUSH = "YES" ]; then + docker push $ASAPO_DOCKER_REPOSITORY/asapo-nomad-cluster +fi diff --git a/deploy/nomad_consul_docker/run.sh b/deploy/nomad_consul_docker/run.sh index 0c5bedbb62907ea8f20f814c1794e233bd8cdd3f..9bdbb41f602d87f822e376cf2c96bb41a3dc478a 100755 --- a/deploy/nomad_consul_docker/run.sh +++ b/deploy/nomad_consul_docker/run.sh @@ -1,5 +1,9 @@ #!/usr/bin/env bash +set -e + +. ../_docker_vars.sh + NOMAD_ALLOC_HOST_SHARED=/tmp/asapo/container_host_shared/nomad_alloc ASAPO_USER=`id -u`:`id -g` @@ -13,5 +17,4 @@ docker run --privileged --rm -v /var/run/docker.sock:/var/run/docker.sock \ -v /var/lib/docker:/var/lib/docker \ -v $NOMAD_ALLOC_HOST_SHARED:$NOMAD_ALLOC_HOST_SHARED \ -e NOMAD_ALLOC_DIR=$NOMAD_ALLOC_HOST_SHARED \ - --name asapo --net=host -d yakser/asapo-nomad-cluster - + --name asapo --net=host -d $ASAPO_DOCKER_REPOSITORY/asapo-nomad-cluster diff --git a/dev-setup-notes.txt b/dev-setup-notes.txt new file mode 100644 index 0000000000000000000000000000000000000000..219da906cece11e48831db2b02367ea4edd222fa --- /dev/null +++ b/dev-setup-notes.txt @@ -0,0 +1,5 @@ +- If you are using newer go version, enable go modules (env GO111MODULE="on") + +- Use nomad <= 0.12.5 (https://releases.hashicorp.com/nomad/0.12.5/nomad_0.12.5_linux_amd64.zip) + Because otherwise the file format will be defaulted to HCL 2 (>=1.0.0) + Because otherwise absolute file paths are not allowed (>=0.12.6) (https://www.nomadproject.io/docs/upgrade/upgrade-specific#artifact-and-template-paths) diff --git a/discovery/src/asapo_discovery/common/consts.go b/discovery/src/asapo_discovery/common/consts.go index 46cf71dcdae48f003e3471fab799e0fc243e4090..acd1a28bfdca47366954ec7f3ab323cbc3a80adf 100644 --- a/discovery/src/asapo_discovery/common/consts.go +++ b/discovery/src/asapo_discovery/common/consts.go @@ -5,5 +5,6 @@ var ( NameFtsService = "asapo-file-transfer" NameBrokerService = "asapo-broker" NameReceiverService = "asapo-receiver" + NameMonitoringServer = "asapo-monitoring" ) diff --git a/discovery/src/asapo_discovery/common/structs.go b/discovery/src/asapo_discovery/common/structs.go index 2844d977195a6bfb8a62e49e4150ae5c8c175757..e9826cb8c50f28ba772de2d701972f4b287c0097 100644 --- a/discovery/src/asapo_discovery/common/structs.go +++ b/discovery/src/asapo_discovery/common/structs.go @@ -8,6 +8,10 @@ type ReceiverInfo struct { UseIBAddress bool } +type MonitoringInfo struct { + StaticEndpoint string +} + type BrokerInfo struct { StaticEndpoint string } @@ -23,6 +27,7 @@ type FtsInfo struct { type Settings struct { Receiver ReceiverInfo Broker BrokerInfo + Monitoring MonitoringInfo Mongo MongoInfo FileTransferService FtsInfo ConsulEndpoints []string diff --git a/discovery/src/asapo_discovery/go.sum b/discovery/src/asapo_discovery/go.sum index 356d38f48e3b3021d57ce478c6f164b10a2e8fe9..ba8c7a42b039825526ed1000796e26736420878c 100644 --- a/discovery/src/asapo_discovery/go.sum +++ b/discovery/src/asapo_discovery/go.sum @@ -17,6 +17,7 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da h1:8GUt8eRujhVEGZFFEjBj46YV4rDjvGrNxb0KMWYkL2I= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= @@ -26,9 +27,13 @@ github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+Ce github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -38,12 +43,19 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= @@ -67,11 +79,13 @@ github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= @@ -82,6 +96,7 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -91,6 +106,7 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d h1:7XGaL1e6bYS1yIonGp9761ExpPPV1ui0SAC59Yube9k= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= @@ -98,6 +114,7 @@ github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEo github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/consul/api v1.4.0 h1:jfESivXnO5uLdH650JU/6AnjRoHrLhULq0FnC3Kp9EY= github.com/hashicorp/consul/api v1.4.0/go.mod h1:xc8u05kyMa3Wjr9eEAsIAo3dg8+LywT5E/Cl7cNS5nU= github.com/hashicorp/consul/sdk v0.4.0 h1:zBtCfKJZcJDBvSCkQJch4ulp59m1rATFLKwNo/LYY30= @@ -216,6 +233,7 @@ github.com/prometheus/client_golang v1.11.0 h1:HNkLOAEQMIDv/K+04rukrLx6ch7msSRwf github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= @@ -227,6 +245,7 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= @@ -246,9 +265,11 @@ github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRci github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -260,6 +281,7 @@ golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -273,16 +295,19 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200625001655-4c5254603344 h1:vGXIOMxbNfDTk/aXCmfdLgkrSV+Z2tcbze+pEc3v5W4= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -322,9 +347,12 @@ golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -333,13 +361,25 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1 h1:7QnIQpGRHE5RnLKnESfDoxm2dTapTZua5a0kS0A+VXQ= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -353,6 +393,7 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -362,6 +403,7 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= k8s.io/api v0.17.0 h1:H9d/lw+VkZKEVIUc8F3wgiQ+FUXTTr21M87jXLU7yqM= k8s.io/api v0.17.0/go.mod h1:npsyOePkeP0CPwyGfXDHxvypiYMJxBWAMpQxCaJ4ZxI= k8s.io/apimachinery v0.17.0 h1:xRBnuie9rXcPxUkDizUsGvPf1cnlZCFu210op7J7LJo= diff --git a/discovery/src/asapo_discovery/protocols/hard_coded_consumer.go b/discovery/src/asapo_discovery/protocols/hard_coded_consumer.go index ec0a5e03ad4835f25cf891f25ae66cc53f58c844..a3c0e6ba1bddaeeda9f00b7df2dd79ad728d2eef 100644 --- a/discovery/src/asapo_discovery/protocols/hard_coded_consumer.go +++ b/discovery/src/asapo_discovery/protocols/hard_coded_consumer.go @@ -12,6 +12,14 @@ func getTimefromDate(date string) time.Time{ func GetSupportedConsumerProtocols() []Protocol { return []Protocol{ + Protocol{"v0.6", + map[string]string{ + "Discovery": "v0.1", + "Authorizer": "v0.2", + "Broker": "v0.6", + "File Transfer": "v0.2", + "Data cache service": "v0.1", + }, &protocolValidatorCurrent{}}, Protocol{"v0.5", map[string]string{ "Discovery": "v0.1", @@ -19,7 +27,7 @@ func GetSupportedConsumerProtocols() []Protocol { "Broker": "v0.5", "File Transfer": "v0.2", "Data cache service": "v0.1", - }, &protocolValidatorCurrent{}}, + }, &protocolValidatorDeprecated{getTimefromDate("2023-03-01")}}, Protocol{"v0.4", map[string]string{ "Discovery": "v0.1", diff --git a/discovery/src/asapo_discovery/protocols/hard_coded_producer.go b/discovery/src/asapo_discovery/protocols/hard_coded_producer.go index 3acd3b625626a4a1eb3c8ca503796949dbca243c..2ece774cc9d3f1fd19bb602aed56d9c1cc1b847c 100644 --- a/discovery/src/asapo_discovery/protocols/hard_coded_producer.go +++ b/discovery/src/asapo_discovery/protocols/hard_coded_producer.go @@ -2,33 +2,35 @@ package protocols func GetSupportedProducerProtocols() []Protocol { return []Protocol{ - Protocol{"v0.5", + Protocol{"v0.6", map[string]string{ "Discovery": "v0.1", - "Receiver": "v0.5", + "Receiver": "v0.6", }, &protocolValidatorCurrent{}}, + Protocol{"v0.5", + map[string]string{ + "Discovery": "v0.1", + "Receiver": "v0.5", + }, &protocolValidatorDeprecated{getTimefromDate("2023-03-01")}}, Protocol{"v0.4", map[string]string{ "Discovery": "v0.1", - "Receiver": "v0.4", + "Receiver": "v0.4", }, &protocolValidatorDeprecated{getTimefromDate("2022-12-01")}}, Protocol{"v0.3", map[string]string{ "Discovery": "v0.1", - "Receiver": "v0.3", + "Receiver": "v0.3", }, &protocolValidatorDeprecated{getTimefromDate("2022-09-01")}}, Protocol{"v0.2", map[string]string{ "Discovery": "v0.1", - "Receiver": "v0.2", + "Receiver": "v0.2", }, &protocolValidatorDeprecated{getTimefromDate("2022-07-01")}}, Protocol{"v0.1", map[string]string{ "Discovery": "v0.1", - "Receiver": "v0.1", + "Receiver": "v0.1", }, &protocolValidatorDeprecated{getTimefromDate("2022-06-01")}}, } } - - - diff --git a/discovery/src/asapo_discovery/protocols/protocol_test.go b/discovery/src/asapo_discovery/protocols/protocol_test.go index 4a419ca810c5dd20acb0d5ea157ec81aa7caea94..fff6749cce93bf2e3f832e1eb9e938ac28d5d325 100644 --- a/discovery/src/asapo_discovery/protocols/protocol_test.go +++ b/discovery/src/asapo_discovery/protocols/protocol_test.go @@ -15,7 +15,8 @@ type protocolTest struct { var protocolTests = []protocolTest{ // consumer - {"consumer", "v0.5", true, "current", "v0.5"}, + {"consumer", "v0.6", true, "current", "v0.6"}, + {"consumer", "v0.5", true, "deprecates", "v0.5"}, {"consumer", "v0.4", true, "deprecates", "v0.4"}, {"consumer", "v0.3", true, "deprecates", "v0.3"}, {"consumer", "v0.2", true, "deprecates", "v0.2"}, @@ -25,7 +26,8 @@ var protocolTests = []protocolTest{ // producer - {"producer", "v0.5", true, "current", "v0.5"}, + {"producer", "v0.6", true, "current", "v0.6"}, + {"producer", "v0.5", true, "deprecates", "v0.5"}, {"producer", "v0.4", true, "deprecates", "v0.4"}, {"producer", "v0.3", true, "deprecates", "v0.3"}, {"producer", "v0.2", true, "deprecates", "v0.2"}, diff --git a/discovery/src/asapo_discovery/protocols/protocols.go b/discovery/src/asapo_discovery/protocols/protocols.go index 89561b378cf0fecdd9f11f1043505b61ca8ca18c..4d5c04f47a15928aa88bcd7d70dc32bd2bc2f06e 100644 --- a/discovery/src/asapo_discovery/protocols/protocols.go +++ b/discovery/src/asapo_discovery/protocols/protocols.go @@ -58,7 +58,7 @@ func getSupportedProtocols(client string) ([]Protocol, error) { case "producer": return GetSupportedProducerProtocols(), nil } - return nil, errors.New("unknown client") + return nil, errors.New("unknown client '" + client + "'") } func FindProtocol(client string, version string) (Protocol, error) { @@ -95,4 +95,4 @@ func GetSupportedProtocolsArray(client string) ([]ProtocolInfo, error) { res = append(res, info) } return res,nil -} \ No newline at end of file +} diff --git a/discovery/src/asapo_discovery/request_handler/request_handler_static.go b/discovery/src/asapo_discovery/request_handler/request_handler_static.go index a874bc522f22754fe79ada97ea6d2ab88ae049db..cf9e3b12e28f696cb8f52c3d1c4d957bcb37043a 100644 --- a/discovery/src/asapo_discovery/request_handler/request_handler_static.go +++ b/discovery/src/asapo_discovery/request_handler/request_handler_static.go @@ -2,8 +2,8 @@ package request_handler import ( "asapo_common/utils" - "errors" "asapo_discovery/common" + "errors" ) type StaticRequestHandler struct { @@ -27,6 +27,7 @@ func (rh *StaticRequestHandler) Init(settings common.Settings) error { rh.receiverResponce.MaxConnections = settings.Receiver.MaxConnections rh.receiverResponce.Uris = settings.Receiver.StaticEndpoints rh.singleServices = make(map[string]string) + rh.singleServices[common.NameMonitoringServer] = settings.Monitoring.StaticEndpoint rh.singleServices[common.NameBrokerService] = settings.Broker.StaticEndpoint rh.singleServices[common.NameMongoService] = settings.Mongo.StaticEndpoint rh.singleServices[common.NameFtsService] = settings.FileTransferService.StaticEndpoint diff --git a/discovery/src/asapo_discovery/request_handler/request_handler_static_test.go b/discovery/src/asapo_discovery/request_handler/request_handler_static_test.go index 2f5cc8c6d314e05c9a7b3737ccfde59c26b8059d..1e949dade60562bc9c68a5b73a977327acb4630f 100644 --- a/discovery/src/asapo_discovery/request_handler/request_handler_static_test.go +++ b/discovery/src/asapo_discovery/request_handler/request_handler_static_test.go @@ -1,17 +1,25 @@ package request_handler import ( + "asapo_discovery/common" "github.com/stretchr/testify/assert" "testing" - "asapo_discovery/common" ) var uris = []string{"ip1","ip2"} const max_conn = 1 -var static_settings common.Settings= common.Settings{Receiver:common.ReceiverInfo{MaxConnections:max_conn,StaticEndpoints:uris},Broker:common.BrokerInfo{ - StaticEndpoint:"ip_broker"}, Mongo:common.MongoInfo{StaticEndpoint:"ip_mongo"}, FileTransferService:common.FtsInfo{StaticEndpoint:"ip_fts"}} +var static_settings common.Settings = common.Settings{ + Receiver: common.ReceiverInfo { + MaxConnections: max_conn, + StaticEndpoints:uris, + }, + Broker: common.BrokerInfo { StaticEndpoint:"ip_broker" }, + Monitoring: common.MonitoringInfo { StaticEndpoint:"ip_monitoring" }, + Mongo: common.MongoInfo {StaticEndpoint:"ip_mongo"}, + FileTransferService: common.FtsInfo {StaticEndpoint:"ip_fts"}, +} @@ -29,6 +37,13 @@ func TestStaticHandlerGetReceviersOK(t *testing.T) { assert.Nil(t, err) } +func TestStaticHandlerGetMonitoringServersOK(t *testing.T) { + rh.Init(static_settings) + res,err := rh.GetSingleService(common.NameMonitoringServer) + assert.Equal(t,string(res), "ip_monitoring") + assert.Nil(t, err) +} + func TestStaticHandlerGetBrokerOK(t *testing.T) { rh.Init(static_settings) res,err := rh.GetSingleService(common.NameBrokerService) @@ -49,4 +64,4 @@ func TestStaticHandlerGetFtsOK(t *testing.T) { res,err := rh.GetSingleService(common.NameFtsService) assert.Equal(t,string(res), "ip_fts") assert.Nil(t, err) -} \ No newline at end of file +} diff --git a/discovery/src/asapo_discovery/server/listroutes.go b/discovery/src/asapo_discovery/server/listroutes.go index 88c566d79e480a08e97a6470cb554ef6a0aa3fdc..1f180155b1454c50e2f282905567cc3272c56d62 100644 --- a/discovery/src/asapo_discovery/server/listroutes.go +++ b/discovery/src/asapo_discovery/server/listroutes.go @@ -6,6 +6,12 @@ import ( ) var listRoutes = utils.Routes{ + utils.Route{ + "GetMonitoringServers", + "Get", + "/" + common.NameMonitoringServer, + routeGetMonitoringServers, + }, utils.Route{ "GetReceivers", "Get", diff --git a/discovery/src/asapo_discovery/server/routes.go b/discovery/src/asapo_discovery/server/routes.go index 9cbc5b920a84dd4e2c51d02257d9263ea40b98a2..7983eba50aa4ab96395d6d4035dcebcfc06255cb 100644 --- a/discovery/src/asapo_discovery/server/routes.go +++ b/discovery/src/asapo_discovery/server/routes.go @@ -58,6 +58,12 @@ func routeGetReceivers(w http.ResponseWriter, r *http.Request) { w.Write(answer) } +func routeGetMonitoringServers(w http.ResponseWriter, r *http.Request) { + answer, code := getService(common.NameMonitoringServer) + w.WriteHeader(code) + w.Write(answer) +} + func routeGetBroker(w http.ResponseWriter, r *http.Request) { if ok := checkDiscoveryApiVersion(w, r); !ok { return diff --git a/discovery/src/asapo_discovery/server/routes_test.go b/discovery/src/asapo_discovery/server/routes_test.go index 98db36704f24217350427b12e3584f83da491e26..b98a83a0d7d1688e88c66d3c785ef0a4f12d7d76 100644 --- a/discovery/src/asapo_discovery/server/routes_test.go +++ b/discovery/src/asapo_discovery/server/routes_test.go @@ -34,7 +34,7 @@ func (suite *GetServicesTestSuite) SetupTest() { requestHandler = new(request_handler.StaticRequestHandler) var s common.Settings = common.Settings{Receiver: common.ReceiverInfo{MaxConnections: 10, StaticEndpoints: []string{"ip1", "ip2"}}, Broker: common.BrokerInfo{StaticEndpoint: "ip_broker"}, Mongo: common.MongoInfo{StaticEndpoint: "ip_mongo"}, - FileTransferService: common.FtsInfo{StaticEndpoint: "ip_fts"}} + FileTransferService: common.FtsInfo{StaticEndpoint: "ip_fts"},Monitoring: common.MonitoringInfo{StaticEndpoint: "ip_monitoring"}} requestHandler.Init(s) logger.SetMockLog() @@ -138,6 +138,18 @@ func (suite *GetServicesTestSuite) TestGetFts() { assertExpectations(suite.T()) } +func (suite *GetServicesTestSuite) TestGetMonitoring() { + logger.MockLog.On("WithFields", mock.Anything) + logger.MockLog.On("Debug", mock.MatchedBy(containsMatcher("request"))) + + w := doRequest("/asapo-monitoring") + + suite.Equal(http.StatusOK, w.Code, "code ok") + suite.Equal(w.Body.String(), "ip_monitoring", "result") + assertExpectations(suite.T()) +} + + func (suite *GetServicesTestSuite) TestGetVersions() { logger.MockLog.On("Debug", mock.MatchedBy(containsMatcher("request"))) diff --git a/discovery/src/asapo_discovery/server/settings_test.go b/discovery/src/asapo_discovery/server/settings_test.go index e053b71a4c8c5c50391fb84333bbd3cb364f4db4..4dc51456a953e47d659606b77e3182677545c2c7 100644 --- a/discovery/src/asapo_discovery/server/settings_test.go +++ b/discovery/src/asapo_discovery/server/settings_test.go @@ -1,9 +1,9 @@ package server import ( + "asapo_discovery/common" "github.com/stretchr/testify/assert" "testing" - "asapo_discovery/common" ) func fillSettings(mode string) common.Settings { @@ -40,6 +40,13 @@ func TestSettingsStaticModeNoReceiverEndpoints(t *testing.T) { assert.NotNil(t, err) } +func TestSettingsStaticModeNoMonitoringEndpoints(t *testing.T) { + settings := fillSettings("static") + settings.Broker.StaticEndpoint="" + err := settings.Validate() + assert.NotNil(t, err) +} + func TestSettingsStaticModeNoBrokerEndpoints(t *testing.T) { settings := fillSettings("static") settings.Broker.StaticEndpoint="" diff --git a/docs/site/examples/c/consume.c b/docs/site/examples/c/consume.c index a29537c61fa0c950f4a4c29e55f6c10e634d3da4..6d00974d168528e7478bd158cfac7a7852c4bc28 100644 --- a/docs/site/examples/c/consume.c +++ b/docs/site/examples/c/consume.c @@ -26,7 +26,7 @@ int main(int argc, char* argv[]) { const char * path_to_files = "/var/tmp/asapo/global_shared/data/test_facility/gpfs/test/2019/data/asapo_test"; //set it according to your configuration. AsapoSourceCredentialsHandle cred = asapo_create_source_credentials(kProcessed, - beamtime, + "auto", "auto", beamtime, "", "test_source", token); AsapoConsumerHandle consumer = asapo_create_consumer(endpoint, path_to_files, 1, @@ -61,6 +61,6 @@ int main(int argc, char* argv[]) { asapo_free_handle(&data); asapo_free_handle(&consumer); asapo_free_handle(&group_id); + return EXIT_SUCCESS; } - diff --git a/examples/pipeline/in_to_out/in_to_out.cpp b/examples/pipeline/in_to_out/in_to_out.cpp index ac47de215c60c4682ffec1f3a4d61e5ba36b5d3f..a031b176dded5d72164707c331c1ec4c11e004b7 100644 --- a/examples/pipeline/in_to_out/in_to_out.cpp +++ b/examples/pipeline/in_to_out/in_to_out.cpp @@ -66,6 +66,7 @@ int ProcessError(const Error& err) { ConsumerPtr CreateConsumerAndGroup(const Args& args, Error* err) { auto consumer = asapo::ConsumerFactory::CreateConsumer(args.server, args.file_path, true, asapo::SourceCredentials{asapo::SourceType::kProcessed, + "auto", "auto", args.beamtime_id, "", args.stream_in, args.token}, err); @@ -193,7 +194,8 @@ std::unique_ptr<asapo::Producer> CreateProducer(const Args& args) { asapo::Error err; auto producer = asapo::Producer::Create(args.server, args.nthreads, asapo::RequestHandlerType::kTcp, - asapo::SourceCredentials{asapo::SourceType::kProcessed, args.beamtime_id, + asapo::SourceCredentials{asapo::SourceType::kProcessed, + "auto", "auto", args.beamtime_id, "", args.stream_out, args.token}, 60000, &err); if (err) { std::cerr << "Cannot start producer. ProducerError: " << err << std::endl; diff --git a/examples/producer/dummy-data-producer/dummy_data_producer.cpp b/examples/producer/dummy-data-producer/dummy_data_producer.cpp index 9792fec457829d2c0aad41f37a379d43185cb0d4..ce71b475a37ee4fd1f3553dba681eee2c670540c 100644 --- a/examples/producer/dummy-data-producer/dummy_data_producer.cpp +++ b/examples/producer/dummy-data-producer/dummy_data_producer.cpp @@ -20,7 +20,7 @@ struct Args { std::string beamtime_id; std::string data_source; std::string token; - size_t data_size; + size_t data_size_bytes; uint64_t iterations; uint8_t nthreads; uint64_t mode; @@ -29,20 +29,22 @@ struct Args { bool write_files; asapo::SourceType type; asapo::RequestHandlerType handler; + std::string pipeline_name = "DummyDataProducerPipelineStep"; }; void PrintCommandArguments(const Args& args) { std::cout << "discovery_service_endpoint: " << args.discovery_service_endpoint << std::endl << "beamtime_id: " << args.beamtime_id << std::endl - << "Package size: " << args.data_size / 1000 << "k" << std::endl + << "Package size: " << args.data_size_bytes / 1000 << "k" << std::endl << "iterations: " << args.iterations << std::endl - << "nthreads: " << args.nthreads << std::endl + << "nthreads: " << (int)args.nthreads << std::endl << "mode: " << args.mode << std::endl << "Write files: " << args.write_files << std::endl - << "Tcp mode: " << ((args.mode % 10) == 0) << std::endl + << "Tcp mode: " << ((args.mode % 10) == 0 ) << std::endl << "Raw: " << (args.mode / 100 == 1) << std::endl << "timeout: " << args.timeout_ms << std::endl << "messages in set: " << args.messages_in_set << std::endl + << "pipelineStep: " << args.pipeline_name << std::endl << std::endl; } @@ -69,10 +71,10 @@ void TryGetDataSourceAndToken(Args* args) { } void ProcessCommandArguments(int argc, char* argv[], Args* args) { - if (argc != 8 && argc != 9) { + if (argc != 8 && argc != 9 && argc != 10) { std::cout << "Usage: " << argv[0] << - " <destination> <beamtime_id[%<data_source>%<token>]> <number_of_kbyte> <iterations> <nthreads>" + " <destination> <beamtime_id[%<data_source>[%<token>]]> <number_of_kbyte> <iterations> <nthreads> [pipeline_name]" " <mode 0xx - processed source type, 1xx - raw source type, xx0 -t tcp, xx1 - filesystem, x0x - write files, x1x - do not write files> <timeout (sec)> [n messages in set (default 1)]" << std::endl; exit(EXIT_FAILURE); @@ -81,20 +83,24 @@ void ProcessCommandArguments(int argc, char* argv[], Args* args) { args->discovery_service_endpoint = argv[1]; args->beamtime_id = argv[2]; TryGetDataSourceAndToken(args); - args->data_size = std::stoull(argv[3]) * 1000; + args->data_size_bytes = std::stoull(argv[3]) * 1000; args->iterations = std::stoull(argv[4]); args->nthreads = static_cast<uint8_t>(std::stoi(argv[5])); args->mode = std::stoull(argv[6]); args->timeout_ms = std::stoull(argv[7]) * 1000; - if (argc == 9) { + if (argc >= 9) { args->messages_in_set = std::stoull(argv[8]); } else { args->messages_in_set = 1; } + if (argc >= 10) { + args->pipeline_name = argv[9]; + } + args->write_files = (args->mode % 100) / 10 == 0; args->type = args->mode / 100 == 0 ? asapo::SourceType::kProcessed : asapo::SourceType::kRaw; args->handler = args->mode % 10 == 0 ? asapo::RequestHandlerType::kTcp - : asapo::RequestHandlerType::kFilesystem; + : asapo::RequestHandlerType::kFilesystem; PrintCommandArguments(*args); return; } catch (std::exception& e) { @@ -133,7 +139,7 @@ asapo::MessageData CreateMemoryBuffer(size_t size) { asapo::MessageHeader PrepareMessageHeader(uint64_t i, const Args& args) { std::string message_folder = GetStringFromSourceType(args.type) + asapo::kPathSeparator; - asapo::MessageHeader message_header{i + 1, args.data_size, std::to_string(i + 1)}; + asapo::MessageHeader message_header{i + 1, args.data_size_bytes, std::to_string(i + 1)}; std::string meta = "{\"user_meta\":\"test" + std::to_string(i + 1) + "\"}"; if (!args.data_source.empty()) { message_header.file_name = args.data_source + "/" + message_header.file_name; @@ -144,7 +150,7 @@ asapo::MessageHeader PrepareMessageHeader(uint64_t i, const Args& args) { } asapo::Error Send(asapo::Producer* producer, const asapo::MessageHeader& message_header, const Args& args) { - auto buffer = CreateMemoryBuffer(args.data_size); + auto buffer = CreateMemoryBuffer(args.data_size_bytes); return producer->Send(message_header, std::move(buffer), args.write_files ? asapo::kDefaultIngestMode : asapo::kTransferData, @@ -207,10 +213,11 @@ bool SendDummyData(asapo::Producer* producer, const Args& args) { std::unique_ptr<asapo::Producer> CreateProducer(const Args& args) { asapo::Error err; auto producer = asapo::Producer::Create(args.discovery_service_endpoint, args.nthreads, args.handler, - asapo::SourceCredentials{ - args.type, args.beamtime_id, - "", args.data_source, args.token}, - 3600000, &err); + asapo::SourceCredentials{ + args.type, "DummyDataProducer", + args.pipeline_name, args.beamtime_id, "", args.data_source, args.token + }, + 3600000, &err); if (err) { std::cerr << "Cannot start producer. ProducerError: " << err << std::endl; exit(EXIT_FAILURE); @@ -226,7 +233,7 @@ void PrintOutput(const Args& args, const system_clock::time_point& start) { double duration_sec = static_cast<double>(std::chrono::duration_cast<std::chrono::milliseconds>(t2 - start).count()) / 1000.0; - double size_gb = static_cast<double>(args.data_size * args.iterations) / 1000.0 / 1000.0 / 1000.0 * 8.0; + double size_gb = static_cast<double>(args.data_size_bytes * args.iterations) / 1000.0 / 1000.0 / 1000.0 * 8.0; double rate = static_cast<double>(args.iterations) / duration_sec; std::cout << "Rate: " << rate << " Hz" << std::endl; std::cout << "Bandwidth " << size_gb / duration_sec << " Gbit/s" << std::endl; diff --git a/file_transfer/src/asapo_file_transfer/go.mod b/file_transfer/src/asapo_file_transfer/go.mod index 6147a5d7f5fc6962ae22dcf4f7d8794bbb7e1461..c617e122ee2dd2c094233ca239391f99b59f4aa2 100644 --- a/file_transfer/src/asapo_file_transfer/go.mod +++ b/file_transfer/src/asapo_file_transfer/go.mod @@ -7,4 +7,5 @@ replace asapo_common v0.0.0 => ../../../common/go/src/asapo_common require ( asapo_common v0.0.0 github.com/stretchr/testify v1.7.0 + google.golang.org/grpc v1.39.0 // indirect ) diff --git a/file_transfer/src/asapo_file_transfer/go.sum b/file_transfer/src/asapo_file_transfer/go.sum index 6f35f25f5853eb59ed8eb5b781b6410839850826..9bd583b4a9f937caf71666fdbd6a0885a534f336 100644 --- a/file_transfer/src/asapo_file_transfer/go.sum +++ b/file_transfer/src/asapo_file_transfer/go.sum @@ -1,24 +1,127 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/magefile/mage v1.10.0 h1:3HiXzCUY12kh9bIuyXShaVe529fJfyqoVM42o/uom2g= github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/sirupsen/logrus v1.8.0 h1:nfhvjKcUMhBMVqbKHJlk5RPrrfYr/NMo3692g0dwfWU= github.com/sirupsen/logrus v1.8.0/go.mod h1:4GuYW9TZmE769R5STWrRakJc4UqQ3+QQ95fyz7ENv1A= github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up98WAHf3f/ulnJ62IyA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.39.0 h1:Klz8I9kdtkIN6EpHHUOMLCYhTn/2WAe5a0s1hcBkdTI= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/file_transfer/src/asapo_file_transfer/main/file_transfer.go b/file_transfer/src/asapo_file_transfer/main/file_transfer.go index 52dd23ab3ca954a1c62a148be85222a0c8dce56f..f5d32e2e9e4f5f77fa6c21b61b8169b8c7dcbee2 100644 --- a/file_transfer/src/asapo_file_transfer/main/file_transfer.go +++ b/file_transfer/src/asapo_file_transfer/main/file_transfer.go @@ -35,5 +35,7 @@ func main() { log.SetLevel(logLevel) + server.CreateDiscoveryService() + server.Start() } diff --git a/file_transfer/src/asapo_file_transfer/server/get_health.go b/file_transfer/src/asapo_file_transfer/server/get_health.go index b7d9f2446fb62c2c3e7d353172978d4a9682e832..812683760c5b2bdafde401887a886eff9dcc3265 100644 --- a/file_transfer/src/asapo_file_transfer/server/get_health.go +++ b/file_transfer/src/asapo_file_transfer/server/get_health.go @@ -4,7 +4,6 @@ import ( "net/http" ) - func routeGetHealth(w http.ResponseWriter, r *http.Request) { r.Header.Set("Content-type", "application/json") w.WriteHeader(http.StatusNoContent) diff --git a/file_transfer/src/asapo_file_transfer/server/monitoring.go b/file_transfer/src/asapo_file_transfer/server/monitoring.go new file mode 100644 index 0000000000000000000000000000000000000000..2b251dfeabf89a79dcc9ab0731ad209435d4a68e --- /dev/null +++ b/file_transfer/src/asapo_file_transfer/server/monitoring.go @@ -0,0 +1,86 @@ +package server + +import ( + pb "asapo_common/generated_proto" + "context" + "sync" + "time" +) + +type brokerMonitoring struct { + Sender BrokerMonitoringDataSender + FtsName string + + toBeSendMutex sync.Mutex + toBeSendDataPoints []*pb.FdsToConsumerDataPoint + + sendingThreadRunningCtx context.Context + + discoveredMonitoringServerUrl string +} + +func (m *brokerMonitoring) getFtsToConsumerTransfer(consumerInstanceId string, pipelineStepId string, + beamtime string, source string, stream string) *pb.FdsToConsumerDataPoint { + for _, element := range m.toBeSendDataPoints { + if element.ConsumerInstanceId == consumerInstanceId && + element.PipelineStepId == pipelineStepId && + element.Beamtime == beamtime && + element.Source == source && + element.Stream == stream { + return element + } + } + + newPoint := &pb.FdsToConsumerDataPoint{ + PipelineStepId: pipelineStepId, + ConsumerInstanceId: consumerInstanceId, + Beamtime: beamtime, + Source: source, + Stream: stream, + FileCount: 0, + TotalFileSize: 0, + TotalTransferSendTimeInMicroseconds: 0, + } + + // Need to insert element + m.toBeSendDataPoints = append(m.toBeSendDataPoints, newPoint) + + return newPoint +} + +func (m *brokerMonitoring) sendNow() error { + + // Lock and quickly exchange the to be sent data + m.toBeSendMutex.Lock() + localToBeSendDataPoints := m.toBeSendDataPoints + m.toBeSendDataPoints = nil + m.toBeSendMutex.Unlock() + + + dataContainer := pb.FtsToConsumerDataPointContainer{ + FtsName: m.FtsName, + TimestampMs: uint64(time.Now().UnixNano() / int64(time.Millisecond)), + GroupedFdsTransfers: localToBeSendDataPoints, + } + + err := m.Sender.Send(&dataContainer) + if err != nil { + return err + } + + return nil +} + +func (m *brokerMonitoring) SendFileTransferServiceRequest( + consumerInstanceId string, pipelineStepId string, beamtimeId string, datasource string, stream string, + transferTimeMicroseconds uint64, size uint64) { + + m.toBeSendMutex.Lock() + + group := m.getFtsToConsumerTransfer(consumerInstanceId, pipelineStepId, beamtimeId, datasource, stream) + group.FileCount++ + group.TotalFileSize += size + group.TotalTransferSendTimeInMicroseconds += transferTimeMicroseconds + + m.toBeSendMutex.Unlock() +} diff --git a/file_transfer/src/asapo_file_transfer/server/monitoring_nottested.go b/file_transfer/src/asapo_file_transfer/server/monitoring_nottested.go new file mode 100644 index 0000000000000000000000000000000000000000..b87341bbf1886f39e3e388bcbc3f96cd2a48d84b --- /dev/null +++ b/file_transfer/src/asapo_file_transfer/server/monitoring_nottested.go @@ -0,0 +1,119 @@ +package server + +import ( + pb "asapo_common/generated_proto" + log "asapo_common/logger" + "context" + "google.golang.org/grpc" + "os" + "strconv" + "time" +) + +type BrokerMonitoringDataSender interface { + Init(serverUrl string) error + Send(container *pb.FtsToConsumerDataPointContainer) error + IsInitialized() bool +} + +type gRPCBrokerMonitoringDataSender struct { + client pb.AsapoMonitoringIngestServiceClient +} + +func (g *gRPCBrokerMonitoringDataSender) IsInitialized() bool { + return g.client != nil +} + +func (g *gRPCBrokerMonitoringDataSender) Init(serverUrl string) error { + var opts []grpc.DialOption + opts = append(opts, grpc.WithInsecure()) + conn, err := grpc.Dial(serverUrl, opts...) + if err != nil { + return err + } + + g.client = pb.NewAsapoMonitoringIngestServiceClient(conn) + + return nil +} + +func (g *gRPCBrokerMonitoringDataSender) Send(container *pb.FtsToConsumerDataPointContainer) error { + _, err := g.client.InsertFtsDataPoints(context.TODO(), container) + + if err != nil { + return err + } + + return nil +} + +func (m *brokerMonitoring) reinitializeSender() error { + if settings.MonitoringServerUrl == "auto" { + fetchedMonitoringServerUrl, err := discoveryService.GetMonitoringServerUrl() + if err != nil { + return err + } + m.discoveredMonitoringServerUrl = fetchedMonitoringServerUrl + } else { + m.discoveredMonitoringServerUrl = settings.MonitoringServerUrl + } + + err := m.Sender.Init(m.discoveredMonitoringServerUrl) + if err != nil { + return err + } + + return nil +} + +func (m *brokerMonitoring) Init() error { + hostname, err := os.Hostname() + if err != nil { + hostname = "hostnameerror" + } + m.FtsName = "fts_" + hostname + "_" + strconv.Itoa(os.Getpid()) + + return nil +} + +func (m *brokerMonitoring) RunThread() { + time.Sleep(5000 * time.Millisecond) + globalStart := time.Now() + + sendingInterval := 5000 * time.Millisecond + time.Sleep(sendingInterval) + + waitForNextIteration := func(iterationStartTime time.Time) { + timeTook := time.Since(iterationStartTime) + if timeTook < sendingInterval { + sleepTime := sendingInterval - (time.Since(globalStart) % sendingInterval) + time.Sleep(sleepTime) + } + } + + for { + iterationStart := time.Now() + if !m.Sender.IsInitialized() { + err := m.reinitializeSender() + if err != nil { + log.Warning("monitoring.reinitializeSender failed " , err.Error()) + waitForNextIteration(iterationStart) + continue + } + } + + err := m.sendNow() + + if err != nil { + logString := "sending monitoring data to '" + m.discoveredMonitoringServerUrl + "'" + log.Error(logString + " - " + err.Error()) + + err = m.reinitializeSender() + if err != nil { + log.Error("reinitializeSender also failed - " + err.Error()) + } + } + + waitForNextIteration(iterationStart) + } +} diff --git a/file_transfer/src/asapo_file_transfer/server/monitoring_test.go b/file_transfer/src/asapo_file_transfer/server/monitoring_test.go new file mode 100644 index 0000000000000000000000000000000000000000..7d258010428bb348649efeb782233d19e5635d3f --- /dev/null +++ b/file_transfer/src/asapo_file_transfer/server/monitoring_test.go @@ -0,0 +1,121 @@ +package server + +import ( + pb "asapo_common/generated_proto" + "errors" + "github.com/stretchr/testify/assert" + "testing" + "time" +) + +type mockRpc struct { + LastSendContainer *pb.FtsToConsumerDataPointContainer +} +func (m *mockRpc) Send(container *pb.FtsToConsumerDataPointContainer) error { + m.LastSendContainer = container + return nil +} +func (m *mockRpc) Init(serverUrl string) error { + return nil +} +func (m *mockRpc) IsInitialized() bool { + return true +} + +type mockErrorRpc struct { +} +func (m *mockErrorRpc) Send(container *pb.FtsToConsumerDataPointContainer) error { + return errors.New("MyMockError from Send") +} +func (m *mockErrorRpc) Init(serverUrl string) error { + return errors.New("MyMockError from Init") +} +func (m *mockErrorRpc) IsInitialized() bool { + return true +} + +func TestMonitoringCycle(t *testing.T) { + mockRpc := new(mockRpc) + monitoring.Sender = mockRpc + monitoring.FtsName = "myFst" + + // Send one file + monitoring.SendFileTransferServiceRequest( + "consumerId", "pipelineStep", "beamtime", "datasource", "stream", + 123, 10000) + + monitoring.sendNow() + + assert.NotNil(t, mockRpc.LastSendContainer) + assert.Equal(t, mockRpc.LastSendContainer.FtsName, "myFst") + assert.GreaterOrEqual(t, mockRpc.LastSendContainer.TimestampMs, uint64(time.Now().UnixNano() / int64(time.Millisecond)) - 1000) + assert.LessOrEqual(t, mockRpc.LastSendContainer.TimestampMs, uint64(time.Now().UnixNano() / int64(time.Millisecond))) + assert.Equal(t, len(mockRpc.LastSendContainer.GroupedFdsTransfers), 1) + assert.Equal(t, mockRpc.LastSendContainer.GroupedFdsTransfers[0].PipelineStepId, "pipelineStep") + assert.Equal(t, mockRpc.LastSendContainer.GroupedFdsTransfers[0].ConsumerInstanceId, "consumerId") + assert.Equal(t, mockRpc.LastSendContainer.GroupedFdsTransfers[0].Beamtime, "beamtime") + assert.Equal(t, mockRpc.LastSendContainer.GroupedFdsTransfers[0].Source, "datasource") + assert.Equal(t, mockRpc.LastSendContainer.GroupedFdsTransfers[0].Stream, "stream") + assert.Equal(t, mockRpc.LastSendContainer.GroupedFdsTransfers[0].FileCount, uint64(1)) + assert.Equal(t, mockRpc.LastSendContainer.GroupedFdsTransfers[0].TotalTransferSendTimeInMicroseconds, uint64(123)) + assert.Equal(t, mockRpc.LastSendContainer.GroupedFdsTransfers[0].TotalFileSize, uint64(10000)) + + // No files send + monitoring.sendNow() + assert.NotNil(t, mockRpc.LastSendContainer) + assert.Equal(t, mockRpc.LastSendContainer.FtsName, "myFst") + assert.GreaterOrEqual(t, mockRpc.LastSendContainer.TimestampMs, uint64(time.Now().UnixNano() / int64(time.Millisecond)) - 1000) + assert.LessOrEqual(t, mockRpc.LastSendContainer.TimestampMs, uint64(time.Now().UnixNano() / int64(time.Millisecond))) + assert.Equal(t, len(mockRpc.LastSendContainer.GroupedFdsTransfers), 0) + + + // Send 3 files in 2 groups + monitoring.SendFileTransferServiceRequest( + "consumerId", "pipelineStep", "beamtime1", "datasource", "stream", + 564, 567123) + monitoring.SendFileTransferServiceRequest( + "consumerId", "pipelineStep", "beamtime1", "datasource", "stream", + 32, 8912) + monitoring.SendFileTransferServiceRequest( + "consumerId", "pipelineStep", "beamtime2", "datasource", "stream", + 401, 9874) + + monitoring.sendNow() + + assert.NotNil(t, mockRpc.LastSendContainer) + assert.Equal(t, mockRpc.LastSendContainer.FtsName, "myFst") + assert.GreaterOrEqual(t, mockRpc.LastSendContainer.TimestampMs, uint64(time.Now().UnixNano() / int64(time.Millisecond)) - 1000) + assert.LessOrEqual(t, mockRpc.LastSendContainer.TimestampMs, uint64(time.Now().UnixNano() / int64(time.Millisecond))) + assert.Equal(t, len(mockRpc.LastSendContainer.GroupedFdsTransfers), 2) + + assert.Equal(t, mockRpc.LastSendContainer.GroupedFdsTransfers[0].PipelineStepId, "pipelineStep") + assert.Equal(t, mockRpc.LastSendContainer.GroupedFdsTransfers[0].ConsumerInstanceId, "consumerId") + assert.Equal(t, mockRpc.LastSendContainer.GroupedFdsTransfers[0].Beamtime, "beamtime1") + assert.Equal(t, mockRpc.LastSendContainer.GroupedFdsTransfers[0].Source, "datasource") + assert.Equal(t, mockRpc.LastSendContainer.GroupedFdsTransfers[0].Stream, "stream") + assert.Equal(t, mockRpc.LastSendContainer.GroupedFdsTransfers[0].FileCount, uint64(2)) + assert.Equal(t, mockRpc.LastSendContainer.GroupedFdsTransfers[0].TotalTransferSendTimeInMicroseconds, uint64(564+32)) + assert.Equal(t, mockRpc.LastSendContainer.GroupedFdsTransfers[0].TotalFileSize, uint64(567123+8912)) + + assert.Equal(t, mockRpc.LastSendContainer.GroupedFdsTransfers[1].PipelineStepId, "pipelineStep") + assert.Equal(t, mockRpc.LastSendContainer.GroupedFdsTransfers[1].ConsumerInstanceId, "consumerId") + assert.Equal(t, mockRpc.LastSendContainer.GroupedFdsTransfers[1].Beamtime, "beamtime2") + assert.Equal(t, mockRpc.LastSendContainer.GroupedFdsTransfers[1].Source, "datasource") + assert.Equal(t, mockRpc.LastSendContainer.GroupedFdsTransfers[1].Stream, "stream") + assert.Equal(t, mockRpc.LastSendContainer.GroupedFdsTransfers[1].FileCount, uint64(1)) + assert.Equal(t, mockRpc.LastSendContainer.GroupedFdsTransfers[1].TotalTransferSendTimeInMicroseconds, uint64(401)) + assert.Equal(t, mockRpc.LastSendContainer.GroupedFdsTransfers[1].TotalFileSize, uint64(9874)) +} + +func TestSendNowErrorForwarding(t *testing.T) { + mockErrorRpc := new(mockErrorRpc) + monitoring.Sender = mockErrorRpc + monitoring.FtsName = "myFst" + + // Send one file + monitoring.SendFileTransferServiceRequest( + "consumerId", "pipelineStep", "beamtime", "datasource", "stream", + 123, 10000) + + assert.Equal(t, monitoring.sendNow().Error(), "MyMockError from Send") +} diff --git a/file_transfer/src/asapo_file_transfer/server/server.go b/file_transfer/src/asapo_file_transfer/server/server.go index 0c07eac6ff8932c2e785aebb66f2984e17782615..bd051e8a6130fd7722608226f88ce7b83f54cafc 100644 --- a/file_transfer/src/asapo_file_transfer/server/server.go +++ b/file_transfer/src/asapo_file_transfer/server/server.go @@ -1,16 +1,44 @@ package server import ( -"asapo_common/utils" + "asapo_common/utils" + "io/ioutil" + "net/http" ) type serverSettings struct { Port int LogLevel string + + DiscoveryServer string + MonitorPerformance bool + MonitoringServerUrl string + SecretFile string key string } var settings serverSettings +var monitoring brokerMonitoring var authJWT utils.Auth +type discoveryAPI struct { + Client *http.Client + baseURL string +} + +var discoveryService discoveryAPI + +func (api *discoveryAPI) GetMonitoringServerUrl() (string, error) { + resp, err := api.Client.Get(api.baseURL + "/asapo-monitoring") + if err != nil { + return "", err + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + return string(body), err +} + +func CreateDiscoveryService() { + discoveryService = discoveryAPI{&http.Client{}, "http://" + settings.DiscoveryServer} +} diff --git a/file_transfer/src/asapo_file_transfer/server/server_nottested.go b/file_transfer/src/asapo_file_transfer/server/server_nottested.go index c6472e77d64d90ebeb2d2e6e88d5a49399b48d22..afd0da5eb8d64e4c26e9c82fc1cae842ed87783f 100644 --- a/file_transfer/src/asapo_file_transfer/server/server_nottested.go +++ b/file_transfer/src/asapo_file_transfer/server/server_nottested.go @@ -8,12 +8,20 @@ import ( "asapo_common/version" "errors" "net/http" - "strconv" _ "net/http/pprof" - + "strconv" ) +func StartMonitoring() { + monitoring.Sender = new(gRPCBrokerMonitoringDataSender) + monitoring.Init() + go monitoring.RunThread() +} + func Start() { + if settings.MonitorPerformance { + StartMonitoring() + } mux := utils.NewRouter(listRoutes) log.Info("Starting ASAPO Authorizer, version " + version.GetVersion()) log.Info("Listening on port: " + strconv.Itoa(settings.Port)) diff --git a/file_transfer/src/asapo_file_transfer/server/transfer.go b/file_transfer/src/asapo_file_transfer/server/transfer.go index 9dffe4b1339814018318f456350db6125fcc44ba..3ca0db5a26d2795508233b5a8c3a24a25b93fa1a 100644 --- a/file_transfer/src/asapo_file_transfer/server/transfer.go +++ b/file_transfer/src/asapo_file_transfer/server/transfer.go @@ -11,6 +11,7 @@ import ( "os" "path" "path/filepath" + "time" ) type fileTransferRequest struct { @@ -63,11 +64,7 @@ func checkRequest(r *http.Request, ver utils.VersionNum) (string, int, error) { return "", status, err } var fullName string - if ver.Id == 1 { // protocol v0.1 - fullName = filepath.Clean(request.Folder + string(os.PathSeparator) + request.FileName) - } else { - fullName = filepath.Clean(request.Folder + string(os.PathSeparator) + request.FileName) - } + fullName = filepath.Clean(request.Folder+string(os.PathSeparator)+request.FileName) if status, err := checkFileExists(r, fullName); err != nil { return "", status, err @@ -102,9 +99,24 @@ func serveFileSize(w http.ResponseWriter, r *http.Request, fullName string) { "size": fi.Size(), }).Debug("sending file size") + + start := time.Now() + fsize.FileSize = fi.Size() b, _ := json.Marshal(&fsize) w.Write(b) + + elapsed := time.Since(start) + + instanceId := r.URL.Query().Get("instanceid") + pipelineStep := r.URL.Query().Get("pipelinestep") + beamtime := r.URL.Query().Get("beamtime") + source := r.URL.Query().Get("source") + stream := r.URL.Query().Get("stream") + if len(instanceId) > 0 && len(pipelineStep) > 0 && len(beamtime) > 0 && len(source) > 0 && len(stream) > 0 { + monitoring.SendFileTransferServiceRequest(instanceId, pipelineStep, beamtime, source, stream, + uint64(elapsed * time.Microsecond), uint64(fsize.FileSize)) + } } func checkFtsApiVersion(w http.ResponseWriter, r *http.Request) (utils.VersionNum, bool) { diff --git a/monitoring/CMakeLists.txt b/monitoring/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..5b0ceeed9c2661aa7482a3b1408b778da22573fd --- /dev/null +++ b/monitoring/CMakeLists.txt @@ -0,0 +1,2 @@ + +add_subdirectory(monitoring_server) diff --git a/monitoring/monitoring_server/CMakeLists.txt b/monitoring/monitoring_server/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..7f0ef4ed1b7b2e688af737c923d7b48313a518b6 --- /dev/null +++ b/monitoring/monitoring_server/CMakeLists.txt @@ -0,0 +1,20 @@ +set (TARGET_NAME asapo-monitoring-server) + +IF(WIN32) + set (exe_name "${TARGET_NAME}.exe") +ELSE() + set (exe_name "${TARGET_NAME}") +ENDIF() + +add_custom_target(${TARGET_NAME} ALL + COMMAND go build ${GO_OPTS} -o ${CMAKE_CURRENT_BINARY_DIR}/${exe_name} main/main.go + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/src/asapo_monitoring_server + VERBATIM) +define_property(TARGET PROPERTY EXENAME + BRIEF_DOCS <executable name> + FULL_DOCS <full-doc>) + +set_target_properties(${TARGET_NAME} PROPERTIES EXENAME ${CMAKE_CURRENT_BINARY_DIR}/${exe_name}) + +# include(testing_go) +# gotest(${TARGET_NAME} "${CMAKE_CURRENT_SOURCE_DIR}/src/asapo_monitoring_server" "./...") diff --git a/monitoring/monitoring_server/docker/Dockerfile b/monitoring/monitoring_server/docker/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..f470c616866332e2579cea319cb48e215bace0fd --- /dev/null +++ b/monitoring/monitoring_server/docker/Dockerfile @@ -0,0 +1,3 @@ +FROM busybox:glibc +ADD asapo-monitoring-server / +CMD ["/asapo-monitoring-server","-config","/var/lib/monitoring_server/config.json"] diff --git a/monitoring/monitoring_server/src/asapo_monitoring_server/.gitignore b/monitoring/monitoring_server/src/asapo_monitoring_server/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/monitoring/monitoring_server/src/asapo_monitoring_server/generate-proto.sh b/monitoring/monitoring_server/src/asapo_monitoring_server/generate-proto.sh new file mode 100755 index 0000000000000000000000000000000000000000..797e2e771cb5e167807d1c4a302e6858138b948a --- /dev/null +++ b/monitoring/monitoring_server/src/asapo_monitoring_server/generate-proto.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +set -e + +PROTO_INPUT_FOLDER=../../../../common/networking/monitoring/ +PROTO_INPUT=$PROTO_INPUT_FOLDER*.proto +PROTO_DEST=./generated_proto + +rm -rf ${PROTO_DEST} +mkdir -p ${PROTO_DEST} + +go get google.golang.org/protobuf/cmd/protoc-gen-go \ + google.golang.org/grpc/cmd/protoc-gen-go-grpc + +PATH="$PATH:$(go env GOPATH)/bin" protoc \ + --go_out=generated_proto --go_opt=paths=source_relative \ + --go-grpc_out=generated_proto --go-grpc_opt=paths=source_relative \ + -I ${PROTO_INPUT_FOLDER} \ + ${PROTO_INPUT} diff --git a/monitoring/monitoring_server/src/asapo_monitoring_server/generated_proto/AsapoMonitoringCommonService.pb.go b/monitoring/monitoring_server/src/asapo_monitoring_server/generated_proto/AsapoMonitoringCommonService.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..73a921332c5a3688c4edd12589de388d8737723e --- /dev/null +++ b/monitoring/monitoring_server/src/asapo_monitoring_server/generated_proto/AsapoMonitoringCommonService.pb.go @@ -0,0 +1,132 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.1 +// protoc v3.15.8 +// source: AsapoMonitoringCommonService.proto + +package generated_proto + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Empty struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *Empty) Reset() { + *x = Empty{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringCommonService_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Empty) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Empty) ProtoMessage() {} + +func (x *Empty) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringCommonService_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Empty.ProtoReflect.Descriptor instead. +func (*Empty) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringCommonService_proto_rawDescGZIP(), []int{0} +} + +var File_AsapoMonitoringCommonService_proto protoreflect.FileDescriptor + +var file_AsapoMonitoringCommonService_proto_rawDesc = []byte{ + 0x0a, 0x22, 0x41, 0x73, 0x61, 0x70, 0x6f, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, + 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x07, 0x0a, 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x13, 0x5a, + 0x11, 0x2e, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_AsapoMonitoringCommonService_proto_rawDescOnce sync.Once + file_AsapoMonitoringCommonService_proto_rawDescData = file_AsapoMonitoringCommonService_proto_rawDesc +) + +func file_AsapoMonitoringCommonService_proto_rawDescGZIP() []byte { + file_AsapoMonitoringCommonService_proto_rawDescOnce.Do(func() { + file_AsapoMonitoringCommonService_proto_rawDescData = protoimpl.X.CompressGZIP(file_AsapoMonitoringCommonService_proto_rawDescData) + }) + return file_AsapoMonitoringCommonService_proto_rawDescData +} + +var file_AsapoMonitoringCommonService_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_AsapoMonitoringCommonService_proto_goTypes = []interface{}{ + (*Empty)(nil), // 0: Empty +} +var file_AsapoMonitoringCommonService_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_AsapoMonitoringCommonService_proto_init() } +func file_AsapoMonitoringCommonService_proto_init() { + if File_AsapoMonitoringCommonService_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_AsapoMonitoringCommonService_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Empty); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_AsapoMonitoringCommonService_proto_rawDesc, + NumEnums: 0, + NumMessages: 1, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_AsapoMonitoringCommonService_proto_goTypes, + DependencyIndexes: file_AsapoMonitoringCommonService_proto_depIdxs, + MessageInfos: file_AsapoMonitoringCommonService_proto_msgTypes, + }.Build() + File_AsapoMonitoringCommonService_proto = out.File + file_AsapoMonitoringCommonService_proto_rawDesc = nil + file_AsapoMonitoringCommonService_proto_goTypes = nil + file_AsapoMonitoringCommonService_proto_depIdxs = nil +} diff --git a/monitoring/monitoring_server/src/asapo_monitoring_server/generated_proto/AsapoMonitoringIngestService.pb.go b/monitoring/monitoring_server/src/asapo_monitoring_server/generated_proto/AsapoMonitoringIngestService.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..f9a471f2f64dbd955a0ccda10a06163e5958eac9 --- /dev/null +++ b/monitoring/monitoring_server/src/asapo_monitoring_server/generated_proto/AsapoMonitoringIngestService.pb.go @@ -0,0 +1,1080 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.1 +// protoc v3.15.8 +// source: AsapoMonitoringIngestService.proto + +package generated_proto + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ProducerToReceiverTransferDataPoint struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PipelineStepId string `protobuf:"bytes,1,opt,name=pipelineStepId,proto3" json:"pipelineStepId,omitempty"` // Customizable from producerLib + ProducerInstanceId string `protobuf:"bytes,2,opt,name=producerInstanceId,proto3" json:"producerInstanceId,omitempty"` + Beamtime string `protobuf:"bytes,3,opt,name=beamtime,proto3" json:"beamtime,omitempty"` + Source string `protobuf:"bytes,4,opt,name=source,proto3" json:"source,omitempty"` + Stream string `protobuf:"bytes,5,opt,name=stream,proto3" json:"stream,omitempty"` + FileCount uint64 `protobuf:"varint,6,opt,name=fileCount,proto3" json:"fileCount,omitempty"` + TotalFileSize uint64 `protobuf:"varint,7,opt,name=totalFileSize,proto3" json:"totalFileSize,omitempty"` + TotalTransferReceiveTimeInMicroseconds uint64 `protobuf:"varint,8,opt,name=totalTransferReceiveTimeInMicroseconds,proto3" json:"totalTransferReceiveTimeInMicroseconds,omitempty"` + TotalWriteIoTimeInMicroseconds uint64 `protobuf:"varint,9,opt,name=totalWriteIoTimeInMicroseconds,proto3" json:"totalWriteIoTimeInMicroseconds,omitempty"` + TotalDbTimeInMicroseconds uint64 `protobuf:"varint,10,opt,name=totalDbTimeInMicroseconds,proto3" json:"totalDbTimeInMicroseconds,omitempty"` +} + +func (x *ProducerToReceiverTransferDataPoint) Reset() { + *x = ProducerToReceiverTransferDataPoint{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringIngestService_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ProducerToReceiverTransferDataPoint) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ProducerToReceiverTransferDataPoint) ProtoMessage() {} + +func (x *ProducerToReceiverTransferDataPoint) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringIngestService_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ProducerToReceiverTransferDataPoint.ProtoReflect.Descriptor instead. +func (*ProducerToReceiverTransferDataPoint) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringIngestService_proto_rawDescGZIP(), []int{0} +} + +func (x *ProducerToReceiverTransferDataPoint) GetPipelineStepId() string { + if x != nil { + return x.PipelineStepId + } + return "" +} + +func (x *ProducerToReceiverTransferDataPoint) GetProducerInstanceId() string { + if x != nil { + return x.ProducerInstanceId + } + return "" +} + +func (x *ProducerToReceiverTransferDataPoint) GetBeamtime() string { + if x != nil { + return x.Beamtime + } + return "" +} + +func (x *ProducerToReceiverTransferDataPoint) GetSource() string { + if x != nil { + return x.Source + } + return "" +} + +func (x *ProducerToReceiverTransferDataPoint) GetStream() string { + if x != nil { + return x.Stream + } + return "" +} + +func (x *ProducerToReceiverTransferDataPoint) GetFileCount() uint64 { + if x != nil { + return x.FileCount + } + return 0 +} + +func (x *ProducerToReceiverTransferDataPoint) GetTotalFileSize() uint64 { + if x != nil { + return x.TotalFileSize + } + return 0 +} + +func (x *ProducerToReceiverTransferDataPoint) GetTotalTransferReceiveTimeInMicroseconds() uint64 { + if x != nil { + return x.TotalTransferReceiveTimeInMicroseconds + } + return 0 +} + +func (x *ProducerToReceiverTransferDataPoint) GetTotalWriteIoTimeInMicroseconds() uint64 { + if x != nil { + return x.TotalWriteIoTimeInMicroseconds + } + return 0 +} + +func (x *ProducerToReceiverTransferDataPoint) GetTotalDbTimeInMicroseconds() uint64 { + if x != nil { + return x.TotalDbTimeInMicroseconds + } + return 0 +} + +type BrokerRequestDataPoint struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PipelineStepId string `protobuf:"bytes,1,opt,name=pipelineStepId,proto3" json:"pipelineStepId,omitempty"` // Customizable from consumerLib can indicates a linkage between a consumer and a producer + ConsumerInstanceId string `protobuf:"bytes,2,opt,name=consumerInstanceId,proto3" json:"consumerInstanceId,omitempty"` + Command string `protobuf:"bytes,3,opt,name=command,proto3" json:"command,omitempty"` // e.g. 'get_next', 'get_last', 'get_by_id' + Beamtime string `protobuf:"bytes,4,opt,name=beamtime,proto3" json:"beamtime,omitempty"` + Source string `protobuf:"bytes,5,opt,name=source,proto3" json:"source,omitempty"` + Stream string `protobuf:"bytes,6,opt,name=stream,proto3" json:"stream,omitempty"` + FileCount uint64 `protobuf:"varint,7,opt,name=fileCount,proto3" json:"fileCount,omitempty"` + TotalFileSize uint64 `protobuf:"varint,8,opt,name=totalFileSize,proto3" json:"totalFileSize,omitempty"` +} + +func (x *BrokerRequestDataPoint) Reset() { + *x = BrokerRequestDataPoint{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringIngestService_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BrokerRequestDataPoint) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BrokerRequestDataPoint) ProtoMessage() {} + +func (x *BrokerRequestDataPoint) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringIngestService_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BrokerRequestDataPoint.ProtoReflect.Descriptor instead. +func (*BrokerRequestDataPoint) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringIngestService_proto_rawDescGZIP(), []int{1} +} + +func (x *BrokerRequestDataPoint) GetPipelineStepId() string { + if x != nil { + return x.PipelineStepId + } + return "" +} + +func (x *BrokerRequestDataPoint) GetConsumerInstanceId() string { + if x != nil { + return x.ConsumerInstanceId + } + return "" +} + +func (x *BrokerRequestDataPoint) GetCommand() string { + if x != nil { + return x.Command + } + return "" +} + +func (x *BrokerRequestDataPoint) GetBeamtime() string { + if x != nil { + return x.Beamtime + } + return "" +} + +func (x *BrokerRequestDataPoint) GetSource() string { + if x != nil { + return x.Source + } + return "" +} + +func (x *BrokerRequestDataPoint) GetStream() string { + if x != nil { + return x.Stream + } + return "" +} + +func (x *BrokerRequestDataPoint) GetFileCount() uint64 { + if x != nil { + return x.FileCount + } + return 0 +} + +func (x *BrokerRequestDataPoint) GetTotalFileSize() uint64 { + if x != nil { + return x.TotalFileSize + } + return 0 +} + +type RdsMemoryDataPoint struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Beamtime string `protobuf:"bytes,1,opt,name=beamtime,proto3" json:"beamtime,omitempty"` + Source string `protobuf:"bytes,2,opt,name=source,proto3" json:"source,omitempty"` + Stream string `protobuf:"bytes,3,opt,name=stream,proto3" json:"stream,omitempty"` + UsedBytes uint64 `protobuf:"varint,4,opt,name=usedBytes,proto3" json:"usedBytes,omitempty"` + TotalBytes uint64 `protobuf:"varint,5,opt,name=totalBytes,proto3" json:"totalBytes,omitempty"` +} + +func (x *RdsMemoryDataPoint) Reset() { + *x = RdsMemoryDataPoint{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringIngestService_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RdsMemoryDataPoint) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RdsMemoryDataPoint) ProtoMessage() {} + +func (x *RdsMemoryDataPoint) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringIngestService_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RdsMemoryDataPoint.ProtoReflect.Descriptor instead. +func (*RdsMemoryDataPoint) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringIngestService_proto_rawDescGZIP(), []int{2} +} + +func (x *RdsMemoryDataPoint) GetBeamtime() string { + if x != nil { + return x.Beamtime + } + return "" +} + +func (x *RdsMemoryDataPoint) GetSource() string { + if x != nil { + return x.Source + } + return "" +} + +func (x *RdsMemoryDataPoint) GetStream() string { + if x != nil { + return x.Stream + } + return "" +} + +func (x *RdsMemoryDataPoint) GetUsedBytes() uint64 { + if x != nil { + return x.UsedBytes + } + return 0 +} + +func (x *RdsMemoryDataPoint) GetTotalBytes() uint64 { + if x != nil { + return x.TotalBytes + } + return 0 +} + +type RdsToConsumerDataPoint struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PipelineStepId string `protobuf:"bytes,1,opt,name=pipelineStepId,proto3" json:"pipelineStepId,omitempty"` // Customizable from consumerLib can indicates a linkage between a consumer and a producer + ConsumerInstanceId string `protobuf:"bytes,2,opt,name=consumerInstanceId,proto3" json:"consumerInstanceId,omitempty"` + Beamtime string `protobuf:"bytes,3,opt,name=beamtime,proto3" json:"beamtime,omitempty"` + Source string `protobuf:"bytes,4,opt,name=source,proto3" json:"source,omitempty"` + Stream string `protobuf:"bytes,5,opt,name=stream,proto3" json:"stream,omitempty"` + Hits uint64 `protobuf:"varint,6,opt,name=hits,proto3" json:"hits,omitempty"` + Misses uint64 `protobuf:"varint,7,opt,name=misses,proto3" json:"misses,omitempty"` + TotalFileSize uint64 `protobuf:"varint,8,opt,name=totalFileSize,proto3" json:"totalFileSize,omitempty"` + TotalTransferSendTimeInMicroseconds uint64 `protobuf:"varint,9,opt,name=totalTransferSendTimeInMicroseconds,proto3" json:"totalTransferSendTimeInMicroseconds,omitempty"` +} + +func (x *RdsToConsumerDataPoint) Reset() { + *x = RdsToConsumerDataPoint{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringIngestService_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RdsToConsumerDataPoint) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RdsToConsumerDataPoint) ProtoMessage() {} + +func (x *RdsToConsumerDataPoint) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringIngestService_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RdsToConsumerDataPoint.ProtoReflect.Descriptor instead. +func (*RdsToConsumerDataPoint) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringIngestService_proto_rawDescGZIP(), []int{3} +} + +func (x *RdsToConsumerDataPoint) GetPipelineStepId() string { + if x != nil { + return x.PipelineStepId + } + return "" +} + +func (x *RdsToConsumerDataPoint) GetConsumerInstanceId() string { + if x != nil { + return x.ConsumerInstanceId + } + return "" +} + +func (x *RdsToConsumerDataPoint) GetBeamtime() string { + if x != nil { + return x.Beamtime + } + return "" +} + +func (x *RdsToConsumerDataPoint) GetSource() string { + if x != nil { + return x.Source + } + return "" +} + +func (x *RdsToConsumerDataPoint) GetStream() string { + if x != nil { + return x.Stream + } + return "" +} + +func (x *RdsToConsumerDataPoint) GetHits() uint64 { + if x != nil { + return x.Hits + } + return 0 +} + +func (x *RdsToConsumerDataPoint) GetMisses() uint64 { + if x != nil { + return x.Misses + } + return 0 +} + +func (x *RdsToConsumerDataPoint) GetTotalFileSize() uint64 { + if x != nil { + return x.TotalFileSize + } + return 0 +} + +func (x *RdsToConsumerDataPoint) GetTotalTransferSendTimeInMicroseconds() uint64 { + if x != nil { + return x.TotalTransferSendTimeInMicroseconds + } + return 0 +} + +type FdsToConsumerDataPoint struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PipelineStepId string `protobuf:"bytes,1,opt,name=pipelineStepId,proto3" json:"pipelineStepId,omitempty"` // Customizable from consumerLib can indicates a linkage between a consumer and a producer + ConsumerInstanceId string `protobuf:"bytes,2,opt,name=consumerInstanceId,proto3" json:"consumerInstanceId,omitempty"` + Beamtime string `protobuf:"bytes,3,opt,name=beamtime,proto3" json:"beamtime,omitempty"` + Source string `protobuf:"bytes,4,opt,name=source,proto3" json:"source,omitempty"` + Stream string `protobuf:"bytes,5,opt,name=stream,proto3" json:"stream,omitempty"` + FileCount uint64 `protobuf:"varint,6,opt,name=fileCount,proto3" json:"fileCount,omitempty"` + TotalFileSize uint64 `protobuf:"varint,7,opt,name=totalFileSize,proto3" json:"totalFileSize,omitempty"` + TotalTransferSendTimeInMicroseconds uint64 `protobuf:"varint,8,opt,name=totalTransferSendTimeInMicroseconds,proto3" json:"totalTransferSendTimeInMicroseconds,omitempty"` +} + +func (x *FdsToConsumerDataPoint) Reset() { + *x = FdsToConsumerDataPoint{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringIngestService_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FdsToConsumerDataPoint) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FdsToConsumerDataPoint) ProtoMessage() {} + +func (x *FdsToConsumerDataPoint) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringIngestService_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FdsToConsumerDataPoint.ProtoReflect.Descriptor instead. +func (*FdsToConsumerDataPoint) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringIngestService_proto_rawDescGZIP(), []int{4} +} + +func (x *FdsToConsumerDataPoint) GetPipelineStepId() string { + if x != nil { + return x.PipelineStepId + } + return "" +} + +func (x *FdsToConsumerDataPoint) GetConsumerInstanceId() string { + if x != nil { + return x.ConsumerInstanceId + } + return "" +} + +func (x *FdsToConsumerDataPoint) GetBeamtime() string { + if x != nil { + return x.Beamtime + } + return "" +} + +func (x *FdsToConsumerDataPoint) GetSource() string { + if x != nil { + return x.Source + } + return "" +} + +func (x *FdsToConsumerDataPoint) GetStream() string { + if x != nil { + return x.Stream + } + return "" +} + +func (x *FdsToConsumerDataPoint) GetFileCount() uint64 { + if x != nil { + return x.FileCount + } + return 0 +} + +func (x *FdsToConsumerDataPoint) GetTotalFileSize() uint64 { + if x != nil { + return x.TotalFileSize + } + return 0 +} + +func (x *FdsToConsumerDataPoint) GetTotalTransferSendTimeInMicroseconds() uint64 { + if x != nil { + return x.TotalTransferSendTimeInMicroseconds + } + return 0 +} + +// ---- Containers ---- +type ReceiverDataPointContainer struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ReceiverName string `protobuf:"bytes,1,opt,name=receiverName,proto3" json:"receiverName,omitempty"` // Receiver InstanceId + TimestampMs uint64 `protobuf:"varint,2,opt,name=timestampMs,proto3" json:"timestampMs,omitempty"` + GroupedP2RTransfers []*ProducerToReceiverTransferDataPoint `protobuf:"bytes,3,rep,name=groupedP2rTransfers,proto3" json:"groupedP2rTransfers,omitempty"` + GroupedRds2CTransfers []*RdsToConsumerDataPoint `protobuf:"bytes,4,rep,name=groupedRds2cTransfers,proto3" json:"groupedRds2cTransfers,omitempty"` + GroupedMemoryStats []*RdsMemoryDataPoint `protobuf:"bytes,5,rep,name=groupedMemoryStats,proto3" json:"groupedMemoryStats,omitempty"` +} + +func (x *ReceiverDataPointContainer) Reset() { + *x = ReceiverDataPointContainer{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringIngestService_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ReceiverDataPointContainer) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ReceiverDataPointContainer) ProtoMessage() {} + +func (x *ReceiverDataPointContainer) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringIngestService_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ReceiverDataPointContainer.ProtoReflect.Descriptor instead. +func (*ReceiverDataPointContainer) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringIngestService_proto_rawDescGZIP(), []int{5} +} + +func (x *ReceiverDataPointContainer) GetReceiverName() string { + if x != nil { + return x.ReceiverName + } + return "" +} + +func (x *ReceiverDataPointContainer) GetTimestampMs() uint64 { + if x != nil { + return x.TimestampMs + } + return 0 +} + +func (x *ReceiverDataPointContainer) GetGroupedP2RTransfers() []*ProducerToReceiverTransferDataPoint { + if x != nil { + return x.GroupedP2RTransfers + } + return nil +} + +func (x *ReceiverDataPointContainer) GetGroupedRds2CTransfers() []*RdsToConsumerDataPoint { + if x != nil { + return x.GroupedRds2CTransfers + } + return nil +} + +func (x *ReceiverDataPointContainer) GetGroupedMemoryStats() []*RdsMemoryDataPoint { + if x != nil { + return x.GroupedMemoryStats + } + return nil +} + +type BrokerDataPointContainer struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + BrokerName string `protobuf:"bytes,1,opt,name=brokerName,proto3" json:"brokerName,omitempty"` // Broker InstanceId + TimestampMs uint64 `protobuf:"varint,2,opt,name=timestampMs,proto3" json:"timestampMs,omitempty"` + GroupedBrokerRequests []*BrokerRequestDataPoint `protobuf:"bytes,3,rep,name=groupedBrokerRequests,proto3" json:"groupedBrokerRequests,omitempty"` +} + +func (x *BrokerDataPointContainer) Reset() { + *x = BrokerDataPointContainer{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringIngestService_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BrokerDataPointContainer) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BrokerDataPointContainer) ProtoMessage() {} + +func (x *BrokerDataPointContainer) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringIngestService_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BrokerDataPointContainer.ProtoReflect.Descriptor instead. +func (*BrokerDataPointContainer) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringIngestService_proto_rawDescGZIP(), []int{6} +} + +func (x *BrokerDataPointContainer) GetBrokerName() string { + if x != nil { + return x.BrokerName + } + return "" +} + +func (x *BrokerDataPointContainer) GetTimestampMs() uint64 { + if x != nil { + return x.TimestampMs + } + return 0 +} + +func (x *BrokerDataPointContainer) GetGroupedBrokerRequests() []*BrokerRequestDataPoint { + if x != nil { + return x.GroupedBrokerRequests + } + return nil +} + +type FtsToConsumerDataPointContainer struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + FtsName string `protobuf:"bytes,1,opt,name=ftsName,proto3" json:"ftsName,omitempty"` // FTS InstanceId + TimestampMs uint64 `protobuf:"varint,2,opt,name=timestampMs,proto3" json:"timestampMs,omitempty"` + GroupedFdsTransfers []*FdsToConsumerDataPoint `protobuf:"bytes,3,rep,name=groupedFdsTransfers,proto3" json:"groupedFdsTransfers,omitempty"` +} + +func (x *FtsToConsumerDataPointContainer) Reset() { + *x = FtsToConsumerDataPointContainer{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringIngestService_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *FtsToConsumerDataPointContainer) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*FtsToConsumerDataPointContainer) ProtoMessage() {} + +func (x *FtsToConsumerDataPointContainer) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringIngestService_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use FtsToConsumerDataPointContainer.ProtoReflect.Descriptor instead. +func (*FtsToConsumerDataPointContainer) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringIngestService_proto_rawDescGZIP(), []int{7} +} + +func (x *FtsToConsumerDataPointContainer) GetFtsName() string { + if x != nil { + return x.FtsName + } + return "" +} + +func (x *FtsToConsumerDataPointContainer) GetTimestampMs() uint64 { + if x != nil { + return x.TimestampMs + } + return 0 +} + +func (x *FtsToConsumerDataPointContainer) GetGroupedFdsTransfers() []*FdsToConsumerDataPoint { + if x != nil { + return x.GroupedFdsTransfers + } + return nil +} + +var File_AsapoMonitoringIngestService_proto protoreflect.FileDescriptor + +var file_AsapoMonitoringIngestService_proto_rawDesc = []byte{ + 0x0a, 0x22, 0x41, 0x73, 0x61, 0x70, 0x6f, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, + 0x67, 0x49, 0x6e, 0x67, 0x65, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x22, 0x41, 0x73, 0x61, 0x70, 0x6f, 0x4d, 0x6f, 0x6e, 0x69, 0x74, + 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xeb, 0x03, 0x0a, 0x23, 0x50, 0x72, 0x6f, + 0x64, 0x75, 0x63, 0x65, 0x72, 0x54, 0x6f, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x54, + 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, + 0x12, 0x26, 0x0a, 0x0e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, + 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, + 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x12, 0x70, 0x72, 0x6f, 0x64, + 0x75, 0x63, 0x65, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x49, 0x6e, + 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x65, 0x61, 0x6d, + 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x65, 0x61, 0x6d, + 0x74, 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, + 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, + 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x53, + 0x69, 0x7a, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, + 0x46, 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x56, 0x0a, 0x26, 0x74, 0x6f, 0x74, 0x61, + 0x6c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, + 0x54, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, + 0x64, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x26, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x54, + 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x54, 0x69, + 0x6d, 0x65, 0x49, 0x6e, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, + 0x12, 0x46, 0x0a, 0x1e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x57, 0x72, 0x69, 0x74, 0x65, 0x49, 0x6f, + 0x54, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, + 0x64, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x1e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x57, + 0x72, 0x69, 0x74, 0x65, 0x49, 0x6f, 0x54, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x4d, 0x69, 0x63, 0x72, + 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x3c, 0x0a, 0x19, 0x74, 0x6f, 0x74, 0x61, + 0x6c, 0x44, 0x62, 0x54, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x65, + 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x19, 0x74, 0x6f, 0x74, + 0x61, 0x6c, 0x44, 0x62, 0x54, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, + 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x22, 0x9a, 0x02, 0x0a, 0x16, 0x42, 0x72, 0x6f, 0x6b, 0x65, + 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, + 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, + 0x70, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x70, 0x69, 0x70, 0x65, 0x6c, + 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x12, 0x63, 0x6f, 0x6e, + 0x73, 0x75, 0x6d, 0x65, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x49, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, + 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, + 0x61, 0x6e, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x65, 0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x65, 0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x12, + 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x72, 0x65, 0x61, + 0x6d, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, + 0x1c, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x24, 0x0a, + 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x08, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x53, + 0x69, 0x7a, 0x65, 0x22, 0x9e, 0x01, 0x0a, 0x12, 0x52, 0x64, 0x73, 0x4d, 0x65, 0x6d, 0x6f, 0x72, + 0x79, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x65, + 0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x65, + 0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x16, + 0x0a, 0x06, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1c, 0x0a, 0x09, 0x75, 0x73, 0x65, 0x64, 0x42, 0x79, + 0x74, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x75, 0x73, 0x65, 0x64, 0x42, + 0x79, 0x74, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, 0x79, 0x74, + 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, + 0x79, 0x74, 0x65, 0x73, 0x22, 0xe0, 0x02, 0x0a, 0x16, 0x52, 0x64, 0x73, 0x54, 0x6f, 0x43, 0x6f, + 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, + 0x26, 0x0a, 0x0e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x49, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, + 0x65, 0x53, 0x74, 0x65, 0x70, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x12, 0x63, 0x6f, 0x6e, 0x73, 0x75, + 0x6d, 0x65, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x49, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x65, 0x61, 0x6d, 0x74, + 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x65, 0x61, 0x6d, 0x74, + 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, + 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x72, + 0x65, 0x61, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x69, 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x04, 0x68, 0x69, 0x74, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x69, 0x73, 0x73, 0x65, + 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6d, 0x69, 0x73, 0x73, 0x65, 0x73, 0x12, + 0x24, 0x0a, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x46, 0x69, 0x6c, + 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x50, 0x0a, 0x23, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x49, 0x6e, + 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x09, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x23, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, + 0x72, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x4d, 0x69, 0x63, 0x72, 0x6f, + 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x22, 0xd2, 0x02, 0x0a, 0x16, 0x46, 0x64, 0x73, 0x54, + 0x6f, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, + 0x6e, 0x74, 0x12, 0x26, 0x0a, 0x0e, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, + 0x65, 0x70, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x70, 0x69, 0x70, 0x65, + 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x49, 0x64, 0x12, 0x2e, 0x0a, 0x12, 0x63, 0x6f, + 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, + 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x62, 0x65, + 0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x62, 0x65, + 0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x16, + 0x0a, 0x06, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x43, 0x6f, + 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x46, 0x69, 0x6c, + 0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x6f, 0x74, + 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x50, 0x0a, 0x23, 0x74, 0x6f, + 0x74, 0x61, 0x6c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x53, 0x65, 0x6e, 0x64, 0x54, + 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, + 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x23, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x69, 0x6d, 0x65, 0x49, 0x6e, + 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x22, 0xce, 0x02, 0x0a, + 0x1a, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, + 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x22, 0x0a, 0x0c, 0x72, + 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0c, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x20, 0x0a, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, + 0x73, 0x12, 0x56, 0x0a, 0x13, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x50, 0x32, 0x72, 0x54, + 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, + 0x2e, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x54, 0x6f, 0x52, 0x65, 0x63, 0x65, 0x69, + 0x76, 0x65, 0x72, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, + 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x13, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x50, 0x32, 0x72, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x12, 0x4d, 0x0a, 0x15, 0x67, 0x72, 0x6f, + 0x75, 0x70, 0x65, 0x64, 0x52, 0x64, 0x73, 0x32, 0x63, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, + 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x52, 0x64, 0x73, 0x54, 0x6f, + 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, + 0x74, 0x52, 0x15, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x52, 0x64, 0x73, 0x32, 0x63, 0x54, + 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x12, 0x43, 0x0a, 0x12, 0x67, 0x72, 0x6f, 0x75, + 0x70, 0x65, 0x64, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x73, 0x18, 0x05, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x52, 0x64, 0x73, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, + 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x12, 0x67, 0x72, 0x6f, 0x75, 0x70, + 0x65, 0x64, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x53, 0x74, 0x61, 0x74, 0x73, 0x22, 0xab, 0x01, + 0x0a, 0x18, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, + 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x1e, 0x0a, 0x0a, 0x62, 0x72, + 0x6f, 0x6b, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, + 0x62, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, 0x73, 0x12, 0x4d, 0x0a, 0x15, + 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x42, 0x72, + 0x6f, 0x6b, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x44, 0x61, 0x74, 0x61, 0x50, + 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x15, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x42, 0x72, 0x6f, + 0x6b, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x22, 0xa8, 0x01, 0x0a, 0x1f, + 0x46, 0x74, 0x73, 0x54, 0x6f, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x44, 0x61, 0x74, + 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, + 0x18, 0x0a, 0x07, 0x66, 0x74, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x66, 0x74, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x4d, 0x73, 0x12, 0x49, 0x0a, 0x13, 0x67, + 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x46, 0x64, 0x73, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, + 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x46, 0x64, 0x73, 0x54, 0x6f, + 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, + 0x74, 0x52, 0x13, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x65, 0x64, 0x46, 0x64, 0x73, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x66, 0x65, 0x72, 0x73, 0x32, 0xe3, 0x01, 0x0a, 0x1c, 0x41, 0x73, 0x61, 0x70, 0x6f, + 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x49, 0x6e, 0x67, 0x65, 0x73, 0x74, + 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x41, 0x0a, 0x18, 0x49, 0x6e, 0x73, 0x65, 0x72, + 0x74, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, + 0x6e, 0x74, 0x73, 0x12, 0x1b, 0x2e, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x44, 0x61, + 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x3d, 0x0a, 0x16, 0x49, 0x6e, + 0x73, 0x65, 0x72, 0x74, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, + 0x69, 0x6e, 0x74, 0x73, 0x12, 0x19, 0x2e, 0x42, 0x72, 0x6f, 0x6b, 0x65, 0x72, 0x44, 0x61, 0x74, + 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x1a, + 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x13, 0x49, 0x6e, 0x73, + 0x65, 0x72, 0x74, 0x46, 0x74, 0x73, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, + 0x12, 0x20, 0x2e, 0x46, 0x74, 0x73, 0x54, 0x6f, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, + 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x1a, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x13, 0x5a, 0x11, + 0x2e, 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_AsapoMonitoringIngestService_proto_rawDescOnce sync.Once + file_AsapoMonitoringIngestService_proto_rawDescData = file_AsapoMonitoringIngestService_proto_rawDesc +) + +func file_AsapoMonitoringIngestService_proto_rawDescGZIP() []byte { + file_AsapoMonitoringIngestService_proto_rawDescOnce.Do(func() { + file_AsapoMonitoringIngestService_proto_rawDescData = protoimpl.X.CompressGZIP(file_AsapoMonitoringIngestService_proto_rawDescData) + }) + return file_AsapoMonitoringIngestService_proto_rawDescData +} + +var file_AsapoMonitoringIngestService_proto_msgTypes = make([]protoimpl.MessageInfo, 8) +var file_AsapoMonitoringIngestService_proto_goTypes = []interface{}{ + (*ProducerToReceiverTransferDataPoint)(nil), // 0: ProducerToReceiverTransferDataPoint + (*BrokerRequestDataPoint)(nil), // 1: BrokerRequestDataPoint + (*RdsMemoryDataPoint)(nil), // 2: RdsMemoryDataPoint + (*RdsToConsumerDataPoint)(nil), // 3: RdsToConsumerDataPoint + (*FdsToConsumerDataPoint)(nil), // 4: FdsToConsumerDataPoint + (*ReceiverDataPointContainer)(nil), // 5: ReceiverDataPointContainer + (*BrokerDataPointContainer)(nil), // 6: BrokerDataPointContainer + (*FtsToConsumerDataPointContainer)(nil), // 7: FtsToConsumerDataPointContainer + (*Empty)(nil), // 8: Empty +} +var file_AsapoMonitoringIngestService_proto_depIdxs = []int32{ + 0, // 0: ReceiverDataPointContainer.groupedP2rTransfers:type_name -> ProducerToReceiverTransferDataPoint + 3, // 1: ReceiverDataPointContainer.groupedRds2cTransfers:type_name -> RdsToConsumerDataPoint + 2, // 2: ReceiverDataPointContainer.groupedMemoryStats:type_name -> RdsMemoryDataPoint + 1, // 3: BrokerDataPointContainer.groupedBrokerRequests:type_name -> BrokerRequestDataPoint + 4, // 4: FtsToConsumerDataPointContainer.groupedFdsTransfers:type_name -> FdsToConsumerDataPoint + 5, // 5: AsapoMonitoringIngestService.InsertReceiverDataPoints:input_type -> ReceiverDataPointContainer + 6, // 6: AsapoMonitoringIngestService.InsertBrokerDataPoints:input_type -> BrokerDataPointContainer + 7, // 7: AsapoMonitoringIngestService.InsertFtsDataPoints:input_type -> FtsToConsumerDataPointContainer + 8, // 8: AsapoMonitoringIngestService.InsertReceiverDataPoints:output_type -> Empty + 8, // 9: AsapoMonitoringIngestService.InsertBrokerDataPoints:output_type -> Empty + 8, // 10: AsapoMonitoringIngestService.InsertFtsDataPoints:output_type -> Empty + 8, // [8:11] is the sub-list for method output_type + 5, // [5:8] is the sub-list for method input_type + 5, // [5:5] is the sub-list for extension type_name + 5, // [5:5] is the sub-list for extension extendee + 0, // [0:5] is the sub-list for field type_name +} + +func init() { file_AsapoMonitoringIngestService_proto_init() } +func file_AsapoMonitoringIngestService_proto_init() { + if File_AsapoMonitoringIngestService_proto != nil { + return + } + file_AsapoMonitoringCommonService_proto_init() + if !protoimpl.UnsafeEnabled { + file_AsapoMonitoringIngestService_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ProducerToReceiverTransferDataPoint); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_AsapoMonitoringIngestService_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BrokerRequestDataPoint); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_AsapoMonitoringIngestService_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RdsMemoryDataPoint); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_AsapoMonitoringIngestService_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RdsToConsumerDataPoint); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_AsapoMonitoringIngestService_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FdsToConsumerDataPoint); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_AsapoMonitoringIngestService_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReceiverDataPointContainer); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_AsapoMonitoringIngestService_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BrokerDataPointContainer); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_AsapoMonitoringIngestService_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*FtsToConsumerDataPointContainer); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_AsapoMonitoringIngestService_proto_rawDesc, + NumEnums: 0, + NumMessages: 8, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_AsapoMonitoringIngestService_proto_goTypes, + DependencyIndexes: file_AsapoMonitoringIngestService_proto_depIdxs, + MessageInfos: file_AsapoMonitoringIngestService_proto_msgTypes, + }.Build() + File_AsapoMonitoringIngestService_proto = out.File + file_AsapoMonitoringIngestService_proto_rawDesc = nil + file_AsapoMonitoringIngestService_proto_goTypes = nil + file_AsapoMonitoringIngestService_proto_depIdxs = nil +} diff --git a/monitoring/monitoring_server/src/asapo_monitoring_server/generated_proto/AsapoMonitoringIngestService_grpc.pb.go b/monitoring/monitoring_server/src/asapo_monitoring_server/generated_proto/AsapoMonitoringIngestService_grpc.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..1176122762f618cec5eed92d1a57fa68f4d693fd --- /dev/null +++ b/monitoring/monitoring_server/src/asapo_monitoring_server/generated_proto/AsapoMonitoringIngestService_grpc.pb.go @@ -0,0 +1,174 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +package generated_proto + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// AsapoMonitoringIngestServiceClient is the client API for AsapoMonitoringIngestService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type AsapoMonitoringIngestServiceClient interface { + InsertReceiverDataPoints(ctx context.Context, in *ReceiverDataPointContainer, opts ...grpc.CallOption) (*Empty, error) + InsertBrokerDataPoints(ctx context.Context, in *BrokerDataPointContainer, opts ...grpc.CallOption) (*Empty, error) + InsertFtsDataPoints(ctx context.Context, in *FtsToConsumerDataPointContainer, opts ...grpc.CallOption) (*Empty, error) +} + +type asapoMonitoringIngestServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewAsapoMonitoringIngestServiceClient(cc grpc.ClientConnInterface) AsapoMonitoringIngestServiceClient { + return &asapoMonitoringIngestServiceClient{cc} +} + +func (c *asapoMonitoringIngestServiceClient) InsertReceiverDataPoints(ctx context.Context, in *ReceiverDataPointContainer, opts ...grpc.CallOption) (*Empty, error) { + out := new(Empty) + err := c.cc.Invoke(ctx, "/AsapoMonitoringIngestService/InsertReceiverDataPoints", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *asapoMonitoringIngestServiceClient) InsertBrokerDataPoints(ctx context.Context, in *BrokerDataPointContainer, opts ...grpc.CallOption) (*Empty, error) { + out := new(Empty) + err := c.cc.Invoke(ctx, "/AsapoMonitoringIngestService/InsertBrokerDataPoints", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *asapoMonitoringIngestServiceClient) InsertFtsDataPoints(ctx context.Context, in *FtsToConsumerDataPointContainer, opts ...grpc.CallOption) (*Empty, error) { + out := new(Empty) + err := c.cc.Invoke(ctx, "/AsapoMonitoringIngestService/InsertFtsDataPoints", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// AsapoMonitoringIngestServiceServer is the server API for AsapoMonitoringIngestService service. +// All implementations must embed UnimplementedAsapoMonitoringIngestServiceServer +// for forward compatibility +type AsapoMonitoringIngestServiceServer interface { + InsertReceiverDataPoints(context.Context, *ReceiverDataPointContainer) (*Empty, error) + InsertBrokerDataPoints(context.Context, *BrokerDataPointContainer) (*Empty, error) + InsertFtsDataPoints(context.Context, *FtsToConsumerDataPointContainer) (*Empty, error) + mustEmbedUnimplementedAsapoMonitoringIngestServiceServer() +} + +// UnimplementedAsapoMonitoringIngestServiceServer must be embedded to have forward compatible implementations. +type UnimplementedAsapoMonitoringIngestServiceServer struct { +} + +func (UnimplementedAsapoMonitoringIngestServiceServer) InsertReceiverDataPoints(context.Context, *ReceiverDataPointContainer) (*Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method InsertReceiverDataPoints not implemented") +} +func (UnimplementedAsapoMonitoringIngestServiceServer) InsertBrokerDataPoints(context.Context, *BrokerDataPointContainer) (*Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method InsertBrokerDataPoints not implemented") +} +func (UnimplementedAsapoMonitoringIngestServiceServer) InsertFtsDataPoints(context.Context, *FtsToConsumerDataPointContainer) (*Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method InsertFtsDataPoints not implemented") +} +func (UnimplementedAsapoMonitoringIngestServiceServer) mustEmbedUnimplementedAsapoMonitoringIngestServiceServer() { +} + +// UnsafeAsapoMonitoringIngestServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to AsapoMonitoringIngestServiceServer will +// result in compilation errors. +type UnsafeAsapoMonitoringIngestServiceServer interface { + mustEmbedUnimplementedAsapoMonitoringIngestServiceServer() +} + +func RegisterAsapoMonitoringIngestServiceServer(s grpc.ServiceRegistrar, srv AsapoMonitoringIngestServiceServer) { + s.RegisterService(&AsapoMonitoringIngestService_ServiceDesc, srv) +} + +func _AsapoMonitoringIngestService_InsertReceiverDataPoints_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ReceiverDataPointContainer) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AsapoMonitoringIngestServiceServer).InsertReceiverDataPoints(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/AsapoMonitoringIngestService/InsertReceiverDataPoints", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AsapoMonitoringIngestServiceServer).InsertReceiverDataPoints(ctx, req.(*ReceiverDataPointContainer)) + } + return interceptor(ctx, in, info, handler) +} + +func _AsapoMonitoringIngestService_InsertBrokerDataPoints_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(BrokerDataPointContainer) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AsapoMonitoringIngestServiceServer).InsertBrokerDataPoints(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/AsapoMonitoringIngestService/InsertBrokerDataPoints", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AsapoMonitoringIngestServiceServer).InsertBrokerDataPoints(ctx, req.(*BrokerDataPointContainer)) + } + return interceptor(ctx, in, info, handler) +} + +func _AsapoMonitoringIngestService_InsertFtsDataPoints_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(FtsToConsumerDataPointContainer) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AsapoMonitoringIngestServiceServer).InsertFtsDataPoints(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/AsapoMonitoringIngestService/InsertFtsDataPoints", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AsapoMonitoringIngestServiceServer).InsertFtsDataPoints(ctx, req.(*FtsToConsumerDataPointContainer)) + } + return interceptor(ctx, in, info, handler) +} + +// AsapoMonitoringIngestService_ServiceDesc is the grpc.ServiceDesc for AsapoMonitoringIngestService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var AsapoMonitoringIngestService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "AsapoMonitoringIngestService", + HandlerType: (*AsapoMonitoringIngestServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "InsertReceiverDataPoints", + Handler: _AsapoMonitoringIngestService_InsertReceiverDataPoints_Handler, + }, + { + MethodName: "InsertBrokerDataPoints", + Handler: _AsapoMonitoringIngestService_InsertBrokerDataPoints_Handler, + }, + { + MethodName: "InsertFtsDataPoints", + Handler: _AsapoMonitoringIngestService_InsertFtsDataPoints_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "AsapoMonitoringIngestService.proto", +} diff --git a/monitoring/monitoring_server/src/asapo_monitoring_server/generated_proto/AsapoMonitoringQueryService.pb.go b/monitoring/monitoring_server/src/asapo_monitoring_server/generated_proto/AsapoMonitoringQueryService.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..a5e1eaf6db5634718e811b73779409db8015c564 --- /dev/null +++ b/monitoring/monitoring_server/src/asapo_monitoring_server/generated_proto/AsapoMonitoringQueryService.pb.go @@ -0,0 +1,1207 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.1 +// protoc v3.15.8 +// source: AsapoMonitoringQueryService.proto + +package generated_proto + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type PipelineConnectionQueryMode int32 + +const ( + PipelineConnectionQueryMode_INVALID_QUERY_MODE PipelineConnectionQueryMode = 0 + PipelineConnectionQueryMode_ExactPath PipelineConnectionQueryMode = 1 + PipelineConnectionQueryMode_JustRelatedToStep PipelineConnectionQueryMode = 2 +) + +// Enum value maps for PipelineConnectionQueryMode. +var ( + PipelineConnectionQueryMode_name = map[int32]string{ + 0: "INVALID_QUERY_MODE", + 1: "ExactPath", + 2: "JustRelatedToStep", + } + PipelineConnectionQueryMode_value = map[string]int32{ + "INVALID_QUERY_MODE": 0, + "ExactPath": 1, + "JustRelatedToStep": 2, + } +) + +func (x PipelineConnectionQueryMode) Enum() *PipelineConnectionQueryMode { + p := new(PipelineConnectionQueryMode) + *p = x + return p +} + +func (x PipelineConnectionQueryMode) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (PipelineConnectionQueryMode) Descriptor() protoreflect.EnumDescriptor { + return file_AsapoMonitoringQueryService_proto_enumTypes[0].Descriptor() +} + +func (PipelineConnectionQueryMode) Type() protoreflect.EnumType { + return &file_AsapoMonitoringQueryService_proto_enumTypes[0] +} + +func (x PipelineConnectionQueryMode) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use PipelineConnectionQueryMode.Descriptor instead. +func (PipelineConnectionQueryMode) EnumDescriptor() ([]byte, []int) { + return file_AsapoMonitoringQueryService_proto_rawDescGZIP(), []int{0} +} + +type DataPointsQuery struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + FromTimestamp uint64 `protobuf:"varint,1,opt,name=fromTimestamp,proto3" json:"fromTimestamp,omitempty"` + ToTimestamp uint64 `protobuf:"varint,2,opt,name=toTimestamp,proto3" json:"toTimestamp,omitempty"` + BeamtimeFilter string `protobuf:"bytes,4,opt,name=beamtimeFilter,proto3" json:"beamtimeFilter,omitempty"` + SourceFilter string `protobuf:"bytes,5,opt,name=sourceFilter,proto3" json:"sourceFilter,omitempty"` + ReceiverFilter string `protobuf:"bytes,6,opt,name=receiverFilter,proto3" json:"receiverFilter,omitempty"` + FromPipelineStepFilter string `protobuf:"bytes,7,opt,name=fromPipelineStepFilter,proto3" json:"fromPipelineStepFilter,omitempty"` + ToPipelineStepFilter string `protobuf:"bytes,8,opt,name=toPipelineStepFilter,proto3" json:"toPipelineStepFilter,omitempty"` + PipelineQueryMode PipelineConnectionQueryMode `protobuf:"varint,9,opt,name=pipelineQueryMode,proto3,enum=PipelineConnectionQueryMode" json:"pipelineQueryMode,omitempty"` +} + +func (x *DataPointsQuery) Reset() { + *x = DataPointsQuery{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DataPointsQuery) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DataPointsQuery) ProtoMessage() {} + +func (x *DataPointsQuery) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DataPointsQuery.ProtoReflect.Descriptor instead. +func (*DataPointsQuery) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringQueryService_proto_rawDescGZIP(), []int{0} +} + +func (x *DataPointsQuery) GetFromTimestamp() uint64 { + if x != nil { + return x.FromTimestamp + } + return 0 +} + +func (x *DataPointsQuery) GetToTimestamp() uint64 { + if x != nil { + return x.ToTimestamp + } + return 0 +} + +func (x *DataPointsQuery) GetBeamtimeFilter() string { + if x != nil { + return x.BeamtimeFilter + } + return "" +} + +func (x *DataPointsQuery) GetSourceFilter() string { + if x != nil { + return x.SourceFilter + } + return "" +} + +func (x *DataPointsQuery) GetReceiverFilter() string { + if x != nil { + return x.ReceiverFilter + } + return "" +} + +func (x *DataPointsQuery) GetFromPipelineStepFilter() string { + if x != nil { + return x.FromPipelineStepFilter + } + return "" +} + +func (x *DataPointsQuery) GetToPipelineStepFilter() string { + if x != nil { + return x.ToPipelineStepFilter + } + return "" +} + +func (x *DataPointsQuery) GetPipelineQueryMode() PipelineConnectionQueryMode { + if x != nil { + return x.PipelineQueryMode + } + return PipelineConnectionQueryMode_INVALID_QUERY_MODE +} + +type TotalTransferRateDataPoint struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TotalBytesPerSecRecv uint64 `protobuf:"varint,1,opt,name=totalBytesPerSecRecv,proto3" json:"totalBytesPerSecRecv,omitempty"` + TotalBytesPerSecSend uint64 `protobuf:"varint,2,opt,name=totalBytesPerSecSend,proto3" json:"totalBytesPerSecSend,omitempty"` + TotalBytesPerSecRdsSend uint64 `protobuf:"varint,3,opt,name=totalBytesPerSecRdsSend,proto3" json:"totalBytesPerSecRdsSend,omitempty"` + TotalBytesPerSecFtsSend uint64 `protobuf:"varint,4,opt,name=totalBytesPerSecFtsSend,proto3" json:"totalBytesPerSecFtsSend,omitempty"` +} + +func (x *TotalTransferRateDataPoint) Reset() { + *x = TotalTransferRateDataPoint{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TotalTransferRateDataPoint) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TotalTransferRateDataPoint) ProtoMessage() {} + +func (x *TotalTransferRateDataPoint) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TotalTransferRateDataPoint.ProtoReflect.Descriptor instead. +func (*TotalTransferRateDataPoint) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringQueryService_proto_rawDescGZIP(), []int{1} +} + +func (x *TotalTransferRateDataPoint) GetTotalBytesPerSecRecv() uint64 { + if x != nil { + return x.TotalBytesPerSecRecv + } + return 0 +} + +func (x *TotalTransferRateDataPoint) GetTotalBytesPerSecSend() uint64 { + if x != nil { + return x.TotalBytesPerSecSend + } + return 0 +} + +func (x *TotalTransferRateDataPoint) GetTotalBytesPerSecRdsSend() uint64 { + if x != nil { + return x.TotalBytesPerSecRdsSend + } + return 0 +} + +func (x *TotalTransferRateDataPoint) GetTotalBytesPerSecFtsSend() uint64 { + if x != nil { + return x.TotalBytesPerSecFtsSend + } + return 0 +} + +type TotalFileRateDataPoint struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TotalRequests uint32 `protobuf:"varint,1,opt,name=totalRequests,proto3" json:"totalRequests,omitempty"` + CacheMisses uint32 `protobuf:"varint,2,opt,name=cacheMisses,proto3" json:"cacheMisses,omitempty"` + FromCache uint32 `protobuf:"varint,3,opt,name=fromCache,proto3" json:"fromCache,omitempty"` + FromDisk uint32 `protobuf:"varint,4,opt,name=fromDisk,proto3" json:"fromDisk,omitempty"` +} + +func (x *TotalFileRateDataPoint) Reset() { + *x = TotalFileRateDataPoint{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TotalFileRateDataPoint) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TotalFileRateDataPoint) ProtoMessage() {} + +func (x *TotalFileRateDataPoint) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TotalFileRateDataPoint.ProtoReflect.Descriptor instead. +func (*TotalFileRateDataPoint) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringQueryService_proto_rawDescGZIP(), []int{2} +} + +func (x *TotalFileRateDataPoint) GetTotalRequests() uint32 { + if x != nil { + return x.TotalRequests + } + return 0 +} + +func (x *TotalFileRateDataPoint) GetCacheMisses() uint32 { + if x != nil { + return x.CacheMisses + } + return 0 +} + +func (x *TotalFileRateDataPoint) GetFromCache() uint32 { + if x != nil { + return x.FromCache + } + return 0 +} + +func (x *TotalFileRateDataPoint) GetFromDisk() uint32 { + if x != nil { + return x.FromDisk + } + return 0 +} + +type TaskTimeDataPoint struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ReceiveIoTimeUs uint32 `protobuf:"varint,1,opt,name=receiveIoTimeUs,proto3" json:"receiveIoTimeUs,omitempty"` + WriteToDiskTimeUs uint32 `protobuf:"varint,2,opt,name=writeToDiskTimeUs,proto3" json:"writeToDiskTimeUs,omitempty"` + WriteToDatabaseTimeUs uint32 `protobuf:"varint,3,opt,name=writeToDatabaseTimeUs,proto3" json:"writeToDatabaseTimeUs,omitempty"` + RdsSendToConsumerTimeUs uint32 `protobuf:"varint,4,opt,name=rdsSendToConsumerTimeUs,proto3" json:"rdsSendToConsumerTimeUs,omitempty"` +} + +func (x *TaskTimeDataPoint) Reset() { + *x = TaskTimeDataPoint{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TaskTimeDataPoint) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TaskTimeDataPoint) ProtoMessage() {} + +func (x *TaskTimeDataPoint) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TaskTimeDataPoint.ProtoReflect.Descriptor instead. +func (*TaskTimeDataPoint) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringQueryService_proto_rawDescGZIP(), []int{3} +} + +func (x *TaskTimeDataPoint) GetReceiveIoTimeUs() uint32 { + if x != nil { + return x.ReceiveIoTimeUs + } + return 0 +} + +func (x *TaskTimeDataPoint) GetWriteToDiskTimeUs() uint32 { + if x != nil { + return x.WriteToDiskTimeUs + } + return 0 +} + +func (x *TaskTimeDataPoint) GetWriteToDatabaseTimeUs() uint32 { + if x != nil { + return x.WriteToDatabaseTimeUs + } + return 0 +} + +func (x *TaskTimeDataPoint) GetRdsSendToConsumerTimeUs() uint32 { + if x != nil { + return x.RdsSendToConsumerTimeUs + } + return 0 +} + +type RdsMemoryUsageDataPoint struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TotalUsedMemory uint64 `protobuf:"varint,1,opt,name=totalUsedMemory,proto3" json:"totalUsedMemory,omitempty"` //uint64 totalMemory = 2; +} + +func (x *RdsMemoryUsageDataPoint) Reset() { + *x = RdsMemoryUsageDataPoint{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RdsMemoryUsageDataPoint) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RdsMemoryUsageDataPoint) ProtoMessage() {} + +func (x *RdsMemoryUsageDataPoint) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RdsMemoryUsageDataPoint.ProtoReflect.Descriptor instead. +func (*RdsMemoryUsageDataPoint) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringQueryService_proto_rawDescGZIP(), []int{4} +} + +func (x *RdsMemoryUsageDataPoint) GetTotalUsedMemory() uint64 { + if x != nil { + return x.TotalUsedMemory + } + return 0 +} + +type DataPointsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + StartTimestampInSec uint64 `protobuf:"varint,1,opt,name=startTimestampInSec,proto3" json:"startTimestampInSec,omitempty"` + TimeIntervalInSec uint32 `protobuf:"varint,2,opt,name=timeIntervalInSec,proto3" json:"timeIntervalInSec,omitempty"` + TransferRates []*TotalTransferRateDataPoint `protobuf:"bytes,3,rep,name=transferRates,proto3" json:"transferRates,omitempty"` + FileRates []*TotalFileRateDataPoint `protobuf:"bytes,4,rep,name=fileRates,proto3" json:"fileRates,omitempty"` + TaskTimes []*TaskTimeDataPoint `protobuf:"bytes,5,rep,name=taskTimes,proto3" json:"taskTimes,omitempty"` + MemoryUsages []*RdsMemoryUsageDataPoint `protobuf:"bytes,6,rep,name=memoryUsages,proto3" json:"memoryUsages,omitempty"` +} + +func (x *DataPointsResponse) Reset() { + *x = DataPointsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DataPointsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DataPointsResponse) ProtoMessage() {} + +func (x *DataPointsResponse) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DataPointsResponse.ProtoReflect.Descriptor instead. +func (*DataPointsResponse) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringQueryService_proto_rawDescGZIP(), []int{5} +} + +func (x *DataPointsResponse) GetStartTimestampInSec() uint64 { + if x != nil { + return x.StartTimestampInSec + } + return 0 +} + +func (x *DataPointsResponse) GetTimeIntervalInSec() uint32 { + if x != nil { + return x.TimeIntervalInSec + } + return 0 +} + +func (x *DataPointsResponse) GetTransferRates() []*TotalTransferRateDataPoint { + if x != nil { + return x.TransferRates + } + return nil +} + +func (x *DataPointsResponse) GetFileRates() []*TotalFileRateDataPoint { + if x != nil { + return x.FileRates + } + return nil +} + +func (x *DataPointsResponse) GetTaskTimes() []*TaskTimeDataPoint { + if x != nil { + return x.TaskTimes + } + return nil +} + +func (x *DataPointsResponse) GetMemoryUsages() []*RdsMemoryUsageDataPoint { + if x != nil { + return x.MemoryUsages + } + return nil +} + +type MetadataResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ClusterName string `protobuf:"bytes,1,opt,name=clusterName,proto3" json:"clusterName,omitempty"` + AvailableBeamtimes []string `protobuf:"bytes,2,rep,name=availableBeamtimes,proto3" json:"availableBeamtimes,omitempty"` +} + +func (x *MetadataResponse) Reset() { + *x = MetadataResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MetadataResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MetadataResponse) ProtoMessage() {} + +func (x *MetadataResponse) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MetadataResponse.ProtoReflect.Descriptor instead. +func (*MetadataResponse) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringQueryService_proto_rawDescGZIP(), []int{6} +} + +func (x *MetadataResponse) GetClusterName() string { + if x != nil { + return x.ClusterName + } + return "" +} + +func (x *MetadataResponse) GetAvailableBeamtimes() []string { + if x != nil { + return x.AvailableBeamtimes + } + return nil +} + +type ToplogyQuery struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + FromTimestamp uint64 `protobuf:"varint,1,opt,name=fromTimestamp,proto3" json:"fromTimestamp,omitempty"` + ToTimestamp uint64 `protobuf:"varint,2,opt,name=toTimestamp,proto3" json:"toTimestamp,omitempty"` + BeamtimeFilter string `protobuf:"bytes,3,opt,name=beamtimeFilter,proto3" json:"beamtimeFilter,omitempty"` +} + +func (x *ToplogyQuery) Reset() { + *x = ToplogyQuery{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ToplogyQuery) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ToplogyQuery) ProtoMessage() {} + +func (x *ToplogyQuery) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ToplogyQuery.ProtoReflect.Descriptor instead. +func (*ToplogyQuery) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringQueryService_proto_rawDescGZIP(), []int{7} +} + +func (x *ToplogyQuery) GetFromTimestamp() uint64 { + if x != nil { + return x.FromTimestamp + } + return 0 +} + +func (x *ToplogyQuery) GetToTimestamp() uint64 { + if x != nil { + return x.ToTimestamp + } + return 0 +} + +func (x *ToplogyQuery) GetBeamtimeFilter() string { + if x != nil { + return x.BeamtimeFilter + } + return "" +} + +type TopologyResponseNode struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + NodeId string `protobuf:"bytes,1,opt,name=nodeId,proto3" json:"nodeId,omitempty"` + Level uint32 `protobuf:"varint,2,opt,name=level,proto3" json:"level,omitempty"` + ConsumerInstances []string `protobuf:"bytes,3,rep,name=consumerInstances,proto3" json:"consumerInstances,omitempty"` + ProducerInstances []string `protobuf:"bytes,4,rep,name=producerInstances,proto3" json:"producerInstances,omitempty"` +} + +func (x *TopologyResponseNode) Reset() { + *x = TopologyResponseNode{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TopologyResponseNode) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TopologyResponseNode) ProtoMessage() {} + +func (x *TopologyResponseNode) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TopologyResponseNode.ProtoReflect.Descriptor instead. +func (*TopologyResponseNode) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringQueryService_proto_rawDescGZIP(), []int{8} +} + +func (x *TopologyResponseNode) GetNodeId() string { + if x != nil { + return x.NodeId + } + return "" +} + +func (x *TopologyResponseNode) GetLevel() uint32 { + if x != nil { + return x.Level + } + return 0 +} + +func (x *TopologyResponseNode) GetConsumerInstances() []string { + if x != nil { + return x.ConsumerInstances + } + return nil +} + +func (x *TopologyResponseNode) GetProducerInstances() []string { + if x != nil { + return x.ProducerInstances + } + return nil +} + +type TopologyResponseEdge struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + FromNodeId string `protobuf:"bytes,1,opt,name=fromNodeId,proto3" json:"fromNodeId,omitempty"` + ToNodeId string `protobuf:"bytes,2,opt,name=toNodeId,proto3" json:"toNodeId,omitempty"` + SourceName string `protobuf:"bytes,3,opt,name=sourceName,proto3" json:"sourceName,omitempty"` + InvolvedReceivers []string `protobuf:"bytes,4,rep,name=involvedReceivers,proto3" json:"involvedReceivers,omitempty"` +} + +func (x *TopologyResponseEdge) Reset() { + *x = TopologyResponseEdge{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TopologyResponseEdge) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TopologyResponseEdge) ProtoMessage() {} + +func (x *TopologyResponseEdge) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TopologyResponseEdge.ProtoReflect.Descriptor instead. +func (*TopologyResponseEdge) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringQueryService_proto_rawDescGZIP(), []int{9} +} + +func (x *TopologyResponseEdge) GetFromNodeId() string { + if x != nil { + return x.FromNodeId + } + return "" +} + +func (x *TopologyResponseEdge) GetToNodeId() string { + if x != nil { + return x.ToNodeId + } + return "" +} + +func (x *TopologyResponseEdge) GetSourceName() string { + if x != nil { + return x.SourceName + } + return "" +} + +func (x *TopologyResponseEdge) GetInvolvedReceivers() []string { + if x != nil { + return x.InvolvedReceivers + } + return nil +} + +type TopologyResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Nodes []*TopologyResponseNode `protobuf:"bytes,1,rep,name=nodes,proto3" json:"nodes,omitempty"` + Edges []*TopologyResponseEdge `protobuf:"bytes,2,rep,name=edges,proto3" json:"edges,omitempty"` +} + +func (x *TopologyResponse) Reset() { + *x = TopologyResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *TopologyResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*TopologyResponse) ProtoMessage() {} + +func (x *TopologyResponse) ProtoReflect() protoreflect.Message { + mi := &file_AsapoMonitoringQueryService_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use TopologyResponse.ProtoReflect.Descriptor instead. +func (*TopologyResponse) Descriptor() ([]byte, []int) { + return file_AsapoMonitoringQueryService_proto_rawDescGZIP(), []int{10} +} + +func (x *TopologyResponse) GetNodes() []*TopologyResponseNode { + if x != nil { + return x.Nodes + } + return nil +} + +func (x *TopologyResponse) GetEdges() []*TopologyResponseEdge { + if x != nil { + return x.Edges + } + return nil +} + +var File_AsapoMonitoringQueryService_proto protoreflect.FileDescriptor + +var file_AsapoMonitoringQueryService_proto_rawDesc = []byte{ + 0x0a, 0x21, 0x41, 0x73, 0x61, 0x70, 0x6f, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, 0x72, 0x69, 0x6e, + 0x67, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x1a, 0x22, 0x41, 0x73, 0x61, 0x70, 0x6f, 0x4d, 0x6f, 0x6e, 0x69, 0x74, 0x6f, + 0x72, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x85, 0x03, 0x0a, 0x0f, 0x44, 0x61, 0x74, 0x61, + 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x51, 0x75, 0x65, 0x72, 0x79, 0x12, 0x24, 0x0a, 0x0d, 0x66, + 0x72, 0x6f, 0x6d, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x0d, 0x66, 0x72, 0x6f, 0x6d, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x12, 0x20, 0x0a, 0x0b, 0x74, 0x6f, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x74, 0x6f, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x12, 0x26, 0x0a, 0x0e, 0x62, 0x65, 0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x46, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x62, 0x65, 0x61, + 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x22, 0x0a, 0x0c, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0c, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, + 0x26, 0x0a, 0x0e, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x46, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, + 0x72, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x36, 0x0a, 0x16, 0x66, 0x72, 0x6f, 0x6d, 0x50, + 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x46, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x16, 0x66, 0x72, 0x6f, 0x6d, 0x50, 0x69, 0x70, + 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, + 0x32, 0x0a, 0x14, 0x74, 0x6f, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, + 0x70, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x14, 0x74, + 0x6f, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x74, 0x65, 0x70, 0x46, 0x69, 0x6c, + 0x74, 0x65, 0x72, 0x12, 0x4a, 0x0a, 0x11, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1c, + 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x11, 0x70, 0x69, + 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4d, 0x6f, 0x64, 0x65, 0x22, + 0xf8, 0x01, 0x0a, 0x1a, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, + 0x72, 0x52, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x32, + 0x0a, 0x14, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, 0x79, 0x74, 0x65, 0x73, 0x50, 0x65, 0x72, 0x53, + 0x65, 0x63, 0x52, 0x65, 0x63, 0x76, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x14, 0x74, 0x6f, + 0x74, 0x61, 0x6c, 0x42, 0x79, 0x74, 0x65, 0x73, 0x50, 0x65, 0x72, 0x53, 0x65, 0x63, 0x52, 0x65, + 0x63, 0x76, 0x12, 0x32, 0x0a, 0x14, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, 0x79, 0x74, 0x65, 0x73, + 0x50, 0x65, 0x72, 0x53, 0x65, 0x63, 0x53, 0x65, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x14, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, 0x79, 0x74, 0x65, 0x73, 0x50, 0x65, 0x72, 0x53, + 0x65, 0x63, 0x53, 0x65, 0x6e, 0x64, 0x12, 0x38, 0x0a, 0x17, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, + 0x79, 0x74, 0x65, 0x73, 0x50, 0x65, 0x72, 0x53, 0x65, 0x63, 0x52, 0x64, 0x73, 0x53, 0x65, 0x6e, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x17, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, 0x79, + 0x74, 0x65, 0x73, 0x50, 0x65, 0x72, 0x53, 0x65, 0x63, 0x52, 0x64, 0x73, 0x53, 0x65, 0x6e, 0x64, + 0x12, 0x38, 0x0a, 0x17, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, 0x79, 0x74, 0x65, 0x73, 0x50, 0x65, + 0x72, 0x53, 0x65, 0x63, 0x46, 0x74, 0x73, 0x53, 0x65, 0x6e, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x17, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x42, 0x79, 0x74, 0x65, 0x73, 0x50, 0x65, 0x72, + 0x53, 0x65, 0x63, 0x46, 0x74, 0x73, 0x53, 0x65, 0x6e, 0x64, 0x22, 0x9a, 0x01, 0x0a, 0x16, 0x54, + 0x6f, 0x74, 0x61, 0x6c, 0x46, 0x69, 0x6c, 0x65, 0x52, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, + 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x74, 0x6f, + 0x74, 0x61, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x63, + 0x61, 0x63, 0x68, 0x65, 0x4d, 0x69, 0x73, 0x73, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x0b, 0x63, 0x61, 0x63, 0x68, 0x65, 0x4d, 0x69, 0x73, 0x73, 0x65, 0x73, 0x12, 0x1c, 0x0a, + 0x09, 0x66, 0x72, 0x6f, 0x6d, 0x43, 0x61, 0x63, 0x68, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x09, 0x66, 0x72, 0x6f, 0x6d, 0x43, 0x61, 0x63, 0x68, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x66, + 0x72, 0x6f, 0x6d, 0x44, 0x69, 0x73, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x66, + 0x72, 0x6f, 0x6d, 0x44, 0x69, 0x73, 0x6b, 0x22, 0xdb, 0x01, 0x0a, 0x11, 0x54, 0x61, 0x73, 0x6b, + 0x54, 0x69, 0x6d, 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x28, 0x0a, + 0x0f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x49, 0x6f, 0x54, 0x69, 0x6d, 0x65, 0x55, 0x73, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x49, + 0x6f, 0x54, 0x69, 0x6d, 0x65, 0x55, 0x73, 0x12, 0x2c, 0x0a, 0x11, 0x77, 0x72, 0x69, 0x74, 0x65, + 0x54, 0x6f, 0x44, 0x69, 0x73, 0x6b, 0x54, 0x69, 0x6d, 0x65, 0x55, 0x73, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x11, 0x77, 0x72, 0x69, 0x74, 0x65, 0x54, 0x6f, 0x44, 0x69, 0x73, 0x6b, 0x54, + 0x69, 0x6d, 0x65, 0x55, 0x73, 0x12, 0x34, 0x0a, 0x15, 0x77, 0x72, 0x69, 0x74, 0x65, 0x54, 0x6f, + 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x55, 0x73, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x15, 0x77, 0x72, 0x69, 0x74, 0x65, 0x54, 0x6f, 0x44, 0x61, 0x74, + 0x61, 0x62, 0x61, 0x73, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x55, 0x73, 0x12, 0x38, 0x0a, 0x17, 0x72, + 0x64, 0x73, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x6f, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, + 0x54, 0x69, 0x6d, 0x65, 0x55, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x17, 0x72, 0x64, + 0x73, 0x53, 0x65, 0x6e, 0x64, 0x54, 0x6f, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x54, + 0x69, 0x6d, 0x65, 0x55, 0x73, 0x22, 0x43, 0x0a, 0x17, 0x52, 0x64, 0x73, 0x4d, 0x65, 0x6d, 0x6f, + 0x72, 0x79, 0x55, 0x73, 0x61, 0x67, 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, + 0x12, 0x28, 0x0a, 0x0f, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x55, 0x73, 0x65, 0x64, 0x4d, 0x65, 0x6d, + 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0f, 0x74, 0x6f, 0x74, 0x61, 0x6c, + 0x55, 0x73, 0x65, 0x64, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x22, 0xde, 0x02, 0x0a, 0x12, 0x44, + 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x30, 0x0a, 0x13, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x49, 0x6e, 0x53, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x13, + 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x49, 0x6e, + 0x53, 0x65, 0x63, 0x12, 0x2c, 0x0a, 0x11, 0x74, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, + 0x76, 0x61, 0x6c, 0x49, 0x6e, 0x53, 0x65, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, + 0x74, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x49, 0x6e, 0x53, 0x65, + 0x63, 0x12, 0x41, 0x0a, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x52, 0x61, 0x74, + 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x54, 0x6f, 0x74, 0x61, 0x6c, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x52, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, + 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x0d, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x52, + 0x61, 0x74, 0x65, 0x73, 0x12, 0x35, 0x0a, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x61, 0x74, 0x65, + 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x46, + 0x69, 0x6c, 0x65, 0x52, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, + 0x52, 0x09, 0x66, 0x69, 0x6c, 0x65, 0x52, 0x61, 0x74, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x09, 0x74, + 0x61, 0x73, 0x6b, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, + 0x2e, 0x54, 0x61, 0x73, 0x6b, 0x54, 0x69, 0x6d, 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, + 0x6e, 0x74, 0x52, 0x09, 0x74, 0x61, 0x73, 0x6b, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x12, 0x3c, 0x0a, + 0x0c, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x55, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x06, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x52, 0x64, 0x73, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x55, + 0x73, 0x61, 0x67, 0x65, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x0c, 0x6d, + 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x55, 0x73, 0x61, 0x67, 0x65, 0x73, 0x22, 0x64, 0x0a, 0x10, 0x4d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x20, 0x0a, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x2e, 0x0a, 0x12, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x42, 0x65, + 0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x61, + 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x42, 0x65, 0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x22, 0x7e, 0x0a, 0x0c, 0x54, 0x6f, 0x70, 0x6c, 0x6f, 0x67, 0x79, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x12, 0x24, 0x0a, 0x0d, 0x66, 0x72, 0x6f, 0x6d, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x66, 0x72, 0x6f, 0x6d, 0x54, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x20, 0x0a, 0x0b, 0x74, 0x6f, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x74, 0x6f, + 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x26, 0x0a, 0x0e, 0x62, 0x65, 0x61, + 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0e, 0x62, 0x65, 0x61, 0x6d, 0x74, 0x69, 0x6d, 0x65, 0x46, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x22, 0xa0, 0x01, 0x0a, 0x14, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x6f, + 0x64, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6e, 0x6f, 0x64, 0x65, + 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x2c, 0x0a, 0x11, 0x63, 0x6f, 0x6e, 0x73, + 0x75, 0x6d, 0x65, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x11, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x72, 0x49, 0x6e, 0x73, + 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x11, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, + 0x65, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x11, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x65, 0x72, 0x49, 0x6e, 0x73, 0x74, 0x61, + 0x6e, 0x63, 0x65, 0x73, 0x22, 0xa0, 0x01, 0x0a, 0x14, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, + 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x45, 0x64, 0x67, 0x65, 0x12, 0x1e, 0x0a, + 0x0a, 0x66, 0x72, 0x6f, 0x6d, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x66, 0x72, 0x6f, 0x6d, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x1a, 0x0a, + 0x08, 0x74, 0x6f, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x74, 0x6f, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2c, 0x0a, 0x11, 0x69, 0x6e, 0x76, + 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x52, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x73, 0x18, 0x04, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x11, 0x69, 0x6e, 0x76, 0x6f, 0x6c, 0x76, 0x65, 0x64, 0x52, 0x65, + 0x63, 0x65, 0x69, 0x76, 0x65, 0x72, 0x73, 0x22, 0x6c, 0x0a, 0x10, 0x54, 0x6f, 0x70, 0x6f, 0x6c, + 0x6f, 0x67, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x05, 0x6e, + 0x6f, 0x64, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x54, 0x6f, 0x70, + 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x4e, 0x6f, 0x64, + 0x65, 0x52, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x12, 0x2b, 0x0a, 0x05, 0x65, 0x64, 0x67, 0x65, + 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, + 0x67, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x45, 0x64, 0x67, 0x65, 0x52, 0x05, + 0x65, 0x64, 0x67, 0x65, 0x73, 0x2a, 0x5b, 0x0a, 0x1b, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, + 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, + 0x51, 0x55, 0x45, 0x52, 0x59, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, + 0x45, 0x78, 0x61, 0x63, 0x74, 0x50, 0x61, 0x74, 0x68, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x4a, + 0x75, 0x73, 0x74, 0x52, 0x65, 0x6c, 0x61, 0x74, 0x65, 0x64, 0x54, 0x6f, 0x53, 0x74, 0x65, 0x70, + 0x10, 0x02, 0x32, 0xb6, 0x01, 0x0a, 0x1b, 0x41, 0x73, 0x61, 0x70, 0x6f, 0x4d, 0x6f, 0x6e, 0x69, + 0x74, 0x6f, 0x72, 0x69, 0x6e, 0x67, 0x51, 0x75, 0x65, 0x72, 0x79, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x2a, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x12, 0x06, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x11, 0x2e, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x31, + 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x54, 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x12, 0x0d, 0x2e, + 0x54, 0x6f, 0x70, 0x6c, 0x6f, 0x67, 0x79, 0x51, 0x75, 0x65, 0x72, 0x79, 0x1a, 0x11, 0x2e, 0x54, + 0x6f, 0x70, 0x6f, 0x6c, 0x6f, 0x67, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x12, 0x38, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, + 0x74, 0x73, 0x12, 0x10, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x1a, 0x13, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x50, 0x6f, 0x69, 0x6e, 0x74, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x13, 0x5a, 0x11, 0x2e, + 0x2f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_AsapoMonitoringQueryService_proto_rawDescOnce sync.Once + file_AsapoMonitoringQueryService_proto_rawDescData = file_AsapoMonitoringQueryService_proto_rawDesc +) + +func file_AsapoMonitoringQueryService_proto_rawDescGZIP() []byte { + file_AsapoMonitoringQueryService_proto_rawDescOnce.Do(func() { + file_AsapoMonitoringQueryService_proto_rawDescData = protoimpl.X.CompressGZIP(file_AsapoMonitoringQueryService_proto_rawDescData) + }) + return file_AsapoMonitoringQueryService_proto_rawDescData +} + +var file_AsapoMonitoringQueryService_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_AsapoMonitoringQueryService_proto_msgTypes = make([]protoimpl.MessageInfo, 11) +var file_AsapoMonitoringQueryService_proto_goTypes = []interface{}{ + (PipelineConnectionQueryMode)(0), // 0: PipelineConnectionQueryMode + (*DataPointsQuery)(nil), // 1: DataPointsQuery + (*TotalTransferRateDataPoint)(nil), // 2: TotalTransferRateDataPoint + (*TotalFileRateDataPoint)(nil), // 3: TotalFileRateDataPoint + (*TaskTimeDataPoint)(nil), // 4: TaskTimeDataPoint + (*RdsMemoryUsageDataPoint)(nil), // 5: RdsMemoryUsageDataPoint + (*DataPointsResponse)(nil), // 6: DataPointsResponse + (*MetadataResponse)(nil), // 7: MetadataResponse + (*ToplogyQuery)(nil), // 8: ToplogyQuery + (*TopologyResponseNode)(nil), // 9: TopologyResponseNode + (*TopologyResponseEdge)(nil), // 10: TopologyResponseEdge + (*TopologyResponse)(nil), // 11: TopologyResponse + (*Empty)(nil), // 12: Empty +} +var file_AsapoMonitoringQueryService_proto_depIdxs = []int32{ + 0, // 0: DataPointsQuery.pipelineQueryMode:type_name -> PipelineConnectionQueryMode + 2, // 1: DataPointsResponse.transferRates:type_name -> TotalTransferRateDataPoint + 3, // 2: DataPointsResponse.fileRates:type_name -> TotalFileRateDataPoint + 4, // 3: DataPointsResponse.taskTimes:type_name -> TaskTimeDataPoint + 5, // 4: DataPointsResponse.memoryUsages:type_name -> RdsMemoryUsageDataPoint + 9, // 5: TopologyResponse.nodes:type_name -> TopologyResponseNode + 10, // 6: TopologyResponse.edges:type_name -> TopologyResponseEdge + 12, // 7: AsapoMonitoringQueryService.GetMetadata:input_type -> Empty + 8, // 8: AsapoMonitoringQueryService.GetTopology:input_type -> ToplogyQuery + 1, // 9: AsapoMonitoringQueryService.GetDataPoints:input_type -> DataPointsQuery + 7, // 10: AsapoMonitoringQueryService.GetMetadata:output_type -> MetadataResponse + 11, // 11: AsapoMonitoringQueryService.GetTopology:output_type -> TopologyResponse + 6, // 12: AsapoMonitoringQueryService.GetDataPoints:output_type -> DataPointsResponse + 10, // [10:13] is the sub-list for method output_type + 7, // [7:10] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name +} + +func init() { file_AsapoMonitoringQueryService_proto_init() } +func file_AsapoMonitoringQueryService_proto_init() { + if File_AsapoMonitoringQueryService_proto != nil { + return + } + file_AsapoMonitoringCommonService_proto_init() + if !protoimpl.UnsafeEnabled { + file_AsapoMonitoringQueryService_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DataPointsQuery); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_AsapoMonitoringQueryService_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TotalTransferRateDataPoint); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_AsapoMonitoringQueryService_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TotalFileRateDataPoint); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_AsapoMonitoringQueryService_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TaskTimeDataPoint); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_AsapoMonitoringQueryService_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RdsMemoryUsageDataPoint); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_AsapoMonitoringQueryService_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DataPointsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_AsapoMonitoringQueryService_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MetadataResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_AsapoMonitoringQueryService_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ToplogyQuery); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_AsapoMonitoringQueryService_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TopologyResponseNode); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_AsapoMonitoringQueryService_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TopologyResponseEdge); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_AsapoMonitoringQueryService_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*TopologyResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_AsapoMonitoringQueryService_proto_rawDesc, + NumEnums: 1, + NumMessages: 11, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_AsapoMonitoringQueryService_proto_goTypes, + DependencyIndexes: file_AsapoMonitoringQueryService_proto_depIdxs, + EnumInfos: file_AsapoMonitoringQueryService_proto_enumTypes, + MessageInfos: file_AsapoMonitoringQueryService_proto_msgTypes, + }.Build() + File_AsapoMonitoringQueryService_proto = out.File + file_AsapoMonitoringQueryService_proto_rawDesc = nil + file_AsapoMonitoringQueryService_proto_goTypes = nil + file_AsapoMonitoringQueryService_proto_depIdxs = nil +} diff --git a/monitoring/monitoring_server/src/asapo_monitoring_server/generated_proto/AsapoMonitoringQueryService_grpc.pb.go b/monitoring/monitoring_server/src/asapo_monitoring_server/generated_proto/AsapoMonitoringQueryService_grpc.pb.go new file mode 100644 index 0000000000000000000000000000000000000000..a3ac238cdfe811a76e3c447369996f5990b289aa --- /dev/null +++ b/monitoring/monitoring_server/src/asapo_monitoring_server/generated_proto/AsapoMonitoringQueryService_grpc.pb.go @@ -0,0 +1,174 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. + +package generated_proto + +import ( + context "context" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// AsapoMonitoringQueryServiceClient is the client API for AsapoMonitoringQueryService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type AsapoMonitoringQueryServiceClient interface { + GetMetadata(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*MetadataResponse, error) + GetTopology(ctx context.Context, in *ToplogyQuery, opts ...grpc.CallOption) (*TopologyResponse, error) + GetDataPoints(ctx context.Context, in *DataPointsQuery, opts ...grpc.CallOption) (*DataPointsResponse, error) +} + +type asapoMonitoringQueryServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewAsapoMonitoringQueryServiceClient(cc grpc.ClientConnInterface) AsapoMonitoringQueryServiceClient { + return &asapoMonitoringQueryServiceClient{cc} +} + +func (c *asapoMonitoringQueryServiceClient) GetMetadata(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*MetadataResponse, error) { + out := new(MetadataResponse) + err := c.cc.Invoke(ctx, "/AsapoMonitoringQueryService/GetMetadata", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *asapoMonitoringQueryServiceClient) GetTopology(ctx context.Context, in *ToplogyQuery, opts ...grpc.CallOption) (*TopologyResponse, error) { + out := new(TopologyResponse) + err := c.cc.Invoke(ctx, "/AsapoMonitoringQueryService/GetTopology", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *asapoMonitoringQueryServiceClient) GetDataPoints(ctx context.Context, in *DataPointsQuery, opts ...grpc.CallOption) (*DataPointsResponse, error) { + out := new(DataPointsResponse) + err := c.cc.Invoke(ctx, "/AsapoMonitoringQueryService/GetDataPoints", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// AsapoMonitoringQueryServiceServer is the server API for AsapoMonitoringQueryService service. +// All implementations must embed UnimplementedAsapoMonitoringQueryServiceServer +// for forward compatibility +type AsapoMonitoringQueryServiceServer interface { + GetMetadata(context.Context, *Empty) (*MetadataResponse, error) + GetTopology(context.Context, *ToplogyQuery) (*TopologyResponse, error) + GetDataPoints(context.Context, *DataPointsQuery) (*DataPointsResponse, error) + mustEmbedUnimplementedAsapoMonitoringQueryServiceServer() +} + +// UnimplementedAsapoMonitoringQueryServiceServer must be embedded to have forward compatible implementations. +type UnimplementedAsapoMonitoringQueryServiceServer struct { +} + +func (UnimplementedAsapoMonitoringQueryServiceServer) GetMetadata(context.Context, *Empty) (*MetadataResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetMetadata not implemented") +} +func (UnimplementedAsapoMonitoringQueryServiceServer) GetTopology(context.Context, *ToplogyQuery) (*TopologyResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetTopology not implemented") +} +func (UnimplementedAsapoMonitoringQueryServiceServer) GetDataPoints(context.Context, *DataPointsQuery) (*DataPointsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetDataPoints not implemented") +} +func (UnimplementedAsapoMonitoringQueryServiceServer) mustEmbedUnimplementedAsapoMonitoringQueryServiceServer() { +} + +// UnsafeAsapoMonitoringQueryServiceServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to AsapoMonitoringQueryServiceServer will +// result in compilation errors. +type UnsafeAsapoMonitoringQueryServiceServer interface { + mustEmbedUnimplementedAsapoMonitoringQueryServiceServer() +} + +func RegisterAsapoMonitoringQueryServiceServer(s grpc.ServiceRegistrar, srv AsapoMonitoringQueryServiceServer) { + s.RegisterService(&AsapoMonitoringQueryService_ServiceDesc, srv) +} + +func _AsapoMonitoringQueryService_GetMetadata_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AsapoMonitoringQueryServiceServer).GetMetadata(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/AsapoMonitoringQueryService/GetMetadata", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AsapoMonitoringQueryServiceServer).GetMetadata(ctx, req.(*Empty)) + } + return interceptor(ctx, in, info, handler) +} + +func _AsapoMonitoringQueryService_GetTopology_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ToplogyQuery) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AsapoMonitoringQueryServiceServer).GetTopology(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/AsapoMonitoringQueryService/GetTopology", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AsapoMonitoringQueryServiceServer).GetTopology(ctx, req.(*ToplogyQuery)) + } + return interceptor(ctx, in, info, handler) +} + +func _AsapoMonitoringQueryService_GetDataPoints_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DataPointsQuery) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AsapoMonitoringQueryServiceServer).GetDataPoints(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/AsapoMonitoringQueryService/GetDataPoints", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AsapoMonitoringQueryServiceServer).GetDataPoints(ctx, req.(*DataPointsQuery)) + } + return interceptor(ctx, in, info, handler) +} + +// AsapoMonitoringQueryService_ServiceDesc is the grpc.ServiceDesc for AsapoMonitoringQueryService service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var AsapoMonitoringQueryService_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "AsapoMonitoringQueryService", + HandlerType: (*AsapoMonitoringQueryServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetMetadata", + Handler: _AsapoMonitoringQueryService_GetMetadata_Handler, + }, + { + MethodName: "GetTopology", + Handler: _AsapoMonitoringQueryService_GetTopology_Handler, + }, + { + MethodName: "GetDataPoints", + Handler: _AsapoMonitoringQueryService_GetDataPoints_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "AsapoMonitoringQueryService.proto", +} diff --git a/monitoring/monitoring_server/src/asapo_monitoring_server/go.mod b/monitoring/monitoring_server/src/asapo_monitoring_server/go.mod new file mode 100644 index 0000000000000000000000000000000000000000..2f95db9a0c3777596ed833f58231c8b762058fca --- /dev/null +++ b/monitoring/monitoring_server/src/asapo_monitoring_server/go.mod @@ -0,0 +1,14 @@ +module asapo_monitoring_server + +go 1.16 + +replace asapo_common v0.0.0 => ../../../../common/go/src/asapo_common + +require ( + asapo_common v0.0.0 + github.com/golang/protobuf v1.5.2 // indirect + github.com/influxdata/influxdb-client-go/v2 v2.4.0 + google.golang.org/grpc v1.39.0 + google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 // indirect + google.golang.org/protobuf v1.27.1 +) diff --git a/monitoring/monitoring_server/src/asapo_monitoring_server/go.sum b/monitoring/monitoring_server/src/asapo_monitoring_server/go.sum new file mode 100644 index 0000000000000000000000000000000000000000..331e41d6b500712c05c73814ecee7841b29b4a9c --- /dev/null +++ b/monitoring/monitoring_server/src/asapo_monitoring_server/go.sum @@ -0,0 +1,198 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/deepmap/oapi-codegen v1.6.0 h1:w/d1ntwh91XI0b/8ja7+u5SvA4IFfM0UNNLmiDR1gg0= +github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M= +github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/influxdata/influxdb-client-go/v2 v2.4.0 h1:HGBfZYStlx3Kqvsv1h2pJixbCl/jhnFtxpKFAv9Tu5k= +github.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8= +github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 h1:W9WBk7wlPfJLvMCdtV4zPulc4uCPrlywQOmbFOhgQNU= +github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= +github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= +github.com/magefile/mage v1.10.0 h1:3HiXzCUY12kh9bIuyXShaVe529fJfyqoVM42o/uom2g= +github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/sirupsen/logrus v1.8.0 h1:nfhvjKcUMhBMVqbKHJlk5RPrrfYr/NMo3692g0dwfWU= +github.com/sirupsen/logrus v1.8.0/go.mod h1:4GuYW9TZmE769R5STWrRakJc4UqQ3+QQ95fyz7ENv1A= +github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777 h1:003p0dJM77cxMSyCPFphvZf/Y5/NXf5fzg6ufd1/Oew= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0 h1:Klz8I9kdtkIN6EpHHUOMLCYhTn/2WAe5a0s1hcBkdTI= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 h1:M1YKkFIboKNieVO5DLUEVzQfGwJD30Nv2jfUgzb5UcE= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/monitoring/monitoring_server/src/asapo_monitoring_server/local_test_config.json b/monitoring/monitoring_server/src/asapo_monitoring_server/local_test_config.json new file mode 100644 index 0000000000000000000000000000000000000000..79f98f2db36d674fbfcf55292fb927d166fe068e --- /dev/null +++ b/monitoring/monitoring_server/src/asapo_monitoring_server/local_test_config.json @@ -0,0 +1,9 @@ +{ + "ThisClusterName": "test-cluster", + + "ServerPort": 50051, + "LogLevel": "debug", + + "InfluxDbUrl": "http://127.0.0.1:8086", + "InfluxDbDatabase": "asapo_monitoring" +} diff --git a/monitoring/monitoring_server/src/asapo_monitoring_server/main/main.go b/monitoring/monitoring_server/src/asapo_monitoring_server/main/main.go new file mode 100644 index 0000000000000000000000000000000000000000..fec5bc505498518250d0cb5219af0a940b07fa45 --- /dev/null +++ b/monitoring/monitoring_server/src/asapo_monitoring_server/main/main.go @@ -0,0 +1,102 @@ +package main + +import ( + log "asapo_common/logger" + "asapo_common/utils" + "asapo_common/version" + "asapo_monitoring_server/server" + "errors" + "flag" + "io/ioutil" + "net/http" + "net/url" + "os" + "strconv" + "strings" +) + +func PrintUsage() { + log.Fatal("Usage: " + os.Args[0] + " -config <config file>") +} + +func loadConfig(configFileName string) (log.Level, server.Settings, error) { + var settings server.Settings + if err := utils.ReadJsonFromFile(configFileName, &settings); err != nil { + return log.FatalLevel, server.Settings{}, err + } + + if settings.ThisClusterName == "" { + return log.FatalLevel, server.Settings{}, errors.New("'ThisClusterName' not set") + } + + if settings.ServerPort == 0 { + return log.FatalLevel, server.Settings{}, errors.New("'ServerPort' not set") + } + + if settings.LogLevel == "" { + return log.FatalLevel, server.Settings{}, errors.New("'LogLevel' not set") + } + + if settings.InfluxDbUrl == "" { + return log.FatalLevel, server.Settings{}, errors.New("'InfluxDbUrl' not set") + } + + if settings.InfluxDbDatabase == "" { + return log.FatalLevel, server.Settings{}, errors.New("'InfluxDbDatabase' not set") + } + + logLevel, err := log.LevelFromString(settings.LogLevel) + if err != nil { + return log.FatalLevel, server.Settings{}, err + } + + return logLevel, settings, nil +} + +func main() { + var configFileName = flag.String("config", "", "config file path") + + if ret := version.ShowVersion(os.Stdout, "ASAPO Monitoring Server"); ret { + return + } + + path, err := os.Getwd() + println("oath: " + path) + + log.SetSoucre("monitoring server") + + flag.Parse() + if *configFileName == "" { + PrintUsage() + } + + logLevel, settings, err := loadConfig(*configFileName) + if err != nil { + log.Fatal(err.Error()) + return + } + + // InfluxDB 1 fix, create database + data := url.Values{} + data.Set("q", "CREATE DATABASE " + settings.InfluxDbDatabase) + + res, err := http.Post( + settings.InfluxDbUrl + "/query", "application/x-www-form-urlencoded", + strings.NewReader(data.Encode())) + + if err != nil { + log.Fatal(err.Error()) + return + } + if res.StatusCode != 200 { + rawResponse, _ := ioutil.ReadAll(res.Body) + strResponse := string(rawResponse) + + log.Fatal("failed to create database, status code was " + strconv.Itoa(res.StatusCode) + ": " + strResponse) + return + } + + log.SetLevel(logLevel) + + server.Start(settings) +} diff --git a/monitoring/monitoring_server/src/asapo_monitoring_server/server/IngestServer.go b/monitoring/monitoring_server/src/asapo_monitoring_server/server/IngestServer.go new file mode 100644 index 0000000000000000000000000000000000000000..376cbd9a1d9913b79991872f57eb024b47607208 --- /dev/null +++ b/monitoring/monitoring_server/src/asapo_monitoring_server/server/IngestServer.go @@ -0,0 +1,180 @@ +package server + +import ( + pb "asapo_common/generated_proto" + log "asapo_common/logger" + "context" + influxdb2 "github.com/influxdata/influxdb-client-go/v2" + "github.com/influxdata/influxdb-client-go/v2/api" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "time" +) + +type IngestServer struct { + pb.UnimplementedAsapoMonitoringIngestServiceServer + + settings Settings + dbWriterApi api.WriteAPI +} + +func (s *IngestServer) InsertReceiverDataPoints(ctx context.Context, data *pb.ReceiverDataPointContainer) (*pb.Empty, error) { + log.Debug("Received InsertReceiverDataPoints") + + if data.ReceiverName == "" { + return nil, status.Errorf(codes.InvalidArgument, "ReceiverName must be filled") + } + + timestamp := time.Unix(0, int64(data.TimestampMs)*int64(time.Millisecond)) + for _, dataPoint := range data.GroupedP2RTransfers { + count := dataPoint.FileCount + if count == 0 { // fix div by 0 + count = 1 + } + + p := influxdb2.NewPoint(dbMeasurementFileInput, + map[string]string{ + "receiverName": data.ReceiverName, + "pipelineStepId": dataPoint.PipelineStepId, + "producerInstanceId": dataPoint.ProducerInstanceId, + "beamtime": dataPoint.Beamtime, + "source": dataPoint.Source, + "stream": dataPoint.Stream, + }, + map[string]interface{}{ + "totalInputFileSize": int64(dataPoint.TotalFileSize), + "avgTransferReceiveTimeUs": int64(dataPoint.TotalTransferReceiveTimeInMicroseconds / count), + "avgWriteIoTimeUs": int64(dataPoint.TotalWriteIoTimeInMicroseconds / count), + "avgDbTimeUs": int64(dataPoint.TotalDbTimeInMicroseconds / count), + "receiverFileCount": int64(dataPoint.FileCount), + }, + timestamp, + ) + + s.dbWriterApi.WritePoint(p) + } + + for _, dataPoint := range data.GroupedRds2CTransfers { + count := dataPoint.Hits + if count == 0 { // fix div by 0 + count = 1 + } + p := influxdb2.NewPoint(dbMeasurementRdsFileRequests, + map[string]string{ + "receiverName": data.ReceiverName, + "pipelineStepId": dataPoint.PipelineStepId, + "consumerInstanceId": dataPoint.ConsumerInstanceId, + + "beamtime": dataPoint.Beamtime, + "source": dataPoint.Source, + "stream": dataPoint.Stream, + }, + map[string]interface{}{ + "totalRdsHits": int64(dataPoint.Hits), + "totalRdsMisses": int64(dataPoint.Misses), + "totalRdsOutputFileSize": int64(dataPoint.TotalFileSize), + "avgRdsOutputTransferTimeUs": int64(dataPoint.TotalTransferSendTimeInMicroseconds / count), + }, + timestamp, + ) + + s.dbWriterApi.WritePoint(p) + } + + for _, dataPoint := range data.GroupedMemoryStats { + p := influxdb2.NewPoint(dbMeasurementRdsCacheMemoryUsage, + map[string]string{ + "receiverName": data.ReceiverName, + + "beamtime": dataPoint.Beamtime, + "source": dataPoint.Source, + "stream": dataPoint.Stream, + }, + map[string]interface{}{ + "rdsCacheUsedBytes": int64(dataPoint.UsedBytes), + "rdsCacheTotalBytes": int64(dataPoint.TotalBytes), + }, + timestamp, + ) + + s.dbWriterApi.WritePoint(p) + } + + s.dbWriterApi.Flush() + + return &pb.Empty{}, nil +} + +func (s *IngestServer) InsertBrokerDataPoints(ctx context.Context, data *pb.BrokerDataPointContainer) (*pb.Empty, error) { + log.Debug("Received InsertBrokerDataPoints") + + if data.BrokerName == "" { + return nil, status.Errorf(codes.InvalidArgument, "BrokerName must be filled") + } + + timestamp := time.Unix(0, int64(data.TimestampMs)*int64(time.Millisecond)) + for _, dataPoint := range data.GroupedBrokerRequests { + p := influxdb2.NewPoint(dbMeasurementBrokerFileRequests, + map[string]string{ + "brokerName": data.BrokerName, + "pipelineStepId": dataPoint.PipelineStepId, + "consumerInstanceId": dataPoint.ConsumerInstanceId, + + "brokerCommand": dataPoint.Command, + + "beamtime": dataPoint.Beamtime, + "source": dataPoint.Source, + "stream": dataPoint.Stream, + }, + map[string]interface{}{ + "requestedFileCount": int64(dataPoint.FileCount), + "totalRequestedFileSize": int64(dataPoint.TotalFileSize), + }, + timestamp, + ) + + s.dbWriterApi.WritePoint(p) + } + s.dbWriterApi.Flush() + return &pb.Empty{}, nil +} + +func (s *IngestServer) InsertFtsDataPoints(ctx context.Context, data *pb.FtsToConsumerDataPointContainer) (*pb.Empty, error) { + log.Debug("Received InsertFtsDataPoints") + + if data.FtsName == "" { + return nil, status.Errorf(codes.InvalidArgument, "FtsName must be filled") + } + + timestamp := time.Unix(0, int64(data.TimestampMs)*int64(time.Millisecond)) + for _, dataPoint := range data.GroupedFdsTransfers { + + count := dataPoint.FileCount + if count == 0 { // fix div by 0 + count = 1 + } + + p := influxdb2.NewPoint(dbMeasurementFtsTransfers, + map[string]string{ + "ftsName": data.FtsName, + "pipelineStepId": dataPoint.PipelineStepId, + "consumerInstanceId": dataPoint.ConsumerInstanceId, + + "beamtime": dataPoint.Beamtime, + "source": dataPoint.Source, + "stream": dataPoint.Stream, + }, + map[string]interface{}{ + "ftsFileCount": int64(dataPoint.FileCount), + "totalFtsTransferredFileSize": int64(dataPoint.TotalFileSize), + "avgTransferSendTimeUs": int64(dataPoint.TotalTransferSendTimeInMicroseconds / count), + }, + timestamp, + ) + + s.dbWriterApi.WritePoint(p) + } + + s.dbWriterApi.Flush() + return &pb.Empty{}, nil +} diff --git a/monitoring/monitoring_server/src/asapo_monitoring_server/server/QueryServer.go b/monitoring/monitoring_server/src/asapo_monitoring_server/server/QueryServer.go new file mode 100644 index 0000000000000000000000000000000000000000..e35fd11ab803c65d94b3243b3d45e730b9615d86 --- /dev/null +++ b/monitoring/monitoring_server/src/asapo_monitoring_server/server/QueryServer.go @@ -0,0 +1,676 @@ +package server + +import ( + pb "asapo_common/generated_proto" + log "asapo_common/logger" + "context" + "errors" + "fmt" + "github.com/influxdata/influxdb-client-go/v2/api" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" + "strconv" + "strings" +) + +type QueryServer struct { + pb.UnimplementedAsapoMonitoringQueryServiceServer + + settings Settings + dbQueryApi api.QueryAPI +} + +func (s *QueryServer) GetMetadata(ctx context.Context, _ *pb.Empty) (*pb.MetadataResponse, error) { + result, err := s.dbQueryApi.Query(ctx, "" + + "tagValues = (bucket, tag, predicate=(r) => true, start=-30d) =>\n" + + " from(bucket: bucket)\n" + + " |> range(start: start)\n" + + " |> filter(fn: predicate)\n" + + " |> keep(columns: [tag])\n" + + " |> group()\n" + + " |> distinct(column: tag)"+ + "tagValues(bucket: \""+s.settings.InfluxDbDatabase+"\", tag: \"beamtime\", predicate: (r) => true, start: -30d)") + + // InfluxDB2 + // result, err := s.dbQueryApi.Query(ctx, "import \"influxdata/influxdb/schema\"\n"+ + // "schema.tagValues(bucket: \""+s.settings.InfluxDbDatabase+"\", tag: \"beamtime\", predicate: (r) => true, start: -30d)") + + if err != nil { + return nil, err + } + + response := pb.MetadataResponse{} + for result.Next() { + response.AvailableBeamtimes = append(response.AvailableBeamtimes, result.Record().Values()["_value"].(string)) + } + response.ClusterName = s.settings.ThisClusterName + + return &response, nil +} + +func createFilterElement(tagName string, tagValue string) string { + return "r[\"" + tagName + "\"] == \""+tagValue+"\"" +} +type filterGenerator func(*pb.DataPointsQuery) string + +func createFilter(query *pb.DataPointsQuery, generator filterGenerator) string { + // always present in database: beamtime, source + filter := " |> filter(fn: (r) => " + filter += createFilterElement("beamtime", query.BeamtimeFilter) + if query.SourceFilter != "" { + filter += " and " + createFilterElement("source", query.SourceFilter) + } + + filter += generator(query) + + filter += ")" + + return filter +} + +func transferSpeedFilterGenerator(query *pb.DataPointsQuery) string { + filter := "" + + if query.ReceiverFilter != "" { + filter += " and " + createFilterElement("receiverName", query.ReceiverFilter) + } + if query.FromPipelineStepFilter != "" && query.ToPipelineStepFilter != "" { + if query.PipelineQueryMode == pb.PipelineConnectionQueryMode_ExactPath { + filter += " and (" + + // From: receiver + "(r._measurement == \"" + dbMeasurementFileInput + "\" and " + createFilterElement("pipelineStepId", query.FromPipelineStepFilter) + ")" + + " or " + + // To: broker or RDS or FTS + "((r._measurement == \"" + dbMeasurementBrokerFileRequests + "\" or r._measurement == \"" + dbMeasurementRdsFileRequests + "\" or r._measurement == \"" + dbMeasurementFtsTransfers + "\") and " + createFilterElement("pipelineStepId", query.ToPipelineStepFilter) + ")" + + ")" + } else if query.PipelineQueryMode == pb.PipelineConnectionQueryMode_JustRelatedToStep { + // Direction is ignored here. Just check if piplineStepId is different + if query.FromPipelineStepFilter == query.ToPipelineStepFilter { + // from and to are the same + filter += " and " + createFilterElement("pipelineStepId", query.FromPipelineStepFilter) + } else { + filter += " and (" + + createFilterElement("pipelineStepId", query.FromPipelineStepFilter) + + " or " + + createFilterElement("pipelineStepId", query.ToPipelineStepFilter) + } + } + } + + return filter +} + +func transferRateFilterGenerator(query *pb.DataPointsQuery) string { + filter := "" + + if query.ReceiverFilter != "" { + filter += " and " + createFilterElement("receiverName", query.ReceiverFilter) + } + if query.FromPipelineStepFilter != "" { + filter += " and " + createFilterElement("pipelineStepId", query.FromPipelineStepFilter) + } + + return filter +} + +func taskTimeFilterGenerator(query *pb.DataPointsQuery) string { + filter := "" + + if query.ReceiverFilter != "" { + filter += " and " + createFilterElement("receiverName", query.ReceiverFilter) + } + if query.PipelineQueryMode == pb.PipelineConnectionQueryMode_ExactPath { + filter += " and (" + + // From: receiver + "(r._measurement == \"" + dbMeasurementFileInput + "\" and " + createFilterElement("pipelineStepId", query.FromPipelineStepFilter) + ")" + + " or " + + // To: RDS or FTS + "((r._measurement == \"" + dbMeasurementRdsFileRequests + "\" or r._measurement == \"" + dbMeasurementFtsTransfers + "\") and " + createFilterElement("pipelineStepId", query.ToPipelineStepFilter) + ")" + + ")" + } else if query.PipelineQueryMode == pb.PipelineConnectionQueryMode_JustRelatedToStep { + // Direction is ignored here. Just check if piplineStepId is different + if query.FromPipelineStepFilter == query.ToPipelineStepFilter { + // from and to are the same + filter += " and " + createFilterElement("pipelineStepId", query.FromPipelineStepFilter) + } else { + filter += " and (" + + createFilterElement("pipelineStepId", query.FromPipelineStepFilter) + + " or " + + createFilterElement("pipelineStepId", query.ToPipelineStepFilter) + } + } + + return filter +} + +func memoryUsageFilterGenerator(query *pb.DataPointsQuery) string { + filter := "" + + if query.ReceiverFilter != "" { + filter += " and " + createFilterElement("receiverName", query.ReceiverFilter) + } + + return filter +} + +// Checks if the string contains any characters that normally should not appear and +// that might interfere with InfluxDb2 Query +func doesStringContainsDangerousElements(input string) bool { + // ref: https://github.com/influxdata/influxdb-client-js/blob/v1.15.0/packages/core/src/query/flux.ts#L40-L99 + return strings.Contains(input, "\"") || + strings.Contains(input, "\n") || + strings.Contains(input, "\r") || + strings.Contains(input, "\\") || + strings.Contains(input, "$") || + strings.Contains(input, "{") || + strings.Contains(input, "}") +} + +func (s *QueryServer) GetDataPoints(ctx context.Context, query *pb.DataPointsQuery) (*pb.DataPointsResponse, error) { + startTime := strconv.FormatUint(query.FromTimestamp, 10) + endTime := strconv.FormatUint(query.ToTimestamp, 10) + intervalInSec := 5 + + + if query.BeamtimeFilter == "" { + return nil, status.Errorf(codes.InvalidArgument, "Beamtime is required") + } + + // InfluxDB 2 does not really support input parameters. So the best attempt is to + // if any from them include '"' or '\' throw an error + if doesStringContainsDangerousElements(query.BeamtimeFilter) || + doesStringContainsDangerousElements(query.FromPipelineStepFilter) || + doesStringContainsDangerousElements(query.ToPipelineStepFilter) || + doesStringContainsDangerousElements(query.ReceiverFilter) || + doesStringContainsDangerousElements(query.SourceFilter) { + return nil, errors.New("some input characters are not allowed") + } + + response := pb.DataPointsResponse{} + + transferSpeedFilter := createFilter(query, transferSpeedFilterGenerator) + transferSpeed, err := queryTransferSpeed(s, ctx, startTime, endTime, intervalInSec, transferSpeedFilter) + if err != nil { + return nil, err + } + response.TransferRates = transferSpeed + + fileRateFilter := createFilter(query, transferRateFilterGenerator) + fileRates, err := queryFileRate(s, ctx, startTime, endTime, intervalInSec, fileRateFilter) + if err != nil { + return nil, err + } + response.FileRates = fileRates + + taskTimeFilter := createFilter(query, taskTimeFilterGenerator) + taskTime, err := queryTaskTime(s, ctx, startTime, endTime, intervalInSec, taskTimeFilter) + if err != nil { + return nil, err + } + response.TaskTimes = taskTime + + memoryUsageFilter := createFilter(query, memoryUsageFilterGenerator) + memoryUsage, err := queryMemoryUsage(s, ctx, startTime, endTime, intervalInSec, memoryUsageFilter) + if err != nil { + return nil, err + } + response.MemoryUsages = memoryUsage + + response.StartTimestampInSec = query.FromTimestamp // TODO: Use first timestamp from query result + response.TimeIntervalInSec = uint32(intervalInSec) + + return &response, nil +} + +func queryTransferSpeed(s *QueryServer, ctx context.Context, startTime string, endTime string, intervalInSec int, filter string) ([]*pb.TotalTransferRateDataPoint, error) { + var arrayResult []*pb.TotalTransferRateDataPoint + + result, err := s.dbQueryApi.Query(ctx, "from(bucket: \""+s.settings.InfluxDbDatabase+"\")"+ + " |> range(start: "+startTime+", stop: "+endTime+")"+ + " |> filter(fn: (r) => r._measurement == \""+dbMeasurementFileInput+"\" or r._measurement == \""+dbMeasurementBrokerFileRequests+"\" or r._measurement == \""+dbMeasurementRdsFileRequests+"\" or r._measurement == \""+dbMeasurementFtsTransfers+"\")"+ + " |> filter(fn: (r) => r._field == \"totalInputFileSize\" or r._field == \"totalRequestedFileSize\" or r._field == \"totalRdsOutputFileSize\" or r._field == \"totalFtsTransferredFileSize\")"+ + filter + + " |> group(columns: [\"_field\"])"+ + " |> aggregateWindow(every: "+strconv.Itoa(intervalInSec)+"s, fn: sum, createEmpty: true)"+ + " |> pivot(rowKey:[\"_time\"], columnKey: [\"_field\"], valueColumn: \"_value\")", + ) + + if err != nil { + return nil, err + } + + for result.Next() { + recvBytes := int64(0) + sendBytes := int64(0) + sendRdsBytes := int64(0) + sendFtsBytes := int64(0) + + if result.Record().Values()["totalInputFileSize"] != nil { + recvBytes = result.Record().Values()["totalInputFileSize"].(int64) + } + if result.Record().Values()["totalRequestedFileSize"] != nil { + sendBytes = result.Record().Values()["totalRequestedFileSize"].(int64) + } + if result.Record().Values()["totalRdsOutputFileSize"] != nil { + sendRdsBytes = result.Record().Values()["totalRdsOutputFileSize"].(int64) + } + if result.Record().Values()["totalFtsTransferredFileSize"] != nil { + sendFtsBytes = result.Record().Values()["totalFtsTransferredFileSize"].(int64) + } + + arrayResult = append(arrayResult, &pb.TotalTransferRateDataPoint{ + TotalBytesPerSecRecv: uint64(recvBytes) / uint64(intervalInSec), + TotalBytesPerSecSend: uint64(sendBytes) / uint64(intervalInSec), + TotalBytesPerSecRdsSend: uint64(sendRdsBytes) / uint64(intervalInSec), + TotalBytesPerSecFtsSend: uint64(sendFtsBytes) / uint64(intervalInSec), + }) + } + + if result.Err() != nil { + return nil, result.Err() + } + + return arrayResult, nil +} + +func queryFileRate(s *QueryServer, ctx context.Context, startTime string, endTime string, intervalInSec int, filter string) ([]*pb.TotalFileRateDataPoint, error) { + var arrayResult []*pb.TotalFileRateDataPoint + + rdsResponses, err := s.dbQueryApi.Query(ctx, "from(bucket: \""+s.settings.InfluxDbDatabase+"\")"+ + " |> range(start: "+startTime+", stop: "+endTime+")"+ + " |> filter(fn: (r) => r._measurement == \""+dbMeasurementRdsFileRequests+"\" or r._measurement == \""+dbMeasurementBrokerFileRequests+"\" or r._measurement == \""+dbMeasurementFtsTransfers+"\")"+ + " |> filter(fn: (r) => r._field == \"totalRdsHits\" or r._field == \"totalRdsMisses\" or r._field == \"requestedFileCount\" or r._field == \"ftsFileCount\")"+ + filter + + " |> group(columns: [\"_field\"])"+ + " |> aggregateWindow(every: "+strconv.Itoa(intervalInSec)+"s, fn: sum, createEmpty: true)"+ + " |> pivot(rowKey:[\"_time\"], columnKey: [\"_field\"], valueColumn: \"_value\")", + ) + if err != nil { + return nil, err + } + + for rdsResponses.Next() { + totalRequests := uint32(0) + hit := uint32(0) + miss := uint32(0) + fromDisk := uint32(0) + + if rdsResponses.Record().Values()["requestedFileCount"] != nil { + totalRequests = uint32(rdsResponses.Record().Values()["requestedFileCount"].(int64)) + } + if rdsResponses.Record().Values()["totalRdsHits"] != nil { + hit = uint32(rdsResponses.Record().Values()["totalRdsHits"].(int64)) + } + if rdsResponses.Record().Values()["totalRdsMisses"] != nil { + miss = uint32(rdsResponses.Record().Values()["totalRdsMisses"].(int64)) + } + if rdsResponses.Record().Values()["ftsFileCount"] != nil { + fromDisk = uint32(rdsResponses.Record().Values()["ftsFileCount"].(int64)) + } + + arrayResult = append(arrayResult, &pb.TotalFileRateDataPoint{ + TotalRequests: totalRequests, + CacheMisses: miss, + FromCache: hit, + FromDisk: fromDisk, + }) + } + + if rdsResponses.Err() != nil { + return nil, rdsResponses.Err() + } + + return arrayResult, nil +} + +func queryTaskTime(s *QueryServer, ctx context.Context, startTime string, endTime string, intervalInSec int, filter string) ([]*pb.TaskTimeDataPoint, error) { + var arrayResult []*pb.TaskTimeDataPoint + + result, err := s.dbQueryApi.Query(ctx, "from(bucket: \""+s.settings.InfluxDbDatabase+"\")"+ + " |> range(start: "+startTime+", stop: "+endTime+")"+ + " |> filter(fn: (r) => r._measurement == \""+dbMeasurementFileInput+"\" or r._measurement == \""+dbMeasurementRdsFileRequests+"\")"+ + " |> filter(fn: (r) => r._field == \"avgTransferReceiveTimeUs\" or r._field == \"avgWriteIoTimeUs\" or r._field == \"avgDbTimeUs\" or r._field == \"avgRdsOutputTransferTimeUs\")"+ + filter + + " |> group(columns: [\"_field\"])"+ + " |> aggregateWindow(every: "+strconv.Itoa(intervalInSec)+"s, fn: mean, createEmpty: true)"+ + " |> pivot(rowKey:[\"_time\"], columnKey: [\"_field\"], valueColumn: \"_value\")", + ) + if err != nil { + return nil, err + } + + for result.Next() { + receiveIoTimeUs := float64(0) + writeToDiskTimeUs := float64(0) + writeToDatabaseTimeUs := float64(0) + rdsOutputTransferTimeUs := float64(0) + + if result.Record().Values()["avgTransferReceiveTimeUs"] != nil { + receiveIoTimeUs = result.Record().Values()["avgTransferReceiveTimeUs"].(float64) + } + if result.Record().Values()["avgWriteIoTimeUs"] != nil { + writeToDiskTimeUs = result.Record().Values()["avgWriteIoTimeUs"].(float64) + } + if result.Record().Values()["avgDbTimeUs"] != nil { + writeToDatabaseTimeUs = result.Record().Values()["avgDbTimeUs"].(float64) + } + if result.Record().Values()["avgRdsOutputTransferTimeUs"] != nil { + rdsOutputTransferTimeUs = result.Record().Values()["avgRdsOutputTransferTimeUs"].(float64) + } + + arrayResult = append(arrayResult, &pb.TaskTimeDataPoint{ + ReceiveIoTimeUs: uint32(receiveIoTimeUs), + WriteToDiskTimeUs: uint32(writeToDiskTimeUs), + WriteToDatabaseTimeUs: uint32(writeToDatabaseTimeUs), + RdsSendToConsumerTimeUs: uint32(rdsOutputTransferTimeUs), + }) + } + + if result.Err() != nil { + return nil, result.Err() + } + + return arrayResult, nil +} + +func queryMemoryUsage(s *QueryServer, ctx context.Context, startTime string, endTime string, intervalInSec int, filter string) ([]*pb.RdsMemoryUsageDataPoint, error) { + var arrayResult []*pb.RdsMemoryUsageDataPoint + + result, err := s.dbQueryApi.Query(ctx, "from(bucket: \""+s.settings.InfluxDbDatabase+"\")"+ + " |> range(start: "+startTime+", stop: "+endTime+")"+ + " |> filter(fn: (r) => r._measurement == \""+dbMeasurementRdsCacheMemoryUsage+"\")"+ + " |> filter(fn: (r) => r._field == \"rdsCacheUsedBytes\")"+ + filter + + " |> group(columns: [\"_field\"])"+ + " |> aggregateWindow(every: "+strconv.Itoa(intervalInSec)+"s, fn: sum, createEmpty: true)"+ + " |> pivot(rowKey:[\"_time\"], columnKey: [\"_field\"], valueColumn: \"_value\")", + ) + if err != nil { + return nil, err + } + + for result.Next() { + usedBytes := int64(0) + + if result.Record().Values()["rdsCacheUsedBytes"] != nil { + usedBytes = result.Record().Values()["rdsCacheUsedBytes"].(int64) + } + + arrayResult = append(arrayResult, &pb.RdsMemoryUsageDataPoint{ + TotalUsedMemory: uint64(usedBytes), + }) + } + + if result.Err() != nil { + return nil, result.Err() + } + + return arrayResult, nil +} + +func (s *QueryServer) GetTopology(ctx context.Context, query *pb.ToplogyQuery) (*pb.TopologyResponse, error) { + if doesStringContainsDangerousElements(query.BeamtimeFilter) { + return nil, errors.New("some input characters are not allowed") + } + + startTime := strconv.FormatUint(query.FromTimestamp, 10) + endTime := strconv.FormatUint(query.ToTimestamp, 10) + + result, err := s.dbQueryApi.Query(ctx, "from(bucket: \""+s.settings.InfluxDbDatabase+"\")"+ + " |> range(start: "+startTime+", stop: "+endTime+")"+ + " |> filter(fn: (r) => r._measurement == \""+dbMeasurementFileInput+"\" or r._measurement == \""+dbMeasurementBrokerFileRequests+"\")" + + " |> filter(fn: (r) => " + createFilterElement("beamtime", query.BeamtimeFilter) + ")" + + " |> keep(columns: [\"receiverName\", \"brokerName\", \"pipelineStepId\", \"source\", \"producerInstanceId\", \"consumerInstanceId\"])" + + " |> group()", + ) + + if err != nil { + fmt.Printf("Error: %v\n", err) + return nil, err + } + + type PipelineStep struct { // these maps here are replacements for HashSets + producesSourceId map[string] /*produces sourceId*/ bool + consumesSourceId map[string] /*consumers sourceId*/ bool + + producerInstances map[string] /*produces instanceId*/ bool + consumerInstances map[string] /*consumers instanceId*/ bool + + involvedReceivers map[string] /*receiver id*/ bool + } + + pipelineSteps := map[string] /*pipelineStepId*/ PipelineStep{} + + getOrCreateStep := func(stepId string) PipelineStep { + if _, containsKey := pipelineSteps[stepId]; !containsKey { + pipelineSteps[stepId] = PipelineStep{ + producesSourceId: map[string] /*produces sourceId*/ bool{}, + consumesSourceId: map[string] /*consumers sourceId*/ bool{}, + producerInstances: map[string] /*produces instanceId*/ bool{}, + consumerInstances: map[string] /*consumers instanceId*/ bool{}, + involvedReceivers: map[string] /*receiver id*/ bool{}, + } + } + return pipelineSteps[stepId] + } + + for result.Next() { + if result.Record().Values()["receiverName"] != nil { // data is coming from receiver => means it must be a producer + stepId,ok := result.Record().Values()["pipelineStepId"].(string) + if !ok { + stepId = "defaultStep" + } + source := result.Record().Values()["source"].(string) + producerInstanceId := result.Record().Values()["producerInstanceId"].(string) + var step = getOrCreateStep(stepId) + step.producesSourceId[source] = true + step.producerInstances[producerInstanceId] = true + var receiverName = result.Record().Values()["receiverName"].(string) + step.involvedReceivers[receiverName] = true + } else if result.Record().Values()["brokerName"] != nil { // data is coming from broker => means it must be a consumer + stepId := result.Record().Values()["pipelineStepId"].(string) + source := result.Record().Values()["source"].(string) + consumerInstanceId := result.Record().Values()["consumerInstanceId"].(string) + var step = getOrCreateStep(stepId) + step.consumesSourceId[source] = true + step.consumerInstances[consumerInstanceId] = true + } else { + log.Debug("Got an entry without receiverName or brokerName") + } + } + + type PipelineLevelStepInfo struct { + stepId string + } + + type PipelineEdgeInfo struct { + fromStepId string + toStepId string + sourceId string + involvedReceivers map[string] /*receiver id*/ bool + } + + // Simple algorithm + // Goes through each remainingStepIds and checks if all consumesSourceIds of this step is available + // If all consuming sources are available + // add it to the current level + // add all connecting edges + // and producing sources to availableSourcesInNextLevel + // If not go to next step, which might produces this + // When an iteration of remainingStepIds is done: + // Add all new producing sources to availableSources + // Go to next level + remainingStepIds := map[string] /*pipelineStepId*/ bool{} + availableSources := map[string] /*sourceId*/ [] /* available from pipelineStepId */ string{} + + for stepId, _ := range pipelineSteps { + remainingStepIds[stepId] = true + } + + var levels [] /*levelDepth*/ [] /*verticalIdx*/ PipelineLevelStepInfo + var edges []PipelineEdgeInfo + var currentLevel = -1 + + for len(remainingStepIds) > 0 { + currentLevel++ + levels = append(levels, []PipelineLevelStepInfo{}) + + var foundAtLeastOne = false + availableSourcesInNextLevel := map[string] /*sourceId*/ [] /* available from pipelineStepId */ string{} + for stepId := range remainingStepIds { + var allConsumingSourcesAvailable = true + for requiredSourceId := range pipelineSteps[stepId].consumesSourceId { + if _, sourceIsAvailable := availableSources[requiredSourceId]; !sourceIsAvailable { // Oh source is unavailable + allConsumingSourcesAvailable = false + } else { + // Verify that no other producer can create this source. + // Maybe we have to wait one or two steps until all producers are available + for stepId2 := range remainingStepIds { + if _, thereIsAnotherProducer := pipelineSteps[stepId2].producesSourceId[requiredSourceId]; thereIsAnotherProducer { + if stepId == stepId2 { + continue // The pipeline has self reference?! allow it + } + allConsumingSourcesAvailable = false + } + } + } + if !allConsumingSourcesAvailable { + break // We don't even need to try the other options + } + } + + if allConsumingSourcesAvailable { + foundAtLeastOne = true + stepInfo := pipelineSteps[stepId] + + // Add edge connection + for consumingSourceId := range stepInfo.consumesSourceId { + if stepInfo.producesSourceId[consumingSourceId] { // Add self reference edge + edges = append(edges, PipelineEdgeInfo{ + fromStepId: stepId, + toStepId: stepId, + sourceId: consumingSourceId, + involvedReceivers: stepInfo.involvedReceivers, + }) + } + for _, sourceIdAvailableFromStepId := range availableSources[consumingSourceId] { // Add all the others edges + var producingSource = pipelineSteps[sourceIdAvailableFromStepId] + edges = append(edges, PipelineEdgeInfo{ + fromStepId: sourceIdAvailableFromStepId, + toStepId: stepId, + sourceId: consumingSourceId, + involvedReceivers: producingSource.involvedReceivers, + }) + } + } + + // prepare sources for next level + for sourceId := range stepInfo.producesSourceId { + if _, sourceIsAvailable := availableSourcesInNextLevel[sourceId]; !sourceIsAvailable { + availableSourcesInNextLevel[sourceId] = nil + } + + availableSourcesInNextLevel[sourceId] = append(availableSourcesInNextLevel[sourceId], stepId) + } + + levels[currentLevel] = append(levels[currentLevel], PipelineLevelStepInfo{ + stepId: stepId, + }) + + delete(remainingStepIds, stepId) + } + } + + if !foundAtLeastOne { + // probably only requests of files came, but no receiver registered a producer + // log.Error("infinite loop while building topology tree; Still has pipeline steps but found no way how to connect them") + // return nil, errors.New("infinite loop while building topology tree; Still has pipeline steps but found no way how to connect them") + + var unkStep = "Unknown" + + pipelineSteps[unkStep] = PipelineStep{ + producesSourceId: nil, + consumesSourceId: nil, + producerInstances: nil, + consumerInstances: nil, + involvedReceivers: nil, + } + + levels[0] = append(levels[0], PipelineLevelStepInfo{ + stepId: unkStep, + }) + + if len(levels) < 2 { + levels = append(levels, []PipelineLevelStepInfo{}) + } + + for stepId := range remainingStepIds { + var step = pipelineSteps[stepId] + levels[1] = append(levels[1], PipelineLevelStepInfo{ + stepId: stepId, + }) + + for sourceId := range step.consumesSourceId { + edges = append(edges, PipelineEdgeInfo{ + fromStepId: unkStep, + toStepId: stepId, + sourceId: sourceId, + involvedReceivers: nil, + }) + } + } + + break // Go to response building + } + + for sourceId, element := range availableSourcesInNextLevel { + if _, sourceIsAvailable := availableSources[sourceId]; !sourceIsAvailable { + availableSources[sourceId] = nil + } + + for _, newSource := range element { + availableSources[sourceId] = append(availableSources[sourceId], newSource) + } + } + } + + // Response building + var response pb.TopologyResponse + + for levelIndex, level := range levels { + for _, node := range level { + var producers []string = nil + var consumers []string = nil + + for producerInstanceId := range pipelineSteps[node.stepId].producerInstances { + producers = append(producers, producerInstanceId) + } + for consumerInstanceId := range pipelineSteps[node.stepId].consumerInstances { + consumers = append(consumers, consumerInstanceId) + } + response.Nodes = append(response.Nodes, &pb.TopologyResponseNode{ + NodeId: node.stepId, + Level: uint32(levelIndex), + ProducerInstances: producers, + ConsumerInstances: consumers, + }) + } + } + + for _, edge := range edges { + newEdge := pb.TopologyResponseEdge{ + FromNodeId: edge.fromStepId, + ToNodeId: edge.toStepId, + SourceName: edge.sourceId, + InvolvedReceivers: nil, + } + + for receiverId := range edge.involvedReceivers { + newEdge.InvolvedReceivers = append(newEdge.InvolvedReceivers, receiverId) + } + + response.Edges = append(response.Edges, &newEdge) + } + + return &response, nil +} diff --git a/monitoring/monitoring_server/src/asapo_monitoring_server/server/ServerEntrypoint.go b/monitoring/monitoring_server/src/asapo_monitoring_server/server/ServerEntrypoint.go new file mode 100644 index 0000000000000000000000000000000000000000..669cd6b2e7758ddd0a781faf156dc68aa45a0765 --- /dev/null +++ b/monitoring/monitoring_server/src/asapo_monitoring_server/server/ServerEntrypoint.go @@ -0,0 +1,48 @@ +package server + +import ( + pb "asapo_common/generated_proto" + log "asapo_common/logger" + "context" + influxdb2 "github.com/influxdata/influxdb-client-go/v2" + "google.golang.org/grpc" + "net" + "strconv" +) + +func Start(settings Settings) { + lis, err := net.Listen("tcp", ":"+strconv.Itoa(int(settings.ServerPort))) + if err != nil { + log.Fatal("failed to listen: ", err) + } + + influxClient := influxdb2.NewClient(settings.InfluxDbUrl, ""/*settings.InfluxDb2AuthToken*/) + // influxClient.BucketsAPI().CreateBucketWithName(context.Background(), domain.Organization{}, "bucketName", domain.RetentionRules{}) + + queryServer := QueryServer{} + ingestServer := IngestServer{} + + dbQueryApi := influxClient.QueryAPI(""/*settings.InfluxDb2Org*/) + queryServer.dbQueryApi = dbQueryApi + queryServer.settings = settings + + dbWriterApi := influxClient.WriteAPI(""/*settings.InfluxDb2Org*/, settings.InfluxDbDatabase) + ingestServer.dbWriterApi = dbWriterApi + ingestServer.settings = settings + + grpcServer := grpc.NewServer() + pb.RegisterAsapoMonitoringQueryServiceServer(grpcServer, &queryServer) + pb.RegisterAsapoMonitoringIngestServiceServer(grpcServer, &ingestServer) + log.Info("server listening at ", lis.Addr()) + + // Check connection + _, err = queryServer.GetMetadata(context.TODO(), &pb.Empty{}) + if err != nil { + log.Fatal("dummy database request failed: ", err) + } + + // Start net server and wait + if err = grpcServer.Serve(lis); err != nil { + log.Fatal("failed to serve: ", err) + } +} diff --git a/monitoring/monitoring_server/src/asapo_monitoring_server/server/Settings.go b/monitoring/monitoring_server/src/asapo_monitoring_server/server/Settings.go new file mode 100644 index 0000000000000000000000000000000000000000..137b8f091211c595cf86bfa36968ebfc212b3e41 --- /dev/null +++ b/monitoring/monitoring_server/src/asapo_monitoring_server/server/Settings.go @@ -0,0 +1,44 @@ +package server + +const ( + // InfluxDb bucket definition + // TAGS + // > Values + + // definition: sourceMeta = beamtime, source, stream + + // From receiver when files are inserted into ASAPO: + // [sourceMeta], receiverName, pipelineStepId, producerInstanceId + // > totalInputFileSize, avgTransferReceiveTimeUs, avgWriteIoTimeUs, avgDbTimeUs, receiverFileCount + dbMeasurementFileInput = "fileInput" + + // From Broker when requests are handled: + // [sourceMeta], brokerName, pipelineStepId, consumerInstanceId, command + // > totalRequestedFileSize, requestedFileCount + dbMeasurementBrokerFileRequests = "brokerRequests" + + // From receiver data service when files are requested + // [sourceMeta], receiverName, pipelineStepId, consumerInstanceId + // > (totalRdsOutputFileSize, avgRdsOutputTransferTimeUs) + dbMeasurementRdsFileRequests = "rdsRequests" + + // From receiver data service when files are requested + // [sourceMeta], receiverName + // > rdsCacheUsedBytes, rdsCacheTotalBytes + dbMeasurementRdsCacheMemoryUsage = "rdsCacheMemoryUsage" + + // From file transfer service when files are transferred + // [sourceMeta], ftsName, pipelineStepId, consumerInstanceId + // > ftsFileCount, totalFtsTransferredFileSize, avgTransferSendTimeUs + dbMeasurementFtsTransfers = "ftsTransfers" +) + +type Settings struct { + ThisClusterName string // e.g. "test-cluster" + + ServerPort uint16 // e.g. "50051" + LogLevel string // e.g. "info" + + InfluxDbUrl string // e.g. "http://127.0.0.1:8086" + InfluxDbDatabase string // e.g. "asapo-monitoring" +} diff --git a/monitoring/monitoring_ui/.dockerignore b/monitoring/monitoring_ui/.dockerignore new file mode 100644 index 0000000000000000000000000000000000000000..d451ff16c1010b8dc4285ef4d338028792a0ecd3 --- /dev/null +++ b/monitoring/monitoring_ui/.dockerignore @@ -0,0 +1,5 @@ +node_modules +.DS_Store +dist +dist-ssr +*.local diff --git a/monitoring/monitoring_ui/.gitignore b/monitoring/monitoring_ui/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..d451ff16c1010b8dc4285ef4d338028792a0ecd3 --- /dev/null +++ b/monitoring/monitoring_ui/.gitignore @@ -0,0 +1,5 @@ +node_modules +.DS_Store +dist +dist-ssr +*.local diff --git a/monitoring/monitoring_ui/.vscode/settings.json b/monitoring/monitoring_ui/.vscode/settings.json new file mode 100644 index 0000000000000000000000000000000000000000..3b664107303df336bab8010caad42ddaed24550e --- /dev/null +++ b/monitoring/monitoring_ui/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "git.ignoreLimitWarning": true +} \ No newline at end of file diff --git a/monitoring/monitoring_ui/Dockerfile b/monitoring/monitoring_ui/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..2ab12a391175ce4529f4853a3728745a47fd5abd --- /dev/null +++ b/monitoring/monitoring_ui/Dockerfile @@ -0,0 +1,13 @@ +FROM node:16 as build-stage +WORKDIR /app +COPY package*.json ./ +RUN npm install +COPY . . +RUN npm run build + +FROM nginx:stable-alpine as production-stage +EXPOSE 80 +COPY nginx.conf /etc/nginx/nginx.conf +RUN rm -rf /usr/share/nginx/html/* +COPY --from=build-stage /app/dist /usr/share/nginx/html +CMD ["nginx", "-g", "daemon off;"] diff --git a/monitoring/monitoring_ui/README.md b/monitoring/monitoring_ui/README.md new file mode 100644 index 0000000000000000000000000000000000000000..dd6cc6dcea52c6656269460c774981e7f2a1c48c --- /dev/null +++ b/monitoring/monitoring_ui/README.md @@ -0,0 +1,11 @@ +# ASAPO Monitoring frontend + +If you use Visual Studio Code please install these plugins: + - Vetur + - Tailwind CSS IntelliSense + + +Start dev server: +```bash +npm run dev +``` diff --git a/monitoring/monitoring_ui/generate-proto.sh b/monitoring/monitoring_ui/generate-proto.sh new file mode 100755 index 0000000000000000000000000000000000000000..b7ecc6867788bd6a8dbc690ccc4f074a2fa0d908 --- /dev/null +++ b/monitoring/monitoring_ui/generate-proto.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +PROTO_INPUT_FOLDER=../../common/networking/monitoring/ +PROTO_INPUT=$PROTO_INPUT_FOLDER*.proto +PROTO_DEST=./src/generated_proto + +rm -rf ${PROTO_DEST} +mkdir -p ${PROTO_DEST} + + +#npx grpc_tools_node_protoc \ +# --grpc_out="grpc_js:${PROTO_DEST}" \ +# --grpc-web_out="import_style=commonjs+dts,mode=grpcwebtext:${PROTO_DEST}" \ +# #--ts_out="grpc_js:${PROTO_DEST}" \ +# -I ${PROTO_INPUT_FOLDER} \ +# ${PROTO_INPUT} + +# Hmm, somehow this client does not work when using binary, and when using grpcwebtext +npx grpc_tools_node_protoc \ + --js_out="import_style=commonjs,binary:${PROTO_DEST}" \ + --grpc-web_out="import_style=commonjs+dts,mode=grpcwebtext:${PROTO_DEST}" \ + -I ${PROTO_INPUT_FOLDER} \ + ${PROTO_INPUT} + +# JavaScript code generation +#npx grpc_tools_node_protoc \ +# --grpc-web_out="import_style=typescript,mode=grpcwebtext:${PROTO_DEST}" \ +# --plugin=protoc-gen-grpc=./node_modules/.bin/grpc_tools_node_protoc_plugin \ +# -I ${PROTO_INPUT_FOLDER} \ +# ${PROTO_INPUT} + #--js_out="import_style=typescript,binary:${PROTO_DEST}" \ + #--ts_out="grpc_js:${PROTO_DEST}" \ + +# TypeScript code generation +#npx grpc_tools_node_protoc \ +# --plugin=protoc-gen-ts=./node_modules/.bin/protoc-gen-ts \ +# --ts_out="mode=grpc-js:${PROTO_DEST}" \ +# -I ${PROTO_INPUT_FOLDER} \ +# ${PROTO_INPUT} diff --git a/monitoring/monitoring_ui/index.html b/monitoring/monitoring_ui/index.html new file mode 100644 index 0000000000000000000000000000000000000000..5633b805de23ab6375238585a116b723821b263b --- /dev/null +++ b/monitoring/monitoring_ui/index.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="UTF-8" /> + <link rel="icon" href="/favicon.ico" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <title>ASAPO Monitoring</title> + </head> + <body> + <div id="app"></div> + <script type="module" src="/src/main.ts"></script> + </body> +</html> diff --git a/monitoring/monitoring_ui/nginx.conf b/monitoring/monitoring_ui/nginx.conf new file mode 100644 index 0000000000000000000000000000000000000000..9602ca798e98713c1447f59a5f27062e543e2f3a --- /dev/null +++ b/monitoring/monitoring_ui/nginx.conf @@ -0,0 +1,49 @@ +user nginx; +worker_processes auto; +error_log /var/log/nginx/error.log; +pid /run/nginx.pid; + +# Load dynamic modules. See /usr/share/nginx/README.dynamic. +include /usr/share/nginx/modules/*.conf; + +events { + worker_connections 1024; +} + +http { + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + include /etc/nginx/conf.d/*.conf; + + server { + listen 80 default_server; + server_name _; + root /usr/share/nginx/html; + + # Load configuration files for the default server block. + include /etc/nginx/default.d/*.conf; + + index index.html; + + etag on; + + location /js/ { + add_header Cache-Control max-age=31536000; + } + + location / { + try_files $uri $uri/ /index.html; + } + location /index.html { + add_header Cache-Control no-cache; + } + + } +} \ No newline at end of file diff --git a/monitoring/monitoring_ui/package-lock.json b/monitoring/monitoring_ui/package-lock.json new file mode 100644 index 0000000000000000000000000000000000000000..ffb0d490fb7a881225477b68346757b8dc450f39 --- /dev/null +++ b/monitoring/monitoring_ui/package-lock.json @@ -0,0 +1,31953 @@ +{ + "name": "asapo-monitoring", + "version": "0.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "asapo-monitoring", + "version": "0.0.0", + "dependencies": { + "@grpc/grpc-js": "^1.3.2", + "@tailwindcss/postcss7-compat": "^2.0.2", + "autoprefixer": "^9", + "grpc-web": "^1.2.1", + "jquery": "^3.6.0", + "leader-line-new": "^1.1.9", + "module": "^1.2.5", + "moment": "^2.29.1", + "postcss": "^7", + "relative-time-parser": "^1.0.13", + "tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.0.2", + "vis-network": "^9.0.4", + "vue": "^3.0.5", + "vue-class-component": "^8.0.0-0", + "vue-router": "^4.0.0-0" + }, + "devDependencies": { + "@types/jquery": "^3.5.5", + "@vue/cli-plugin-router": "~4.5.0", + "@vue/cli-plugin-typescript": "~4.5.0", + "@vue/cli-service": "~4.5.0", + "@vue/compiler-sfc": "^3.0.0", + "@vue/eslint-config-typescript": "^7.0.0", + "grpc_tools_node_protoc_ts": "^5.2.2", + "grpc-tools": "^1.11.1", + "protoc-gen-grpc-web": "^1.2.1", + "sass": "^1.26.5", + "sass-loader": "^8.0.2", + "typescript": "^4.1.3", + "vite": "^2.3.3", + "vue-cli-plugin-tailwind": "~2.0.6", + "vue-tsc": "^0.0.24" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.12.13" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", + "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==" + }, + "node_modules/@babel/highlight": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", + "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.14.0", + "chalk": "^2.0.0", + "js-tokens": "^4.0.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": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "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": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "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.14.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.3.tgz", + "integrity": "sha512-7MpZDIfI7sUC5zWo2+foJ50CSI5lcqDehZ0lVgIhSi4bFEk94fLAKlF3Q0nzSQQ+ca0lm+O6G9ztKVBeu8PMRQ==", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.2.tgz", + "integrity": "sha512-SdjAG/3DikRHpUOjxZgnkbR11xUlyDMUFJdvnIgZEE16mqmY0BINMmc4//JMJglEmn6i7sq6p+mGrFWyZ98EEw==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.14.0", + "to-fast-properties": "^2.0.0" + } + }, + "node_modules/@egjs/hammerjs": { + "version": "2.0.17", + "resolved": "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz", + "integrity": "sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==", + "peer": true, + "dependencies": { + "@types/hammerjs": "^2.0.36" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@fullhuman/postcss-purgecss": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@fullhuman/postcss-purgecss/-/postcss-purgecss-3.1.3.tgz", + "integrity": "sha512-kwOXw8fZ0Lt1QmeOOrd+o4Ibvp4UTEBFQbzvWldjlKv5n+G9sXfIPn1hh63IQIL8K8vbvv1oYMJiIUbuy9bGaA==", + "dependencies": { + "purgecss": "^3.1.3" + } + }, + "node_modules/@grpc/grpc-js": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.3.2.tgz", + "integrity": "sha512-UXepkOKCATJrhHGsxt+CGfpZy9zUn1q9mop5kfcXq1fBkTePxVNPOdnISlCbJFlCtld+pSLGyZCzr9/zVprFKA==", + "dependencies": { + "@types/node": ">=12.12.47" + }, + "engines": { + "node": "^8.13.0 || >=10.10.0" + } + }, + "node_modules/@gulp-sourcemaps/map-sources": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz", + "integrity": "sha1-iQrnxdjId/bThIYCFazp1+yUW9o=", + "dependencies": { + "normalize-path": "^2.0.1", + "through2": "^2.0.3" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/@gulp-sourcemaps/map-sources/node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@hapi/address": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz", + "integrity": "sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ==", + "deprecated": "Moved to 'npm install @sideway/address'", + "dev": true + }, + "node_modules/@hapi/bourne": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-1.3.2.tgz", + "integrity": "sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==", + "deprecated": "This version has been deprecated and is no longer supported or maintained", + "dev": true + }, + "node_modules/@hapi/hoek": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.1.tgz", + "integrity": "sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==", + "deprecated": "This version has been deprecated and is no longer supported or maintained", + "dev": true + }, + "node_modules/@hapi/joi": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-15.1.1.tgz", + "integrity": "sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ==", + "deprecated": "Switch to 'npm install joi'", + "dev": true, + "dependencies": { + "@hapi/address": "2.x.x", + "@hapi/bourne": "1.x.x", + "@hapi/hoek": "8.x.x", + "@hapi/topo": "3.x.x" + } + }, + "node_modules/@hapi/topo": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-3.1.6.tgz", + "integrity": "sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ==", + "deprecated": "This version has been deprecated and is no longer supported or maintained", + "dev": true, + "dependencies": { + "@hapi/hoek": "^8.3.0" + } + }, + "node_modules/@intervolga/optimize-cssnano-plugin": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@intervolga/optimize-cssnano-plugin/-/optimize-cssnano-plugin-1.0.6.tgz", + "integrity": "sha512-zN69TnSr0viRSU6cEDIcuPcP67QcpQ6uHACg58FiN9PDrU6SLyGW3MR4tiISbYxy1kDWAVPwD+XwQTWE5cigAA==", + "dev": true, + "dependencies": { + "cssnano": "^4.0.0", + "cssnano-preset-default": "^4.0.0", + "postcss": "^7.0.0" + }, + "peerDependencies": { + "webpack": "^4.0.0" + } + }, + "node_modules/@mrmlnc/readdir-enhanced": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", + "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", + "dev": true, + "dependencies": { + "call-me-maybe": "^1.0.1", + "glob-to-regexp": "^0.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", + "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", + "dependencies": { + "@nodelib/fs.stat": "2.0.4", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", + "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", + "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.4", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@sindresorhus/is": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz", + "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@soda/friendly-errors-webpack-plugin": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@soda/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.8.0.tgz", + "integrity": "sha512-RLotfx6k1+nfLacwNCenj7VnTMPxVwYKoGOcffMFoJDKM8tXzBiCN0hMHFJNnoAojduYAsxuiMm0EOMixgiRow==", + "dev": true, + "dependencies": { + "chalk": "^2.4.2", + "error-stack-parser": "^2.0.2", + "string-width": "^2.0.0", + "strip-ansi": "^5" + }, + "engines": { + "node": ">=8.0.0" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/@soda/friendly-errors-webpack-plugin/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@soda/friendly-errors-webpack-plugin/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/@soda/friendly-errors-webpack-plugin/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/@soda/friendly-errors-webpack-plugin/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/@soda/friendly-errors-webpack-plugin/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/@soda/friendly-errors-webpack-plugin/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@soda/friendly-errors-webpack-plugin/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@soda/friendly-errors-webpack-plugin/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@soda/friendly-errors-webpack-plugin/node_modules/string-width/node_modules/ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@soda/friendly-errors-webpack-plugin/node_modules/string-width/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@soda/friendly-errors-webpack-plugin/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@soda/friendly-errors-webpack-plugin/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/@soda/get-current-script": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@soda/get-current-script/-/get-current-script-1.0.2.tgz", + "integrity": "sha512-T7VNNlYVM1SgQ+VsMYhnDkcGmWhQdL0bDyGm5TlQ3GBXnJscEClUUOKduWTmm2zCnvNLC1hc3JpuXjs/nFOc5w==", + "dev": true + }, + "node_modules/@tailwindcss/postcss7-compat": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/postcss7-compat/-/postcss7-compat-2.1.3.tgz", + "integrity": "sha512-SuuCv7XkB2WIdTsiRLCX8eTF6s2r7E+0aIg+ASYZE/5YAJlojYWDENth+ywRJpWXW1ZoQKo0g/8xsMKijzPm8g==", + "dependencies": { + "@fullhuman/postcss-purgecss": "^3.1.3", + "autoprefixer": "^9", + "bytes": "^3.0.0", + "chalk": "^4.1.0", + "chokidar": "^3.5.1", + "color": "^3.1.3", + "detective": "^5.2.0", + "didyoumean": "^1.2.1", + "dlv": "^1.1.3", + "fast-glob": "^3.2.5", + "fs-extra": "^9.1.0", + "html-tags": "^3.1.0", + "lodash": "^4.17.21", + "lodash.topath": "^4.5.2", + "modern-normalize": "^1.0.0", + "node-emoji": "^1.8.1", + "normalize-path": "^3.0.0", + "object-hash": "^2.1.1", + "parse-glob": "^3.0.4", + "postcss": "^7", + "postcss-functions": "^3", + "postcss-js": "^2", + "postcss-nested": "^4", + "postcss-selector-parser": "^6.0.4", + "postcss-value-parser": "^4.1.0", + "pretty-hrtime": "^1.0.3", + "quick-lru": "^5.1.1", + "reduce-css-calc": "^2.1.8", + "resolve": "^1.20.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=12.13.0" + } + }, + "node_modules/@types/anymatch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-3.0.0.tgz", + "integrity": "sha512-qLChUo6yhpQ9k905NwL74GU7TxH+9UODwwQ6ICNI+O6EDMExqH/Cv9NsbmcZ7yC/rRXJ/AHCzfgjsFRY5fKjYw==", + "deprecated": "This is a stub types definition. anymatch provides its own type definitions, so you do not need this installed.", + "dev": true, + "dependencies": { + "anymatch": "*" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.34", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz", + "integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.4.tgz", + "integrity": "sha512-Kf8v0wljR5GSCOCF/VQWdV3ZhKOVA73drXtY3geMTQgHy9dgqQ0dLrf31M0hcuWkhFzK5sP0kkS3mJzcKVtZbw==", + "dev": true, + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/express": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.11.tgz", + "integrity": "sha512-no+R6rW60JEc59977wIxreQVsIEOAYwgCqldrA/vkpCnbD7MqTefO97lmoBe4WE0F156bC4uLSP1XHDOySnChg==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.19.tgz", + "integrity": "sha512-DJOSHzX7pCiSElWaGR8kCprwibCB/3yW6vcT8VG3P0SJjnv19gnWG/AZMfM60Xj/YJIp/YCaDHyvzsFVeniARA==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, + "node_modules/@types/glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==", + "dev": true, + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/hammerjs": { + "version": "2.0.40", + "resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.40.tgz", + "integrity": "sha512-VbjwR1fhsn2h2KXAY4oy1fm7dCxaKy0D+deTb8Ilc3Eo3rc5+5eA4rfYmZaHgNJKxVyI0f6WIXzO2zLkVmQPHA==", + "peer": true + }, + "node_modules/@types/http-proxy": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.6.tgz", + "integrity": "sha512-+qsjqR75S/ib0ig0R9WN+CDoZeOBU6F2XLewgC4KVgdXiNHiKKHFEMRHOrs5PbYE97D5vataw5wPj4KLYfUkuQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/jquery": { + "version": "3.5.5", + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.5.tgz", + "integrity": "sha512-6RXU9Xzpc6vxNrS6FPPapN1SxSHgQ336WC6Jj/N8q30OiaBZ00l1GBgeP7usjVZPivSkGUfL1z/WW6TX989M+w==", + "dev": true, + "dependencies": { + "@types/sizzle": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", + "dev": true + }, + "node_modules/@types/mime": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", + "dev": true + }, + "node_modules/@types/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA==", + "dev": true + }, + "node_modules/@types/minimist": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.1.tgz", + "integrity": "sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==", + "dev": true + }, + "node_modules/@types/node": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.3.1.tgz", + "integrity": "sha512-weaeiP4UF4XgF++3rpQhpIJWsCTS4QJw5gvBhQu6cFIxTwyxWIe3xbnrY/o2lTCQ0lsdb8YIUDUvLR4Vuz5rbw==" + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "dev": true + }, + "node_modules/@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "dev": true, + "optional": true + }, + "node_modules/@types/q": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", + "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==", + "dev": true + }, + "node_modules/@types/qs": { + "version": "6.9.6", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.6.tgz", + "integrity": "sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", + "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==", + "dev": true + }, + "node_modules/@types/serve-static": { + "version": "1.13.9", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.9.tgz", + "integrity": "sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/sizzle": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz", + "integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==", + "dev": true + }, + "node_modules/@types/source-list-map": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", + "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", + "dev": true + }, + "node_modules/@types/tapable": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.7.tgz", + "integrity": "sha512-0VBprVqfgFD7Ehb2vd8Lh9TG3jP98gvr8rgehQqzztZNI7o8zS8Ad4jyZneKELphpuE212D8J70LnSNQSyO6bQ==", + "dev": true + }, + "node_modules/@types/uglify-js": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.13.0.tgz", + "integrity": "sha512-EGkrJD5Uy+Pg0NUR8uA4bJ5WMfljyad0G+784vLCNUkD+QwOJXUbBYExXfVGf7YtyzdQp3L/XMYcliB987kL5Q==", + "dev": true, + "dependencies": { + "source-map": "^0.6.1" + } + }, + "node_modules/@types/webpack": { + "version": "4.41.28", + "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.28.tgz", + "integrity": "sha512-Nn84RAiJjKRfPFFCVR8LC4ueTtTdfWAMZ03THIzZWRJB+rX24BD3LqPSFnbMscWauEsT4segAsylPDIaZyZyLQ==", + "dev": true, + "dependencies": { + "@types/anymatch": "*", + "@types/node": "*", + "@types/tapable": "^1", + "@types/uglify-js": "*", + "@types/webpack-sources": "*", + "source-map": "^0.6.0" + } + }, + "node_modules/@types/webpack-dev-server": { + "version": "3.11.4", + "resolved": "https://registry.npmjs.org/@types/webpack-dev-server/-/webpack-dev-server-3.11.4.tgz", + "integrity": "sha512-DCKORHjqNNVuMIDWFrlljftvc9CL0+09p3l7lBpb8dRqgN5SmvkWCY4MPKxoI6wJgdRqohmoNbptkxqSKAzLRg==", + "dev": true, + "dependencies": { + "@types/connect-history-api-fallback": "*", + "@types/express": "*", + "@types/serve-static": "*", + "@types/webpack": "^4", + "http-proxy-middleware": "^1.0.0" + } + }, + "node_modules/@types/webpack-env": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.16.0.tgz", + "integrity": "sha512-Fx+NpfOO0CpeYX2g9bkvX8O5qh9wrU1sOF4g8sft4Mu7z+qfe387YlyY8w8daDyDsKY5vUxM0yxkAYnbkRbZEw==", + "dev": true + }, + "node_modules/@types/webpack-sources": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-2.1.0.tgz", + "integrity": "sha512-LXn/oYIpBeucgP1EIJbKQ2/4ZmpvRl+dlrFdX7+94SKRUV3Evy3FsfMZY318vGhkWUS5MPhtOM3w1/hCOAOXcg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/source-list-map": "*", + "source-map": "^0.7.3" + } + }, + "node_modules/@types/webpack-sources/node_modules/source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@vue/cli-overlay": { + "version": "4.5.13", + "resolved": "https://registry.npmjs.org/@vue/cli-overlay/-/cli-overlay-4.5.13.tgz", + "integrity": "sha512-jhUIg3klgi5Cxhs8dnat5hi/W2tQJvsqCxR0u6hgfSob0ORODgUBlN+F/uwq7cKIe/pzedVUk1y07F13GQvPqg==", + "dev": true + }, + "node_modules/@vue/cli-plugin-router": { + "version": "4.5.13", + "resolved": "https://registry.npmjs.org/@vue/cli-plugin-router/-/cli-plugin-router-4.5.13.tgz", + "integrity": "sha512-tgtMDjchB/M1z8BcfV4jSOY9fZSMDTPgF9lsJIiqBWMxvBIsk9uIZHxp62DibYME4CCKb/nNK61XHaikFp+83w==", + "dev": true, + "dependencies": { + "@vue/cli-shared-utils": "^4.5.13" + }, + "peerDependencies": { + "@vue/cli-service": "^3.0.0 || ^4.0.0-0" + } + }, + "node_modules/@vue/cli-plugin-typescript": { + "version": "4.5.13", + "resolved": "https://registry.npmjs.org/@vue/cli-plugin-typescript/-/cli-plugin-typescript-4.5.13.tgz", + "integrity": "sha512-CpLlIdFNV1gn9uC4Yh6QgWI42uk2x5Z3cb2ScxNSwWsR1vgSdr0/1DdNzoBm68aP8RUtnHHO/HZfPnvXiq42xA==", + "dev": true, + "dependencies": { + "@types/webpack-env": "^1.15.2", + "@vue/cli-shared-utils": "^4.5.13", + "cache-loader": "^4.1.0", + "fork-ts-checker-webpack-plugin": "^3.1.1", + "globby": "^9.2.0", + "thread-loader": "^2.1.3", + "ts-loader": "^6.2.2", + "tslint": "^5.20.1", + "webpack": "^4.0.0", + "yorkie": "^2.0.0" + }, + "optionalDependencies": { + "fork-ts-checker-webpack-plugin-v5": "npm:fork-ts-checker-webpack-plugin@^5.0.11" + }, + "peerDependencies": { + "@vue/cli-service": "^3.0.0 || ^4.0.0-0", + "@vue/compiler-sfc": "^3.0.0-beta.14", + "typescript": ">=2" + }, + "peerDependenciesMeta": { + "@vue/compiler-sfc": { + "optional": true + } + } + }, + "node_modules/@vue/cli-plugin-typescript/node_modules/@nodelib/fs.stat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", + "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@vue/cli-plugin-typescript/node_modules/array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "dependencies": { + "array-uniq": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@vue/cli-plugin-typescript/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@vue/cli-plugin-typescript/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@vue/cli-plugin-typescript/node_modules/dir-glob": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", + "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", + "dev": true, + "dependencies": { + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@vue/cli-plugin-typescript/node_modules/fast-glob": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", + "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", + "dev": true, + "dependencies": { + "@mrmlnc/readdir-enhanced": "^2.2.1", + "@nodelib/fs.stat": "^1.1.2", + "glob-parent": "^3.1.0", + "is-glob": "^4.0.0", + "merge2": "^1.2.3", + "micromatch": "^3.1.10" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/@vue/cli-plugin-typescript/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@vue/cli-plugin-typescript/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@vue/cli-plugin-typescript/node_modules/glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "dependencies": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "node_modules/@vue/cli-plugin-typescript/node_modules/glob-parent/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@vue/cli-plugin-typescript/node_modules/globby": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", + "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", + "dev": true, + "dependencies": { + "@types/glob": "^7.1.1", + "array-union": "^1.0.2", + "dir-glob": "^2.2.2", + "fast-glob": "^2.2.6", + "glob": "^7.1.3", + "ignore": "^4.0.3", + "pify": "^4.0.1", + "slash": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@vue/cli-plugin-typescript/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@vue/cli-plugin-typescript/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@vue/cli-plugin-typescript/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@vue/cli-plugin-typescript/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@vue/cli-plugin-typescript/node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@vue/cli-plugin-typescript/node_modules/path-type/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@vue/cli-plugin-typescript/node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@vue/cli-plugin-typescript/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@vue/cli-plugin-vuex": { + "version": "4.5.13", + "resolved": "https://registry.npmjs.org/@vue/cli-plugin-vuex/-/cli-plugin-vuex-4.5.13.tgz", + "integrity": "sha512-I1S9wZC7iI0Wn8kw8Zh+A2Qkf6s1M6vTGBkx8boXjuzfwEEyEHRxadsVCecZc8Mkpydo0nykj+MyYF96TKFuVA==", + "dev": true, + "peerDependencies": { + "@vue/cli-service": "^3.0.0 || ^4.0.0-0" + } + }, + "node_modules/@vue/cli-service": { + "version": "4.5.13", + "resolved": "https://registry.npmjs.org/@vue/cli-service/-/cli-service-4.5.13.tgz", + "integrity": "sha512-CKAZN4iokMMsaUyJRU22oUAz3oS/X9sVBSKAF2/shFBV5xh3jqAlKl8OXZYz4cXGFLA6djNuYrniuLAo7Ku97A==", + "dev": true, + "dependencies": { + "@intervolga/optimize-cssnano-plugin": "^1.0.5", + "@soda/friendly-errors-webpack-plugin": "^1.7.1", + "@soda/get-current-script": "^1.0.0", + "@types/minimist": "^1.2.0", + "@types/webpack": "^4.0.0", + "@types/webpack-dev-server": "^3.11.0", + "@vue/cli-overlay": "^4.5.13", + "@vue/cli-plugin-router": "^4.5.13", + "@vue/cli-plugin-vuex": "^4.5.13", + "@vue/cli-shared-utils": "^4.5.13", + "@vue/component-compiler-utils": "^3.1.2", + "@vue/preload-webpack-plugin": "^1.1.0", + "@vue/web-component-wrapper": "^1.2.0", + "acorn": "^7.4.0", + "acorn-walk": "^7.1.1", + "address": "^1.1.2", + "autoprefixer": "^9.8.6", + "browserslist": "^4.12.0", + "cache-loader": "^4.1.0", + "case-sensitive-paths-webpack-plugin": "^2.3.0", + "cli-highlight": "^2.1.4", + "clipboardy": "^2.3.0", + "cliui": "^6.0.0", + "copy-webpack-plugin": "^5.1.1", + "css-loader": "^3.5.3", + "cssnano": "^4.1.10", + "debug": "^4.1.1", + "default-gateway": "^5.0.5", + "dotenv": "^8.2.0", + "dotenv-expand": "^5.1.0", + "file-loader": "^4.2.0", + "fs-extra": "^7.0.1", + "globby": "^9.2.0", + "hash-sum": "^2.0.0", + "html-webpack-plugin": "^3.2.0", + "launch-editor-middleware": "^2.2.1", + "lodash.defaultsdeep": "^4.6.1", + "lodash.mapvalues": "^4.6.0", + "lodash.transform": "^4.6.0", + "mini-css-extract-plugin": "^0.9.0", + "minimist": "^1.2.5", + "pnp-webpack-plugin": "^1.6.4", + "portfinder": "^1.0.26", + "postcss-loader": "^3.0.0", + "ssri": "^8.0.1", + "terser-webpack-plugin": "^1.4.4", + "thread-loader": "^2.1.3", + "url-loader": "^2.2.0", + "vue-loader": "^15.9.2", + "vue-style-loader": "^4.1.2", + "webpack": "^4.0.0", + "webpack-bundle-analyzer": "^3.8.0", + "webpack-chain": "^6.4.0", + "webpack-dev-server": "^3.11.0", + "webpack-merge": "^4.2.2" + }, + "bin": { + "vue-cli-service": "bin/vue-cli-service.js" + }, + "engines": { + "node": ">=8" + }, + "optionalDependencies": { + "vue-loader-v16": "npm:vue-loader@^16.1.0" + }, + "peerDependencies": { + "@vue/compiler-sfc": "^3.0.0-beta.14", + "vue-template-compiler": "^2.0.0" + }, + "peerDependenciesMeta": { + "@vue/compiler-sfc": { + "optional": true + }, + "less-loader": { + "optional": true + }, + "pug-plain-loader": { + "optional": true + }, + "raw-loader": { + "optional": true + }, + "sass-loader": { + "optional": true + }, + "stylus-loader": { + "optional": true + }, + "vue-template-compiler": { + "optional": true + } + } + }, + "node_modules/@vue/cli-service/node_modules/@nodelib/fs.stat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", + "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@vue/cli-service/node_modules/array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "dependencies": { + "array-uniq": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@vue/cli-service/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@vue/cli-service/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@vue/cli-service/node_modules/debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@vue/cli-service/node_modules/dir-glob": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", + "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", + "dev": true, + "dependencies": { + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@vue/cli-service/node_modules/fast-glob": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", + "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", + "dev": true, + "dependencies": { + "@mrmlnc/readdir-enhanced": "^2.2.1", + "@nodelib/fs.stat": "^1.1.2", + "glob-parent": "^3.1.0", + "is-glob": "^4.0.0", + "merge2": "^1.2.3", + "micromatch": "^3.1.10" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/@vue/cli-service/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@vue/cli-service/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@vue/cli-service/node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/@vue/cli-service/node_modules/glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "dependencies": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "node_modules/@vue/cli-service/node_modules/glob-parent/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@vue/cli-service/node_modules/globby": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", + "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", + "dev": true, + "dependencies": { + "@types/glob": "^7.1.1", + "array-union": "^1.0.2", + "dir-glob": "^2.2.2", + "fast-glob": "^2.2.6", + "glob": "^7.1.3", + "ignore": "^4.0.3", + "pify": "^4.0.1", + "slash": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@vue/cli-service/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@vue/cli-service/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@vue/cli-service/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@vue/cli-service/node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@vue/cli-service/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@vue/cli-service/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/@vue/cli-service/node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@vue/cli-service/node_modules/path-type/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@vue/cli-service/node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@vue/cli-service/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@vue/cli-service/node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/@vue/cli-shared-utils": { + "version": "4.5.13", + "resolved": "https://registry.npmjs.org/@vue/cli-shared-utils/-/cli-shared-utils-4.5.13.tgz", + "integrity": "sha512-HpnOrkLg42RFUsQGMJv26oTG3J3FmKtO2WSRhKIIL+1ok3w9OjGCtA3nMMXN27f9eX14TqO64M36DaiSZ1fSiw==", + "dev": true, + "dependencies": { + "@hapi/joi": "^15.0.1", + "chalk": "^2.4.2", + "execa": "^1.0.0", + "launch-editor": "^2.2.1", + "lru-cache": "^5.1.1", + "node-ipc": "^9.1.1", + "open": "^6.3.0", + "ora": "^3.4.0", + "read-pkg": "^5.1.1", + "request": "^2.88.2", + "semver": "^6.1.0", + "strip-ansi": "^6.0.0" + } + }, + "node_modules/@vue/cli-shared-utils/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@vue/cli-shared-utils/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/@vue/cli-shared-utils/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/@vue/cli-shared-utils/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/@vue/cli-shared-utils/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/@vue/cli-shared-utils/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@vue/cli-shared-utils/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/@vue/cli-shared-utils/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@vue/cli-shared-utils/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/@vue/compiler-core": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.0.11.tgz", + "integrity": "sha512-6sFj6TBac1y2cWCvYCA8YzHJEbsVkX7zdRs/3yK/n1ilvRqcn983XvpBbnN3v4mZ1UiQycTvOiajJmOgN9EVgw==", + "dependencies": { + "@babel/parser": "^7.12.0", + "@babel/types": "^7.12.0", + "@vue/shared": "3.0.11", + "estree-walker": "^2.0.1", + "source-map": "^0.6.1" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.0.11.tgz", + "integrity": "sha512-+3xB50uGeY5Fv9eMKVJs2WSRULfgwaTJsy23OIltKgMrynnIj8hTYY2UL97HCoz78aDw1VDXdrBQ4qepWjnQcw==", + "dependencies": { + "@vue/compiler-core": "3.0.11", + "@vue/shared": "3.0.11" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.0.11.tgz", + "integrity": "sha512-7fNiZuCecRleiyVGUWNa6pn8fB2fnuJU+3AGjbjl7r1P5wBivfl02H4pG+2aJP5gh2u+0wXov1W38tfWOphsXw==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.13.9", + "@babel/types": "^7.13.0", + "@vue/compiler-core": "3.0.11", + "@vue/compiler-dom": "3.0.11", + "@vue/compiler-ssr": "3.0.11", + "@vue/shared": "3.0.11", + "consolidate": "^0.16.0", + "estree-walker": "^2.0.1", + "hash-sum": "^2.0.0", + "lru-cache": "^5.1.1", + "magic-string": "^0.25.7", + "merge-source-map": "^1.1.0", + "postcss": "^8.1.10", + "postcss-modules": "^4.0.0", + "postcss-selector-parser": "^6.0.4", + "source-map": "^0.6.1" + } + }, + "node_modules/@vue/compiler-sfc/node_modules/postcss": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.0.tgz", + "integrity": "sha512-+ogXpdAjWGa+fdYY5BQ96V/6tAo+TdSSIMP5huJBIygdWwKtVoB5JWZ7yUd4xZ8r+8Kvvx4nyg/PQ071H4UtcQ==", + "dev": true, + "dependencies": { + "colorette": "^1.2.2", + "nanoid": "^3.1.23", + "source-map-js": "^0.6.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.0.11.tgz", + "integrity": "sha512-66yUGI8SGOpNvOcrQybRIhl2M03PJ+OrDPm78i7tvVln86MHTKhM3ERbALK26F7tXl0RkjX4sZpucCpiKs3MnA==", + "dev": true, + "dependencies": { + "@vue/compiler-dom": "3.0.11", + "@vue/shared": "3.0.11" + } + }, + "node_modules/@vue/component-compiler-utils": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@vue/component-compiler-utils/-/component-compiler-utils-3.2.0.tgz", + "integrity": "sha512-lejBLa7xAMsfiZfNp7Kv51zOzifnb29FwdnMLa96z26kXErPFioSf9BMcePVIQ6/Gc6/mC0UrPpxAWIHyae0vw==", + "dev": true, + "dependencies": { + "consolidate": "^0.15.1", + "hash-sum": "^1.0.2", + "lru-cache": "^4.1.2", + "merge-source-map": "^1.1.0", + "postcss": "^7.0.14", + "postcss-selector-parser": "^6.0.2", + "source-map": "~0.6.1", + "vue-template-es2015-compiler": "^1.9.0" + }, + "optionalDependencies": { + "prettier": "^1.18.2" + } + }, + "node_modules/@vue/component-compiler-utils/node_modules/consolidate": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.15.1.tgz", + "integrity": "sha512-DW46nrsMJgy9kqAbPt5rKaCr7uFtpo4mSUvLHIUbJEjm0vo+aY5QLwBUq3FK4tRnJr/X0Psc0C4jf/h+HtXSMw==", + "dev": true, + "dependencies": { + "bluebird": "^3.1.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/@vue/component-compiler-utils/node_modules/hash-sum": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", + "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=", + "dev": true + }, + "node_modules/@vue/component-compiler-utils/node_modules/lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/@vue/component-compiler-utils/node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "node_modules/@vue/devtools-api": { + "version": "6.0.0-beta.10", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.0.0-beta.10.tgz", + "integrity": "sha512-nktQYRnIFrh4DdXiCBjHnsHOMZXDIVcP9qlm/DMfxmjJMtpMGrSZCOKP8j7kDhObNHyqlicwoGLd+a4hf4x9ww==" + }, + "node_modules/@vue/eslint-config-typescript": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@vue/eslint-config-typescript/-/eslint-config-typescript-7.0.0.tgz", + "integrity": "sha512-UxUlvpSrFOoF8aQ+zX1leYiEBEm7CZmXYn/ZEM1zwSadUzpamx56RB4+Htdjisv1mX2tOjBegNUqH3kz2OL+Aw==", + "dev": true, + "dependencies": { + "vue-eslint-parser": "^7.0.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^4.4.0", + "@typescript-eslint/parser": "^4.4.0", + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0", + "eslint-plugin-vue": "^5.2.3 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/@vue/preload-webpack-plugin": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@vue/preload-webpack-plugin/-/preload-webpack-plugin-1.1.2.tgz", + "integrity": "sha512-LIZMuJk38pk9U9Ur4YzHjlIyMuxPlACdBIHH9/nGYVTsaGKOSnSuELiE8vS9wa+dJpIYspYUOqk+L1Q4pgHQHQ==", + "dev": true, + "engines": { + "node": ">=6.0.0" + }, + "peerDependencies": { + "html-webpack-plugin": ">=2.26.0", + "webpack": ">=4.0.0" + } + }, + "node_modules/@vue/reactivity": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.0.11.tgz", + "integrity": "sha512-SKM3YKxtXHBPMf7yufXeBhCZ4XZDKP9/iXeQSC8bBO3ivBuzAi4aZi0bNoeE2IF2iGfP/AHEt1OU4ARj4ao/Xw==", + "dependencies": { + "@vue/shared": "3.0.11" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.0.11.tgz", + "integrity": "sha512-87XPNwHfz9JkmOlayBeCCfMh9PT2NBnv795DSbi//C/RaAnc/bGZgECjmkD7oXJ526BZbgk9QZBPdFT8KMxkAg==", + "dependencies": { + "@vue/reactivity": "3.0.11", + "@vue/shared": "3.0.11" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.0.11.tgz", + "integrity": "sha512-jm3FVQESY3y2hKZ2wlkcmFDDyqaPyU3p1IdAX92zTNeCH7I8zZ37PtlE1b9NlCtzV53WjB4TZAYh9yDCMIEumA==", + "dependencies": { + "@vue/runtime-core": "3.0.11", + "@vue/shared": "3.0.11", + "csstype": "^2.6.8" + } + }, + "node_modules/@vue/shared": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.0.11.tgz", + "integrity": "sha512-b+zB8A2so8eCE0JsxjL24J7vdGl8rzPQ09hZNhystm+KqSbKcAej1A+Hbva1rCMmTTqA+hFnUSDc5kouEo0JzA==" + }, + "node_modules/@vue/web-component-wrapper": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@vue/web-component-wrapper/-/web-component-wrapper-1.3.0.tgz", + "integrity": "sha512-Iu8Tbg3f+emIIMmI2ycSI8QcEuAUgPTgHwesDU1eKMLE4YC/c/sFbGc70QgMq31ijRftV0R7vCm9co6rldCeOA==", + "dev": true + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", + "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", + "dev": true, + "dependencies": { + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", + "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", + "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", + "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-code-frame": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", + "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", + "dev": true, + "dependencies": { + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "node_modules/@webassemblyjs/helper-fsm": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", + "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-module-context": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", + "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", + "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", + "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", + "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", + "dev": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", + "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", + "dev": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", + "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==", + "dev": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", + "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/helper-wasm-section": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-opt": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", + "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", + "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", + "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "node_modules/@webassemblyjs/wast-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", + "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/floating-point-hex-parser": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-code-frame": "1.9.0", + "@webassemblyjs/helper-fsm": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", + "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "node_modules/accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-node": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", + "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", + "dependencies": { + "acorn": "^7.0.0", + "acorn-walk": "^7.0.0", + "xtend": "^4.0.2" + } + }, + "node_modules/acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/address": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz", + "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==", + "dev": true, + "engines": { + "node": ">= 0.12.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/ajv-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", + "dev": true, + "peerDependencies": { + "ajv": ">=5.0.0" + } + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/alphanum-sort": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", + "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", + "dev": true + }, + "node_modules/ansi-colors": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", + "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-html": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", + "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", + "dev": true, + "engines": [ + "node >= 0.8.0" + ], + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=", + "dev": true + }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "node_modules/arch": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", + "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", + "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/archive-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/archive-type/-/archive-type-4.0.0.tgz", + "integrity": "sha1-+S5yIzBW38aWlHJ0nCZ72wRrHXA=", + "dev": true, + "dependencies": { + "file-type": "^4.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/archive-type/node_modules/file-type": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-4.4.0.tgz", + "integrity": "sha1-G2AOX8ofvcboDApwxxyNul95BsU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "dev": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "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/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "dev": true + }, + "node_modules/array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "dependencies": { + "safer-buffer": "~2.1.0" + } + }, + "node_modules/asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "dev": true, + "dependencies": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/asn1.js/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "dev": true, + "dependencies": { + "object-assign": "^4.1.1", + "util": "0.10.3" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/assert/node_modules/inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "node_modules/assert/node_modules/util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "dependencies": { + "inherits": "2.0.1" + } + }, + "node_modules/assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", + "dev": true + }, + "node_modules/async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", + "dev": true + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/autoprefixer": { + "version": "9.8.6", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.6.tgz", + "integrity": "sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg==", + "dependencies": { + "browserslist": "^4.12.0", + "caniuse-lite": "^1.0.30001109", + "colorette": "^1.2.1", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "postcss": "^7.0.32", + "postcss-value-parser": "^4.1.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + } + }, + "node_modules/aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "dev": true + }, + "node_modules/babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "dependencies": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + } + }, + "node_modules/babel-code-frame/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/babel-code-frame/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/babel-code-frame/node_modules/js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "node_modules/babel-code-frame/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true, + "engines": { + "node": ">=0.8.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==" + }, + "node_modules/base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "dependencies": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", + "dev": true + }, + "node_modules/bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "dependencies": { + "tweetnacl": "^0.14.3" + } + }, + "node_modules/bfj": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/bfj/-/bfj-6.1.2.tgz", + "integrity": "sha512-BmBJa4Lip6BPRINSZ0BPEIfB1wUY/9rwbwvIHQA1KjX9om29B6id0wnWXq7m3bn5JrUVjeOTnVuhPT1FiHwPGw==", + "dev": true, + "dependencies": { + "bluebird": "^3.5.5", + "check-types": "^8.0.3", + "hoopy": "^0.1.4", + "tryer": "^1.0.1" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/big-integer": { + "version": "1.6.48", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz", + "integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/binary": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", + "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=", + "dev": true, + "dependencies": { + "buffers": "~0.1.1", + "chainsaw": "~0.1.0" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "engines": { + "node": ">=8" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "optional": true, + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bl": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", + "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", + "dev": true, + "dependencies": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "node_modules/bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", + "dev": true + }, + "node_modules/body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "dev": true, + "dependencies": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/body-parser/node_modules/qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/bonjour": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", + "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", + "dev": true, + "dependencies": { + "array-flatten": "^2.1.0", + "deep-equal": "^1.0.1", + "dns-equal": "^1.0.0", + "dns-txt": "^2.0.2", + "multicast-dns": "^6.0.1", + "multicast-dns-service-types": "^1.1.0" + } + }, + "node_modules/bonjour/node_modules/array-flatten": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", + "dev": true + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", + "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==", + "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==", + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "dependencies": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "node_modules/browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/browserify-rsa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", + "dev": true, + "dependencies": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "node_modules/browserify-sign": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", + "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", + "dev": true, + "dependencies": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "node_modules/browserify-sign/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/browserify-sign/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "dependencies": { + "pako": "~1.0.5" + } + }, + "node_modules/browserslist": { + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "dependencies": { + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "dev": true, + "dependencies": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "node_modules/buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", + "dev": true + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", + "dev": true + }, + "node_modules/buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "node_modules/buffer-indexof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", + "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==", + "dev": true + }, + "node_modules/buffer-indexof-polyfill": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz", + "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/buffer-json": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/buffer-json/-/buffer-json-2.0.0.tgz", + "integrity": "sha512-+jjPFVqyfF1esi9fvfUs3NqM0pH1ziZ36VP4hmA/y/Ssfo/5w5xHKfTw9BwQjoJ1w/oVtpLomqwUHKdefGyuHw==", + "dev": true + }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "node_modules/buffers": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", + "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=", + "dev": true, + "engines": { + "node": ">=0.2.0" + } + }, + "node_modules/builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "node_modules/bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacache": { + "version": "12.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", + "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", + "dev": true, + "dependencies": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + } + }, + "node_modules/cacache/node_modules/ssri": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz", + "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==", + "dev": true, + "dependencies": { + "figgy-pudding": "^3.5.1" + } + }, + "node_modules/cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "dependencies": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/cache-loader": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cache-loader/-/cache-loader-4.1.0.tgz", + "integrity": "sha512-ftOayxve0PwKzBF/GLsZNC9fJBXl8lkZE3TOsjkboHfVHVkL39iUEs1FO07A33mizmci5Dudt38UZrrYXDtbhw==", + "dev": true, + "dependencies": { + "buffer-json": "^2.0.0", + "find-cache-dir": "^3.0.0", + "loader-utils": "^1.2.3", + "mkdirp": "^0.5.1", + "neo-async": "^2.6.1", + "schema-utils": "^2.0.0" + }, + "engines": { + "node": ">= 8.9.0" + }, + "peerDependencies": { + "webpack": "^4.0.0" + } + }, + "node_modules/cacheable-request": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz", + "integrity": "sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0=", + "dev": true, + "dependencies": { + "clone-response": "1.0.2", + "get-stream": "3.0.0", + "http-cache-semantics": "3.8.1", + "keyv": "3.0.0", + "lowercase-keys": "1.0.0", + "normalize-url": "2.0.1", + "responselike": "1.0.2" + } + }, + "node_modules/cacheable-request/node_modules/get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/cacheable-request/node_modules/lowercase-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", + "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-me-maybe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", + "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=", + "dev": true + }, + "node_modules/caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "dev": true, + "dependencies": { + "callsites": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "dev": true, + "dependencies": { + "caller-callsite": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/camel-case": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", + "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", + "dev": true, + "dependencies": { + "no-case": "^2.2.0", + "upper-case": "^1.1.1" + } + }, + "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/camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "dev": true, + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001232", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001232.tgz", + "integrity": "sha512-e4Gyp7P8vqC2qV2iHA+cJNf/yqUKOShXQOJHQt81OHxlIZl/j/j3soEA0adAQi8CPUQgvOdDENyQ5kd6a6mNSg==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } + }, + "node_modules/case-sensitive-paths-webpack-plugin": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz", + "integrity": "sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "node_modules/chainsaw": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", + "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=", + "dev": true, + "dependencies": { + "traverse": ">=0.3.0 <0.4" + } + }, + "node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/check-types": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/check-types/-/check-types-8.0.3.tgz", + "integrity": "sha512-YpeKZngUmG65rLudJ4taU7VLkOCTMhNl/u4ctNC56LQS/zJTyNH0Lrtwm1tfTsbLlwvlfsA2d1c8vCf/Kh2KwQ==", + "dev": true + }, + "node_modules/chokidar": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "dependencies": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.1" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/ci-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "dev": true + }, + "node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "dependencies": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/clean-css": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz", + "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==", + "dev": true, + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/cli-highlight": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz", + "integrity": "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "highlight.js": "^10.7.1", + "mz": "^2.4.0", + "parse5": "^5.1.1", + "parse5-htmlparser2-tree-adapter": "^6.0.0", + "yargs": "^16.0.0" + }, + "bin": { + "highlight": "bin/highlight" + }, + "engines": { + "node": ">=8.0.0", + "npm": ">=5.0.0" + } + }, + "node_modules/cli-spinners": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.0.tgz", + "integrity": "sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clipboardy": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-2.3.0.tgz", + "integrity": "sha512-mKhiIL2DrQIsuXMgBgnfEHOZOryC7kY7YO//TN6c63wlEm3NG5tz+YgY5rVi29KCmq/QQjKYvM7a19+MDOTHOQ==", + "dev": true, + "dependencies": { + "arch": "^2.1.1", + "execa": "^1.0.0", + "is-wsl": "^2.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/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/cliui/node_modules/string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "dependencies": { + "mimic-response": "^1.0.0" + } + }, + "node_modules/clone-stats": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", + "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=" + }, + "node_modules/coa": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", + "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", + "dev": true, + "dependencies": { + "@types/q": "^1.5.1", + "chalk": "^2.4.1", + "q": "^1.1.2" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/coa/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/coa/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/coa/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/coa/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/coa/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/coa/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/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "dependencies": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/color/-/color-3.1.3.tgz", + "integrity": "sha512-xgXAcTHa2HeFCGLE9Xs/R82hujGtu9Jd9x4NW3T34+OMs7VoPsjwzRczKHvTAHeJwWFwX5j15+MgAppE8ztObQ==", + "dependencies": { + "color-convert": "^1.9.1", + "color-string": "^1.5.4" + } + }, + "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==", + "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==" + }, + "node_modules/color-string": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.5.tgz", + "integrity": "sha512-jgIoum0OfQfq9Whcfc2z/VhCNcmQjWbey6qBX0vqt7YICflUmBCh9E9CiQD5GSJ+Uehixm3NUwHVhqUAWRivZg==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/color/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==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "node_modules/colorette": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==" + }, + "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/commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "node_modules/component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dev": true, + "dependencies": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/connect-history-api-fallback": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", + "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "dev": true + }, + "node_modules/consolidate": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.16.0.tgz", + "integrity": "sha512-Nhl1wzCslqXYTJVDyJCu3ODohy9OfBMB5uD2BiBTzd7w+QY0lBzafkR8y8755yMYHAaMD4NuzbAw03/xzfw+eQ==", + "dev": true, + "dependencies": { + "bluebird": "^3.7.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "node_modules/content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "dev": true, + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "dev": true + }, + "node_modules/copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "dev": true, + "dependencies": { + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" + } + }, + "node_modules/copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/copy-webpack-plugin": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.1.2.tgz", + "integrity": "sha512-Uh7crJAco3AjBvgAy9Z75CjK8IG+gxaErro71THQ+vv/bl4HaQcpkexAY8KVW/T6D2W2IRr+couF/knIRkZMIQ==", + "dev": true, + "dependencies": { + "cacache": "^12.0.3", + "find-cache-dir": "^2.1.0", + "glob-parent": "^3.1.0", + "globby": "^7.1.1", + "is-glob": "^4.0.1", + "loader-utils": "^1.2.3", + "minimatch": "^3.0.4", + "normalize-path": "^3.0.0", + "p-limit": "^2.2.1", + "schema-utils": "^1.0.0", + "serialize-javascript": "^4.0.0", + "webpack-log": "^2.0.0" + }, + "engines": { + "node": ">= 6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "dependencies": { + "array-uniq": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/dir-glob": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", + "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", + "dev": true, + "dependencies": { + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/copy-webpack-plugin/node_modules/find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/copy-webpack-plugin/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/copy-webpack-plugin/node_modules/glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "dependencies": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/glob-parent/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/copy-webpack-plugin/node_modules/globby": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz", + "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=", + "dev": true, + "dependencies": { + "array-union": "^1.0.1", + "dir-glob": "^2.0.0", + "glob": "^7.1.2", + "ignore": "^3.3.5", + "pify": "^3.0.0", + "slash": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/copy-webpack-plugin/node_modules/ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "dev": true + }, + "node_modules/copy-webpack-plugin/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/copy-webpack-plugin/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/copy-webpack-plugin/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/copy-webpack-plugin/node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/copy-webpack-plugin/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/copy-webpack-plugin/node_modules/pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/copy-webpack-plugin/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/copy-webpack-plugin/node_modules/slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "node_modules/cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "dependencies": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/create-ecdh": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + } + }, + "node_modules/create-ecdh/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "dependencies": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + }, + "engines": { + "node": "*" + } + }, + "node_modules/css": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", + "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", + "dependencies": { + "inherits": "^2.0.3", + "source-map": "^0.6.1", + "source-map-resolve": "^0.5.2", + "urix": "^0.1.0" + } + }, + "node_modules/css-color-names": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", + "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/css-declaration-sorter": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz", + "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==", + "dev": true, + "dependencies": { + "postcss": "^7.0.1", + "timsort": "^0.3.0" + }, + "engines": { + "node": ">4" + } + }, + "node_modules/css-loader": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.6.0.tgz", + "integrity": "sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "cssesc": "^3.0.0", + "icss-utils": "^4.1.1", + "loader-utils": "^1.2.3", + "normalize-path": "^3.0.0", + "postcss": "^7.0.32", + "postcss-modules-extract-imports": "^2.0.0", + "postcss-modules-local-by-default": "^3.0.2", + "postcss-modules-scope": "^2.2.0", + "postcss-modules-values": "^3.0.0", + "postcss-value-parser": "^4.1.0", + "schema-utils": "^2.7.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/css-loader/node_modules/icss-utils": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz", + "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==", + "dev": true, + "dependencies": { + "postcss": "^7.0.14" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/css-loader/node_modules/postcss-modules-extract-imports": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", + "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", + "dev": true, + "dependencies": { + "postcss": "^7.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/css-loader/node_modules/postcss-modules-local-by-default": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz", + "integrity": "sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw==", + "dev": true, + "dependencies": { + "icss-utils": "^4.1.1", + "postcss": "^7.0.32", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/css-loader/node_modules/postcss-modules-scope": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz", + "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==", + "dev": true, + "dependencies": { + "postcss": "^7.0.6", + "postcss-selector-parser": "^6.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/css-loader/node_modules/postcss-modules-values": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz", + "integrity": "sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==", + "dev": true, + "dependencies": { + "icss-utils": "^4.0.0", + "postcss": "^7.0.6" + } + }, + "node_modules/css-loader/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/css-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", + "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^3.2.1", + "domutils": "^1.7.0", + "nth-check": "^1.0.2" + } + }, + "node_modules/css-select-base-adapter": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", + "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==", + "dev": true + }, + "node_modules/css-tree": { + "version": "1.0.0-alpha.37", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", + "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.4", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/css-unit-converter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.2.tgz", + "integrity": "sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA==" + }, + "node_modules/css-what": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", + "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==", + "dev": true, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssnano": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.11.tgz", + "integrity": "sha512-6gZm2htn7xIPJOHY824ERgj8cNPgPxyCSnkXc4v7YvNW+TdVfzgngHcEhy/8D11kUWRUMbke+tC+AUcUsnMz2g==", + "dev": true, + "dependencies": { + "cosmiconfig": "^5.0.0", + "cssnano-preset-default": "^4.0.8", + "is-resolvable": "^1.0.0", + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/cssnano-preset-default": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.8.tgz", + "integrity": "sha512-LdAyHuq+VRyeVREFmuxUZR1TXjQm8QQU/ktoo/x7bz+SdOge1YKc5eMN6pRW7YWBmyq59CqYba1dJ5cUukEjLQ==", + "dev": true, + "dependencies": { + "css-declaration-sorter": "^4.0.1", + "cssnano-util-raw-cache": "^4.0.1", + "postcss": "^7.0.0", + "postcss-calc": "^7.0.1", + "postcss-colormin": "^4.0.3", + "postcss-convert-values": "^4.0.1", + "postcss-discard-comments": "^4.0.2", + "postcss-discard-duplicates": "^4.0.2", + "postcss-discard-empty": "^4.0.1", + "postcss-discard-overridden": "^4.0.1", + "postcss-merge-longhand": "^4.0.11", + "postcss-merge-rules": "^4.0.3", + "postcss-minify-font-values": "^4.0.2", + "postcss-minify-gradients": "^4.0.2", + "postcss-minify-params": "^4.0.2", + "postcss-minify-selectors": "^4.0.2", + "postcss-normalize-charset": "^4.0.1", + "postcss-normalize-display-values": "^4.0.2", + "postcss-normalize-positions": "^4.0.2", + "postcss-normalize-repeat-style": "^4.0.2", + "postcss-normalize-string": "^4.0.2", + "postcss-normalize-timing-functions": "^4.0.2", + "postcss-normalize-unicode": "^4.0.1", + "postcss-normalize-url": "^4.0.1", + "postcss-normalize-whitespace": "^4.0.2", + "postcss-ordered-values": "^4.1.2", + "postcss-reduce-initial": "^4.0.3", + "postcss-reduce-transforms": "^4.0.2", + "postcss-svgo": "^4.0.3", + "postcss-unique-selectors": "^4.0.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/cssnano-util-get-arguments": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz", + "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/cssnano-util-get-match": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz", + "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/cssnano-util-raw-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz", + "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/cssnano-util-same-parent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz", + "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/csso": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", + "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "dev": true, + "dependencies": { + "css-tree": "^1.1.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", + "dev": true + }, + "node_modules/csstype": { + "version": "2.6.17", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.17.tgz", + "integrity": "sha512-u1wmTI1jJGzCJzWndZo8mk4wnPTZd1eOIYTYvuEyOQGfmDl3TrabCCfKnOC86FZwW/9djqTl933UF/cS425i9A==" + }, + "node_modules/cyclist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", + "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", + "dev": true + }, + "node_modules/dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/debug-fabulous": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-0.0.4.tgz", + "integrity": "sha1-+gccXYdIRoVCSAdCHKSxawsaB2M=", + "dependencies": { + "debug": "2.X", + "lazy-debug-legacy": "0.0.X", + "object-assign": "4.1.0" + } + }, + "node_modules/debug-fabulous/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/debug-fabulous/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/debug-fabulous/node_modules/object-assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz", + "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/decompress": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.1.tgz", + "integrity": "sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==", + "dev": true, + "dependencies": { + "decompress-tar": "^4.0.0", + "decompress-tarbz2": "^4.0.0", + "decompress-targz": "^4.0.0", + "decompress-unzip": "^4.0.1", + "graceful-fs": "^4.1.10", + "make-dir": "^1.0.0", + "pify": "^2.3.0", + "strip-dirs": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dev": true, + "dependencies": { + "mimic-response": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-tar": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", + "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", + "dev": true, + "dependencies": { + "file-type": "^5.2.0", + "is-stream": "^1.1.0", + "tar-stream": "^1.5.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-tar/node_modules/file-type": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", + "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-tarbz2": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", + "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", + "dev": true, + "dependencies": { + "decompress-tar": "^4.1.0", + "file-type": "^6.1.0", + "is-stream": "^1.1.0", + "seek-bzip": "^1.0.5", + "unbzip2-stream": "^1.0.9" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-tarbz2/node_modules/file-type": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz", + "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-targz": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", + "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", + "dev": true, + "dependencies": { + "decompress-tar": "^4.1.1", + "file-type": "^5.2.0", + "is-stream": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-targz/node_modules/file-type": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", + "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-unzip": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", + "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=", + "dev": true, + "dependencies": { + "file-type": "^3.8.0", + "get-stream": "^2.2.0", + "pify": "^2.3.0", + "yauzl": "^2.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress-unzip/node_modules/file-type": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", + "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress-unzip/node_modules/get-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", + "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", + "dev": true, + "dependencies": { + "object-assign": "^4.0.1", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress-unzip/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress/node_modules/make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "dev": true, + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress/node_modules/make-dir/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/decompress/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/deep-equal": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", + "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", + "dev": true, + "dependencies": { + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.1", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.2.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "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, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-gateway": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-5.0.5.tgz", + "integrity": "sha512-z2RnruVmj8hVMmAnEJMTIJNijhKCDiGjbLP+BHJFOT7ld3Bo5qcIBpVYDniqhbMIIf+jZDlkP2MkPXiQy/DBLA==", + "dev": true, + "dependencies": { + "execa": "^3.3.0" + }, + "engines": { + "node": "^8.12.0 || >=9.7.0" + } + }, + "node_modules/default-gateway/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/default-gateway/node_modules/execa": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-3.4.0.tgz", + "integrity": "sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "p-finally": "^2.0.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": "^8.12.0 || >=9.7.0" + } + }, + "node_modules/default-gateway/node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-gateway/node_modules/is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/default-gateway/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/default-gateway/node_modules/p-finally": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", + "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/default-gateway/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/default-gateway/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/default-gateway/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/default-gateway/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/defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "dev": true, + "dependencies": { + "clone": "^1.0.2" + } + }, + "node_modules/define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=" + }, + "node_modules/del": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", + "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", + "dev": true, + "dependencies": { + "@types/glob": "^7.1.1", + "globby": "^6.1.0", + "is-path-cwd": "^2.0.0", + "is-path-in-cwd": "^2.0.0", + "p-map": "^2.0.0", + "pify": "^4.0.1", + "rimraf": "^2.6.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/del/node_modules/array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "dependencies": { + "array-uniq": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/del/node_modules/globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true, + "dependencies": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/del/node_modules/globby/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true, + "engines": { + "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": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true + }, + "node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true + }, + "node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", + "dev": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/detect-newline": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", + "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true + }, + "node_modules/detective": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz", + "integrity": "sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg==", + "dependencies": { + "acorn-node": "^1.6.1", + "defined": "^1.0.0", + "minimist": "^1.1.1" + }, + "bin": { + "detective": "bin/detective.js" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/didyoumean": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.1.tgz", + "integrity": "sha1-6S7f2tplN9SE1zwBcv0eugxJdv8=" + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "node_modules/diffie-hellman/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" + }, + "node_modules/dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=", + "dev": true + }, + "node_modules/dns-packet": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz", + "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", + "dev": true, + "dependencies": { + "ip": "^1.1.0", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/dns-txt": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", + "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", + "dev": true, + "dependencies": { + "buffer-indexof": "^1.0.0" + } + }, + "node_modules/dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "dev": true, + "dependencies": { + "utila": "~0.4" + } + }, + "node_modules/dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "dev": true, + "dependencies": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + } + }, + "node_modules/dom-serializer/node_modules/domelementtype": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true, + "engines": { + "node": ">=0.4", + "npm": ">=1.2" + } + }, + "node_modules/domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true + }, + "node_modules/domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "dev": true, + "dependencies": { + "domelementtype": "1" + } + }, + "node_modules/domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dev": true, + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", + "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/dotenv-expand": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", + "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==", + "dev": true + }, + "node_modules/download": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/download/-/download-8.0.0.tgz", + "integrity": "sha512-ASRY5QhDk7FK+XrQtQyvhpDKanLluEEQtWl/J7Lxuf/b+i8RYh997QeXvL85xitrmRKVlx9c7eTrcRdq2GS4eA==", + "dev": true, + "dependencies": { + "archive-type": "^4.0.0", + "content-disposition": "^0.5.2", + "decompress": "^4.2.1", + "ext-name": "^5.0.0", + "file-type": "^11.1.0", + "filenamify": "^3.0.0", + "get-stream": "^4.1.0", + "got": "^8.3.1", + "make-dir": "^2.1.0", + "p-event": "^2.1.0", + "pify": "^4.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "dev": true + }, + "node_modules/duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "dev": true, + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "node_modules/duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, + "node_modules/duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "dependencies": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "node_modules/easy-stack": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/easy-stack/-/easy-stack-1.0.1.tgz", + "integrity": "sha512-wK2sCs4feiiJeFXn3zvY0p41mdU5VUgbgs1rNsc/y5ngFUijdWd+iIN8eoyuZHKB8xN6BL4PdWmzqFmxNg6V2w==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "dependencies": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "node_modules/ejs": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.4.tgz", + "integrity": "sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==", + "dev": true, + "hasInstallScript": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.3.732", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.732.tgz", + "integrity": "sha512-qKD5Pbq+QMk4nea4lMuncUMhpEiQwaJyCW7MrvissnRcBDENhVfDmAqQYRQ3X525oTzhar9Zh1cK0L2d1UKYcw==" + }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "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/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", + "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.5.0", + "tapable": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dev": true, + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "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==", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/error-ex/node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + }, + "node_modules/error-stack-parser": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.0.6.tgz", + "integrity": "sha512-d51brTeqC+BHlwF0BhPtcYgF5nlzf9ZZ0ZIUQNZpc9ZB9qw5IJ2diTrBY9jlCJkTLITYPjmiX6OWCwH+fuyNgQ==", + "dev": true, + "dependencies": { + "stackframe": "^1.1.1" + } + }, + "node_modules/es-abstract": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz", + "integrity": "sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.2", + "is-string": "^1.0.5", + "object-inspect": "^1.9.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/esbuild": { + "version": "0.11.23", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.11.23.tgz", + "integrity": "sha512-iaiZZ9vUF5wJV8ob1tl+5aJTrwDczlvGP0JoMmnpC2B0ppiMCu8n8gmy5ZTGl5bcG081XBVn+U+jP+mPFm5T5Q==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "engines": { + "node": ">=0.8.0" + } + }, + "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/espree": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", + "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", + "dev": true, + "dependencies": { + "acorn": "^7.1.1", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "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/esquery/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "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/esrecurse/node_modules/estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "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/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/event-pubsub": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/event-pubsub/-/event-pubsub-4.3.0.tgz", + "integrity": "sha512-z7IyloorXvKbFx9Bpie2+vMJKKx1fH1EN5yiTfp8CiLOTptSYy1g8H4yDpGlEdshL1PBiFtBHepF2cNsqeEeFQ==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/eventsource": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.0.tgz", + "integrity": "sha512-VSJjT5oCNrFvCS6igjzPAt5hBzQ2qPBFIbJ03zLI9SE0mxwZpMw6BfJrbFHm1a141AavMEB8JHmBhWAd66PfCg==", + "dev": true, + "dependencies": { + "original": "^1.0.0" + }, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "dependencies": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "dependencies": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/expand-brackets/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "dependencies": { + "fill-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-range/node_modules/fill-range": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", + "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", + "dependencies": { + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^3.0.0", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-range/node_modules/is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-range/node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-range/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "dev": true, + "dependencies": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/express/node_modules/qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/ext-list": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz", + "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==", + "dev": true, + "dependencies": { + "mime-db": "^1.28.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ext-name": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz", + "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==", + "dev": true, + "dependencies": { + "ext-list": "^2.0.0", + "sort-keys-length": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "dependencies": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true, + "engines": [ + "node >=0.6.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.5", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", + "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8" + } + }, + "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/fastq": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", + "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", + "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", + "dev": true, + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/figgy-pudding": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", + "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", + "dev": true + }, + "node_modules/file-loader": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-4.3.0.tgz", + "integrity": "sha512-aKrYPYjF1yG3oX0kWRrqrSMfgftm7oJW5M+m4owoldH5C51C0RkIwB++JbRvEW3IU6/ZG5n8UvEcdgwOt2UOWA==", + "dev": true, + "dependencies": { + "loader-utils": "^1.2.3", + "schema-utils": "^2.5.0" + }, + "engines": { + "node": ">= 8.9.0" + }, + "peerDependencies": { + "webpack": "^4.0.0" + } + }, + "node_modules/file-type": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-11.1.0.tgz", + "integrity": "sha512-rM0UO7Qm9K7TWTtA6AShI/t7H5BPjDeGVDaNyg9BjHAj3PysKy7+8C8D137R88jnR3rFJZQB/tFgydl5sN5m7g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, + "node_modules/filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/filename-reserved-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", + "integrity": "sha1-q/c9+rc10EVECr/qLZHzieu/oik=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/filenamify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-3.0.0.tgz", + "integrity": "sha512-5EFZ//MsvJgXjBAFJ+Bh2YaCTRF/VP1YOmGrgt+KJ4SFRLjI87EIdwLLuT6wQX0I4F9W41xutobzczjsOKlI/g==", + "dev": true, + "dependencies": { + "filename-reserved-regex": "^2.0.0", + "strip-outer": "^1.0.0", + "trim-repeated": "^1.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/filesize": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-3.6.1.tgz", + "integrity": "sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg==", + "dev": true, + "engines": { + "node": ">= 0.4.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==", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/find-cache-dir": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/avajs/find-cache-dir?sponsor=1" + } + }, + "node_modules/find-cache-dir/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/find-cache-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/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/first-chunk-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz", + "integrity": "sha1-Wb+1DNkF9g18OUzT2ayqtOatk04=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "node_modules/follow-redirects": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz", + "integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "dependencies": { + "for-in": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/fork-ts-checker-webpack-plugin": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-3.1.1.tgz", + "integrity": "sha512-DuVkPNrM12jR41KM2e+N+styka0EgLkTnXmNcXdgOM37vtGeY+oCBK/Jx0hzSeEU6memFCtWb4htrHPMDfwwUQ==", + "dev": true, + "dependencies": { + "babel-code-frame": "^6.22.0", + "chalk": "^2.4.1", + "chokidar": "^3.3.0", + "micromatch": "^3.1.10", + "minimatch": "^3.0.4", + "semver": "^5.6.0", + "tapable": "^1.0.0", + "worker-rpc": "^0.1.0" + }, + "engines": { + "node": ">=6.11.5", + "yarn": ">=1.0.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin-v5": { + "name": "fork-ts-checker-webpack-plugin", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-5.2.1.tgz", + "integrity": "sha512-SVi+ZAQOGbtAsUWrZvGzz38ga2YqjWvca1pXQFUArIVXqli0lLoDQ8uS0wg0kSpcwpZmaW5jVCZXQebkyUQSsw==", + "dev": true, + "optional": true, + "dependencies": { + "@babel/code-frame": "^7.8.3", + "@types/json-schema": "^7.0.5", + "chalk": "^4.1.0", + "cosmiconfig": "^6.0.0", + "deepmerge": "^4.2.2", + "fs-extra": "^9.0.0", + "memfs": "^3.1.2", + "minimatch": "^3.0.4", + "schema-utils": "2.7.0", + "semver": "^7.3.2", + "tapable": "^1.0.0" + }, + "engines": { + "node": ">=10", + "yarn": ">=1.0.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin-v5/node_modules/cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "dev": true, + "optional": true, + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fork-ts-checker-webpack-plugin-v5/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, + "optional": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/fork-ts-checker-webpack-plugin-v5/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, + "optional": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fork-ts-checker-webpack-plugin-v5/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, + "optional": 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/fork-ts-checker-webpack-plugin-v5/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, + "optional": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/fork-ts-checker-webpack-plugin-v5/node_modules/schema-utils": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", + "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "dev": true, + "optional": true, + "dependencies": { + "@types/json-schema": "^7.0.4", + "ajv": "^6.12.2", + "ajv-keywords": "^3.4.1" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/fork-ts-checker-webpack-plugin-v5/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "optional": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fork-ts-checker-webpack-plugin-v5/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, + "optional": true + }, + "node_modules/fork-ts-checker-webpack-plugin/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/fork-ts-checker-webpack-plugin/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/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/fork-ts-checker-webpack-plugin/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/fork-ts-checker-webpack-plugin/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fork-ts-checker-webpack-plugin/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/fork-ts-checker-webpack-plugin/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "dependencies": { + "map-cache": "^0.2.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, + "node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "dev": true, + "dependencies": { + "minipass": "^2.6.0" + } + }, + "node_modules/fs-monkey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", + "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==", + "dev": true, + "optional": true + }, + "node_modules/fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dev": true, + "dependencies": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "node_modules/generic-names": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generic-names/-/generic-names-2.0.1.tgz", + "integrity": "sha512-kPCHWa1m9wGG/OwQpeweTwM/PYiQLrUIxXbt/P4Nic3LbGjCP0YwrALHW1uNLKZ0LIMg+RF+XRlj2ekT9ZlZAQ==", + "dev": true, + "dependencies": { + "loader-utils": "^1.1.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-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0" + } + }, + "node_modules/glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "dependencies": { + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/glob-base/node_modules/glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "dependencies": { + "is-glob": "^2.0.0" + } + }, + "node_modules/glob-base/node_modules/is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/glob-base/node_modules/is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dependencies": { + "is-extglob": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-stream": { + "version": "5.3.5", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-5.3.5.tgz", + "integrity": "sha1-pVZlqajM3EGRWofHAeMtTgFvrSI=", + "dependencies": { + "extend": "^3.0.0", + "glob": "^5.0.3", + "glob-parent": "^3.0.0", + "micromatch": "^2.3.7", + "ordered-read-streams": "^0.3.0", + "through2": "^0.6.0", + "to-absolute-glob": "^0.1.1", + "unique-stream": "^2.0.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/glob-stream/node_modules/arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "dependencies": { + "arr-flatten": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/glob-stream/node_modules/array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/glob-stream/node_modules/braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "dependencies": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/glob-stream/node_modules/expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "dependencies": { + "is-posix-bracket": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/glob-stream/node_modules/extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "dependencies": { + "is-extglob": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/glob-stream/node_modules/extglob/node_modules/is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/glob-stream/node_modules/glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dependencies": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/glob-stream/node_modules/glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dependencies": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "node_modules/glob-stream/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/glob-stream/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "node_modules/glob-stream/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/glob-stream/node_modules/micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "dependencies": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/glob-stream/node_modules/micromatch/node_modules/is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/glob-stream/node_modules/micromatch/node_modules/is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dependencies": { + "is-extglob": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/glob-stream/node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/glob-stream/node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/glob-stream/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "node_modules/glob-stream/node_modules/through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "dependencies": { + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", + "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=", + "dev": true + }, + "node_modules/google-protobuf": { + "version": "3.15.8", + "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.15.8.tgz", + "integrity": "sha512-2jtfdqTaSxk0cuBJBtTTWsot4WtR9RVr2rXg7x7OoqiuOKopPrwXpM1G4dXIkLcUNRh3RKzz76C8IOkksZSeOw==", + "dev": true + }, + "node_modules/got": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/got/-/got-8.3.2.tgz", + "integrity": "sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==", + "dev": true, + "dependencies": { + "@sindresorhus/is": "^0.7.0", + "cacheable-request": "^2.1.1", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "into-stream": "^3.1.0", + "is-retry-allowed": "^1.1.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "mimic-response": "^1.0.0", + "p-cancelable": "^0.4.0", + "p-timeout": "^2.0.1", + "pify": "^3.0.0", + "safe-buffer": "^5.1.1", + "timed-out": "^4.0.1", + "url-parse-lax": "^3.0.0", + "url-to-options": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/got/node_modules/get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/got/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" + }, + "node_modules/grpc_tools_node_protoc_ts": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/grpc_tools_node_protoc_ts/-/grpc_tools_node_protoc_ts-5.2.2.tgz", + "integrity": "sha512-j8waJdU9uzNSyYJfEAGFFJdxP2C3k7RNkgI1dXxLB/iaT+D54p/RX1Wo+cHH2wPhBSE8hnv+BUv7HuEVT/XLPw==", + "dev": true, + "dependencies": { + "google-protobuf": "3.15.8", + "handlebars": "4.7.7" + }, + "bin": { + "protoc-gen-ts": "bin/protoc-gen-ts" + } + }, + "node_modules/grpc-tools": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/grpc-tools/-/grpc-tools-1.11.1.tgz", + "integrity": "sha512-QNz6xuiyBuHXKu78bv5PAOzv/EBKkH54OgeTkHyFkic8TrY8oiifs6hozRJQxJb+L7k+udWYmPvfK76Pgt4JhA==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "node-pre-gyp": "^0.15.0" + }, + "bin": { + "grpc_tools_node_protoc": "bin/protoc.js", + "grpc_tools_node_protoc_plugin": "bin/protoc_plugin.js" + } + }, + "node_modules/grpc-web": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/grpc-web/-/grpc-web-1.2.1.tgz", + "integrity": "sha512-ibBaJPzfMVuLPgaST9w0kZl60s+SnkPBQp6QKdpEr85tpc1gXW2QDqSne9xiyiym0logDfdUSm4aX5h9YBA2mw==" + }, + "node_modules/gulp-sourcemaps": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-1.12.1.tgz", + "integrity": "sha1-tDfR89mAzyboEYSCNxjOFa5ll7Y=", + "dependencies": { + "@gulp-sourcemaps/map-sources": "1.X", + "acorn": "4.X", + "convert-source-map": "1.X", + "css": "2.X", + "debug-fabulous": "0.0.X", + "detect-newline": "2.X", + "graceful-fs": "4.X", + "source-map": "~0.6.0", + "strip-bom": "2.X", + "through2": "2.X", + "vinyl": "1.X" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gulp-sourcemaps/node_modules/acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/gzip-size": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz", + "integrity": "sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA==", + "dev": true, + "dependencies": { + "duplexer": "^0.1.1", + "pify": "^4.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "dev": true + }, + "node_modules/handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "dev": true, + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbol-support-x": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", + "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-to-string-tag-x": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", + "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", + "dev": true, + "dependencies": { + "has-symbol-support-x": "^1.4.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "dev": true + }, + "node_modules/has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "dependencies": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash-base/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/hash-base/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/hash-sum": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz", + "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==", + "dev": true + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/hex-color-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", + "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==", + "dev": true + }, + "node_modules/highlight.js": { + "version": "10.7.2", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.2.tgz", + "integrity": "sha512-oFLl873u4usRM9K63j4ME9u3etNF0PLiJhSQ8rdfuL51Wn3zkD6drf9ZW0dOzjnZI22YYG24z30JcmfCZjMgYg==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/hoopy": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", + "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==", + "dev": true, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==" + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hsl-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz", + "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=", + "dev": true + }, + "node_modules/hsla-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz", + "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=", + "dev": true + }, + "node_modules/html-entities": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.4.0.tgz", + "integrity": "sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA==", + "dev": true + }, + "node_modules/html-minifier": { + "version": "3.5.21", + "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.21.tgz", + "integrity": "sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==", + "dev": true, + "dependencies": { + "camel-case": "3.0.x", + "clean-css": "4.2.x", + "commander": "2.17.x", + "he": "1.2.x", + "param-case": "2.1.x", + "relateurl": "0.2.x", + "uglify-js": "3.4.x" + }, + "bin": { + "html-minifier": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/html-minifier/node_modules/commander": { + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", + "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", + "dev": true + }, + "node_modules/html-minifier/node_modules/uglify-js": { + "version": "3.4.10", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz", + "integrity": "sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==", + "dev": true, + "dependencies": { + "commander": "~2.19.0", + "source-map": "~0.6.1" + }, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/html-minifier/node_modules/uglify-js/node_modules/commander": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", + "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", + "dev": true + }, + "node_modules/html-tags": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.1.0.tgz", + "integrity": "sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/html-webpack-plugin": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-3.2.0.tgz", + "integrity": "sha1-sBq71yOsqqeze2r0SS69oD2d03s=", + "deprecated": "3.x is no longer supported", + "dev": true, + "dependencies": { + "html-minifier": "^3.2.3", + "loader-utils": "^0.2.16", + "lodash": "^4.17.3", + "pretty-error": "^2.0.2", + "tapable": "^1.0.0", + "toposort": "^1.0.0", + "util.promisify": "1.0.0" + }, + "engines": { + "node": ">=6.9" + }, + "peerDependencies": { + "webpack": "^1.0.0 || ^2.0.0 || ^3.0.0 || ^4.0.0" + } + }, + "node_modules/html-webpack-plugin/node_modules/big.js": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", + "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/html-webpack-plugin/node_modules/emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/html-webpack-plugin/node_modules/json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/html-webpack-plugin/node_modules/loader-utils": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", + "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", + "dev": true, + "dependencies": { + "big.js": "^3.1.3", + "emojis-list": "^2.0.0", + "json5": "^0.5.0", + "object-assign": "^4.0.1" + } + }, + "node_modules/htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "dev": true, + "dependencies": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + } + }, + "node_modules/htmlparser2/node_modules/entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true + }, + "node_modules/htmlparser2/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/http-cache-semantics": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", + "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==", + "dev": true + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", + "dev": true + }, + "node_modules/http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-errors/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "node_modules/http-parser-js": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.3.tgz", + "integrity": "sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg==", + "dev": true + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-middleware": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-1.3.1.tgz", + "integrity": "sha512-13eVVDYS4z79w7f1+NPllJtOQFx/FdUW4btIvVRMaRlUY9VGstAbo5MOhLEuUgZFRHn3x50ufn25zkj/boZnEg==", + "dev": true, + "dependencies": { + "@types/http-proxy": "^1.17.5", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-middleware/node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "node_modules/human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true, + "engines": { + "node": ">=8.12.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-replace-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", + "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=", + "dev": true + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >= 14" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", + "dev": true + }, + "node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-walk": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.4.tgz", + "integrity": "sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ==", + "dev": true, + "dependencies": { + "minimatch": "^3.0.4" + } + }, + "node_modules/import-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", + "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=", + "dev": true, + "dependencies": { + "import-from": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "dependencies": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-from": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", + "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=", + "dev": true, + "dependencies": { + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "dev": true, + "dependencies": { + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/import-local/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/import-local/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/import-local/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/import-local/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/import-local/node_modules/pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", + "dev": true + }, + "node_modules/infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "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==" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/internal-ip": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", + "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", + "dev": true, + "dependencies": { + "default-gateway": "^4.2.0", + "ipaddr.js": "^1.9.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/internal-ip/node_modules/default-gateway": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", + "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", + "dev": true, + "dependencies": { + "execa": "^1.0.0", + "ip-regex": "^2.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/into-stream": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz", + "integrity": "sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY=", + "dev": true, + "dependencies": { + "from2": "^2.1.1", + "p-is-promise": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "dev": true + }, + "node_modules/ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-absolute-url": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", + "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-arguments": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", + "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, + "node_modules/is-bigint": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz", + "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz", + "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "node_modules/is-callable": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-ci": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", + "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", + "dev": true, + "dependencies": { + "ci-info": "^1.5.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-color-stop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", + "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=", + "dev": true, + "dependencies": { + "css-color-names": "^0.0.4", + "hex-color-regex": "^1.1.0", + "hsl-regex": "^1.0.0", + "hsla-regex": "^1.0.0", + "rgb-regex": "^1.0.1", + "rgba-regex": "^1.0.0" + } + }, + "node_modules/is-core-module": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", + "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", + "dependencies": { + "has": "^1.0.3" + } + }, + "node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-date-object": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", + "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "dependencies": { + "is-primitive": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-natural-number": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", + "integrity": "sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=", + "dev": true + }, + "node_modules/is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz", + "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", + "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-path-in-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", + "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", + "dev": true, + "dependencies": { + "is-path-inside": "^2.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-path-inside": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", + "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", + "dev": true, + "dependencies": { + "path-is-inside": "^1.0.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regex": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", + "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "dev": true + }, + "node_modules/is-retry-allowed": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", + "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-string": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", + "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "node_modules/is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" + }, + "node_modules/is-valid-glob": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-0.3.0.tgz", + "integrity": "sha1-1LVcafUYhvm2XHDWwmItN+KfSP4=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "node_modules/isurl": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", + "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", + "dev": true, + "dependencies": { + "has-to-string-tag-x": "^1.2.0", + "is-object": "^1.0.1" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/javascript-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", + "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==", + "dev": true + }, + "node_modules/jquery": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz", + "integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw==" + }, + "node_modules/js-message": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/js-message/-/js-message-1.0.7.tgz", + "integrity": "sha512-efJLHhLjIyKRewNS9EGZ4UpI8NguuL6fKkhRxVuMmrGV2xN/0APGdQYwLFky5w9naebSZ0OwAGp0G6/2Cg90rA==", + "dev": true, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/js-queue": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/js-queue/-/js-queue-2.0.2.tgz", + "integrity": "sha512-pbKLsbCfi7kriM3s1J4DDCo7jQkI58zPLHi0heXPzPlj0hjUsm+FesPUbE0DSbIVIK503A36aUBoCN7eMFedkA==", + "dev": true, + "dependencies": { + "easy-stack": "^1.0.1" + }, + "engines": { + "node": ">=1.0.0" + } + }, + "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": "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/jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "node_modules/json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "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": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "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": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "node_modules/json3": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz", + "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==", + "dev": true + }, + "node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "node_modules/jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "node_modules/keycharm": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/keycharm/-/keycharm-0.4.0.tgz", + "integrity": "sha512-TyQTtsabOVv3MeOpR92sIKk/br9wxS+zGj4BG7CR8YbK4jM3tyIBaF0zhzeBUMx36/Q/iQLOKKOT+3jOQtemRQ==", + "peer": true + }, + "node_modules/keyv": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz", + "integrity": "sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.0" + } + }, + "node_modules/killable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", + "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==", + "dev": true + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/launch-editor": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.2.1.tgz", + "integrity": "sha512-On+V7K2uZK6wK7x691ycSUbLD/FyKKelArkbaAMSSJU8JmqmhwN2+mnJDNINuJWSrh2L0kDk+ZQtbC/gOWUwLw==", + "dev": true, + "dependencies": { + "chalk": "^2.3.0", + "shell-quote": "^1.6.1" + } + }, + "node_modules/launch-editor-middleware": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/launch-editor-middleware/-/launch-editor-middleware-2.2.1.tgz", + "integrity": "sha512-s0UO2/gEGiCgei3/2UN3SMuUj1phjQN8lcpnvgLSz26fAzNWPQ6Nf/kF5IFClnfU2ehp6LrmKdMU/beveO+2jg==", + "dev": true, + "dependencies": { + "launch-editor": "^2.2.1" + } + }, + "node_modules/launch-editor/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/launch-editor/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/launch-editor/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/launch-editor/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/launch-editor/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/launch-editor/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/lazy-debug-legacy": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/lazy-debug-legacy/-/lazy-debug-legacy-0.0.1.tgz", + "integrity": "sha1-U3cWwHduTPeePtG2IfdljCkRsbE=", + "peerDependencies": { + "debug": "*" + } + }, + "node_modules/lazystream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", + "dependencies": { + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 0.6.3" + } + }, + "node_modules/lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dependencies": { + "invert-kv": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/leader-line-new": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/leader-line-new/-/leader-line-new-1.1.9.tgz", + "integrity": "sha512-x56aRYaqJTA4aAS2fgbSpvWKY3IxRXDSFeGkNBmCQ3LX44B3F1HEjcBTkCiK5I3W0nPWeUTWe7dTt59VtdfFWw==" + }, + "node_modules/lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "node_modules/listenercount": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", + "integrity": "sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc=", + "dev": true + }, + "node_modules/load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/load-json-file/node_modules/parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dependencies": { + "error-ex": "^1.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/load-json-file/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/loader-runner": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", + "dev": true, + "engines": { + "node": ">=4.3.0 <5.0.0 || >=5.10" + } + }, + "node_modules/loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "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/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" + }, + "node_modules/lodash.assign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=" + }, + "node_modules/lodash.assigninwith": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assigninwith/-/lodash.assigninwith-4.2.0.tgz", + "integrity": "sha1-rwLJhDKshtk9ppW0voAUAZcXNq8=" + }, + "node_modules/lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", + "dev": true + }, + "node_modules/lodash.defaultsdeep": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz", + "integrity": "sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==", + "dev": true + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" + }, + "node_modules/lodash.keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-4.2.0.tgz", + "integrity": "sha1-oIYCrBLk+4P5H8H7ejYKTZujUgU=" + }, + "node_modules/lodash.mapvalues": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz", + "integrity": "sha1-G6+lAF3p3W9PJmaMMMo3IwzJaJw=", + "dev": true + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "dev": true + }, + "node_modules/lodash.rest": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/lodash.rest/-/lodash.rest-4.0.5.tgz", + "integrity": "sha1-lU73UEkmIDjJbR/Jiyj9r58Hcqo=" + }, + "node_modules/lodash.template": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.2.4.tgz", + "integrity": "sha1-0FPBno50442WW/T7SV2A8Qnn96Q=", + "dependencies": { + "lodash._reinterpolate": "~3.0.0", + "lodash.assigninwith": "^4.0.0", + "lodash.keys": "^4.0.0", + "lodash.rest": "^4.0.0", + "lodash.templatesettings": "^4.0.0", + "lodash.tostring": "^4.0.0" + } + }, + "node_modules/lodash.templatesettings": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", + "dependencies": { + "lodash._reinterpolate": "^3.0.0" + } + }, + "node_modules/lodash.toarray": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz", + "integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE=" + }, + "node_modules/lodash.topath": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/lodash.topath/-/lodash.topath-4.5.2.tgz", + "integrity": "sha1-NhY1Hzu6YZlKCTGYlmC9AyVP0Ak=" + }, + "node_modules/lodash.tostring": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/lodash.tostring/-/lodash.tostring-4.1.4.tgz", + "integrity": "sha1-Vgwn0fjq3eA8LM4Zj+9cAx2CmPs=" + }, + "node_modules/lodash.transform": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.transform/-/lodash.transform-4.6.0.tgz", + "integrity": "sha1-EjBkIvYzJK7YSD0/ODMrX2cFR6A=", + "dev": true + }, + "node_modules/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", + "dev": true + }, + "node_modules/log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "dependencies": { + "chalk": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/log-symbols/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/log-symbols/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/log-symbols/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/log-symbols/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/log-symbols/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/log-symbols/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/loglevel": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.7.1.tgz", + "integrity": "sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/loglevel" + } + }, + "node_modules/lower-case": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", + "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=", + "dev": true + }, + "node_modules/lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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/magic-string": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", + "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", + "dev": true, + "dependencies": { + "sourcemap-codec": "^1.4.4" + } + }, + "node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-stream": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.6.tgz", + "integrity": "sha1-0u9OuBGihkTHqJiZhcacL91JaCc=" + }, + "node_modules/map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "dependencies": { + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/math-random": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", + "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==" + }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/mdn-data": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", + "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", + "dev": true + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.2.2.tgz", + "integrity": "sha512-RE0CwmIM3CEvpcdK3rZ19BC4E6hv9kADkMN5rPduRak58cNArWLi/9jFLsa4rhsjfVxMP3v0jO7FHXq7SvFY5Q==", + "dev": true, + "optional": true, + "dependencies": { + "fs-monkey": "1.0.3" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/memory-fs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", + "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", + "dev": true, + "dependencies": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + }, + "engines": { + "node": ">=4.3.0 <5.0.0 || >=5.10" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, + "node_modules/merge-source-map": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", + "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", + "dev": true, + "dependencies": { + "source-map": "^0.6.1" + } + }, + "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==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/microevent.ts": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/microevent.ts/-/microevent.ts-0.1.1.tgz", + "integrity": "sha512-jo1OfR4TaEwd5HOrt5+tAZ9mqT4jmpNAusXtyfNzqVm9uiSYFZlKM1wYL4oU7azZW/PxQW53wM0S6OR1JHNa2g==", + "dev": true + }, + "node_modules/micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dependencies": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "dependencies": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "bin": { + "miller-rabin": "bin/miller-rabin" + } + }, + "node_modules/miller-rabin/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/mime": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", + "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.47.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", + "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.30", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", + "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", + "dev": true, + "dependencies": { + "mime-db": "1.47.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz", + "integrity": "sha512-lp3GeY7ygcgAmVIcRPBVhIkf8Us7FZjA+ILpal44qLdSu11wmjKQ3d9k15lfD7pO4esu9eUIAW7qiYIBppv40A==", + "dev": true, + "dependencies": { + "loader-utils": "^1.1.0", + "normalize-url": "1.9.1", + "schema-utils": "^1.0.0", + "webpack-sources": "^1.1.0" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "webpack": "^4.4.0" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/normalize-url": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", + "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", + "dev": true, + "dependencies": { + "object-assign": "^4.0.1", + "prepend-http": "^1.0.0", + "query-string": "^4.1.0", + "sort-keys": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/query-string": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", + "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", + "dev": true, + "dependencies": { + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", + "dev": true, + "dependencies": { + "is-plain-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "node_modules/minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "node_modules/minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "dev": true, + "dependencies": { + "minipass": "^2.9.0" + } + }, + "node_modules/mississippi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "dev": true, + "dependencies": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^3.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "dependencies": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/modern-normalize": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/modern-normalize/-/modern-normalize-1.1.0.tgz", + "integrity": "sha512-2lMlY1Yc1+CUy0gw4H95uNN7vjbpoED7NNRSBHE25nWfLBdmMzFCsPshlzbxHz+gYMcBEUN8V4pU16prcdPSgA==", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/module": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/module/-/module-1.2.5.tgz", + "integrity": "sha1-tQPrBs3BNHP1aBhCaXTN5+xZvxU=", + "dependencies": { + "chalk": "1.1.3", + "concat-stream": "1.5.1", + "lodash.template": "4.2.4", + "map-stream": "0.0.6", + "tildify": "1.2.0", + "vinyl-fs": "2.4.3", + "yargs": "4.6.0" + }, + "bin": { + "module": "dist/cli.js" + } + }, + "node_modules/module/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/module/node_modules/camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/module/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/module/node_modules/cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + } + }, + "node_modules/module/node_modules/concat-stream": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.1.tgz", + "integrity": "sha1-87gKz54fSOOHXAaItBtsMWAu6hw=", + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "inherits": "~2.0.1", + "readable-stream": "~2.0.0", + "typedarray": "~0.0.5" + } + }, + "node_modules/module/node_modules/process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "node_modules/module/node_modules/readable-stream": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/module/node_modules/require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" + }, + "node_modules/module/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "node_modules/module/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/module/node_modules/wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dependencies": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/module/node_modules/y18n": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", + "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==" + }, + "node_modules/module/node_modules/yargs": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.6.0.tgz", + "integrity": "sha1-y0BQwBWb+2u2ScD0r1UFJqhGGdw=", + "dependencies": { + "camelcase": "^2.0.1", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "lodash.assign": "^4.0.3", + "os-locale": "^1.4.0", + "pkg-conf": "^1.1.2", + "read-pkg-up": "^1.0.1", + "require-main-filename": "^1.0.1", + "string-width": "^1.0.1", + "window-size": "^0.2.0", + "y18n": "^3.2.1", + "yargs-parser": "^2.4.0" + } + }, + "node_modules/module/node_modules/yargs-parser": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", + "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=", + "dependencies": { + "camelcase": "^3.0.0", + "lodash.assign": "^4.0.6" + } + }, + "node_modules/module/node_modules/yargs-parser/node_modules/camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/moment": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==", + "engines": { + "node": "*" + } + }, + "node_modules/move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "dev": true, + "dependencies": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "node_modules/multicast-dns": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", + "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", + "dev": true, + "dependencies": { + "dns-packet": "^1.3.1", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/multicast-dns-service-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", + "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", + "dev": true + }, + "node_modules/mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "node_modules/nan": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", + "dev": true, + "optional": true + }, + "node_modules/nanoid": { + "version": "3.1.23", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz", + "integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/needle": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.6.0.tgz", + "integrity": "sha512-KKYdza4heMsEfSWD7VPUIz3zX2XDwOyX2d+geb4vrERZMT5RMU6ujjaD+I5Yr54uZxQ2w6XRTAhHBbSCyovZBg==", + "dev": true, + "dependencies": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, + "node_modules/negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node_modules/no-case": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", + "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", + "dev": true, + "dependencies": { + "lower-case": "^1.1.1" + } + }, + "node_modules/node-emoji": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.10.0.tgz", + "integrity": "sha512-Yt3384If5H6BYGVHiHwTL+99OzJKHhgp82S8/dktEK73T26BazdgZ4JZh92xSVtGNJvz9UbXdNAc5hcrXV42vw==", + "dependencies": { + "lodash.toarray": "^4.4.0" + } + }, + "node_modules/node-forge": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", + "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", + "dev": true, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/node-ipc": { + "version": "9.1.4", + "resolved": "https://registry.npmjs.org/node-ipc/-/node-ipc-9.1.4.tgz", + "integrity": "sha512-A+f0mn2KxUt1uRTSd5ktxQUsn2OEhj5evo7NUi/powBzMSZ0vocdzDjlq9QN2v3LH6CJi3e5xAenpZ1QwU5A8g==", + "dev": true, + "dependencies": { + "event-pubsub": "4.3.0", + "js-message": "1.0.7", + "js-queue": "2.0.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "dev": true, + "dependencies": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "^1.0.1" + } + }, + "node_modules/node-libs-browser/node_modules/buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "dependencies": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "node_modules/node-libs-browser/node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "node_modules/node-pre-gyp": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.15.0.tgz", + "integrity": "sha512-7QcZa8/fpaU/BKenjcaeFF9hLz2+7S9AqyXFhlH/rilsQ/hPZKK32RtR5EQHJElgu+q5RfbJ34KriI79UWaorA==", + "deprecated": "Please upgrade to @mapbox/node-pre-gyp: the non-scoped node-pre-gyp package is deprecated and only the @mapbox scoped package will recieve updates in the future", + "dev": true, + "dependencies": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.3", + "needle": "^2.5.0", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4.4.2" + }, + "bin": { + "node-pre-gyp": "bin/node-pre-gyp" + } + }, + "node_modules/node-releases": { + "version": "1.1.72", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", + "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==" + }, + "node_modules/nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "dev": true, + "dependencies": { + "abbrev": "1", + "osenv": "^0.1.4" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "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==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-url": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz", + "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==", + "dev": true, + "dependencies": { + "prepend-http": "^2.0.0", + "query-string": "^5.0.1", + "sort-keys": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm-bundled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz", + "integrity": "sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==", + "dev": true, + "dependencies": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", + "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", + "dev": true + }, + "node_modules/npm-packlist": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", + "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", + "dev": true, + "dependencies": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dev": true, + "dependencies": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "node_modules/nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "dev": true, + "dependencies": { + "boolbase": "~1.0.0" + } + }, + "node_modules/num2fraction": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=" + }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "dependencies": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/is-descriptor/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-hash": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", + "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/object-inspect": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", + "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "dependencies": { + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.getownpropertydescriptors": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz", + "integrity": "sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "dependencies": { + "for-own": "^0.1.4", + "is-extendable": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.omit/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.values": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.3.tgz", + "integrity": "sha512-nkF6PfDB9alkOUxpf1HNm/QlkeW3SReqL5WXeBLpEJJnlPSvRaDQpW3gQTksTN3fgJX4hL42RzKyOin6ff3tyw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2", + "has": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true + }, + "node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "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/open": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/open/-/open-6.4.0.tgz", + "integrity": "sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==", + "dev": true, + "dependencies": { + "is-wsl": "^1.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/open/node_modules/is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "dev": true, + "bin": { + "opener": "bin/opener-bin.js" + } + }, + "node_modules/opn": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", + "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", + "dev": true, + "dependencies": { + "is-wsl": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/opn/node_modules/is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ora": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz", + "integrity": "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==", + "dev": true, + "dependencies": { + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-spinners": "^2.0.0", + "log-symbols": "^2.2.0", + "strip-ansi": "^5.2.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ora/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ora/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/ora/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/ora/node_modules/cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "dependencies": { + "restore-cursor": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ora/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/ora/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/ora/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ora/node_modules/mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ora/node_modules/onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "dependencies": { + "mimic-fn": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ora/node_modules/restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "dependencies": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ora/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/ora/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/ordered-read-streams": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz", + "integrity": "sha1-cTfmmzKYuzQiR6G77jiByA4v14s=", + "dependencies": { + "is-stream": "^1.0.1", + "readable-stream": "^2.0.1" + } + }, + "node_modules/original": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", + "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", + "dev": true, + "dependencies": { + "url-parse": "^1.4.3" + } + }, + "node_modules/os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, + "node_modules/os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "dependencies": { + "lcid": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "dependencies": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "node_modules/p-cancelable": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz", + "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-event": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-2.3.1.tgz", + "integrity": "sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA==", + "dev": true, + "dependencies": { + "p-timeout": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-is-promise": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", + "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "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/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/p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-retry": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz", + "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==", + "dev": true, + "dependencies": { + "retry": "^0.12.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-timeout": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz", + "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==", + "dev": true, + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "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/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + }, + "node_modules/parallel-transform": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", + "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", + "dev": true, + "dependencies": { + "cyclist": "^1.0.1", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + } + }, + "node_modules/param-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", + "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", + "dev": true, + "dependencies": { + "no-case": "^2.2.0" + } + }, + "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, + "optional": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parent-module/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, + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-asn1": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "dev": true, + "dependencies": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "dependencies": { + "glob-base": "^0.3.0", + "is-dotfile": "^1.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parse-glob/node_modules/is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parse-glob/node_modules/is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "dependencies": { + "is-extglob": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/parse5": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "dev": true + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", + "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", + "dev": true, + "dependencies": { + "parse5": "^6.0.1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter/node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "dev": true + }, + "node_modules/path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" + }, + "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": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "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, + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dev": true, + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, + "node_modules/performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", + "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==", + "engines": { + "node": ">=8.6" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pkg-conf": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-1.1.3.tgz", + "integrity": "sha1-N45W1v0T6Iv7b0ol33qD+qvduls=", + "dependencies": { + "find-up": "^1.0.0", + "load-json-file": "^1.1.0", + "object-assign": "^4.0.1", + "symbol": "^0.2.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pkg-conf/node_modules/find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dependencies": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pkg-conf/node_modules/path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dependencies": { + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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/pnp-webpack-plugin": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz", + "integrity": "sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg==", + "dev": true, + "dependencies": { + "ts-pnp": "^1.1.6" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/portfinder": { + "version": "1.0.28", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", + "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", + "dev": true, + "dependencies": { + "async": "^2.6.2", + "debug": "^3.1.1", + "mkdirp": "^0.5.5" + }, + "engines": { + "node": ">= 0.12.0" + } + }, + "node_modules/posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss": { + "version": "7.0.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", + "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", + "dependencies": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/postcss-calc": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.5.tgz", + "integrity": "sha512-1tKHutbGtLtEZF6PT4JSihCHfIVldU72mZ8SdZHIYriIZ9fh9k9aWSppaT8rHsyI3dX+KSR+W+Ix9BMY3AODrg==", + "dev": true, + "dependencies": { + "postcss": "^7.0.27", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.0.2" + } + }, + "node_modules/postcss-colormin": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz", + "integrity": "sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==", + "dev": true, + "dependencies": { + "browserslist": "^4.0.0", + "color": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-colormin/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-convert-values": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz", + "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-convert-values/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-discard-comments": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz", + "integrity": "sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-discard-duplicates": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz", + "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-discard-empty": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz", + "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-discard-overridden": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz", + "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-functions": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-functions/-/postcss-functions-3.0.0.tgz", + "integrity": "sha1-DpTQFERwCkgd4g3k1V+yZAVkJQ4=", + "dependencies": { + "glob": "^7.1.2", + "object-assign": "^4.1.1", + "postcss": "^6.0.9", + "postcss-value-parser": "^3.3.0" + } + }, + "node_modules/postcss-functions/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==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-functions/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==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-functions/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==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/postcss-functions/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "node_modules/postcss-functions/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-functions/node_modules/postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dependencies": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/postcss-functions/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/postcss-functions/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==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-js": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-2.0.3.tgz", + "integrity": "sha512-zS59pAk3deu6dVHyrGqmC3oDXBdNdajk4k1RyxeVXCrcEDBUBHoIhE4QTsmhxgzXxsaqFDAkUZfmMa5f/N/79w==", + "dependencies": { + "camelcase-css": "^2.0.1", + "postcss": "^7.0.18" + } + }, + "node_modules/postcss-load-config": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.2.tgz", + "integrity": "sha512-/rDeGV6vMUo3mwJZmeHfEDvwnTKKqQ0S7OHUi/kJvvtx3aWtyWG2/0ZWnzCt2keEclwN6Tf0DST2v9kITdOKYw==", + "dev": true, + "dependencies": { + "cosmiconfig": "^5.0.0", + "import-cwd": "^2.0.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/postcss-loader": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz", + "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==", + "dev": true, + "dependencies": { + "loader-utils": "^1.1.0", + "postcss": "^7.0.0", + "postcss-load-config": "^2.0.0", + "schema-utils": "^1.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss-loader/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/postcss-merge-longhand": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz", + "integrity": "sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==", + "dev": true, + "dependencies": { + "css-color-names": "0.0.4", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "stylehacks": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-merge-longhand/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-merge-rules": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz", + "integrity": "sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==", + "dev": true, + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "cssnano-util-same-parent": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0", + "vendors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-merge-rules/node_modules/postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dev": true, + "dependencies": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/postcss-minify-font-values": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz", + "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-minify-font-values/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-minify-gradients": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz", + "integrity": "sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==", + "dev": true, + "dependencies": { + "cssnano-util-get-arguments": "^4.0.0", + "is-color-stop": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-minify-gradients/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-minify-params": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz", + "integrity": "sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==", + "dev": true, + "dependencies": { + "alphanum-sort": "^1.0.0", + "browserslist": "^4.0.0", + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "uniqs": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-minify-params/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-minify-selectors": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz", + "integrity": "sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==", + "dev": true, + "dependencies": { + "alphanum-sort": "^1.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-minify-selectors/node_modules/postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dev": true, + "dependencies": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/postcss-modules": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules/-/postcss-modules-4.0.0.tgz", + "integrity": "sha512-ghS/ovDzDqARm4Zj6L2ntadjyQMoyJmi0JkLlYtH2QFLrvNlxH5OAVRPWPeKilB0pY7SbuhO173KOWkPAxRJcw==", + "dev": true, + "dependencies": { + "generic-names": "^2.0.1", + "icss-replace-symbols": "^1.1.0", + "lodash.camelcase": "^4.3.0", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.0", + "postcss-modules-scope": "^3.0.0", + "postcss-modules-values": "^4.0.0", + "string-hash": "^1.1.1" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >= 14" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz", + "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==", + "dev": true, + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", + "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dev": true, + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + } + }, + "node_modules/postcss-nested": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-4.2.3.tgz", + "integrity": "sha512-rOv0W1HquRCamWy2kFl3QazJMMe1ku6rCFoAAH+9AcxdbpDeBr6k968MLWuLjvjMcGEip01ak09hKOEgpK9hvw==", + "dependencies": { + "postcss": "^7.0.32", + "postcss-selector-parser": "^6.0.2" + } + }, + "node_modules/postcss-normalize-charset": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz", + "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-display-values": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz", + "integrity": "sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==", + "dev": true, + "dependencies": { + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-display-values/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-normalize-positions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz", + "integrity": "sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==", + "dev": true, + "dependencies": { + "cssnano-util-get-arguments": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-positions/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-normalize-repeat-style": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz", + "integrity": "sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==", + "dev": true, + "dependencies": { + "cssnano-util-get-arguments": "^4.0.0", + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-repeat-style/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-normalize-string": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz", + "integrity": "sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==", + "dev": true, + "dependencies": { + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-string/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-normalize-timing-functions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz", + "integrity": "sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==", + "dev": true, + "dependencies": { + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-timing-functions/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-normalize-unicode": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz", + "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==", + "dev": true, + "dependencies": { + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-unicode/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-normalize-url": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz", + "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==", + "dev": true, + "dependencies": { + "is-absolute-url": "^2.0.0", + "normalize-url": "^3.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-url/node_modules/normalize-url": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", + "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/postcss-normalize-url/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-normalize-whitespace": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz", + "integrity": "sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-normalize-whitespace/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-ordered-values": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz", + "integrity": "sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==", + "dev": true, + "dependencies": { + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-ordered-values/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-reduce-initial": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz", + "integrity": "sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==", + "dev": true, + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-reduce-transforms": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz", + "integrity": "sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==", + "dev": true, + "dependencies": { + "cssnano-util-get-match": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-reduce-transforms/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-selector-parser": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz", + "integrity": "sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-svgo": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.3.tgz", + "integrity": "sha512-NoRbrcMWTtUghzuKSoIm6XV+sJdvZ7GZSc3wdBN0W19FTtp2ko8NqLsgoh/m9CzNhU3KLPvQmjIwtaNFkaFTvw==", + "dev": true, + "dependencies": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "svgo": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-svgo/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/postcss-unique-selectors": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz", + "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==", + "dev": true, + "dependencies": { + "alphanum-sort": "^1.0.0", + "postcss": "^7.0.0", + "uniqs": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", + "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==" + }, + "node_modules/postcss/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==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss/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==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss/node_modules/chalk/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==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss/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==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/postcss/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "node_modules/postcss/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss/node_modules/supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", + "dev": true, + "optional": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pretty-error": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.2.tgz", + "integrity": "sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw==", + "dev": true, + "dependencies": { + "lodash": "^4.17.20", + "renderkid": "^2.0.4" + } + }, + "node_modules/pretty-hrtime": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", + "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", + "dev": true + }, + "node_modules/protoc-gen-grpc-web": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/protoc-gen-grpc-web/-/protoc-gen-grpc-web-1.2.1.tgz", + "integrity": "sha512-xQm+XdzNsZOxPYaM/pNvaYhA9J48zVbXbeMjADC+U14BVNadSgSenbQ7lih2xrRz+3kBYXhP2Gqqg7q/WwR9hw==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "download": "^8.0.0", + "fs-extra": "^9.0.1" + }, + "bin": { + "protoc-gen-grpc-web": "cli.js" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "dev": true, + "dependencies": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "node_modules/psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "node_modules/public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/public-encrypt/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, + "dependencies": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + } + }, + "node_modules/pumpify/node_modules/pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/purgecss": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/purgecss/-/purgecss-3.1.3.tgz", + "integrity": "sha512-hRSLN9mguJ2lzlIQtW4qmPS2kh6oMnA9RxdIYK8sz18QYqd6ePp4GNDl18oWHA1f2v2NEQIh51CO8s/E3YGckQ==", + "dependencies": { + "commander": "^6.0.0", + "glob": "^7.0.0", + "postcss": "^8.2.1", + "postcss-selector-parser": "^6.0.2" + }, + "bin": { + "purgecss": "bin/purgecss.js" + } + }, + "node_modules/purgecss/node_modules/postcss": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.0.tgz", + "integrity": "sha512-+ogXpdAjWGa+fdYY5BQ96V/6tAo+TdSSIMP5huJBIygdWwKtVoB5JWZ7yUd4xZ8r+8Kvvx4nyg/PQ071H4UtcQ==", + "dependencies": { + "colorette": "^1.2.2", + "nanoid": "^3.1.23", + "source-map-js": "^0.6.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "dev": true, + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } + }, + "node_modules/qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/query-string": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", + "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", + "dev": true, + "dependencies": { + "decode-uri-component": "^0.2.0", + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, + "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", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/randomatic": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", + "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", + "dependencies": { + "is-number": "^4.0.0", + "kind-of": "^6.0.0", + "math-random": "^1.0.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/randomatic/node_modules/is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "dependencies": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "dev": true, + "dependencies": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dependencies": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dependencies": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg-up/node_modules/path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dependencies": { + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg-up/node_modules/path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dependencies": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg-up/node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg-up/node_modules/read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dependencies": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg/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/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/reduce-css-calc": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-2.1.8.tgz", + "integrity": "sha512-8liAVezDmUcH+tdzoEGrhfbGcP7nOV4NkGE3a74+qqvE7nt9i4sKLGBuZNOnpI4WiGksiNPklZxva80061QiPg==", + "dependencies": { + "css-unit-converter": "^1.1.1", + "postcss-value-parser": "^3.3.0" + } + }, + "node_modules/reduce-css-calc/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "node_modules/regex-cache": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "dependencies": { + "is-equal-shallow": "^0.1.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "dependencies": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz", + "integrity": "sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/relative-time-parser": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/relative-time-parser/-/relative-time-parser-1.0.13.tgz", + "integrity": "sha512-e8w9MUXKwfW49BvkIjkMIjPt36CBk9obucgb7Z1I9NQdRxnV3hDvuTNSUBpYC5AhM7EuV8eYrs7w2l7SJFQAIA==", + "dependencies": { + "moment": "^2.24.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" + }, + "node_modules/renderkid": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.5.tgz", + "integrity": "sha512-ccqoLg+HLOHq1vdfYNm4TBeaCDIi1FLt3wGojTDSvdewUv65oTmI3cnT2E4hRjl1gzKZIPK+KZrXzlUYKnR+vQ==", + "dev": true, + "dependencies": { + "css-select": "^2.0.2", + "dom-converter": "^0.2", + "htmlparser2": "^3.10.1", + "lodash": "^4.17.20", + "strip-ansi": "^3.0.0" + } + }, + "node_modules/repeat-element": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", + "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/replace-ext": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", + "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dev": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "node_modules/resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dependencies": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "node_modules/resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "dev": true, + "dependencies": { + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "deprecated": "https://github.com/lydell/resolve-url#deprecated" + }, + "node_modules/responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, + "dependencies": { + "lowercase-keys": "^1.0.0" + } + }, + "node_modules/ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rgb-regex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", + "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=", + "dev": true + }, + "node_modules/rgba-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", + "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=", + "dev": true + }, + "node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/rollup": { + "version": "2.48.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.48.0.tgz", + "integrity": "sha512-wl9ZSSSsi5579oscSDYSzGn092tCS076YB+TQrzsGuSfYyJeep8eEWj0eaRjuC5McuMNmcnR8icBqiE/FWNB1A==", + "dev": true, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=10.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.1" + } + }, + "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==", + "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/run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "dev": true, + "dependencies": { + "aproba": "^1.1.1" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "node_modules/safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "dependencies": { + "ret": "~0.1.10" + } + }, + "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/sass": { + "version": "1.32.13", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.32.13.tgz", + "integrity": "sha512-dEgI9nShraqP7cXQH+lEXVf73WOPCse0QlFzSD8k+1TcOxCMwVXfQlr0jtoluZysQOyJGnfr21dLvYKDJq8HkA==", + "dev": true, + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/sass-loader": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-8.0.2.tgz", + "integrity": "sha512-7o4dbSK8/Ol2KflEmSco4jTjQoV988bM82P9CZdmo9hR3RLnvNc0ufMNdMrB0caq38JQ/FgF4/7RcbcfKzxoFQ==", + "dev": true, + "dependencies": { + "clone-deep": "^4.0.1", + "loader-utils": "^1.2.3", + "neo-async": "^2.6.1", + "schema-utils": "^2.6.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "fibers": ">= 3.1.0", + "node-sass": "^4.0.0", + "sass": "^1.3.0", + "webpack": "^4.36.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "fibers": { + "optional": true + }, + "node-sass": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/sass-loader/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/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "node_modules/schema-utils": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/seek-bzip": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz", + "integrity": "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==", + "dev": true, + "dependencies": { + "commander": "^2.8.1" + }, + "bin": { + "seek-bunzip": "bin/seek-bunzip", + "seek-table": "bin/seek-bzip-table" + } + }, + "node_modules/seek-bzip/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", + "dev": true + }, + "node_modules/selfsigned": { + "version": "1.10.11", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.11.tgz", + "integrity": "sha512-aVmbPOfViZqOZPgRBT0+3u4yZFHpmnIghLMlAcb5/xhp5ZtB/RVnKhz5vl2M32CLXAqR4kha9zfhNg0Lf/sxKA==", + "dev": true, + "dependencies": { + "node-forge": "^0.10.0" + } + }, + "node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/send/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "node_modules/serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", + "dev": true, + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "node_modules/serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "dev": true, + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "node_modules/set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/set-value/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/set-value/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "node_modules/setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "dev": true + }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shell-quote": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", + "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", + "dev": true + }, + "node_modules/signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "dependencies": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "dependencies": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "dependencies": { + "kind-of": "^3.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/snapdragon/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/snapdragon/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sockjs": { + "version": "0.3.21", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.21.tgz", + "integrity": "sha512-DhbPFGpxjc6Z3I+uX07Id5ZO2XwYsWOrYjaSeieES78cq+JaJvVe5q/m1uvjIQhXinhIeCFRH6JgXe+mvVMyXw==", + "dev": true, + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^3.4.0", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/sockjs-client": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.5.1.tgz", + "integrity": "sha512-VnVAb663fosipI/m6pqRXakEOw7nvd7TUgdr3PlR/8V2I95QIdwT8L4nMxhyU8SmDBHYXU1TOElaKOmKLfYzeQ==", + "dev": true, + "dependencies": { + "debug": "^3.2.6", + "eventsource": "^1.0.7", + "faye-websocket": "^0.11.3", + "inherits": "^2.0.4", + "json3": "^3.3.3", + "url-parse": "^1.5.1" + } + }, + "node_modules/sockjs/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/sort-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", + "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=", + "dev": true, + "dependencies": { + "is-plain-obj": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/sort-keys-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz", + "integrity": "sha1-nLb09OnkgVWmqgZx7dM2/xR5oYg=", + "dev": true, + "dependencies": { + "sort-keys": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sort-keys-length/node_modules/sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", + "dev": true, + "dependencies": { + "is-plain-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "dev": true + }, + "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==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz", + "integrity": "sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dependencies": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-url": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", + "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==" + }, + "node_modules/sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "dev": true + }, + "node_modules/spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.8.tgz", + "integrity": "sha512-NDgA96EnaLSvtbM7trJj+t1LUR3pirkDCcz9nOUlPb5DMBGsH7oES6C3hs3j7R9oHEa1EMvReS/BUAIT5Tcr0g==" + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/spdy-transport/node_modules/debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/spdy-transport/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/spdy-transport/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/spdy/node_modules/debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/spdy/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/split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "dependencies": { + "extend-shallow": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "dependencies": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ssri": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", + "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", + "dev": true, + "dependencies": { + "minipass": "^3.1.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/ssri/node_modules/minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ssri/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/stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "dev": true + }, + "node_modules/stackframe": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.2.0.tgz", + "integrity": "sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA==", + "dev": true + }, + "node_modules/static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "dependencies": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "dependencies": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "node_modules/stream-each": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", + "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "node_modules/stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "dependencies": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "node_modules/stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" + }, + "node_modules/strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string-hash": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/string-hash/-/string-hash-1.1.3.tgz", + "integrity": "sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs=", + "dev": true + }, + "node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dependencies": { + "is-utf8": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-bom-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-1.0.0.tgz", + "integrity": "sha1-5xRDmFd9Uaa+0PoZlPoF9D/ZiO4=", + "dependencies": { + "first-chunk-stream": "^1.0.0", + "strip-bom": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-dirs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", + "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", + "dev": true, + "dependencies": { + "is-natural-number": "^4.0.1" + } + }, + "node_modules/strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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-indent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", + "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-outer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", + "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stylehacks": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz", + "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==", + "dev": true, + "dependencies": { + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/stylehacks/node_modules/postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dev": true, + "dependencies": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/svgo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", + "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", + "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "coa": "^2.0.2", + "css-select": "^2.0.0", + "css-select-base-adapter": "^0.1.1", + "css-tree": "1.0.0-alpha.37", + "csso": "^4.0.2", + "js-yaml": "^3.13.1", + "mkdirp": "~0.5.1", + "object.values": "^1.1.0", + "sax": "~1.2.4", + "stable": "^0.1.8", + "unquote": "~1.1.1", + "util.promisify": "~1.0.0" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/svgo/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/svgo/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/svgo/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/svgo/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/svgo/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/svgo/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/symbol": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/symbol/-/symbol-0.2.3.tgz", + "integrity": "sha1-O5hzuKkB5Hxu/iFSajrDcu8ou8c=" + }, + "node_modules/tailwindcss": { + "name": "@tailwindcss/postcss7-compat", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/postcss7-compat/-/postcss7-compat-2.1.3.tgz", + "integrity": "sha512-SuuCv7XkB2WIdTsiRLCX8eTF6s2r7E+0aIg+ASYZE/5YAJlojYWDENth+ywRJpWXW1ZoQKo0g/8xsMKijzPm8g==", + "dependencies": { + "@fullhuman/postcss-purgecss": "^3.1.3", + "autoprefixer": "^9", + "bytes": "^3.0.0", + "chalk": "^4.1.0", + "chokidar": "^3.5.1", + "color": "^3.1.3", + "detective": "^5.2.0", + "didyoumean": "^1.2.1", + "dlv": "^1.1.3", + "fast-glob": "^3.2.5", + "fs-extra": "^9.1.0", + "html-tags": "^3.1.0", + "lodash": "^4.17.21", + "lodash.topath": "^4.5.2", + "modern-normalize": "^1.0.0", + "node-emoji": "^1.8.1", + "normalize-path": "^3.0.0", + "object-hash": "^2.1.1", + "parse-glob": "^3.0.4", + "postcss": "^7", + "postcss-functions": "^3", + "postcss-js": "^2", + "postcss-nested": "^4", + "postcss-selector-parser": "^6.0.4", + "postcss-value-parser": "^4.1.0", + "pretty-hrtime": "^1.0.3", + "quick-lru": "^5.1.1", + "reduce-css-calc": "^2.1.8", + "resolve": "^1.20.0" + }, + "bin": { + "tailwind": "lib/cli.js", + "tailwindcss": "lib/cli.js" + }, + "engines": { + "node": ">=12.13.0" + } + }, + "node_modules/tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar": { + "version": "4.4.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", + "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", + "dev": true, + "dependencies": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + }, + "engines": { + "node": ">=4.5" + } + }, + "node_modules/tar-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", + "dev": true, + "dependencies": { + "bl": "^1.0.0", + "buffer-alloc": "^1.2.0", + "end-of-stream": "^1.0.0", + "fs-constants": "^1.0.0", + "readable-stream": "^2.3.0", + "to-buffer": "^1.1.1", + "xtend": "^4.0.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/terser": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz", + "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==", + "dev": true, + "dependencies": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz", + "integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==", + "dev": true, + "dependencies": { + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", + "is-wsl": "^1.1.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^4.0.0", + "source-map": "^0.6.1", + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", + "worker-farm": "^1.7.0" + }, + "engines": { + "node": ">= 6.9.0" + }, + "peerDependencies": { + "webpack": "^4.0.0" + } + }, + "node_modules/terser-webpack-plugin/node_modules/find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "dependencies": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser-webpack-plugin/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser-webpack-plugin/node_modules/is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/terser-webpack-plugin/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser-webpack-plugin/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser-webpack-plugin/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/terser-webpack-plugin/node_modules/pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "node_modules/thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=", + "dev": true, + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/thread-loader": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/thread-loader/-/thread-loader-2.1.3.tgz", + "integrity": "sha512-wNrVKH2Lcf8ZrWxDF/khdlLlsTMczdcwPA9VEK4c2exlEPynYWxi9op3nPTo5lAnDIkE0rQEB3VBP+4Zncc9Hg==", + "dev": true, + "dependencies": { + "loader-runner": "^2.3.1", + "loader-utils": "^1.1.0", + "neo-async": "^2.6.0" + }, + "engines": { + "node": ">= 6.9.0 <7.0.0 || >= 8.9.0" + }, + "peerDependencies": { + "webpack": "^2.0.0 || ^3.0.0 || ^4.0.0" + } + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/through2-filter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-2.0.0.tgz", + "integrity": "sha1-YLxVoNrLdghdsfna6Zq0P4PWIuw=", + "dependencies": { + "through2": "~2.0.0", + "xtend": "~4.0.0" + } + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true + }, + "node_modules/tildify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tildify/-/tildify-1.2.0.tgz", + "integrity": "sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo=", + "dependencies": { + "os-homedir": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/timers-browserify": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", + "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", + "dev": true, + "dependencies": { + "setimmediate": "^1.0.4" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/timsort": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", + "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=" + }, + "node_modules/to-absolute-glob": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-0.1.1.tgz", + "integrity": "sha1-HN+kcqnvUMI57maZm2YsoOs5k38=", + "dependencies": { + "extend-shallow": "^2.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-absolute-glob/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-absolute-glob/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "node_modules/to-buffer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", + "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": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "engines": { + "node": ">=4" + } + }, + "node_modules/to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-object-path/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "dependencies": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/toposort": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.7.tgz", + "integrity": "sha1-LmhELZ9k7HILjMieZEOsbKqVACk=", + "dev": true + }, + "node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/traverse": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", + "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=", + "dev": true + }, + "node_modules/trim-repeated": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", + "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tryer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", + "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==", + "dev": true + }, + "node_modules/ts-loader": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-6.2.2.tgz", + "integrity": "sha512-HDo5kXZCBml3EUPcc7RlZOV/JGlLHwppTLEHb3SHnr5V7NXD4klMEkrhJe5wgRbaWsSXi+Y1SIBN/K9B6zWGWQ==", + "dev": true, + "dependencies": { + "chalk": "^2.3.0", + "enhanced-resolve": "^4.0.0", + "loader-utils": "^1.0.2", + "micromatch": "^4.0.0", + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8.6" + }, + "peerDependencies": { + "typescript": "*" + } + }, + "node_modules/ts-loader/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/ts-loader/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/ts-loader/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/ts-loader/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/ts-loader/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ts-loader/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/ts-loader/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/ts-pnp": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.2.0.tgz", + "integrity": "sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==", + "dev": true, + "engines": { + "node": ">=6" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "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/tslint": { + "version": "5.20.1", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.20.1.tgz", + "integrity": "sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^4.0.1", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.8.0", + "tsutils": "^2.29.0" + }, + "bin": { + "tslint": "bin/tslint" + }, + "engines": { + "node": ">=4.8.0" + }, + "peerDependencies": { + "typescript": ">=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev" + } + }, + "node_modules/tslint/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/tslint/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/tslint/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/tslint/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/tslint/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/tslint/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/tslint/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/tslint/node_modules/tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "peerDependencies": { + "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" + } + }, + "node_modules/tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, + "node_modules/typescript": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", + "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/uglify-js": { + "version": "3.13.7", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.7.tgz", + "integrity": "sha512-1Psi2MmnZJbnEsgJJIlfnd7tFlJfitusmR7zDI8lXlFI0ACD4/Rm/xdrU8bh6zF0i74aiVoBtkRiFulkrmh3AA==", + "dev": true, + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "dev": true, + "dependencies": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, + "node_modules/union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "dependencies": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/union-value/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", + "dev": true + }, + "node_modules/uniqs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", + "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=", + "dev": true + }, + "node_modules/unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dev": true, + "dependencies": { + "unique-slug": "^2.0.0" + } + }, + "node_modules/unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4" + } + }, + "node_modules/unique-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", + "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", + "dependencies": { + "json-stable-stringify-without-jsonify": "^1.0.1", + "through2-filter": "^3.0.0" + } + }, + "node_modules/unique-stream/node_modules/through2-filter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", + "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", + "dependencies": { + "through2": "~2.0.0", + "xtend": "~4.0.0" + } + }, + "node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/unquote": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", + "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=", + "dev": true + }, + "node_modules/unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "dependencies": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "dependencies": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unzipper": { + "version": "0.10.11", + "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.11.tgz", + "integrity": "sha512-+BrAq2oFqWod5IESRjL3S8baohbevGcVA+teAIOYWM3pDVdseogqbzhhvvmiyQrUNKFUnDMtELW3X8ykbyDCJw==", + "dev": true, + "dependencies": { + "big-integer": "^1.6.17", + "binary": "~0.3.0", + "bluebird": "~3.4.1", + "buffer-indexof-polyfill": "~1.0.0", + "duplexer2": "~0.1.4", + "fstream": "^1.0.12", + "graceful-fs": "^4.2.2", + "listenercount": "~1.0.1", + "readable-stream": "~2.3.6", + "setimmediate": "~1.0.4" + } + }, + "node_modules/unzipper/node_modules/bluebird": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", + "integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=", + "dev": true + }, + "node_modules/upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true, + "engines": { + "node": ">=4", + "yarn": "*" + } + }, + "node_modules/upper-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", + "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=", + "dev": true + }, + "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/urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "deprecated": "Please see https://github.com/lydell/urix#deprecated" + }, + "node_modules/url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "dependencies": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "node_modules/url-loader": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-2.3.0.tgz", + "integrity": "sha512-goSdg8VY+7nPZKUEChZSEtW5gjbS66USIGCeSJ1OVOJ7Yfuh/36YxCwMi5HVEJh6mqUYOoy3NJ0vlOMrWsSHog==", + "dev": true, + "dependencies": { + "loader-utils": "^1.2.3", + "mime": "^2.4.4", + "schema-utils": "^2.5.0" + }, + "engines": { + "node": ">= 8.9.0" + }, + "peerDependencies": { + "file-loader": "*", + "webpack": "^4.0.0" + }, + "peerDependenciesMeta": { + "file-loader": { + "optional": true + } + } + }, + "node_modules/url-parse": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.1.tgz", + "integrity": "sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==", + "dev": true, + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "node_modules/url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dev": true, + "dependencies": { + "prepend-http": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/url-to-options": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", + "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/url/node_modules/punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + }, + "node_modules/use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "dev": true, + "dependencies": { + "inherits": "2.0.3" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "node_modules/util.promisify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", + "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.2", + "object.getownpropertydescriptors": "^2.0.3" + } + }, + "node_modules/util/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "node_modules/utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=", + "dev": true + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "peer": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/vali-date": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/vali-date/-/vali-date-1.0.0.tgz", + "integrity": "sha1-G5BKWWCfsyjvB4E4Qgk09rhnCaY=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vendors": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz", + "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "node_modules/vinyl": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", + "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", + "dependencies": { + "clone": "^1.0.0", + "clone-stats": "^0.0.1", + "replace-ext": "0.0.1" + }, + "engines": { + "node": ">= 0.9" + } + }, + "node_modules/vinyl-fs": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-2.4.3.tgz", + "integrity": "sha1-PZflYuv91LZpId6nBia4S96dLQc=", + "dependencies": { + "duplexify": "^3.2.0", + "glob-stream": "^5.3.2", + "graceful-fs": "^4.0.0", + "gulp-sourcemaps": "^1.5.2", + "is-valid-glob": "^0.3.0", + "lazystream": "^1.0.0", + "lodash.isequal": "^4.0.0", + "merge-stream": "^1.0.0", + "mkdirp": "^0.5.0", + "object-assign": "^4.0.0", + "readable-stream": "^2.0.4", + "strip-bom": "^2.0.0", + "strip-bom-stream": "^1.0.0", + "through2": "^2.0.0", + "through2-filter": "^2.0.0", + "vali-date": "^1.0.0", + "vinyl": "^1.0.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/vinyl-fs/node_modules/merge-stream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", + "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", + "dependencies": { + "readable-stream": "^2.0.1" + } + }, + "node_modules/vis-data": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/vis-data/-/vis-data-7.1.2.tgz", + "integrity": "sha512-RPSegFxEcnp3HUEJSzhS2vBdbJ2PSsrYYuhRlpHp2frO/MfRtTYbIkkLZmPkA/Sg3pPfBlR235gcoKbtdm4mbw==", + "hasInstallScript": true, + "peer": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/visjs" + }, + "peerDependencies": { + "uuid": "^7.0.0 || ^8.0.0", + "vis-util": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/vis-network": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/vis-network/-/vis-network-9.0.4.tgz", + "integrity": "sha512-F/pq8yBJUuB9lNKXHhtn4GP2h91FV0c2O2nvfU34RX4VCYOlqs+mINdz+J+QkWiYhiPdlVy15gzVEzkhJ9hpaw==", + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/visjs" + }, + "peerDependencies": { + "@egjs/hammerjs": "^2.0.0", + "component-emitter": "^1.3.0", + "keycharm": "^0.2.0 || ^0.3.0 || ^0.4.0", + "timsort": "^0.3.0", + "uuid": "^3.4.0 || ^7.0.0 || ^8.0.0", + "vis-data": "^7.0.0", + "vis-util": "^5.0.1" + } + }, + "node_modules/vis-util": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vis-util/-/vis-util-5.0.2.tgz", + "integrity": "sha512-oPDmPc4o0uQLoKpKai2XD1DjrhYsA7MRz75Wx9KmfX84e9LLgsbno7jVL5tR0K9eNVQkD6jf0Ei8NtbBHDkF1A==", + "peer": true, + "engines": { + "node": ">=8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/visjs" + }, + "peerDependencies": { + "@egjs/hammerjs": "^2.0.0", + "component-emitter": "^1.3.0" + } + }, + "node_modules/vite": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-2.3.3.tgz", + "integrity": "sha512-eO1iwRbn3/BfkNVMNJDeANAFCZ5NobYOFPu7IqfY7DcI7I9nFGjJIZid0EViTmLDGwwSUPmRAq3cRBbO3+DsMA==", + "dev": true, + "dependencies": { + "esbuild": "^0.11.23", + "postcss": "^8.2.10", + "resolve": "^1.19.0", + "rollup": "^2.38.5" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": ">=12.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.1" + } + }, + "node_modules/vite/node_modules/postcss": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.0.tgz", + "integrity": "sha512-+ogXpdAjWGa+fdYY5BQ96V/6tAo+TdSSIMP5huJBIygdWwKtVoB5JWZ7yUd4xZ8r+8Kvvx4nyg/PQ071H4UtcQ==", + "dev": true, + "dependencies": { + "colorette": "^1.2.2", + "nanoid": "^3.1.23", + "source-map-js": "^0.6.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true + }, + "node_modules/vue": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.0.11.tgz", + "integrity": "sha512-3/eUi4InQz8MPzruHYSTQPxtM3LdZ1/S/BvaU021zBnZi0laRUyH6pfuE4wtUeLvI8wmUNwj5wrZFvbHUXL9dw==", + "dependencies": { + "@vue/compiler-dom": "3.0.11", + "@vue/runtime-dom": "3.0.11", + "@vue/shared": "3.0.11" + } + }, + "node_modules/vue-class-component": { + "version": "8.0.0-rc.1", + "resolved": "https://registry.npmjs.org/vue-class-component/-/vue-class-component-8.0.0-rc.1.tgz", + "integrity": "sha512-w1nMzsT/UdbDAXKqhwTmSoyuJzUXKrxLE77PCFVuC6syr8acdFDAq116xgvZh9UCuV0h+rlCtxXolr3Hi3HyPQ==" + }, + "node_modules/vue-cli-plugin-tailwind": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/vue-cli-plugin-tailwind/-/vue-cli-plugin-tailwind-2.0.6.tgz", + "integrity": "sha512-HgR3gSmlnypNU+hlqoiRBJsnShXSoig4XTFNZiPlyVZBtkDZdfD884wTxz+GDJHzWLPtv4wnAyuO95UCsPbyoQ==", + "dev": true + }, + "node_modules/vue-eslint-parser": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.6.0.tgz", + "integrity": "sha512-QXxqH8ZevBrtiZMZK0LpwaMfevQi9UL7lY6Kcp+ogWHC88AuwUPwwCIzkOUc1LR4XsYAt/F9yHXAB/QoD17QXA==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "eslint-scope": "^5.0.0", + "eslint-visitor-keys": "^1.1.0", + "espree": "^6.2.1", + "esquery": "^1.4.0", + "lodash": "^4.17.15" + }, + "engines": { + "node": ">=8.10" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5.0.0" + } + }, + "node_modules/vue-eslint-parser/node_modules/debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/vue-eslint-parser/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/vue-eslint-parser/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/vue-hot-reload-api": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz", + "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==", + "dev": true + }, + "node_modules/vue-loader": { + "version": "15.9.7", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.7.tgz", + "integrity": "sha512-qzlsbLV1HKEMf19IqCJqdNvFJRCI58WNbS6XbPqK13MrLz65es75w392MSQ5TsARAfIjUw+ATm3vlCXUJSOH9Q==", + "dev": true, + "dependencies": { + "@vue/component-compiler-utils": "^3.1.0", + "hash-sum": "^1.0.2", + "loader-utils": "^1.1.0", + "vue-hot-reload-api": "^2.3.0", + "vue-style-loader": "^4.1.0" + }, + "peerDependencies": { + "css-loader": "*", + "webpack": "^3.0.0 || ^4.1.0 || ^5.0.0-0" + }, + "peerDependenciesMeta": { + "cache-loader": { + "optional": true + }, + "vue-template-compiler": { + "optional": true + } + } + }, + "node_modules/vue-loader-v16": { + "name": "vue-loader", + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.2.0.tgz", + "integrity": "sha512-TitGhqSQ61RJljMmhIGvfWzJ2zk9m1Qug049Ugml6QP3t0e95o0XJjk29roNEiPKJQBEi8Ord5hFuSuELzSp8Q==", + "dev": true, + "optional": true, + "dependencies": { + "chalk": "^4.1.0", + "hash-sum": "^2.0.0", + "loader-utils": "^2.0.0" + } + }, + "node_modules/vue-loader-v16/node_modules/json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "optional": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/vue-loader-v16/node_modules/loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "optional": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/vue-loader/node_modules/hash-sum": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", + "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=", + "dev": true + }, + "node_modules/vue-router": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.0.8.tgz", + "integrity": "sha512-42mWSQaH7CCBQDspQTHv63f34VEnZC20g9QNK4WJ/zW8SdIUeT6TQ2i/78fjF/pVBUPLBWrGhvB7uDnaz7O/pA==", + "dependencies": { + "@vue/devtools-api": "^6.0.0-beta.10" + } + }, + "node_modules/vue-style-loader": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.3.tgz", + "integrity": "sha512-sFuh0xfbtpRlKfm39ss/ikqs9AbKCoXZBpHeVZ8Tx650o0k0q/YCM7FRvigtxpACezfq6af+a7JeqVTWvncqDg==", + "dev": true, + "dependencies": { + "hash-sum": "^1.0.2", + "loader-utils": "^1.0.2" + } + }, + "node_modules/vue-style-loader/node_modules/hash-sum": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", + "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=", + "dev": true + }, + "node_modules/vue-template-es2015-compiler": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz", + "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==", + "dev": true + }, + "node_modules/vue-tsc": { + "version": "0.0.24", + "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-0.0.24.tgz", + "integrity": "sha512-Qx0V7jkWMtvddtaWa1SA8YKkBCRmjq9zZUB2UIMZiso6JSH538oHD2VumSzkoDnAfFbY3t0/j1mB2abpA0bGWA==", + "dev": true, + "dependencies": { + "unzipper": "0.10.11" + }, + "bin": { + "vue-tsc": "vue-tsc.js" + } + }, + "node_modules/watchpack": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz", + "integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0" + }, + "optionalDependencies": { + "chokidar": "^3.4.1", + "watchpack-chokidar2": "^2.0.1" + } + }, + "node_modules/watchpack-chokidar2": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz", + "integrity": "sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww==", + "dev": true, + "optional": true, + "dependencies": { + "chokidar": "^2.1.8" + } + }, + "node_modules/watchpack-chokidar2/node_modules/anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "optional": true, + "dependencies": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "node_modules/watchpack-chokidar2/node_modules/anymatch/node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "optional": true, + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack-chokidar2/node_modules/binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack-chokidar2/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "optional": true, + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack-chokidar2/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "optional": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack-chokidar2/node_modules/chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "deprecated": "Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.", + "dev": true, + "optional": true, + "dependencies": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + }, + "optionalDependencies": { + "fsevents": "^1.2.7" + } + }, + "node_modules/watchpack-chokidar2/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "optional": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack-chokidar2/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "optional": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack-chokidar2/node_modules/fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "deprecated": "fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/watchpack-chokidar2/node_modules/glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "optional": true, + "dependencies": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "node_modules/watchpack-chokidar2/node_modules/glob-parent/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "optional": true, + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack-chokidar2/node_modules/is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "optional": true, + "dependencies": { + "binary-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack-chokidar2/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack-chokidar2/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "optional": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack-chokidar2/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "optional": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack-chokidar2/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "optional": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack-chokidar2/node_modules/readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "optional": true, + "dependencies": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/watchpack-chokidar2/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "optional": true, + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dev": true, + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dev": true, + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/webpack": { + "version": "4.46.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.46.0.tgz", + "integrity": "sha512-6jJuJjg8znb/xRItk7bkT0+Q7AHCYjjFnvKIWQPkNIOyRqoCGvkOs0ipeQzrqz4l5FtN5ZI/ukEHroeX/o1/5Q==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/wasm-edit": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "acorn": "^6.4.1", + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^4.5.0", + "eslint-scope": "^4.0.3", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^2.4.0", + "loader-utils": "^1.2.3", + "memory-fs": "^0.4.1", + "micromatch": "^3.1.10", + "mkdirp": "^0.5.3", + "neo-async": "^2.6.1", + "node-libs-browser": "^2.2.1", + "schema-utils": "^1.0.0", + "tapable": "^1.1.3", + "terser-webpack-plugin": "^1.4.3", + "watchpack": "^1.7.4", + "webpack-sources": "^1.4.1" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + }, + "webpack-command": { + "optional": true + } + } + }, + "node_modules/webpack-bundle-analyzer": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.9.0.tgz", + "integrity": "sha512-Ob8amZfCm3rMB1ScjQVlbYYUEJyEjdEtQ92jqiFUYt5VkEeO2v5UMbv49P/gnmCZm3A6yaFQzCBvpZqN4MUsdA==", + "dev": true, + "dependencies": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1", + "bfj": "^6.1.1", + "chalk": "^2.4.1", + "commander": "^2.18.0", + "ejs": "^2.6.1", + "express": "^4.16.3", + "filesize": "^3.6.1", + "gzip-size": "^5.0.0", + "lodash": "^4.17.19", + "mkdirp": "^0.5.1", + "opener": "^1.5.1", + "ws": "^6.0.0" + }, + "bin": { + "webpack-bundle-analyzer": "lib/bin/analyzer.js" + }, + "engines": { + "node": ">= 6.14.4" + } + }, + "node_modules/webpack-bundle-analyzer/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/webpack-bundle-analyzer/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/webpack-bundle-analyzer/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/webpack-bundle-analyzer/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/webpack-bundle-analyzer/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "node_modules/webpack-bundle-analyzer/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/webpack-bundle-analyzer/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/webpack-chain": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/webpack-chain/-/webpack-chain-6.5.1.tgz", + "integrity": "sha512-7doO/SRtLu8q5WM0s7vPKPWX580qhi0/yBHkOxNkv50f6qB76Zy9o2wRTrrPULqYTvQlVHuvbA8v+G5ayuUDsA==", + "dev": true, + "dependencies": { + "deepmerge": "^1.5.2", + "javascript-stringify": "^2.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/webpack-chain/node_modules/deepmerge": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-1.5.2.tgz", + "integrity": "sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-middleware": { + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz", + "integrity": "sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ==", + "dev": true, + "dependencies": { + "memory-fs": "^0.4.1", + "mime": "^2.4.4", + "mkdirp": "^0.5.1", + "range-parser": "^1.2.1", + "webpack-log": "^2.0.0" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/webpack-dev-middleware/node_modules/memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "dependencies": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "node_modules/webpack-dev-server": { + "version": "3.11.2", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.2.tgz", + "integrity": "sha512-A80BkuHRQfCiNtGBS1EMf2ChTUs0x+B3wGDFmOeT4rmJOHhHTCH2naNxIHhmkr0/UillP4U3yeIyv1pNp+QDLQ==", + "dev": true, + "dependencies": { + "ansi-html": "0.0.7", + "bonjour": "^3.5.0", + "chokidar": "^2.1.8", + "compression": "^1.7.4", + "connect-history-api-fallback": "^1.6.0", + "debug": "^4.1.1", + "del": "^4.1.1", + "express": "^4.17.1", + "html-entities": "^1.3.1", + "http-proxy-middleware": "0.19.1", + "import-local": "^2.0.0", + "internal-ip": "^4.3.0", + "ip": "^1.1.5", + "is-absolute-url": "^3.0.3", + "killable": "^1.0.1", + "loglevel": "^1.6.8", + "opn": "^5.5.0", + "p-retry": "^3.0.1", + "portfinder": "^1.0.26", + "schema-utils": "^1.0.0", + "selfsigned": "^1.10.8", + "semver": "^6.3.0", + "serve-index": "^1.9.1", + "sockjs": "^0.3.21", + "sockjs-client": "^1.5.0", + "spdy": "^4.0.2", + "strip-ansi": "^3.0.1", + "supports-color": "^6.1.0", + "url": "^0.11.0", + "webpack-dev-middleware": "^3.7.2", + "webpack-log": "^2.0.0", + "ws": "^6.2.1", + "yargs": "^13.3.2" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 6.11.5" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-dev-server/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/webpack-dev-server/node_modules/anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "dependencies": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + } + }, + "node_modules/webpack-dev-server/node_modules/anymatch/node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "deprecated": "Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.", + "dev": true, + "dependencies": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + }, + "optionalDependencies": { + "fsevents": "^1.2.7" + } + }, + "node_modules/webpack-dev-server/node_modules/cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/webpack-dev-server/node_modules/cliui/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-dev-server/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/webpack-dev-server/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/webpack-dev-server/node_modules/debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "node_modules/webpack-dev-server/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-dev-server/node_modules/fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "deprecated": "fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/webpack-dev-server/node_modules/glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "dependencies": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "node_modules/webpack-dev-server/node_modules/glob-parent/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/webpack-dev-server/node_modules/http-proxy-middleware": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", + "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", + "dev": true, + "dependencies": { + "http-proxy": "^1.17.0", + "is-glob": "^4.0.0", + "lodash": "^4.17.11", + "micromatch": "^3.1.10" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/webpack-dev-server/node_modules/is-absolute-url": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", + "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/webpack-dev-server/node_modules/is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "dependencies": { + "binary-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/webpack-dev-server/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-dev-server/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/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/webpack-dev-server/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-dev-server/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/webpack-dev-server/node_modules/readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/webpack-dev-server/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/webpack-dev-server/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/webpack-dev-server/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-dev-server/node_modules/string-width/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-dev-server/node_modules/supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-dev-server/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-dev-server/node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/webpack-dev-server/node_modules/yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "dependencies": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "node_modules/webpack-dev-server/node_modules/yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "node_modules/webpack-log": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", + "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", + "dev": true, + "dependencies": { + "ansi-colors": "^3.0.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/webpack-log/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/webpack-merge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", + "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", + "dev": true, + "dependencies": { + "lodash": "^4.17.15" + } + }, + "node_modules/webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dev": true, + "dependencies": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } + }, + "node_modules/webpack/node_modules/acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/webpack/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack/node_modules/eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "dependencies": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/webpack/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack/node_modules/memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "dependencies": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "node_modules/webpack/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/webpack/node_modules/schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "dependencies": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/webpack/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "node_modules/wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "dependencies": { + "string-width": "^1.0.2 || 2" + } + }, + "node_modules/window-size": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", + "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=", + "bin": { + "window-size": "cli.js" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "node_modules/worker-farm": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", + "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", + "dev": true, + "dependencies": { + "errno": "~0.1.7" + } + }, + "node_modules/worker-rpc": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/worker-rpc/-/worker-rpc-0.1.1.tgz", + "integrity": "sha512-P1WjMrUB3qgJNI9jfmpZ/htmBEjFh//6l/5y8SD9hg1Ef5zTTVVoRjTrTEzPrNBQvmhMxkoTsjOXN10GWU7aCg==", + "dev": true, + "dependencies": { + "microevent.ts": "~0.1.1" + } + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/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/wrap-ansi/node_modules/string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "node_modules/ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "dev": true, + "dependencies": { + "async-limiter": "~1.0.0" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "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/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "optional": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.7", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz", + "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/yargs/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/yargs/node_modules/string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/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/yargs/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/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yorkie": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yorkie/-/yorkie-2.0.0.tgz", + "integrity": "sha512-jcKpkthap6x63MB4TxwCyuIGkV0oYP/YRyuQU5UO0Yz/E/ZAu+653/uov+phdmO54n6BcvFRyyt0RRrWdN2mpw==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "execa": "^0.8.0", + "is-ci": "^1.0.10", + "normalize-path": "^1.0.0", + "strip-indent": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/yorkie/node_modules/cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "dependencies": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "node_modules/yorkie/node_modules/execa": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.8.0.tgz", + "integrity": "sha1-2NdrvBtVIX7RkP1t1J08d07PyNo=", + "dev": true, + "dependencies": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/yorkie/node_modules/get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/yorkie/node_modules/lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/yorkie/node_modules/normalize-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-1.0.0.tgz", + "integrity": "sha1-MtDkcvkf80VwHBWoMRAY07CpA3k=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/yorkie/node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + } + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.12.13" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", + "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==" + }, + "@babel/highlight": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", + "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.0", + "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": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "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.14.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.3.tgz", + "integrity": "sha512-7MpZDIfI7sUC5zWo2+foJ50CSI5lcqDehZ0lVgIhSi4bFEk94fLAKlF3Q0nzSQQ+ca0lm+O6G9ztKVBeu8PMRQ==" + }, + "@babel/types": { + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.2.tgz", + "integrity": "sha512-SdjAG/3DikRHpUOjxZgnkbR11xUlyDMUFJdvnIgZEE16mqmY0BINMmc4//JMJglEmn6i7sq6p+mGrFWyZ98EEw==", + "requires": { + "@babel/helper-validator-identifier": "^7.14.0", + "to-fast-properties": "^2.0.0" + } + }, + "@egjs/hammerjs": { + "version": "2.0.17", + "resolved": "https://registry.npmjs.org/@egjs/hammerjs/-/hammerjs-2.0.17.tgz", + "integrity": "sha512-XQsZgjm2EcVUiZQf11UBJQfmZeEmOW8DpI1gsFeln6w0ae0ii4dMQEQ0kjl6DspdWX1aGY1/loyXnP0JS06e/A==", + "peer": true, + "requires": { + "@types/hammerjs": "^2.0.36" + } + }, + "@fullhuman/postcss-purgecss": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@fullhuman/postcss-purgecss/-/postcss-purgecss-3.1.3.tgz", + "integrity": "sha512-kwOXw8fZ0Lt1QmeOOrd+o4Ibvp4UTEBFQbzvWldjlKv5n+G9sXfIPn1hh63IQIL8K8vbvv1oYMJiIUbuy9bGaA==", + "requires": { + "purgecss": "^3.1.3" + } + }, + "@grpc/grpc-js": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.3.2.tgz", + "integrity": "sha512-UXepkOKCATJrhHGsxt+CGfpZy9zUn1q9mop5kfcXq1fBkTePxVNPOdnISlCbJFlCtld+pSLGyZCzr9/zVprFKA==", + "requires": { + "@types/node": ">=12.12.47" + } + }, + "@gulp-sourcemaps/map-sources": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz", + "integrity": "sha1-iQrnxdjId/bThIYCFazp1+yUW9o=", + "requires": { + "normalize-path": "^2.0.1", + "through2": "^2.0.3" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "@hapi/address": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz", + "integrity": "sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ==", + "dev": true + }, + "@hapi/bourne": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@hapi/bourne/-/bourne-1.3.2.tgz", + "integrity": "sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA==", + "dev": true + }, + "@hapi/hoek": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-8.5.1.tgz", + "integrity": "sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow==", + "dev": true + }, + "@hapi/joi": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/@hapi/joi/-/joi-15.1.1.tgz", + "integrity": "sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ==", + "dev": true, + "requires": { + "@hapi/address": "2.x.x", + "@hapi/bourne": "1.x.x", + "@hapi/hoek": "8.x.x", + "@hapi/topo": "3.x.x" + } + }, + "@hapi/topo": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-3.1.6.tgz", + "integrity": "sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ==", + "dev": true, + "requires": { + "@hapi/hoek": "^8.3.0" + } + }, + "@intervolga/optimize-cssnano-plugin": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@intervolga/optimize-cssnano-plugin/-/optimize-cssnano-plugin-1.0.6.tgz", + "integrity": "sha512-zN69TnSr0viRSU6cEDIcuPcP67QcpQ6uHACg58FiN9PDrU6SLyGW3MR4tiISbYxy1kDWAVPwD+XwQTWE5cigAA==", + "dev": true, + "requires": { + "cssnano": "^4.0.0", + "cssnano-preset-default": "^4.0.0", + "postcss": "^7.0.0" + } + }, + "@mrmlnc/readdir-enhanced": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", + "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", + "dev": true, + "requires": { + "call-me-maybe": "^1.0.1", + "glob-to-regexp": "^0.3.0" + } + }, + "@nodelib/fs.scandir": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz", + "integrity": "sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==", + "requires": { + "@nodelib/fs.stat": "2.0.4", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz", + "integrity": "sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==" + }, + "@nodelib/fs.walk": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz", + "integrity": "sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==", + "requires": { + "@nodelib/fs.scandir": "2.1.4", + "fastq": "^1.6.0" + } + }, + "@sindresorhus/is": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz", + "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==", + "dev": true + }, + "@soda/friendly-errors-webpack-plugin": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@soda/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.8.0.tgz", + "integrity": "sha512-RLotfx6k1+nfLacwNCenj7VnTMPxVwYKoGOcffMFoJDKM8tXzBiCN0hMHFJNnoAojduYAsxuiMm0EOMixgiRow==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "error-stack-parser": "^2.0.2", + "string-width": "^2.0.0", + "strip-ansi": "^5" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "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": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "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" + } + } + } + }, + "@soda/get-current-script": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@soda/get-current-script/-/get-current-script-1.0.2.tgz", + "integrity": "sha512-T7VNNlYVM1SgQ+VsMYhnDkcGmWhQdL0bDyGm5TlQ3GBXnJscEClUUOKduWTmm2zCnvNLC1hc3JpuXjs/nFOc5w==", + "dev": true + }, + "@tailwindcss/postcss7-compat": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/postcss7-compat/-/postcss7-compat-2.1.3.tgz", + "integrity": "sha512-SuuCv7XkB2WIdTsiRLCX8eTF6s2r7E+0aIg+ASYZE/5YAJlojYWDENth+ywRJpWXW1ZoQKo0g/8xsMKijzPm8g==", + "requires": { + "@fullhuman/postcss-purgecss": "^3.1.3", + "autoprefixer": "^9", + "bytes": "^3.0.0", + "chalk": "^4.1.0", + "chokidar": "^3.5.1", + "color": "^3.1.3", + "detective": "^5.2.0", + "didyoumean": "^1.2.1", + "dlv": "^1.1.3", + "fast-glob": "^3.2.5", + "fs-extra": "^9.1.0", + "html-tags": "^3.1.0", + "lodash": "^4.17.21", + "lodash.topath": "^4.5.2", + "modern-normalize": "^1.0.0", + "node-emoji": "^1.8.1", + "normalize-path": "^3.0.0", + "object-hash": "^2.1.1", + "parse-glob": "^3.0.4", + "postcss": "^7", + "postcss-functions": "^3", + "postcss-js": "^2", + "postcss-nested": "^4", + "postcss-selector-parser": "^6.0.4", + "postcss-value-parser": "^4.1.0", + "pretty-hrtime": "^1.0.3", + "quick-lru": "^5.1.1", + "reduce-css-calc": "^2.1.8", + "resolve": "^1.20.0" + } + }, + "@types/anymatch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-3.0.0.tgz", + "integrity": "sha512-qLChUo6yhpQ9k905NwL74GU7TxH+9UODwwQ6ICNI+O6EDMExqH/Cv9NsbmcZ7yC/rRXJ/AHCzfgjsFRY5fKjYw==", + "dev": true, + "requires": { + "anymatch": "*" + } + }, + "@types/body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", + "dev": true, + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/connect": { + "version": "3.4.34", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz", + "integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/connect-history-api-fallback": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.4.tgz", + "integrity": "sha512-Kf8v0wljR5GSCOCF/VQWdV3ZhKOVA73drXtY3geMTQgHy9dgqQ0dLrf31M0hcuWkhFzK5sP0kkS3mJzcKVtZbw==", + "dev": true, + "requires": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "@types/express": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.11.tgz", + "integrity": "sha512-no+R6rW60JEc59977wIxreQVsIEOAYwgCqldrA/vkpCnbD7MqTefO97lmoBe4WE0F156bC4uLSP1XHDOySnChg==", + "dev": true, + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.19.tgz", + "integrity": "sha512-DJOSHzX7pCiSElWaGR8kCprwibCB/3yW6vcT8VG3P0SJjnv19gnWG/AZMfM60Xj/YJIp/YCaDHyvzsFVeniARA==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, + "@types/glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==", + "dev": true, + "requires": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "@types/hammerjs": { + "version": "2.0.40", + "resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.40.tgz", + "integrity": "sha512-VbjwR1fhsn2h2KXAY4oy1fm7dCxaKy0D+deTb8Ilc3Eo3rc5+5eA4rfYmZaHgNJKxVyI0f6WIXzO2zLkVmQPHA==", + "peer": true + }, + "@types/http-proxy": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.6.tgz", + "integrity": "sha512-+qsjqR75S/ib0ig0R9WN+CDoZeOBU6F2XLewgC4KVgdXiNHiKKHFEMRHOrs5PbYE97D5vataw5wPj4KLYfUkuQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/jquery": { + "version": "3.5.5", + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.5.tgz", + "integrity": "sha512-6RXU9Xzpc6vxNrS6FPPapN1SxSHgQ336WC6Jj/N8q30OiaBZ00l1GBgeP7usjVZPivSkGUfL1z/WW6TX989M+w==", + "dev": true, + "requires": { + "@types/sizzle": "*" + } + }, + "@types/json-schema": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", + "dev": true + }, + "@types/mime": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", + "dev": true + }, + "@types/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA==", + "dev": true + }, + "@types/minimist": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.1.tgz", + "integrity": "sha512-fZQQafSREFyuZcdWFAExYjBiCL7AUCdgsk80iO0q4yihYYdcIiH28CcuPTGFgLOCC8RlW49GSQxdHwZP+I7CNg==", + "dev": true + }, + "@types/node": { + "version": "15.3.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.3.1.tgz", + "integrity": "sha512-weaeiP4UF4XgF++3rpQhpIJWsCTS4QJw5gvBhQu6cFIxTwyxWIe3xbnrY/o2lTCQ0lsdb8YIUDUvLR4Vuz5rbw==" + }, + "@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "dev": true + }, + "@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "dev": true, + "optional": true + }, + "@types/q": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", + "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==", + "dev": true + }, + "@types/qs": { + "version": "6.9.6", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.6.tgz", + "integrity": "sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA==", + "dev": true + }, + "@types/range-parser": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", + "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==", + "dev": true + }, + "@types/serve-static": { + "version": "1.13.9", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.9.tgz", + "integrity": "sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA==", + "dev": true, + "requires": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "@types/sizzle": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz", + "integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==", + "dev": true + }, + "@types/source-list-map": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", + "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", + "dev": true + }, + "@types/tapable": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.7.tgz", + "integrity": "sha512-0VBprVqfgFD7Ehb2vd8Lh9TG3jP98gvr8rgehQqzztZNI7o8zS8Ad4jyZneKELphpuE212D8J70LnSNQSyO6bQ==", + "dev": true + }, + "@types/uglify-js": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.13.0.tgz", + "integrity": "sha512-EGkrJD5Uy+Pg0NUR8uA4bJ5WMfljyad0G+784vLCNUkD+QwOJXUbBYExXfVGf7YtyzdQp3L/XMYcliB987kL5Q==", + "dev": true, + "requires": { + "source-map": "^0.6.1" + } + }, + "@types/webpack": { + "version": "4.41.28", + "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.28.tgz", + "integrity": "sha512-Nn84RAiJjKRfPFFCVR8LC4ueTtTdfWAMZ03THIzZWRJB+rX24BD3LqPSFnbMscWauEsT4segAsylPDIaZyZyLQ==", + "dev": true, + "requires": { + "@types/anymatch": "*", + "@types/node": "*", + "@types/tapable": "^1", + "@types/uglify-js": "*", + "@types/webpack-sources": "*", + "source-map": "^0.6.0" + } + }, + "@types/webpack-dev-server": { + "version": "3.11.4", + "resolved": "https://registry.npmjs.org/@types/webpack-dev-server/-/webpack-dev-server-3.11.4.tgz", + "integrity": "sha512-DCKORHjqNNVuMIDWFrlljftvc9CL0+09p3l7lBpb8dRqgN5SmvkWCY4MPKxoI6wJgdRqohmoNbptkxqSKAzLRg==", + "dev": true, + "requires": { + "@types/connect-history-api-fallback": "*", + "@types/express": "*", + "@types/serve-static": "*", + "@types/webpack": "^4", + "http-proxy-middleware": "^1.0.0" + } + }, + "@types/webpack-env": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.16.0.tgz", + "integrity": "sha512-Fx+NpfOO0CpeYX2g9bkvX8O5qh9wrU1sOF4g8sft4Mu7z+qfe387YlyY8w8daDyDsKY5vUxM0yxkAYnbkRbZEw==", + "dev": true + }, + "@types/webpack-sources": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-2.1.0.tgz", + "integrity": "sha512-LXn/oYIpBeucgP1EIJbKQ2/4ZmpvRl+dlrFdX7+94SKRUV3Evy3FsfMZY318vGhkWUS5MPhtOM3w1/hCOAOXcg==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/source-list-map": "*", + "source-map": "^0.7.3" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } + } + }, + "@vue/cli-overlay": { + "version": "4.5.13", + "resolved": "https://registry.npmjs.org/@vue/cli-overlay/-/cli-overlay-4.5.13.tgz", + "integrity": "sha512-jhUIg3klgi5Cxhs8dnat5hi/W2tQJvsqCxR0u6hgfSob0ORODgUBlN+F/uwq7cKIe/pzedVUk1y07F13GQvPqg==", + "dev": true + }, + "@vue/cli-plugin-router": { + "version": "4.5.13", + "resolved": "https://registry.npmjs.org/@vue/cli-plugin-router/-/cli-plugin-router-4.5.13.tgz", + "integrity": "sha512-tgtMDjchB/M1z8BcfV4jSOY9fZSMDTPgF9lsJIiqBWMxvBIsk9uIZHxp62DibYME4CCKb/nNK61XHaikFp+83w==", + "dev": true, + "requires": { + "@vue/cli-shared-utils": "^4.5.13" + } + }, + "@vue/cli-plugin-typescript": { + "version": "4.5.13", + "resolved": "https://registry.npmjs.org/@vue/cli-plugin-typescript/-/cli-plugin-typescript-4.5.13.tgz", + "integrity": "sha512-CpLlIdFNV1gn9uC4Yh6QgWI42uk2x5Z3cb2ScxNSwWsR1vgSdr0/1DdNzoBm68aP8RUtnHHO/HZfPnvXiq42xA==", + "dev": true, + "requires": { + "@types/webpack-env": "^1.15.2", + "@vue/cli-shared-utils": "^4.5.13", + "cache-loader": "^4.1.0", + "fork-ts-checker-webpack-plugin": "^3.1.1", + "fork-ts-checker-webpack-plugin-v5": "npm:fork-ts-checker-webpack-plugin@^5.0.11", + "globby": "^9.2.0", + "thread-loader": "^2.1.3", + "ts-loader": "^6.2.2", + "tslint": "^5.20.1", + "webpack": "^4.0.0", + "yorkie": "^2.0.0" + }, + "dependencies": { + "@nodelib/fs.stat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", + "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", + "dev": true + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "dir-glob": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", + "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", + "dev": true, + "requires": { + "path-type": "^3.0.0" + } + }, + "fast-glob": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", + "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", + "dev": true, + "requires": { + "@mrmlnc/readdir-enhanced": "^2.2.1", + "@nodelib/fs.stat": "^1.1.2", + "glob-parent": "^3.1.0", + "is-glob": "^4.0.0", + "merge2": "^1.2.3", + "micromatch": "^3.1.10" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "globby": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", + "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^1.0.2", + "dir-glob": "^2.2.2", + "fast-glob": "^2.2.6", + "glob": "^7.1.3", + "ignore": "^4.0.3", + "pify": "^4.0.1", + "slash": "^2.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "@vue/cli-plugin-vuex": { + "version": "4.5.13", + "resolved": "https://registry.npmjs.org/@vue/cli-plugin-vuex/-/cli-plugin-vuex-4.5.13.tgz", + "integrity": "sha512-I1S9wZC7iI0Wn8kw8Zh+A2Qkf6s1M6vTGBkx8boXjuzfwEEyEHRxadsVCecZc8Mkpydo0nykj+MyYF96TKFuVA==", + "dev": true, + "requires": {} + }, + "@vue/cli-service": { + "version": "4.5.13", + "resolved": "https://registry.npmjs.org/@vue/cli-service/-/cli-service-4.5.13.tgz", + "integrity": "sha512-CKAZN4iokMMsaUyJRU22oUAz3oS/X9sVBSKAF2/shFBV5xh3jqAlKl8OXZYz4cXGFLA6djNuYrniuLAo7Ku97A==", + "dev": true, + "requires": { + "@intervolga/optimize-cssnano-plugin": "^1.0.5", + "@soda/friendly-errors-webpack-plugin": "^1.7.1", + "@soda/get-current-script": "^1.0.0", + "@types/minimist": "^1.2.0", + "@types/webpack": "^4.0.0", + "@types/webpack-dev-server": "^3.11.0", + "@vue/cli-overlay": "^4.5.13", + "@vue/cli-plugin-router": "^4.5.13", + "@vue/cli-plugin-vuex": "^4.5.13", + "@vue/cli-shared-utils": "^4.5.13", + "@vue/component-compiler-utils": "^3.1.2", + "@vue/preload-webpack-plugin": "^1.1.0", + "@vue/web-component-wrapper": "^1.2.0", + "acorn": "^7.4.0", + "acorn-walk": "^7.1.1", + "address": "^1.1.2", + "autoprefixer": "^9.8.6", + "browserslist": "^4.12.0", + "cache-loader": "^4.1.0", + "case-sensitive-paths-webpack-plugin": "^2.3.0", + "cli-highlight": "^2.1.4", + "clipboardy": "^2.3.0", + "cliui": "^6.0.0", + "copy-webpack-plugin": "^5.1.1", + "css-loader": "^3.5.3", + "cssnano": "^4.1.10", + "debug": "^4.1.1", + "default-gateway": "^5.0.5", + "dotenv": "^8.2.0", + "dotenv-expand": "^5.1.0", + "file-loader": "^4.2.0", + "fs-extra": "^7.0.1", + "globby": "^9.2.0", + "hash-sum": "^2.0.0", + "html-webpack-plugin": "^3.2.0", + "launch-editor-middleware": "^2.2.1", + "lodash.defaultsdeep": "^4.6.1", + "lodash.mapvalues": "^4.6.0", + "lodash.transform": "^4.6.0", + "mini-css-extract-plugin": "^0.9.0", + "minimist": "^1.2.5", + "pnp-webpack-plugin": "^1.6.4", + "portfinder": "^1.0.26", + "postcss-loader": "^3.0.0", + "ssri": "^8.0.1", + "terser-webpack-plugin": "^1.4.4", + "thread-loader": "^2.1.3", + "url-loader": "^2.2.0", + "vue-loader": "^15.9.2", + "vue-loader-v16": "npm:vue-loader@^16.1.0", + "vue-style-loader": "^4.1.2", + "webpack": "^4.0.0", + "webpack-bundle-analyzer": "^3.8.0", + "webpack-chain": "^6.4.0", + "webpack-dev-server": "^3.11.0", + "webpack-merge": "^4.2.2" + }, + "dependencies": { + "@nodelib/fs.stat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", + "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", + "dev": true + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "dir-glob": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", + "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", + "dev": true, + "requires": { + "path-type": "^3.0.0" + } + }, + "fast-glob": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", + "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", + "dev": true, + "requires": { + "@mrmlnc/readdir-enhanced": "^2.2.1", + "@nodelib/fs.stat": "^1.1.2", + "glob-parent": "^3.1.0", + "is-glob": "^4.0.0", + "merge2": "^1.2.3", + "micromatch": "^3.1.10" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "globby": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", + "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^1.0.2", + "dir-glob": "^2.2.2", + "fast-glob": "^2.2.6", + "glob": "^7.1.3", + "ignore": "^4.0.3", + "pify": "^4.0.1", + "slash": "^2.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "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 + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + } + } + }, + "@vue/cli-shared-utils": { + "version": "4.5.13", + "resolved": "https://registry.npmjs.org/@vue/cli-shared-utils/-/cli-shared-utils-4.5.13.tgz", + "integrity": "sha512-HpnOrkLg42RFUsQGMJv26oTG3J3FmKtO2WSRhKIIL+1ok3w9OjGCtA3nMMXN27f9eX14TqO64M36DaiSZ1fSiw==", + "dev": true, + "requires": { + "@hapi/joi": "^15.0.1", + "chalk": "^2.4.2", + "execa": "^1.0.0", + "launch-editor": "^2.2.1", + "lru-cache": "^5.1.1", + "node-ipc": "^9.1.1", + "open": "^6.3.0", + "ora": "^3.4.0", + "read-pkg": "^5.1.1", + "request": "^2.88.2", + "semver": "^6.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "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": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "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 + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "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" + } + } + } + }, + "@vue/compiler-core": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.0.11.tgz", + "integrity": "sha512-6sFj6TBac1y2cWCvYCA8YzHJEbsVkX7zdRs/3yK/n1ilvRqcn983XvpBbnN3v4mZ1UiQycTvOiajJmOgN9EVgw==", + "requires": { + "@babel/parser": "^7.12.0", + "@babel/types": "^7.12.0", + "@vue/shared": "3.0.11", + "estree-walker": "^2.0.1", + "source-map": "^0.6.1" + } + }, + "@vue/compiler-dom": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.0.11.tgz", + "integrity": "sha512-+3xB50uGeY5Fv9eMKVJs2WSRULfgwaTJsy23OIltKgMrynnIj8hTYY2UL97HCoz78aDw1VDXdrBQ4qepWjnQcw==", + "requires": { + "@vue/compiler-core": "3.0.11", + "@vue/shared": "3.0.11" + } + }, + "@vue/compiler-sfc": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.0.11.tgz", + "integrity": "sha512-7fNiZuCecRleiyVGUWNa6pn8fB2fnuJU+3AGjbjl7r1P5wBivfl02H4pG+2aJP5gh2u+0wXov1W38tfWOphsXw==", + "dev": true, + "requires": { + "@babel/parser": "^7.13.9", + "@babel/types": "^7.13.0", + "@vue/compiler-core": "3.0.11", + "@vue/compiler-dom": "3.0.11", + "@vue/compiler-ssr": "3.0.11", + "@vue/shared": "3.0.11", + "consolidate": "^0.16.0", + "estree-walker": "^2.0.1", + "hash-sum": "^2.0.0", + "lru-cache": "^5.1.1", + "magic-string": "^0.25.7", + "merge-source-map": "^1.1.0", + "postcss": "^8.1.10", + "postcss-modules": "^4.0.0", + "postcss-selector-parser": "^6.0.4", + "source-map": "^0.6.1" + }, + "dependencies": { + "postcss": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.0.tgz", + "integrity": "sha512-+ogXpdAjWGa+fdYY5BQ96V/6tAo+TdSSIMP5huJBIygdWwKtVoB5JWZ7yUd4xZ8r+8Kvvx4nyg/PQ071H4UtcQ==", + "dev": true, + "requires": { + "colorette": "^1.2.2", + "nanoid": "^3.1.23", + "source-map-js": "^0.6.2" + } + } + } + }, + "@vue/compiler-ssr": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.0.11.tgz", + "integrity": "sha512-66yUGI8SGOpNvOcrQybRIhl2M03PJ+OrDPm78i7tvVln86MHTKhM3ERbALK26F7tXl0RkjX4sZpucCpiKs3MnA==", + "dev": true, + "requires": { + "@vue/compiler-dom": "3.0.11", + "@vue/shared": "3.0.11" + } + }, + "@vue/component-compiler-utils": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@vue/component-compiler-utils/-/component-compiler-utils-3.2.0.tgz", + "integrity": "sha512-lejBLa7xAMsfiZfNp7Kv51zOzifnb29FwdnMLa96z26kXErPFioSf9BMcePVIQ6/Gc6/mC0UrPpxAWIHyae0vw==", + "dev": true, + "requires": { + "consolidate": "^0.15.1", + "hash-sum": "^1.0.2", + "lru-cache": "^4.1.2", + "merge-source-map": "^1.1.0", + "postcss": "^7.0.14", + "postcss-selector-parser": "^6.0.2", + "prettier": "^1.18.2", + "source-map": "~0.6.1", + "vue-template-es2015-compiler": "^1.9.0" + }, + "dependencies": { + "consolidate": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.15.1.tgz", + "integrity": "sha512-DW46nrsMJgy9kqAbPt5rKaCr7uFtpo4mSUvLHIUbJEjm0vo+aY5QLwBUq3FK4tRnJr/X0Psc0C4jf/h+HtXSMw==", + "dev": true, + "requires": { + "bluebird": "^3.1.1" + } + }, + "hash-sum": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", + "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=", + "dev": true + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + } + } + }, + "@vue/devtools-api": { + "version": "6.0.0-beta.10", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.0.0-beta.10.tgz", + "integrity": "sha512-nktQYRnIFrh4DdXiCBjHnsHOMZXDIVcP9qlm/DMfxmjJMtpMGrSZCOKP8j7kDhObNHyqlicwoGLd+a4hf4x9ww==" + }, + "@vue/eslint-config-typescript": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@vue/eslint-config-typescript/-/eslint-config-typescript-7.0.0.tgz", + "integrity": "sha512-UxUlvpSrFOoF8aQ+zX1leYiEBEm7CZmXYn/ZEM1zwSadUzpamx56RB4+Htdjisv1mX2tOjBegNUqH3kz2OL+Aw==", + "dev": true, + "requires": { + "vue-eslint-parser": "^7.0.0" + } + }, + "@vue/preload-webpack-plugin": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@vue/preload-webpack-plugin/-/preload-webpack-plugin-1.1.2.tgz", + "integrity": "sha512-LIZMuJk38pk9U9Ur4YzHjlIyMuxPlACdBIHH9/nGYVTsaGKOSnSuELiE8vS9wa+dJpIYspYUOqk+L1Q4pgHQHQ==", + "dev": true, + "requires": {} + }, + "@vue/reactivity": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.0.11.tgz", + "integrity": "sha512-SKM3YKxtXHBPMf7yufXeBhCZ4XZDKP9/iXeQSC8bBO3ivBuzAi4aZi0bNoeE2IF2iGfP/AHEt1OU4ARj4ao/Xw==", + "requires": { + "@vue/shared": "3.0.11" + } + }, + "@vue/runtime-core": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.0.11.tgz", + "integrity": "sha512-87XPNwHfz9JkmOlayBeCCfMh9PT2NBnv795DSbi//C/RaAnc/bGZgECjmkD7oXJ526BZbgk9QZBPdFT8KMxkAg==", + "requires": { + "@vue/reactivity": "3.0.11", + "@vue/shared": "3.0.11" + } + }, + "@vue/runtime-dom": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.0.11.tgz", + "integrity": "sha512-jm3FVQESY3y2hKZ2wlkcmFDDyqaPyU3p1IdAX92zTNeCH7I8zZ37PtlE1b9NlCtzV53WjB4TZAYh9yDCMIEumA==", + "requires": { + "@vue/runtime-core": "3.0.11", + "@vue/shared": "3.0.11", + "csstype": "^2.6.8" + } + }, + "@vue/shared": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.0.11.tgz", + "integrity": "sha512-b+zB8A2so8eCE0JsxjL24J7vdGl8rzPQ09hZNhystm+KqSbKcAej1A+Hbva1rCMmTTqA+hFnUSDc5kouEo0JzA==" + }, + "@vue/web-component-wrapper": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@vue/web-component-wrapper/-/web-component-wrapper-1.3.0.tgz", + "integrity": "sha512-Iu8Tbg3f+emIIMmI2ycSI8QcEuAUgPTgHwesDU1eKMLE4YC/c/sFbGc70QgMq31ijRftV0R7vCm9co6rldCeOA==", + "dev": true + }, + "@webassemblyjs/ast": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", + "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", + "dev": true, + "requires": { + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", + "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", + "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", + "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==", + "dev": true + }, + "@webassemblyjs/helper-code-frame": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", + "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", + "dev": true, + "requires": { + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "@webassemblyjs/helper-fsm": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", + "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==", + "dev": true + }, + "@webassemblyjs/helper-module-context": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", + "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", + "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", + "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", + "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", + "dev": true, + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", + "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", + "dev": true, + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", + "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", + "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/helper-wasm-section": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-opt": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", + "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", + "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", + "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "@webassemblyjs/wast-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", + "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/floating-point-hex-parser": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-code-frame": "1.9.0", + "@webassemblyjs/helper-fsm": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", + "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "dev": true, + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" + }, + "acorn-jsx": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "dev": true, + "requires": {} + }, + "acorn-node": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", + "integrity": "sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==", + "requires": { + "acorn": "^7.0.0", + "acorn-walk": "^7.0.0", + "xtend": "^4.0.2" + } + }, + "acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==" + }, + "address": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz", + "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==", + "dev": true + }, + "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" + } + }, + "ajv-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", + "dev": true, + "requires": {} + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "requires": {} + }, + "alphanum-sort": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", + "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", + "dev": true + }, + "ansi-colors": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", + "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", + "dev": true + }, + "ansi-html": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", + "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=", + "dev": true + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "arch": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", + "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", + "dev": true + }, + "archive-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/archive-type/-/archive-type-4.0.0.tgz", + "integrity": "sha1-+S5yIzBW38aWlHJ0nCZ72wRrHXA=", + "dev": true, + "requires": { + "file-type": "^4.2.0" + }, + "dependencies": { + "file-type": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-4.4.0.tgz", + "integrity": "sha1-G2AOX8ofvcboDApwxxyNul95BsU=", + "dev": true + } + } + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "dev": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "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" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "dev": true + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, + "assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "dev": true, + "requires": { + "object-assign": "^4.1.1", + "util": "0.10.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } + }, + "async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", + "dev": true + }, + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==" + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" + }, + "autoprefixer": { + "version": "9.8.6", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.6.tgz", + "integrity": "sha512-XrvP4VVHdRBCdX1S3WXVD8+RyG9qeb1D5Sn1DeLiG2xfSpzellk5k54xbUERJ3M5DggQxes39UGOTP8CFrEGbg==", + "requires": { + "browserslist": "^4.12.0", + "caniuse-lite": "^1.0.30001109", + "colorette": "^1.2.1", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "postcss": "^7.0.32", + "postcss-value-parser": "^4.1.0" + } + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "aws4": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz", + "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==", + "dev": true + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + } + } + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true + }, + "batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "bfj": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/bfj/-/bfj-6.1.2.tgz", + "integrity": "sha512-BmBJa4Lip6BPRINSZ0BPEIfB1wUY/9rwbwvIHQA1KjX9om29B6id0wnWXq7m3bn5JrUVjeOTnVuhPT1FiHwPGw==", + "dev": true, + "requires": { + "bluebird": "^3.5.5", + "check-types": "^8.0.3", + "hoopy": "^0.1.4", + "tryer": "^1.0.1" + } + }, + "big-integer": { + "version": "1.6.48", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.48.tgz", + "integrity": "sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w==", + "dev": true + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true + }, + "binary": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", + "integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=", + "dev": true, + "requires": { + "buffers": "~0.1.1", + "chainsaw": "~0.1.0" + } + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "optional": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "bl": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", + "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", + "dev": true, + "requires": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + } + }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw==", + "dev": true + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "dev": true + } + } + }, + "bonjour": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", + "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", + "dev": true, + "requires": { + "array-flatten": "^2.1.0", + "deep-equal": "^1.0.1", + "dns-equal": "^1.0.0", + "dns-txt": "^2.0.2", + "multicast-dns": "^6.0.1", + "multicast-dns-service-types": "^1.1.0" + }, + "dependencies": { + "array-flatten": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", + "dev": true + } + } + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", + "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==", + "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==", + "requires": { + "fill-range": "^7.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", + "dev": true, + "requires": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "browserify-sign": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", + "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", + "dev": true, + "requires": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + } + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "requires": { + "pako": "~1.0.5" + } + }, + "browserslist": { + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "requires": { + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" + } + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "dev": true, + "requires": { + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" + } + }, + "buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", + "dev": true + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, + "buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", + "dev": true + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "buffer-indexof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", + "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==", + "dev": true + }, + "buffer-indexof-polyfill": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz", + "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==", + "dev": true + }, + "buffer-json": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/buffer-json/-/buffer-json-2.0.0.tgz", + "integrity": "sha512-+jjPFVqyfF1esi9fvfUs3NqM0pH1ziZ36VP4hmA/y/Ssfo/5w5xHKfTw9BwQjoJ1w/oVtpLomqwUHKdefGyuHw==", + "dev": true + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "buffers": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", + "integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=", + "dev": true + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + }, + "cacache": { + "version": "12.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", + "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", + "dev": true, + "requires": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + }, + "dependencies": { + "ssri": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.2.tgz", + "integrity": "sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==", + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1" + } + } + } + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "cache-loader": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cache-loader/-/cache-loader-4.1.0.tgz", + "integrity": "sha512-ftOayxve0PwKzBF/GLsZNC9fJBXl8lkZE3TOsjkboHfVHVkL39iUEs1FO07A33mizmci5Dudt38UZrrYXDtbhw==", + "dev": true, + "requires": { + "buffer-json": "^2.0.0", + "find-cache-dir": "^3.0.0", + "loader-utils": "^1.2.3", + "mkdirp": "^0.5.1", + "neo-async": "^2.6.1", + "schema-utils": "^2.0.0" + } + }, + "cacheable-request": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz", + "integrity": "sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0=", + "dev": true, + "requires": { + "clone-response": "1.0.2", + "get-stream": "3.0.0", + "http-cache-semantics": "3.8.1", + "keyv": "3.0.0", + "lowercase-keys": "1.0.0", + "normalize-url": "2.0.1", + "responselike": "1.0.2" + }, + "dependencies": { + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "lowercase-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", + "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=", + "dev": true + } + } + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "call-me-maybe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", + "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=", + "dev": true + }, + "caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "dev": true, + "requires": { + "callsites": "^2.0.0" + } + }, + "caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "dev": true, + "requires": { + "caller-callsite": "^2.0.0" + } + }, + "callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "dev": true + }, + "camel-case": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", + "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", + "dev": true, + "requires": { + "no-case": "^2.2.0", + "upper-case": "^1.1.1" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "camelcase-css": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", + "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==" + }, + "caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "caniuse-lite": { + "version": "1.0.30001232", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001232.tgz", + "integrity": "sha512-e4Gyp7P8vqC2qV2iHA+cJNf/yqUKOShXQOJHQt81OHxlIZl/j/j3soEA0adAQi8CPUQgvOdDENyQ5kd6a6mNSg==" + }, + "case-sensitive-paths-webpack-plugin": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz", + "integrity": "sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "chainsaw": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", + "integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=", + "dev": true, + "requires": { + "traverse": ">=0.3.0 <0.4" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "check-types": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/check-types/-/check-types-8.0.3.tgz", + "integrity": "sha512-YpeKZngUmG65rLudJ4taU7VLkOCTMhNl/u4ctNC56LQS/zJTyNH0Lrtwm1tfTsbLlwvlfsA2d1c8vCf/Kh2KwQ==", + "dev": true + }, + "chokidar": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.3.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + } + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true + }, + "ci-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "dev": true + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "clean-css": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz", + "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==", + "dev": true, + "requires": { + "source-map": "~0.6.0" + } + }, + "cli-highlight": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz", + "integrity": "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "highlight.js": "^10.7.1", + "mz": "^2.4.0", + "parse5": "^5.1.1", + "parse5-htmlparser2-tree-adapter": "^6.0.0", + "yargs": "^16.0.0" + } + }, + "cli-spinners": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.0.tgz", + "integrity": "sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q==", + "dev": true + }, + "clipboardy": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-2.3.0.tgz", + "integrity": "sha512-mKhiIL2DrQIsuXMgBgnfEHOZOryC7kY7YO//TN6c63wlEm3NG5tz+YgY5rVi29KCmq/QQjKYvM7a19+MDOTHOQ==", + "dev": true, + "requires": { + "arch": "^2.1.1", + "execa": "^1.0.0", + "is-wsl": "^2.1.1" + } + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "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 + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=" + }, + "clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + } + }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "clone-stats": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", + "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=" + }, + "coa": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", + "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", + "dev": true, + "requires": { + "@types/q": "^1.5.1", + "chalk": "^2.4.1", + "q": "^1.1.2" + }, + "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": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "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" + } + } + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/color/-/color-3.1.3.tgz", + "integrity": "sha512-xgXAcTHa2HeFCGLE9Xs/R82hujGtu9Jd9x4NW3T34+OMs7VoPsjwzRczKHvTAHeJwWFwX5j15+MgAppE8ztObQ==", + "requires": { + "color-convert": "^1.9.1", + "color-string": "^1.5.4" + }, + "dependencies": { + "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==", + "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": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + } + } + }, + "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==", + "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==" + }, + "color-string": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.5.tgz", + "integrity": "sha512-jgIoum0OfQfq9Whcfc2z/VhCNcmQjWbey6qBX0vqt7YICflUmBCh9E9CiQD5GSJ+Uehixm3NUwHVhqUAWRivZg==", + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "colorette": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==" + }, + "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" + } + }, + "commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==" + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" + }, + "compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "requires": { + "mime-db": ">= 1.43.0 < 2" + } + }, + "compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dev": true, + "requires": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "dependencies": { + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "connect-history-api-fallback": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", + "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", + "dev": true + }, + "console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "dev": true + }, + "consolidate": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.16.0.tgz", + "integrity": "sha512-Nhl1wzCslqXYTJVDyJCu3ODohy9OfBMB5uD2BiBTzd7w+QY0lBzafkR8y8755yMYHAaMD4NuzbAw03/xzfw+eQ==", + "dev": true, + "requires": { + "bluebird": "^3.7.2" + } + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "dev": true, + "requires": { + "safe-buffer": "5.1.2" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true + }, + "convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "dev": true + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "dev": true + }, + "copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "dev": true, + "requires": { + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "copy-webpack-plugin": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.1.2.tgz", + "integrity": "sha512-Uh7crJAco3AjBvgAy9Z75CjK8IG+gxaErro71THQ+vv/bl4HaQcpkexAY8KVW/T6D2W2IRr+couF/knIRkZMIQ==", + "dev": true, + "requires": { + "cacache": "^12.0.3", + "find-cache-dir": "^2.1.0", + "glob-parent": "^3.1.0", + "globby": "^7.1.1", + "is-glob": "^4.0.1", + "loader-utils": "^1.2.3", + "minimatch": "^3.0.4", + "normalize-path": "^3.0.0", + "p-limit": "^2.2.1", + "schema-utils": "^1.0.0", + "serialize-javascript": "^4.0.0", + "webpack-log": "^2.0.0" + }, + "dependencies": { + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } + }, + "dir-glob": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", + "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", + "dev": true, + "requires": { + "path-type": "^3.0.0" + } + }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "globby": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz", + "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "dir-glob": "^2.0.0", + "glob": "^7.1.2", + "ignore": "^3.3.5", + "pify": "^3.0.0", + "slash": "^1.0.0" + } + }, + "ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "dev": true + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true + } + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + } + }, + "create-ecdh": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "css": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", + "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", + "requires": { + "inherits": "^2.0.3", + "source-map": "^0.6.1", + "source-map-resolve": "^0.5.2", + "urix": "^0.1.0" + } + }, + "css-color-names": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", + "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", + "dev": true + }, + "css-declaration-sorter": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz", + "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==", + "dev": true, + "requires": { + "postcss": "^7.0.1", + "timsort": "^0.3.0" + } + }, + "css-loader": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-3.6.0.tgz", + "integrity": "sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "cssesc": "^3.0.0", + "icss-utils": "^4.1.1", + "loader-utils": "^1.2.3", + "normalize-path": "^3.0.0", + "postcss": "^7.0.32", + "postcss-modules-extract-imports": "^2.0.0", + "postcss-modules-local-by-default": "^3.0.2", + "postcss-modules-scope": "^2.2.0", + "postcss-modules-values": "^3.0.0", + "postcss-value-parser": "^4.1.0", + "schema-utils": "^2.7.0", + "semver": "^6.3.0" + }, + "dependencies": { + "icss-utils": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz", + "integrity": "sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==", + "dev": true, + "requires": { + "postcss": "^7.0.14" + } + }, + "postcss-modules-extract-imports": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz", + "integrity": "sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==", + "dev": true, + "requires": { + "postcss": "^7.0.5" + } + }, + "postcss-modules-local-by-default": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz", + "integrity": "sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw==", + "dev": true, + "requires": { + "icss-utils": "^4.1.1", + "postcss": "^7.0.32", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-modules-scope": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz", + "integrity": "sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==", + "dev": true, + "requires": { + "postcss": "^7.0.6", + "postcss-selector-parser": "^6.0.0" + } + }, + "postcss-modules-values": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz", + "integrity": "sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==", + "dev": true, + "requires": { + "icss-utils": "^4.0.0", + "postcss": "^7.0.6" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "css-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", + "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", + "dev": true, + "requires": { + "boolbase": "^1.0.0", + "css-what": "^3.2.1", + "domutils": "^1.7.0", + "nth-check": "^1.0.2" + } + }, + "css-select-base-adapter": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", + "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==", + "dev": true + }, + "css-tree": { + "version": "1.0.0-alpha.37", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", + "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", + "dev": true, + "requires": { + "mdn-data": "2.0.4", + "source-map": "^0.6.1" + } + }, + "css-unit-converter": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.2.tgz", + "integrity": "sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA==" + }, + "css-what": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", + "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==", + "dev": true + }, + "cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==" + }, + "cssnano": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.11.tgz", + "integrity": "sha512-6gZm2htn7xIPJOHY824ERgj8cNPgPxyCSnkXc4v7YvNW+TdVfzgngHcEhy/8D11kUWRUMbke+tC+AUcUsnMz2g==", + "dev": true, + "requires": { + "cosmiconfig": "^5.0.0", + "cssnano-preset-default": "^4.0.8", + "is-resolvable": "^1.0.0", + "postcss": "^7.0.0" + } + }, + "cssnano-preset-default": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.8.tgz", + "integrity": "sha512-LdAyHuq+VRyeVREFmuxUZR1TXjQm8QQU/ktoo/x7bz+SdOge1YKc5eMN6pRW7YWBmyq59CqYba1dJ5cUukEjLQ==", + "dev": true, + "requires": { + "css-declaration-sorter": "^4.0.1", + "cssnano-util-raw-cache": "^4.0.1", + "postcss": "^7.0.0", + "postcss-calc": "^7.0.1", + "postcss-colormin": "^4.0.3", + "postcss-convert-values": "^4.0.1", + "postcss-discard-comments": "^4.0.2", + "postcss-discard-duplicates": "^4.0.2", + "postcss-discard-empty": "^4.0.1", + "postcss-discard-overridden": "^4.0.1", + "postcss-merge-longhand": "^4.0.11", + "postcss-merge-rules": "^4.0.3", + "postcss-minify-font-values": "^4.0.2", + "postcss-minify-gradients": "^4.0.2", + "postcss-minify-params": "^4.0.2", + "postcss-minify-selectors": "^4.0.2", + "postcss-normalize-charset": "^4.0.1", + "postcss-normalize-display-values": "^4.0.2", + "postcss-normalize-positions": "^4.0.2", + "postcss-normalize-repeat-style": "^4.0.2", + "postcss-normalize-string": "^4.0.2", + "postcss-normalize-timing-functions": "^4.0.2", + "postcss-normalize-unicode": "^4.0.1", + "postcss-normalize-url": "^4.0.1", + "postcss-normalize-whitespace": "^4.0.2", + "postcss-ordered-values": "^4.1.2", + "postcss-reduce-initial": "^4.0.3", + "postcss-reduce-transforms": "^4.0.2", + "postcss-svgo": "^4.0.3", + "postcss-unique-selectors": "^4.0.1" + } + }, + "cssnano-util-get-arguments": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz", + "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=", + "dev": true + }, + "cssnano-util-get-match": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz", + "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=", + "dev": true + }, + "cssnano-util-raw-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz", + "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "cssnano-util-same-parent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz", + "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==", + "dev": true + }, + "csso": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", + "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "dev": true, + "requires": { + "css-tree": "^1.1.2" + }, + "dependencies": { + "css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "dev": true, + "requires": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + } + }, + "mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", + "dev": true + } + } + }, + "csstype": { + "version": "2.6.17", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.17.tgz", + "integrity": "sha512-u1wmTI1jJGzCJzWndZo8mk4wnPTZd1eOIYTYvuEyOQGfmDl3TrabCCfKnOC86FZwW/9djqTl933UF/cS425i9A==" + }, + "cyclist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", + "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", + "dev": true + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "debug-fabulous": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-0.0.4.tgz", + "integrity": "sha1-+gccXYdIRoVCSAdCHKSxawsaB2M=", + "requires": { + "debug": "2.X", + "lazy-debug-legacy": "0.0.X", + "object-assign": "4.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "object-assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz", + "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A=" + } + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" + }, + "decompress": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.1.tgz", + "integrity": "sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==", + "dev": true, + "requires": { + "decompress-tar": "^4.0.0", + "decompress-tarbz2": "^4.0.0", + "decompress-targz": "^4.0.0", + "decompress-unzip": "^4.0.1", + "graceful-fs": "^4.1.10", + "make-dir": "^1.0.0", + "pify": "^2.3.0", + "strip-dirs": "^2.0.0" + }, + "dependencies": { + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "dev": true, + "requires": { + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "decompress-response": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", + "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "decompress-tar": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", + "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", + "dev": true, + "requires": { + "file-type": "^5.2.0", + "is-stream": "^1.1.0", + "tar-stream": "^1.5.2" + }, + "dependencies": { + "file-type": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", + "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=", + "dev": true + } + } + }, + "decompress-tarbz2": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", + "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", + "dev": true, + "requires": { + "decompress-tar": "^4.1.0", + "file-type": "^6.1.0", + "is-stream": "^1.1.0", + "seek-bzip": "^1.0.5", + "unbzip2-stream": "^1.0.9" + }, + "dependencies": { + "file-type": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz", + "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==", + "dev": true + } + } + }, + "decompress-targz": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", + "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", + "dev": true, + "requires": { + "decompress-tar": "^4.1.1", + "file-type": "^5.2.0", + "is-stream": "^1.1.0" + }, + "dependencies": { + "file-type": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", + "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=", + "dev": true + } + } + }, + "decompress-unzip": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", + "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=", + "dev": true, + "requires": { + "file-type": "^3.8.0", + "get-stream": "^2.2.0", + "pify": "^2.3.0", + "yauzl": "^2.4.2" + }, + "dependencies": { + "file-type": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", + "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=", + "dev": true + }, + "get-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", + "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", + "dev": true, + "requires": { + "object-assign": "^4.0.1", + "pinkie-promise": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "deep-equal": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", + "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", + "dev": true, + "requires": { + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.1", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.2.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "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, + "optional": true + }, + "default-gateway": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-5.0.5.tgz", + "integrity": "sha512-z2RnruVmj8hVMmAnEJMTIJNijhKCDiGjbLP+BHJFOT7ld3Bo5qcIBpVYDniqhbMIIf+jZDlkP2MkPXiQy/DBLA==", + "dev": true, + "requires": { + "execa": "^3.3.0" + }, + "dependencies": { + "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" + } + }, + "execa": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-3.4.0.tgz", + "integrity": "sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "p-finally": "^2.0.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + } + }, + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "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" + } + }, + "p-finally": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", + "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==", + "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 + }, + "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 + }, + "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" + } + } + } + }, + "defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "dev": true, + "requires": { + "clone": "^1.0.2" + } + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + } + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=" + }, + "del": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", + "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "globby": "^6.1.0", + "is-path-cwd": "^2.0.0", + "is-path-in-cwd": "^2.0.0", + "p-map": "^2.0.0", + "pify": "^4.0.1", + "rimraf": "^2.6.3" + }, + "dependencies": { + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } + }, + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true + }, + "des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true + }, + "detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", + "dev": true + }, + "detect-newline": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", + "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=" + }, + "detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true + }, + "detective": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz", + "integrity": "sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg==", + "requires": { + "acorn-node": "^1.6.1", + "defined": "^1.0.0", + "minimist": "^1.1.1" + } + }, + "didyoumean": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.1.tgz", + "integrity": "sha1-6S7f2tplN9SE1zwBcv0eugxJdv8=" + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, + "dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" + }, + "dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=", + "dev": true + }, + "dns-packet": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz", + "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", + "dev": true, + "requires": { + "ip": "^1.1.0", + "safe-buffer": "^5.0.1" + } + }, + "dns-txt": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", + "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", + "dev": true, + "requires": { + "buffer-indexof": "^1.0.0" + } + }, + "dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "dev": true, + "requires": { + "utila": "~0.4" + } + }, + "dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + }, + "dependencies": { + "domelementtype": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", + "dev": true + } + } + }, + "domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true + }, + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true + }, + "domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "dev": true, + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dev": true, + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "requires": { + "is-obj": "^2.0.0" + } + }, + "dotenv": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", + "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==", + "dev": true + }, + "dotenv-expand": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", + "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==", + "dev": true + }, + "download": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/download/-/download-8.0.0.tgz", + "integrity": "sha512-ASRY5QhDk7FK+XrQtQyvhpDKanLluEEQtWl/J7Lxuf/b+i8RYh997QeXvL85xitrmRKVlx9c7eTrcRdq2GS4eA==", + "dev": true, + "requires": { + "archive-type": "^4.0.0", + "content-disposition": "^0.5.2", + "decompress": "^4.2.1", + "ext-name": "^5.0.0", + "file-type": "^11.1.0", + "filenamify": "^3.0.0", + "get-stream": "^4.1.0", + "got": "^8.3.1", + "make-dir": "^2.1.0", + "p-event": "^2.1.0", + "pify": "^4.0.1" + } + }, + "duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "dev": true + }, + "duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "dev": true, + "requires": { + "readable-stream": "^2.0.2" + } + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, + "duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "easy-stack": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/easy-stack/-/easy-stack-1.0.1.tgz", + "integrity": "sha512-wK2sCs4feiiJeFXn3zvY0p41mdU5VUgbgs1rNsc/y5ngFUijdWd+iIN8eoyuZHKB8xN6BL4PdWmzqFmxNg6V2w==", + "dev": true + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "ejs": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.4.tgz", + "integrity": "sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==", + "dev": true + }, + "electron-to-chromium": { + "version": "1.3.732", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.732.tgz", + "integrity": "sha512-qKD5Pbq+QMk4nea4lMuncUMhpEiQwaJyCW7MrvissnRcBDENhVfDmAqQYRQ3X525oTzhar9Zh1cK0L2d1UKYcw==" + }, + "elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "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 + }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "requires": { + "once": "^1.4.0" + } + }, + "enhanced-resolve": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", + "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.5.0", + "tapable": "^1.0.0" + } + }, + "entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true + }, + "errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dev": true, + "requires": { + "prr": "~1.0.1" + } + }, + "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==", + "requires": { + "is-arrayish": "^0.2.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + } + } + }, + "error-stack-parser": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.0.6.tgz", + "integrity": "sha512-d51brTeqC+BHlwF0BhPtcYgF5nlzf9ZZ0ZIUQNZpc9ZB9qw5IJ2diTrBY9jlCJkTLITYPjmiX6OWCwH+fuyNgQ==", + "dev": true, + "requires": { + "stackframe": "^1.1.1" + } + }, + "es-abstract": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz", + "integrity": "sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.2", + "is-string": "^1.0.5", + "object-inspect": "^1.9.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.0" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "esbuild": { + "version": "0.11.23", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.11.23.tgz", + "integrity": "sha512-iaiZZ9vUF5wJV8ob1tl+5aJTrwDczlvGP0JoMmnpC2B0ppiMCu8n8gmy5ZTGl5bcG081XBVn+U+jP+mPFm5T5Q==", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "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": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "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" + } + }, + "espree": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", + "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", + "dev": true, + "requires": { + "acorn": "^7.1.1", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "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" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "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" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true + }, + "event-pubsub": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/event-pubsub/-/event-pubsub-4.3.0.tgz", + "integrity": "sha512-z7IyloorXvKbFx9Bpie2+vMJKKx1fH1EN5yiTfp8CiLOTptSYy1g8H4yDpGlEdshL1PBiFtBHepF2cNsqeEeFQ==", + "dev": true + }, + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true + }, + "eventsource": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.1.0.tgz", + "integrity": "sha512-VSJjT5oCNrFvCS6igjzPAt5hBzQ2qPBFIbJ03zLI9SE0mxwZpMw6BfJrbFHm1a141AavMEB8JHmBhWAd66PfCg==", + "dev": true, + "requires": { + "original": "^1.0.0" + } + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "requires": { + "fill-range": "^2.1.0" + }, + "dependencies": { + "fill-range": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", + "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", + "requires": { + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^3.0.0", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" + } + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "requires": { + "kind-of": "^3.0.2" + } + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "requires": { + "isarray": "1.0.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "dev": true, + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "dev": true + } + } + }, + "ext-list": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz", + "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==", + "dev": true, + "requires": { + "mime-db": "^1.28.0" + } + }, + "ext-name": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz", + "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==", + "dev": true, + "requires": { + "ext-list": "^2.0.0", + "sort-keys-length": "^1.0.0" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "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.5", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.5.tgz", + "integrity": "sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==", + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2", + "picomatch": "^2.2.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 + }, + "fastq": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.11.0.tgz", + "integrity": "sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==", + "requires": { + "reusify": "^1.0.4" + } + }, + "faye-websocket": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", + "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", + "dev": true, + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, + "figgy-pudding": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", + "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", + "dev": true + }, + "file-loader": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-4.3.0.tgz", + "integrity": "sha512-aKrYPYjF1yG3oX0kWRrqrSMfgftm7oJW5M+m4owoldH5C51C0RkIwB++JbRvEW3IU6/ZG5n8UvEcdgwOt2UOWA==", + "dev": true, + "requires": { + "loader-utils": "^1.2.3", + "schema-utils": "^2.5.0" + } + }, + "file-type": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-11.1.0.tgz", + "integrity": "sha512-rM0UO7Qm9K7TWTtA6AShI/t7H5BPjDeGVDaNyg9BjHAj3PysKy7+8C8D137R88jnR3rFJZQB/tFgydl5sN5m7g==", + "dev": true + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=" + }, + "filename-reserved-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", + "integrity": "sha1-q/c9+rc10EVECr/qLZHzieu/oik=", + "dev": true + }, + "filenamify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-3.0.0.tgz", + "integrity": "sha512-5EFZ//MsvJgXjBAFJ+Bh2YaCTRF/VP1YOmGrgt+KJ4SFRLjI87EIdwLLuT6wQX0I4F9W41xutobzczjsOKlI/g==", + "dev": true, + "requires": { + "filename-reserved-regex": "^2.0.0", + "strip-outer": "^1.0.0", + "trim-repeated": "^1.0.0" + } + }, + "filesize": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-3.6.1.tgz", + "integrity": "sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg==", + "dev": true + }, + "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==", + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "find-cache-dir": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "dependencies": { + "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" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "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" + } + }, + "first-chunk-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz", + "integrity": "sha1-Wb+1DNkF9g18OUzT2ayqtOatk04=" + }, + "flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "follow-redirects": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz", + "integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==", + "dev": true + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" + }, + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "requires": { + "for-in": "^1.0.1" + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "fork-ts-checker-webpack-plugin": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-3.1.1.tgz", + "integrity": "sha512-DuVkPNrM12jR41KM2e+N+styka0EgLkTnXmNcXdgOM37vtGeY+oCBK/Jx0hzSeEU6memFCtWb4htrHPMDfwwUQ==", + "dev": true, + "requires": { + "babel-code-frame": "^6.22.0", + "chalk": "^2.4.1", + "chokidar": "^3.3.0", + "micromatch": "^3.1.10", + "minimatch": "^3.0.4", + "semver": "^5.6.0", + "tapable": "^1.0.0", + "worker-rpc": "^0.1.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" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.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": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "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" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "fork-ts-checker-webpack-plugin-v5": { + "version": "npm:fork-ts-checker-webpack-plugin@5.2.1", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-5.2.1.tgz", + "integrity": "sha512-SVi+ZAQOGbtAsUWrZvGzz38ga2YqjWvca1pXQFUArIVXqli0lLoDQ8uS0wg0kSpcwpZmaW5jVCZXQebkyUQSsw==", + "dev": true, + "optional": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@types/json-schema": "^7.0.5", + "chalk": "^4.1.0", + "cosmiconfig": "^6.0.0", + "deepmerge": "^4.2.2", + "fs-extra": "^9.0.0", + "memfs": "^3.1.2", + "minimatch": "^3.0.4", + "schema-utils": "2.7.0", + "semver": "^7.3.2", + "tapable": "^1.0.0" + }, + "dependencies": { + "cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "dev": true, + "optional": true, + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + } + }, + "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, + "optional": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "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, + "optional": true, + "requires": { + "yallist": "^4.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, + "optional": 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" + } + }, + "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, + "optional": true + }, + "schema-utils": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", + "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "dev": true, + "optional": true, + "requires": { + "@types/json-schema": "^7.0.4", + "ajv": "^6.12.2", + "ajv-keywords": "^3.4.1" + } + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "optional": true, + "requires": { + "lru-cache": "^6.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, + "optional": true + } + } + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "dev": true + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "dev": true + }, + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "dev": true, + "requires": { + "minipass": "^2.6.0" + } + }, + "fs-monkey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", + "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==", + "dev": true, + "optional": true + }, + "fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "optional": true + }, + "fstream": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", + "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dev": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "generic-names": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generic-names/-/generic-names-2.0.1.tgz", + "integrity": "sha512-kPCHWa1m9wGG/OwQpeweTwM/PYiQLrUIxXbt/P4Nic3LbGjCP0YwrALHW1uNLKZ0LIMg+RF+XRlj2ekT9ZlZAQ==", + "dev": true, + "requires": { + "loader-utils": "^1.1.0" + } + }, + "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-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "requires": { + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" + }, + "dependencies": { + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "requires": { + "is-glob": "^2.0.0" + } + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "requires": { + "is-extglob": "^1.0.0" + } + } + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "requires": { + "is-glob": "^4.0.1" + } + }, + "glob-stream": { + "version": "5.3.5", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-5.3.5.tgz", + "integrity": "sha1-pVZlqajM3EGRWofHAeMtTgFvrSI=", + "requires": { + "extend": "^3.0.0", + "glob": "^5.0.3", + "glob-parent": "^3.0.0", + "micromatch": "^2.3.7", + "ordered-read-streams": "^0.3.0", + "through2": "^0.6.0", + "to-absolute-glob": "^0.1.1", + "unique-stream": "^2.0.2" + }, + "dependencies": { + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "requires": { + "arr-flatten": "^1.0.1" + } + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=" + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "requires": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "requires": { + "is-posix-bracket": "^0.1.0" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "requires": { + "is-extglob": "^1.0.0" + }, + "dependencies": { + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + } + } + }, + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "requires": { + "is-extglob": "^2.1.0" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "requires": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" + }, + "dependencies": { + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "requires": { + "is-extglob": "^1.0.0" + } + } + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "requires": { + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + } + } + } + }, + "glob-to-regexp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", + "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=", + "dev": true + }, + "google-protobuf": { + "version": "3.15.8", + "resolved": "https://registry.npmjs.org/google-protobuf/-/google-protobuf-3.15.8.tgz", + "integrity": "sha512-2jtfdqTaSxk0cuBJBtTTWsot4WtR9RVr2rXg7x7OoqiuOKopPrwXpM1G4dXIkLcUNRh3RKzz76C8IOkksZSeOw==", + "dev": true + }, + "got": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/got/-/got-8.3.2.tgz", + "integrity": "sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==", + "dev": true, + "requires": { + "@sindresorhus/is": "^0.7.0", + "cacheable-request": "^2.1.1", + "decompress-response": "^3.3.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "into-stream": "^3.1.0", + "is-retry-allowed": "^1.1.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "mimic-response": "^1.0.0", + "p-cancelable": "^0.4.0", + "p-timeout": "^2.0.1", + "pify": "^3.0.0", + "safe-buffer": "^5.1.1", + "timed-out": "^4.0.1", + "url-parse-lax": "^3.0.0", + "url-to-options": "^1.0.1" + }, + "dependencies": { + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, + "graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==" + }, + "grpc_tools_node_protoc_ts": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/grpc_tools_node_protoc_ts/-/grpc_tools_node_protoc_ts-5.2.2.tgz", + "integrity": "sha512-j8waJdU9uzNSyYJfEAGFFJdxP2C3k7RNkgI1dXxLB/iaT+D54p/RX1Wo+cHH2wPhBSE8hnv+BUv7HuEVT/XLPw==", + "dev": true, + "requires": { + "google-protobuf": "3.15.8", + "handlebars": "4.7.7" + } + }, + "grpc-tools": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/grpc-tools/-/grpc-tools-1.11.1.tgz", + "integrity": "sha512-QNz6xuiyBuHXKu78bv5PAOzv/EBKkH54OgeTkHyFkic8TrY8oiifs6hozRJQxJb+L7k+udWYmPvfK76Pgt4JhA==", + "dev": true, + "requires": { + "node-pre-gyp": "^0.15.0" + } + }, + "grpc-web": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/grpc-web/-/grpc-web-1.2.1.tgz", + "integrity": "sha512-ibBaJPzfMVuLPgaST9w0kZl60s+SnkPBQp6QKdpEr85tpc1gXW2QDqSne9xiyiym0logDfdUSm4aX5h9YBA2mw==" + }, + "gulp-sourcemaps": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-1.12.1.tgz", + "integrity": "sha1-tDfR89mAzyboEYSCNxjOFa5ll7Y=", + "requires": { + "@gulp-sourcemaps/map-sources": "1.X", + "acorn": "4.X", + "convert-source-map": "1.X", + "css": "2.X", + "debug-fabulous": "0.0.X", + "detect-newline": "2.X", + "graceful-fs": "4.X", + "source-map": "~0.6.0", + "strip-bom": "2.X", + "through2": "2.X", + "vinyl": "1.X" + }, + "dependencies": { + "acorn": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", + "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=" + } + } + }, + "gzip-size": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz", + "integrity": "sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA==", + "dev": true, + "requires": { + "duplexer": "^0.1.1", + "pify": "^4.0.1" + } + }, + "handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "dev": true + }, + "handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "dev": true, + "requires": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4", + "wordwrap": "^1.0.0" + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "dev": true, + "requires": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "has-symbol-support-x": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", + "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==", + "dev": true + }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true + }, + "has-to-string-tag-x": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", + "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", + "dev": true, + "requires": { + "has-symbol-support-x": "^1.4.1" + } + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "dev": true + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + } + } + }, + "hash-sum": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz", + "integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==", + "dev": true + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "hex-color-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", + "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==", + "dev": true + }, + "highlight.js": { + "version": "10.7.2", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.2.tgz", + "integrity": "sha512-oFLl873u4usRM9K63j4ME9u3etNF0PLiJhSQ8rdfuL51Wn3zkD6drf9ZW0dOzjnZI22YYG24z30JcmfCZjMgYg==", + "dev": true + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "hoopy": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", + "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==", + "dev": true + }, + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==" + }, + "hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "hsl-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz", + "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=", + "dev": true + }, + "hsla-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz", + "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=", + "dev": true + }, + "html-entities": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.4.0.tgz", + "integrity": "sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA==", + "dev": true + }, + "html-minifier": { + "version": "3.5.21", + "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.21.tgz", + "integrity": "sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==", + "dev": true, + "requires": { + "camel-case": "3.0.x", + "clean-css": "4.2.x", + "commander": "2.17.x", + "he": "1.2.x", + "param-case": "2.1.x", + "relateurl": "0.2.x", + "uglify-js": "3.4.x" + }, + "dependencies": { + "commander": { + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", + "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", + "dev": true + }, + "uglify-js": { + "version": "3.4.10", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz", + "integrity": "sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==", + "dev": true, + "requires": { + "commander": "~2.19.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "commander": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", + "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", + "dev": true + } + } + } + } + }, + "html-tags": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.1.0.tgz", + "integrity": "sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==" + }, + "html-webpack-plugin": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-3.2.0.tgz", + "integrity": "sha1-sBq71yOsqqeze2r0SS69oD2d03s=", + "dev": true, + "requires": { + "html-minifier": "^3.2.3", + "loader-utils": "^0.2.16", + "lodash": "^4.17.3", + "pretty-error": "^2.0.2", + "tapable": "^1.0.0", + "toposort": "^1.0.0", + "util.promisify": "1.0.0" + }, + "dependencies": { + "big.js": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", + "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", + "dev": true + }, + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "dev": true + }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true + }, + "loader-utils": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", + "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", + "dev": true, + "requires": { + "big.js": "^3.1.3", + "emojis-list": "^2.0.0", + "json5": "^0.5.0", + "object-assign": "^4.0.1" + } + } + } + }, + "htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "dev": true, + "requires": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + }, + "dependencies": { + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "http-cache-semantics": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz", + "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==", + "dev": true + }, + "http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", + "dev": true + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + } + } + }, + "http-parser-js": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.3.tgz", + "integrity": "sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg==", + "dev": true + }, + "http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "requires": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-proxy-middleware": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-1.3.1.tgz", + "integrity": "sha512-13eVVDYS4z79w7f1+NPllJtOQFx/FdUW4btIvVRMaRlUY9VGstAbo5MOhLEuUgZFRHn3x50ufn25zkj/boZnEg==", + "dev": true, + "requires": { + "@types/http-proxy": "^1.17.5", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "dependencies": { + "is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "dev": true + } + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "human-signals": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", + "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "icss-replace-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", + "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=", + "dev": true + }, + "icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "dev": true + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true + }, + "iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", + "dev": true + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "ignore-walk": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.4.tgz", + "integrity": "sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ==", + "dev": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "import-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", + "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=", + "dev": true, + "requires": { + "import-from": "^2.1.0" + } + }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, + "import-from": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", + "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=", + "dev": true, + "requires": { + "resolve-from": "^3.0.0" + } + }, + "import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "dev": true, + "requires": { + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + } + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", + "dev": true + }, + "infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "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==" + }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "internal-ip": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", + "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", + "dev": true, + "requires": { + "default-gateway": "^4.2.0", + "ipaddr.js": "^1.9.0" + }, + "dependencies": { + "default-gateway": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", + "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "ip-regex": "^2.1.0" + } + } + } + }, + "into-stream": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz", + "integrity": "sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY=", + "dev": true, + "requires": { + "from2": "^2.1.1", + "p-is-promise": "^1.1.0" + } + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" + }, + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "dev": true + }, + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "dev": true + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true + }, + "is-absolute-url": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", + "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=", + "dev": true + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-arguments": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.0.tgz", + "integrity": "sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==", + "dev": true, + "requires": { + "call-bind": "^1.0.0" + } + }, + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, + "is-bigint": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz", + "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-boolean-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz", + "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "is-callable": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", + "dev": true + }, + "is-ci": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", + "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", + "dev": true, + "requires": { + "ci-info": "^1.5.0" + } + }, + "is-color-stop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", + "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=", + "dev": true, + "requires": { + "css-color-names": "^0.0.4", + "hex-color-regex": "^1.1.0", + "hsl-regex": "^1.0.0", + "hsla-regex": "^1.0.0", + "rgb-regex": "^1.0.1", + "rgba-regex": "^1.0.0" + } + }, + "is-core-module": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", + "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", + "requires": { + "has": "^1.0.3" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-date-object": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", + "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==", + "dev": true + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "dev": true + }, + "is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true + }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=" + }, + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "requires": { + "is-primitive": "^2.0.0" + } + }, + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-natural-number": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", + "integrity": "sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=", + "dev": true + }, + "is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "is-number-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz", + "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==", + "dev": true + }, + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true + }, + "is-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz", + "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==", + "dev": true + }, + "is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "dev": true + }, + "is-path-in-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", + "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", + "dev": true, + "requires": { + "is-path-inside": "^2.1.0" + } + }, + "is-path-inside": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", + "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", + "dev": true, + "requires": { + "path-is-inside": "^1.0.2" + } + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=" + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=" + }, + "is-regex": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", + "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.2" + } + }, + "is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "dev": true + }, + "is-retry-allowed": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz", + "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "is-string": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", + "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==", + "dev": true + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" + }, + "is-valid-glob": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-0.3.0.tgz", + "integrity": "sha1-1LVcafUYhvm2XHDWwmItN+KfSP4=" + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "requires": { + "is-docker": "^2.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "isurl": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", + "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", + "dev": true, + "requires": { + "has-to-string-tag-x": "^1.2.0", + "is-object": "^1.0.1" + } + }, + "javascript-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", + "integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==", + "dev": true + }, + "jquery": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz", + "integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw==" + }, + "js-message": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/js-message/-/js-message-1.0.7.tgz", + "integrity": "sha512-efJLHhLjIyKRewNS9EGZ4UpI8NguuL6fKkhRxVuMmrGV2xN/0APGdQYwLFky5w9naebSZ0OwAGp0G6/2Cg90rA==", + "dev": true + }, + "js-queue": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/js-queue/-/js-queue-2.0.2.tgz", + "integrity": "sha512-pbKLsbCfi7kriM3s1J4DDCo7jQkI58zPLHi0heXPzPlj0hjUsm+FesPUbE0DSbIVIK503A36aUBoCN7eMFedkA==", + "dev": true, + "requires": { + "easy-stack": "^1.0.1" + } + }, + "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": "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" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "json-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", + "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "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": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "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": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "json3": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz", + "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "keycharm": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/keycharm/-/keycharm-0.4.0.tgz", + "integrity": "sha512-TyQTtsabOVv3MeOpR92sIKk/br9wxS+zGj4BG7CR8YbK4jM3tyIBaF0zhzeBUMx36/Q/iQLOKKOT+3jOQtemRQ==", + "peer": true + }, + "keyv": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz", + "integrity": "sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==", + "dev": true, + "requires": { + "json-buffer": "3.0.0" + } + }, + "killable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", + "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==", + "dev": true + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + }, + "launch-editor": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.2.1.tgz", + "integrity": "sha512-On+V7K2uZK6wK7x691ycSUbLD/FyKKelArkbaAMSSJU8JmqmhwN2+mnJDNINuJWSrh2L0kDk+ZQtbC/gOWUwLw==", + "dev": true, + "requires": { + "chalk": "^2.3.0", + "shell-quote": "^1.6.1" + }, + "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": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "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" + } + } + } + }, + "launch-editor-middleware": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/launch-editor-middleware/-/launch-editor-middleware-2.2.1.tgz", + "integrity": "sha512-s0UO2/gEGiCgei3/2UN3SMuUj1phjQN8lcpnvgLSz26fAzNWPQ6Nf/kF5IFClnfU2ehp6LrmKdMU/beveO+2jg==", + "dev": true, + "requires": { + "launch-editor": "^2.2.1" + } + }, + "lazy-debug-legacy": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/lazy-debug-legacy/-/lazy-debug-legacy-0.0.1.tgz", + "integrity": "sha1-U3cWwHduTPeePtG2IfdljCkRsbE=", + "requires": {} + }, + "lazystream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", + "requires": { + "readable-stream": "^2.0.5" + } + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "requires": { + "invert-kv": "^1.0.0" + } + }, + "leader-line-new": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/leader-line-new/-/leader-line-new-1.1.9.tgz", + "integrity": "sha512-x56aRYaqJTA4aAS2fgbSpvWKY3IxRXDSFeGkNBmCQ3LX44B3F1HEjcBTkCiK5I3W0nPWeUTWe7dTt59VtdfFWw==" + }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "listenercount": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", + "integrity": "sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc=", + "dev": true + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + }, + "dependencies": { + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "requires": { + "error-ex": "^1.2.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + } + } + }, + "loader-runner": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", + "dev": true + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + }, + "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" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" + }, + "lodash.assign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", + "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=" + }, + "lodash.assigninwith": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.assigninwith/-/lodash.assigninwith-4.2.0.tgz", + "integrity": "sha1-rwLJhDKshtk9ppW0voAUAZcXNq8=" + }, + "lodash.camelcase": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", + "dev": true + }, + "lodash.defaultsdeep": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz", + "integrity": "sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==", + "dev": true + }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" + }, + "lodash.keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-4.2.0.tgz", + "integrity": "sha1-oIYCrBLk+4P5H8H7ejYKTZujUgU=" + }, + "lodash.mapvalues": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz", + "integrity": "sha1-G6+lAF3p3W9PJmaMMMo3IwzJaJw=", + "dev": true + }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "dev": true + }, + "lodash.rest": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/lodash.rest/-/lodash.rest-4.0.5.tgz", + "integrity": "sha1-lU73UEkmIDjJbR/Jiyj9r58Hcqo=" + }, + "lodash.template": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.2.4.tgz", + "integrity": "sha1-0FPBno50442WW/T7SV2A8Qnn96Q=", + "requires": { + "lodash._reinterpolate": "~3.0.0", + "lodash.assigninwith": "^4.0.0", + "lodash.keys": "^4.0.0", + "lodash.rest": "^4.0.0", + "lodash.templatesettings": "^4.0.0", + "lodash.tostring": "^4.0.0" + } + }, + "lodash.templatesettings": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", + "requires": { + "lodash._reinterpolate": "^3.0.0" + } + }, + "lodash.toarray": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz", + "integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE=" + }, + "lodash.topath": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/lodash.topath/-/lodash.topath-4.5.2.tgz", + "integrity": "sha1-NhY1Hzu6YZlKCTGYlmC9AyVP0Ak=" + }, + "lodash.tostring": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/lodash.tostring/-/lodash.tostring-4.1.4.tgz", + "integrity": "sha1-Vgwn0fjq3eA8LM4Zj+9cAx2CmPs=" + }, + "lodash.transform": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.transform/-/lodash.transform-4.6.0.tgz", + "integrity": "sha1-EjBkIvYzJK7YSD0/ODMrX2cFR6A=", + "dev": true + }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", + "dev": true + }, + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "requires": { + "chalk": "^2.0.1" + }, + "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": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "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" + } + } + } + }, + "loglevel": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.7.1.tgz", + "integrity": "sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw==", + "dev": true + }, + "lower-case": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", + "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=", + "dev": true + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "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" + } + }, + "magic-string": { + "version": "0.25.7", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz", + "integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==", + "dev": true, + "requires": { + "sourcemap-codec": "^1.4.4" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-stream": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.6.tgz", + "integrity": "sha1-0u9OuBGihkTHqJiZhcacL91JaCc=" + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "math-random": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", + "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==" + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "mdn-data": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", + "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", + "dev": true + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true + }, + "memfs": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.2.2.tgz", + "integrity": "sha512-RE0CwmIM3CEvpcdK3rZ19BC4E6hv9kADkMN5rPduRak58cNArWLi/9jFLsa4rhsjfVxMP3v0jO7FHXq7SvFY5Q==", + "dev": true, + "optional": true, + "requires": { + "fs-monkey": "1.0.3" + } + }, + "memory-fs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", + "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, + "merge-source-map": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", + "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", + "dev": true, + "requires": { + "source-map": "^0.6.1" + } + }, + "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==" + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "dev": true + }, + "microevent.ts": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/microevent.ts/-/microevent.ts-0.1.1.tgz", + "integrity": "sha512-jo1OfR4TaEwd5HOrt5+tAZ9mqT4jmpNAusXtyfNzqVm9uiSYFZlKM1wYL4oU7azZW/PxQW53wM0S6OR1JHNa2g==", + "dev": true + }, + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, + "mime": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", + "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", + "dev": true + }, + "mime-db": { + "version": "1.47.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.47.0.tgz", + "integrity": "sha512-QBmA/G2y+IfeS4oktet3qRZ+P5kPhCKRXxXnQEudYqUaEioAU1/Lq2us3D/t1Jfo4hE9REQPrbB7K5sOczJVIw==", + "dev": true + }, + "mime-types": { + "version": "2.1.30", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.30.tgz", + "integrity": "sha512-crmjA4bLtR8m9qLpHvgxSChT+XoSlZi8J4n/aIdn3z92e/U47Z0V/yl+Wh9W046GgFVAmoNR/fmdbZYcSSIUeg==", + "dev": true, + "requires": { + "mime-db": "1.47.0" + } + }, + "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 + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true + }, + "mini-css-extract-plugin": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz", + "integrity": "sha512-lp3GeY7ygcgAmVIcRPBVhIkf8Us7FZjA+ILpal44qLdSu11wmjKQ3d9k15lfD7pO4esu9eUIAW7qiYIBppv40A==", + "dev": true, + "requires": { + "loader-utils": "^1.1.0", + "normalize-url": "1.9.1", + "schema-utils": "^1.0.0", + "webpack-sources": "^1.1.0" + }, + "dependencies": { + "normalize-url": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", + "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", + "dev": true, + "requires": { + "object-assign": "^4.0.1", + "prepend-http": "^1.0.0", + "query-string": "^4.1.0", + "sort-keys": "^1.0.0" + } + }, + "prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "dev": true + }, + "query-string": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", + "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", + "dev": true, + "requires": { + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + } + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, + "sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", + "dev": true, + "requires": { + "is-plain-obj": "^1.0.0" + } + } + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "dev": true, + "requires": { + "minipass": "^2.9.0" + } + }, + "mississippi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "dev": true, + "requires": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^3.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + } + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + }, + "modern-normalize": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/modern-normalize/-/modern-normalize-1.1.0.tgz", + "integrity": "sha512-2lMlY1Yc1+CUy0gw4H95uNN7vjbpoED7NNRSBHE25nWfLBdmMzFCsPshlzbxHz+gYMcBEUN8V4pU16prcdPSgA==" + }, + "module": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/module/-/module-1.2.5.tgz", + "integrity": "sha1-tQPrBs3BNHP1aBhCaXTN5+xZvxU=", + "requires": { + "chalk": "1.1.3", + "concat-stream": "1.5.1", + "lodash.template": "4.2.4", + "map-stream": "0.0.6", + "tildify": "1.2.0", + "vinyl-fs": "2.4.3", + "yargs": "4.6.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + } + }, + "concat-stream": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.1.tgz", + "integrity": "sha1-87gKz54fSOOHXAaItBtsMWAu6hw=", + "requires": { + "inherits": "~2.0.1", + "readable-stream": "~2.0.0", + "typedarray": "~0.0.5" + } + }, + "process-nextick-args": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", + "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" + }, + "readable-stream": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "~1.0.0", + "process-nextick-args": "~1.0.6", + "string_decoder": "~0.10.x", + "util-deprecate": "~1.0.1" + } + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + } + }, + "y18n": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", + "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==" + }, + "yargs": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.6.0.tgz", + "integrity": "sha1-y0BQwBWb+2u2ScD0r1UFJqhGGdw=", + "requires": { + "camelcase": "^2.0.1", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "lodash.assign": "^4.0.3", + "os-locale": "^1.4.0", + "pkg-conf": "^1.1.2", + "read-pkg-up": "^1.0.1", + "require-main-filename": "^1.0.1", + "string-width": "^1.0.1", + "window-size": "^0.2.0", + "y18n": "^3.2.1", + "yargs-parser": "^2.4.0" + } + }, + "yargs-parser": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", + "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=", + "requires": { + "camelcase": "^3.0.0", + "lodash.assign": "^4.0.6" + }, + "dependencies": { + "camelcase": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=" + } + } + } + } + }, + "moment": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" + }, + "move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "dev": true, + "requires": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "multicast-dns": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", + "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", + "dev": true, + "requires": { + "dns-packet": "^1.3.1", + "thunky": "^1.0.2" + } + }, + "multicast-dns-service-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", + "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", + "dev": true + }, + "mz": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", + "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", + "dev": true, + "requires": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "nan": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", + "dev": true, + "optional": true + }, + "nanoid": { + "version": "3.1.23", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz", + "integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==" + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "needle": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.6.0.tgz", + "integrity": "sha512-KKYdza4heMsEfSWD7VPUIz3zX2XDwOyX2d+geb4vrERZMT5RMU6ujjaD+I5Yr54uZxQ2w6XRTAhHBbSCyovZBg==", + "dev": true, + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "dev": true + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "no-case": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", + "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", + "dev": true, + "requires": { + "lower-case": "^1.1.1" + } + }, + "node-emoji": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.10.0.tgz", + "integrity": "sha512-Yt3384If5H6BYGVHiHwTL+99OzJKHhgp82S8/dktEK73T26BazdgZ4JZh92xSVtGNJvz9UbXdNAc5hcrXV42vw==", + "requires": { + "lodash.toarray": "^4.4.0" + } + }, + "node-forge": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", + "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==", + "dev": true + }, + "node-ipc": { + "version": "9.1.4", + "resolved": "https://registry.npmjs.org/node-ipc/-/node-ipc-9.1.4.tgz", + "integrity": "sha512-A+f0mn2KxUt1uRTSd5ktxQUsn2OEhj5evo7NUi/powBzMSZ0vocdzDjlq9QN2v3LH6CJi3e5xAenpZ1QwU5A8g==", + "dev": true, + "requires": { + "event-pubsub": "4.3.0", + "js-message": "1.0.7", + "js-queue": "2.0.2" + } + }, + "node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "dev": true, + "requires": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "^1.0.1" + }, + "dependencies": { + "buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + } + } + }, + "node-pre-gyp": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.15.0.tgz", + "integrity": "sha512-7QcZa8/fpaU/BKenjcaeFF9hLz2+7S9AqyXFhlH/rilsQ/hPZKK32RtR5EQHJElgu+q5RfbJ34KriI79UWaorA==", + "dev": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.3", + "needle": "^2.5.0", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4.4.2" + } + }, + "node-releases": { + "version": "1.1.72", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.72.tgz", + "integrity": "sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==" + }, + "nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "dev": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + }, + "normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=" + }, + "normalize-url": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz", + "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==", + "dev": true, + "requires": { + "prepend-http": "^2.0.0", + "query-string": "^5.0.1", + "sort-keys": "^2.0.0" + } + }, + "npm-bundled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.2.tgz", + "integrity": "sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==", + "dev": true, + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-normalize-package-bin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", + "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", + "dev": true + }, + "npm-packlist": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", + "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", + "dev": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dev": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "dev": true, + "requires": { + "boolbase": "~1.0.0" + } + }, + "num2fraction": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=" + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-hash": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-2.2.0.tgz", + "integrity": "sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==" + }, + "object-inspect": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", + "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==", + "dev": true + }, + "object-is": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz", + "integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "object.getownpropertydescriptors": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz", + "integrity": "sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2" + } + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "requires": { + "for-own": "^0.1.4", + "is-extendable": "^0.1.1" + }, + "dependencies": { + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + } + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "object.values": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.3.tgz", + "integrity": "sha512-nkF6PfDB9alkOUxpf1HNm/QlkeW3SReqL5WXeBLpEJJnlPSvRaDQpW3gQTksTN3fgJX4hL42RzKyOin6ff3tyw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2", + "has": "^1.0.3" + } + }, + "obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "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" + } + }, + "open": { + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/open/-/open-6.4.0.tgz", + "integrity": "sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==", + "dev": true, + "requires": { + "is-wsl": "^1.1.0" + }, + "dependencies": { + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + } + } + }, + "opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "dev": true + }, + "opn": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", + "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", + "dev": true, + "requires": { + "is-wsl": "^1.1.0" + }, + "dependencies": { + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + } + } + }, + "ora": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-3.4.0.tgz", + "integrity": "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-spinners": "^2.0.0", + "log-symbols": "^2.2.0", + "strip-ansi": "^5.2.0", + "wcwidth": "^1.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "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" + } + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "^2.0.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": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "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" + } + } + } + }, + "ordered-read-streams": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz", + "integrity": "sha1-cTfmmzKYuzQiR6G77jiByA4v14s=", + "requires": { + "is-stream": "^1.0.1", + "readable-stream": "^2.0.1" + } + }, + "original": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", + "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", + "dev": true, + "requires": { + "url-parse": "^1.4.3" + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, + "os-locale": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "requires": { + "lcid": "^1.0.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "p-cancelable": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz", + "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==", + "dev": true + }, + "p-event": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/p-event/-/p-event-2.3.1.tgz", + "integrity": "sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA==", + "dev": true, + "requires": { + "p-timeout": "^2.0.1" + } + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-is-promise": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz", + "integrity": "sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4=", + "dev": true + }, + "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" + } + }, + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true + }, + "p-retry": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz", + "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==", + "dev": true, + "requires": { + "retry": "^0.12.0" + } + }, + "p-timeout": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz", + "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==", + "dev": true, + "requires": { + "p-finally": "^1.0.0" + } + }, + "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 + }, + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + }, + "parallel-transform": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", + "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", + "dev": true, + "requires": { + "cyclist": "^1.0.1", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + } + }, + "param-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", + "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", + "dev": true, + "requires": { + "no-case": "^2.2.0" + } + }, + "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, + "optional": true, + "requires": { + "callsites": "^3.0.0" + }, + "dependencies": { + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "optional": true + } + } + }, + "parse-asn1": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "dev": true, + "requires": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "requires": { + "glob-base": "^0.3.0", + "is-dotfile": "^1.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.0" + }, + "dependencies": { + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "requires": { + "is-extglob": "^1.0.0" + } + } + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "parse5": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", + "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==", + "dev": true + }, + "parse5-htmlparser2-tree-adapter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", + "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", + "dev": true, + "requires": { + "parse5": "^6.0.1" + }, + "dependencies": { + "parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + } + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" + }, + "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": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "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, + "optional": true + }, + "pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "picomatch": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", + "integrity": "sha512-KpELjfwcCDUb9PeigTs2mBJzXUPzAuP2oPcA989He8Rte0+YUAjw1JVedDhuTKPkHjSYzMN3npC9luThGYEKdg==" + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "requires": { + "pinkie": "^2.0.0" + } + }, + "pkg-conf": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-1.1.3.tgz", + "integrity": "sha1-N45W1v0T6Iv7b0ol33qD+qvduls=", + "requires": { + "find-up": "^1.0.0", + "load-json-file": "^1.1.0", + "object-assign": "^4.0.1", + "symbol": "^0.2.1" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "requires": { + "pinkie-promise": "^2.0.0" + } + } + } + }, + "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" + } + }, + "pnp-webpack-plugin": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz", + "integrity": "sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg==", + "dev": true, + "requires": { + "ts-pnp": "^1.1.6" + } + }, + "portfinder": { + "version": "1.0.28", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", + "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", + "dev": true, + "requires": { + "async": "^2.6.2", + "debug": "^3.1.1", + "mkdirp": "^0.5.5" + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "postcss": { + "version": "7.0.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", + "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.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==", + "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==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.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==", + "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": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-calc": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.5.tgz", + "integrity": "sha512-1tKHutbGtLtEZF6PT4JSihCHfIVldU72mZ8SdZHIYriIZ9fh9k9aWSppaT8rHsyI3dX+KSR+W+Ix9BMY3AODrg==", + "dev": true, + "requires": { + "postcss": "^7.0.27", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.0.2" + } + }, + "postcss-colormin": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz", + "integrity": "sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "color": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-convert-values": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz", + "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==", + "dev": true, + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-discard-comments": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz", + "integrity": "sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-discard-duplicates": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz", + "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-discard-empty": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz", + "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-discard-overridden": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz", + "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-functions": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-functions/-/postcss-functions-3.0.0.tgz", + "integrity": "sha1-DpTQFERwCkgd4g3k1V+yZAVkJQ4=", + "requires": { + "glob": "^7.1.2", + "object-assign": "^4.1.1", + "postcss": "^6.0.9", + "postcss-value-parser": "^3.3.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==", + "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==", + "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==", + "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": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-js": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/postcss-js/-/postcss-js-2.0.3.tgz", + "integrity": "sha512-zS59pAk3deu6dVHyrGqmC3oDXBdNdajk4k1RyxeVXCrcEDBUBHoIhE4QTsmhxgzXxsaqFDAkUZfmMa5f/N/79w==", + "requires": { + "camelcase-css": "^2.0.1", + "postcss": "^7.0.18" + } + }, + "postcss-load-config": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.2.tgz", + "integrity": "sha512-/rDeGV6vMUo3mwJZmeHfEDvwnTKKqQ0S7OHUi/kJvvtx3aWtyWG2/0ZWnzCt2keEclwN6Tf0DST2v9kITdOKYw==", + "dev": true, + "requires": { + "cosmiconfig": "^5.0.0", + "import-cwd": "^2.0.0" + } + }, + "postcss-loader": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz", + "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==", + "dev": true, + "requires": { + "loader-utils": "^1.1.0", + "postcss": "^7.0.0", + "postcss-load-config": "^2.0.0", + "schema-utils": "^1.0.0" + }, + "dependencies": { + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + } + } + }, + "postcss-merge-longhand": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz", + "integrity": "sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==", + "dev": true, + "requires": { + "css-color-names": "0.0.4", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "stylehacks": "^4.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-merge-rules": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz", + "integrity": "sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "cssnano-util-same-parent": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0", + "vendors": "^1.0.0" + }, + "dependencies": { + "postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dev": true, + "requires": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "postcss-minify-font-values": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz", + "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==", + "dev": true, + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-minify-gradients": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz", + "integrity": "sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==", + "dev": true, + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "is-color-stop": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-minify-params": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz", + "integrity": "sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==", + "dev": true, + "requires": { + "alphanum-sort": "^1.0.0", + "browserslist": "^4.0.0", + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "uniqs": "^2.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-minify-selectors": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz", + "integrity": "sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==", + "dev": true, + "requires": { + "alphanum-sort": "^1.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" + }, + "dependencies": { + "postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dev": true, + "requires": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "postcss-modules": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules/-/postcss-modules-4.0.0.tgz", + "integrity": "sha512-ghS/ovDzDqARm4Zj6L2ntadjyQMoyJmi0JkLlYtH2QFLrvNlxH5OAVRPWPeKilB0pY7SbuhO173KOWkPAxRJcw==", + "dev": true, + "requires": { + "generic-names": "^2.0.1", + "icss-replace-symbols": "^1.1.0", + "lodash.camelcase": "^4.3.0", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.0", + "postcss-modules-scope": "^3.0.0", + "postcss-modules-values": "^4.0.0", + "string-hash": "^1.1.1" + } + }, + "postcss-modules-extract-imports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "dev": true + }, + "postcss-modules-local-by-default": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz", + "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==", + "dev": true, + "requires": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-modules-scope": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", + "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", + "dev": true, + "requires": { + "postcss-selector-parser": "^6.0.4" + } + }, + "postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dev": true, + "requires": { + "icss-utils": "^5.0.0" + } + }, + "postcss-nested": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-4.2.3.tgz", + "integrity": "sha512-rOv0W1HquRCamWy2kFl3QazJMMe1ku6rCFoAAH+9AcxdbpDeBr6k968MLWuLjvjMcGEip01ak09hKOEgpK9hvw==", + "requires": { + "postcss": "^7.0.32", + "postcss-selector-parser": "^6.0.2" + } + }, + "postcss-normalize-charset": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz", + "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-normalize-display-values": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz", + "integrity": "sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==", + "dev": true, + "requires": { + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-normalize-positions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz", + "integrity": "sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==", + "dev": true, + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-normalize-repeat-style": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz", + "integrity": "sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==", + "dev": true, + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-normalize-string": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz", + "integrity": "sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==", + "dev": true, + "requires": { + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-normalize-timing-functions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz", + "integrity": "sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==", + "dev": true, + "requires": { + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-normalize-unicode": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz", + "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-normalize-url": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz", + "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==", + "dev": true, + "requires": { + "is-absolute-url": "^2.0.0", + "normalize-url": "^3.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "normalize-url": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", + "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==", + "dev": true + }, + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-normalize-whitespace": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz", + "integrity": "sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==", + "dev": true, + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-ordered-values": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz", + "integrity": "sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==", + "dev": true, + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-reduce-initial": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz", + "integrity": "sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0" + } + }, + "postcss-reduce-transforms": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz", + "integrity": "sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==", + "dev": true, + "requires": { + "cssnano-util-get-match": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-selector-parser": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz", + "integrity": "sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==", + "requires": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + } + }, + "postcss-svgo": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.3.tgz", + "integrity": "sha512-NoRbrcMWTtUghzuKSoIm6XV+sJdvZ7GZSc3wdBN0W19FTtp2ko8NqLsgoh/m9CzNhU3KLPvQmjIwtaNFkaFTvw==", + "dev": true, + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "svgo": "^1.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-unique-selectors": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz", + "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==", + "dev": true, + "requires": { + "alphanum-sort": "^1.0.0", + "postcss": "^7.0.0", + "uniqs": "^2.0.0" + } + }, + "postcss-value-parser": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", + "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==" + }, + "prepend-http": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", + "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=", + "dev": true + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=" + }, + "prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", + "dev": true, + "optional": true + }, + "pretty-error": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.2.tgz", + "integrity": "sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw==", + "dev": true, + "requires": { + "lodash": "^4.17.20", + "renderkid": "^2.0.4" + } + }, + "pretty-hrtime": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", + "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=" + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", + "dev": true + }, + "protoc-gen-grpc-web": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/protoc-gen-grpc-web/-/protoc-gen-grpc-web-1.2.1.tgz", + "integrity": "sha512-xQm+XdzNsZOxPYaM/pNvaYhA9J48zVbXbeMjADC+U14BVNadSgSenbQ7lih2xrRz+3kBYXhP2Gqqg7q/WwR9hw==", + "dev": true, + "requires": { + "download": "^8.0.0", + "fs-extra": "^9.0.1" + } + }, + "proxy-addr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "dev": true, + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" + } + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "purgecss": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/purgecss/-/purgecss-3.1.3.tgz", + "integrity": "sha512-hRSLN9mguJ2lzlIQtW4qmPS2kh6oMnA9RxdIYK8sz18QYqd6ePp4GNDl18oWHA1f2v2NEQIh51CO8s/E3YGckQ==", + "requires": { + "commander": "^6.0.0", + "glob": "^7.0.0", + "postcss": "^8.2.1", + "postcss-selector-parser": "^6.0.2" + }, + "dependencies": { + "postcss": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.0.tgz", + "integrity": "sha512-+ogXpdAjWGa+fdYY5BQ96V/6tAo+TdSSIMP5huJBIygdWwKtVoB5JWZ7yUd4xZ8r+8Kvvx4nyg/PQ071H4UtcQ==", + "requires": { + "colorette": "^1.2.2", + "nanoid": "^3.1.23", + "source-map-js": "^0.6.2" + } + } + } + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "query-string": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", + "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", + "dev": true, + "requires": { + "decode-uri-component": "^0.2.0", + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + } + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "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", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" + }, + "quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==" + }, + "randomatic": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", + "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", + "requires": { + "is-number": "^4.0.0", + "kind-of": "^6.0.0", + "math-random": "^1.0.1" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==" + } + } + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "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" + } + }, + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + } + } + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "requires": { + "picomatch": "^2.2.1" + } + }, + "reduce-css-calc": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-2.1.8.tgz", + "integrity": "sha512-8liAVezDmUcH+tdzoEGrhfbGcP7nOV4NkGE3a74+qqvE7nt9i4sKLGBuZNOnpI4WiGksiNPklZxva80061QiPg==", + "requires": { + "css-unit-converter": "^1.1.1", + "postcss-value-parser": "^3.3.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + } + } + }, + "regex-cache": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "requires": { + "is-equal-shallow": "^0.1.3" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "regexp.prototype.flags": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz", + "integrity": "sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", + "dev": true + }, + "relative-time-parser": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/relative-time-parser/-/relative-time-parser-1.0.13.tgz", + "integrity": "sha512-e8w9MUXKwfW49BvkIjkMIjPt36CBk9obucgb7Z1I9NQdRxnV3hDvuTNSUBpYC5AhM7EuV8eYrs7w2l7SJFQAIA==", + "requires": { + "moment": "^2.24.0" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" + }, + "renderkid": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.5.tgz", + "integrity": "sha512-ccqoLg+HLOHq1vdfYNm4TBeaCDIi1FLt3wGojTDSvdewUv65oTmI3cnT2E4hRjl1gzKZIPK+KZrXzlUYKnR+vQ==", + "dev": true, + "requires": { + "css-select": "^2.0.2", + "dom-converter": "^0.2", + "htmlparser2": "^3.10.1", + "lodash": "^4.17.20", + "strip-ansi": "^3.0.0" + } + }, + "repeat-element": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", + "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==" + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "replace-ext": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", + "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=" + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + } + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "dev": true, + "requires": { + "resolve-from": "^3.0.0" + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" + }, + "responselike": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", + "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=", + "dev": true, + "requires": { + "lowercase-keys": "^1.0.0" + } + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", + "dev": true + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" + }, + "rgb-regex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", + "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=", + "dev": true + }, + "rgba-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", + "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "rollup": { + "version": "2.48.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.48.0.tgz", + "integrity": "sha512-wl9ZSSSsi5579oscSDYSzGn092tCS076YB+TQrzsGuSfYyJeep8eEWj0eaRjuC5McuMNmcnR8icBqiE/FWNB1A==", + "dev": true, + "requires": { + "fsevents": "~2.3.1" + } + }, + "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==", + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "dev": true, + "requires": { + "aproba": "^1.1.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "sass": { + "version": "1.32.13", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.32.13.tgz", + "integrity": "sha512-dEgI9nShraqP7cXQH+lEXVf73WOPCse0QlFzSD8k+1TcOxCMwVXfQlr0jtoluZysQOyJGnfr21dLvYKDJq8HkA==", + "dev": true, + "requires": { + "chokidar": ">=3.0.0 <4.0.0" + } + }, + "sass-loader": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-8.0.2.tgz", + "integrity": "sha512-7o4dbSK8/Ol2KflEmSco4jTjQoV988bM82P9CZdmo9hR3RLnvNc0ufMNdMrB0caq38JQ/FgF4/7RcbcfKzxoFQ==", + "dev": true, + "requires": { + "clone-deep": "^4.0.1", + "loader-utils": "^1.2.3", + "neo-async": "^2.6.1", + "schema-utils": "^2.6.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 + } + } + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "schema-utils": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" + } + }, + "seek-bzip": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz", + "integrity": "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==", + "dev": true, + "requires": { + "commander": "^2.8.1" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + } + } + }, + "select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", + "dev": true + }, + "selfsigned": { + "version": "1.10.11", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.11.tgz", + "integrity": "sha512-aVmbPOfViZqOZPgRBT0+3u4yZFHpmnIghLMlAcb5/xhp5ZtB/RVnKhz5vl2M32CLXAqR4kha9zfhNg0Lf/sxKA==", + "dev": true, + "requires": { + "node-forge": "^0.10.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, + "serialize-javascript": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz", + "integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", + "dev": true, + "requires": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + } + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "dev": true, + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + } + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "dev": true + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "requires": { + "kind-of": "^6.0.2" + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "shell-quote": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.7.2.tgz", + "integrity": "sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==", + "dev": true + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "requires": { + "is-arrayish": "^0.3.1" + } + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "sockjs": { + "version": "0.3.21", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.21.tgz", + "integrity": "sha512-DhbPFGpxjc6Z3I+uX07Id5ZO2XwYsWOrYjaSeieES78cq+JaJvVe5q/m1uvjIQhXinhIeCFRH6JgXe+mvVMyXw==", + "dev": true, + "requires": { + "faye-websocket": "^0.11.3", + "uuid": "^3.4.0", + "websocket-driver": "^0.7.4" + }, + "dependencies": { + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + } + } + }, + "sockjs-client": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.5.1.tgz", + "integrity": "sha512-VnVAb663fosipI/m6pqRXakEOw7nvd7TUgdr3PlR/8V2I95QIdwT8L4nMxhyU8SmDBHYXU1TOElaKOmKLfYzeQ==", + "dev": true, + "requires": { + "debug": "^3.2.6", + "eventsource": "^1.0.7", + "faye-websocket": "^0.11.3", + "inherits": "^2.0.4", + "json3": "^3.3.3", + "url-parse": "^1.5.1" + } + }, + "sort-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", + "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=", + "dev": true, + "requires": { + "is-plain-obj": "^1.0.0" + } + }, + "sort-keys-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz", + "integrity": "sha1-nLb09OnkgVWmqgZx7dM2/xR5oYg=", + "dev": true, + "requires": { + "sort-keys": "^1.0.0" + }, + "dependencies": { + "sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", + "dev": true, + "requires": { + "is-plain-obj": "^1.0.0" + } + } + } + }, + "source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "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==" + }, + "source-map-js": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz", + "integrity": "sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==" + }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "source-map-url": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", + "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==" + }, + "sourcemap-codec": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz", + "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", + "dev": true + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==" + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.8.tgz", + "integrity": "sha512-NDgA96EnaLSvtbM7trJj+t1LUR3pirkDCcz9nOUlPb5DMBGsH7oES6C3hs3j7R9oHEa1EMvReS/BUAIT5Tcr0g==" + }, + "spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dev": true, + "requires": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "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 + } + } + }, + "spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dev": true, + "requires": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "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 + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "ssri": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", + "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", + "dev": true, + "requires": { + "minipass": "^3.1.1" + }, + "dependencies": { + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "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 + } + } + }, + "stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "dev": true + }, + "stackframe": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.2.0.tgz", + "integrity": "sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA==", + "dev": true + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-each": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", + "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" + }, + "strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "string-hash": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/string-hash/-/string-hash-1.1.3.tgz", + "integrity": "sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs=", + "dev": true + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "requires": { + "is-utf8": "^0.2.0" + } + }, + "strip-bom-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-stream/-/strip-bom-stream-1.0.0.tgz", + "integrity": "sha1-5xRDmFd9Uaa+0PoZlPoF9D/ZiO4=", + "requires": { + "first-chunk-stream": "^1.0.0", + "strip-bom": "^2.0.0" + } + }, + "strip-dirs": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", + "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", + "dev": true, + "requires": { + "is-natural-number": "^4.0.1" + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "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-indent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", + "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "strip-outer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", + "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.2" + } + }, + "stylehacks": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz", + "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" + }, + "dependencies": { + "postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dev": true, + "requires": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "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==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "svgo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", + "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "coa": "^2.0.2", + "css-select": "^2.0.0", + "css-select-base-adapter": "^0.1.1", + "css-tree": "1.0.0-alpha.37", + "csso": "^4.0.2", + "js-yaml": "^3.13.1", + "mkdirp": "~0.5.1", + "object.values": "^1.1.0", + "sax": "~1.2.4", + "stable": "^0.1.8", + "unquote": "~1.1.1", + "util.promisify": "~1.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": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "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" + } + } + } + }, + "symbol": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/symbol/-/symbol-0.2.3.tgz", + "integrity": "sha1-O5hzuKkB5Hxu/iFSajrDcu8ou8c=" + }, + "tailwindcss": { + "version": "npm:@tailwindcss/postcss7-compat@2.1.3", + "resolved": "https://registry.npmjs.org/@tailwindcss/postcss7-compat/-/postcss7-compat-2.1.3.tgz", + "integrity": "sha512-SuuCv7XkB2WIdTsiRLCX8eTF6s2r7E+0aIg+ASYZE/5YAJlojYWDENth+ywRJpWXW1ZoQKo0g/8xsMKijzPm8g==", + "requires": { + "@fullhuman/postcss-purgecss": "^3.1.3", + "autoprefixer": "^9", + "bytes": "^3.0.0", + "chalk": "^4.1.0", + "chokidar": "^3.5.1", + "color": "^3.1.3", + "detective": "^5.2.0", + "didyoumean": "^1.2.1", + "dlv": "^1.1.3", + "fast-glob": "^3.2.5", + "fs-extra": "^9.1.0", + "html-tags": "^3.1.0", + "lodash": "^4.17.21", + "lodash.topath": "^4.5.2", + "modern-normalize": "^1.0.0", + "node-emoji": "^1.8.1", + "normalize-path": "^3.0.0", + "object-hash": "^2.1.1", + "parse-glob": "^3.0.4", + "postcss": "^7", + "postcss-functions": "^3", + "postcss-js": "^2", + "postcss-nested": "^4", + "postcss-selector-parser": "^6.0.4", + "postcss-value-parser": "^4.1.0", + "pretty-hrtime": "^1.0.3", + "quick-lru": "^5.1.1", + "reduce-css-calc": "^2.1.8", + "resolve": "^1.20.0" + } + }, + "tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "dev": true + }, + "tar": { + "version": "4.4.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", + "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", + "dev": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + } + }, + "tar-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", + "dev": true, + "requires": { + "bl": "^1.0.0", + "buffer-alloc": "^1.2.0", + "end-of-stream": "^1.0.0", + "fs-constants": "^1.0.0", + "readable-stream": "^2.3.0", + "to-buffer": "^1.1.1", + "xtend": "^4.0.0" + } + }, + "terser": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz", + "integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + } + } + }, + "terser-webpack-plugin": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz", + "integrity": "sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw==", + "dev": true, + "requires": { + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", + "is-wsl": "^1.1.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^4.0.0", + "source-map": "^0.6.1", + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", + "worker-farm": "^1.7.0" + }, + "dependencies": { + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + } + } + }, + "thenify": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", + "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", + "dev": true, + "requires": { + "any-promise": "^1.0.0" + } + }, + "thenify-all": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", + "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=", + "dev": true, + "requires": { + "thenify": ">= 3.1.0 < 4" + } + }, + "thread-loader": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/thread-loader/-/thread-loader-2.1.3.tgz", + "integrity": "sha512-wNrVKH2Lcf8ZrWxDF/khdlLlsTMczdcwPA9VEK4c2exlEPynYWxi9op3nPTo5lAnDIkE0rQEB3VBP+4Zncc9Hg==", + "dev": true, + "requires": { + "loader-runner": "^2.3.1", + "loader-utils": "^1.1.0", + "neo-async": "^2.6.0" + } + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "through2-filter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-2.0.0.tgz", + "integrity": "sha1-YLxVoNrLdghdsfna6Zq0P4PWIuw=", + "requires": { + "through2": "~2.0.0", + "xtend": "~4.0.0" + } + }, + "thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true + }, + "tildify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tildify/-/tildify-1.2.0.tgz", + "integrity": "sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo=", + "requires": { + "os-homedir": "^1.0.0" + } + }, + "timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", + "dev": true + }, + "timers-browserify": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", + "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", + "dev": true, + "requires": { + "setimmediate": "^1.0.4" + } + }, + "timsort": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", + "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=" + }, + "to-absolute-glob": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-0.1.1.tgz", + "integrity": "sha1-HN+kcqnvUMI57maZm2YsoOs5k38=", + "requires": { + "extend-shallow": "^2.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + } + } + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "to-buffer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", + "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": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "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==", + "requires": { + "is-number": "^7.0.0" + } + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "dev": true + }, + "toposort": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.7.tgz", + "integrity": "sha1-LmhELZ9k7HILjMieZEOsbKqVACk=", + "dev": true + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "traverse": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", + "integrity": "sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=", + "dev": true + }, + "trim-repeated": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", + "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.2" + } + }, + "tryer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", + "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==", + "dev": true + }, + "ts-loader": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-6.2.2.tgz", + "integrity": "sha512-HDo5kXZCBml3EUPcc7RlZOV/JGlLHwppTLEHb3SHnr5V7NXD4klMEkrhJe5wgRbaWsSXi+Y1SIBN/K9B6zWGWQ==", + "dev": true, + "requires": { + "chalk": "^2.3.0", + "enhanced-resolve": "^4.0.0", + "loader-utils": "^1.0.2", + "micromatch": "^4.0.0", + "semver": "^6.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": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "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 + }, + "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" + } + } + } + }, + "ts-pnp": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ts-pnp/-/ts-pnp-1.2.0.tgz", + "integrity": "sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==", + "dev": true + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "tslint": { + "version": "5.20.1", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.20.1.tgz", + "integrity": "sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^4.0.1", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.8.0", + "tsutils": "^2.29.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": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "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" + } + }, + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + } + } + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, + "typescript": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", + "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==", + "dev": true + }, + "uglify-js": { + "version": "3.13.7", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.7.tgz", + "integrity": "sha512-1Psi2MmnZJbnEsgJJIlfnd7tFlJfitusmR7zDI8lXlFI0ACD4/Rm/xdrU8bh6zF0i74aiVoBtkRiFulkrmh3AA==", + "dev": true, + "optional": true + }, + "unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + } + }, + "unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "dev": true, + "requires": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + } + } + }, + "uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", + "dev": true + }, + "uniqs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", + "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=", + "dev": true + }, + "unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dev": true, + "requires": { + "unique-slug": "^2.0.0" + } + }, + "unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "unique-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", + "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", + "requires": { + "json-stable-stringify-without-jsonify": "^1.0.1", + "through2-filter": "^3.0.0" + }, + "dependencies": { + "through2-filter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", + "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", + "requires": { + "through2": "~2.0.0", + "xtend": "~4.0.0" + } + } + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, + "unquote": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", + "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=", + "dev": true + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, + "unzipper": { + "version": "0.10.11", + "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.11.tgz", + "integrity": "sha512-+BrAq2oFqWod5IESRjL3S8baohbevGcVA+teAIOYWM3pDVdseogqbzhhvvmiyQrUNKFUnDMtELW3X8ykbyDCJw==", + "dev": true, + "requires": { + "big-integer": "^1.6.17", + "binary": "~0.3.0", + "bluebird": "~3.4.1", + "buffer-indexof-polyfill": "~1.0.0", + "duplexer2": "~0.1.4", + "fstream": "^1.0.12", + "graceful-fs": "^4.2.2", + "listenercount": "~1.0.1", + "readable-stream": "~2.3.6", + "setimmediate": "~1.0.4" + }, + "dependencies": { + "bluebird": { + "version": "3.4.7", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", + "integrity": "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM=", + "dev": true + } + } + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true + }, + "upper-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", + "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=", + "dev": true + }, + "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" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, + "url-loader": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-2.3.0.tgz", + "integrity": "sha512-goSdg8VY+7nPZKUEChZSEtW5gjbS66USIGCeSJ1OVOJ7Yfuh/36YxCwMi5HVEJh6mqUYOoy3NJ0vlOMrWsSHog==", + "dev": true, + "requires": { + "loader-utils": "^1.2.3", + "mime": "^2.4.4", + "schema-utils": "^2.5.0" + } + }, + "url-parse": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.1.tgz", + "integrity": "sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==", + "dev": true, + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "url-parse-lax": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", + "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=", + "dev": true, + "requires": { + "prepend-http": "^2.0.0" + } + }, + "url-to-options": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", + "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=", + "dev": true + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "dev": true, + "requires": { + "inherits": "2.0.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "util.promisify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", + "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "object.getownpropertydescriptors": "^2.0.3" + } + }, + "utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=", + "dev": true + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "peer": true + }, + "vali-date": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/vali-date/-/vali-date-1.0.0.tgz", + "integrity": "sha1-G5BKWWCfsyjvB4E4Qgk09rhnCaY=" + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true + }, + "vendors": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz", + "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==", + "dev": true + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "vinyl": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", + "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", + "requires": { + "clone": "^1.0.0", + "clone-stats": "^0.0.1", + "replace-ext": "0.0.1" + } + }, + "vinyl-fs": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-2.4.3.tgz", + "integrity": "sha1-PZflYuv91LZpId6nBia4S96dLQc=", + "requires": { + "duplexify": "^3.2.0", + "glob-stream": "^5.3.2", + "graceful-fs": "^4.0.0", + "gulp-sourcemaps": "^1.5.2", + "is-valid-glob": "^0.3.0", + "lazystream": "^1.0.0", + "lodash.isequal": "^4.0.0", + "merge-stream": "^1.0.0", + "mkdirp": "^0.5.0", + "object-assign": "^4.0.0", + "readable-stream": "^2.0.4", + "strip-bom": "^2.0.0", + "strip-bom-stream": "^1.0.0", + "through2": "^2.0.0", + "through2-filter": "^2.0.0", + "vali-date": "^1.0.0", + "vinyl": "^1.0.0" + }, + "dependencies": { + "merge-stream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", + "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", + "requires": { + "readable-stream": "^2.0.1" + } + } + } + }, + "vis-data": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/vis-data/-/vis-data-7.1.2.tgz", + "integrity": "sha512-RPSegFxEcnp3HUEJSzhS2vBdbJ2PSsrYYuhRlpHp2frO/MfRtTYbIkkLZmPkA/Sg3pPfBlR235gcoKbtdm4mbw==", + "peer": true, + "requires": {} + }, + "vis-network": { + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/vis-network/-/vis-network-9.0.4.tgz", + "integrity": "sha512-F/pq8yBJUuB9lNKXHhtn4GP2h91FV0c2O2nvfU34RX4VCYOlqs+mINdz+J+QkWiYhiPdlVy15gzVEzkhJ9hpaw==", + "requires": {} + }, + "vis-util": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/vis-util/-/vis-util-5.0.2.tgz", + "integrity": "sha512-oPDmPc4o0uQLoKpKai2XD1DjrhYsA7MRz75Wx9KmfX84e9LLgsbno7jVL5tR0K9eNVQkD6jf0Ei8NtbBHDkF1A==", + "peer": true, + "requires": {} + }, + "vite": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-2.3.3.tgz", + "integrity": "sha512-eO1iwRbn3/BfkNVMNJDeANAFCZ5NobYOFPu7IqfY7DcI7I9nFGjJIZid0EViTmLDGwwSUPmRAq3cRBbO3+DsMA==", + "dev": true, + "requires": { + "esbuild": "^0.11.23", + "fsevents": "~2.3.1", + "postcss": "^8.2.10", + "resolve": "^1.19.0", + "rollup": "^2.38.5" + }, + "dependencies": { + "postcss": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.0.tgz", + "integrity": "sha512-+ogXpdAjWGa+fdYY5BQ96V/6tAo+TdSSIMP5huJBIygdWwKtVoB5JWZ7yUd4xZ8r+8Kvvx4nyg/PQ071H4UtcQ==", + "dev": true, + "requires": { + "colorette": "^1.2.2", + "nanoid": "^3.1.23", + "source-map-js": "^0.6.2" + } + } + } + }, + "vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true + }, + "vue": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.0.11.tgz", + "integrity": "sha512-3/eUi4InQz8MPzruHYSTQPxtM3LdZ1/S/BvaU021zBnZi0laRUyH6pfuE4wtUeLvI8wmUNwj5wrZFvbHUXL9dw==", + "requires": { + "@vue/compiler-dom": "3.0.11", + "@vue/runtime-dom": "3.0.11", + "@vue/shared": "3.0.11" + } + }, + "vue-class-component": { + "version": "8.0.0-rc.1", + "resolved": "https://registry.npmjs.org/vue-class-component/-/vue-class-component-8.0.0-rc.1.tgz", + "integrity": "sha512-w1nMzsT/UdbDAXKqhwTmSoyuJzUXKrxLE77PCFVuC6syr8acdFDAq116xgvZh9UCuV0h+rlCtxXolr3Hi3HyPQ==" + }, + "vue-cli-plugin-tailwind": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/vue-cli-plugin-tailwind/-/vue-cli-plugin-tailwind-2.0.6.tgz", + "integrity": "sha512-HgR3gSmlnypNU+hlqoiRBJsnShXSoig4XTFNZiPlyVZBtkDZdfD884wTxz+GDJHzWLPtv4wnAyuO95UCsPbyoQ==", + "dev": true + }, + "vue-eslint-parser": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.6.0.tgz", + "integrity": "sha512-QXxqH8ZevBrtiZMZK0LpwaMfevQi9UL7lY6Kcp+ogWHC88AuwUPwwCIzkOUc1LR4XsYAt/F9yHXAB/QoD17QXA==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "eslint-scope": "^5.0.0", + "eslint-visitor-keys": "^1.1.0", + "espree": "^6.2.1", + "esquery": "^1.4.0", + "lodash": "^4.17.15" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + }, + "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 + } + } + }, + "vue-hot-reload-api": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz", + "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==", + "dev": true + }, + "vue-loader": { + "version": "15.9.7", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.7.tgz", + "integrity": "sha512-qzlsbLV1HKEMf19IqCJqdNvFJRCI58WNbS6XbPqK13MrLz65es75w392MSQ5TsARAfIjUw+ATm3vlCXUJSOH9Q==", + "dev": true, + "requires": { + "@vue/component-compiler-utils": "^3.1.0", + "hash-sum": "^1.0.2", + "loader-utils": "^1.1.0", + "vue-hot-reload-api": "^2.3.0", + "vue-style-loader": "^4.1.0" + }, + "dependencies": { + "hash-sum": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", + "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=", + "dev": true + } + } + }, + "vue-loader-v16": { + "version": "npm:vue-loader@16.2.0", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-16.2.0.tgz", + "integrity": "sha512-TitGhqSQ61RJljMmhIGvfWzJ2zk9m1Qug049Ugml6QP3t0e95o0XJjk29roNEiPKJQBEi8Ord5hFuSuELzSp8Q==", + "dev": true, + "optional": true, + "requires": { + "chalk": "^4.1.0", + "hash-sum": "^2.0.0", + "loader-utils": "^2.0.0" + }, + "dependencies": { + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "optional": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "optional": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + } + } + }, + "vue-router": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.0.8.tgz", + "integrity": "sha512-42mWSQaH7CCBQDspQTHv63f34VEnZC20g9QNK4WJ/zW8SdIUeT6TQ2i/78fjF/pVBUPLBWrGhvB7uDnaz7O/pA==", + "requires": { + "@vue/devtools-api": "^6.0.0-beta.10" + } + }, + "vue-style-loader": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.3.tgz", + "integrity": "sha512-sFuh0xfbtpRlKfm39ss/ikqs9AbKCoXZBpHeVZ8Tx650o0k0q/YCM7FRvigtxpACezfq6af+a7JeqVTWvncqDg==", + "dev": true, + "requires": { + "hash-sum": "^1.0.2", + "loader-utils": "^1.0.2" + }, + "dependencies": { + "hash-sum": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", + "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=", + "dev": true + } + } + }, + "vue-template-es2015-compiler": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz", + "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==", + "dev": true + }, + "vue-tsc": { + "version": "0.0.24", + "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-0.0.24.tgz", + "integrity": "sha512-Qx0V7jkWMtvddtaWa1SA8YKkBCRmjq9zZUB2UIMZiso6JSH538oHD2VumSzkoDnAfFbY3t0/j1mB2abpA0bGWA==", + "dev": true, + "requires": { + "unzipper": "0.10.11" + } + }, + "watchpack": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz", + "integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==", + "dev": true, + "requires": { + "chokidar": "^3.4.1", + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0", + "watchpack-chokidar2": "^2.0.1" + } + }, + "watchpack-chokidar2": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz", + "integrity": "sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww==", + "dev": true, + "optional": true, + "requires": { + "chokidar": "^2.1.8" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "optional": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "optional": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true, + "optional": true + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "optional": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "optional": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "dev": true, + "optional": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "optional": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "optional": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "dev": true, + "optional": true, + "requires": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "optional": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "optional": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "optional": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "optional": true + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "optional": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "optional": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "optional": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "optional": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "optional": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dev": true, + "requires": { + "minimalistic-assert": "^1.0.0" + } + }, + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dev": true, + "requires": { + "defaults": "^1.0.3" + } + }, + "webpack": { + "version": "4.46.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.46.0.tgz", + "integrity": "sha512-6jJuJjg8znb/xRItk7bkT0+Q7AHCYjjFnvKIWQPkNIOyRqoCGvkOs0ipeQzrqz4l5FtN5ZI/ukEHroeX/o1/5Q==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/wasm-edit": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "acorn": "^6.4.1", + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^4.5.0", + "eslint-scope": "^4.0.3", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^2.4.0", + "loader-utils": "^1.2.3", + "memory-fs": "^0.4.1", + "micromatch": "^3.1.10", + "mkdirp": "^0.5.3", + "neo-async": "^2.6.1", + "node-libs-browser": "^2.2.1", + "schema-utils": "^1.0.0", + "tapable": "^1.1.3", + "terser-webpack-plugin": "^1.4.3", + "watchpack": "^1.7.4", + "webpack-sources": "^1.4.1" + }, + "dependencies": { + "acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", + "dev": true + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + } + } + }, + "webpack-bundle-analyzer": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.9.0.tgz", + "integrity": "sha512-Ob8amZfCm3rMB1ScjQVlbYYUEJyEjdEtQ92jqiFUYt5VkEeO2v5UMbv49P/gnmCZm3A6yaFQzCBvpZqN4MUsdA==", + "dev": true, + "requires": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1", + "bfj": "^6.1.1", + "chalk": "^2.4.1", + "commander": "^2.18.0", + "ejs": "^2.6.1", + "express": "^4.16.3", + "filesize": "^3.6.1", + "gzip-size": "^5.0.0", + "lodash": "^4.17.19", + "mkdirp": "^0.5.1", + "opener": "^1.5.1", + "ws": "^6.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": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "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" + } + } + } + }, + "webpack-chain": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/webpack-chain/-/webpack-chain-6.5.1.tgz", + "integrity": "sha512-7doO/SRtLu8q5WM0s7vPKPWX580qhi0/yBHkOxNkv50f6qB76Zy9o2wRTrrPULqYTvQlVHuvbA8v+G5ayuUDsA==", + "dev": true, + "requires": { + "deepmerge": "^1.5.2", + "javascript-stringify": "^2.0.1" + }, + "dependencies": { + "deepmerge": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-1.5.2.tgz", + "integrity": "sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ==", + "dev": true + } + } + }, + "webpack-dev-middleware": { + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz", + "integrity": "sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ==", + "dev": true, + "requires": { + "memory-fs": "^0.4.1", + "mime": "^2.4.4", + "mkdirp": "^0.5.1", + "range-parser": "^1.2.1", + "webpack-log": "^2.0.0" + }, + "dependencies": { + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + } + } + }, + "webpack-dev-server": { + "version": "3.11.2", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.2.tgz", + "integrity": "sha512-A80BkuHRQfCiNtGBS1EMf2ChTUs0x+B3wGDFmOeT4rmJOHhHTCH2naNxIHhmkr0/UillP4U3yeIyv1pNp+QDLQ==", + "dev": true, + "requires": { + "ansi-html": "0.0.7", + "bonjour": "^3.5.0", + "chokidar": "^2.1.8", + "compression": "^1.7.4", + "connect-history-api-fallback": "^1.6.0", + "debug": "^4.1.1", + "del": "^4.1.1", + "express": "^4.17.1", + "html-entities": "^1.3.1", + "http-proxy-middleware": "0.19.1", + "import-local": "^2.0.0", + "internal-ip": "^4.3.0", + "ip": "^1.1.5", + "is-absolute-url": "^3.0.3", + "killable": "^1.0.1", + "loglevel": "^1.6.8", + "opn": "^5.5.0", + "p-retry": "^3.0.1", + "portfinder": "^1.0.26", + "schema-utils": "^1.0.0", + "selfsigned": "^1.10.8", + "semver": "^6.3.0", + "serve-index": "^1.9.1", + "sockjs": "^0.3.21", + "sockjs-client": "^1.5.0", + "spdy": "^4.0.2", + "strip-ansi": "^3.0.1", + "supports-color": "^6.1.0", + "url": "^0.11.0", + "webpack-dev-middleware": "^3.7.2", + "webpack-log": "^2.0.0", + "ws": "^6.2.1", + "yargs": "^13.3.2" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "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" + } + }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.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": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "dev": true, + "optional": true, + "requires": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "http-proxy-middleware": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", + "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", + "dev": true, + "requires": { + "http-proxy": "^1.17.0", + "is-glob": "^4.0.0", + "lodash": "^4.17.11", + "micromatch": "^3.1.10" + } + }, + "is-absolute-url": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", + "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "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 + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "dependencies": { + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "webpack-log": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", + "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", + "dev": true, + "requires": { + "ansi-colors": "^3.0.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + } + } + }, + "webpack-merge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", + "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", + "dev": true, + "requires": { + "lodash": "^4.17.15" + } + }, + "webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dev": true, + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } + }, + "websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "requires": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + } + }, + "websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "window-size": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", + "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=" + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "worker-farm": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", + "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", + "dev": true, + "requires": { + "errno": "~0.1.7" + } + }, + "worker-rpc": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/worker-rpc/-/worker-rpc-0.1.1.tgz", + "integrity": "sha512-P1WjMrUB3qgJNI9jfmpZ/htmBEjFh//6l/5y8SD9hg1Ef5zTTVVoRjTrTEzPrNBQvmhMxkoTsjOXN10GWU7aCg==", + "dev": true, + "requires": { + "microevent.ts": "~0.1.1" + } + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "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 + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, + "y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "optional": true + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "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 + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "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" + } + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + } + } + }, + "yargs-parser": { + "version": "20.2.7", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.7.tgz", + "integrity": "sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==", + "dev": true + }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "yorkie": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yorkie/-/yorkie-2.0.0.tgz", + "integrity": "sha512-jcKpkthap6x63MB4TxwCyuIGkV0oYP/YRyuQU5UO0Yz/E/ZAu+653/uov+phdmO54n6BcvFRyyt0RRrWdN2mpw==", + "dev": true, + "requires": { + "execa": "^0.8.0", + "is-ci": "^1.0.10", + "normalize-path": "^1.0.0", + "strip-indent": "^2.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.8.0.tgz", + "integrity": "sha1-2NdrvBtVIX7RkP1t1J08d07PyNo=", + "dev": true, + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "normalize-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-1.0.0.tgz", + "integrity": "sha1-MtDkcvkf80VwHBWoMRAY07CpA3k=", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + } + } + } + } +} diff --git a/monitoring/monitoring_ui/package.json b/monitoring/monitoring_ui/package.json new file mode 100644 index 0000000000000000000000000000000000000000..647d5e99762efd7740fc42180a46102a136d7130 --- /dev/null +++ b/monitoring/monitoring_ui/package.json @@ -0,0 +1,43 @@ +{ + "name": "asapo-monitoring", + "version": "0.0.0", + "scripts": { + "build": "vue-cli-service build", + "lint": "vue-cli-service lint", + "dev": "vue-cli-service serve" + }, + "dependencies": { + "@grpc/grpc-js": "^1.3.2", + "@tailwindcss/postcss7-compat": "^2.0.2", + "autoprefixer": "^9", + "grpc-web": "^1.2.1", + "jquery": "^3.6.0", + "leader-line-new": "^1.1.9", + "module": "^1.2.5", + "moment": "^2.29.1", + "postcss": "^7", + "relative-time-parser": "^1.0.13", + "tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.0.2", + "vis-network": "^9.0.4", + "vue": "^3.0.5", + "vue-class-component": "^8.0.0-0", + "vue-router": "^4.0.0-0" + }, + "devDependencies": { + "@types/jquery": "^3.5.5", + "@vue/cli-plugin-router": "~4.5.0", + "@vue/cli-plugin-typescript": "~4.5.0", + "@vue/cli-service": "~4.5.0", + "@vue/compiler-sfc": "^3.0.0", + "@vue/eslint-config-typescript": "^7.0.0", + "grpc_tools_node_protoc_ts": "^5.2.2", + "grpc-tools": "^1.11.1", + "protoc-gen-grpc-web": "^1.2.1", + "sass": "^1.26.5", + "sass-loader": "^8.0.2", + "typescript": "^4.1.3", + "vite": "^2.3.3", + "vue-cli-plugin-tailwind": "~2.0.6", + "vue-tsc": "^0.0.24" + } +} diff --git a/monitoring/monitoring_ui/postcss.config.js b/monitoring/monitoring_ui/postcss.config.js new file mode 100644 index 0000000000000000000000000000000000000000..85f717cc09ecb1153d6a4c0962284e09e4b8d6a9 --- /dev/null +++ b/monitoring/monitoring_ui/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {} + } +} diff --git a/monitoring/monitoring_ui/public/favicon.ico b/monitoring/monitoring_ui/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..df36fcfb72584e00488330b560ebcf34a41c64c2 Binary files /dev/null and b/monitoring/monitoring_ui/public/favicon.ico differ diff --git a/monitoring/monitoring_ui/src/3dparty/flot.d.ts b/monitoring/monitoring_ui/src/3dparty/flot.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..cd38bda09a8e9aea410e94778c43220f28db1d99 --- /dev/null +++ b/monitoring/monitoring_ui/src/3dparty/flot.d.ts @@ -0,0 +1,255 @@ +// Type definitions for Flot +// Project: http://www.flotcharts.org/ +// Definitions by: Matt Burland <https://github.com/burlandm> +// Timo Mühlbach <https://github.com/Anticom> +// Ariel Kuechler <https://github.com/admiralsmaster> +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +// TypeScript Version: 2.3 + + +/// <reference types="jquery" /> + +declare module jquery.flot { + interface plotOptions { + colors?: any[]; + series?: seriesOptions; + legend?: legendOptions; + xaxis?: axisOptions; + yaxis?: axisOptions; + xaxes?: axisOptions[]; + yaxes?: axisOptions[]; + grid?: gridOptions; + interaction?: interaction; + hooks?: hooks; + selection?: any; + crosshair?: any; + } + + interface hooks { + processOptions?: { (plot: plot, options: plotOptions): void; } []; + processRawData?: { (plot: plot, series: dataSeries, data: any[], datapoints: datapoints): void; }[]; + processDatapoints?: { (plot: plot, series: dataSeries, datapoints: datapoints): void; }[]; + processOffset?: { (plot: plot, offset: canvasPoint): void; }[]; + drawBackground?: { (plot: plot, context: CanvasRenderingContext2D): void; }[]; + drawSeries?: { (plot: plot, context: CanvasRenderingContext2D, series: dataSeries): void; }[]; + draw?: { (plot: plot, context: CanvasRenderingContext2D): void; }[]; + bindEvents?: { (plot: plot, eventHolder: JQuery): void; }[]; + drawOverlay?: { (plot: plot, context: CanvasRenderingContext2D): void; }[]; + shutdown?: { (plot: plot, eventHolder: JQuery): void; }[]; + } + + interface interaction { + redrawOverlayInterval?: number; + } + + interface gridOptions { + show?: boolean; + aboveData?: boolean; + color?: any; // color + backgroundColor?: any; //color/gradient or null + margin?: any; // number or margin object + labelMargin?: number; + axisMargin?: number; + markings?: any; //array of markings or (fn: axes -> array of markings) + borderWidth?: any; // number or width object + borderColor?: any; // color or null + minBorderMargin?: number; // or null + clickable?: boolean; + hoverable?: boolean; + autoHighlight?: boolean; + mouseActiveRadius?: number; + tickColor?: any; + markingsColor?: any; + markingsLineWidth?: number; + } + + interface legendOptions { + show?: boolean; + labelFormatter?: (label: string, series: any) => string; // null or (fn: string, series object -> string) + labelBoxBorderColor?: any; //color + noColumns?: number; + position?: string; //"ne" or "nw" or "se" or "sw" + margin?: any; //number of pixels or [x margin, y margin] + backgroundColor?: any; //null or color + backgroundOpacity?: number; // between 0 and 1 + container?: JQuery; // null or jQuery object/DOM element/jQuery expression + sorted?: any; //null/false, true, "ascending", "descending" or a comparator + } + + interface seriesOptions { + stack?: boolean; + color?: any; // color or number + label?: string; + lines?: linesOptions; + bars?: barsOptions; + points?: pointsOptions; + xaxis?: number; + yaxis?: number; + clickable?: boolean; + hoverable?: boolean; + shadowSize?: number; + highlightColor?: any; + } + + interface dataSeries extends seriesOptions { + data: any[]; + } + + interface axisOptions { + show?: boolean; // null or true/false + position?: string; // "bottom" or "top" or "left" or "right" + mode?: string; // "time" + monthNames?: string[]; // array of month names + + color?: any; // null or color spec + tickColor?: any; // null or color spec + font?: any; // null or font spec object + + min?: number; + max?: number; + autoscaleMargin?: number; + + transform?: (v: number) => number; // null or fn: number -> number + inverseTransform?: (v: number) => number; // null or fn: number -> number + + ticks?: any; // null or number or ticks array or (fn: axis -> ticks array) + tickSize?: any; // number or array + minTickSize?: any; // number or array + tickFormatter?: (t: number, a?: axis) => string; // (fn: number, object -> string) or string + tickDecimals?: number; + + labelWidth?: number; + labelHeight?: number; + reserveSpace?: boolean; + + tickLength?: number; + + alignTicksWithAxis?: number; + + timezone?: string; // "browser" or timezone (only makes sense for mode: "time") + timeformat?: string; // null or format string + twelveHourClock?: boolean; + } + + interface seriesTypeBase { + show?: boolean; + lineWidth?: number; + fill?: any; //boolean or number + fillColor?: any; //null or color/gradient + } + + interface linesOptions extends seriesTypeBase { + steps?: boolean; + } + + interface barsOptions extends seriesTypeBase { + barWidth?: number; + align?: string; + horizontal?: boolean; + } + + interface pointsOptions extends seriesTypeBase { + radius?: number; + symbol?: any; + } + + interface gradient { + colors: any[]; + } + + interface item { + datapoint: number[]; // the point, e.g. [0, 2] + dataIndex: number; // the index of the point in the data array + series: dataSeries; //the series object + seriesIndex: number; //the index of the series + pageX: number; + pageY: number; //the global screen coordinates of the point + } + + interface datapoints { + points: number[]; + pointsize: number; + format: datapointFormat[]; + } + + interface datapointFormat { + x?: boolean; + y?: boolean; + number: boolean; + required: boolean; + defaultValue?: number; + } + + interface point { + x: number; + y: number; + } + + interface offset { + left: number; + top: number; + } + + interface canvasPoint { + top: number; + left: number; + bottom?: number; + right?: number; + } + + interface axes { + xaxis: axis; + yaxis: axis; + x2axis?: axis; + y2axis?: axis; + } + + interface axis extends axisOptions { + options: axisOptions; + p2c(point: point):canvasPoint; + c2p(canvasPoint: canvasPoint):point; + } + + interface plugin { + init(options: plotOptions): any; + options?: any; + name?: string; + version?: string; + } + + interface plot { + highlight(series: dataSeries, datapoint: item): void; + unhighlight(): void; + unhighlight(series: dataSeries, datapoint: item): void; + setData(data: any): void; + setupGrid(): void; + draw(): void; + triggerRedrawOverlay(): void; + width(): number; + height(): number; + offset(): JQueryCoordinates; + pointOffset(point: point): offset; + resize(): void; + shutdown(): void; + getData(): dataSeries[]; + getAxes(): axes; + getXAxes(): axis[]; + getYAxes(): axis[]; + getPlaceholder(): JQuery; + getCanvas(): HTMLCanvasElement; + getPlotOffset(): canvasPoint; + getOptions(): plotOptions; + setSelection(data: any, preventEvent?: boolean): any; + clearSelection(): void; + } + + interface plotStatic { + (placeholder: JQuery, data: dataSeries[], options?: plotOptions): plot; + (placeholder: JQuery, data: any[], options?: plotOptions): plot; + plugins: plugin[]; + } +} + +interface JQueryStatic { + plot: jquery.flot.plotStatic; +} diff --git a/monitoring/monitoring_ui/src/3dparty/flot/.gitignore b/monitoring/monitoring_ui/src/3dparty/flot/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..477d588c16c6f2913cfc5d9063db1db5e74d4a60 --- /dev/null +++ b/monitoring/monitoring_ui/src/3dparty/flot/.gitignore @@ -0,0 +1,3 @@ +*.min.js +!excanvas.min.js +node_modules/ diff --git a/monitoring/monitoring_ui/src/3dparty/flot/.travis.yml b/monitoring/monitoring_ui/src/3dparty/flot/.travis.yml new file mode 100644 index 0000000000000000000000000000000000000000..baa0031d5003b75b611433c7a8d83cc0e63fc050 --- /dev/null +++ b/monitoring/monitoring_ui/src/3dparty/flot/.travis.yml @@ -0,0 +1,3 @@ +language: node_js +node_js: + - 0.8 diff --git a/monitoring/monitoring_ui/src/3dparty/flot/API.md b/monitoring/monitoring_ui/src/3dparty/flot/API.md new file mode 100644 index 0000000000000000000000000000000000000000..e08b44cf1d2749f8527696168b16f00f973d063d --- /dev/null +++ b/monitoring/monitoring_ui/src/3dparty/flot/API.md @@ -0,0 +1,1498 @@ +# Flot Reference # + +**Table of Contents** + +[Introduction](#introduction) +| [Data Format](#data-format) +| [Plot Options](#plot-options) +| [Customizing the legend](#customizing-the-legend) +| [Customizing the axes](#customizing-the-axes) +| [Multiple axes](#multiple-axes) +| [Time series data](#time-series-data) +| [Customizing the data series](#customizing-the-data-series) +| [Customizing the grid](#customizing-the-grid) +| [Specifying gradients](#specifying-gradients) +| [Plot Methods](#plot-methods) +| [Hooks](#hooks) +| [Plugins](#plugins) +| [Version number](#version-number) + +--- + +## Introduction ## + +Consider a call to the plot function: + +```js +var plot = $.plot(placeholder, data, options) +``` + +The placeholder is a jQuery object or DOM element or jQuery expression +that the plot will be put into. This placeholder needs to have its +width and height set as explained in the [README](README.md) (go read that now if +you haven't, it's short). The plot will modify some properties of the +placeholder so it's recommended you simply pass in a div that you +don't use for anything else. Make sure you check any fancy styling +you apply to the div, e.g. background images have been reported to be a +problem on IE 7. + +The plot function can also be used as a jQuery chainable property. This form +naturally can't return the plot object directly, but you can still access it +via the 'plot' data key, like this: + +```js +var plot = $("#placeholder").plot(data, options).data("plot"); +``` + +The format of the data is documented below, as is the available +options. The plot object returned from the call has some methods you +can call. These are documented separately below. + +Note that in general Flot gives no guarantees if you change any of the +objects you pass in to the plot function or get out of it since +they're not necessarily deep-copied. + + +## Data Format ## + +The data is an array of data series: + +```js +[ series1, series2, ... ] +``` + +A series can either be raw data or an object with properties. The raw +data format is an array of points: + +```js +[ [x1, y1], [x2, y2], ... ] +``` + +E.g. + +```js +[ [1, 3], [2, 14.01], [3.5, 3.14] ] +``` + +Note that to simplify the internal logic in Flot both the x and y +values must be numbers (even if specifying time series, see below for +how to do this). This is a common problem because you might retrieve +data from the database and serialize them directly to JSON without +noticing the wrong type. If you're getting mysterious errors, double +check that you're inputting numbers and not strings. + +If a null is specified as a point or if one of the coordinates is null +or couldn't be converted to a number, the point is ignored when +drawing. As a special case, a null value for lines is interpreted as a +line segment end, i.e. the points before and after the null value are +not connected. + +Lines and points take two coordinates. For filled lines and bars, you +can specify a third coordinate which is the bottom of the filled +area/bar (defaults to 0). + +The format of a single series object is as follows: + +```js +{ + color: color or number + data: rawdata + label: string + lines: specific lines options + bars: specific bars options + points: specific points options + xaxis: number + yaxis: number + clickable: boolean + hoverable: boolean + shadowSize: number + highlightColor: color or number +} +``` + +You don't have to specify any of them except the data, the rest are +options that will get default values. Typically you'd only specify +label and data, like this: + +```js +{ + label: "y = 3", + data: [[0, 3], [10, 3]] +} +``` + +The label is used for the legend, if you don't specify one, the series +will not show up in the legend. + +If you don't specify color, the series will get a color from the +auto-generated colors. The color is either a CSS color specification +(like "rgb(255, 100, 123)") or an integer that specifies which of +auto-generated colors to select, e.g. 0 will get color no. 0, etc. + +The latter is mostly useful if you let the user add and remove series, +in which case you can hard-code the color index to prevent the colors +from jumping around between the series. + +The "xaxis" and "yaxis" options specify which axis to use. The axes +are numbered from 1 (default), so { yaxis: 2} means that the series +should be plotted against the second y axis. + +"clickable" and "hoverable" can be set to false to disable +interactivity for specific series if interactivity is turned on in +the plot, see below. + +The rest of the options are all documented below as they are the same +as the default options passed in via the options parameter in the plot +commmand. When you specify them for a specific data series, they will +override the default options for the plot for that data series. + +Here's a complete example of a simple data specification: + +```js +[ { label: "Foo", data: [ [10, 1], [17, -14], [30, 5] ] }, + { label: "Bar", data: [ [11, 13], [19, 11], [30, -7] ] } +] +``` + + +## Plot Options ## + +All options are completely optional. They are documented individually +below, to change them you just specify them in an object, e.g. + +```js +var options = { + series: { + lines: { show: true }, + points: { show: true } + } +}; + +$.plot(placeholder, data, options); +``` + + +## Customizing the legend ## + +```js +legend: { + show: boolean + labelFormatter: null or (fn: string, series object -> string) + labelBoxBorderColor: color + noColumns: number + position: "ne" or "nw" or "se" or "sw" + margin: number of pixels or [x margin, y margin] + backgroundColor: null or color + backgroundOpacity: number between 0 and 1 + container: null or jQuery object/DOM element/jQuery expression + sorted: null/false, true, "ascending", "descending", "reverse", or a comparator +} +``` + +The legend is generated as a table with the data series labels and +small label boxes with the color of the series. If you want to format +the labels in some way, e.g. make them to links, you can pass in a +function for "labelFormatter". Here's an example that makes them +clickable: + +```js +labelFormatter: function(label, series) { + // series is the series object for the label + return '<a href="#' + label + '">' + label + '</a>'; +} +``` + +To prevent a series from showing up in the legend, simply have the function +return null. + +"noColumns" is the number of columns to divide the legend table into. +"position" specifies the overall placement of the legend within the +plot (top-right, top-left, etc.) and margin the distance to the plot +edge (this can be either a number or an array of two numbers like [x, +y]). "backgroundColor" and "backgroundOpacity" specifies the +background. The default is a partly transparent auto-detected +background. + +If you want the legend to appear somewhere else in the DOM, you can +specify "container" as a jQuery object/expression to put the legend +table into. The "position" and "margin" etc. options will then be +ignored. Note that Flot will overwrite the contents of the container. + +Legend entries appear in the same order as their series by default. If "sorted" +is "reverse" then they appear in the opposite order from their series. To sort +them alphabetically, you can specify true, "ascending" or "descending", where +true and "ascending" are equivalent. + +You can also provide your own comparator function that accepts two +objects with "label" and "color" properties, and returns zero if they +are equal, a positive value if the first is greater than the second, +and a negative value if the first is less than the second. + +```js +sorted: function(a, b) { + // sort alphabetically in ascending order + return a.label == b.label ? 0 : ( + a.label > b.label ? 1 : -1 + ) +} +``` + + +## Customizing the axes ## + +```js +xaxis, yaxis: { + show: null or true/false + position: "bottom" or "top" or "left" or "right" + mode: null or "time" ("time" requires jquery.flot.time.js plugin) + timezone: null, "browser" or timezone (only makes sense for mode: "time") + + color: null or color spec + tickColor: null or color spec + font: null or font spec object + + min: null or number + max: null or number + autoscaleMargin: null or number + + transform: null or fn: number -> number + inverseTransform: null or fn: number -> number + + ticks: null or number or ticks array or (fn: axis -> ticks array) + tickSize: number or array + minTickSize: number or array + tickFormatter: (fn: number, object -> string) or string + tickDecimals: null or number + + labelWidth: null or number + labelHeight: null or number + reserveSpace: null or true + + tickLength: null or number + + alignTicksWithAxis: null or number +} +``` + +All axes have the same kind of options. The following describes how to +configure one axis, see below for what to do if you've got more than +one x axis or y axis. + +If you don't set the "show" option (i.e. it is null), visibility is +auto-detected, i.e. the axis will show up if there's data associated +with it. You can override this by setting the "show" option to true or +false. + +The "position" option specifies where the axis is placed, bottom or +top for x axes, left or right for y axes. The "mode" option determines +how the data is interpreted, the default of null means as decimal +numbers. Use "time" for time series data; see the time series data +section. The time plugin (jquery.flot.time.js) is required for time +series support. + +The "color" option determines the color of the line and ticks for the axis, and +defaults to the grid color with transparency. For more fine-grained control you +can also set the color of the ticks separately with "tickColor". + +You can customize the font and color used to draw the axis tick labels with CSS +or directly via the "font" option. When "font" is null - the default - each +tick label is given the 'flot-tick-label' class. For compatibility with Flot +0.7 and earlier the labels are also given the 'tickLabel' class, but this is +deprecated and scheduled to be removed with the release of version 1.0.0. + +To enable more granular control over styles, labels are divided between a set +of text containers, with each holding the labels for one axis. These containers +are given the classes 'flot-[x|y]-axis', and 'flot-[x|y]#-axis', where '#' is +the number of the axis when there are multiple axes. For example, the x-axis +labels for a simple plot with only a single x-axis might look like this: + +```html +<div class='flot-x-axis flot-x1-axis'> + <div class='flot-tick-label'>January 2013</div> + ... +</div> +``` + +For direct control over label styles you can also provide "font" as an object +with this format: + +```js +{ + size: 11, + lineHeight: 13, + style: "italic", + weight: "bold", + family: "sans-serif", + variant: "small-caps", + color: "#545454" +} +``` + +The size and lineHeight must be expressed in pixels; CSS units such as 'em' +or 'smaller' are not allowed. + +The options "min"/"max" are the precise minimum/maximum value on the +scale. If you don't specify either of them, a value will automatically +be chosen based on the minimum/maximum data values. Note that Flot +always examines all the data values you feed to it, even if a +restriction on another axis may make some of them invisible (this +makes interactive use more stable). + +The "autoscaleMargin" is a bit esoteric: it's the fraction of margin +that the scaling algorithm will add to avoid that the outermost points +ends up on the grid border. Note that this margin is only applied when +a min or max value is not explicitly set. If a margin is specified, +the plot will furthermore extend the axis end-point to the nearest +whole tick. The default value is "null" for the x axes and 0.02 for y +axes which seems appropriate for most cases. + +"transform" and "inverseTransform" are callbacks you can put in to +change the way the data is drawn. You can design a function to +compress or expand certain parts of the axis non-linearly, e.g. +suppress weekends or compress far away points with a logarithm or some +other means. When Flot draws the plot, each value is first put through +the transform function. Here's an example, the x axis can be turned +into a natural logarithm axis with the following code: + +```js +xaxis: { + transform: function (v) { return Math.log(v); }, + inverseTransform: function (v) { return Math.exp(v); } +} +``` + +Similarly, for reversing the y axis so the values appear in inverse +order: + +```js +yaxis: { + transform: function (v) { return -v; }, + inverseTransform: function (v) { return -v; } +} +``` + +Note that for finding extrema, Flot assumes that the transform +function does not reorder values (it should be monotone). + +The inverseTransform is simply the inverse of the transform function +(so v == inverseTransform(transform(v)) for all relevant v). It is +required for converting from canvas coordinates to data coordinates, +e.g. for a mouse interaction where a certain pixel is clicked. If you +don't use any interactive features of Flot, you may not need it. + + +The rest of the options deal with the ticks. + +If you don't specify any ticks, a tick generator algorithm will make +some for you. The algorithm has two passes. It first estimates how +many ticks would be reasonable and uses this number to compute a nice +round tick interval size. Then it generates the ticks. + +You can specify how many ticks the algorithm aims for by setting +"ticks" to a number. The algorithm always tries to generate reasonably +round tick values so even if you ask for three ticks, you might get +five if that fits better with the rounding. If you don't want any +ticks at all, set "ticks" to 0 or an empty array. + +Another option is to skip the rounding part and directly set the tick +interval size with "tickSize". If you set it to 2, you'll get ticks at +2, 4, 6, etc. Alternatively, you can specify that you just don't want +ticks at a size less than a specific tick size with "minTickSize". +Note that for time series, the format is an array like [2, "month"], +see the next section. + +If you want to completely override the tick algorithm, you can specify +an array for "ticks", either like this: + +```js +ticks: [0, 1.2, 2.4] +``` + +Or like this where the labels are also customized: + +```js +ticks: [[0, "zero"], [1.2, "one mark"], [2.4, "two marks"]] +``` + +You can mix the two if you like. + +For extra flexibility you can specify a function as the "ticks" +parameter. The function will be called with an object with the axis +min and max and should return a ticks array. Here's a simplistic tick +generator that spits out intervals of pi, suitable for use on the x +axis for trigonometric functions: + +```js +function piTickGenerator(axis) { + var res = [], i = Math.floor(axis.min / Math.PI); + do { + var v = i * Math.PI; + res.push([v, i + "\u03c0"]); + ++i; + } while (v < axis.max); + return res; +} +``` + +You can control how the ticks look like with "tickDecimals", the +number of decimals to display (default is auto-detected). + +Alternatively, for ultimate control over how ticks are formatted you can +provide a function to "tickFormatter". The function is passed two +parameters, the tick value and an axis object with information, and +should return a string. The default formatter looks like this: + +```js +function formatter(val, axis) { + return val.toFixed(axis.tickDecimals); +} +``` + +The axis object has "min" and "max" with the range of the axis, +"tickDecimals" with the number of decimals to round the value to and +"tickSize" with the size of the interval between ticks as calculated +by the automatic axis scaling algorithm (or specified by you). Here's +an example of a custom formatter: + +```js +function suffixFormatter(val, axis) { + if (val > 1000000) + return (val / 1000000).toFixed(axis.tickDecimals) + " MB"; + else if (val > 1000) + return (val / 1000).toFixed(axis.tickDecimals) + " kB"; + else + return val.toFixed(axis.tickDecimals) + " B"; +} +``` + +"labelWidth" and "labelHeight" specifies a fixed size of the tick +labels in pixels. They're useful in case you need to align several +plots. "reserveSpace" means that even if an axis isn't shown, Flot +should reserve space for it - it is useful in combination with +labelWidth and labelHeight for aligning multi-axis charts. + +"tickLength" is the length of the tick lines in pixels. By default, the +innermost axes will have ticks that extend all across the plot, while +any extra axes use small ticks. A value of null means use the default, +while a number means small ticks of that length - set it to 0 to hide +the lines completely. + +If you set "alignTicksWithAxis" to the number of another axis, e.g. +alignTicksWithAxis: 1, Flot will ensure that the autogenerated ticks +of this axis are aligned with the ticks of the other axis. This may +improve the looks, e.g. if you have one y axis to the left and one to +the right, because the grid lines will then match the ticks in both +ends. The trade-off is that the forced ticks won't necessarily be at +natural places. + + +## Multiple axes ## + +If you need more than one x axis or y axis, you need to specify for +each data series which axis they are to use, as described under the +format of the data series, e.g. { data: [...], yaxis: 2 } specifies +that a series should be plotted against the second y axis. + +To actually configure that axis, you can't use the xaxis/yaxis options +directly - instead there are two arrays in the options: + +```js +xaxes: [] +yaxes: [] +``` + +Here's an example of configuring a single x axis and two y axes (we +can leave options of the first y axis empty as the defaults are fine): + +```js +{ + xaxes: [ { position: "top" } ], + yaxes: [ { }, { position: "right", min: 20 } ] +} +``` + +The arrays get their default values from the xaxis/yaxis settings, so +say you want to have all y axes start at zero, you can simply specify +yaxis: { min: 0 } instead of adding a min parameter to all the axes. + +Generally, the various interfaces in Flot dealing with data points +either accept an xaxis/yaxis parameter to specify which axis number to +use (starting from 1), or lets you specify the coordinate directly as +x2/x3/... or x2axis/x3axis/... instead of "x" or "xaxis". + + +## Time series data ## + +Please note that it is now required to include the time plugin, +jquery.flot.time.js, for time series support. + +Time series are a bit more difficult than scalar data because +calendars don't follow a simple base 10 system. For many cases, Flot +abstracts most of this away, but it can still be a bit difficult to +get the data into Flot. So we'll first discuss the data format. + +The time series support in Flot is based on Javascript timestamps, +i.e. everywhere a time value is expected or handed over, a Javascript +timestamp number is used. This is a number, not a Date object. A +Javascript timestamp is the number of milliseconds since January 1, +1970 00:00:00 UTC. This is almost the same as Unix timestamps, except it's +in milliseconds, so remember to multiply by 1000! + +You can see a timestamp like this + +```js +alert((new Date()).getTime()) +``` + +There are different schools of thought when it comes to display of +timestamps. Many will want the timestamps to be displayed according to +a certain time zone, usually the time zone in which the data has been +produced. Some want the localized experience, where the timestamps are +displayed according to the local time of the visitor. Flot supports +both. Optionally you can include a third-party library to get +additional timezone support. + +Default behavior is that Flot always displays timestamps according to +UTC. The reason being that the core Javascript Date object does not +support other fixed time zones. Often your data is at another time +zone, so it may take a little bit of tweaking to work around this +limitation. + +The easiest way to think about it is to pretend that the data +production time zone is UTC, even if it isn't. So if you have a +datapoint at 2002-02-20 08:00, you can generate a timestamp for eight +o'clock UTC even if it really happened eight o'clock UTC+0200. + +In PHP you can get an appropriate timestamp with: + +```php +strtotime("2002-02-20 UTC") * 1000 +``` + +In Python you can get it with something like: + +```python +calendar.timegm(datetime_object.timetuple()) * 1000 +``` +In Ruby you can get it using the `#to_i` method on the +[`Time`](http://apidock.com/ruby/Time/to_i) object. If you're using the +`active_support` gem (default for Ruby on Rails applications) `#to_i` is also +available on the `DateTime` and `ActiveSupport::TimeWithZone` objects. You +simply need to multiply the result by 1000: + +```ruby +Time.now.to_i * 1000 # => 1383582043000 +# ActiveSupport examples: +DateTime.now.to_i * 1000 # => 1383582043000 +ActiveSupport::TimeZone.new('Asia/Shanghai').now.to_i * 1000 +# => 1383582043000 +``` + +In .NET you can get it with something like: + +```aspx +public static int GetJavascriptTimestamp(System.DateTime input) +{ + System.TimeSpan span = new System.TimeSpan(System.DateTime.Parse("1/1/1970").Ticks); + System.DateTime time = input.Subtract(span); + return (long)(time.Ticks / 10000); +} +``` + +Javascript also has some support for parsing date strings, so it is +possible to generate the timestamps manually client-side. + +If you've already got the real UTC timestamp, it's too late to use the +pretend trick described above. But you can fix up the timestamps by +adding the time zone offset, e.g. for UTC+0200 you would add 2 hours +to the UTC timestamp you got. Then it'll look right on the plot. Most +programming environments have some means of getting the timezone +offset for a specific date (note that you need to get the offset for +each individual timestamp to account for daylight savings). + +The alternative with core Javascript is to interpret the timestamps +according to the time zone that the visitor is in, which means that +the ticks will shift with the time zone and daylight savings of each +visitor. This behavior is enabled by setting the axis option +"timezone" to the value "browser". + +If you need more time zone functionality than this, there is still +another option. If you include the "timezone-js" library +<https://github.com/mde/timezone-js> in the page and set axis.timezone +to a value recognized by said library, Flot will use timezone-js to +interpret the timestamps according to that time zone. + +Once you've gotten the timestamps into the data and specified "time" +as the axis mode, Flot will automatically generate relevant ticks and +format them. As always, you can tweak the ticks via the "ticks" option +- just remember that the values should be timestamps (numbers), not +Date objects. + +Tick generation and formatting can also be controlled separately +through the following axis options: + +```js +minTickSize: array +timeformat: null or format string +monthNames: null or array of size 12 of strings +dayNames: null or array of size 7 of strings +twelveHourClock: boolean +``` + +Here "timeformat" is a format string to use. You might use it like +this: + +```js +xaxis: { + mode: "time", + timeformat: "%Y/%m/%d" +} +``` + +This will result in tick labels like "2000/12/24". A subset of the +standard strftime specifiers are supported (plus the nonstandard %q): + +```js +%a: weekday name (customizable) +%b: month name (customizable) +%d: day of month, zero-padded (01-31) +%e: day of month, space-padded ( 1-31) +%H: hours, 24-hour time, zero-padded (00-23) +%I: hours, 12-hour time, zero-padded (01-12) +%m: month, zero-padded (01-12) +%M: minutes, zero-padded (00-59) +%q: quarter (1-4) +%S: seconds, zero-padded (00-59) +%y: year (two digits) +%Y: year (four digits) +%p: am/pm +%P: AM/PM (uppercase version of %p) +%w: weekday as number (0-6, 0 being Sunday) +``` + +Flot 0.8 switched from %h to the standard %H hours specifier. The %h specifier +is still available, for backwards-compatibility, but is deprecated and +scheduled to be removed permanently with the release of version 1.0. + +You can customize the month names with the "monthNames" option. For +instance, for Danish you might specify: + +```js +monthNames: ["jan", "feb", "mar", "apr", "maj", "jun", "jul", "aug", "sep", "okt", "nov", "dec"] +``` + +Similarly you can customize the weekday names with the "dayNames" +option. An example in French: + +```js +dayNames: ["dim", "lun", "mar", "mer", "jeu", "ven", "sam"] +``` + +If you set "twelveHourClock" to true, the autogenerated timestamps +will use 12 hour AM/PM timestamps instead of 24 hour. This only +applies if you have not set "timeformat". Use the "%I" and "%p" or +"%P" options if you want to build your own format string with 12-hour +times. + +If the Date object has a strftime property (and it is a function), it +will be used instead of the built-in formatter. Thus you can include +a strftime library such as http://hacks.bluesmoon.info/strftime/ for +more powerful date/time formatting. + +If everything else fails, you can control the formatting by specifying +a custom tick formatter function as usual. Here's a simple example +which will format December 24 as 24/12: + +```js +tickFormatter: function (val, axis) { + var d = new Date(val); + return d.getUTCDate() + "/" + (d.getUTCMonth() + 1); +} +``` + +Note that for the time mode "tickSize" and "minTickSize" are a bit +special in that they are arrays on the form "[value, unit]" where unit +is one of "second", "minute", "hour", "day", "month" and "year". So +you can specify + +```js +minTickSize: [1, "month"] +``` + +to get a tick interval size of at least 1 month and correspondingly, +if axis.tickSize is [2, "day"] in the tick formatter, the ticks have +been produced with two days in-between. + + +## Customizing the data series ## + +```js +series: { + lines, points, bars: { + show: boolean + lineWidth: number + fill: boolean or number + fillColor: null or color/gradient + } + + lines, bars: { + zero: boolean + } + + points: { + radius: number + symbol: "circle" or function + } + + bars: { + barWidth: number + align: "left", "right" or "center" + horizontal: boolean + } + + lines: { + steps: boolean + } + + shadowSize: number + highlightColor: color or number +} + +colors: [ color1, color2, ... ] +``` + +The options inside "series: {}" are copied to each of the series. So +you can specify that all series should have bars by putting it in the +global options, or override it for individual series by specifying +bars in a particular the series object in the array of data. + +The most important options are "lines", "points" and "bars" that +specify whether and how lines, points and bars should be shown for +each data series. In case you don't specify anything at all, Flot will +default to showing lines (you can turn this off with +lines: { show: false }). You can specify the various types +independently of each other, and Flot will happily draw each of them +in turn (this is probably only useful for lines and points), e.g. + +```js +var options = { + series: { + lines: { show: true, fill: true, fillColor: "rgba(255, 255, 255, 0.8)" }, + points: { show: true, fill: false } + } +}; +``` + +"lineWidth" is the thickness of the line or outline in pixels. You can +set it to 0 to prevent a line or outline from being drawn; this will +also hide the shadow. + +"fill" is whether the shape should be filled. For lines, this produces +area graphs. You can use "fillColor" to specify the color of the fill. +If "fillColor" evaluates to false (default for everything except +points which are filled with white), the fill color is auto-set to the +color of the data series. You can adjust the opacity of the fill by +setting fill to a number between 0 (fully transparent) and 1 (fully +opaque). + +For bars, fillColor can be a gradient, see the gradient documentation +below. "barWidth" is the width of the bars in units of the x axis (or +the y axis if "horizontal" is true), contrary to most other measures +that are specified in pixels. For instance, for time series the unit +is milliseconds so 24 * 60 * 60 * 1000 produces bars with the width of +a day. "align" specifies whether a bar should be left-aligned +(default), right-aligned or centered on top of the value it represents. +When "horizontal" is on, the bars are drawn horizontally, i.e. from the +y axis instead of the x axis; note that the bar end points are still +defined in the same way so you'll probably want to swap the +coordinates if you've been plotting vertical bars first. + +Area and bar charts normally start from zero, regardless of the data's range. +This is because they convey information through size, and starting from a +different value would distort their meaning. In cases where the fill is purely +for decorative purposes, however, "zero" allows you to override this behavior. +It defaults to true for filled lines and bars; setting it to false tells the +series to use the same automatic scaling as an un-filled line. + +For lines, "steps" specifies whether two adjacent data points are +connected with a straight (possibly diagonal) line or with first a +horizontal and then a vertical line. Note that this transforms the +data by adding extra points. + +For points, you can specify the radius and the symbol. The only +built-in symbol type is circles, for other types you can use a plugin +or define them yourself by specifying a callback: + +```js +function cross(ctx, x, y, radius, shadow) { + var size = radius * Math.sqrt(Math.PI) / 2; + ctx.moveTo(x - size, y - size); + ctx.lineTo(x + size, y + size); + ctx.moveTo(x - size, y + size); + ctx.lineTo(x + size, y - size); +} +``` + +The parameters are the drawing context, x and y coordinates of the +center of the point, a radius which corresponds to what the circle +would have used and whether the call is to draw a shadow (due to +limited canvas support, shadows are currently faked through extra +draws). It's good practice to ensure that the area covered by the +symbol is the same as for the circle with the given radius, this +ensures that all symbols have approximately the same visual weight. + +"shadowSize" is the default size of shadows in pixels. Set it to 0 to +remove shadows. + +"highlightColor" is the default color of the translucent overlay used +to highlight the series when the mouse hovers over it. + +The "colors" array specifies a default color theme to get colors for +the data series from. You can specify as many colors as you like, like +this: + +```js +colors: ["#d18b2c", "#dba255", "#919733"] +``` + +If there are more data series than colors, Flot will try to generate +extra colors by lightening and darkening colors in the theme. + + +## Customizing the grid ## + +```js +grid: { + show: boolean + aboveData: boolean + color: color + backgroundColor: color/gradient or null + margin: number or margin object + labelMargin: number + axisMargin: number + markings: array of markings or (fn: axes -> array of markings) + borderWidth: number or object with "top", "right", "bottom" and "left" properties with different widths + borderColor: color or null or object with "top", "right", "bottom" and "left" properties with different colors + minBorderMargin: number or null + clickable: boolean + hoverable: boolean + autoHighlight: boolean + mouseActiveRadius: number +} + +interaction: { + redrawOverlayInterval: number or -1 +} +``` + +The grid is the thing with the axes and a number of ticks. Many of the +things in the grid are configured under the individual axes, but not +all. "color" is the color of the grid itself whereas "backgroundColor" +specifies the background color inside the grid area, here null means +that the background is transparent. You can also set a gradient, see +the gradient documentation below. + +You can turn off the whole grid including tick labels by setting +"show" to false. "aboveData" determines whether the grid is drawn +above the data or below (below is default). + +"margin" is the space in pixels between the canvas edge and the grid, +which can be either a number or an object with individual margins for +each side, in the form: + +```js +margin: { + top: top margin in pixels + left: left margin in pixels + bottom: bottom margin in pixels + right: right margin in pixels +} +``` + +"labelMargin" is the space in pixels between tick labels and axis +line, and "axisMargin" is the space in pixels between axes when there +are two next to each other. + +"borderWidth" is the width of the border around the plot. Set it to 0 +to disable the border. Set it to an object with "top", "right", +"bottom" and "left" properties to use different widths. You can +also set "borderColor" if you want the border to have a different color +than the grid lines. Set it to an object with "top", "right", "bottom" +and "left" properties to use different colors. "minBorderMargin" controls +the default minimum margin around the border - it's used to make sure +that points aren't accidentally clipped by the canvas edge so by default +the value is computed from the point radius. + +"markings" is used to draw simple lines and rectangular areas in the +background of the plot. You can either specify an array of ranges on +the form { xaxis: { from, to }, yaxis: { from, to } } (with multiple +axes, you can specify coordinates for other axes instead, e.g. as +x2axis/x3axis/...) or with a function that returns such an array given +the axes for the plot in an object as the first parameter. + +You can set the color of markings by specifying "color" in the ranges +object. Here's an example array: + +```js +markings: [ { xaxis: { from: 0, to: 2 }, yaxis: { from: 10, to: 10 }, color: "#bb0000" }, ... ] +``` + +If you leave out one of the values, that value is assumed to go to the +border of the plot. So for example if you only specify { xaxis: { +from: 0, to: 2 } } it means an area that extends from the top to the +bottom of the plot in the x range 0-2. + +A line is drawn if from and to are the same, e.g. + +```js +markings: [ { yaxis: { from: 1, to: 1 } }, ... ] +``` + +would draw a line parallel to the x axis at y = 1. You can control the +line width with "lineWidth" in the range object. + +An example function that makes vertical stripes might look like this: + +```js +markings: function (axes) { + var markings = []; + for (var x = Math.floor(axes.xaxis.min); x < axes.xaxis.max; x += 2) + markings.push({ xaxis: { from: x, to: x + 1 } }); + return markings; +} +``` + +If you set "clickable" to true, the plot will listen for click events +on the plot area and fire a "plotclick" event on the placeholder with +a position and a nearby data item object as parameters. The coordinates +are available both in the unit of the axes (not in pixels) and in +global screen coordinates. + +Likewise, if you set "hoverable" to true, the plot will listen for +mouse move events on the plot area and fire a "plothover" event with +the same parameters as the "plotclick" event. If "autoHighlight" is +true (the default), nearby data items are highlighted automatically. +If needed, you can disable highlighting and control it yourself with +the highlight/unhighlight plot methods described elsewhere. + +You can use "plotclick" and "plothover" events like this: + +```js +$.plot($("#placeholder"), [ d ], { grid: { clickable: true } }); + +$("#placeholder").bind("plotclick", function (event, pos, item) { + alert("You clicked at " + pos.x + ", " + pos.y); + // axis coordinates for other axes, if present, are in pos.x2, pos.x3, ... + // if you need global screen coordinates, they are pos.pageX, pos.pageY + + if (item) { + highlight(item.series, item.datapoint); + alert("You clicked a point!"); + } +}); +``` + +The item object in this example is either null or a nearby object on the form: + +```js +item: { + datapoint: the point, e.g. [0, 2] + dataIndex: the index of the point in the data array + series: the series object + seriesIndex: the index of the series + pageX, pageY: the global screen coordinates of the point +} +``` + +For instance, if you have specified the data like this + +```js +$.plot($("#placeholder"), [ { label: "Foo", data: [[0, 10], [7, 3]] } ], ...); +``` + +and the mouse is near the point (7, 3), "datapoint" is [7, 3], +"dataIndex" will be 1, "series" is a normalized series object with +among other things the "Foo" label in series.label and the color in +series.color, and "seriesIndex" is 0. Note that plugins and options +that transform the data can shift the indexes from what you specified +in the original data array. + +If you use the above events to update some other information and want +to clear out that info in case the mouse goes away, you'll probably +also need to listen to "mouseout" events on the placeholder div. + +"mouseActiveRadius" specifies how far the mouse can be from an item +and still activate it. If there are two or more points within this +radius, Flot chooses the closest item. For bars, the top-most bar +(from the latest specified data series) is chosen. + +If you want to disable interactivity for a specific data series, you +can set "hoverable" and "clickable" to false in the options for that +series, like this: + +```js +{ data: [...], label: "Foo", clickable: false } +``` + +"redrawOverlayInterval" specifies the maximum time to delay a redraw +of interactive things (this works as a rate limiting device). The +default is capped to 60 frames per second. You can set it to -1 to +disable the rate limiting. + + +## Specifying gradients ## + +A gradient is specified like this: + +```js +{ colors: [ color1, color2, ... ] } +``` + +For instance, you might specify a background on the grid going from +black to gray like this: + +```js +grid: { + backgroundColor: { colors: ["#000", "#999"] } +} +``` + +For the series you can specify the gradient as an object that +specifies the scaling of the brightness and the opacity of the series +color, e.g. + +```js +{ colors: [{ opacity: 0.8 }, { brightness: 0.6, opacity: 0.8 } ] } +``` + +where the first color simply has its alpha scaled, whereas the second +is also darkened. For instance, for bars the following makes the bars +gradually disappear, without outline: + +```js +bars: { + show: true, + lineWidth: 0, + fill: true, + fillColor: { colors: [ { opacity: 0.8 }, { opacity: 0.1 } ] } +} +``` + +Flot currently only supports vertical gradients drawn from top to +bottom because that's what works with IE. + + +## Plot Methods ## + +The Plot object returned from the plot function has some methods you +can call: + + - highlight(series, datapoint) + + Highlight a specific datapoint in the data series. You can either + specify the actual objects, e.g. if you got them from a + "plotclick" event, or you can specify the indices, e.g. + highlight(1, 3) to highlight the fourth point in the second series + (remember, zero-based indexing). + + - unhighlight(series, datapoint) or unhighlight() + + Remove the highlighting of the point, same parameters as + highlight. + + If you call unhighlight with no parameters, e.g. as + plot.unhighlight(), all current highlights are removed. + + - setData(data) + + You can use this to reset the data used. Note that axis scaling, + ticks, legend etc. will not be recomputed (use setupGrid() to do + that). You'll probably want to call draw() afterwards. + + You can use this function to speed up redrawing a small plot if + you know that the axes won't change. Put in the new data with + setData(newdata), call draw(), and you're good to go. Note that + for large datasets, almost all the time is consumed in draw() + plotting the data so in this case don't bother. + + - setupGrid() + + Recalculate and set axis scaling, ticks, legend etc. + + Note that because of the drawing model of the canvas, this + function will immediately redraw (actually reinsert in the DOM) + the labels and the legend, but not the actual tick lines because + they're drawn on the canvas. You need to call draw() to get the + canvas redrawn. + + - draw() + + Redraws the plot canvas. + + - triggerRedrawOverlay() + + Schedules an update of an overlay canvas used for drawing + interactive things like a selection and point highlights. This + is mostly useful for writing plugins. The redraw doesn't happen + immediately, instead a timer is set to catch multiple successive + redraws (e.g. from a mousemove). You can get to the overlay by + setting up a drawOverlay hook. + + - width()/height() + + Gets the width and height of the plotting area inside the grid. + This is smaller than the canvas or placeholder dimensions as some + extra space is needed (e.g. for labels). + + - offset() + + Returns the offset of the plotting area inside the grid relative + to the document, useful for instance for calculating mouse + positions (event.pageX/Y minus this offset is the pixel position + inside the plot). + + - pointOffset({ x: xpos, y: ypos }) + + Returns the calculated offset of the data point at (x, y) in data + space within the placeholder div. If you are working with multiple + axes, you can specify the x and y axis references, e.g. + + ```js + o = pointOffset({ x: xpos, y: ypos, xaxis: 2, yaxis: 3 }) + // o.left and o.top now contains the offset within the div + ```` + + - resize() + + Tells Flot to resize the drawing canvas to the size of the + placeholder. You need to run setupGrid() and draw() afterwards as + canvas resizing is a destructive operation. This is used + internally by the resize plugin. + + - shutdown() + + Cleans up any event handlers Flot has currently registered. This + is used internally. + +There are also some members that let you peek inside the internal +workings of Flot which is useful in some cases. Note that if you change +something in the objects returned, you're changing the objects used by +Flot to keep track of its state, so be careful. + + - getData() + + Returns an array of the data series currently used in normalized + form with missing settings filled in according to the global + options. So for instance to find out what color Flot has assigned + to the data series, you could do this: + + ```js + var series = plot.getData(); + for (var i = 0; i < series.length; ++i) + alert(series[i].color); + ``` + + A notable other interesting field besides color is datapoints + which has a field "points" with the normalized data points in a + flat array (the field "pointsize" is the increment in the flat + array to get to the next point so for a dataset consisting only of + (x,y) pairs it would be 2). + + - getAxes() + + Gets an object with the axes. The axes are returned as the + attributes of the object, so for instance getAxes().xaxis is the + x axis. + + Various things are stuffed inside an axis object, e.g. you could + use getAxes().xaxis.ticks to find out what the ticks are for the + xaxis. Two other useful attributes are p2c and c2p, functions for + transforming from data point space to the canvas plot space and + back. Both returns values that are offset with the plot offset. + Check the Flot source code for the complete set of attributes (or + output an axis with console.log() and inspect it). + + With multiple axes, the extra axes are returned as x2axis, x3axis, + etc., e.g. getAxes().y2axis is the second y axis. You can check + y2axis.used to see whether the axis is associated with any data + points and y2axis.show to see if it is currently shown. + + - getPlaceholder() + + Returns placeholder that the plot was put into. This can be useful + for plugins for adding DOM elements or firing events. + + - getCanvas() + + Returns the canvas used for drawing in case you need to hack on it + yourself. You'll probably need to get the plot offset too. + + - getPlotOffset() + + Gets the offset that the grid has within the canvas as an object + with distances from the canvas edges as "left", "right", "top", + "bottom". I.e., if you draw a circle on the canvas with the center + placed at (left, top), its center will be at the top-most, left + corner of the grid. + + - getOptions() + + Gets the options for the plot, normalized, with default values + filled in. You get a reference to actual values used by Flot, so + if you modify the values in here, Flot will use the new values. + If you change something, you probably have to call draw() or + setupGrid() or triggerRedrawOverlay() to see the change. + + +## Hooks ## + +In addition to the public methods, the Plot object also has some hooks +that can be used to modify the plotting process. You can install a +callback function at various points in the process, the function then +gets access to the internal data structures in Flot. + +Here's an overview of the phases Flot goes through: + + 1. Plugin initialization, parsing options + + 2. Constructing the canvases used for drawing + + 3. Set data: parsing data specification, calculating colors, + copying raw data points into internal format, + normalizing them, finding max/min for axis auto-scaling + + 4. Grid setup: calculating axis spacing, ticks, inserting tick + labels, the legend + + 5. Draw: drawing the grid, drawing each of the series in turn + + 6. Setting up event handling for interactive features + + 7. Responding to events, if any + + 8. Shutdown: this mostly happens in case a plot is overwritten + +Each hook is simply a function which is put in the appropriate array. +You can add them through the "hooks" option, and they are also available +after the plot is constructed as the "hooks" attribute on the returned +plot object, e.g. + +```js + // define a simple draw hook + function hellohook(plot, canvascontext) { alert("hello!"); }; + + // pass it in, in an array since we might want to specify several + var plot = $.plot(placeholder, data, { hooks: { draw: [hellohook] } }); + + // we can now find it again in plot.hooks.draw[0] unless a plugin + // has added other hooks +``` + +The available hooks are described below. All hook callbacks get the +plot object as first parameter. You can find some examples of defined +hooks in the plugins bundled with Flot. + + - processOptions [phase 1] + + ```function(plot, options)``` + + Called after Flot has parsed and merged options. Useful in the + instance where customizations beyond simple merging of default + values is needed. A plugin might use it to detect that it has been + enabled and then turn on or off other options. + + + - processRawData [phase 3] + + ```function(plot, series, data, datapoints)``` + + Called before Flot copies and normalizes the raw data for the given + series. If the function fills in datapoints.points with normalized + points and sets datapoints.pointsize to the size of the points, + Flot will skip the copying/normalization step for this series. + + In any case, you might be interested in setting datapoints.format, + an array of objects for specifying how a point is normalized and + how it interferes with axis scaling. It accepts the following options: + + ```js + { + x, y: boolean, + number: boolean, + required: boolean, + defaultValue: value, + autoscale: boolean + } + ``` + + "x" and "y" specify whether the value is plotted against the x or y axis, + and is currently used only to calculate axis min-max ranges. The default + format array, for example, looks like this: + + ```js + [ + { x: true, number: true, required: true }, + { y: true, number: true, required: true } + ] + ``` + + This indicates that a point, i.e. [0, 25], consists of two values, with the + first being plotted on the x axis and the second on the y axis. + + If "number" is true, then the value must be numeric, and is set to null if + it cannot be converted to a number. + + "defaultValue" provides a fallback in case the original value is null. This + is for instance handy for bars, where one can omit the third coordinate + (the bottom of the bar), which then defaults to zero. + + If "required" is true, then the value must exist (be non-null) for the + point as a whole to be valid. If no value is provided, then the entire + point is cleared out with nulls, turning it into a gap in the series. + + "autoscale" determines whether the value is considered when calculating an + automatic min-max range for the axes that the value is plotted against. + + - processDatapoints [phase 3] + + ```function(plot, series, datapoints)``` + + Called after normalization of the given series but before finding + min/max of the data points. This hook is useful for implementing data + transformations. "datapoints" contains the normalized data points in + a flat array as datapoints.points with the size of a single point + given in datapoints.pointsize. Here's a simple transform that + multiplies all y coordinates by 2: + + ```js + function multiply(plot, series, datapoints) { + var points = datapoints.points, ps = datapoints.pointsize; + for (var i = 0; i < points.length; i += ps) + points[i + 1] *= 2; + } + ``` + + Note that you must leave datapoints in a good condition as Flot + doesn't check it or do any normalization on it afterwards. + + - processOffset [phase 4] + + ```function(plot, offset)``` + + Called after Flot has initialized the plot's offset, but before it + draws any axes or plot elements. This hook is useful for customizing + the margins between the grid and the edge of the canvas. "offset" is + an object with attributes "top", "bottom", "left" and "right", + corresponding to the margins on the four sides of the plot. + + - drawBackground [phase 5] + + ```function(plot, canvascontext)``` + + Called before all other drawing operations. Used to draw backgrounds + or other custom elements before the plot or axes have been drawn. + + - drawSeries [phase 5] + + ```function(plot, canvascontext, series)``` + + Hook for custom drawing of a single series. Called just before the + standard drawing routine has been called in the loop that draws + each series. + + - draw [phase 5] + + ```function(plot, canvascontext)``` + + Hook for drawing on the canvas. Called after the grid is drawn + (unless it's disabled or grid.aboveData is set) and the series have + been plotted (in case any points, lines or bars have been turned + on). For examples of how to draw things, look at the source code. + + - bindEvents [phase 6] + + ```function(plot, eventHolder)``` + + Called after Flot has setup its event handlers. Should set any + necessary event handlers on eventHolder, a jQuery object with the + canvas, e.g. + + ```js + function (plot, eventHolder) { + eventHolder.mousedown(function (e) { + alert("You pressed the mouse at " + e.pageX + " " + e.pageY); + }); + } + ``` + + Interesting events include click, mousemove, mouseup/down. You can + use all jQuery events. Usually, the event handlers will update the + state by drawing something (add a drawOverlay hook and call + triggerRedrawOverlay) or firing an externally visible event for + user code. See the crosshair plugin for an example. + + Currently, eventHolder actually contains both the static canvas + used for the plot itself and the overlay canvas used for + interactive features because some versions of IE get the stacking + order wrong. The hook only gets one event, though (either for the + overlay or for the static canvas). + + Note that custom plot events generated by Flot are not generated on + eventHolder, but on the div placeholder supplied as the first + argument to the plot call. You can get that with + plot.getPlaceholder() - that's probably also the one you should use + if you need to fire a custom event. + + - drawOverlay [phase 7] + + ```function (plot, canvascontext)``` + + The drawOverlay hook is used for interactive things that need a + canvas to draw on. The model currently used by Flot works the way + that an extra overlay canvas is positioned on top of the static + canvas. This overlay is cleared and then completely redrawn + whenever something interesting happens. This hook is called when + the overlay canvas is to be redrawn. + + "canvascontext" is the 2D context of the overlay canvas. You can + use this to draw things. You'll most likely need some of the + metrics computed by Flot, e.g. plot.width()/plot.height(). See the + crosshair plugin for an example. + + - shutdown [phase 8] + + ```function (plot, eventHolder)``` + + Run when plot.shutdown() is called, which usually only happens in + case a plot is overwritten by a new plot. If you're writing a + plugin that adds extra DOM elements or event handlers, you should + add a callback to clean up after you. Take a look at the section in + the [PLUGINS](PLUGINS.md) document for more info. + + +## Plugins ## + +Plugins extend the functionality of Flot. To use a plugin, simply +include its Javascript file after Flot in the HTML page. + +If you're worried about download size/latency, you can concatenate all +the plugins you use, and Flot itself for that matter, into one big file +(make sure you get the order right), then optionally run it through a +Javascript minifier such as YUI Compressor. + +Here's a brief explanation of how the plugin plumbings work: + +Each plugin registers itself in the global array $.plot.plugins. When +you make a new plot object with $.plot, Flot goes through this array +calling the "init" function of each plugin and merging default options +from the "option" attribute of the plugin. The init function gets a +reference to the plot object created and uses this to register hooks +and add new public methods if needed. + +See the [PLUGINS](PLUGINS.md) document for details on how to write a plugin. As the +above description hints, it's actually pretty easy. + + +## Version number ## + +The version number of Flot is available in ```$.plot.version```. diff --git a/monitoring/monitoring_ui/src/3dparty/flot/CONTRIBUTING.md b/monitoring/monitoring_ui/src/3dparty/flot/CONTRIBUTING.md new file mode 100644 index 0000000000000000000000000000000000000000..3e6e43a0fd4783174d2c2e26df02717249f598d4 --- /dev/null +++ b/monitoring/monitoring_ui/src/3dparty/flot/CONTRIBUTING.md @@ -0,0 +1,98 @@ +## Contributing to Flot ## + +We welcome all contributions, but following these guidelines results in less +work for us, and a faster and better response. + +### Issues ### + +Issues are not a way to ask general questions about Flot. If you see unexpected +behavior but are not 100% certain that it is a bug, please try posting to the +[forum](http://groups.google.com/group/flot-graphs) first, and confirm that +what you see is really a Flot problem before creating a new issue for it. When +reporting a bug, please include a working demonstration of the problem, if +possible, or at least a clear description of the options you're using and the +environment (browser and version, jQuery version, other libraries) that you're +running under. + +If you have suggestions for new features, or changes to existing ones, we'd +love to hear them! Please submit each suggestion as a separate new issue. + +If you would like to work on an existing issue, please make sure it is not +already assigned to someone else. If an issue is assigned to someone, that +person has already started working on it. So, pick unassigned issues to prevent +duplicated effort. + +### Pull Requests ### + +To make merging as easy as possible, please keep these rules in mind: + + 1. Submit new features or architectural changes to the *<version>-work* + branch for the next major release. Submit bug fixes to the master branch. + + 2. Divide larger changes into a series of small, logical commits with + descriptive messages. + + 3. Rebase, if necessary, before submitting your pull request, to reduce the + work we need to do to merge it. + + 4. Format your code according to the style guidelines below. + +### Flot Style Guidelines ### + +Flot follows the [jQuery Core Style Guidelines](http://docs.jquery.com/JQuery_Core_Style_Guidelines), +with the following updates and exceptions: + +#### Spacing #### + +Use four-space indents, no tabs. Do not add horizontal space around parameter +lists, loop definitions, or array/object indices. For example: + +```js + for ( var i = 0; i < data.length; i++ ) { // This block is wrong! + if ( data[ i ] > 1 ) { + data[ i ] = 2; + } + } + + for (var i = 0; i < data.length; i++) { // This block is correct! + if (data[i] > 1) { + data[i] = 2; + } + } +``` + +#### Comments #### + +Use [jsDoc](http://usejsdoc.org) comments for all file and function headers. +Use // for all inline and block comments, regardless of length. + +All // comment blocks should have an empty line above *and* below them. For +example: + +```js + var a = 5; + + // We're going to loop here + // TODO: Make this loop faster, better, stronger! + + for (var x = 0; x < 10; x++) {} +``` + +#### Wrapping #### + +Block comments should be wrapped at 80 characters. + +Code should attempt to wrap at 80 characters, but may run longer if wrapping +would hurt readability more than having to scroll horizontally. This is a +judgement call made on a situational basis. + +Statements containing complex logic should not be wrapped arbitrarily if they +do not exceed 80 characters. For example: + +```js + if (a == 1 && // This block is wrong! + b == 2 && + c == 3) {} + + if (a == 1 && b == 2 && c == 3) {} // This block is correct! +``` diff --git a/monitoring/monitoring_ui/src/3dparty/flot/FAQ.md b/monitoring/monitoring_ui/src/3dparty/flot/FAQ.md new file mode 100644 index 0000000000000000000000000000000000000000..9131e043985f8281cc5b0c4eec06b84447e9eb67 --- /dev/null +++ b/monitoring/monitoring_ui/src/3dparty/flot/FAQ.md @@ -0,0 +1,75 @@ +## Frequently asked questions ## + +#### How much data can Flot cope with? #### + +Flot will happily draw everything you send to it so the answer +depends on the browser. The excanvas emulation used for IE (built with +VML) makes IE by far the slowest browser so be sure to test with that +if IE users are in your target group (for large plots in IE, you can +also check out Flashcanvas which may be faster). + +1000 points is not a problem, but as soon as you start having more +points than the pixel width, you should probably start thinking about +downsampling/aggregation as this is near the resolution limit of the +chart anyway. If you downsample server-side, you also save bandwidth. + + +#### Flot isn't working when I'm using JSON data as source! #### + +Actually, Flot loves JSON data, you just got the format wrong. +Double check that you're not inputting strings instead of numbers, +like [["0", "-2.13"], ["5", "4.3"]]. This is most common mistake, and +the error might not show up immediately because Javascript can do some +conversion automatically. + + +#### Can I export the graph? #### + +You can grab the image rendered by the canvas element used by Flot +as a PNG or JPEG (remember to set a background). Note that it won't +include anything not drawn in the canvas (such as the legend). And it +doesn't work with excanvas which uses VML, but you could try +Flashcanvas. + + +#### The bars are all tiny in time mode? #### + +It's not really possible to determine the bar width automatically. +So you have to set the width with the barWidth option which is NOT in +pixels, but in the units of the x axis (or the y axis for horizontal +bars). For time mode that's milliseconds so the default value of 1 +makes the bars 1 millisecond wide. + + +#### Can I use Flot with libraries like Mootools or Prototype? #### + +Yes, Flot supports it out of the box and it's easy! Just use jQuery +instead of $, e.g. call jQuery.plot instead of $.plot and use +jQuery(something) instead of $(something). As a convenience, you can +put in a DOM element for the graph placeholder where the examples and +the API documentation are using jQuery objects. + +Depending on how you include jQuery, you may have to add one line of +code to prevent jQuery from overwriting functions from the other +libraries, see the documentation in jQuery ("Using jQuery with other +libraries") for details. + + +#### Flot doesn't work with [insert name of Javascript UI framework]! #### + +Flot is using standard HTML to make charts. If this is not working, +it's probably because the framework you're using is doing something +weird with the DOM or with the CSS that is interfering with Flot. + +A common problem is that there's display:none on a container until the +user does something. Many tab widgets work this way, and there's +nothing wrong with it - you just can't call Flot inside a display:none +container as explained in the README so you need to hold off the Flot +call until the container is actually displayed (or use +visibility:hidden instead of display:none or move the container +off-screen). + +If you find there's a specific thing we can do to Flot to help, feel +free to submit a bug report. Otherwise, you're welcome to ask for help +on the forum/mailing list, but please don't submit a bug report to +Flot. diff --git a/monitoring/monitoring_ui/src/3dparty/flot/LICENSE.txt b/monitoring/monitoring_ui/src/3dparty/flot/LICENSE.txt new file mode 100644 index 0000000000000000000000000000000000000000..719da064fefb4e2f99ca269f32a2e4432ce052fb --- /dev/null +++ b/monitoring/monitoring_ui/src/3dparty/flot/LICENSE.txt @@ -0,0 +1,22 @@ +Copyright (c) 2007-2014 IOLA and Ole Laursen + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/monitoring/monitoring_ui/src/3dparty/flot/NEWS.md b/monitoring/monitoring_ui/src/3dparty/flot/NEWS.md new file mode 100644 index 0000000000000000000000000000000000000000..ad0303d742eb9898d8feb8d9481f9ba3453b903e --- /dev/null +++ b/monitoring/monitoring_ui/src/3dparty/flot/NEWS.md @@ -0,0 +1,1026 @@ +## Flot 0.8.3 ## + +### Changes ### + +- Updated example code to avoid encouraging unnecessary re-plots. + (patch by soenter, pull request #1221) + +### Bug fixes ### + + - Added a work-around to disable the allocation of extra space for first and + last axis ticks, allowing plots to span the full width of their container. + A proper solution for this bug will be implemented in the 0.9 release. + (reported by Josh Pigford and andig, issue #1212, pull request #1290) + + - Fixed a regression introduced in 0.8.1, where the last tick label would + sometimes wrap rather than extending the plot's offset to create space. + (reported by Elite Gamer, issue #1283) + + - Fixed a regression introduced in 0.8.2, where the resize plugin would use + unexpectedly high amounts of CPU even when idle. + (reported by tommie, issue #1277, pull request #1289) + + - Fixed the selection example to work with jQuery 1.9.x and later. + (reported by EGLadona and dmfalke, issue #1250, pull request #1285) + + - Added a detach shim to fix support for jQuery versions earlier than 1.4.x. + (reported by ngavard, issue #1240, pull request #1286) + + - Fixed a rare 'Uncaught TypeError' when using the resize plugin in IE 7/8. + (reported by tleish, issue #1265, pull request #1289) + + - Fixed zoom constraints to apply only in the direction of the zoom. + (patch by Neil Katin, issue #1204, pull request #1205) + + - Markings lines are no longer blurry when drawn on pixel boundaries. + (reported by btccointicker and Rouillard, issue #1210) + + - Don't discard original pie data-series values when combining slices. + (patch by Phil Tsarik, pull request #1238) + + - Fixed broken auto-scale behavior when using deprecated [x|y]2axis options. + (reported by jorese, issue #1228, pull request #1284) + + - Exposed the dateGenerator function on the plot object, as it used to be + before time-mode was moved into a separate plugin. + (patch by Paolo Valleri, pull request #1028) + + +## Flot 0.8.2 ## + +### Changes ### + + - Added a plot.destroy method as a way to free memory when emptying the plot + placeholder and then re-using it for some other purpose. + (patch by Thodoris Greasidis, issue #1129, pull request #1130) + + - Added a table of contents and PLUGINS link to the API documentation. + (patches by Brian Peiris, pull requests #1064 and #1127) + + - Added Ruby code examples for time conversion. + (patch by Mike Połtyn, pull request #1182) + + - Minor improvements to API.md and README.md. + (patches by Patrik Ragnarsson, pull requests #1085 and #1086) + + - Updated inlined jQuery Resize to the latest version to fix errors. + (reported by Matthew Sabol and sloker, issues #997 ad #1081) + +### Bug fixes ### + + - Fixed an unexpected change in behavior that resulted in duplicate tick + labels when using a plugin, like flot-tickrotor, that overrode tick labels. + (patch by Mark Cote, pull request #1091) + + - Fixed a regression from 0.7 where axis labels were given the wrong width, + causing them to overlap at certain scales and ignore the labelWidth option. + (patch by Benjamin Gram, pull request #1177) + + - Fixed a bug where the second axis in an xaxes/yaxes array incorrectly had + its 'innermost' property set to false or undefined, even if it was on the + other side of the plot from the first axis. This resulted in the axis bar + being visible when it shouldn't have been, which was especially obvious + when the grid had a left/right border width of zero. + (reported by Teq1, fix researched by ryleyb, issue #1056) + + - Fixed an error when using a placeholder that has no font-size property. + (patch by Craig Oldford, pull request #1135) + + - Fixed a regression from 0.7 where nulls at the end of a series were ignored + for purposes of determing the range of the x-axis. + (reported by Munsifali Rashid, issue #1095) + + - If a font size is provided, base the default lineHeight on that size rather + that the font size of the plot placeholder, which may be very different. + (reported by Daniel Hoffmann Bernardes, issue #1131, pull request #1199) + + - Fix broken highlighting for right-aligned bars. + (reported by BeWiBu and Mihai Stanciu, issues #975 and #1093, with further + assistance by Eric Byers, pull request #1120) + + - Prevent white circles from sometimes showing up inside of pie charts. + (reported by Pierre Dubois and Jack Klink, issues #1128 and #1073) + + - Label formatting no longer breaks when a page contains multiple pie charts. + (reported by Brend Wanders, issue #1055) + + - When using multiple axes on opposite sides of the plot, the innermost axis + coming later in the list no longer has its bar drawn incorrectly. + (reported by ryleyb, issue #1056) + + - When removing series labels and redrawing the plot, the legend now updates + correctly even when using an external container. + (patch by Luis Silva, issue #1159, pull request #1160) + + - The pie plugin no longer ignores the value of the left offset option. + (reported by melanker, issue #1136) + + - Fixed a regression from 0.7, where extra padding was added unnecessarily to + sides of the plot where there was no last tick label. + (reported by sknob001, issue #1048, pull request #1200) + + - Fixed incorrect tooltip behavior in the interacting example. + (patch by cleroux, issue #686, pull request #1074) + + - Fixed an error in CSS color extraction with elements outside the DOM. + (patch by execjosh, pull request #1084) + + - Fixed :not selector error when using jQuery without Sizzle. + (patch by Anthony Ryan, pull request #1180) + + - Worked around a browser issue that caused bars to appear un-filled. + (reported by irbian, issue #915) + +## Flot 0.8.1 ## + +### Bug fixes ### + + - Fixed a regression in the time plugin, introduced in 0.8, that caused dates + to align to the minute rather than to the highest appropriate unit. This + caused many x-axes in 0.8 to have different ticks than they did in 0.7. + (reported by Tom Sheppard, patch by Daniel Shapiro, issue #1017, pull + request #1023) + + - Fixed a regression in text rendering, introduced in 0.8, that caused axis + labels with the same text as another label on the same axis to disappear. + More generally, it's again possible to have the same text in two locations. + (issue #1032) + + - Fixed a regression in text rendering, introduced in 0.8, where axis labels + were no longer assigned an explicit width, and their text could not wrap. + (reported by sabregreen, issue #1019) + + - Fixed a regression in the pie plugin, introduced in 0.8, that prevented it + from accepting data in the format '[[x, y]]'. + (patch by Nicolas Morel, pull request #1024) + + - The 'zero' series option and 'autoscale' format option are no longer + ignored when the series contains a null value. + (reported by Daniel Shapiro, issue #1033) + + - Avoid triggering the time-mode plugin exception when there are zero series. + (reported by Daniel Rothig, patch by Mark Raymond, issue #1016) + + - When a custom color palette has fewer colors than the default palette, Flot + no longer fills out the colors with the remainder of the default. + (patch by goorpy, issue #1031, pull request #1034) + + - Fixed missing update for bar highlights after a zoom or other redraw. + (reported by Paolo Valleri, issue #1030) + + - Fixed compatibility with jQuery versions earlier than 1.7. + (patch by Lee Willis, issue #1027, pull request #1027) + + - The mouse wheel no longer scrolls the page when using the navigate plugin. + (patch by vird, pull request #1020) + + - Fixed missing semicolons in the core library. + (reported by Michal Zglinski) + + +## Flot 0.8.0 ## + +### API changes ### + +Support for time series has been moved into a plugin, jquery.flot.time.js. +This results in less code if time series are not used. The functionality +remains the same (plus timezone support, as described below); however, the +plugin must be included if axis.mode is set to "time". + +When the axis mode is "time", the axis option "timezone" can be set to null, +"browser", or a particular timezone (e.g. "America/New_York") to control how +the dates are displayed. If null, the dates are displayed as UTC. If +"browser", the dates are displayed in the time zone of the user's browser. + +Date/time formatting has changed and now follows a proper subset of the +standard strftime specifiers, plus one nonstandard specifier for quarters. +Additionally, if a strftime function is found in the Date object's prototype, +it will be used instead of the built-in formatter. + +Axis tick labels now use the class 'flot-tick-label' instead of 'tickLabel'. +The text containers for each axis now use the classes 'flot-[x|y]-axis' and +'flot-[x|y]#-axis' instead of '[x|y]Axis' and '[x|y]#Axis'. For compatibility +with Flot 0.7 and earlier text will continue to use the old classes as well, +but they are considered deprecated and will be removed in a future version. + +In previous versions the axis 'color' option was used to set the color of tick +marks and their label text. It now controls the color of the axis line, which +previously could not be changed separately, and continues to act as a default +for the tick-mark color. The color of tick label text is now set either by +overriding the 'flot-tick-label' CSS rule or via the axis 'font' option. + +A new plugin, jquery.flot.canvas.js, allows axis tick labels to be rendered +directly to the canvas, rather than using HTML elements. This feature can be +toggled with a simple option, making it easy to create interactive plots in the +browser using HTML, then re-render them to canvas for export as an image. + +The plugin tries to remain as faithful as possible to the original HTML render, +and goes so far as to automatically extract styles from CSS, to avoid having to +provide a separate set of styles when rendering to canvas. Due to limitations +of the canvas text API, the plugin cannot reproduce certain features, including +HTML markup embedded in labels, and advanced text styles such as 'em' units. + +The plugin requires support for canvas text, which may not be present in some +older browsers, even if they support the canvas tag itself. To use the plugin +with these browsers try using a shim such as canvas-text or FlashCanvas. + +The base and overlay canvas are now using the CSS classes "flot-base" and +"flot-overlay" to prevent accidental clashes (issue 540). + +### Changes ### + + - Addition of nonstandard %q specifier to date/time formatting. (patch + by risicle, issue 49) + + - Date/time formatting follows proper subset of strftime specifiers, and + support added for Date.prototype.strftime, if found. (patch by Mark Cote, + issues 419 and 558) + + - Fixed display of year ticks. (patch by Mark Cote, issue 195) + + - Support for time series moved to plugin. (patch by Mark Cote) + + - Display time series in different time zones. (patch by Knut Forkalsrud, + issue 141) + + - Added a canvas plugin to enable rendering axis tick labels to the canvas. + (sponsored by YCharts.com, implementation by Ole Laursen and David Schnur) + + - Support for setting the interval between redraws of the overlay canvas with + redrawOverlayInterval. (suggested in issue 185) + + - Support for multiple thresholds in thresholds plugin. (patch by Arnaud + Bellec, issue 523) + + - Support for plotting categories/textual data directly with new categories + plugin. + + - Tick generators now get the whole axis rather than just min/max. + + - Added processOffset and drawBackground hooks. (suggested in issue 639) + + - Added a grid "margin" option to set the space between the canvas edge and + the grid. + + - Prevent the pie example page from generating single-slice pies. (patch by + Shane Reustle) + + - In addition to "left" and "center", bars now recognize "right" as an + alignment option. (patch by Michael Mayer, issue 520) + + - Switched from toFixed to a much faster default tickFormatter. (patch by + Clemens Stolle) + + - Added to a more helpful error when using a time-mode axis without including + the flot.time plugin. (patch by Yael Elmatad) + + - Added a legend "sorted" option to control sorting of legend entries + independent of their series order. (patch by Tom Cleaveland) + + - Added a series "highlightColor" option to control the color of the + translucent overlay that identifies the dataset when the mouse hovers over + it. (patch by Eric Wendelin and Nate Abele, issues 168 and 299) + + - Added a plugin jquery.flot.errorbars, with an accompanying example, that + adds the ability to plot error bars, commonly used in many kinds of + statistical data visualizations. (patch by Rui Pereira, issue 215) + + - The legend now omits entries whose labelFormatter returns null. (patch by + Tom Cleaveland, Christopher Lambert, and Simon Strandgaard) + + - Added support for high pixel density (retina) displays, resulting in much + crisper charts on such devices. (patch by Olivier Guerriat, additional + fixes by Julien Thomas, maimairel, and Lau Bech Lauritzen) + + - Added the ability to control pie shadow position and alpha via a new pie + 'shadow' option. (patch by Julien Thomas, pull request #78) + + - Added the ability to set width and color for individual sides of the grid. + (patch by Ara Anjargolian, additional fixes by Karl Swedberg, pull requests #855 + and #880) + + - The selection plugin's getSelection now returns null when the selection + has been cleared. (patch by Nick Campbell, pull request #852) + + - Added a new option called 'zero' to bars and filled lines series, to control + whether the y-axis minimum is scaled to fit the data or set to zero. + (patch by David Schnur, issues #316, #529, and #856, pull request #911) + + - The plot function is now also a jQuery chainable property. + (patch by David Schnur, issues #734 and #816, pull request #953) + + - When only a single pie slice is beneath the combine threshold it is no longer + replaced by an 'other' slice. (suggested by Devin Bayer, issue #638) + + - Added lineJoin and minSize options to the selection plugin to control the + corner style and minimum size of the selection, respectively. + (patch by Ruth Linehan, pull request #963) + +### Bug fixes ### + + - Fix problem with null values and pie plugin. (patch by gcruxifix, + issue 500) + + - Fix problem with threshold plugin and bars. (based on patch by + kaarlenkaski, issue 348) + + - Fix axis box calculations so the boxes include the outermost part of the + labels too. + + - Fix problem with event clicking and hovering in IE 8 by updating Excanvas + and removing previous work-around. (test case by Ara Anjargolian) + + - Fix issues with blurry 1px border when some measures aren't integer. + (reported by Ara Anjargolian) + + - Fix bug with formats in the data processor. (reported by Peter Hull, + issue 534) + + - Prevent i from being declared global in extractRange. (reported by + Alexander Obukhov, issue 627) + + - Throw errors in a more cross-browser-compatible manner. (patch by + Eddie Kay) + + - Prevent pie slice outlines from being drawn when the stroke width is zero. + (reported by Chris Minett, issue 585) + + - Updated the navigate plugin's inline copy of jquery.mousewheel to fix + Webkit zoom problems. (reported by Hau Nguyen, issue 685) + + - Axis labels no longer appear as decimals rather than integers in certain + cases. (patch by Clemens Stolle, issue 541) + + - Automatic color generation no longer produces only whites and blacks when + there are many series. (patch by David Schnur and Tom Cleaveland) + + - Fixed an error when custom tick labels weren't provided as strings. (patch + by Shad Downey) + + - Prevented the local insertSteps and fmt variables from becoming global. + (first reported by Marc Bennewitz and Szymon Barglowski, patch by Nick + Campbell, issues #825 and #831, pull request #851) + + - Prevented several threshold plugin variables from becoming global. (patch + by Lasse Dahl Ebert) + + - Fixed various jQuery 1.8 compatibility issues. (issues #814 and #819, + pull request #877) + + - Pie charts with a slice equal to or approaching 100% of the pie no longer + appear invisible. (patch by David Schnur, issues #444, #658, #726, #824 + and #850, pull request #879) + + - Prevented several local variables from becoming global. (patch by aaa707) + + - Ensure that the overlay and primary canvases remain aligned. (issue #670, + pull request #901) + + - Added support for jQuery 1.9 by removing and replacing uses of $.browser. + (analysis and patch by Anthony Ryan, pull request #905) + + - Pie charts no longer disappear when redrawn during a resize or update. + (reported by Julien Bec, issue #656, pull request #910) + + - Avoided floating-point precision errors when calculating pie percentages. + (patch by James Ward, pull request #918) + + - Fixed compatibility with jQuery 1.2.6, which has no 'mouseleave' shortcut. + (reported by Bevan, original pull request #920, replaced by direct patch) + + - Fixed sub-pixel rendering issues with crosshair and selection lines. + (patches by alanayoub and Daniel Shapiro, pull requests #17 and #925) + + - Fixed rendering issues when using the threshold plugin with several series. + (patch by Ivan Novikov, pull request #934) + + - Pie charts no longer disappear when redrawn after calling setData(). + (reported by zengge1984 and pareeohnos, issues #810 and #945) + + - Added a work-around for the problem where points with a lineWidth of zero + still showed up with a visible line. (reported by SalvoSav, issue #842, + patch by Jamie Hamel-Smith, pull request #937) + + - Pie charts now accept values in string form, like other plot types. + (reported by laerdal.no, issue #534) + + - Avoid rounding errors in the threshold plugin. + (reported by jerikojerk, issue #895) + + - Fixed an error when using the navigate plugin with jQuery 1.9.x or later. + (reported by Paolo Valleri, issue #964) + + - Fixed inconsistencies between the highlight and unhighlight functions. + (reported by djamshed, issue #987) + + - Fixed recalculation of tickSize and tickDecimals on calls to setupGrid. + (patch by thecountofzero, pull request #861, issues #860, #1000) + + +## Flot 0.7 ## + +### API changes ### + +Multiple axes support. Code using dual axes should be changed from using +x2axis/y2axis in the options to using an array (although backwards- +compatibility hooks are in place). For instance, + +```js +{ + xaxis: { ... }, x2axis: { ... }, + yaxis: { ... }, y2axis: { ... } +} +``` + +becomes + +```js +{ + xaxes: [ { ... }, { ... } ], + yaxes: [ { ... }, { ... } ] +} +``` + +Note that if you're just using one axis, continue to use the xaxis/yaxis +directly (it now sets the default settings for the arrays). Plugins touching +the axes must be ported to take the extra axes into account, check the source +to see some examples. + +A related change is that the visibility of axes is now auto-detected. So if +you were relying on an axis to show up even without any data in the chart, you +now need to set the axis "show" option explicitly. + +"tickColor" on the grid options is now deprecated in favour of a corresponding +option on the axes, so: + +```js +{ grid: { tickColor: "#000" }} +``` + +becomes + +```js +{ xaxis: { tickColor: "#000"}, yaxis: { tickColor: "#000"} } +``` + +But if you just configure a base color Flot will now autogenerate a tick color +by adding transparency. Backwards-compatibility hooks are in place. + +Final note: now that IE 9 is coming out with canvas support, you may want to +adapt the excanvas include to skip loading it in IE 9 (the examples have been +adapted thanks to Ryley Breiddal). An alternative to excanvas using Flash has +also surfaced, if your graphs are slow in IE, you may want to give it a spin: + + http://code.google.com/p/flashcanvas/ + +### Changes ### + + - Support for specifying a bottom for each point for line charts when filling + them, this means that an arbitrary bottom can be used instead of just the x + axis. (based on patches patiently provided by Roman V. Prikhodchenko) + + - New fillbetween plugin that can compute a bottom for a series from another + series, useful for filling areas between lines. + + See new example percentiles.html for a use case. + + - More predictable handling of gaps for the stacking plugin, now all + undefined ranges are skipped. + + - Stacking plugin can stack horizontal bar charts. + + - Navigate plugin now redraws the plot while panning instead of only after + the fact. (raised by lastthemy, issue 235) + + Can be disabled by setting the pan.frameRate option to null. + + - Date formatter now accepts %0m and %0d to get a zero-padded month or day. + (issue raised by Maximillian Dornseif) + + - Revamped internals to support an unlimited number of axes, not just dual. + (sponsored by Flight Data Services, www.flightdataservices.com) + + - New setting on axes, "tickLength", to control the size of ticks or turn + them off without turning off the labels. + + - Axis labels are now put in container divs with classes, for instance labels + in the x axes can be reached via ".xAxis .tickLabel". + + - Support for setting the color of an axis. (sponsored by Flight Data + Services, www.flightdataservices.com) + + - Tick color is now auto-generated as the base color with some transparency, + unless you override it. + + - Support for aligning ticks in the axes with "alignTicksWithAxis" to ensure + that they appear next to each other rather than in between, at the expense + of possibly awkward tick steps. (sponsored by Flight Data Services, + www.flightdataservices.com) + + - Support for customizing the point type through a callback when plotting + points and new symbol plugin with some predefined point types. (sponsored + by Utility Data Corporation) + + - Resize plugin for automatically redrawing when the placeholder changes + size, e.g. on window resizes. (sponsored by Novus Partners) + + A resize() method has been added to plot object facilitate this. + + - Support Infinity/-Infinity for plotting asymptotes by hacking it into + +/-Number.MAX_VALUE. (reported by rabaea.mircea) + + - Support for restricting navigate plugin to not pan/zoom an axis. (based on + patch by kkaefer) + + - Support for providing the drag cursor for the navigate plugin as an option. + (based on patch by Kelly T. Moore) + + - Options for controlling whether an axis is shown or not (suggestion by Timo + Tuominen) and whether to reserve space for it even if it isn't shown. + + - New attribute $.plot.version with the Flot version as a string. + + - The version comment is now included in the minified jquery.flot.min.js. + + - New options.grid.minBorderMargin for adjusting the minimum margin provided + around the border (based on patch by corani, issue 188). + + - Refactor replot behaviour so Flot tries to reuse the existing canvas, + adding shutdown() methods to the plot. (based on patch by Ryley Breiddal, + issue 269) + + This prevents a memory leak in Chrome and hopefully makes replotting faster + for those who are using $.plot instead of .setData()/.draw(). Also update + jQuery to 1.5.1 to prevent IE leaks fixed in jQuery. + + - New real-time line chart example. + + - New hooks: drawSeries, shutdown. + +### Bug fixes ### + + - Fixed problem with findNearbyItem and bars on top of each other. (reported + by ragingchikn, issue 242) + + - Fixed problem with ticks and the border. (based on patch from + ultimatehustler69, issue 236) + + - Fixed problem with plugins adding options to the series objects. + + - Fixed a problem introduced in 0.6 with specifying a gradient with: + + ```{brightness: x, opacity: y }``` + + - Don't use $.browser.msie, check for getContext on the created canvas element + instead and try to use excanvas if it's not found. + + Fixes IE 9 compatibility. + + - highlight(s, index) was looking up the point in the original s.data instead + of in the computed datapoints array, which breaks with plugins that modify + the datapoints, such as the stacking plugin. (reported by curlypaul924, + issue 316) + + - More robust handling of axis from data passed in from getData(). (reported) + by Morgan) + + - Fixed problem with turning off bar outline. (fix by Jordi Castells, + issue 253) + + - Check the selection passed into setSelection in the selection + plugin, to guard against errors when synchronizing plots (fix by Lau + Bech Lauritzen). + + - Fix bug in crosshair code with mouseout resetting the crosshair even + if it is locked (fix by Lau Bech Lauritzen and Banko Adam). + + - Fix bug with points plotting using line width from lines rather than + points. + + - Fix bug with passing non-array 0 data (for plugins that don't expect + arrays, patch by vpapp1). + + - Fix errors in JSON in examples so they work with jQuery 1.4.2 + (fix reported by honestbleeps, issue 357). + + - Fix bug with tooltip in interacting.html, this makes the tooltip + much smoother (fix by bdkahn). Fix related bug inside highlighting + handler in Flot. + + - Use closure trick to make inline colorhelpers plugin respect + jQuery.noConflict(true), renaming the global jQuery object (reported + by Nick Stielau). + + - Listen for mouseleave events and fire a plothover event with empty + item when it occurs to drop highlights when the mouse leaves the + plot (reported by by outspirit). + + - Fix bug with using aboveData with a background (reported by + amitayd). + + - Fix possible excanvas leak (report and suggested fix by tom9729). + + - Fix bug with backwards compatibility for shadowSize = 0 (report and + suggested fix by aspinak). + + - Adapt examples to skip loading excanvas (fix by Ryley Breiddal). + + - Fix bug that prevent a simple f(x) = -x transform from working + correctly (fix by Mike, issue 263). + + - Fix bug in restoring cursor in navigate plugin (reported by Matteo + Gattanini, issue 395). + + - Fix bug in picking items when transform/inverseTransform is in use + (reported by Ofri Raviv, and patches and analysis by Jan and Tom + Paton, issue 334 and 467). + + - Fix problem with unaligned ticks and hover/click events caused by + padding on the placeholder by hardcoding the placeholder padding to + 0 (reported by adityadineshsaxena, Matt Sommer, Daniel Atos and some + other people, issue 301). + + - Update colorhelpers plugin to avoid dying when trying to parse an + invalid string (reported by cadavor, issue 483). + + + +## Flot 0.6 ## + +### API changes ### + +Selection support has been moved to a plugin. Thus if you're passing +selection: { mode: something }, you MUST include the file +jquery.flot.selection.js after jquery.flot.js. This reduces the size of +base Flot and makes it easier to customize the selection as well as +improving code clarity. The change is based on a patch from andershol. + +In the global options specified in the $.plot command, "lines", "points", +"bars" and "shadowSize" have been moved to a sub-object called "series": + +```js +$.plot(placeholder, data, { lines: { show: true }}) +``` + +should be changed to + +```js + $.plot(placeholder, data, { series: { lines: { show: true }}}) +``` + +All future series-specific options will go into this sub-object to +simplify plugin writing. Backward-compatibility code is in place, so +old code should not break. + +"plothover" no longer provides the original data point, but instead a +normalized one, since there may be no corresponding original point. + +Due to a bug in previous versions of jQuery, you now need at least +jQuery 1.2.6. But if you can, try jQuery 1.3.2 as it got some improvements +in event handling speed. + +## Changes ## + + - Added support for disabling interactivity for specific data series. + (request from Ronald Schouten and Steve Upton) + + - Flot now calls $() on the placeholder and optional legend container passed + in so you can specify DOM elements or CSS expressions to make it easier to + use Flot with libraries like Prototype or Mootools or through raw JSON from + Ajax responses. + + - A new "plotselecting" event is now emitted while the user is making a + selection. + + - The "plothover" event is now emitted immediately instead of at most 10 + times per second, you'll have to put in a setTimeout yourself if you're + doing something really expensive on this event. + + - The built-in date formatter can now be accessed as $.plot.formatDate(...) + (suggestion by Matt Manela) and even replaced. + + - Added "borderColor" option to the grid. (patches from Amaury Chamayou and + Mike R. Williamson) + + - Added support for gradient backgrounds for the grid. (based on patch from + Amaury Chamayou, issue 90) + + The "setting options" example provides a demonstration. + + - Gradient bars. (suggestion by stefpet) + + - Added a "plotunselected" event which is triggered when the selection is + removed, see "selection" example. (suggestion by Meda Ugo) + + - The option legend.margin can now specify horizontal and vertical margins + independently. (suggestion by someone who's annoyed) + + - Data passed into Flot is now copied to a new canonical format to enable + further processing before it hits the drawing routines. As a side-effect, + this should make Flot more robust in the face of bad data. (issue 112) + + - Step-wise charting: line charts have a new option "steps" that when set to + true connects the points with horizontal/vertical steps instead of diagonal + lines. + + - The legend labelFormatter now passes the series in addition to just the + label. (suggestion by Vincent Lemeltier) + + - Horizontal bars (based on patch by Jason LeBrun). + + - Support for partial bars by specifying a third coordinate, i.e. they don't + have to start from the axis. This can be used to make stacked bars. + + - New option to disable the (grid.show). + + - Added pointOffset method for converting a point in data space to an offset + within the placeholder. + + - Plugin system: register an init method in the $.flot.plugins array to get + started, see PLUGINS.txt for details on how to write plugins (it's easy). + There are also some extra methods to enable access to internal state. + + - Hooks: you can register functions that are called while Flot is crunching + the data and doing the plot. This can be used to modify Flot without + changing the source, useful for writing plugins. Some hooks are defined, + more are likely to come. + + - Threshold plugin: you can set a threshold and a color, and the data points + below that threshold will then get the color. Useful for marking data + below 0, for instance. + + - Stack plugin: you can specify a stack key for each series to have them + summed. This is useful for drawing additive/cumulative graphs with bars and + (currently unfilled) lines. + + - Crosshairs plugin: trace the mouse position on the axes, enable with + crosshair: { mode: "x"} (see the new tracking example for a use). + + - Image plugin: plot prerendered images. + + - Navigation plugin for panning and zooming a plot. + + - More configurable grid. + + - Axis transformation support, useful for non-linear plots, e.g. log axes and + compressed time axes (like omitting weekends). + + - Support for twelve-hour date formatting (patch by Forrest Aldridge). + + - The color parsing code in Flot has been cleaned up and split out so it's + now available as a separate jQuery plugin. It's included inline in the Flot + source to make dependency managing easier. This also makes it really easy + to use the color helpers in Flot plugins. + +## Bug fixes ## + + - Fixed two corner-case bugs when drawing filled curves. (report and analysis + by Joshua Varner) + + - Fix auto-adjustment code when setting min to 0 for an axis where the + dataset is completely flat on that axis. (report by chovy) + + - Fixed a bug with passing in data from getData to setData when the secondary + axes are used. (reported by nperelman, issue 65) + + - Fixed so that it is possible to turn lines off when no other chart type is + shown (based on problem reported by Glenn Vanderburg), and fixed so that + setting lineWidth to 0 also hides the shadow. (based on problem reported by + Sergio Nunes) + + - Updated mousemove position expression to the latest from jQuery. (reported + by meyuchas) + + - Use CSS borders instead of background in legend. (issues 25 and 45) + + - Explicitly convert axis min/max to numbers. + + - Fixed a bug with drawing marking lines with different colors. (reported by + Khurram) + + - Fixed a bug with returning y2 values in the selection event. (fix by + exists, issue 75) + + - Only set position relative on placeholder if it hasn't already a position + different from static. (reported by kyberneticist, issue 95) + + - Don't round markings to prevent sub-pixel problems. (reported by + Dan Lipsitt) + + - Make the grid border act similarly to a regular CSS border, i.e. prevent + it from overlapping the plot itself. This also fixes a problem with anti- + aliasing when the width is 1 pixel. (reported by Anthony Ettinger) + + - Imported version 3 of excanvas and fixed two issues with the newer version. + Hopefully, this will make Flot work with IE8. (nudge by Fabien Menager, + further analysis by Booink, issue 133) + + - Changed the shadow code for lines to hopefully look a bit better with + vertical lines. + + - Round tick positions to avoid possible problems with fractions. (suggestion + by Fred, issue 130) + + - Made the heuristic for determining how many ticks to aim for a bit smarter. + + - Fix for uneven axis margins (report and patch by Paul Kienzle) and snapping + to ticks. (report and patch by lifthrasiir) + + - Fixed bug with slicing in findNearbyItems. (patch by zollman) + + - Make heuristic for x axis label widths more dynamic. (patch by + rickinhethuis) + + - Make sure points on top take precedence when finding nearby points when + hovering. (reported by didroe, issue 224) + + + +## Flot 0.5 ## + +Timestamps are now in UTC. Also "selected" event -> becomes "plotselected" +with new data, the parameters for setSelection are now different (but +backwards compatibility hooks are in place), coloredAreas becomes markings +with a new interface (but backwards compatibility hooks are in place). + +### API changes ### + +Timestamps in time mode are now displayed according to UTC instead of the time +zone of the visitor. This affects the way the timestamps should be input; +you'll probably have to offset the timestamps according to your local time +zone. It also affects any custom date handling code (which basically now +should use the equivalent UTC date mehods, e.g. .setUTCMonth() instead of +.setMonth(). + +Markings, previously coloredAreas, are now specified as ranges on the axes, +like ```{ xaxis: { from: 0, to: 10 }}```. Furthermore with markings you can +now draw horizontal/vertical lines by setting from and to to the same +coordinate. (idea from line support patch by by Ryan Funduk) + +Interactivity: added a new "plothover" event and this and the "plotclick" +event now returns the closest data item (based on patch by /david, patch by +Mark Byers for bar support). See the revamped "interacting with the data" +example for some hints on what you can do. + +Highlighting: you can now highlight points and datapoints are autohighlighted +when you hover over them (if hovering is turned on). + +Support for dual axis has been added (based on patch by someone who's annoyed +and /david). For each data series you can specify which axes it belongs to, +and there are two more axes, x2axis and y2axis, to customize. This affects the +"selected" event which has been renamed to "plotselected" and spews out +```{ xaxis: { from: -10, to: 20 } ... },``` setSelection in which the +parameters are on a new form (backwards compatible hooks are in place so old +code shouldn't break) and markings (formerly coloredAreas). + +## Changes ## + + - Added support for specifying the size of tick labels (axis.labelWidth, + axis.labelHeight). Useful for specifying a max label size to keep multiple + plots aligned. + + - The "fill" option can now be a number that specifies the opacity of the + fill. + + - You can now specify a coordinate as null (like [2, null]) and Flot will + take the other coordinate into account when scaling the axes. (based on + patch by joebno) + + - New option for bars "align". Set it to "center" to center the bars on the + value they represent. + + - setSelection now takes a second parameter which you can use to prevent the + method from firing the "plotselected" handler. + + - Improved the handling of axis auto-scaling with bars. + +## Bug fixes ## + + - Fixed a bug in calculating spacing around the plot. (reported by + timothytoe) + + - Fixed a bug in finding max values for all-negative data sets. + + - Prevent the possibility of eternal looping in tick calculations. + + - Fixed a bug when borderWidth is set to 0. (reported by Rob/sanchothefat) + + - Fixed a bug with drawing bars extending below 0. (reported by James Hewitt, + patch by Ryan Funduk). + + - Fixed a bug with line widths of bars. (reported by MikeM) + + - Fixed a bug with 'nw' and 'sw' legend positions. + + - Fixed a bug with multi-line x-axis tick labels. (reported by Luca Ciano, + IE-fix help by Savage Zhang) + + - Using the "container" option in legend now overwrites the container element + instead of just appending to it, fixing the infinite legend bug. (reported + by several people, fix by Brad Dewey) + + + +## Flot 0.4 ## + +### API changes ### + +Deprecated axis.noTicks in favor of just specifying the number as axis.ticks. +So ```xaxis: { noTicks: 10 }``` becomes ```xaxis: { ticks: 10 }```. + +Time series support. Specify axis.mode: "time", put in Javascript timestamps +as data, and Flot will automatically spit out sensible ticks. Take a look at +the two new examples. The format can be customized with axis.timeformat and +axis.monthNames, or if that fails with axis.tickFormatter. + +Support for colored background areas via grid.coloredAreas. Specify an array +of { x1, y1, x2, y2 } objects or a function that returns these given +{ xmin, xmax, ymin, ymax }. + +More members on the plot object (report by Chris Davies and others). +"getData" for inspecting the assigned settings on data series (e.g. color) and +"setData", "setupGrid" and "draw" for updating the contents without a total +replot. + +The default number of ticks to aim for is now dependent on the size of the +plot in pixels. Support for customizing tick interval sizes directly with +axis.minTickSize and axis.tickSize. + +Cleaned up the automatic axis scaling algorithm and fixed how it interacts +with ticks. Also fixed a couple of tick-related corner case bugs (one reported +by mainstreetmark, another reported by timothytoe). + +The option axis.tickFormatter now takes a function with two parameters, the +second parameter is an optional object with information about the axis. It has +min, max, tickDecimals, tickSize. + +## Changes ## + + - Added support for segmented lines. (based on patch from Michael MacDonald) + + - Added support for ignoring null and bad values. (suggestion from Nick + Konidaris and joshwaihi) + + - Added support for changing the border width. (thanks to joebno and safoo) + + - Label colors can be changed via CSS by selecting the tickLabel class. + +## Bug fixes ## + + - Fixed a bug in handling single-item bar series. (reported by Emil Filipov) + + - Fixed erratic behaviour when interacting with the plot with IE 7. (reported + by Lau Bech Lauritzen). + + - Prevent IE/Safari text selection when selecting stuff on the canvas. + + + +## Flot 0.3 ## + +This is mostly a quick-fix release because jquery.js wasn't included in the +previous zip/tarball. + +## Changes ## + + - Include jquery.js in the zip/tarball. + + - Support clicking on the plot. Turn it on with grid: { clickable: true }, + then you get a "plotclick" event on the graph placeholder with the position + in units of the plot. + +## Bug fixes ## + + - Fixed a bug in dealing with data where min = max. (thanks to Michael + Messinides) + + + +## Flot 0.2 ## + +The API should now be fully documented. + +### API changes ### + +Moved labelMargin option to grid from x/yaxis. + +## Changes ## + + - Added support for putting a background behind the default legend. The + default is the partly transparent background color. Added backgroundColor + and backgroundOpacity to the legend options to control this. + + - The ticks options can now be a callback function that takes one parameter, + an object with the attributes min and max. The function should return a + ticks array. + + - Added labelFormatter option in legend, useful for turning the legend + labels into links. + + - Reduced the size of the code. (patch by Guy Fraser) + + + +## Flot 0.1 ## + +First public release. diff --git a/monitoring/monitoring_ui/src/3dparty/flot/PLUGINS.md b/monitoring/monitoring_ui/src/3dparty/flot/PLUGINS.md new file mode 100644 index 0000000000000000000000000000000000000000..b5bf3002033b99f67bf8bae9e90c5050512a24f6 --- /dev/null +++ b/monitoring/monitoring_ui/src/3dparty/flot/PLUGINS.md @@ -0,0 +1,143 @@ +## Writing plugins ## + +All you need to do to make a new plugin is creating an init function +and a set of options (if needed), stuffing it into an object and +putting it in the $.plot.plugins array. For example: + +```js +function myCoolPluginInit(plot) { + plot.coolstring = "Hello!"; +}; + +$.plot.plugins.push({ init: myCoolPluginInit, options: { ... } }); + +// if $.plot is called, it will return a plot object with the +// attribute "coolstring" +``` + +Now, given that the plugin might run in many different places, it's +a good idea to avoid leaking names. The usual trick here is wrap the +above lines in an anonymous function which is called immediately, like +this: (function () { inner code ... })(). To make it even more robust +in case $ is not bound to jQuery but some other Javascript library, we +can write it as + +```js +(function ($) { + // plugin definition + // ... +})(jQuery); +``` + +There's a complete example below, but you should also check out the +plugins bundled with Flot. + + +## Complete example ## + +Here is a simple debug plugin which alerts each of the series in the +plot. It has a single option that control whether it is enabled and +how much info to output: + +```js +(function ($) { + function init(plot) { + var debugLevel = 1; + + function checkDebugEnabled(plot, options) { + if (options.debug) { + debugLevel = options.debug; + plot.hooks.processDatapoints.push(alertSeries); + } + } + + function alertSeries(plot, series, datapoints) { + var msg = "series " + series.label; + if (debugLevel > 1) { + msg += " with " + series.data.length + " points"; + alert(msg); + } + } + + plot.hooks.processOptions.push(checkDebugEnabled); + } + + var options = { debug: 0 }; + + $.plot.plugins.push({ + init: init, + options: options, + name: "simpledebug", + version: "0.1" + }); +})(jQuery); +``` + +We also define "name" and "version". It's not used by Flot, but might +be helpful for other plugins in resolving dependencies. + +Put the above in a file named "jquery.flot.debug.js", include it in an +HTML page and then it can be used with: + +```js + $.plot($("#placeholder"), [...], { debug: 2 }); +``` + +This simple plugin illustrates a couple of points: + + - It uses the anonymous function trick to avoid name pollution. + - It can be enabled/disabled through an option. + - Variables in the init function can be used to store plot-specific + state between the hooks. + +The two last points are important because there may be multiple plots +on the same page, and you'd want to make sure they are not mixed up. + + +## Shutting down a plugin ## + +Each plot object has a shutdown hook which is run when plot.shutdown() +is called. This usually mostly happens in case another plot is made on +top of an existing one. + +The purpose of the hook is to give you a chance to unbind any event +handlers you've registered and remove any extra DOM things you've +inserted. + +The problem with event handlers is that you can have registered a +handler which is run in some point in the future, e.g. with +setTimeout(). Meanwhile, the plot may have been shutdown and removed, +but because your event handler is still referencing it, it can't be +garbage collected yet, and worse, if your handler eventually runs, it +may overwrite stuff on a completely different plot. + + +## Some hints on the options ## + +Plugins should always support appropriate options to enable/disable +them because the plugin user may have several plots on the same page +where only one should use the plugin. In most cases it's probably a +good idea if the plugin is turned off rather than on per default, just +like most of the powerful features in Flot. + +If the plugin needs options that are specific to each series, like the +points or lines options in core Flot, you can put them in "series" in +the options object, e.g. + +```js +var options = { + series: { + downsample: { + algorithm: null, + maxpoints: 1000 + } + } +} +``` + +Then they will be copied by Flot into each series, providing default +values in case none are specified. + +Think hard and long about naming the options. These names are going to +be public API, and code is going to depend on them if the plugin is +successful. diff --git a/monitoring/monitoring_ui/src/3dparty/flot/README.md b/monitoring/monitoring_ui/src/3dparty/flot/README.md new file mode 100644 index 0000000000000000000000000000000000000000..a8f70640a6b4a72ec2e5848d38ec63c792a0c92f --- /dev/null +++ b/monitoring/monitoring_ui/src/3dparty/flot/README.md @@ -0,0 +1,110 @@ +# Flot [](https://travis-ci.org/flot/flot) + +## About ## + +Flot is a Javascript plotting library for jQuery. +Read more at the website: <http://www.flotcharts.org/> + +Take a look at the the examples in examples/index.html; they should give a good +impression of what Flot can do, and the source code of the examples is probably +the fastest way to learn how to use Flot. + + +## Installation ## + +Just include the Javascript file after you've included jQuery. + +Generally, all browsers that support the HTML5 canvas tag are +supported. + +For support for Internet Explorer < 9, you can use [Excanvas] +[excanvas], a canvas emulator; this is used in the examples bundled +with Flot. You just include the excanvas script like this: + +```html +<!--[if lte IE 8]><script language="javascript" type="text/javascript" src="excanvas.min.js"></script><![endif]--> +``` + +If it's not working on your development IE 6.0, check that it has +support for VML which Excanvas is relying on. It appears that some +stripped down versions used for test environments on virtual machines +lack the VML support. + +You can also try using [Flashcanvas][flashcanvas], which uses Flash to +do the emulation. Although Flash can be a bit slower to load than VML, +if you've got a lot of points, the Flash version can be much faster +overall. Flot contains some wrapper code for activating Excanvas which +Flashcanvas is compatible with. + +You need at least jQuery 1.2.6, but try at least 1.3.2 for interactive +charts because of performance improvements in event handling. + + +## Basic usage ## + +Create a placeholder div to put the graph in: + +```html +<div id="placeholder"></div> +``` + +You need to set the width and height of this div, otherwise the plot +library doesn't know how to scale the graph. You can do it inline like +this: + +```html +<div id="placeholder" style="width:600px;height:300px"></div> +``` + +You can also do it with an external stylesheet. Make sure that the +placeholder isn't within something with a display:none CSS property - +in that case, Flot has trouble measuring label dimensions which +results in garbled looks and might have trouble measuring the +placeholder dimensions which is fatal (it'll throw an exception). + +Then when the div is ready in the DOM, which is usually on document +ready, run the plot function: + +```js +$.plot($("#placeholder"), data, options); +``` + +Here, data is an array of data series and options is an object with +settings if you want to customize the plot. Take a look at the +examples for some ideas of what to put in or look at the +[API reference](API.md). Here's a quick example that'll draw a line +from (0, 0) to (1, 1): + +```js +$.plot($("#placeholder"), [ [[0, 0], [1, 1]] ], { yaxis: { max: 1 } }); +``` + +The plot function immediately draws the chart and then returns a plot +object with a couple of methods. + + +## What's with the name? ## + +First: it's pronounced with a short o, like "plot". Not like "flawed". + +So "Flot" rhymes with "plot". + +And if you look up "flot" in a Danish-to-English dictionary, some of +the words that come up are "good-looking", "attractive", "stylish", +"smart", "impressive", "extravagant". One of the main goals with Flot +is pretty looks. + + +## Notes about the examples ## + +In order to have a useful, functional example of time-series plots using time +zones, date.js from [timezone-js][timezone-js] (released under the Apache 2.0 +license) and the [Olson][olson] time zone database (released to the public +domain) have been included in the examples directory. They are used in +examples/axes-time-zones/index.html. + + +[excanvas]: http://code.google.com/p/explorercanvas/ +[flashcanvas]: http://code.google.com/p/flashcanvas/ +[timezone-js]: https://github.com/mde/timezone-js +[olson]: http://ftp.iana.org/time-zones diff --git a/monitoring/monitoring_ui/src/3dparty/flot/component.json b/monitoring/monitoring_ui/src/3dparty/flot/component.json new file mode 100644 index 0000000000000000000000000000000000000000..596117235528eef1a24a329e68df599f55eba9c1 --- /dev/null +++ b/monitoring/monitoring_ui/src/3dparty/flot/component.json @@ -0,0 +1,8 @@ +{ + "name": "Flot", + "version": "0.8.3", + "main": "jquery.flot.js", + "dependencies": { + "jquery": ">= 1.2.6" + } +} diff --git a/monitoring/monitoring_ui/src/3dparty/flot/excanvas.js b/monitoring/monitoring_ui/src/3dparty/flot/excanvas.js new file mode 100644 index 0000000000000000000000000000000000000000..70a8f25ca86ad64f14dc2e6d062320ced8cb9263 --- /dev/null +++ b/monitoring/monitoring_ui/src/3dparty/flot/excanvas.js @@ -0,0 +1,1428 @@ +// Copyright 2006 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +// Known Issues: +// +// * Patterns only support repeat. +// * Radial gradient are not implemented. The VML version of these look very +// different from the canvas one. +// * Clipping paths are not implemented. +// * Coordsize. The width and height attribute have higher priority than the +// width and height style values which isn't correct. +// * Painting mode isn't implemented. +// * Canvas width/height should is using content-box by default. IE in +// Quirks mode will draw the canvas using border-box. Either change your +// doctype to HTML5 +// (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype) +// or use Box Sizing Behavior from WebFX +// (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html) +// * Non uniform scaling does not correctly scale strokes. +// * Filling very large shapes (above 5000 points) is buggy. +// * Optimize. There is always room for speed improvements. + +// Only add this code if we do not already have a canvas implementation +if (!document.createElement('canvas').getContext) { + +(function() { + + // alias some functions to make (compiled) code shorter + var m = Math; + var mr = m.round; + var ms = m.sin; + var mc = m.cos; + var abs = m.abs; + var sqrt = m.sqrt; + + // this is used for sub pixel precision + var Z = 10; + var Z2 = Z / 2; + + var IE_VERSION = +navigator.userAgent.match(/MSIE ([\d.]+)?/)[1]; + + /** + * This funtion is assigned to the <canvas> elements as element.getContext(). + * @this {HTMLElement} + * @return {CanvasRenderingContext2D_} + */ + function getContext() { + return this.context_ || + (this.context_ = new CanvasRenderingContext2D_(this)); + } + + var slice = Array.prototype.slice; + + /** + * Binds a function to an object. The returned function will always use the + * passed in {@code obj} as {@code this}. + * + * Example: + * + * g = bind(f, obj, a, b) + * g(c, d) // will do f.call(obj, a, b, c, d) + * + * @param {Function} f The function to bind the object to + * @param {Object} obj The object that should act as this when the function + * is called + * @param {*} var_args Rest arguments that will be used as the initial + * arguments when the function is called + * @return {Function} A new function that has bound this + */ + function bind(f, obj, var_args) { + var a = slice.call(arguments, 2); + return function() { + return f.apply(obj, a.concat(slice.call(arguments))); + }; + } + + function encodeHtmlAttribute(s) { + return String(s).replace(/&/g, '&').replace(/"/g, '"'); + } + + function addNamespace(doc, prefix, urn) { + if (!doc.namespaces[prefix]) { + doc.namespaces.add(prefix, urn, '#default#VML'); + } + } + + function addNamespacesAndStylesheet(doc) { + addNamespace(doc, 'g_vml_', 'urn:schemas-microsoft-com:vml'); + addNamespace(doc, 'g_o_', 'urn:schemas-microsoft-com:office:office'); + + // Setup default CSS. Only add one style sheet per document + if (!doc.styleSheets['ex_canvas_']) { + var ss = doc.createStyleSheet(); + ss.owningElement.id = 'ex_canvas_'; + ss.cssText = 'canvas{display:inline-block;overflow:hidden;' + + // default size is 300x150 in Gecko and Opera + 'text-align:left;width:300px;height:150px}'; + } + } + + // Add namespaces and stylesheet at startup. + addNamespacesAndStylesheet(document); + + var G_vmlCanvasManager_ = { + init: function(opt_doc) { + var doc = opt_doc || document; + // Create a dummy element so that IE will allow canvas elements to be + // recognized. + doc.createElement('canvas'); + doc.attachEvent('onreadystatechange', bind(this.init_, this, doc)); + }, + + init_: function(doc) { + // find all canvas elements + var els = doc.getElementsByTagName('canvas'); + for (var i = 0; i < els.length; i++) { + this.initElement(els[i]); + } + }, + + /** + * Public initializes a canvas element so that it can be used as canvas + * element from now on. This is called automatically before the page is + * loaded but if you are creating elements using createElement you need to + * make sure this is called on the element. + * @param {HTMLElement} el The canvas element to initialize. + * @return {HTMLElement} the element that was created. + */ + initElement: function(el) { + if (!el.getContext) { + el.getContext = getContext; + + // Add namespaces and stylesheet to document of the element. + addNamespacesAndStylesheet(el.ownerDocument); + + // Remove fallback content. There is no way to hide text nodes so we + // just remove all childNodes. We could hide all elements and remove + // text nodes but who really cares about the fallback content. + el.innerHTML = ''; + + // do not use inline function because that will leak memory + el.attachEvent('onpropertychange', onPropertyChange); + el.attachEvent('onresize', onResize); + + var attrs = el.attributes; + if (attrs.width && attrs.width.specified) { + // TODO: use runtimeStyle and coordsize + // el.getContext().setWidth_(attrs.width.nodeValue); + el.style.width = attrs.width.nodeValue + 'px'; + } else { + el.width = el.clientWidth; + } + if (attrs.height && attrs.height.specified) { + // TODO: use runtimeStyle and coordsize + // el.getContext().setHeight_(attrs.height.nodeValue); + el.style.height = attrs.height.nodeValue + 'px'; + } else { + el.height = el.clientHeight; + } + //el.getContext().setCoordsize_() + } + return el; + } + }; + + function onPropertyChange(e) { + var el = e.srcElement; + + switch (e.propertyName) { + case 'width': + el.getContext().clearRect(); + el.style.width = el.attributes.width.nodeValue + 'px'; + // In IE8 this does not trigger onresize. + el.firstChild.style.width = el.clientWidth + 'px'; + break; + case 'height': + el.getContext().clearRect(); + el.style.height = el.attributes.height.nodeValue + 'px'; + el.firstChild.style.height = el.clientHeight + 'px'; + break; + } + } + + function onResize(e) { + var el = e.srcElement; + if (el.firstChild) { + el.firstChild.style.width = el.clientWidth + 'px'; + el.firstChild.style.height = el.clientHeight + 'px'; + } + } + + G_vmlCanvasManager_.init(); + + // precompute "00" to "FF" + var decToHex = []; + for (var i = 0; i < 16; i++) { + for (var j = 0; j < 16; j++) { + decToHex[i * 16 + j] = i.toString(16) + j.toString(16); + } + } + + function createMatrixIdentity() { + return [ + [1, 0, 0], + [0, 1, 0], + [0, 0, 1] + ]; + } + + function matrixMultiply(m1, m2) { + var result = createMatrixIdentity(); + + for (var x = 0; x < 3; x++) { + for (var y = 0; y < 3; y++) { + var sum = 0; + + for (var z = 0; z < 3; z++) { + sum += m1[x][z] * m2[z][y]; + } + + result[x][y] = sum; + } + } + return result; + } + + function copyState(o1, o2) { + o2.fillStyle = o1.fillStyle; + o2.lineCap = o1.lineCap; + o2.lineJoin = o1.lineJoin; + o2.lineWidth = o1.lineWidth; + o2.miterLimit = o1.miterLimit; + o2.shadowBlur = o1.shadowBlur; + o2.shadowColor = o1.shadowColor; + o2.shadowOffsetX = o1.shadowOffsetX; + o2.shadowOffsetY = o1.shadowOffsetY; + o2.strokeStyle = o1.strokeStyle; + o2.globalAlpha = o1.globalAlpha; + o2.font = o1.font; + o2.textAlign = o1.textAlign; + o2.textBaseline = o1.textBaseline; + o2.arcScaleX_ = o1.arcScaleX_; + o2.arcScaleY_ = o1.arcScaleY_; + o2.lineScale_ = o1.lineScale_; + } + + var colorData = { + aliceblue: '#F0F8FF', + antiquewhite: '#FAEBD7', + aquamarine: '#7FFFD4', + azure: '#F0FFFF', + beige: '#F5F5DC', + bisque: '#FFE4C4', + black: '#000000', + blanchedalmond: '#FFEBCD', + blueviolet: '#8A2BE2', + brown: '#A52A2A', + burlywood: '#DEB887', + cadetblue: '#5F9EA0', + chartreuse: '#7FFF00', + chocolate: '#D2691E', + coral: '#FF7F50', + cornflowerblue: '#6495ED', + cornsilk: '#FFF8DC', + crimson: '#DC143C', + cyan: '#00FFFF', + darkblue: '#00008B', + darkcyan: '#008B8B', + darkgoldenrod: '#B8860B', + darkgray: '#A9A9A9', + darkgreen: '#006400', + darkgrey: '#A9A9A9', + darkkhaki: '#BDB76B', + darkmagenta: '#8B008B', + darkolivegreen: '#556B2F', + darkorange: '#FF8C00', + darkorchid: '#9932CC', + darkred: '#8B0000', + darksalmon: '#E9967A', + darkseagreen: '#8FBC8F', + darkslateblue: '#483D8B', + darkslategray: '#2F4F4F', + darkslategrey: '#2F4F4F', + darkturquoise: '#00CED1', + darkviolet: '#9400D3', + deeppink: '#FF1493', + deepskyblue: '#00BFFF', + dimgray: '#696969', + dimgrey: '#696969', + dodgerblue: '#1E90FF', + firebrick: '#B22222', + floralwhite: '#FFFAF0', + forestgreen: '#228B22', + gainsboro: '#DCDCDC', + ghostwhite: '#F8F8FF', + gold: '#FFD700', + goldenrod: '#DAA520', + grey: '#808080', + greenyellow: '#ADFF2F', + honeydew: '#F0FFF0', + hotpink: '#FF69B4', + indianred: '#CD5C5C', + indigo: '#4B0082', + ivory: '#FFFFF0', + khaki: '#F0E68C', + lavender: '#E6E6FA', + lavenderblush: '#FFF0F5', + lawngreen: '#7CFC00', + lemonchiffon: '#FFFACD', + lightblue: '#ADD8E6', + lightcoral: '#F08080', + lightcyan: '#E0FFFF', + lightgoldenrodyellow: '#FAFAD2', + lightgreen: '#90EE90', + lightgrey: '#D3D3D3', + lightpink: '#FFB6C1', + lightsalmon: '#FFA07A', + lightseagreen: '#20B2AA', + lightskyblue: '#87CEFA', + lightslategray: '#778899', + lightslategrey: '#778899', + lightsteelblue: '#B0C4DE', + lightyellow: '#FFFFE0', + limegreen: '#32CD32', + linen: '#FAF0E6', + magenta: '#FF00FF', + mediumaquamarine: '#66CDAA', + mediumblue: '#0000CD', + mediumorchid: '#BA55D3', + mediumpurple: '#9370DB', + mediumseagreen: '#3CB371', + mediumslateblue: '#7B68EE', + mediumspringgreen: '#00FA9A', + mediumturquoise: '#48D1CC', + mediumvioletred: '#C71585', + midnightblue: '#191970', + mintcream: '#F5FFFA', + mistyrose: '#FFE4E1', + moccasin: '#FFE4B5', + navajowhite: '#FFDEAD', + oldlace: '#FDF5E6', + olivedrab: '#6B8E23', + orange: '#FFA500', + orangered: '#FF4500', + orchid: '#DA70D6', + palegoldenrod: '#EEE8AA', + palegreen: '#98FB98', + paleturquoise: '#AFEEEE', + palevioletred: '#DB7093', + papayawhip: '#FFEFD5', + peachpuff: '#FFDAB9', + peru: '#CD853F', + pink: '#FFC0CB', + plum: '#DDA0DD', + powderblue: '#B0E0E6', + rosybrown: '#BC8F8F', + royalblue: '#4169E1', + saddlebrown: '#8B4513', + salmon: '#FA8072', + sandybrown: '#F4A460', + seagreen: '#2E8B57', + seashell: '#FFF5EE', + sienna: '#A0522D', + skyblue: '#87CEEB', + slateblue: '#6A5ACD', + slategray: '#708090', + slategrey: '#708090', + snow: '#FFFAFA', + springgreen: '#00FF7F', + steelblue: '#4682B4', + tan: '#D2B48C', + thistle: '#D8BFD8', + tomato: '#FF6347', + turquoise: '#40E0D0', + violet: '#EE82EE', + wheat: '#F5DEB3', + whitesmoke: '#F5F5F5', + yellowgreen: '#9ACD32' + }; + + + function getRgbHslContent(styleString) { + var start = styleString.indexOf('(', 3); + var end = styleString.indexOf(')', start + 1); + var parts = styleString.substring(start + 1, end).split(','); + // add alpha if needed + if (parts.length != 4 || styleString.charAt(3) != 'a') { + parts[3] = 1; + } + return parts; + } + + function percent(s) { + return parseFloat(s) / 100; + } + + function clamp(v, min, max) { + return Math.min(max, Math.max(min, v)); + } + + function hslToRgb(parts){ + var r, g, b, h, s, l; + h = parseFloat(parts[0]) / 360 % 360; + if (h < 0) + h++; + s = clamp(percent(parts[1]), 0, 1); + l = clamp(percent(parts[2]), 0, 1); + if (s == 0) { + r = g = b = l; // achromatic + } else { + var q = l < 0.5 ? l * (1 + s) : l + s - l * s; + var p = 2 * l - q; + r = hueToRgb(p, q, h + 1 / 3); + g = hueToRgb(p, q, h); + b = hueToRgb(p, q, h - 1 / 3); + } + + return '#' + decToHex[Math.floor(r * 255)] + + decToHex[Math.floor(g * 255)] + + decToHex[Math.floor(b * 255)]; + } + + function hueToRgb(m1, m2, h) { + if (h < 0) + h++; + if (h > 1) + h--; + + if (6 * h < 1) + return m1 + (m2 - m1) * 6 * h; + else if (2 * h < 1) + return m2; + else if (3 * h < 2) + return m1 + (m2 - m1) * (2 / 3 - h) * 6; + else + return m1; + } + + var processStyleCache = {}; + + function processStyle(styleString) { + if (styleString in processStyleCache) { + return processStyleCache[styleString]; + } + + var str, alpha = 1; + + styleString = String(styleString); + if (styleString.charAt(0) == '#') { + str = styleString; + } else if (/^rgb/.test(styleString)) { + var parts = getRgbHslContent(styleString); + var str = '#', n; + for (var i = 0; i < 3; i++) { + if (parts[i].indexOf('%') != -1) { + n = Math.floor(percent(parts[i]) * 255); + } else { + n = +parts[i]; + } + str += decToHex[clamp(n, 0, 255)]; + } + alpha = +parts[3]; + } else if (/^hsl/.test(styleString)) { + var parts = getRgbHslContent(styleString); + str = hslToRgb(parts); + alpha = parts[3]; + } else { + str = colorData[styleString] || styleString; + } + return processStyleCache[styleString] = {color: str, alpha: alpha}; + } + + var DEFAULT_STYLE = { + style: 'normal', + variant: 'normal', + weight: 'normal', + size: 10, + family: 'sans-serif' + }; + + // Internal text style cache + var fontStyleCache = {}; + + function processFontStyle(styleString) { + if (fontStyleCache[styleString]) { + return fontStyleCache[styleString]; + } + + var el = document.createElement('div'); + var style = el.style; + try { + style.font = styleString; + } catch (ex) { + // Ignore failures to set to invalid font. + } + + return fontStyleCache[styleString] = { + style: style.fontStyle || DEFAULT_STYLE.style, + variant: style.fontVariant || DEFAULT_STYLE.variant, + weight: style.fontWeight || DEFAULT_STYLE.weight, + size: style.fontSize || DEFAULT_STYLE.size, + family: style.fontFamily || DEFAULT_STYLE.family + }; + } + + function getComputedStyle(style, element) { + var computedStyle = {}; + + for (var p in style) { + computedStyle[p] = style[p]; + } + + // Compute the size + var canvasFontSize = parseFloat(element.currentStyle.fontSize), + fontSize = parseFloat(style.size); + + if (typeof style.size == 'number') { + computedStyle.size = style.size; + } else if (style.size.indexOf('px') != -1) { + computedStyle.size = fontSize; + } else if (style.size.indexOf('em') != -1) { + computedStyle.size = canvasFontSize * fontSize; + } else if(style.size.indexOf('%') != -1) { + computedStyle.size = (canvasFontSize / 100) * fontSize; + } else if (style.size.indexOf('pt') != -1) { + computedStyle.size = fontSize / .75; + } else { + computedStyle.size = canvasFontSize; + } + + // Different scaling between normal text and VML text. This was found using + // trial and error to get the same size as non VML text. + computedStyle.size *= 0.981; + + return computedStyle; + } + + function buildStyle(style) { + return style.style + ' ' + style.variant + ' ' + style.weight + ' ' + + style.size + 'px ' + style.family; + } + + var lineCapMap = { + 'butt': 'flat', + 'round': 'round' + }; + + function processLineCap(lineCap) { + return lineCapMap[lineCap] || 'square'; + } + + /** + * This class implements CanvasRenderingContext2D interface as described by + * the WHATWG. + * @param {HTMLElement} canvasElement The element that the 2D context should + * be associated with + */ + function CanvasRenderingContext2D_(canvasElement) { + this.m_ = createMatrixIdentity(); + + this.mStack_ = []; + this.aStack_ = []; + this.currentPath_ = []; + + // Canvas context properties + this.strokeStyle = '#000'; + this.fillStyle = '#000'; + + this.lineWidth = 1; + this.lineJoin = 'miter'; + this.lineCap = 'butt'; + this.miterLimit = Z * 1; + this.globalAlpha = 1; + this.font = '10px sans-serif'; + this.textAlign = 'left'; + this.textBaseline = 'alphabetic'; + this.canvas = canvasElement; + + var cssText = 'width:' + canvasElement.clientWidth + 'px;height:' + + canvasElement.clientHeight + 'px;overflow:hidden;position:absolute'; + var el = canvasElement.ownerDocument.createElement('div'); + el.style.cssText = cssText; + canvasElement.appendChild(el); + + var overlayEl = el.cloneNode(false); + // Use a non transparent background. + overlayEl.style.backgroundColor = 'red'; + overlayEl.style.filter = 'alpha(opacity=0)'; + canvasElement.appendChild(overlayEl); + + this.element_ = el; + this.arcScaleX_ = 1; + this.arcScaleY_ = 1; + this.lineScale_ = 1; + } + + var contextPrototype = CanvasRenderingContext2D_.prototype; + contextPrototype.clearRect = function() { + if (this.textMeasureEl_) { + this.textMeasureEl_.removeNode(true); + this.textMeasureEl_ = null; + } + this.element_.innerHTML = ''; + }; + + contextPrototype.beginPath = function() { + // TODO: Branch current matrix so that save/restore has no effect + // as per safari docs. + this.currentPath_ = []; + }; + + contextPrototype.moveTo = function(aX, aY) { + var p = getCoords(this, aX, aY); + this.currentPath_.push({type: 'moveTo', x: p.x, y: p.y}); + this.currentX_ = p.x; + this.currentY_ = p.y; + }; + + contextPrototype.lineTo = function(aX, aY) { + var p = getCoords(this, aX, aY); + this.currentPath_.push({type: 'lineTo', x: p.x, y: p.y}); + + this.currentX_ = p.x; + this.currentY_ = p.y; + }; + + contextPrototype.bezierCurveTo = function(aCP1x, aCP1y, + aCP2x, aCP2y, + aX, aY) { + var p = getCoords(this, aX, aY); + var cp1 = getCoords(this, aCP1x, aCP1y); + var cp2 = getCoords(this, aCP2x, aCP2y); + bezierCurveTo(this, cp1, cp2, p); + }; + + // Helper function that takes the already fixed cordinates. + function bezierCurveTo(self, cp1, cp2, p) { + self.currentPath_.push({ + type: 'bezierCurveTo', + cp1x: cp1.x, + cp1y: cp1.y, + cp2x: cp2.x, + cp2y: cp2.y, + x: p.x, + y: p.y + }); + self.currentX_ = p.x; + self.currentY_ = p.y; + } + + contextPrototype.quadraticCurveTo = function(aCPx, aCPy, aX, aY) { + // the following is lifted almost directly from + // http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes + + var cp = getCoords(this, aCPx, aCPy); + var p = getCoords(this, aX, aY); + + var cp1 = { + x: this.currentX_ + 2.0 / 3.0 * (cp.x - this.currentX_), + y: this.currentY_ + 2.0 / 3.0 * (cp.y - this.currentY_) + }; + var cp2 = { + x: cp1.x + (p.x - this.currentX_) / 3.0, + y: cp1.y + (p.y - this.currentY_) / 3.0 + }; + + bezierCurveTo(this, cp1, cp2, p); + }; + + contextPrototype.arc = function(aX, aY, aRadius, + aStartAngle, aEndAngle, aClockwise) { + aRadius *= Z; + var arcType = aClockwise ? 'at' : 'wa'; + + var xStart = aX + mc(aStartAngle) * aRadius - Z2; + var yStart = aY + ms(aStartAngle) * aRadius - Z2; + + var xEnd = aX + mc(aEndAngle) * aRadius - Z2; + var yEnd = aY + ms(aEndAngle) * aRadius - Z2; + + // IE won't render arches drawn counter clockwise if xStart == xEnd. + if (xStart == xEnd && !aClockwise) { + xStart += 0.125; // Offset xStart by 1/80 of a pixel. Use something + // that can be represented in binary + } + + var p = getCoords(this, aX, aY); + var pStart = getCoords(this, xStart, yStart); + var pEnd = getCoords(this, xEnd, yEnd); + + this.currentPath_.push({type: arcType, + x: p.x, + y: p.y, + radius: aRadius, + xStart: pStart.x, + yStart: pStart.y, + xEnd: pEnd.x, + yEnd: pEnd.y}); + + }; + + contextPrototype.rect = function(aX, aY, aWidth, aHeight) { + this.moveTo(aX, aY); + this.lineTo(aX + aWidth, aY); + this.lineTo(aX + aWidth, aY + aHeight); + this.lineTo(aX, aY + aHeight); + this.closePath(); + }; + + contextPrototype.strokeRect = function(aX, aY, aWidth, aHeight) { + var oldPath = this.currentPath_; + this.beginPath(); + + this.moveTo(aX, aY); + this.lineTo(aX + aWidth, aY); + this.lineTo(aX + aWidth, aY + aHeight); + this.lineTo(aX, aY + aHeight); + this.closePath(); + this.stroke(); + + this.currentPath_ = oldPath; + }; + + contextPrototype.fillRect = function(aX, aY, aWidth, aHeight) { + var oldPath = this.currentPath_; + this.beginPath(); + + this.moveTo(aX, aY); + this.lineTo(aX + aWidth, aY); + this.lineTo(aX + aWidth, aY + aHeight); + this.lineTo(aX, aY + aHeight); + this.closePath(); + this.fill(); + + this.currentPath_ = oldPath; + }; + + contextPrototype.createLinearGradient = function(aX0, aY0, aX1, aY1) { + var gradient = new CanvasGradient_('gradient'); + gradient.x0_ = aX0; + gradient.y0_ = aY0; + gradient.x1_ = aX1; + gradient.y1_ = aY1; + return gradient; + }; + + contextPrototype.createRadialGradient = function(aX0, aY0, aR0, + aX1, aY1, aR1) { + var gradient = new CanvasGradient_('gradientradial'); + gradient.x0_ = aX0; + gradient.y0_ = aY0; + gradient.r0_ = aR0; + gradient.x1_ = aX1; + gradient.y1_ = aY1; + gradient.r1_ = aR1; + return gradient; + }; + + contextPrototype.drawImage = function(image, var_args) { + var dx, dy, dw, dh, sx, sy, sw, sh; + + // to find the original width we overide the width and height + var oldRuntimeWidth = image.runtimeStyle.width; + var oldRuntimeHeight = image.runtimeStyle.height; + image.runtimeStyle.width = 'auto'; + image.runtimeStyle.height = 'auto'; + + // get the original size + var w = image.width; + var h = image.height; + + // and remove overides + image.runtimeStyle.width = oldRuntimeWidth; + image.runtimeStyle.height = oldRuntimeHeight; + + if (arguments.length == 3) { + dx = arguments[1]; + dy = arguments[2]; + sx = sy = 0; + sw = dw = w; + sh = dh = h; + } else if (arguments.length == 5) { + dx = arguments[1]; + dy = arguments[2]; + dw = arguments[3]; + dh = arguments[4]; + sx = sy = 0; + sw = w; + sh = h; + } else if (arguments.length == 9) { + sx = arguments[1]; + sy = arguments[2]; + sw = arguments[3]; + sh = arguments[4]; + dx = arguments[5]; + dy = arguments[6]; + dw = arguments[7]; + dh = arguments[8]; + } else { + throw Error('Invalid number of arguments'); + } + + var d = getCoords(this, dx, dy); + + var w2 = sw / 2; + var h2 = sh / 2; + + var vmlStr = []; + + var W = 10; + var H = 10; + + // For some reason that I've now forgotten, using divs didn't work + vmlStr.push(' <g_vml_:group', + ' coordsize="', Z * W, ',', Z * H, '"', + ' coordorigin="0,0"' , + ' style="width:', W, 'px;height:', H, 'px;position:absolute;'); + + // If filters are necessary (rotation exists), create them + // filters are bog-slow, so only create them if abbsolutely necessary + // The following check doesn't account for skews (which don't exist + // in the canvas spec (yet) anyway. + + if (this.m_[0][0] != 1 || this.m_[0][1] || + this.m_[1][1] != 1 || this.m_[1][0]) { + var filter = []; + + // Note the 12/21 reversal + filter.push('M11=', this.m_[0][0], ',', + 'M12=', this.m_[1][0], ',', + 'M21=', this.m_[0][1], ',', + 'M22=', this.m_[1][1], ',', + 'Dx=', mr(d.x / Z), ',', + 'Dy=', mr(d.y / Z), ''); + + // Bounding box calculation (need to minimize displayed area so that + // filters don't waste time on unused pixels. + var max = d; + var c2 = getCoords(this, dx + dw, dy); + var c3 = getCoords(this, dx, dy + dh); + var c4 = getCoords(this, dx + dw, dy + dh); + + max.x = m.max(max.x, c2.x, c3.x, c4.x); + max.y = m.max(max.y, c2.y, c3.y, c4.y); + + vmlStr.push('padding:0 ', mr(max.x / Z), 'px ', mr(max.y / Z), + 'px 0;filter:progid:DXImageTransform.Microsoft.Matrix(', + filter.join(''), ", sizingmethod='clip');"); + + } else { + vmlStr.push('top:', mr(d.y / Z), 'px;left:', mr(d.x / Z), 'px;'); + } + + vmlStr.push(' ">' , + '<g_vml_:image src="', image.src, '"', + ' style="width:', Z * dw, 'px;', + ' height:', Z * dh, 'px"', + ' cropleft="', sx / w, '"', + ' croptop="', sy / h, '"', + ' cropright="', (w - sx - sw) / w, '"', + ' cropbottom="', (h - sy - sh) / h, '"', + ' />', + '</g_vml_:group>'); + + this.element_.insertAdjacentHTML('BeforeEnd', vmlStr.join('')); + }; + + contextPrototype.stroke = function(aFill) { + var W = 10; + var H = 10; + // Divide the shape into chunks if it's too long because IE has a limit + // somewhere for how long a VML shape can be. This simple division does + // not work with fills, only strokes, unfortunately. + var chunkSize = 5000; + + var min = {x: null, y: null}; + var max = {x: null, y: null}; + + for (var j = 0; j < this.currentPath_.length; j += chunkSize) { + var lineStr = []; + var lineOpen = false; + + lineStr.push('<g_vml_:shape', + ' filled="', !!aFill, '"', + ' style="position:absolute;width:', W, 'px;height:', H, 'px;"', + ' coordorigin="0,0"', + ' coordsize="', Z * W, ',', Z * H, '"', + ' stroked="', !aFill, '"', + ' path="'); + + var newSeq = false; + + for (var i = j; i < Math.min(j + chunkSize, this.currentPath_.length); i++) { + if (i % chunkSize == 0 && i > 0) { // move into position for next chunk + lineStr.push(' m ', mr(this.currentPath_[i-1].x), ',', mr(this.currentPath_[i-1].y)); + } + + var p = this.currentPath_[i]; + var c; + + switch (p.type) { + case 'moveTo': + c = p; + lineStr.push(' m ', mr(p.x), ',', mr(p.y)); + break; + case 'lineTo': + lineStr.push(' l ', mr(p.x), ',', mr(p.y)); + break; + case 'close': + lineStr.push(' x '); + p = null; + break; + case 'bezierCurveTo': + lineStr.push(' c ', + mr(p.cp1x), ',', mr(p.cp1y), ',', + mr(p.cp2x), ',', mr(p.cp2y), ',', + mr(p.x), ',', mr(p.y)); + break; + case 'at': + case 'wa': + lineStr.push(' ', p.type, ' ', + mr(p.x - this.arcScaleX_ * p.radius), ',', + mr(p.y - this.arcScaleY_ * p.radius), ' ', + mr(p.x + this.arcScaleX_ * p.radius), ',', + mr(p.y + this.arcScaleY_ * p.radius), ' ', + mr(p.xStart), ',', mr(p.yStart), ' ', + mr(p.xEnd), ',', mr(p.yEnd)); + break; + } + + + // TODO: Following is broken for curves due to + // move to proper paths. + + // Figure out dimensions so we can do gradient fills + // properly + if (p) { + if (min.x == null || p.x < min.x) { + min.x = p.x; + } + if (max.x == null || p.x > max.x) { + max.x = p.x; + } + if (min.y == null || p.y < min.y) { + min.y = p.y; + } + if (max.y == null || p.y > max.y) { + max.y = p.y; + } + } + } + lineStr.push(' ">'); + + if (!aFill) { + appendStroke(this, lineStr); + } else { + appendFill(this, lineStr, min, max); + } + + lineStr.push('</g_vml_:shape>'); + + this.element_.insertAdjacentHTML('beforeEnd', lineStr.join('')); + } + }; + + function appendStroke(ctx, lineStr) { + var a = processStyle(ctx.strokeStyle); + var color = a.color; + var opacity = a.alpha * ctx.globalAlpha; + var lineWidth = ctx.lineScale_ * ctx.lineWidth; + + // VML cannot correctly render a line if the width is less than 1px. + // In that case, we dilute the color to make the line look thinner. + if (lineWidth < 1) { + opacity *= lineWidth; + } + + lineStr.push( + '<g_vml_:stroke', + ' opacity="', opacity, '"', + ' joinstyle="', ctx.lineJoin, '"', + ' miterlimit="', ctx.miterLimit, '"', + ' endcap="', processLineCap(ctx.lineCap), '"', + ' weight="', lineWidth, 'px"', + ' color="', color, '" />' + ); + } + + function appendFill(ctx, lineStr, min, max) { + var fillStyle = ctx.fillStyle; + var arcScaleX = ctx.arcScaleX_; + var arcScaleY = ctx.arcScaleY_; + var width = max.x - min.x; + var height = max.y - min.y; + if (fillStyle instanceof CanvasGradient_) { + // TODO: Gradients transformed with the transformation matrix. + var angle = 0; + var focus = {x: 0, y: 0}; + + // additional offset + var shift = 0; + // scale factor for offset + var expansion = 1; + + if (fillStyle.type_ == 'gradient') { + var x0 = fillStyle.x0_ / arcScaleX; + var y0 = fillStyle.y0_ / arcScaleY; + var x1 = fillStyle.x1_ / arcScaleX; + var y1 = fillStyle.y1_ / arcScaleY; + var p0 = getCoords(ctx, x0, y0); + var p1 = getCoords(ctx, x1, y1); + var dx = p1.x - p0.x; + var dy = p1.y - p0.y; + angle = Math.atan2(dx, dy) * 180 / Math.PI; + + // The angle should be a non-negative number. + if (angle < 0) { + angle += 360; + } + + // Very small angles produce an unexpected result because they are + // converted to a scientific notation string. + if (angle < 1e-6) { + angle = 0; + } + } else { + var p0 = getCoords(ctx, fillStyle.x0_, fillStyle.y0_); + focus = { + x: (p0.x - min.x) / width, + y: (p0.y - min.y) / height + }; + + width /= arcScaleX * Z; + height /= arcScaleY * Z; + var dimension = m.max(width, height); + shift = 2 * fillStyle.r0_ / dimension; + expansion = 2 * fillStyle.r1_ / dimension - shift; + } + + // We need to sort the color stops in ascending order by offset, + // otherwise IE won't interpret it correctly. + var stops = fillStyle.colors_; + stops.sort(function(cs1, cs2) { + return cs1.offset - cs2.offset; + }); + + var length = stops.length; + var color1 = stops[0].color; + var color2 = stops[length - 1].color; + var opacity1 = stops[0].alpha * ctx.globalAlpha; + var opacity2 = stops[length - 1].alpha * ctx.globalAlpha; + + var colors = []; + for (var i = 0; i < length; i++) { + var stop = stops[i]; + colors.push(stop.offset * expansion + shift + ' ' + stop.color); + } + + // When colors attribute is used, the meanings of opacity and o:opacity2 + // are reversed. + lineStr.push('<g_vml_:fill type="', fillStyle.type_, '"', + ' method="none" focus="100%"', + ' color="', color1, '"', + ' color2="', color2, '"', + ' colors="', colors.join(','), '"', + ' opacity="', opacity2, '"', + ' g_o_:opacity2="', opacity1, '"', + ' angle="', angle, '"', + ' focusposition="', focus.x, ',', focus.y, '" />'); + } else if (fillStyle instanceof CanvasPattern_) { + if (width && height) { + var deltaLeft = -min.x; + var deltaTop = -min.y; + lineStr.push('<g_vml_:fill', + ' position="', + deltaLeft / width * arcScaleX * arcScaleX, ',', + deltaTop / height * arcScaleY * arcScaleY, '"', + ' type="tile"', + // TODO: Figure out the correct size to fit the scale. + //' size="', w, 'px ', h, 'px"', + ' src="', fillStyle.src_, '" />'); + } + } else { + var a = processStyle(ctx.fillStyle); + var color = a.color; + var opacity = a.alpha * ctx.globalAlpha; + lineStr.push('<g_vml_:fill color="', color, '" opacity="', opacity, + '" />'); + } + } + + contextPrototype.fill = function() { + this.stroke(true); + }; + + contextPrototype.closePath = function() { + this.currentPath_.push({type: 'close'}); + }; + + function getCoords(ctx, aX, aY) { + var m = ctx.m_; + return { + x: Z * (aX * m[0][0] + aY * m[1][0] + m[2][0]) - Z2, + y: Z * (aX * m[0][1] + aY * m[1][1] + m[2][1]) - Z2 + }; + }; + + contextPrototype.save = function() { + var o = {}; + copyState(this, o); + this.aStack_.push(o); + this.mStack_.push(this.m_); + this.m_ = matrixMultiply(createMatrixIdentity(), this.m_); + }; + + contextPrototype.restore = function() { + if (this.aStack_.length) { + copyState(this.aStack_.pop(), this); + this.m_ = this.mStack_.pop(); + } + }; + + function matrixIsFinite(m) { + return isFinite(m[0][0]) && isFinite(m[0][1]) && + isFinite(m[1][0]) && isFinite(m[1][1]) && + isFinite(m[2][0]) && isFinite(m[2][1]); + } + + function setM(ctx, m, updateLineScale) { + if (!matrixIsFinite(m)) { + return; + } + ctx.m_ = m; + + if (updateLineScale) { + // Get the line scale. + // Determinant of this.m_ means how much the area is enlarged by the + // transformation. So its square root can be used as a scale factor + // for width. + var det = m[0][0] * m[1][1] - m[0][1] * m[1][0]; + ctx.lineScale_ = sqrt(abs(det)); + } + } + + contextPrototype.translate = function(aX, aY) { + var m1 = [ + [1, 0, 0], + [0, 1, 0], + [aX, aY, 1] + ]; + + setM(this, matrixMultiply(m1, this.m_), false); + }; + + contextPrototype.rotate = function(aRot) { + var c = mc(aRot); + var s = ms(aRot); + + var m1 = [ + [c, s, 0], + [-s, c, 0], + [0, 0, 1] + ]; + + setM(this, matrixMultiply(m1, this.m_), false); + }; + + contextPrototype.scale = function(aX, aY) { + this.arcScaleX_ *= aX; + this.arcScaleY_ *= aY; + var m1 = [ + [aX, 0, 0], + [0, aY, 0], + [0, 0, 1] + ]; + + setM(this, matrixMultiply(m1, this.m_), true); + }; + + contextPrototype.transform = function(m11, m12, m21, m22, dx, dy) { + var m1 = [ + [m11, m12, 0], + [m21, m22, 0], + [dx, dy, 1] + ]; + + setM(this, matrixMultiply(m1, this.m_), true); + }; + + contextPrototype.setTransform = function(m11, m12, m21, m22, dx, dy) { + var m = [ + [m11, m12, 0], + [m21, m22, 0], + [dx, dy, 1] + ]; + + setM(this, m, true); + }; + + /** + * The text drawing function. + * The maxWidth argument isn't taken in account, since no browser supports + * it yet. + */ + contextPrototype.drawText_ = function(text, x, y, maxWidth, stroke) { + var m = this.m_, + delta = 1000, + left = 0, + right = delta, + offset = {x: 0, y: 0}, + lineStr = []; + + var fontStyle = getComputedStyle(processFontStyle(this.font), + this.element_); + + var fontStyleString = buildStyle(fontStyle); + + var elementStyle = this.element_.currentStyle; + var textAlign = this.textAlign.toLowerCase(); + switch (textAlign) { + case 'left': + case 'center': + case 'right': + break; + case 'end': + textAlign = elementStyle.direction == 'ltr' ? 'right' : 'left'; + break; + case 'start': + textAlign = elementStyle.direction == 'rtl' ? 'right' : 'left'; + break; + default: + textAlign = 'left'; + } + + // 1.75 is an arbitrary number, as there is no info about the text baseline + switch (this.textBaseline) { + case 'hanging': + case 'top': + offset.y = fontStyle.size / 1.75; + break; + case 'middle': + break; + default: + case null: + case 'alphabetic': + case 'ideographic': + case 'bottom': + offset.y = -fontStyle.size / 2.25; + break; + } + + switch(textAlign) { + case 'right': + left = delta; + right = 0.05; + break; + case 'center': + left = right = delta / 2; + break; + } + + var d = getCoords(this, x + offset.x, y + offset.y); + + lineStr.push('<g_vml_:line from="', -left ,' 0" to="', right ,' 0.05" ', + ' coordsize="100 100" coordorigin="0 0"', + ' filled="', !stroke, '" stroked="', !!stroke, + '" style="position:absolute;width:1px;height:1px;">'); + + if (stroke) { + appendStroke(this, lineStr); + } else { + // TODO: Fix the min and max params. + appendFill(this, lineStr, {x: -left, y: 0}, + {x: right, y: fontStyle.size}); + } + + var skewM = m[0][0].toFixed(3) + ',' + m[1][0].toFixed(3) + ',' + + m[0][1].toFixed(3) + ',' + m[1][1].toFixed(3) + ',0,0'; + + var skewOffset = mr(d.x / Z) + ',' + mr(d.y / Z); + + lineStr.push('<g_vml_:skew on="t" matrix="', skewM ,'" ', + ' offset="', skewOffset, '" origin="', left ,' 0" />', + '<g_vml_:path textpathok="true" />', + '<g_vml_:textpath on="true" string="', + encodeHtmlAttribute(text), + '" style="v-text-align:', textAlign, + ';font:', encodeHtmlAttribute(fontStyleString), + '" /></g_vml_:line>'); + + this.element_.insertAdjacentHTML('beforeEnd', lineStr.join('')); + }; + + contextPrototype.fillText = function(text, x, y, maxWidth) { + this.drawText_(text, x, y, maxWidth, false); + }; + + contextPrototype.strokeText = function(text, x, y, maxWidth) { + this.drawText_(text, x, y, maxWidth, true); + }; + + contextPrototype.measureText = function(text) { + if (!this.textMeasureEl_) { + var s = '<span style="position:absolute;' + + 'top:-20000px;left:0;padding:0;margin:0;border:none;' + + 'white-space:pre;"></span>'; + this.element_.insertAdjacentHTML('beforeEnd', s); + this.textMeasureEl_ = this.element_.lastChild; + } + var doc = this.element_.ownerDocument; + this.textMeasureEl_.innerHTML = ''; + this.textMeasureEl_.style.font = this.font; + // Don't use innerHTML or innerText because they allow markup/whitespace. + this.textMeasureEl_.appendChild(doc.createTextNode(text)); + return {width: this.textMeasureEl_.offsetWidth}; + }; + + /******** STUBS ********/ + contextPrototype.clip = function() { + // TODO: Implement + }; + + contextPrototype.arcTo = function() { + // TODO: Implement + }; + + contextPrototype.createPattern = function(image, repetition) { + return new CanvasPattern_(image, repetition); + }; + + // Gradient / Pattern Stubs + function CanvasGradient_(aType) { + this.type_ = aType; + this.x0_ = 0; + this.y0_ = 0; + this.r0_ = 0; + this.x1_ = 0; + this.y1_ = 0; + this.r1_ = 0; + this.colors_ = []; + } + + CanvasGradient_.prototype.addColorStop = function(aOffset, aColor) { + aColor = processStyle(aColor); + this.colors_.push({offset: aOffset, + color: aColor.color, + alpha: aColor.alpha}); + }; + + function CanvasPattern_(image, repetition) { + assertImageIsValid(image); + switch (repetition) { + case 'repeat': + case null: + case '': + this.repetition_ = 'repeat'; + break + case 'repeat-x': + case 'repeat-y': + case 'no-repeat': + this.repetition_ = repetition; + break; + default: + throwException('SYNTAX_ERR'); + } + + this.src_ = image.src; + this.width_ = image.width; + this.height_ = image.height; + } + + function throwException(s) { + throw new DOMException_(s); + } + + function assertImageIsValid(img) { + if (!img || img.nodeType != 1 || img.tagName != 'IMG') { + throwException('TYPE_MISMATCH_ERR'); + } + if (img.readyState != 'complete') { + throwException('INVALID_STATE_ERR'); + } + } + + function DOMException_(s) { + this.code = this[s]; + this.message = s +': DOM Exception ' + this.code; + } + var p = DOMException_.prototype = new Error; + p.INDEX_SIZE_ERR = 1; + p.DOMSTRING_SIZE_ERR = 2; + p.HIERARCHY_REQUEST_ERR = 3; + p.WRONG_DOCUMENT_ERR = 4; + p.INVALID_CHARACTER_ERR = 5; + p.NO_DATA_ALLOWED_ERR = 6; + p.NO_MODIFICATION_ALLOWED_ERR = 7; + p.NOT_FOUND_ERR = 8; + p.NOT_SUPPORTED_ERR = 9; + p.INUSE_ATTRIBUTE_ERR = 10; + p.INVALID_STATE_ERR = 11; + p.SYNTAX_ERR = 12; + p.INVALID_MODIFICATION_ERR = 13; + p.NAMESPACE_ERR = 14; + p.INVALID_ACCESS_ERR = 15; + p.VALIDATION_ERR = 16; + p.TYPE_MISMATCH_ERR = 17; + + // set up externs + G_vmlCanvasManager = G_vmlCanvasManager_; + CanvasRenderingContext2D = CanvasRenderingContext2D_; + CanvasGradient = CanvasGradient_; + CanvasPattern = CanvasPattern_; + DOMException = DOMException_; +})(); + +} // if diff --git a/monitoring/monitoring_ui/src/3dparty/flot/excanvas.min.js b/monitoring/monitoring_ui/src/3dparty/flot/excanvas.min.js new file mode 100644 index 0000000000000000000000000000000000000000..fcf876c749ed323a9b08e5e46d8cdf7f021e14aa --- /dev/null +++ b/monitoring/monitoring_ui/src/3dparty/flot/excanvas.min.js @@ -0,0 +1 @@ +if(!document.createElement("canvas").getContext){(function(){var ab=Math;var n=ab.round;var l=ab.sin;var A=ab.cos;var H=ab.abs;var N=ab.sqrt;var d=10;var f=d/2;var z=+navigator.userAgent.match(/MSIE ([\d.]+)?/)[1];function y(){return this.context_||(this.context_=new D(this))}var t=Array.prototype.slice;function g(j,m,p){var i=t.call(arguments,2);return function(){return j.apply(m,i.concat(t.call(arguments)))}}function af(i){return String(i).replace(/&/g,"&").replace(/"/g,""")}function Y(m,j,i){if(!m.namespaces[j]){m.namespaces.add(j,i,"#default#VML")}}function R(j){Y(j,"g_vml_","urn:schemas-microsoft-com:vml");Y(j,"g_o_","urn:schemas-microsoft-com:office:office");if(!j.styleSheets.ex_canvas_){var i=j.createStyleSheet();i.owningElement.id="ex_canvas_";i.cssText="canvas{display:inline-block;overflow:hidden;text-align:left;width:300px;height:150px}"}}R(document);var e={init:function(i){var j=i||document;j.createElement("canvas");j.attachEvent("onreadystatechange",g(this.init_,this,j))},init_:function(p){var m=p.getElementsByTagName("canvas");for(var j=0;j<m.length;j++){this.initElement(m[j])}},initElement:function(j){if(!j.getContext){j.getContext=y;R(j.ownerDocument);j.innerHTML="";j.attachEvent("onpropertychange",x);j.attachEvent("onresize",W);var i=j.attributes;if(i.width&&i.width.specified){j.style.width=i.width.nodeValue+"px"}else{j.width=j.clientWidth}if(i.height&&i.height.specified){j.style.height=i.height.nodeValue+"px"}else{j.height=j.clientHeight}}return j}};function x(j){var i=j.srcElement;switch(j.propertyName){case"width":i.getContext().clearRect();i.style.width=i.attributes.width.nodeValue+"px";i.firstChild.style.width=i.clientWidth+"px";break;case"height":i.getContext().clearRect();i.style.height=i.attributes.height.nodeValue+"px";i.firstChild.style.height=i.clientHeight+"px";break}}function W(j){var i=j.srcElement;if(i.firstChild){i.firstChild.style.width=i.clientWidth+"px";i.firstChild.style.height=i.clientHeight+"px"}}e.init();var k=[];for(var ae=0;ae<16;ae++){for(var ad=0;ad<16;ad++){k[ae*16+ad]=ae.toString(16)+ad.toString(16)}}function B(){return[[1,0,0],[0,1,0],[0,0,1]]}function J(p,m){var j=B();for(var i=0;i<3;i++){for(var ah=0;ah<3;ah++){var Z=0;for(var ag=0;ag<3;ag++){Z+=p[i][ag]*m[ag][ah]}j[i][ah]=Z}}return j}function v(j,i){i.fillStyle=j.fillStyle;i.lineCap=j.lineCap;i.lineJoin=j.lineJoin;i.lineWidth=j.lineWidth;i.miterLimit=j.miterLimit;i.shadowBlur=j.shadowBlur;i.shadowColor=j.shadowColor;i.shadowOffsetX=j.shadowOffsetX;i.shadowOffsetY=j.shadowOffsetY;i.strokeStyle=j.strokeStyle;i.globalAlpha=j.globalAlpha;i.font=j.font;i.textAlign=j.textAlign;i.textBaseline=j.textBaseline;i.arcScaleX_=j.arcScaleX_;i.arcScaleY_=j.arcScaleY_;i.lineScale_=j.lineScale_}var b={aliceblue:"#F0F8FF",antiquewhite:"#FAEBD7",aquamarine:"#7FFFD4",azure:"#F0FFFF",beige:"#F5F5DC",bisque:"#FFE4C4",black:"#000000",blanchedalmond:"#FFEBCD",blueviolet:"#8A2BE2",brown:"#A52A2A",burlywood:"#DEB887",cadetblue:"#5F9EA0",chartreuse:"#7FFF00",chocolate:"#D2691E",coral:"#FF7F50",cornflowerblue:"#6495ED",cornsilk:"#FFF8DC",crimson:"#DC143C",cyan:"#00FFFF",darkblue:"#00008B",darkcyan:"#008B8B",darkgoldenrod:"#B8860B",darkgray:"#A9A9A9",darkgreen:"#006400",darkgrey:"#A9A9A9",darkkhaki:"#BDB76B",darkmagenta:"#8B008B",darkolivegreen:"#556B2F",darkorange:"#FF8C00",darkorchid:"#9932CC",darkred:"#8B0000",darksalmon:"#E9967A",darkseagreen:"#8FBC8F",darkslateblue:"#483D8B",darkslategray:"#2F4F4F",darkslategrey:"#2F4F4F",darkturquoise:"#00CED1",darkviolet:"#9400D3",deeppink:"#FF1493",deepskyblue:"#00BFFF",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1E90FF",firebrick:"#B22222",floralwhite:"#FFFAF0",forestgreen:"#228B22",gainsboro:"#DCDCDC",ghostwhite:"#F8F8FF",gold:"#FFD700",goldenrod:"#DAA520",grey:"#808080",greenyellow:"#ADFF2F",honeydew:"#F0FFF0",hotpink:"#FF69B4",indianred:"#CD5C5C",indigo:"#4B0082",ivory:"#FFFFF0",khaki:"#F0E68C",lavender:"#E6E6FA",lavenderblush:"#FFF0F5",lawngreen:"#7CFC00",lemonchiffon:"#FFFACD",lightblue:"#ADD8E6",lightcoral:"#F08080",lightcyan:"#E0FFFF",lightgoldenrodyellow:"#FAFAD2",lightgreen:"#90EE90",lightgrey:"#D3D3D3",lightpink:"#FFB6C1",lightsalmon:"#FFA07A",lightseagreen:"#20B2AA",lightskyblue:"#87CEFA",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#B0C4DE",lightyellow:"#FFFFE0",limegreen:"#32CD32",linen:"#FAF0E6",magenta:"#FF00FF",mediumaquamarine:"#66CDAA",mediumblue:"#0000CD",mediumorchid:"#BA55D3",mediumpurple:"#9370DB",mediumseagreen:"#3CB371",mediumslateblue:"#7B68EE",mediumspringgreen:"#00FA9A",mediumturquoise:"#48D1CC",mediumvioletred:"#C71585",midnightblue:"#191970",mintcream:"#F5FFFA",mistyrose:"#FFE4E1",moccasin:"#FFE4B5",navajowhite:"#FFDEAD",oldlace:"#FDF5E6",olivedrab:"#6B8E23",orange:"#FFA500",orangered:"#FF4500",orchid:"#DA70D6",palegoldenrod:"#EEE8AA",palegreen:"#98FB98",paleturquoise:"#AFEEEE",palevioletred:"#DB7093",papayawhip:"#FFEFD5",peachpuff:"#FFDAB9",peru:"#CD853F",pink:"#FFC0CB",plum:"#DDA0DD",powderblue:"#B0E0E6",rosybrown:"#BC8F8F",royalblue:"#4169E1",saddlebrown:"#8B4513",salmon:"#FA8072",sandybrown:"#F4A460",seagreen:"#2E8B57",seashell:"#FFF5EE",sienna:"#A0522D",skyblue:"#87CEEB",slateblue:"#6A5ACD",slategray:"#708090",slategrey:"#708090",snow:"#FFFAFA",springgreen:"#00FF7F",steelblue:"#4682B4",tan:"#D2B48C",thistle:"#D8BFD8",tomato:"#FF6347",turquoise:"#40E0D0",violet:"#EE82EE",wheat:"#F5DEB3",whitesmoke:"#F5F5F5",yellowgreen:"#9ACD32"};function M(j){var p=j.indexOf("(",3);var i=j.indexOf(")",p+1);var m=j.substring(p+1,i).split(",");if(m.length!=4||j.charAt(3)!="a"){m[3]=1}return m}function c(i){return parseFloat(i)/100}function r(j,m,i){return Math.min(i,Math.max(m,j))}function I(ag){var i,ai,aj,ah,ak,Z;ah=parseFloat(ag[0])/360%360;if(ah<0){ah++}ak=r(c(ag[1]),0,1);Z=r(c(ag[2]),0,1);if(ak==0){i=ai=aj=Z}else{var j=Z<0.5?Z*(1+ak):Z+ak-Z*ak;var m=2*Z-j;i=a(m,j,ah+1/3);ai=a(m,j,ah);aj=a(m,j,ah-1/3)}return"#"+k[Math.floor(i*255)]+k[Math.floor(ai*255)]+k[Math.floor(aj*255)]}function a(j,i,m){if(m<0){m++}if(m>1){m--}if(6*m<1){return j+(i-j)*6*m}else{if(2*m<1){return i}else{if(3*m<2){return j+(i-j)*(2/3-m)*6}else{return j}}}}var C={};function F(j){if(j in C){return C[j]}var ag,Z=1;j=String(j);if(j.charAt(0)=="#"){ag=j}else{if(/^rgb/.test(j)){var p=M(j);var ag="#",ah;for(var m=0;m<3;m++){if(p[m].indexOf("%")!=-1){ah=Math.floor(c(p[m])*255)}else{ah=+p[m]}ag+=k[r(ah,0,255)]}Z=+p[3]}else{if(/^hsl/.test(j)){var p=M(j);ag=I(p);Z=p[3]}else{ag=b[j]||j}}}return C[j]={color:ag,alpha:Z}}var o={style:"normal",variant:"normal",weight:"normal",size:10,family:"sans-serif"};var L={};function E(i){if(L[i]){return L[i]}var p=document.createElement("div");var m=p.style;try{m.font=i}catch(j){}return L[i]={style:m.fontStyle||o.style,variant:m.fontVariant||o.variant,weight:m.fontWeight||o.weight,size:m.fontSize||o.size,family:m.fontFamily||o.family}}function u(m,j){var i={};for(var ah in m){i[ah]=m[ah]}var ag=parseFloat(j.currentStyle.fontSize),Z=parseFloat(m.size);if(typeof m.size=="number"){i.size=m.size}else{if(m.size.indexOf("px")!=-1){i.size=Z}else{if(m.size.indexOf("em")!=-1){i.size=ag*Z}else{if(m.size.indexOf("%")!=-1){i.size=(ag/100)*Z}else{if(m.size.indexOf("pt")!=-1){i.size=Z/0.75}else{i.size=ag}}}}}i.size*=0.981;return i}function ac(i){return i.style+" "+i.variant+" "+i.weight+" "+i.size+"px "+i.family}var s={butt:"flat",round:"round"};function S(i){return s[i]||"square"}function D(i){this.m_=B();this.mStack_=[];this.aStack_=[];this.currentPath_=[];this.strokeStyle="#000";this.fillStyle="#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt";this.miterLimit=d*1;this.globalAlpha=1;this.font="10px sans-serif";this.textAlign="left";this.textBaseline="alphabetic";this.canvas=i;var m="width:"+i.clientWidth+"px;height:"+i.clientHeight+"px;overflow:hidden;position:absolute";var j=i.ownerDocument.createElement("div");j.style.cssText=m;i.appendChild(j);var p=j.cloneNode(false);p.style.backgroundColor="red";p.style.filter="alpha(opacity=0)";i.appendChild(p);this.element_=j;this.arcScaleX_=1;this.arcScaleY_=1;this.lineScale_=1}var q=D.prototype;q.clearRect=function(){if(this.textMeasureEl_){this.textMeasureEl_.removeNode(true);this.textMeasureEl_=null}this.element_.innerHTML=""};q.beginPath=function(){this.currentPath_=[]};q.moveTo=function(j,i){var m=V(this,j,i);this.currentPath_.push({type:"moveTo",x:m.x,y:m.y});this.currentX_=m.x;this.currentY_=m.y};q.lineTo=function(j,i){var m=V(this,j,i);this.currentPath_.push({type:"lineTo",x:m.x,y:m.y});this.currentX_=m.x;this.currentY_=m.y};q.bezierCurveTo=function(m,j,ak,aj,ai,ag){var i=V(this,ai,ag);var ah=V(this,m,j);var Z=V(this,ak,aj);K(this,ah,Z,i)};function K(i,Z,m,j){i.currentPath_.push({type:"bezierCurveTo",cp1x:Z.x,cp1y:Z.y,cp2x:m.x,cp2y:m.y,x:j.x,y:j.y});i.currentX_=j.x;i.currentY_=j.y}q.quadraticCurveTo=function(ai,m,j,i){var ah=V(this,ai,m);var ag=V(this,j,i);var aj={x:this.currentX_+2/3*(ah.x-this.currentX_),y:this.currentY_+2/3*(ah.y-this.currentY_)};var Z={x:aj.x+(ag.x-this.currentX_)/3,y:aj.y+(ag.y-this.currentY_)/3};K(this,aj,Z,ag)};q.arc=function(al,aj,ak,ag,j,m){ak*=d;var ap=m?"at":"wa";var am=al+A(ag)*ak-f;var ao=aj+l(ag)*ak-f;var i=al+A(j)*ak-f;var an=aj+l(j)*ak-f;if(am==i&&!m){am+=0.125}var Z=V(this,al,aj);var ai=V(this,am,ao);var ah=V(this,i,an);this.currentPath_.push({type:ap,x:Z.x,y:Z.y,radius:ak,xStart:ai.x,yStart:ai.y,xEnd:ah.x,yEnd:ah.y})};q.rect=function(m,j,i,p){this.moveTo(m,j);this.lineTo(m+i,j);this.lineTo(m+i,j+p);this.lineTo(m,j+p);this.closePath()};q.strokeRect=function(m,j,i,p){var Z=this.currentPath_;this.beginPath();this.moveTo(m,j);this.lineTo(m+i,j);this.lineTo(m+i,j+p);this.lineTo(m,j+p);this.closePath();this.stroke();this.currentPath_=Z};q.fillRect=function(m,j,i,p){var Z=this.currentPath_;this.beginPath();this.moveTo(m,j);this.lineTo(m+i,j);this.lineTo(m+i,j+p);this.lineTo(m,j+p);this.closePath();this.fill();this.currentPath_=Z};q.createLinearGradient=function(j,p,i,m){var Z=new U("gradient");Z.x0_=j;Z.y0_=p;Z.x1_=i;Z.y1_=m;return Z};q.createRadialGradient=function(p,ag,m,j,Z,i){var ah=new U("gradientradial");ah.x0_=p;ah.y0_=ag;ah.r0_=m;ah.x1_=j;ah.y1_=Z;ah.r1_=i;return ah};q.drawImage=function(aq,m){var aj,ah,al,ay,ao,am,at,aA;var ak=aq.runtimeStyle.width;var ap=aq.runtimeStyle.height;aq.runtimeStyle.width="auto";aq.runtimeStyle.height="auto";var ai=aq.width;var aw=aq.height;aq.runtimeStyle.width=ak;aq.runtimeStyle.height=ap;if(arguments.length==3){aj=arguments[1];ah=arguments[2];ao=am=0;at=al=ai;aA=ay=aw}else{if(arguments.length==5){aj=arguments[1];ah=arguments[2];al=arguments[3];ay=arguments[4];ao=am=0;at=ai;aA=aw}else{if(arguments.length==9){ao=arguments[1];am=arguments[2];at=arguments[3];aA=arguments[4];aj=arguments[5];ah=arguments[6];al=arguments[7];ay=arguments[8]}else{throw Error("Invalid number of arguments")}}}var az=V(this,aj,ah);var p=at/2;var j=aA/2;var ax=[];var i=10;var ag=10;ax.push(" <g_vml_:group",' coordsize="',d*i,",",d*ag,'"',' coordorigin="0,0"',' style="width:',i,"px;height:",ag,"px;position:absolute;");if(this.m_[0][0]!=1||this.m_[0][1]||this.m_[1][1]!=1||this.m_[1][0]){var Z=[];Z.push("M11=",this.m_[0][0],",","M12=",this.m_[1][0],",","M21=",this.m_[0][1],",","M22=",this.m_[1][1],",","Dx=",n(az.x/d),",","Dy=",n(az.y/d),"");var av=az;var au=V(this,aj+al,ah);var ar=V(this,aj,ah+ay);var an=V(this,aj+al,ah+ay);av.x=ab.max(av.x,au.x,ar.x,an.x);av.y=ab.max(av.y,au.y,ar.y,an.y);ax.push("padding:0 ",n(av.x/d),"px ",n(av.y/d),"px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",Z.join(""),", sizingmethod='clip');")}else{ax.push("top:",n(az.y/d),"px;left:",n(az.x/d),"px;")}ax.push(' ">','<g_vml_:image src="',aq.src,'"',' style="width:',d*al,"px;"," height:",d*ay,'px"',' cropleft="',ao/ai,'"',' croptop="',am/aw,'"',' cropright="',(ai-ao-at)/ai,'"',' cropbottom="',(aw-am-aA)/aw,'"'," />","</g_vml_:group>");this.element_.insertAdjacentHTML("BeforeEnd",ax.join(""))};q.stroke=function(ao){var Z=10;var ap=10;var ag=5000;var ai={x:null,y:null};var an={x:null,y:null};for(var aj=0;aj<this.currentPath_.length;aj+=ag){var am=[];var ah=false;am.push("<g_vml_:shape",' filled="',!!ao,'"',' style="position:absolute;width:',Z,"px;height:",ap,'px;"',' coordorigin="0,0"',' coordsize="',d*Z,",",d*ap,'"',' stroked="',!ao,'"',' path="');var aq=false;for(var ak=aj;ak<Math.min(aj+ag,this.currentPath_.length);ak++){if(ak%ag==0&&ak>0){am.push(" m ",n(this.currentPath_[ak-1].x),",",n(this.currentPath_[ak-1].y))}var m=this.currentPath_[ak];var al;switch(m.type){case"moveTo":al=m;am.push(" m ",n(m.x),",",n(m.y));break;case"lineTo":am.push(" l ",n(m.x),",",n(m.y));break;case"close":am.push(" x ");m=null;break;case"bezierCurveTo":am.push(" c ",n(m.cp1x),",",n(m.cp1y),",",n(m.cp2x),",",n(m.cp2y),",",n(m.x),",",n(m.y));break;case"at":case"wa":am.push(" ",m.type," ",n(m.x-this.arcScaleX_*m.radius),",",n(m.y-this.arcScaleY_*m.radius)," ",n(m.x+this.arcScaleX_*m.radius),",",n(m.y+this.arcScaleY_*m.radius)," ",n(m.xStart),",",n(m.yStart)," ",n(m.xEnd),",",n(m.yEnd));break}if(m){if(ai.x==null||m.x<ai.x){ai.x=m.x}if(an.x==null||m.x>an.x){an.x=m.x}if(ai.y==null||m.y<ai.y){ai.y=m.y}if(an.y==null||m.y>an.y){an.y=m.y}}}am.push(' ">');if(!ao){w(this,am)}else{G(this,am,ai,an)}am.push("</g_vml_:shape>");this.element_.insertAdjacentHTML("beforeEnd",am.join(""))}};function w(m,ag){var j=F(m.strokeStyle);var p=j.color;var Z=j.alpha*m.globalAlpha;var i=m.lineScale_*m.lineWidth;if(i<1){Z*=i}ag.push("<g_vml_:stroke",' opacity="',Z,'"',' joinstyle="',m.lineJoin,'"',' miterlimit="',m.miterLimit,'"',' endcap="',S(m.lineCap),'"',' weight="',i,'px"',' color="',p,'" />')}function G(aq,ai,aK,ar){var aj=aq.fillStyle;var aB=aq.arcScaleX_;var aA=aq.arcScaleY_;var j=ar.x-aK.x;var p=ar.y-aK.y;if(aj instanceof U){var an=0;var aF={x:0,y:0};var ax=0;var am=1;if(aj.type_=="gradient"){var al=aj.x0_/aB;var m=aj.y0_/aA;var ak=aj.x1_/aB;var aM=aj.y1_/aA;var aJ=V(aq,al,m);var aI=V(aq,ak,aM);var ag=aI.x-aJ.x;var Z=aI.y-aJ.y;an=Math.atan2(ag,Z)*180/Math.PI;if(an<0){an+=360}if(an<0.000001){an=0}}else{var aJ=V(aq,aj.x0_,aj.y0_);aF={x:(aJ.x-aK.x)/j,y:(aJ.y-aK.y)/p};j/=aB*d;p/=aA*d;var aD=ab.max(j,p);ax=2*aj.r0_/aD;am=2*aj.r1_/aD-ax}var av=aj.colors_;av.sort(function(aN,i){return aN.offset-i.offset});var ap=av.length;var au=av[0].color;var at=av[ap-1].color;var az=av[0].alpha*aq.globalAlpha;var ay=av[ap-1].alpha*aq.globalAlpha;var aE=[];for(var aH=0;aH<ap;aH++){var ao=av[aH];aE.push(ao.offset*am+ax+" "+ao.color)}ai.push('<g_vml_:fill type="',aj.type_,'"',' method="none" focus="100%"',' color="',au,'"',' color2="',at,'"',' colors="',aE.join(","),'"',' opacity="',ay,'"',' g_o_:opacity2="',az,'"',' angle="',an,'"',' focusposition="',aF.x,",",aF.y,'" />')}else{if(aj instanceof T){if(j&&p){var ah=-aK.x;var aC=-aK.y;ai.push("<g_vml_:fill",' position="',ah/j*aB*aB,",",aC/p*aA*aA,'"',' type="tile"',' src="',aj.src_,'" />')}}else{var aL=F(aq.fillStyle);var aw=aL.color;var aG=aL.alpha*aq.globalAlpha;ai.push('<g_vml_:fill color="',aw,'" opacity="',aG,'" />')}}}q.fill=function(){this.stroke(true)};q.closePath=function(){this.currentPath_.push({type:"close"})};function V(j,Z,p){var i=j.m_;return{x:d*(Z*i[0][0]+p*i[1][0]+i[2][0])-f,y:d*(Z*i[0][1]+p*i[1][1]+i[2][1])-f}}q.save=function(){var i={};v(this,i);this.aStack_.push(i);this.mStack_.push(this.m_);this.m_=J(B(),this.m_)};q.restore=function(){if(this.aStack_.length){v(this.aStack_.pop(),this);this.m_=this.mStack_.pop()}};function h(i){return isFinite(i[0][0])&&isFinite(i[0][1])&&isFinite(i[1][0])&&isFinite(i[1][1])&&isFinite(i[2][0])&&isFinite(i[2][1])}function aa(j,i,p){if(!h(i)){return}j.m_=i;if(p){var Z=i[0][0]*i[1][1]-i[0][1]*i[1][0];j.lineScale_=N(H(Z))}}q.translate=function(m,j){var i=[[1,0,0],[0,1,0],[m,j,1]];aa(this,J(i,this.m_),false)};q.rotate=function(j){var p=A(j);var m=l(j);var i=[[p,m,0],[-m,p,0],[0,0,1]];aa(this,J(i,this.m_),false)};q.scale=function(m,j){this.arcScaleX_*=m;this.arcScaleY_*=j;var i=[[m,0,0],[0,j,0],[0,0,1]];aa(this,J(i,this.m_),true)};q.transform=function(Z,p,ah,ag,j,i){var m=[[Z,p,0],[ah,ag,0],[j,i,1]];aa(this,J(m,this.m_),true)};q.setTransform=function(ag,Z,ai,ah,p,j){var i=[[ag,Z,0],[ai,ah,0],[p,j,1]];aa(this,i,true)};q.drawText_=function(am,ak,aj,ap,ai){var ao=this.m_,at=1000,j=0,ar=at,ah={x:0,y:0},ag=[];var i=u(E(this.font),this.element_);var p=ac(i);var au=this.element_.currentStyle;var Z=this.textAlign.toLowerCase();switch(Z){case"left":case"center":case"right":break;case"end":Z=au.direction=="ltr"?"right":"left";break;case"start":Z=au.direction=="rtl"?"right":"left";break;default:Z="left"}switch(this.textBaseline){case"hanging":case"top":ah.y=i.size/1.75;break;case"middle":break;default:case null:case"alphabetic":case"ideographic":case"bottom":ah.y=-i.size/2.25;break}switch(Z){case"right":j=at;ar=0.05;break;case"center":j=ar=at/2;break}var aq=V(this,ak+ah.x,aj+ah.y);ag.push('<g_vml_:line from="',-j,' 0" to="',ar,' 0.05" ',' coordsize="100 100" coordorigin="0 0"',' filled="',!ai,'" stroked="',!!ai,'" style="position:absolute;width:1px;height:1px;">');if(ai){w(this,ag)}else{G(this,ag,{x:-j,y:0},{x:ar,y:i.size})}var an=ao[0][0].toFixed(3)+","+ao[1][0].toFixed(3)+","+ao[0][1].toFixed(3)+","+ao[1][1].toFixed(3)+",0,0";var al=n(aq.x/d)+","+n(aq.y/d);ag.push('<g_vml_:skew on="t" matrix="',an,'" ',' offset="',al,'" origin="',j,' 0" />','<g_vml_:path textpathok="true" />','<g_vml_:textpath on="true" string="',af(am),'" style="v-text-align:',Z,";font:",af(p),'" /></g_vml_:line>');this.element_.insertAdjacentHTML("beforeEnd",ag.join(""))};q.fillText=function(m,i,p,j){this.drawText_(m,i,p,j,false)};q.strokeText=function(m,i,p,j){this.drawText_(m,i,p,j,true)};q.measureText=function(m){if(!this.textMeasureEl_){var i='<span style="position:absolute;top:-20000px;left:0;padding:0;margin:0;border:none;white-space:pre;"></span>';this.element_.insertAdjacentHTML("beforeEnd",i);this.textMeasureEl_=this.element_.lastChild}var j=this.element_.ownerDocument;this.textMeasureEl_.innerHTML="";this.textMeasureEl_.style.font=this.font;this.textMeasureEl_.appendChild(j.createTextNode(m));return{width:this.textMeasureEl_.offsetWidth}};q.clip=function(){};q.arcTo=function(){};q.createPattern=function(j,i){return new T(j,i)};function U(i){this.type_=i;this.x0_=0;this.y0_=0;this.r0_=0;this.x1_=0;this.y1_=0;this.r1_=0;this.colors_=[]}U.prototype.addColorStop=function(j,i){i=F(i);this.colors_.push({offset:j,color:i.color,alpha:i.alpha})};function T(j,i){Q(j);switch(i){case"repeat":case null:case"":this.repetition_="repeat";break;case"repeat-x":case"repeat-y":case"no-repeat":this.repetition_=i;break;default:O("SYNTAX_ERR")}this.src_=j.src;this.width_=j.width;this.height_=j.height}function O(i){throw new P(i)}function Q(i){if(!i||i.nodeType!=1||i.tagName!="IMG"){O("TYPE_MISMATCH_ERR")}if(i.readyState!="complete"){O("INVALID_STATE_ERR")}}function P(i){this.code=this[i];this.message=i+": DOM Exception "+this.code}var X=P.prototype=new Error;X.INDEX_SIZE_ERR=1;X.DOMSTRING_SIZE_ERR=2;X.HIERARCHY_REQUEST_ERR=3;X.WRONG_DOCUMENT_ERR=4;X.INVALID_CHARACTER_ERR=5;X.NO_DATA_ALLOWED_ERR=6;X.NO_MODIFICATION_ALLOWED_ERR=7;X.NOT_FOUND_ERR=8;X.NOT_SUPPORTED_ERR=9;X.INUSE_ATTRIBUTE_ERR=10;X.INVALID_STATE_ERR=11;X.SYNTAX_ERR=12;X.INVALID_MODIFICATION_ERR=13;X.NAMESPACE_ERR=14;X.INVALID_ACCESS_ERR=15;X.VALIDATION_ERR=16;X.TYPE_MISMATCH_ERR=17;G_vmlCanvasManager=e;CanvasRenderingContext2D=D;CanvasGradient=U;CanvasPattern=T;DOMException=P})()}; \ No newline at end of file diff --git a/monitoring/monitoring_ui/src/3dparty/flot/flot.jquery.json b/monitoring/monitoring_ui/src/3dparty/flot/flot.jquery.json new file mode 100644 index 0000000000000000000000000000000000000000..91ac79af1519f706709c044673f7823f173c7c9d --- /dev/null +++ b/monitoring/monitoring_ui/src/3dparty/flot/flot.jquery.json @@ -0,0 +1,27 @@ +{ + "name": "flot", + "version": "0.8.3", + "title": "Flot", + "author": { + "name": "Ole Laursen", + "url": "https://github.com/OleLaursen" + }, + "licenses": [{ + "type": "MIT", + "url": "http://github.com/flot/flot/blob/master/LICENSE.txt" + }], + "dependencies": { + "jquery": ">=1.2.6" + }, + "description": "Flot is a pure JavaScript plotting library for jQuery, with a focus on simple usage, attractive looks and interactive features.", + "keywords": ["plot", "chart", "graph", "visualization", "canvas", "graphics"], + "homepage": "http://www.flotcharts.org", + "docs": "http://github.com/flot/flot/blob/master/API.md", + "demo": "http://www.flotcharts.org/flot/examples/", + "bugs": "http://github.com/flot/flot/issues", + "maintainers": [{ + "name": "David Schnur", + "email": "dnschnur@gmail.com", + "url": "http://github.com/dnschnur" + }] +} diff --git a/monitoring/monitoring_ui/src/3dparty/flot/jquery.colorhelpers.js b/monitoring/monitoring_ui/src/3dparty/flot/jquery.colorhelpers.js new file mode 100644 index 0000000000000000000000000000000000000000..b2f6dc4e433a31a1997ed7f553e432b94b3ad391 --- /dev/null +++ b/monitoring/monitoring_ui/src/3dparty/flot/jquery.colorhelpers.js @@ -0,0 +1,180 @@ +/* Plugin for jQuery for working with colors. + * + * Version 1.1. + * + * Inspiration from jQuery color animation plugin by John Resig. + * + * Released under the MIT license by Ole Laursen, October 2009. + * + * Examples: + * + * $.color.parse("#fff").scale('rgb', 0.25).add('a', -0.5).toString() + * var c = $.color.extract($("#mydiv"), 'background-color'); + * console.log(c.r, c.g, c.b, c.a); + * $.color.make(100, 50, 25, 0.4).toString() // returns "rgba(100,50,25,0.4)" + * + * Note that .scale() and .add() return the same modified object + * instead of making a new one. + * + * V. 1.1: Fix error handling so e.g. parsing an empty string does + * produce a color rather than just crashing. + */ + +(function($) { + $.color = {}; + + // construct color object with some convenient chainable helpers + $.color.make = function (r, g, b, a) { + var o = {}; + o.r = r || 0; + o.g = g || 0; + o.b = b || 0; + o.a = a != null ? a : 1; + + o.add = function (c, d) { + for (var i = 0; i < c.length; ++i) + o[c.charAt(i)] += d; + return o.normalize(); + }; + + o.scale = function (c, f) { + for (var i = 0; i < c.length; ++i) + o[c.charAt(i)] *= f; + return o.normalize(); + }; + + o.toString = function () { + if (o.a >= 1.0) { + return "rgb("+[o.r, o.g, o.b].join(",")+")"; + } else { + return "rgba("+[o.r, o.g, o.b, o.a].join(",")+")"; + } + }; + + o.normalize = function () { + function clamp(min, value, max) { + return value < min ? min: (value > max ? max: value); + } + + o.r = clamp(0, parseInt(o.r), 255); + o.g = clamp(0, parseInt(o.g), 255); + o.b = clamp(0, parseInt(o.b), 255); + o.a = clamp(0, o.a, 1); + return o; + }; + + o.clone = function () { + return $.color.make(o.r, o.b, o.g, o.a); + }; + + return o.normalize(); + } + + // extract CSS color property from element, going up in the DOM + // if it's "transparent" + $.color.extract = function (elem, css) { + var c; + + do { + c = elem.css(css).toLowerCase(); + // keep going until we find an element that has color, or + // we hit the body or root (have no parent) + if (c != '' && c != 'transparent') + break; + elem = elem.parent(); + } while (elem.length && !$.nodeName(elem.get(0), "body")); + + // catch Safari's way of signalling transparent + if (c == "rgba(0, 0, 0, 0)") + c = "transparent"; + + return $.color.parse(c); + } + + // parse CSS color string (like "rgb(10, 32, 43)" or "#fff"), + // returns color object, if parsing failed, you get black (0, 0, + // 0) out + $.color.parse = function (str) { + var res, m = $.color.make; + + // Look for rgb(num,num,num) + if (res = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str)) + return m(parseInt(res[1], 10), parseInt(res[2], 10), parseInt(res[3], 10)); + + // Look for rgba(num,num,num,num) + if (res = /rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str)) + return m(parseInt(res[1], 10), parseInt(res[2], 10), parseInt(res[3], 10), parseFloat(res[4])); + + // Look for rgb(num%,num%,num%) + if (res = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(str)) + return m(parseFloat(res[1])*2.55, parseFloat(res[2])*2.55, parseFloat(res[3])*2.55); + + // Look for rgba(num%,num%,num%,num) + if (res = /rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str)) + return m(parseFloat(res[1])*2.55, parseFloat(res[2])*2.55, parseFloat(res[3])*2.55, parseFloat(res[4])); + + // Look for #a0b1c2 + if (res = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str)) + return m(parseInt(res[1], 16), parseInt(res[2], 16), parseInt(res[3], 16)); + + // Look for #fff + if (res = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str)) + return m(parseInt(res[1]+res[1], 16), parseInt(res[2]+res[2], 16), parseInt(res[3]+res[3], 16)); + + // Otherwise, we're most likely dealing with a named color + var name = $.trim(str).toLowerCase(); + if (name == "transparent") + return m(255, 255, 255, 0); + else { + // default to black + res = lookupColors[name] || [0, 0, 0]; + return m(res[0], res[1], res[2]); + } + } + + var lookupColors = { + aqua:[0,255,255], + azure:[240,255,255], + beige:[245,245,220], + black:[0,0,0], + blue:[0,0,255], + brown:[165,42,42], + cyan:[0,255,255], + darkblue:[0,0,139], + darkcyan:[0,139,139], + darkgrey:[169,169,169], + darkgreen:[0,100,0], + darkkhaki:[189,183,107], + darkmagenta:[139,0,139], + darkolivegreen:[85,107,47], + darkorange:[255,140,0], + darkorchid:[153,50,204], + darkred:[139,0,0], + darksalmon:[233,150,122], + darkviolet:[148,0,211], + fuchsia:[255,0,255], + gold:[255,215,0], + green:[0,128,0], + indigo:[75,0,130], + khaki:[240,230,140], + lightblue:[173,216,230], + lightcyan:[224,255,255], + lightgreen:[144,238,144], + lightgrey:[211,211,211], + lightpink:[255,182,193], + lightyellow:[255,255,224], + lime:[0,255,0], + magenta:[255,0,255], + maroon:[128,0,0], + navy:[0,0,128], + olive:[128,128,0], + orange:[255,165,0], + pink:[255,192,203], + purple:[128,0,128], + violet:[128,0,128], + red:[255,0,0], + silver:[192,192,192], + white:[255,255,255], + yellow:[255,255,0] + }; +})(jQuery); diff --git a/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.canvas.js b/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.canvas.js new file mode 100644 index 0000000000000000000000000000000000000000..29328d58121277812f355091429a7a4128b0f3e9 --- /dev/null +++ b/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.canvas.js @@ -0,0 +1,345 @@ +/* Flot plugin for drawing all elements of a plot on the canvas. + +Copyright (c) 2007-2014 IOLA and Ole Laursen. +Licensed under the MIT license. + +Flot normally produces certain elements, like axis labels and the legend, using +HTML elements. This permits greater interactivity and customization, and often +looks better, due to cross-browser canvas text inconsistencies and limitations. + +It can also be desirable to render the plot entirely in canvas, particularly +if the goal is to save it as an image, or if Flot is being used in a context +where the HTML DOM does not exist, as is the case within Node.js. This plugin +switches out Flot's standard drawing operations for canvas-only replacements. + +Currently the plugin supports only axis labels, but it will eventually allow +every element of the plot to be rendered directly to canvas. + +The plugin supports these options: + +{ + canvas: boolean +} + +The "canvas" option controls whether full canvas drawing is enabled, making it +possible to toggle on and off. This is useful when a plot uses HTML text in the +browser, but needs to redraw with canvas text when exporting as an image. + +*/ + +(function($) { + + var options = { + canvas: true + }; + + var render, getTextInfo, addText; + + // Cache the prototype hasOwnProperty for faster access + + var hasOwnProperty = Object.prototype.hasOwnProperty; + + function init(plot, classes) { + + var Canvas = classes.Canvas; + + // We only want to replace the functions once; the second time around + // we would just get our new function back. This whole replacing of + // prototype functions is a disaster, and needs to be changed ASAP. + + if (render == null) { + getTextInfo = Canvas.prototype.getTextInfo, + addText = Canvas.prototype.addText, + render = Canvas.prototype.render; + } + + // Finishes rendering the canvas, including overlaid text + + Canvas.prototype.render = function() { + + if (!plot.getOptions().canvas) { + return render.call(this); + } + + var context = this.context, + cache = this._textCache; + + // For each text layer, render elements marked as active + + context.save(); + context.textBaseline = "middle"; + + for (var layerKey in cache) { + if (hasOwnProperty.call(cache, layerKey)) { + var layerCache = cache[layerKey]; + for (var styleKey in layerCache) { + if (hasOwnProperty.call(layerCache, styleKey)) { + var styleCache = layerCache[styleKey], + updateStyles = true; + for (var key in styleCache) { + if (hasOwnProperty.call(styleCache, key)) { + + var info = styleCache[key], + positions = info.positions, + lines = info.lines; + + // Since every element at this level of the cache have the + // same font and fill styles, we can just change them once + // using the values from the first element. + + if (updateStyles) { + context.fillStyle = info.font.color; + context.font = info.font.definition; + updateStyles = false; + } + + for (var i = 0, position; position = positions[i]; i++) { + if (position.active) { + for (var j = 0, line; line = position.lines[j]; j++) { + context.fillText(lines[j].text, line[0], line[1]); + } + } else { + positions.splice(i--, 1); + } + } + + if (positions.length == 0) { + delete styleCache[key]; + } + } + } + } + } + } + } + + context.restore(); + }; + + // Creates (if necessary) and returns a text info object. + // + // When the canvas option is set, the object looks like this: + // + // { + // width: Width of the text's bounding box. + // height: Height of the text's bounding box. + // positions: Array of positions at which this text is drawn. + // lines: [{ + // height: Height of this line. + // widths: Width of this line. + // text: Text on this line. + // }], + // font: { + // definition: Canvas font property string. + // color: Color of the text. + // }, + // } + // + // The positions array contains objects that look like this: + // + // { + // active: Flag indicating whether the text should be visible. + // lines: Array of [x, y] coordinates at which to draw the line. + // x: X coordinate at which to draw the text. + // y: Y coordinate at which to draw the text. + // } + + Canvas.prototype.getTextInfo = function(layer, text, font, angle, width) { + + if (!plot.getOptions().canvas) { + return getTextInfo.call(this, layer, text, font, angle, width); + } + + var textStyle, layerCache, styleCache, info; + + // Cast the value to a string, in case we were given a number + + text = "" + text; + + // If the font is a font-spec object, generate a CSS definition + + if (typeof font === "object") { + textStyle = font.style + " " + font.variant + " " + font.weight + " " + font.size + "px " + font.family; + } else { + textStyle = font; + } + + // Retrieve (or create) the cache for the text's layer and styles + + layerCache = this._textCache[layer]; + + if (layerCache == null) { + layerCache = this._textCache[layer] = {}; + } + + styleCache = layerCache[textStyle]; + + if (styleCache == null) { + styleCache = layerCache[textStyle] = {}; + } + + info = styleCache[text]; + + if (info == null) { + + var context = this.context; + + // If the font was provided as CSS, create a div with those + // classes and examine it to generate a canvas font spec. + + if (typeof font !== "object") { + + var element = $("<div> </div>") + .css("position", "absolute") + .addClass(typeof font === "string" ? font : null) + .appendTo(this.getTextLayer(layer)); + + font = { + lineHeight: element.height(), + style: element.css("font-style"), + variant: element.css("font-variant"), + weight: element.css("font-weight"), + family: element.css("font-family"), + color: element.css("color") + }; + + // Setting line-height to 1, without units, sets it equal + // to the font-size, even if the font-size is abstract, + // like 'smaller'. This enables us to read the real size + // via the element's height, working around browsers that + // return the literal 'smaller' value. + + font.size = element.css("line-height", 1).height(); + + element.remove(); + } + + textStyle = font.style + " " + font.variant + " " + font.weight + " " + font.size + "px " + font.family; + + // Create a new info object, initializing the dimensions to + // zero so we can count them up line-by-line. + + info = styleCache[text] = { + width: 0, + height: 0, + positions: [], + lines: [], + font: { + definition: textStyle, + color: font.color + } + }; + + context.save(); + context.font = textStyle; + + // Canvas can't handle multi-line strings; break on various + // newlines, including HTML brs, to build a list of lines. + // Note that we could split directly on regexps, but IE < 9 is + // broken; revisit when we drop IE 7/8 support. + + var lines = (text + "").replace(/<br ?\/?>|\r\n|\r/g, "\n").split("\n"); + + for (var i = 0; i < lines.length; ++i) { + + var lineText = lines[i], + measured = context.measureText(lineText); + + info.width = Math.max(measured.width, info.width); + info.height += font.lineHeight; + + info.lines.push({ + text: lineText, + width: measured.width, + height: font.lineHeight + }); + } + + context.restore(); + } + + return info; + }; + + // Adds a text string to the canvas text overlay. + + Canvas.prototype.addText = function(layer, x, y, text, font, angle, width, halign, valign) { + + if (!plot.getOptions().canvas) { + return addText.call(this, layer, x, y, text, font, angle, width, halign, valign); + } + + var info = this.getTextInfo(layer, text, font, angle, width), + positions = info.positions, + lines = info.lines; + + // Text is drawn with baseline 'middle', which we need to account + // for by adding half a line's height to the y position. + + y += info.height / lines.length / 2; + + // Tweak the initial y-position to match vertical alignment + + if (valign == "middle") { + y = Math.round(y - info.height / 2); + } else if (valign == "bottom") { + y = Math.round(y - info.height); + } else { + y = Math.round(y); + } + + // FIXME: LEGACY BROWSER FIX + // AFFECTS: Opera < 12.00 + + // Offset the y coordinate, since Opera is off pretty + // consistently compared to the other browsers. + + if (!!(window.opera && window.opera.version().split(".")[0] < 12)) { + y -= 2; + } + + // Determine whether this text already exists at this position. + // If so, mark it for inclusion in the next render pass. + + for (var i = 0, position; position = positions[i]; i++) { + if (position.x == x && position.y == y) { + position.active = true; + return; + } + } + + // If the text doesn't exist at this position, create a new entry + + position = { + active: true, + lines: [], + x: x, + y: y + }; + + positions.push(position); + + // Fill in the x & y positions of each line, adjusting them + // individually for horizontal alignment. + + for (var i = 0, line; line = lines[i]; i++) { + if (halign == "center") { + position.lines.push([Math.round(x - line.width / 2), y]); + } else if (halign == "right") { + position.lines.push([Math.round(x - line.width), y]); + } else { + position.lines.push([Math.round(x), y]); + } + y += line.height; + } + }; + } + + $.plot.plugins.push({ + init: init, + options: options, + name: "canvas", + version: "1.0" + }); + +})(jQuery); diff --git a/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.categories.js b/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.categories.js new file mode 100644 index 0000000000000000000000000000000000000000..2f9b2579714997092e497a19dd4d16e05602d069 --- /dev/null +++ b/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.categories.js @@ -0,0 +1,190 @@ +/* Flot plugin for plotting textual data or categories. + +Copyright (c) 2007-2014 IOLA and Ole Laursen. +Licensed under the MIT license. + +Consider a dataset like [["February", 34], ["March", 20], ...]. This plugin +allows you to plot such a dataset directly. + +To enable it, you must specify mode: "categories" on the axis with the textual +labels, e.g. + + $.plot("#placeholder", data, { xaxis: { mode: "categories" } }); + +By default, the labels are ordered as they are met in the data series. If you +need a different ordering, you can specify "categories" on the axis options +and list the categories there: + + xaxis: { + mode: "categories", + categories: ["February", "March", "April"] + } + +If you need to customize the distances between the categories, you can specify +"categories" as an object mapping labels to values + + xaxis: { + mode: "categories", + categories: { "February": 1, "March": 3, "April": 4 } + } + +If you don't specify all categories, the remaining categories will be numbered +from the max value plus 1 (with a spacing of 1 between each). + +Internally, the plugin works by transforming the input data through an auto- +generated mapping where the first category becomes 0, the second 1, etc. +Hence, a point like ["February", 34] becomes [0, 34] internally in Flot (this +is visible in hover and click events that return numbers rather than the +category labels). The plugin also overrides the tick generator to spit out the +categories as ticks instead of the values. + +If you need to map a value back to its label, the mapping is always accessible +as "categories" on the axis object, e.g. plot.getAxes().xaxis.categories. + +*/ + +(function ($) { + var options = { + xaxis: { + categories: null + }, + yaxis: { + categories: null + } + }; + + function processRawData(plot, series, data, datapoints) { + // if categories are enabled, we need to disable + // auto-transformation to numbers so the strings are intact + // for later processing + + var xCategories = series.xaxis.options.mode == "categories", + yCategories = series.yaxis.options.mode == "categories"; + + if (!(xCategories || yCategories)) + return; + + var format = datapoints.format; + + if (!format) { + // FIXME: auto-detection should really not be defined here + var s = series; + format = []; + format.push({ x: true, number: true, required: true }); + format.push({ y: true, number: true, required: true }); + + if (s.bars.show || (s.lines.show && s.lines.fill)) { + var autoscale = !!((s.bars.show && s.bars.zero) || (s.lines.show && s.lines.zero)); + format.push({ y: true, number: true, required: false, defaultValue: 0, autoscale: autoscale }); + if (s.bars.horizontal) { + delete format[format.length - 1].y; + format[format.length - 1].x = true; + } + } + + datapoints.format = format; + } + + for (var m = 0; m < format.length; ++m) { + if (format[m].x && xCategories) + format[m].number = false; + + if (format[m].y && yCategories) + format[m].number = false; + } + } + + function getNextIndex(categories) { + var index = -1; + + for (var v in categories) + if (categories[v] > index) + index = categories[v]; + + return index + 1; + } + + function categoriesTickGenerator(axis) { + var res = []; + for (var label in axis.categories) { + var v = axis.categories[label]; + if (v >= axis.min && v <= axis.max) + res.push([v, label]); + } + + res.sort(function (a, b) { return a[0] - b[0]; }); + + return res; + } + + function setupCategoriesForAxis(series, axis, datapoints) { + if (series[axis].options.mode != "categories") + return; + + if (!series[axis].categories) { + // parse options + var c = {}, o = series[axis].options.categories || {}; + if ($.isArray(o)) { + for (var i = 0; i < o.length; ++i) + c[o[i]] = i; + } + else { + for (var v in o) + c[v] = o[v]; + } + + series[axis].categories = c; + } + + // fix ticks + if (!series[axis].options.ticks) + series[axis].options.ticks = categoriesTickGenerator; + + transformPointsOnAxis(datapoints, axis, series[axis].categories); + } + + function transformPointsOnAxis(datapoints, axis, categories) { + // go through the points, transforming them + var points = datapoints.points, + ps = datapoints.pointsize, + format = datapoints.format, + formatColumn = axis.charAt(0), + index = getNextIndex(categories); + + for (var i = 0; i < points.length; i += ps) { + if (points[i] == null) + continue; + + for (var m = 0; m < ps; ++m) { + var val = points[i + m]; + + if (val == null || !format[m][formatColumn]) + continue; + + if (!(val in categories)) { + categories[val] = index; + ++index; + } + + points[i + m] = categories[val]; + } + } + } + + function processDatapoints(plot, series, datapoints) { + setupCategoriesForAxis(series, "xaxis", datapoints); + setupCategoriesForAxis(series, "yaxis", datapoints); + } + + function init(plot) { + plot.hooks.processRawData.push(processRawData); + plot.hooks.processDatapoints.push(processDatapoints); + } + + $.plot.plugins.push({ + init: init, + options: options, + name: 'categories', + version: '1.0' + }); +})(jQuery); diff --git a/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.crosshair.js b/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.crosshair.js new file mode 100644 index 0000000000000000000000000000000000000000..5111695e3d12cedc94f5538ce37a2799e9b662ad --- /dev/null +++ b/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.crosshair.js @@ -0,0 +1,176 @@ +/* Flot plugin for showing crosshairs when the mouse hovers over the plot. + +Copyright (c) 2007-2014 IOLA and Ole Laursen. +Licensed under the MIT license. + +The plugin supports these options: + + crosshair: { + mode: null or "x" or "y" or "xy" + color: color + lineWidth: number + } + +Set the mode to one of "x", "y" or "xy". The "x" mode enables a vertical +crosshair that lets you trace the values on the x axis, "y" enables a +horizontal crosshair and "xy" enables them both. "color" is the color of the +crosshair (default is "rgba(170, 0, 0, 0.80)"), "lineWidth" is the width of +the drawn lines (default is 1). + +The plugin also adds four public methods: + + - setCrosshair( pos ) + + Set the position of the crosshair. Note that this is cleared if the user + moves the mouse. "pos" is in coordinates of the plot and should be on the + form { x: xpos, y: ypos } (you can use x2/x3/... if you're using multiple + axes), which is coincidentally the same format as what you get from a + "plothover" event. If "pos" is null, the crosshair is cleared. + + - clearCrosshair() + + Clear the crosshair. + + - lockCrosshair(pos) + + Cause the crosshair to lock to the current location, no longer updating if + the user moves the mouse. Optionally supply a position (passed on to + setCrosshair()) to move it to. + + Example usage: + + var myFlot = $.plot( $("#graph"), ..., { crosshair: { mode: "x" } } }; + $("#graph").bind( "plothover", function ( evt, position, item ) { + if ( item ) { + // Lock the crosshair to the data point being hovered + myFlot.lockCrosshair({ + x: item.datapoint[ 0 ], + y: item.datapoint[ 1 ] + }); + } else { + // Return normal crosshair operation + myFlot.unlockCrosshair(); + } + }); + + - unlockCrosshair() + + Free the crosshair to move again after locking it. +*/ + +(function ($) { + var options = { + crosshair: { + mode: null, // one of null, "x", "y" or "xy", + color: "rgba(170, 0, 0, 0.80)", + lineWidth: 1 + } + }; + + function init(plot) { + // position of crosshair in pixels + var crosshair = { x: -1, y: -1, locked: false }; + + plot.setCrosshair = function setCrosshair(pos) { + if (!pos) + crosshair.x = -1; + else { + var o = plot.p2c(pos); + crosshair.x = Math.max(0, Math.min(o.left, plot.width())); + crosshair.y = Math.max(0, Math.min(o.top, plot.height())); + } + + plot.triggerRedrawOverlay(); + }; + + plot.clearCrosshair = plot.setCrosshair; // passes null for pos + + plot.lockCrosshair = function lockCrosshair(pos) { + if (pos) + plot.setCrosshair(pos); + crosshair.locked = true; + }; + + plot.unlockCrosshair = function unlockCrosshair() { + crosshair.locked = false; + }; + + function onMouseOut(e) { + if (crosshair.locked) + return; + + if (crosshair.x != -1) { + crosshair.x = -1; + plot.triggerRedrawOverlay(); + } + } + + function onMouseMove(e) { + if (crosshair.locked) + return; + + if (plot.getSelection && plot.getSelection()) { + crosshair.x = -1; // hide the crosshair while selecting + return; + } + + var offset = plot.offset(); + crosshair.x = Math.max(0, Math.min(e.pageX - offset.left, plot.width())); + crosshair.y = Math.max(0, Math.min(e.pageY - offset.top, plot.height())); + plot.triggerRedrawOverlay(); + } + + plot.hooks.bindEvents.push(function (plot, eventHolder) { + if (!plot.getOptions().crosshair.mode) + return; + + eventHolder.mouseout(onMouseOut); + eventHolder.mousemove(onMouseMove); + }); + + plot.hooks.drawOverlay.push(function (plot, ctx) { + var c = plot.getOptions().crosshair; + if (!c.mode) + return; + + var plotOffset = plot.getPlotOffset(); + + ctx.save(); + ctx.translate(plotOffset.left, plotOffset.top); + + if (crosshair.x != -1) { + var adj = plot.getOptions().crosshair.lineWidth % 2 ? 0.5 : 0; + + ctx.strokeStyle = c.color; + ctx.lineWidth = c.lineWidth; + ctx.lineJoin = "round"; + + ctx.beginPath(); + if (c.mode.indexOf("x") != -1) { + var drawX = Math.floor(crosshair.x) + adj; + ctx.moveTo(drawX, 0); + ctx.lineTo(drawX, plot.height()); + } + if (c.mode.indexOf("y") != -1) { + var drawY = Math.floor(crosshair.y) + adj; + ctx.moveTo(0, drawY); + ctx.lineTo(plot.width(), drawY); + } + ctx.stroke(); + } + ctx.restore(); + }); + + plot.hooks.shutdown.push(function (plot, eventHolder) { + eventHolder.unbind("mouseout", onMouseOut); + eventHolder.unbind("mousemove", onMouseMove); + }); + } + + $.plot.plugins.push({ + init: init, + options: options, + name: 'crosshair', + version: '1.0' + }); +})(jQuery); diff --git a/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.errorbars.js b/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.errorbars.js new file mode 100644 index 0000000000000000000000000000000000000000..2583d5c20c3213b104fece922128f4a7ff0b6069 --- /dev/null +++ b/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.errorbars.js @@ -0,0 +1,353 @@ +/* Flot plugin for plotting error bars. + +Copyright (c) 2007-2014 IOLA and Ole Laursen. +Licensed under the MIT license. + +Error bars are used to show standard deviation and other statistical +properties in a plot. + +* Created by Rui Pereira - rui (dot) pereira (at) gmail (dot) com + +This plugin allows you to plot error-bars over points. Set "errorbars" inside +the points series to the axis name over which there will be error values in +your data array (*even* if you do not intend to plot them later, by setting +"show: null" on xerr/yerr). + +The plugin supports these options: + + series: { + points: { + errorbars: "x" or "y" or "xy", + xerr: { + show: null/false or true, + asymmetric: null/false or true, + upperCap: null or "-" or function, + lowerCap: null or "-" or function, + color: null or color, + radius: null or number + }, + yerr: { same options as xerr } + } + } + +Each data point array is expected to be of the type: + + "x" [ x, y, xerr ] + "y" [ x, y, yerr ] + "xy" [ x, y, xerr, yerr ] + +Where xerr becomes xerr_lower,xerr_upper for the asymmetric error case, and +equivalently for yerr. Eg., a datapoint for the "xy" case with symmetric +error-bars on X and asymmetric on Y would be: + + [ x, y, xerr, yerr_lower, yerr_upper ] + +By default no end caps are drawn. Setting upperCap and/or lowerCap to "-" will +draw a small cap perpendicular to the error bar. They can also be set to a +user-defined drawing function, with (ctx, x, y, radius) as parameters, as eg. + + function drawSemiCircle( ctx, x, y, radius ) { + ctx.beginPath(); + ctx.arc( x, y, radius, 0, Math.PI, false ); + ctx.moveTo( x - radius, y ); + ctx.lineTo( x + radius, y ); + ctx.stroke(); + } + +Color and radius both default to the same ones of the points series if not +set. The independent radius parameter on xerr/yerr is useful for the case when +we may want to add error-bars to a line, without showing the interconnecting +points (with radius: 0), and still showing end caps on the error-bars. +shadowSize and lineWidth are derived as well from the points series. + +*/ + +(function ($) { + var options = { + series: { + points: { + errorbars: null, //should be 'x', 'y' or 'xy' + xerr: { err: 'x', show: null, asymmetric: null, upperCap: null, lowerCap: null, color: null, radius: null}, + yerr: { err: 'y', show: null, asymmetric: null, upperCap: null, lowerCap: null, color: null, radius: null} + } + } + }; + + function processRawData(plot, series, data, datapoints){ + if (!series.points.errorbars) + return; + + // x,y values + var format = [ + { x: true, number: true, required: true }, + { y: true, number: true, required: true } + ]; + + var errors = series.points.errorbars; + // error bars - first X then Y + if (errors == 'x' || errors == 'xy') { + // lower / upper error + if (series.points.xerr.asymmetric) { + format.push({ x: true, number: true, required: true }); + format.push({ x: true, number: true, required: true }); + } else + format.push({ x: true, number: true, required: true }); + } + if (errors == 'y' || errors == 'xy') { + // lower / upper error + if (series.points.yerr.asymmetric) { + format.push({ y: true, number: true, required: true }); + format.push({ y: true, number: true, required: true }); + } else + format.push({ y: true, number: true, required: true }); + } + datapoints.format = format; + } + + function parseErrors(series, i){ + + var points = series.datapoints.points; + + // read errors from points array + var exl = null, + exu = null, + eyl = null, + eyu = null; + var xerr = series.points.xerr, + yerr = series.points.yerr; + + var eb = series.points.errorbars; + // error bars - first X + if (eb == 'x' || eb == 'xy') { + if (xerr.asymmetric) { + exl = points[i + 2]; + exu = points[i + 3]; + if (eb == 'xy') + if (yerr.asymmetric){ + eyl = points[i + 4]; + eyu = points[i + 5]; + } else eyl = points[i + 4]; + } else { + exl = points[i + 2]; + if (eb == 'xy') + if (yerr.asymmetric) { + eyl = points[i + 3]; + eyu = points[i + 4]; + } else eyl = points[i + 3]; + } + // only Y + } else if (eb == 'y') + if (yerr.asymmetric) { + eyl = points[i + 2]; + eyu = points[i + 3]; + } else eyl = points[i + 2]; + + // symmetric errors? + if (exu == null) exu = exl; + if (eyu == null) eyu = eyl; + + var errRanges = [exl, exu, eyl, eyu]; + // nullify if not showing + if (!xerr.show){ + errRanges[0] = null; + errRanges[1] = null; + } + if (!yerr.show){ + errRanges[2] = null; + errRanges[3] = null; + } + return errRanges; + } + + function drawSeriesErrors(plot, ctx, s){ + + var points = s.datapoints.points, + ps = s.datapoints.pointsize, + ax = [s.xaxis, s.yaxis], + radius = s.points.radius, + err = [s.points.xerr, s.points.yerr]; + + //sanity check, in case some inverted axis hack is applied to flot + var invertX = false; + if (ax[0].p2c(ax[0].max) < ax[0].p2c(ax[0].min)) { + invertX = true; + var tmp = err[0].lowerCap; + err[0].lowerCap = err[0].upperCap; + err[0].upperCap = tmp; + } + + var invertY = false; + if (ax[1].p2c(ax[1].min) < ax[1].p2c(ax[1].max)) { + invertY = true; + var tmp = err[1].lowerCap; + err[1].lowerCap = err[1].upperCap; + err[1].upperCap = tmp; + } + + for (var i = 0; i < s.datapoints.points.length; i += ps) { + + //parse + var errRanges = parseErrors(s, i); + + //cycle xerr & yerr + for (var e = 0; e < err.length; e++){ + + var minmax = [ax[e].min, ax[e].max]; + + //draw this error? + if (errRanges[e * err.length]){ + + //data coordinates + var x = points[i], + y = points[i + 1]; + + //errorbar ranges + var upper = [x, y][e] + errRanges[e * err.length + 1], + lower = [x, y][e] - errRanges[e * err.length]; + + //points outside of the canvas + if (err[e].err == 'x') + if (y > ax[1].max || y < ax[1].min || upper < ax[0].min || lower > ax[0].max) + continue; + if (err[e].err == 'y') + if (x > ax[0].max || x < ax[0].min || upper < ax[1].min || lower > ax[1].max) + continue; + + // prevent errorbars getting out of the canvas + var drawUpper = true, + drawLower = true; + + if (upper > minmax[1]) { + drawUpper = false; + upper = minmax[1]; + } + if (lower < minmax[0]) { + drawLower = false; + lower = minmax[0]; + } + + //sanity check, in case some inverted axis hack is applied to flot + if ((err[e].err == 'x' && invertX) || (err[e].err == 'y' && invertY)) { + //swap coordinates + var tmp = lower; + lower = upper; + upper = tmp; + tmp = drawLower; + drawLower = drawUpper; + drawUpper = tmp; + tmp = minmax[0]; + minmax[0] = minmax[1]; + minmax[1] = tmp; + } + + // convert to pixels + x = ax[0].p2c(x), + y = ax[1].p2c(y), + upper = ax[e].p2c(upper); + lower = ax[e].p2c(lower); + minmax[0] = ax[e].p2c(minmax[0]); + minmax[1] = ax[e].p2c(minmax[1]); + + //same style as points by default + var lw = err[e].lineWidth ? err[e].lineWidth : s.points.lineWidth, + sw = s.points.shadowSize != null ? s.points.shadowSize : s.shadowSize; + + //shadow as for points + if (lw > 0 && sw > 0) { + var w = sw / 2; + ctx.lineWidth = w; + ctx.strokeStyle = "rgba(0,0,0,0.1)"; + drawError(ctx, err[e], x, y, upper, lower, drawUpper, drawLower, radius, w + w/2, minmax); + + ctx.strokeStyle = "rgba(0,0,0,0.2)"; + drawError(ctx, err[e], x, y, upper, lower, drawUpper, drawLower, radius, w/2, minmax); + } + + ctx.strokeStyle = err[e].color? err[e].color: s.color; + ctx.lineWidth = lw; + //draw it + drawError(ctx, err[e], x, y, upper, lower, drawUpper, drawLower, radius, 0, minmax); + } + } + } + } + + function drawError(ctx,err,x,y,upper,lower,drawUpper,drawLower,radius,offset,minmax){ + + //shadow offset + y += offset; + upper += offset; + lower += offset; + + // error bar - avoid plotting over circles + if (err.err == 'x'){ + if (upper > x + radius) drawPath(ctx, [[upper,y],[Math.max(x + radius,minmax[0]),y]]); + else drawUpper = false; + if (lower < x - radius) drawPath(ctx, [[Math.min(x - radius,minmax[1]),y],[lower,y]] ); + else drawLower = false; + } + else { + if (upper < y - radius) drawPath(ctx, [[x,upper],[x,Math.min(y - radius,minmax[0])]] ); + else drawUpper = false; + if (lower > y + radius) drawPath(ctx, [[x,Math.max(y + radius,minmax[1])],[x,lower]] ); + else drawLower = false; + } + + //internal radius value in errorbar, allows to plot radius 0 points and still keep proper sized caps + //this is a way to get errorbars on lines without visible connecting dots + radius = err.radius != null? err.radius: radius; + + // upper cap + if (drawUpper) { + if (err.upperCap == '-'){ + if (err.err=='x') drawPath(ctx, [[upper,y - radius],[upper,y + radius]] ); + else drawPath(ctx, [[x - radius,upper],[x + radius,upper]] ); + } else if ($.isFunction(err.upperCap)){ + if (err.err=='x') err.upperCap(ctx, upper, y, radius); + else err.upperCap(ctx, x, upper, radius); + } + } + // lower cap + if (drawLower) { + if (err.lowerCap == '-'){ + if (err.err=='x') drawPath(ctx, [[lower,y - radius],[lower,y + radius]] ); + else drawPath(ctx, [[x - radius,lower],[x + radius,lower]] ); + } else if ($.isFunction(err.lowerCap)){ + if (err.err=='x') err.lowerCap(ctx, lower, y, radius); + else err.lowerCap(ctx, x, lower, radius); + } + } + } + + function drawPath(ctx, pts){ + ctx.beginPath(); + ctx.moveTo(pts[0][0], pts[0][1]); + for (var p=1; p < pts.length; p++) + ctx.lineTo(pts[p][0], pts[p][1]); + ctx.stroke(); + } + + function draw(plot, ctx){ + var plotOffset = plot.getPlotOffset(); + + ctx.save(); + ctx.translate(plotOffset.left, plotOffset.top); + $.each(plot.getData(), function (i, s) { + if (s.points.errorbars && (s.points.xerr.show || s.points.yerr.show)) + drawSeriesErrors(plot, ctx, s); + }); + ctx.restore(); + } + + function init(plot) { + plot.hooks.processRawData.push(processRawData); + plot.hooks.draw.push(draw); + } + + $.plot.plugins.push({ + init: init, + options: options, + name: 'errorbars', + version: '1.0' + }); +})(jQuery); diff --git a/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.fillbetween.js b/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.fillbetween.js new file mode 100644 index 0000000000000000000000000000000000000000..18b15d26db8c91e8527ea35f87d39674bb8f1c70 --- /dev/null +++ b/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.fillbetween.js @@ -0,0 +1,226 @@ +/* Flot plugin for computing bottoms for filled line and bar charts. + +Copyright (c) 2007-2014 IOLA and Ole Laursen. +Licensed under the MIT license. + +The case: you've got two series that you want to fill the area between. In Flot +terms, you need to use one as the fill bottom of the other. You can specify the +bottom of each data point as the third coordinate manually, or you can use this +plugin to compute it for you. + +In order to name the other series, you need to give it an id, like this: + + var dataset = [ + { data: [ ... ], id: "foo" } , // use default bottom + { data: [ ... ], fillBetween: "foo" }, // use first dataset as bottom + ]; + + $.plot($("#placeholder"), dataset, { lines: { show: true, fill: true }}); + +As a convenience, if the id given is a number that doesn't appear as an id in +the series, it is interpreted as the index in the array instead (so fillBetween: +0 can also mean the first series). + +Internally, the plugin modifies the datapoints in each series. For line series, +extra data points might be inserted through interpolation. Note that at points +where the bottom line is not defined (due to a null point or start/end of line), +the current line will show a gap too. The algorithm comes from the +jquery.flot.stack.js plugin, possibly some code could be shared. + +*/ + +(function ( $ ) { + + var options = { + series: { + fillBetween: null // or number + } + }; + + function init( plot ) { + + function findBottomSeries( s, allseries ) { + + var i; + + for ( i = 0; i < allseries.length; ++i ) { + if ( allseries[ i ].id === s.fillBetween ) { + return allseries[ i ]; + } + } + + if ( typeof s.fillBetween === "number" ) { + if ( s.fillBetween < 0 || s.fillBetween >= allseries.length ) { + return null; + } + return allseries[ s.fillBetween ]; + } + + return null; + } + + function computeFillBottoms( plot, s, datapoints ) { + + if ( s.fillBetween == null ) { + return; + } + + var other = findBottomSeries( s, plot.getData() ); + + if ( !other ) { + return; + } + + var ps = datapoints.pointsize, + points = datapoints.points, + otherps = other.datapoints.pointsize, + otherpoints = other.datapoints.points, + newpoints = [], + px, py, intery, qx, qy, bottom, + withlines = s.lines.show, + withbottom = ps > 2 && datapoints.format[2].y, + withsteps = withlines && s.lines.steps, + fromgap = true, + i = 0, + j = 0, + l, m; + + while ( true ) { + + if ( i >= points.length ) { + break; + } + + l = newpoints.length; + + if ( points[ i ] == null ) { + + // copy gaps + + for ( m = 0; m < ps; ++m ) { + newpoints.push( points[ i + m ] ); + } + + i += ps; + + } else if ( j >= otherpoints.length ) { + + // for lines, we can't use the rest of the points + + if ( !withlines ) { + for ( m = 0; m < ps; ++m ) { + newpoints.push( points[ i + m ] ); + } + } + + i += ps; + + } else if ( otherpoints[ j ] == null ) { + + // oops, got a gap + + for ( m = 0; m < ps; ++m ) { + newpoints.push( null ); + } + + fromgap = true; + j += otherps; + + } else { + + // cases where we actually got two points + + px = points[ i ]; + py = points[ i + 1 ]; + qx = otherpoints[ j ]; + qy = otherpoints[ j + 1 ]; + bottom = 0; + + if ( px === qx ) { + + for ( m = 0; m < ps; ++m ) { + newpoints.push( points[ i + m ] ); + } + + //newpoints[ l + 1 ] += qy; + bottom = qy; + + i += ps; + j += otherps; + + } else if ( px > qx ) { + + // we got past point below, might need to + // insert interpolated extra point + + if ( withlines && i > 0 && points[ i - ps ] != null ) { + intery = py + ( points[ i - ps + 1 ] - py ) * ( qx - px ) / ( points[ i - ps ] - px ); + newpoints.push( qx ); + newpoints.push( intery ); + for ( m = 2; m < ps; ++m ) { + newpoints.push( points[ i + m ] ); + } + bottom = qy; + } + + j += otherps; + + } else { // px < qx + + // if we come from a gap, we just skip this point + + if ( fromgap && withlines ) { + i += ps; + continue; + } + + for ( m = 0; m < ps; ++m ) { + newpoints.push( points[ i + m ] ); + } + + // we might be able to interpolate a point below, + // this can give us a better y + + if ( withlines && j > 0 && otherpoints[ j - otherps ] != null ) { + bottom = qy + ( otherpoints[ j - otherps + 1 ] - qy ) * ( px - qx ) / ( otherpoints[ j - otherps ] - qx ); + } + + //newpoints[l + 1] += bottom; + + i += ps; + } + + fromgap = false; + + if ( l !== newpoints.length && withbottom ) { + newpoints[ l + 2 ] = bottom; + } + } + + // maintain the line steps invariant + + if ( withsteps && l !== newpoints.length && l > 0 && + newpoints[ l ] !== null && + newpoints[ l ] !== newpoints[ l - ps ] && + newpoints[ l + 1 ] !== newpoints[ l - ps + 1 ] ) { + for (m = 0; m < ps; ++m) { + newpoints[ l + ps + m ] = newpoints[ l + m ]; + } + newpoints[ l + 1 ] = newpoints[ l - ps + 1 ]; + } + } + + datapoints.points = newpoints; + } + + plot.hooks.processDatapoints.push( computeFillBottoms ); + } + + $.plot.plugins.push({ + init: init, + options: options, + name: "fillbetween", + version: "1.0" + }); + +})(jQuery); diff --git a/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.image.js b/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.image.js new file mode 100644 index 0000000000000000000000000000000000000000..625a03571d270151c5df9075462e47c231c28a00 --- /dev/null +++ b/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.image.js @@ -0,0 +1,241 @@ +/* Flot plugin for plotting images. + +Copyright (c) 2007-2014 IOLA and Ole Laursen. +Licensed under the MIT license. + +The data syntax is [ [ image, x1, y1, x2, y2 ], ... ] where (x1, y1) and +(x2, y2) are where you intend the two opposite corners of the image to end up +in the plot. Image must be a fully loaded Javascript image (you can make one +with new Image()). If the image is not complete, it's skipped when plotting. + +There are two helpers included for retrieving images. The easiest work the way +that you put in URLs instead of images in the data, like this: + + [ "myimage.png", 0, 0, 10, 10 ] + +Then call $.plot.image.loadData( data, options, callback ) where data and +options are the same as you pass in to $.plot. This loads the images, replaces +the URLs in the data with the corresponding images and calls "callback" when +all images are loaded (or failed loading). In the callback, you can then call +$.plot with the data set. See the included example. + +A more low-level helper, $.plot.image.load(urls, callback) is also included. +Given a list of URLs, it calls callback with an object mapping from URL to +Image object when all images are loaded or have failed loading. + +The plugin supports these options: + + series: { + images: { + show: boolean + anchor: "corner" or "center" + alpha: [ 0, 1 ] + } + } + +They can be specified for a specific series: + + $.plot( $("#placeholder"), [{ + data: [ ... ], + images: { ... } + ]) + +Note that because the data format is different from usual data points, you +can't use images with anything else in a specific data series. + +Setting "anchor" to "center" causes the pixels in the image to be anchored at +the corner pixel centers inside of at the pixel corners, effectively letting +half a pixel stick out to each side in the plot. + +A possible future direction could be support for tiling for large images (like +Google Maps). + +*/ + +(function ($) { + var options = { + series: { + images: { + show: false, + alpha: 1, + anchor: "corner" // or "center" + } + } + }; + + $.plot.image = {}; + + $.plot.image.loadDataImages = function (series, options, callback) { + var urls = [], points = []; + + var defaultShow = options.series.images.show; + + $.each(series, function (i, s) { + if (!(defaultShow || s.images.show)) + return; + + if (s.data) + s = s.data; + + $.each(s, function (i, p) { + if (typeof p[0] == "string") { + urls.push(p[0]); + points.push(p); + } + }); + }); + + $.plot.image.load(urls, function (loadedImages) { + $.each(points, function (i, p) { + var url = p[0]; + if (loadedImages[url]) + p[0] = loadedImages[url]; + }); + + callback(); + }); + } + + $.plot.image.load = function (urls, callback) { + var missing = urls.length, loaded = {}; + if (missing == 0) + callback({}); + + $.each(urls, function (i, url) { + var handler = function () { + --missing; + + loaded[url] = this; + + if (missing == 0) + callback(loaded); + }; + + $('<img />').load(handler).error(handler).attr('src', url); + }); + }; + + function drawSeries(plot, ctx, series) { + var plotOffset = plot.getPlotOffset(); + + if (!series.images || !series.images.show) + return; + + var points = series.datapoints.points, + ps = series.datapoints.pointsize; + + for (var i = 0; i < points.length; i += ps) { + var img = points[i], + x1 = points[i + 1], y1 = points[i + 2], + x2 = points[i + 3], y2 = points[i + 4], + xaxis = series.xaxis, yaxis = series.yaxis, + tmp; + + // actually we should check img.complete, but it + // appears to be a somewhat unreliable indicator in + // IE6 (false even after load event) + if (!img || img.width <= 0 || img.height <= 0) + continue; + + if (x1 > x2) { + tmp = x2; + x2 = x1; + x1 = tmp; + } + if (y1 > y2) { + tmp = y2; + y2 = y1; + y1 = tmp; + } + + // if the anchor is at the center of the pixel, expand the + // image by 1/2 pixel in each direction + if (series.images.anchor == "center") { + tmp = 0.5 * (x2-x1) / (img.width - 1); + x1 -= tmp; + x2 += tmp; + tmp = 0.5 * (y2-y1) / (img.height - 1); + y1 -= tmp; + y2 += tmp; + } + + // clip + if (x1 == x2 || y1 == y2 || + x1 >= xaxis.max || x2 <= xaxis.min || + y1 >= yaxis.max || y2 <= yaxis.min) + continue; + + var sx1 = 0, sy1 = 0, sx2 = img.width, sy2 = img.height; + if (x1 < xaxis.min) { + sx1 += (sx2 - sx1) * (xaxis.min - x1) / (x2 - x1); + x1 = xaxis.min; + } + + if (x2 > xaxis.max) { + sx2 += (sx2 - sx1) * (xaxis.max - x2) / (x2 - x1); + x2 = xaxis.max; + } + + if (y1 < yaxis.min) { + sy2 += (sy1 - sy2) * (yaxis.min - y1) / (y2 - y1); + y1 = yaxis.min; + } + + if (y2 > yaxis.max) { + sy1 += (sy1 - sy2) * (yaxis.max - y2) / (y2 - y1); + y2 = yaxis.max; + } + + x1 = xaxis.p2c(x1); + x2 = xaxis.p2c(x2); + y1 = yaxis.p2c(y1); + y2 = yaxis.p2c(y2); + + // the transformation may have swapped us + if (x1 > x2) { + tmp = x2; + x2 = x1; + x1 = tmp; + } + if (y1 > y2) { + tmp = y2; + y2 = y1; + y1 = tmp; + } + + tmp = ctx.globalAlpha; + ctx.globalAlpha *= series.images.alpha; + ctx.drawImage(img, + sx1, sy1, sx2 - sx1, sy2 - sy1, + x1 + plotOffset.left, y1 + plotOffset.top, + x2 - x1, y2 - y1); + ctx.globalAlpha = tmp; + } + } + + function processRawData(plot, series, data, datapoints) { + if (!series.images.show) + return; + + // format is Image, x1, y1, x2, y2 (opposite corners) + datapoints.format = [ + { required: true }, + { x: true, number: true, required: true }, + { y: true, number: true, required: true }, + { x: true, number: true, required: true }, + { y: true, number: true, required: true } + ]; + } + + function init(plot) { + plot.hooks.processRawData.push(processRawData); + plot.hooks.drawSeries.push(drawSeries); + } + + $.plot.plugins.push({ + init: init, + options: options, + name: 'image', + version: '1.1' + }); +})(jQuery); diff --git a/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.js b/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.js new file mode 100644 index 0000000000000000000000000000000000000000..39f3e4cf3efe5c314d7c9d1ee3626acc84c0822e --- /dev/null +++ b/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.js @@ -0,0 +1,3168 @@ +/* Javascript plotting library for jQuery, version 0.8.3. + +Copyright (c) 2007-2014 IOLA and Ole Laursen. +Licensed under the MIT license. + +*/ + +// first an inline dependency, jquery.colorhelpers.js, we inline it here +// for convenience + +/* Plugin for jQuery for working with colors. + * + * Version 1.1. + * + * Inspiration from jQuery color animation plugin by John Resig. + * + * Released under the MIT license by Ole Laursen, October 2009. + * + * Examples: + * + * $.color.parse("#fff").scale('rgb', 0.25).add('a', -0.5).toString() + * var c = $.color.extract($("#mydiv"), 'background-color'); + * console.log(c.r, c.g, c.b, c.a); + * $.color.make(100, 50, 25, 0.4).toString() // returns "rgba(100,50,25,0.4)" + * + * Note that .scale() and .add() return the same modified object + * instead of making a new one. + * + * V. 1.1: Fix error handling so e.g. parsing an empty string does + * produce a color rather than just crashing. + */ +(function($){$.color={};$.color.make=function(r,g,b,a){var o={};o.r=r||0;o.g=g||0;o.b=b||0;o.a=a!=null?a:1;o.add=function(c,d){for(var i=0;i<c.length;++i)o[c.charAt(i)]+=d;return o.normalize()};o.scale=function(c,f){for(var i=0;i<c.length;++i)o[c.charAt(i)]*=f;return o.normalize()};o.toString=function(){if(o.a>=1){return"rgb("+[o.r,o.g,o.b].join(",")+")"}else{return"rgba("+[o.r,o.g,o.b,o.a].join(",")+")"}};o.normalize=function(){function clamp(min,value,max){return value<min?min:value>max?max:value}o.r=clamp(0,parseInt(o.r),255);o.g=clamp(0,parseInt(o.g),255);o.b=clamp(0,parseInt(o.b),255);o.a=clamp(0,o.a,1);return o};o.clone=function(){return $.color.make(o.r,o.b,o.g,o.a)};return o.normalize()};$.color.extract=function(elem,css){var c;do{c=elem.css(css).toLowerCase();if(c!=""&&c!="transparent")break;elem=elem.parent()}while(elem.length&&!$.nodeName(elem.get(0),"body"));if(c=="rgba(0, 0, 0, 0)")c="transparent";return $.color.parse(c)};$.color.parse=function(str){var res,m=$.color.make;if(res=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str))return m(parseInt(res[1],10),parseInt(res[2],10),parseInt(res[3],10));if(res=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))return m(parseInt(res[1],10),parseInt(res[2],10),parseInt(res[3],10),parseFloat(res[4]));if(res=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(str))return m(parseFloat(res[1])*2.55,parseFloat(res[2])*2.55,parseFloat(res[3])*2.55);if(res=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))return m(parseFloat(res[1])*2.55,parseFloat(res[2])*2.55,parseFloat(res[3])*2.55,parseFloat(res[4]));if(res=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str))return m(parseInt(res[1],16),parseInt(res[2],16),parseInt(res[3],16));if(res=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str))return m(parseInt(res[1]+res[1],16),parseInt(res[2]+res[2],16),parseInt(res[3]+res[3],16));var name=$.trim(str).toLowerCase();if(name=="transparent")return m(255,255,255,0);else{res=lookupColors[name]||[0,0,0];return m(res[0],res[1],res[2])}};var lookupColors={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}})(jQuery); + +// the actual Flot code +(function($) { + + // Cache the prototype hasOwnProperty for faster access + + var hasOwnProperty = Object.prototype.hasOwnProperty; + + // A shim to provide 'detach' to jQuery versions prior to 1.4. Using a DOM + // operation produces the same effect as detach, i.e. removing the element + // without touching its jQuery data. + + // Do not merge this into Flot 0.9, since it requires jQuery 1.4.4+. + + if (!$.fn.detach) { + $.fn.detach = function() { + return this.each(function() { + if (this.parentNode) { + this.parentNode.removeChild( this ); + } + }); + }; + } + + /////////////////////////////////////////////////////////////////////////// + // The Canvas object is a wrapper around an HTML5 <canvas> tag. + // + // @constructor + // @param {string} cls List of classes to apply to the canvas. + // @param {element} container Element onto which to append the canvas. + // + // Requiring a container is a little iffy, but unfortunately canvas + // operations don't work unless the canvas is attached to the DOM. + + function Canvas(cls, container) { + + var element = container.children("." + cls)[0]; + + if (element == null) { + + element = document.createElement("canvas"); + element.className = cls; + + $(element).css({ direction: "ltr", position: "absolute", left: 0, top: 0 }) + .appendTo(container); + + // If HTML5 Canvas isn't available, fall back to [Ex|Flash]canvas + + if (!element.getContext) { + if (window.G_vmlCanvasManager) { + element = window.G_vmlCanvasManager.initElement(element); + } else { + throw new Error("Canvas is not available. If you're using IE with a fall-back such as Excanvas, then there's either a mistake in your conditional include, or the page has no DOCTYPE and is rendering in Quirks Mode."); + } + } + } + + this.element = element; + + var context = this.context = element.getContext("2d"); + + // Determine the screen's ratio of physical to device-independent + // pixels. This is the ratio between the canvas width that the browser + // advertises and the number of pixels actually present in that space. + + // The iPhone 4, for example, has a device-independent width of 320px, + // but its screen is actually 640px wide. It therefore has a pixel + // ratio of 2, while most normal devices have a ratio of 1. + + var devicePixelRatio = window.devicePixelRatio || 1, + backingStoreRatio = + context.webkitBackingStorePixelRatio || + context.mozBackingStorePixelRatio || + context.msBackingStorePixelRatio || + context.oBackingStorePixelRatio || + context.backingStorePixelRatio || 1; + + this.pixelRatio = devicePixelRatio / backingStoreRatio; + + // Size the canvas to match the internal dimensions of its container + + this.resize(container.width(), container.height()); + + // Collection of HTML div layers for text overlaid onto the canvas + + this.textContainer = null; + this.text = {}; + + // Cache of text fragments and metrics, so we can avoid expensively + // re-calculating them when the plot is re-rendered in a loop. + + this._textCache = {}; + } + + // Resizes the canvas to the given dimensions. + // + // @param {number} width New width of the canvas, in pixels. + // @param {number} width New height of the canvas, in pixels. + + Canvas.prototype.resize = function(width, height) { + + if (width <= 0 || height <= 0) { + throw new Error("Invalid dimensions for plot, width = " + width + ", height = " + height); + } + + var element = this.element, + context = this.context, + pixelRatio = this.pixelRatio; + + // Resize the canvas, increasing its density based on the display's + // pixel ratio; basically giving it more pixels without increasing the + // size of its element, to take advantage of the fact that retina + // displays have that many more pixels in the same advertised space. + + // Resizing should reset the state (excanvas seems to be buggy though) + + if (this.width != width) { + element.width = width * pixelRatio; + element.style.width = width + "px"; + this.width = width; + } + + if (this.height != height) { + element.height = height * pixelRatio; + element.style.height = height + "px"; + this.height = height; + } + + // Save the context, so we can reset in case we get replotted. The + // restore ensure that we're really back at the initial state, and + // should be safe even if we haven't saved the initial state yet. + + context.restore(); + context.save(); + + // Scale the coordinate space to match the display density; so even though we + // may have twice as many pixels, we still want lines and other drawing to + // appear at the same size; the extra pixels will just make them crisper. + + context.scale(pixelRatio, pixelRatio); + }; + + // Clears the entire canvas area, not including any overlaid HTML text + + Canvas.prototype.clear = function() { + this.context.clearRect(0, 0, this.width, this.height); + }; + + // Finishes rendering the canvas, including managing the text overlay. + + Canvas.prototype.render = function() { + + var cache = this._textCache; + + // For each text layer, add elements marked as active that haven't + // already been rendered, and remove those that are no longer active. + + for (var layerKey in cache) { + if (hasOwnProperty.call(cache, layerKey)) { + + var layer = this.getTextLayer(layerKey), + layerCache = cache[layerKey]; + + layer.hide(); + + for (var styleKey in layerCache) { + if (hasOwnProperty.call(layerCache, styleKey)) { + var styleCache = layerCache[styleKey]; + for (var key in styleCache) { + if (hasOwnProperty.call(styleCache, key)) { + + var positions = styleCache[key].positions; + + for (var i = 0, position; position = positions[i]; i++) { + if (position.active) { + if (!position.rendered) { + layer.append(position.element); + position.rendered = true; + } + } else { + positions.splice(i--, 1); + if (position.rendered) { + position.element.detach(); + } + } + } + + if (positions.length == 0) { + delete styleCache[key]; + } + } + } + } + } + + layer.show(); + } + } + }; + + // Creates (if necessary) and returns the text overlay container. + // + // @param {string} classes String of space-separated CSS classes used to + // uniquely identify the text layer. + // @return {object} The jQuery-wrapped text-layer div. + + Canvas.prototype.getTextLayer = function(classes) { + + var layer = this.text[classes]; + + // Create the text layer if it doesn't exist + + if (layer == null) { + + // Create the text layer container, if it doesn't exist + + if (this.textContainer == null) { + this.textContainer = $("<div class='flot-text'></div>") + .css({ + position: "absolute", + top: 0, + left: 0, + bottom: 0, + right: 0, + 'font-size': "smaller", + color: "#545454" + }) + .insertAfter(this.element); + } + + layer = this.text[classes] = $("<div></div>") + .addClass(classes) + .css({ + position: "absolute", + top: 0, + left: 0, + bottom: 0, + right: 0 + }) + .appendTo(this.textContainer); + } + + return layer; + }; + + // Creates (if necessary) and returns a text info object. + // + // The object looks like this: + // + // { + // width: Width of the text's wrapper div. + // height: Height of the text's wrapper div. + // element: The jQuery-wrapped HTML div containing the text. + // positions: Array of positions at which this text is drawn. + // } + // + // The positions array contains objects that look like this: + // + // { + // active: Flag indicating whether the text should be visible. + // rendered: Flag indicating whether the text is currently visible. + // element: The jQuery-wrapped HTML div containing the text. + // x: X coordinate at which to draw the text. + // y: Y coordinate at which to draw the text. + // } + // + // Each position after the first receives a clone of the original element. + // + // The idea is that that the width, height, and general 'identity' of the + // text is constant no matter where it is placed; the placements are a + // secondary property. + // + // Canvas maintains a cache of recently-used text info objects; getTextInfo + // either returns the cached element or creates a new entry. + // + // @param {string} layer A string of space-separated CSS classes uniquely + // identifying the layer containing this text. + // @param {string} text Text string to retrieve info for. + // @param {(string|object)=} font Either a string of space-separated CSS + // classes or a font-spec object, defining the text's font and style. + // @param {number=} angle Angle at which to rotate the text, in degrees. + // Angle is currently unused, it will be implemented in the future. + // @param {number=} width Maximum width of the text before it wraps. + // @return {object} a text info object. + + Canvas.prototype.getTextInfo = function(layer, text, font, angle, width) { + + var textStyle, layerCache, styleCache, info; + + // Cast the value to a string, in case we were given a number or such + + text = "" + text; + + // If the font is a font-spec object, generate a CSS font definition + + if (typeof font === "object") { + textStyle = font.style + " " + font.variant + " " + font.weight + " " + font.size + "px/" + font.lineHeight + "px " + font.family; + } else { + textStyle = font; + } + + // Retrieve (or create) the cache for the text's layer and styles + + layerCache = this._textCache[layer]; + + if (layerCache == null) { + layerCache = this._textCache[layer] = {}; + } + + styleCache = layerCache[textStyle]; + + if (styleCache == null) { + styleCache = layerCache[textStyle] = {}; + } + + info = styleCache[text]; + + // If we can't find a matching element in our cache, create a new one + + if (info == null) { + + var element = $("<div></div>").html(text) + .css({ + position: "absolute", + 'max-width': width, + top: -9999 + }) + .appendTo(this.getTextLayer(layer)); + + if (typeof font === "object") { + element.css({ + font: textStyle, + color: font.color + }); + } else if (typeof font === "string") { + element.addClass(font); + } + + info = styleCache[text] = { + width: element.outerWidth(true), + height: element.outerHeight(true), + element: element, + positions: [] + }; + + element.detach(); + } + + return info; + }; + + // Adds a text string to the canvas text overlay. + // + // The text isn't drawn immediately; it is marked as rendering, which will + // result in its addition to the canvas on the next render pass. + // + // @param {string} layer A string of space-separated CSS classes uniquely + // identifying the layer containing this text. + // @param {number} x X coordinate at which to draw the text. + // @param {number} y Y coordinate at which to draw the text. + // @param {string} text Text string to draw. + // @param {(string|object)=} font Either a string of space-separated CSS + // classes or a font-spec object, defining the text's font and style. + // @param {number=} angle Angle at which to rotate the text, in degrees. + // Angle is currently unused, it will be implemented in the future. + // @param {number=} width Maximum width of the text before it wraps. + // @param {string=} halign Horizontal alignment of the text; either "left", + // "center" or "right". + // @param {string=} valign Vertical alignment of the text; either "top", + // "middle" or "bottom". + + Canvas.prototype.addText = function(layer, x, y, text, font, angle, width, halign, valign) { + + var info = this.getTextInfo(layer, text, font, angle, width), + positions = info.positions; + + // Tweak the div's position to match the text's alignment + + if (halign == "center") { + x -= info.width / 2; + } else if (halign == "right") { + x -= info.width; + } + + if (valign == "middle") { + y -= info.height / 2; + } else if (valign == "bottom") { + y -= info.height; + } + + // Determine whether this text already exists at this position. + // If so, mark it for inclusion in the next render pass. + + for (var i = 0, position; position = positions[i]; i++) { + if (position.x == x && position.y == y) { + position.active = true; + return; + } + } + + // If the text doesn't exist at this position, create a new entry + + // For the very first position we'll re-use the original element, + // while for subsequent ones we'll clone it. + + position = { + active: true, + rendered: false, + element: positions.length ? info.element.clone() : info.element, + x: x, + y: y + }; + + positions.push(position); + + // Move the element to its final position within the container + + position.element.css({ + top: Math.round(y), + left: Math.round(x), + 'text-align': halign // In case the text wraps + }); + }; + + // Removes one or more text strings from the canvas text overlay. + // + // If no parameters are given, all text within the layer is removed. + // + // Note that the text is not immediately removed; it is simply marked as + // inactive, which will result in its removal on the next render pass. + // This avoids the performance penalty for 'clear and redraw' behavior, + // where we potentially get rid of all text on a layer, but will likely + // add back most or all of it later, as when redrawing axes, for example. + // + // @param {string} layer A string of space-separated CSS classes uniquely + // identifying the layer containing this text. + // @param {number=} x X coordinate of the text. + // @param {number=} y Y coordinate of the text. + // @param {string=} text Text string to remove. + // @param {(string|object)=} font Either a string of space-separated CSS + // classes or a font-spec object, defining the text's font and style. + // @param {number=} angle Angle at which the text is rotated, in degrees. + // Angle is currently unused, it will be implemented in the future. + + Canvas.prototype.removeText = function(layer, x, y, text, font, angle) { + if (text == null) { + var layerCache = this._textCache[layer]; + if (layerCache != null) { + for (var styleKey in layerCache) { + if (hasOwnProperty.call(layerCache, styleKey)) { + var styleCache = layerCache[styleKey]; + for (var key in styleCache) { + if (hasOwnProperty.call(styleCache, key)) { + var positions = styleCache[key].positions; + for (var i = 0, position; position = positions[i]; i++) { + position.active = false; + } + } + } + } + } + } + } else { + var positions = this.getTextInfo(layer, text, font, angle).positions; + for (var i = 0, position; position = positions[i]; i++) { + if (position.x == x && position.y == y) { + position.active = false; + } + } + } + }; + + /////////////////////////////////////////////////////////////////////////// + // The top-level container for the entire plot. + + function Plot(placeholder, data_, options_, plugins) { + // data is on the form: + // [ series1, series2 ... ] + // where series is either just the data as [ [x1, y1], [x2, y2], ... ] + // or { data: [ [x1, y1], [x2, y2], ... ], label: "some label", ... } + + var series = [], + options = { + // the color theme used for graphs + colors: ["#edc240", "#afd8f8", "#cb4b4b", "#4da74d", "#9440ed"], + legend: { + show: true, + noColumns: 1, // number of colums in legend table + labelFormatter: null, // fn: string -> string + labelBoxBorderColor: "#ccc", // border color for the little label boxes + container: null, // container (as jQuery object) to put legend in, null means default on top of graph + position: "ne", // position of default legend container within plot + margin: 5, // distance from grid edge to default legend container within plot + backgroundColor: null, // null means auto-detect + backgroundOpacity: 0.85, // set to 0 to avoid background + sorted: null // default to no legend sorting + }, + xaxis: { + show: null, // null = auto-detect, true = always, false = never + position: "bottom", // or "top" + mode: null, // null or "time" + font: null, // null (derived from CSS in placeholder) or object like { size: 11, lineHeight: 13, style: "italic", weight: "bold", family: "sans-serif", variant: "small-caps" } + color: null, // base color, labels, ticks + tickColor: null, // possibly different color of ticks, e.g. "rgba(0,0,0,0.15)" + transform: null, // null or f: number -> number to transform axis + inverseTransform: null, // if transform is set, this should be the inverse function + min: null, // min. value to show, null means set automatically + max: null, // max. value to show, null means set automatically + autoscaleMargin: null, // margin in % to add if auto-setting min/max + ticks: null, // either [1, 3] or [[1, "a"], 3] or (fn: axis info -> ticks) or app. number of ticks for auto-ticks + tickFormatter: null, // fn: number -> string + labelWidth: null, // size of tick labels in pixels + labelHeight: null, + reserveSpace: null, // whether to reserve space even if axis isn't shown + tickLength: null, // size in pixels of ticks, or "full" for whole line + alignTicksWithAxis: null, // axis number or null for no sync + tickDecimals: null, // no. of decimals, null means auto + tickSize: null, // number or [number, "unit"] + minTickSize: null // number or [number, "unit"] + }, + yaxis: { + autoscaleMargin: 0.02, + position: "left" // or "right" + }, + xaxes: [], + yaxes: [], + series: { + points: { + show: false, + radius: 3, + lineWidth: 2, // in pixels + fill: true, + fillColor: "#ffffff", + symbol: "circle" // or callback + }, + lines: { + // we don't put in show: false so we can see + // whether lines were actively disabled + lineWidth: 2, // in pixels + fill: false, + fillColor: null, + steps: false + // Omit 'zero', so we can later default its value to + // match that of the 'fill' option. + }, + bars: { + show: false, + lineWidth: 2, // in pixels + barWidth: 1, // in units of the x axis + fill: true, + fillColor: null, + align: "left", // "left", "right", or "center" + horizontal: false, + zero: true + }, + shadowSize: 3, + highlightColor: null + }, + grid: { + show: true, + aboveData: false, + color: "#545454", // primary color used for outline and labels + backgroundColor: null, // null for transparent, else color + borderColor: null, // set if different from the grid color + tickColor: null, // color for the ticks, e.g. "rgba(0,0,0,0.15)" + margin: 0, // distance from the canvas edge to the grid + labelMargin: 5, // in pixels + axisMargin: 8, // in pixels + borderWidth: 2, // in pixels + minBorderMargin: null, // in pixels, null means taken from points radius + markings: null, // array of ranges or fn: axes -> array of ranges + markingsColor: "#f4f4f4", + markingsLineWidth: 2, + // interactive stuff + clickable: false, + hoverable: false, + autoHighlight: true, // highlight in case mouse is near + mouseActiveRadius: 10 // how far the mouse can be away to activate an item + }, + interaction: { + redrawOverlayInterval: 1000/60 // time between updates, -1 means in same flow + }, + hooks: {} + }, + surface = null, // the canvas for the plot itself + overlay = null, // canvas for interactive stuff on top of plot + eventHolder = null, // jQuery object that events should be bound to + ctx = null, octx = null, + xaxes = [], yaxes = [], + plotOffset = { left: 0, right: 0, top: 0, bottom: 0}, + plotWidth = 0, plotHeight = 0, + hooks = { + processOptions: [], + processRawData: [], + processDatapoints: [], + processOffset: [], + drawBackground: [], + drawSeries: [], + draw: [], + bindEvents: [], + drawOverlay: [], + shutdown: [] + }, + plot = this; + + // public functions + plot.setData = setData; + plot.setupGrid = setupGrid; + plot.draw = draw; + plot.getPlaceholder = function() { return placeholder; }; + plot.getCanvas = function() { return surface.element; }; + plot.getPlotOffset = function() { return plotOffset; }; + plot.width = function () { return plotWidth; }; + plot.height = function () { return plotHeight; }; + plot.offset = function () { + var o = eventHolder.offset(); + o.left += plotOffset.left; + o.top += plotOffset.top; + return o; + }; + plot.getData = function () { return series; }; + plot.getAxes = function () { + var res = {}, i; + $.each(xaxes.concat(yaxes), function (_, axis) { + if (axis) + res[axis.direction + (axis.n != 1 ? axis.n : "") + "axis"] = axis; + }); + return res; + }; + plot.getXAxes = function () { return xaxes; }; + plot.getYAxes = function () { return yaxes; }; + plot.c2p = canvasToAxisCoords; + plot.p2c = axisToCanvasCoords; + plot.getOptions = function () { return options; }; + plot.highlight = highlight; + plot.unhighlight = unhighlight; + plot.triggerRedrawOverlay = triggerRedrawOverlay; + plot.pointOffset = function(point) { + return { + left: parseInt(xaxes[axisNumber(point, "x") - 1].p2c(+point.x) + plotOffset.left, 10), + top: parseInt(yaxes[axisNumber(point, "y") - 1].p2c(+point.y) + plotOffset.top, 10) + }; + }; + plot.shutdown = shutdown; + plot.destroy = function () { + shutdown(); + placeholder.removeData("plot").empty(); + + series = []; + options = null; + surface = null; + overlay = null; + eventHolder = null; + ctx = null; + octx = null; + xaxes = []; + yaxes = []; + hooks = null; + highlights = []; + plot = null; + }; + plot.resize = function () { + var width = placeholder.width(), + height = placeholder.height(); + surface.resize(width, height); + overlay.resize(width, height); + }; + + // public attributes + plot.hooks = hooks; + + // initialize + initPlugins(plot); + parseOptions(options_); + setupCanvases(); + setData(data_); + setupGrid(); + draw(); + bindEvents(); + + + function executeHooks(hook, args) { + args = [plot].concat(args); + for (var i = 0; i < hook.length; ++i) + hook[i].apply(this, args); + } + + function initPlugins() { + + // References to key classes, allowing plugins to modify them + + var classes = { + Canvas: Canvas + }; + + for (var i = 0; i < plugins.length; ++i) { + var p = plugins[i]; + p.init(plot, classes); + if (p.options) + $.extend(true, options, p.options); + } + } + + function parseOptions(opts) { + + $.extend(true, options, opts); + + // $.extend merges arrays, rather than replacing them. When less + // colors are provided than the size of the default palette, we + // end up with those colors plus the remaining defaults, which is + // not expected behavior; avoid it by replacing them here. + + if (opts && opts.colors) { + options.colors = opts.colors; + } + + if (options.xaxis.color == null) + options.xaxis.color = $.color.parse(options.grid.color).scale('a', 0.22).toString(); + if (options.yaxis.color == null) + options.yaxis.color = $.color.parse(options.grid.color).scale('a', 0.22).toString(); + + if (options.xaxis.tickColor == null) // grid.tickColor for back-compatibility + options.xaxis.tickColor = options.grid.tickColor || options.xaxis.color; + if (options.yaxis.tickColor == null) // grid.tickColor for back-compatibility + options.yaxis.tickColor = options.grid.tickColor || options.yaxis.color; + + if (options.grid.borderColor == null) + options.grid.borderColor = options.grid.color; + if (options.grid.tickColor == null) + options.grid.tickColor = $.color.parse(options.grid.color).scale('a', 0.22).toString(); + + // Fill in defaults for axis options, including any unspecified + // font-spec fields, if a font-spec was provided. + + // If no x/y axis options were provided, create one of each anyway, + // since the rest of the code assumes that they exist. + + var i, axisOptions, axisCount, + fontSize = placeholder.css("font-size"), + fontSizeDefault = fontSize ? +fontSize.replace("px", "") : 13, + fontDefaults = { + style: placeholder.css("font-style"), + size: Math.round(0.8 * fontSizeDefault), + variant: placeholder.css("font-variant"), + weight: placeholder.css("font-weight"), + family: placeholder.css("font-family") + }; + + axisCount = options.xaxes.length || 1; + for (i = 0; i < axisCount; ++i) { + + axisOptions = options.xaxes[i]; + if (axisOptions && !axisOptions.tickColor) { + axisOptions.tickColor = axisOptions.color; + } + + axisOptions = $.extend(true, {}, options.xaxis, axisOptions); + options.xaxes[i] = axisOptions; + + if (axisOptions.font) { + axisOptions.font = $.extend({}, fontDefaults, axisOptions.font); + if (!axisOptions.font.color) { + axisOptions.font.color = axisOptions.color; + } + if (!axisOptions.font.lineHeight) { + axisOptions.font.lineHeight = Math.round(axisOptions.font.size * 1.15); + } + } + } + + axisCount = options.yaxes.length || 1; + for (i = 0; i < axisCount; ++i) { + + axisOptions = options.yaxes[i]; + if (axisOptions && !axisOptions.tickColor) { + axisOptions.tickColor = axisOptions.color; + } + + axisOptions = $.extend(true, {}, options.yaxis, axisOptions); + options.yaxes[i] = axisOptions; + + if (axisOptions.font) { + axisOptions.font = $.extend({}, fontDefaults, axisOptions.font); + if (!axisOptions.font.color) { + axisOptions.font.color = axisOptions.color; + } + if (!axisOptions.font.lineHeight) { + axisOptions.font.lineHeight = Math.round(axisOptions.font.size * 1.15); + } + } + } + + // backwards compatibility, to be removed in future + if (options.xaxis.noTicks && options.xaxis.ticks == null) + options.xaxis.ticks = options.xaxis.noTicks; + if (options.yaxis.noTicks && options.yaxis.ticks == null) + options.yaxis.ticks = options.yaxis.noTicks; + if (options.x2axis) { + options.xaxes[1] = $.extend(true, {}, options.xaxis, options.x2axis); + options.xaxes[1].position = "top"; + // Override the inherit to allow the axis to auto-scale + if (options.x2axis.min == null) { + options.xaxes[1].min = null; + } + if (options.x2axis.max == null) { + options.xaxes[1].max = null; + } + } + if (options.y2axis) { + options.yaxes[1] = $.extend(true, {}, options.yaxis, options.y2axis); + options.yaxes[1].position = "right"; + // Override the inherit to allow the axis to auto-scale + if (options.y2axis.min == null) { + options.yaxes[1].min = null; + } + if (options.y2axis.max == null) { + options.yaxes[1].max = null; + } + } + if (options.grid.coloredAreas) + options.grid.markings = options.grid.coloredAreas; + if (options.grid.coloredAreasColor) + options.grid.markingsColor = options.grid.coloredAreasColor; + if (options.lines) + $.extend(true, options.series.lines, options.lines); + if (options.points) + $.extend(true, options.series.points, options.points); + if (options.bars) + $.extend(true, options.series.bars, options.bars); + if (options.shadowSize != null) + options.series.shadowSize = options.shadowSize; + if (options.highlightColor != null) + options.series.highlightColor = options.highlightColor; + + // save options on axes for future reference + for (i = 0; i < options.xaxes.length; ++i) + getOrCreateAxis(xaxes, i + 1).options = options.xaxes[i]; + for (i = 0; i < options.yaxes.length; ++i) + getOrCreateAxis(yaxes, i + 1).options = options.yaxes[i]; + + // add hooks from options + for (var n in hooks) + if (options.hooks[n] && options.hooks[n].length) + hooks[n] = hooks[n].concat(options.hooks[n]); + + executeHooks(hooks.processOptions, [options]); + } + + function setData(d) { + series = parseData(d); + fillInSeriesOptions(); + processData(); + } + + function parseData(d) { + var res = []; + for (var i = 0; i < d.length; ++i) { + var s = $.extend(true, {}, options.series); + + if (d[i].data != null) { + s.data = d[i].data; // move the data instead of deep-copy + delete d[i].data; + + $.extend(true, s, d[i]); + + d[i].data = s.data; + } + else + s.data = d[i]; + res.push(s); + } + + return res; + } + + function axisNumber(obj, coord) { + var a = obj[coord + "axis"]; + if (typeof a == "object") // if we got a real axis, extract number + a = a.n; + if (typeof a != "number") + a = 1; // default to first axis + return a; + } + + function allAxes() { + // return flat array without annoying null entries + return $.grep(xaxes.concat(yaxes), function (a) { return a; }); + } + + function canvasToAxisCoords(pos) { + // return an object with x/y corresponding to all used axes + var res = {}, i, axis; + for (i = 0; i < xaxes.length; ++i) { + axis = xaxes[i]; + if (axis && axis.used) + res["x" + axis.n] = axis.c2p(pos.left); + } + + for (i = 0; i < yaxes.length; ++i) { + axis = yaxes[i]; + if (axis && axis.used) + res["y" + axis.n] = axis.c2p(pos.top); + } + + if (res.x1 !== undefined) + res.x = res.x1; + if (res.y1 !== undefined) + res.y = res.y1; + + return res; + } + + function axisToCanvasCoords(pos) { + // get canvas coords from the first pair of x/y found in pos + var res = {}, i, axis, key; + + for (i = 0; i < xaxes.length; ++i) { + axis = xaxes[i]; + if (axis && axis.used) { + key = "x" + axis.n; + if (pos[key] == null && axis.n == 1) + key = "x"; + + if (pos[key] != null) { + res.left = axis.p2c(pos[key]); + break; + } + } + } + + for (i = 0; i < yaxes.length; ++i) { + axis = yaxes[i]; + if (axis && axis.used) { + key = "y" + axis.n; + if (pos[key] == null && axis.n == 1) + key = "y"; + + if (pos[key] != null) { + res.top = axis.p2c(pos[key]); + break; + } + } + } + + return res; + } + + function getOrCreateAxis(axes, number) { + if (!axes[number - 1]) + axes[number - 1] = { + n: number, // save the number for future reference + direction: axes == xaxes ? "x" : "y", + options: $.extend(true, {}, axes == xaxes ? options.xaxis : options.yaxis) + }; + + return axes[number - 1]; + } + + function fillInSeriesOptions() { + + var neededColors = series.length, maxIndex = -1, i; + + // Subtract the number of series that already have fixed colors or + // color indexes from the number that we still need to generate. + + for (i = 0; i < series.length; ++i) { + var sc = series[i].color; + if (sc != null) { + neededColors--; + if (typeof sc == "number" && sc > maxIndex) { + maxIndex = sc; + } + } + } + + // If any of the series have fixed color indexes, then we need to + // generate at least as many colors as the highest index. + + if (neededColors <= maxIndex) { + neededColors = maxIndex + 1; + } + + // Generate all the colors, using first the option colors and then + // variations on those colors once they're exhausted. + + var c, colors = [], colorPool = options.colors, + colorPoolSize = colorPool.length, variation = 0; + + for (i = 0; i < neededColors; i++) { + + c = $.color.parse(colorPool[i % colorPoolSize] || "#666"); + + // Each time we exhaust the colors in the pool we adjust + // a scaling factor used to produce more variations on + // those colors. The factor alternates negative/positive + // to produce lighter/darker colors. + + // Reset the variation after every few cycles, or else + // it will end up producing only white or black colors. + + if (i % colorPoolSize == 0 && i) { + if (variation >= 0) { + if (variation < 0.5) { + variation = -variation - 0.2; + } else variation = 0; + } else variation = -variation; + } + + colors[i] = c.scale('rgb', 1 + variation); + } + + // Finalize the series options, filling in their colors + + var colori = 0, s; + for (i = 0; i < series.length; ++i) { + s = series[i]; + + // assign colors + if (s.color == null) { + s.color = colors[colori].toString(); + ++colori; + } + else if (typeof s.color == "number") + s.color = colors[s.color].toString(); + + // turn on lines automatically in case nothing is set + if (s.lines.show == null) { + var v, show = true; + for (v in s) + if (s[v] && s[v].show) { + show = false; + break; + } + if (show) + s.lines.show = true; + } + + // If nothing was provided for lines.zero, default it to match + // lines.fill, since areas by default should extend to zero. + + if (s.lines.zero == null) { + s.lines.zero = !!s.lines.fill; + } + + // setup axes + s.xaxis = getOrCreateAxis(xaxes, axisNumber(s, "x")); + s.yaxis = getOrCreateAxis(yaxes, axisNumber(s, "y")); + } + } + + function processData() { + var topSentry = Number.POSITIVE_INFINITY, + bottomSentry = Number.NEGATIVE_INFINITY, + fakeInfinity = Number.MAX_VALUE, + i, j, k, m, length, + s, points, ps, x, y, axis, val, f, p, + data, format; + + function updateAxis(axis, min, max) { + if (min < axis.datamin && min != -fakeInfinity) + axis.datamin = min; + if (max > axis.datamax && max != fakeInfinity) + axis.datamax = max; + } + + $.each(allAxes(), function (_, axis) { + // init axis + axis.datamin = topSentry; + axis.datamax = bottomSentry; + axis.used = false; + }); + + for (i = 0; i < series.length; ++i) { + s = series[i]; + s.datapoints = { points: [] }; + + executeHooks(hooks.processRawData, [ s, s.data, s.datapoints ]); + } + + // first pass: clean and copy data + for (i = 0; i < series.length; ++i) { + s = series[i]; + + data = s.data; + format = s.datapoints.format; + + if (!format) { + format = []; + // find out how to copy + format.push({ x: true, number: true, required: true }); + format.push({ y: true, number: true, required: true }); + + if (s.bars.show || (s.lines.show && s.lines.fill)) { + var autoscale = !!((s.bars.show && s.bars.zero) || (s.lines.show && s.lines.zero)); + format.push({ y: true, number: true, required: false, defaultValue: 0, autoscale: autoscale }); + if (s.bars.horizontal) { + delete format[format.length - 1].y; + format[format.length - 1].x = true; + } + } + + s.datapoints.format = format; + } + + if (s.datapoints.pointsize != null) + continue; // already filled in + + s.datapoints.pointsize = format.length; + + ps = s.datapoints.pointsize; + points = s.datapoints.points; + + var insertSteps = s.lines.show && s.lines.steps; + s.xaxis.used = s.yaxis.used = true; + + for (j = k = 0; j < data.length; ++j, k += ps) { + p = data[j]; + + var nullify = p == null; + if (!nullify) { + for (m = 0; m < ps; ++m) { + val = p[m]; + f = format[m]; + + if (f) { + if (f.number && val != null) { + val = +val; // convert to number + if (isNaN(val)) + val = null; + else if (val == Infinity) + val = fakeInfinity; + else if (val == -Infinity) + val = -fakeInfinity; + } + + if (val == null) { + if (f.required) + nullify = true; + + if (f.defaultValue != null) + val = f.defaultValue; + } + } + + points[k + m] = val; + } + } + + if (nullify) { + for (m = 0; m < ps; ++m) { + val = points[k + m]; + if (val != null) { + f = format[m]; + // extract min/max info + if (f.autoscale !== false) { + if (f.x) { + updateAxis(s.xaxis, val, val); + } + if (f.y) { + updateAxis(s.yaxis, val, val); + } + } + } + points[k + m] = null; + } + } + else { + // a little bit of line specific stuff that + // perhaps shouldn't be here, but lacking + // better means... + if (insertSteps && k > 0 + && points[k - ps] != null + && points[k - ps] != points[k] + && points[k - ps + 1] != points[k + 1]) { + // copy the point to make room for a middle point + for (m = 0; m < ps; ++m) + points[k + ps + m] = points[k + m]; + + // middle point has same y + points[k + 1] = points[k - ps + 1]; + + // we've added a point, better reflect that + k += ps; + } + } + } + } + + // give the hooks a chance to run + for (i = 0; i < series.length; ++i) { + s = series[i]; + + executeHooks(hooks.processDatapoints, [ s, s.datapoints]); + } + + // second pass: find datamax/datamin for auto-scaling + for (i = 0; i < series.length; ++i) { + s = series[i]; + points = s.datapoints.points; + ps = s.datapoints.pointsize; + format = s.datapoints.format; + + var xmin = topSentry, ymin = topSentry, + xmax = bottomSentry, ymax = bottomSentry; + + for (j = 0; j < points.length; j += ps) { + if (points[j] == null) + continue; + + for (m = 0; m < ps; ++m) { + val = points[j + m]; + f = format[m]; + if (!f || f.autoscale === false || val == fakeInfinity || val == -fakeInfinity) + continue; + + if (f.x) { + if (val < xmin) + xmin = val; + if (val > xmax) + xmax = val; + } + if (f.y) { + if (val < ymin) + ymin = val; + if (val > ymax) + ymax = val; + } + } + } + + if (s.bars.show) { + // make sure we got room for the bar on the dancing floor + var delta; + + switch (s.bars.align) { + case "left": + delta = 0; + break; + case "right": + delta = -s.bars.barWidth; + break; + default: + delta = -s.bars.barWidth / 2; + } + + if (s.bars.horizontal) { + ymin += delta; + ymax += delta + s.bars.barWidth; + } + else { + xmin += delta; + xmax += delta + s.bars.barWidth; + } + } + + updateAxis(s.xaxis, xmin, xmax); + updateAxis(s.yaxis, ymin, ymax); + } + + $.each(allAxes(), function (_, axis) { + if (axis.datamin == topSentry) + axis.datamin = null; + if (axis.datamax == bottomSentry) + axis.datamax = null; + }); + } + + function setupCanvases() { + + // Make sure the placeholder is clear of everything except canvases + // from a previous plot in this container that we'll try to re-use. + + placeholder.css("padding", 0) // padding messes up the positioning + .children().filter(function(){ + return !$(this).hasClass("flot-overlay") && !$(this).hasClass('flot-base'); + }).remove(); + + if (placeholder.css("position") == 'static') + placeholder.css("position", "relative"); // for positioning labels and overlay + + surface = new Canvas("flot-base", placeholder); + overlay = new Canvas("flot-overlay", placeholder); // overlay canvas for interactive features + + ctx = surface.context; + octx = overlay.context; + + // define which element we're listening for events on + eventHolder = $(overlay.element).unbind(); + + // If we're re-using a plot object, shut down the old one + + var existing = placeholder.data("plot"); + + if (existing) { + existing.shutdown(); + overlay.clear(); + } + + // save in case we get replotted + placeholder.data("plot", plot); + } + + function bindEvents() { + // bind events + if (options.grid.hoverable) { + eventHolder.mousemove(onMouseMove); + + // Use bind, rather than .mouseleave, because we officially + // still support jQuery 1.2.6, which doesn't define a shortcut + // for mouseenter or mouseleave. This was a bug/oversight that + // was fixed somewhere around 1.3.x. We can return to using + // .mouseleave when we drop support for 1.2.6. + + eventHolder.bind("mouseleave", onMouseLeave); + } + + if (options.grid.clickable) + eventHolder.click(onClick); + + executeHooks(hooks.bindEvents, [eventHolder]); + } + + function shutdown() { + if (redrawTimeout) + clearTimeout(redrawTimeout); + + eventHolder.unbind("mousemove", onMouseMove); + eventHolder.unbind("mouseleave", onMouseLeave); + eventHolder.unbind("click", onClick); + + executeHooks(hooks.shutdown, [eventHolder]); + } + + function setTransformationHelpers(axis) { + // set helper functions on the axis, assumes plot area + // has been computed already + + function identity(x) { return x; } + + var s, m, t = axis.options.transform || identity, + it = axis.options.inverseTransform; + + // precompute how much the axis is scaling a point + // in canvas space + if (axis.direction == "x") { + s = axis.scale = plotWidth / Math.abs(t(axis.max) - t(axis.min)); + m = Math.min(t(axis.max), t(axis.min)); + } + else { + s = axis.scale = plotHeight / Math.abs(t(axis.max) - t(axis.min)); + s = -s; + m = Math.max(t(axis.max), t(axis.min)); + } + + // data point to canvas coordinate + if (t == identity) // slight optimization + axis.p2c = function (p) { return (p - m) * s; }; + else + axis.p2c = function (p) { return (t(p) - m) * s; }; + // canvas coordinate to data point + if (!it) + axis.c2p = function (c) { return m + c / s; }; + else + axis.c2p = function (c) { return it(m + c / s); }; + } + + function measureTickLabels(axis) { + + var opts = axis.options, + ticks = axis.ticks || [], + labelWidth = opts.labelWidth || 0, + labelHeight = opts.labelHeight || 0, + maxWidth = labelWidth || (axis.direction == "x" ? Math.floor(surface.width / (ticks.length || 1)) : null), + legacyStyles = axis.direction + "Axis " + axis.direction + axis.n + "Axis", + layer = "flot-" + axis.direction + "-axis flot-" + axis.direction + axis.n + "-axis " + legacyStyles, + font = opts.font || "flot-tick-label tickLabel"; + + for (var i = 0; i < ticks.length; ++i) { + + var t = ticks[i]; + + if (!t.label) + continue; + + var info = surface.getTextInfo(layer, t.label, font, null, maxWidth); + + labelWidth = Math.max(labelWidth, info.width); + labelHeight = Math.max(labelHeight, info.height); + } + + axis.labelWidth = opts.labelWidth || labelWidth; + axis.labelHeight = opts.labelHeight || labelHeight; + } + + function allocateAxisBoxFirstPhase(axis) { + // find the bounding box of the axis by looking at label + // widths/heights and ticks, make room by diminishing the + // plotOffset; this first phase only looks at one + // dimension per axis, the other dimension depends on the + // other axes so will have to wait + + var lw = axis.labelWidth, + lh = axis.labelHeight, + pos = axis.options.position, + isXAxis = axis.direction === "x", + tickLength = axis.options.tickLength, + axisMargin = options.grid.axisMargin, + padding = options.grid.labelMargin, + innermost = true, + outermost = true, + first = true, + found = false; + + // Determine the axis's position in its direction and on its side + + $.each(isXAxis ? xaxes : yaxes, function(i, a) { + if (a && (a.show || a.reserveSpace)) { + if (a === axis) { + found = true; + } else if (a.options.position === pos) { + if (found) { + outermost = false; + } else { + innermost = false; + } + } + if (!found) { + first = false; + } + } + }); + + // The outermost axis on each side has no margin + + if (outermost) { + axisMargin = 0; + } + + // The ticks for the first axis in each direction stretch across + + if (tickLength == null) { + tickLength = first ? "full" : 5; + } + + if (!isNaN(+tickLength)) + padding += +tickLength; + + if (isXAxis) { + lh += padding; + + if (pos == "bottom") { + plotOffset.bottom += lh + axisMargin; + axis.box = { top: surface.height - plotOffset.bottom, height: lh }; + } + else { + axis.box = { top: plotOffset.top + axisMargin, height: lh }; + plotOffset.top += lh + axisMargin; + } + } + else { + lw += padding; + + if (pos == "left") { + axis.box = { left: plotOffset.left + axisMargin, width: lw }; + plotOffset.left += lw + axisMargin; + } + else { + plotOffset.right += lw + axisMargin; + axis.box = { left: surface.width - plotOffset.right, width: lw }; + } + } + + // save for future reference + axis.position = pos; + axis.tickLength = tickLength; + axis.box.padding = padding; + axis.innermost = innermost; + } + + function allocateAxisBoxSecondPhase(axis) { + // now that all axis boxes have been placed in one + // dimension, we can set the remaining dimension coordinates + if (axis.direction == "x") { + axis.box.left = plotOffset.left - axis.labelWidth / 2; + axis.box.width = surface.width - plotOffset.left - plotOffset.right + axis.labelWidth; + } + else { + axis.box.top = plotOffset.top - axis.labelHeight / 2; + axis.box.height = surface.height - plotOffset.bottom - plotOffset.top + axis.labelHeight; + } + } + + function adjustLayoutForThingsStickingOut() { + // possibly adjust plot offset to ensure everything stays + // inside the canvas and isn't clipped off + + var minMargin = options.grid.minBorderMargin, + axis, i; + + // check stuff from the plot (FIXME: this should just read + // a value from the series, otherwise it's impossible to + // customize) + if (minMargin == null) { + minMargin = 0; + for (i = 0; i < series.length; ++i) + minMargin = Math.max(minMargin, 2 * (series[i].points.radius + series[i].points.lineWidth/2)); + } + + var margins = { + left: minMargin, + right: minMargin, + top: minMargin, + bottom: minMargin + }; + + // check axis labels, note we don't check the actual + // labels but instead use the overall width/height to not + // jump as much around with replots + $.each(allAxes(), function (_, axis) { + if (axis.reserveSpace && axis.ticks && axis.ticks.length) { + if (axis.direction === "x") { + margins.left = Math.max(margins.left, axis.labelWidth / 2); + margins.right = Math.max(margins.right, axis.labelWidth / 2); + } else { + margins.bottom = Math.max(margins.bottom, axis.labelHeight / 2); + margins.top = Math.max(margins.top, axis.labelHeight / 2); + } + } + }); + + plotOffset.left = Math.ceil(Math.max(margins.left, plotOffset.left)); + plotOffset.right = Math.ceil(Math.max(margins.right, plotOffset.right)); + plotOffset.top = Math.ceil(Math.max(margins.top, plotOffset.top)); + plotOffset.bottom = Math.ceil(Math.max(margins.bottom, plotOffset.bottom)); + } + + function setupGrid() { + var i, axes = allAxes(), showGrid = options.grid.show; + + // Initialize the plot's offset from the edge of the canvas + + for (var a in plotOffset) { + var margin = options.grid.margin || 0; + plotOffset[a] = typeof margin == "number" ? margin : margin[a] || 0; + } + + executeHooks(hooks.processOffset, [plotOffset]); + + // If the grid is visible, add its border width to the offset + + for (var a in plotOffset) { + if(typeof(options.grid.borderWidth) == "object") { + plotOffset[a] += showGrid ? options.grid.borderWidth[a] : 0; + } + else { + plotOffset[a] += showGrid ? options.grid.borderWidth : 0; + } + } + + $.each(axes, function (_, axis) { + var axisOpts = axis.options; + axis.show = axisOpts.show == null ? axis.used : axisOpts.show; + axis.reserveSpace = axisOpts.reserveSpace == null ? axis.show : axisOpts.reserveSpace; + setRange(axis); + }); + + if (showGrid) { + + var allocatedAxes = $.grep(axes, function (axis) { + return axis.show || axis.reserveSpace; + }); + + $.each(allocatedAxes, function (_, axis) { + // make the ticks + setupTickGeneration(axis); + setTicks(axis); + snapRangeToTicks(axis, axis.ticks); + // find labelWidth/Height for axis + measureTickLabels(axis); + }); + + // with all dimensions calculated, we can compute the + // axis bounding boxes, start from the outside + // (reverse order) + for (i = allocatedAxes.length - 1; i >= 0; --i) + allocateAxisBoxFirstPhase(allocatedAxes[i]); + + // make sure we've got enough space for things that + // might stick out + adjustLayoutForThingsStickingOut(); + + $.each(allocatedAxes, function (_, axis) { + allocateAxisBoxSecondPhase(axis); + }); + } + + plotWidth = surface.width - plotOffset.left - plotOffset.right; + plotHeight = surface.height - plotOffset.bottom - plotOffset.top; + + // now we got the proper plot dimensions, we can compute the scaling + $.each(axes, function (_, axis) { + setTransformationHelpers(axis); + }); + + if (showGrid) { + drawAxisLabels(); + } + + insertLegend(); + } + + function setRange(axis) { + var opts = axis.options, + min = +(opts.min != null ? opts.min : axis.datamin), + max = +(opts.max != null ? opts.max : axis.datamax), + delta = max - min; + + if (delta == 0.0) { + // degenerate case + var widen = max == 0 ? 1 : 0.01; + + if (opts.min == null) + min -= widen; + // always widen max if we couldn't widen min to ensure we + // don't fall into min == max which doesn't work + if (opts.max == null || opts.min != null) + max += widen; + } + else { + // consider autoscaling + var margin = opts.autoscaleMargin; + if (margin != null) { + if (opts.min == null) { + min -= delta * margin; + // make sure we don't go below zero if all values + // are positive + if (min < 0 && axis.datamin != null && axis.datamin >= 0) + min = 0; + } + if (opts.max == null) { + max += delta * margin; + if (max > 0 && axis.datamax != null && axis.datamax <= 0) + max = 0; + } + } + } + axis.min = min; + axis.max = max; + } + + function setupTickGeneration(axis) { + var opts = axis.options; + + // estimate number of ticks + var noTicks; + if (typeof opts.ticks == "number" && opts.ticks > 0) + noTicks = opts.ticks; + else + // heuristic based on the model a*sqrt(x) fitted to + // some data points that seemed reasonable + noTicks = 0.3 * Math.sqrt(axis.direction == "x" ? surface.width : surface.height); + + var delta = (axis.max - axis.min) / noTicks, + dec = -Math.floor(Math.log(delta) / Math.LN10), + maxDec = opts.tickDecimals; + + if (maxDec != null && dec > maxDec) { + dec = maxDec; + } + + var magn = Math.pow(10, -dec), + norm = delta / magn, // norm is between 1.0 and 10.0 + size; + + if (norm < 1.5) { + size = 1; + } else if (norm < 3) { + size = 2; + // special case for 2.5, requires an extra decimal + if (norm > 2.25 && (maxDec == null || dec + 1 <= maxDec)) { + size = 2.5; + ++dec; + } + } else if (norm < 7.5) { + size = 5; + } else { + size = 10; + } + + size *= magn; + + if (opts.minTickSize != null && size < opts.minTickSize) { + size = opts.minTickSize; + } + + axis.delta = delta; + axis.tickDecimals = Math.max(0, maxDec != null ? maxDec : dec); + axis.tickSize = opts.tickSize || size; + + // Time mode was moved to a plug-in in 0.8, and since so many people use it + // we'll add an especially friendly reminder to make sure they included it. + + if (opts.mode == "time" && !axis.tickGenerator) { + throw new Error("Time mode requires the flot.time plugin."); + } + + // Flot supports base-10 axes; any other mode else is handled by a plug-in, + // like flot.time.js. + + if (!axis.tickGenerator) { + + axis.tickGenerator = function (axis) { + + var ticks = [], + start = floorInBase(axis.min, axis.tickSize), + i = 0, + v = Number.NaN, + prev; + + do { + prev = v; + v = start + i * axis.tickSize; + ticks.push(v); + ++i; + } while (v < axis.max && v != prev); + return ticks; + }; + + axis.tickFormatter = function (value, axis) { + + var factor = axis.tickDecimals ? Math.pow(10, axis.tickDecimals) : 1; + var formatted = "" + Math.round(value * factor) / factor; + + // If tickDecimals was specified, ensure that we have exactly that + // much precision; otherwise default to the value's own precision. + + if (axis.tickDecimals != null) { + var decimal = formatted.indexOf("."); + var precision = decimal == -1 ? 0 : formatted.length - decimal - 1; + if (precision < axis.tickDecimals) { + return (precision ? formatted : formatted + ".") + ("" + factor).substr(1, axis.tickDecimals - precision); + } + } + + return formatted; + }; + } + + if ($.isFunction(opts.tickFormatter)) + axis.tickFormatter = function (v, axis) { return "" + opts.tickFormatter(v, axis); }; + + if (opts.alignTicksWithAxis != null) { + var otherAxis = (axis.direction == "x" ? xaxes : yaxes)[opts.alignTicksWithAxis - 1]; + if (otherAxis && otherAxis.used && otherAxis != axis) { + // consider snapping min/max to outermost nice ticks + var niceTicks = axis.tickGenerator(axis); + if (niceTicks.length > 0) { + if (opts.min == null) + axis.min = Math.min(axis.min, niceTicks[0]); + if (opts.max == null && niceTicks.length > 1) + axis.max = Math.max(axis.max, niceTicks[niceTicks.length - 1]); + } + + axis.tickGenerator = function (axis) { + // copy ticks, scaled to this axis + var ticks = [], v, i; + for (i = 0; i < otherAxis.ticks.length; ++i) { + v = (otherAxis.ticks[i].v - otherAxis.min) / (otherAxis.max - otherAxis.min); + v = axis.min + v * (axis.max - axis.min); + ticks.push(v); + } + return ticks; + }; + + // we might need an extra decimal since forced + // ticks don't necessarily fit naturally + if (!axis.mode && opts.tickDecimals == null) { + var extraDec = Math.max(0, -Math.floor(Math.log(axis.delta) / Math.LN10) + 1), + ts = axis.tickGenerator(axis); + + // only proceed if the tick interval rounded + // with an extra decimal doesn't give us a + // zero at end + if (!(ts.length > 1 && /\..*0$/.test((ts[1] - ts[0]).toFixed(extraDec)))) + axis.tickDecimals = extraDec; + } + } + } + } + + function setTicks(axis) { + var oticks = axis.options.ticks, ticks = []; + if (oticks == null || (typeof oticks == "number" && oticks > 0)) + ticks = axis.tickGenerator(axis); + else if (oticks) { + if ($.isFunction(oticks)) + // generate the ticks + ticks = oticks(axis); + else + ticks = oticks; + } + + // clean up/labelify the supplied ticks, copy them over + var i, v; + axis.ticks = []; + for (i = 0; i < ticks.length; ++i) { + var label = null; + var t = ticks[i]; + if (typeof t == "object") { + v = +t[0]; + if (t.length > 1) + label = t[1]; + } + else + v = +t; + if (label == null) + label = axis.tickFormatter(v, axis); + if (!isNaN(v)) + axis.ticks.push({ v: v, label: label }); + } + } + + function snapRangeToTicks(axis, ticks) { + if (axis.options.autoscaleMargin && ticks.length > 0) { + // snap to ticks + if (axis.options.min == null) + axis.min = Math.min(axis.min, ticks[0].v); + if (axis.options.max == null && ticks.length > 1) + axis.max = Math.max(axis.max, ticks[ticks.length - 1].v); + } + } + + function draw() { + + surface.clear(); + + executeHooks(hooks.drawBackground, [ctx]); + + var grid = options.grid; + + // draw background, if any + if (grid.show && grid.backgroundColor) + drawBackground(); + + if (grid.show && !grid.aboveData) { + drawGrid(); + } + + for (var i = 0; i < series.length; ++i) { + executeHooks(hooks.drawSeries, [ctx, series[i]]); + drawSeries(series[i]); + } + + executeHooks(hooks.draw, [ctx]); + + if (grid.show && grid.aboveData) { + drawGrid(); + } + + surface.render(); + + // A draw implies that either the axes or data have changed, so we + // should probably update the overlay highlights as well. + + triggerRedrawOverlay(); + } + + function extractRange(ranges, coord) { + var axis, from, to, key, axes = allAxes(); + + for (var i = 0; i < axes.length; ++i) { + axis = axes[i]; + if (axis.direction == coord) { + key = coord + axis.n + "axis"; + if (!ranges[key] && axis.n == 1) + key = coord + "axis"; // support x1axis as xaxis + if (ranges[key]) { + from = ranges[key].from; + to = ranges[key].to; + break; + } + } + } + + // backwards-compat stuff - to be removed in future + if (!ranges[key]) { + axis = coord == "x" ? xaxes[0] : yaxes[0]; + from = ranges[coord + "1"]; + to = ranges[coord + "2"]; + } + + // auto-reverse as an added bonus + if (from != null && to != null && from > to) { + var tmp = from; + from = to; + to = tmp; + } + + return { from: from, to: to, axis: axis }; + } + + function drawBackground() { + ctx.save(); + ctx.translate(plotOffset.left, plotOffset.top); + + ctx.fillStyle = getColorOrGradient(options.grid.backgroundColor, plotHeight, 0, "rgba(255, 255, 255, 0)"); + ctx.fillRect(0, 0, plotWidth, plotHeight); + ctx.restore(); + } + + function drawGrid() { + var i, axes, bw, bc; + + ctx.save(); + ctx.translate(plotOffset.left, plotOffset.top); + + // draw markings + var markings = options.grid.markings; + if (markings) { + if ($.isFunction(markings)) { + axes = plot.getAxes(); + // xmin etc. is backwards compatibility, to be + // removed in the future + axes.xmin = axes.xaxis.min; + axes.xmax = axes.xaxis.max; + axes.ymin = axes.yaxis.min; + axes.ymax = axes.yaxis.max; + + markings = markings(axes); + } + + for (i = 0; i < markings.length; ++i) { + var m = markings[i], + xrange = extractRange(m, "x"), + yrange = extractRange(m, "y"); + + // fill in missing + if (xrange.from == null) + xrange.from = xrange.axis.min; + if (xrange.to == null) + xrange.to = xrange.axis.max; + if (yrange.from == null) + yrange.from = yrange.axis.min; + if (yrange.to == null) + yrange.to = yrange.axis.max; + + // clip + if (xrange.to < xrange.axis.min || xrange.from > xrange.axis.max || + yrange.to < yrange.axis.min || yrange.from > yrange.axis.max) + continue; + + xrange.from = Math.max(xrange.from, xrange.axis.min); + xrange.to = Math.min(xrange.to, xrange.axis.max); + yrange.from = Math.max(yrange.from, yrange.axis.min); + yrange.to = Math.min(yrange.to, yrange.axis.max); + + var xequal = xrange.from === xrange.to, + yequal = yrange.from === yrange.to; + + if (xequal && yequal) { + continue; + } + + // then draw + xrange.from = Math.floor(xrange.axis.p2c(xrange.from)); + xrange.to = Math.floor(xrange.axis.p2c(xrange.to)); + yrange.from = Math.floor(yrange.axis.p2c(yrange.from)); + yrange.to = Math.floor(yrange.axis.p2c(yrange.to)); + + if (xequal || yequal) { + var lineWidth = m.lineWidth || options.grid.markingsLineWidth, + subPixel = lineWidth % 2 ? 0.5 : 0; + ctx.beginPath(); + ctx.strokeStyle = m.color || options.grid.markingsColor; + ctx.lineWidth = lineWidth; + if (xequal) { + ctx.moveTo(xrange.to + subPixel, yrange.from); + ctx.lineTo(xrange.to + subPixel, yrange.to); + } else { + ctx.moveTo(xrange.from, yrange.to + subPixel); + ctx.lineTo(xrange.to, yrange.to + subPixel); + } + ctx.stroke(); + } else { + ctx.fillStyle = m.color || options.grid.markingsColor; + ctx.fillRect(xrange.from, yrange.to, + xrange.to - xrange.from, + yrange.from - yrange.to); + } + } + } + + // draw the ticks + axes = allAxes(); + bw = options.grid.borderWidth; + + for (var j = 0; j < axes.length; ++j) { + var axis = axes[j], box = axis.box, + t = axis.tickLength, x, y, xoff, yoff; + if (!axis.show || axis.ticks.length == 0) + continue; + + ctx.lineWidth = 1; + + // find the edges + if (axis.direction == "x") { + x = 0; + if (t == "full") + y = (axis.position == "top" ? 0 : plotHeight); + else + y = box.top - plotOffset.top + (axis.position == "top" ? box.height : 0); + } + else { + y = 0; + if (t == "full") + x = (axis.position == "left" ? 0 : plotWidth); + else + x = box.left - plotOffset.left + (axis.position == "left" ? box.width : 0); + } + + // draw tick bar + if (!axis.innermost) { + ctx.strokeStyle = axis.options.color; + ctx.beginPath(); + xoff = yoff = 0; + if (axis.direction == "x") + xoff = plotWidth + 1; + else + yoff = plotHeight + 1; + + if (ctx.lineWidth == 1) { + if (axis.direction == "x") { + y = Math.floor(y) + 0.5; + } else { + x = Math.floor(x) + 0.5; + } + } + + ctx.moveTo(x, y); + ctx.lineTo(x + xoff, y + yoff); + ctx.stroke(); + } + + // draw ticks + + ctx.strokeStyle = axis.options.tickColor; + + ctx.beginPath(); + for (i = 0; i < axis.ticks.length; ++i) { + var v = axis.ticks[i].v; + + xoff = yoff = 0; + + if (isNaN(v) || v < axis.min || v > axis.max + // skip those lying on the axes if we got a border + || (t == "full" + && ((typeof bw == "object" && bw[axis.position] > 0) || bw > 0) + && (v == axis.min || v == axis.max))) + continue; + + if (axis.direction == "x") { + x = axis.p2c(v); + yoff = t == "full" ? -plotHeight : t; + + if (axis.position == "top") + yoff = -yoff; + } + else { + y = axis.p2c(v); + xoff = t == "full" ? -plotWidth : t; + + if (axis.position == "left") + xoff = -xoff; + } + + if (ctx.lineWidth == 1) { + if (axis.direction == "x") + x = Math.floor(x) + 0.5; + else + y = Math.floor(y) + 0.5; + } + + ctx.moveTo(x, y); + ctx.lineTo(x + xoff, y + yoff); + } + + ctx.stroke(); + } + + + // draw border + if (bw) { + // If either borderWidth or borderColor is an object, then draw the border + // line by line instead of as one rectangle + bc = options.grid.borderColor; + if(typeof bw == "object" || typeof bc == "object") { + if (typeof bw !== "object") { + bw = {top: bw, right: bw, bottom: bw, left: bw}; + } + if (typeof bc !== "object") { + bc = {top: bc, right: bc, bottom: bc, left: bc}; + } + + if (bw.top > 0) { + ctx.strokeStyle = bc.top; + ctx.lineWidth = bw.top; + ctx.beginPath(); + ctx.moveTo(0 - bw.left, 0 - bw.top/2); + ctx.lineTo(plotWidth, 0 - bw.top/2); + ctx.stroke(); + } + + if (bw.right > 0) { + ctx.strokeStyle = bc.right; + ctx.lineWidth = bw.right; + ctx.beginPath(); + ctx.moveTo(plotWidth + bw.right / 2, 0 - bw.top); + ctx.lineTo(plotWidth + bw.right / 2, plotHeight); + ctx.stroke(); + } + + if (bw.bottom > 0) { + ctx.strokeStyle = bc.bottom; + ctx.lineWidth = bw.bottom; + ctx.beginPath(); + ctx.moveTo(plotWidth + bw.right, plotHeight + bw.bottom / 2); + ctx.lineTo(0, plotHeight + bw.bottom / 2); + ctx.stroke(); + } + + if (bw.left > 0) { + ctx.strokeStyle = bc.left; + ctx.lineWidth = bw.left; + ctx.beginPath(); + ctx.moveTo(0 - bw.left/2, plotHeight + bw.bottom); + ctx.lineTo(0- bw.left/2, 0); + ctx.stroke(); + } + } + else { + ctx.lineWidth = bw; + ctx.strokeStyle = options.grid.borderColor; + ctx.strokeRect(-bw/2, -bw/2, plotWidth + bw, plotHeight + bw); + } + } + + ctx.restore(); + } + + function drawAxisLabels() { + + $.each(allAxes(), function (_, axis) { + var box = axis.box, + legacyStyles = axis.direction + "Axis " + axis.direction + axis.n + "Axis", + layer = "flot-" + axis.direction + "-axis flot-" + axis.direction + axis.n + "-axis " + legacyStyles, + font = axis.options.font || "flot-tick-label tickLabel", + tick, x, y, halign, valign; + + // Remove text before checking for axis.show and ticks.length; + // otherwise plugins, like flot-tickrotor, that draw their own + // tick labels will end up with both theirs and the defaults. + + surface.removeText(layer); + + if (!axis.show || axis.ticks.length == 0) + return; + + for (var i = 0; i < axis.ticks.length; ++i) { + + tick = axis.ticks[i]; + if (!tick.label || tick.v < axis.min || tick.v > axis.max) + continue; + + if (axis.direction == "x") { + halign = "center"; + x = plotOffset.left + axis.p2c(tick.v); + if (axis.position == "bottom") { + y = box.top + box.padding; + } else { + y = box.top + box.height - box.padding; + valign = "bottom"; + } + } else { + valign = "middle"; + y = plotOffset.top + axis.p2c(tick.v); + if (axis.position == "left") { + x = box.left + box.width - box.padding; + halign = "right"; + } else { + x = box.left + box.padding; + } + } + + surface.addText(layer, x, y, tick.label, font, null, null, halign, valign); + } + }); + } + + function drawSeries(series) { + if (series.lines.show) + drawSeriesLines(series); + if (series.bars.show) + drawSeriesBars(series); + if (series.points.show) + drawSeriesPoints(series); + } + + function drawSeriesLines(series) { + function plotLine(datapoints, xoffset, yoffset, axisx, axisy) { + var points = datapoints.points, + ps = datapoints.pointsize, + prevx = null, prevy = null; + + ctx.beginPath(); + for (var i = ps; i < points.length; i += ps) { + var x1 = points[i - ps], y1 = points[i - ps + 1], + x2 = points[i], y2 = points[i + 1]; + + if (x1 == null || x2 == null) + continue; + + // clip with ymin + if (y1 <= y2 && y1 < axisy.min) { + if (y2 < axisy.min) + continue; // line segment is outside + // compute new intersection point + x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; + y1 = axisy.min; + } + else if (y2 <= y1 && y2 < axisy.min) { + if (y1 < axisy.min) + continue; + x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; + y2 = axisy.min; + } + + // clip with ymax + if (y1 >= y2 && y1 > axisy.max) { + if (y2 > axisy.max) + continue; + x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; + y1 = axisy.max; + } + else if (y2 >= y1 && y2 > axisy.max) { + if (y1 > axisy.max) + continue; + x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; + y2 = axisy.max; + } + + // clip with xmin + if (x1 <= x2 && x1 < axisx.min) { + if (x2 < axisx.min) + continue; + y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; + x1 = axisx.min; + } + else if (x2 <= x1 && x2 < axisx.min) { + if (x1 < axisx.min) + continue; + y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; + x2 = axisx.min; + } + + // clip with xmax + if (x1 >= x2 && x1 > axisx.max) { + if (x2 > axisx.max) + continue; + y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; + x1 = axisx.max; + } + else if (x2 >= x1 && x2 > axisx.max) { + if (x1 > axisx.max) + continue; + y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; + x2 = axisx.max; + } + + if (x1 != prevx || y1 != prevy) + ctx.moveTo(axisx.p2c(x1) + xoffset, axisy.p2c(y1) + yoffset); + + prevx = x2; + prevy = y2; + ctx.lineTo(axisx.p2c(x2) + xoffset, axisy.p2c(y2) + yoffset); + } + ctx.stroke(); + } + + function plotLineArea(datapoints, axisx, axisy) { + var points = datapoints.points, + ps = datapoints.pointsize, + bottom = Math.min(Math.max(0, axisy.min), axisy.max), + i = 0, top, areaOpen = false, + ypos = 1, segmentStart = 0, segmentEnd = 0; + + // we process each segment in two turns, first forward + // direction to sketch out top, then once we hit the + // end we go backwards to sketch the bottom + while (true) { + if (ps > 0 && i > points.length + ps) + break; + + i += ps; // ps is negative if going backwards + + var x1 = points[i - ps], + y1 = points[i - ps + ypos], + x2 = points[i], y2 = points[i + ypos]; + + if (areaOpen) { + if (ps > 0 && x1 != null && x2 == null) { + // at turning point + segmentEnd = i; + ps = -ps; + ypos = 2; + continue; + } + + if (ps < 0 && i == segmentStart + ps) { + // done with the reverse sweep + ctx.fill(); + areaOpen = false; + ps = -ps; + ypos = 1; + i = segmentStart = segmentEnd + ps; + continue; + } + } + + if (x1 == null || x2 == null) + continue; + + // clip x values + + // clip with xmin + if (x1 <= x2 && x1 < axisx.min) { + if (x2 < axisx.min) + continue; + y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; + x1 = axisx.min; + } + else if (x2 <= x1 && x2 < axisx.min) { + if (x1 < axisx.min) + continue; + y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; + x2 = axisx.min; + } + + // clip with xmax + if (x1 >= x2 && x1 > axisx.max) { + if (x2 > axisx.max) + continue; + y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; + x1 = axisx.max; + } + else if (x2 >= x1 && x2 > axisx.max) { + if (x1 > axisx.max) + continue; + y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; + x2 = axisx.max; + } + + if (!areaOpen) { + // open area + ctx.beginPath(); + ctx.moveTo(axisx.p2c(x1), axisy.p2c(bottom)); + areaOpen = true; + } + + // now first check the case where both is outside + if (y1 >= axisy.max && y2 >= axisy.max) { + ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.max)); + ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.max)); + continue; + } + else if (y1 <= axisy.min && y2 <= axisy.min) { + ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.min)); + ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.min)); + continue; + } + + // else it's a bit more complicated, there might + // be a flat maxed out rectangle first, then a + // triangular cutout or reverse; to find these + // keep track of the current x values + var x1old = x1, x2old = x2; + + // clip the y values, without shortcutting, we + // go through all cases in turn + + // clip with ymin + if (y1 <= y2 && y1 < axisy.min && y2 >= axisy.min) { + x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; + y1 = axisy.min; + } + else if (y2 <= y1 && y2 < axisy.min && y1 >= axisy.min) { + x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; + y2 = axisy.min; + } + + // clip with ymax + if (y1 >= y2 && y1 > axisy.max && y2 <= axisy.max) { + x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; + y1 = axisy.max; + } + else if (y2 >= y1 && y2 > axisy.max && y1 <= axisy.max) { + x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; + y2 = axisy.max; + } + + // if the x value was changed we got a rectangle + // to fill + if (x1 != x1old) { + ctx.lineTo(axisx.p2c(x1old), axisy.p2c(y1)); + // it goes to (x1, y1), but we fill that below + } + + // fill triangular section, this sometimes result + // in redundant points if (x1, y1) hasn't changed + // from previous line to, but we just ignore that + ctx.lineTo(axisx.p2c(x1), axisy.p2c(y1)); + ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2)); + + // fill the other rectangle if it's there + if (x2 != x2old) { + ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2)); + ctx.lineTo(axisx.p2c(x2old), axisy.p2c(y2)); + } + } + } + + ctx.save(); + ctx.translate(plotOffset.left, plotOffset.top); + ctx.lineJoin = "round"; + + var lw = series.lines.lineWidth, + sw = series.shadowSize; + // FIXME: consider another form of shadow when filling is turned on + if (lw > 0 && sw > 0) { + // draw shadow as a thick and thin line with transparency + ctx.lineWidth = sw; + ctx.strokeStyle = "rgba(0,0,0,0.1)"; + // position shadow at angle from the mid of line + var angle = Math.PI/18; + plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/2), Math.cos(angle) * (lw/2 + sw/2), series.xaxis, series.yaxis); + ctx.lineWidth = sw/2; + plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/4), Math.cos(angle) * (lw/2 + sw/4), series.xaxis, series.yaxis); + } + + ctx.lineWidth = lw; + ctx.strokeStyle = series.color; + var fillStyle = getFillStyle(series.lines, series.color, 0, plotHeight); + if (fillStyle) { + ctx.fillStyle = fillStyle; + plotLineArea(series.datapoints, series.xaxis, series.yaxis); + } + + if (lw > 0) + plotLine(series.datapoints, 0, 0, series.xaxis, series.yaxis); + ctx.restore(); + } + + function drawSeriesPoints(series) { + function plotPoints(datapoints, radius, fillStyle, offset, shadow, axisx, axisy, symbol) { + var points = datapoints.points, ps = datapoints.pointsize; + + for (var i = 0; i < points.length; i += ps) { + var x = points[i], y = points[i + 1]; + if (x == null || x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max) + continue; + + ctx.beginPath(); + x = axisx.p2c(x); + y = axisy.p2c(y) + offset; + if (symbol == "circle") + ctx.arc(x, y, radius, 0, shadow ? Math.PI : Math.PI * 2, false); + else + symbol(ctx, x, y, radius, shadow); + ctx.closePath(); + + if (fillStyle) { + ctx.fillStyle = fillStyle; + ctx.fill(); + } + ctx.stroke(); + } + } + + ctx.save(); + ctx.translate(plotOffset.left, plotOffset.top); + + var lw = series.points.lineWidth, + sw = series.shadowSize, + radius = series.points.radius, + symbol = series.points.symbol; + + // If the user sets the line width to 0, we change it to a very + // small value. A line width of 0 seems to force the default of 1. + // Doing the conditional here allows the shadow setting to still be + // optional even with a lineWidth of 0. + + if( lw == 0 ) + lw = 0.0001; + + if (lw > 0 && sw > 0) { + // draw shadow in two steps + var w = sw / 2; + ctx.lineWidth = w; + ctx.strokeStyle = "rgba(0,0,0,0.1)"; + plotPoints(series.datapoints, radius, null, w + w/2, true, + series.xaxis, series.yaxis, symbol); + + ctx.strokeStyle = "rgba(0,0,0,0.2)"; + plotPoints(series.datapoints, radius, null, w/2, true, + series.xaxis, series.yaxis, symbol); + } + + ctx.lineWidth = lw; + ctx.strokeStyle = series.color; + plotPoints(series.datapoints, radius, + getFillStyle(series.points, series.color), 0, false, + series.xaxis, series.yaxis, symbol); + ctx.restore(); + } + + function drawBar(x, y, b, barLeft, barRight, fillStyleCallback, axisx, axisy, c, horizontal, lineWidth) { + var left, right, bottom, top, + drawLeft, drawRight, drawTop, drawBottom, + tmp; + + // in horizontal mode, we start the bar from the left + // instead of from the bottom so it appears to be + // horizontal rather than vertical + if (horizontal) { + drawBottom = drawRight = drawTop = true; + drawLeft = false; + left = b; + right = x; + top = y + barLeft; + bottom = y + barRight; + + // account for negative bars + if (right < left) { + tmp = right; + right = left; + left = tmp; + drawLeft = true; + drawRight = false; + } + } + else { + drawLeft = drawRight = drawTop = true; + drawBottom = false; + left = x + barLeft; + right = x + barRight; + bottom = b; + top = y; + + // account for negative bars + if (top < bottom) { + tmp = top; + top = bottom; + bottom = tmp; + drawBottom = true; + drawTop = false; + } + } + + // clip + if (right < axisx.min || left > axisx.max || + top < axisy.min || bottom > axisy.max) + return; + + if (left < axisx.min) { + left = axisx.min; + drawLeft = false; + } + + if (right > axisx.max) { + right = axisx.max; + drawRight = false; + } + + if (bottom < axisy.min) { + bottom = axisy.min; + drawBottom = false; + } + + if (top > axisy.max) { + top = axisy.max; + drawTop = false; + } + + left = axisx.p2c(left); + bottom = axisy.p2c(bottom); + right = axisx.p2c(right); + top = axisy.p2c(top); + + // fill the bar + if (fillStyleCallback) { + c.fillStyle = fillStyleCallback(bottom, top); + c.fillRect(left, top, right - left, bottom - top) + } + + // draw outline + if (lineWidth > 0 && (drawLeft || drawRight || drawTop || drawBottom)) { + c.beginPath(); + + // FIXME: inline moveTo is buggy with excanvas + c.moveTo(left, bottom); + if (drawLeft) + c.lineTo(left, top); + else + c.moveTo(left, top); + if (drawTop) + c.lineTo(right, top); + else + c.moveTo(right, top); + if (drawRight) + c.lineTo(right, bottom); + else + c.moveTo(right, bottom); + if (drawBottom) + c.lineTo(left, bottom); + else + c.moveTo(left, bottom); + c.stroke(); + } + } + + function drawSeriesBars(series) { + function plotBars(datapoints, barLeft, barRight, fillStyleCallback, axisx, axisy) { + var points = datapoints.points, ps = datapoints.pointsize; + + for (var i = 0; i < points.length; i += ps) { + if (points[i] == null) + continue; + drawBar(points[i], points[i + 1], points[i + 2], barLeft, barRight, fillStyleCallback, axisx, axisy, ctx, series.bars.horizontal, series.bars.lineWidth); + } + } + + ctx.save(); + ctx.translate(plotOffset.left, plotOffset.top); + + // FIXME: figure out a way to add shadows (for instance along the right edge) + ctx.lineWidth = series.bars.lineWidth; + ctx.strokeStyle = series.color; + + var barLeft; + + switch (series.bars.align) { + case "left": + barLeft = 0; + break; + case "right": + barLeft = -series.bars.barWidth; + break; + default: + barLeft = -series.bars.barWidth / 2; + } + + var fillStyleCallback = series.bars.fill ? function (bottom, top) { return getFillStyle(series.bars, series.color, bottom, top); } : null; + plotBars(series.datapoints, barLeft, barLeft + series.bars.barWidth, fillStyleCallback, series.xaxis, series.yaxis); + ctx.restore(); + } + + function getFillStyle(filloptions, seriesColor, bottom, top) { + var fill = filloptions.fill; + if (!fill) + return null; + + if (filloptions.fillColor) + return getColorOrGradient(filloptions.fillColor, bottom, top, seriesColor); + + var c = $.color.parse(seriesColor); + c.a = typeof fill == "number" ? fill : 0.4; + c.normalize(); + return c.toString(); + } + + function insertLegend() { + + if (options.legend.container != null) { + $(options.legend.container).html(""); + } else { + placeholder.find(".legend").remove(); + } + + if (!options.legend.show) { + return; + } + + var fragments = [], entries = [], rowStarted = false, + lf = options.legend.labelFormatter, s, label; + + // Build a list of legend entries, with each having a label and a color + + for (var i = 0; i < series.length; ++i) { + s = series[i]; + if (s.label) { + label = lf ? lf(s.label, s) : s.label; + if (label) { + entries.push({ + label: label, + color: s.color + }); + } + } + } + + // Sort the legend using either the default or a custom comparator + + if (options.legend.sorted) { + if ($.isFunction(options.legend.sorted)) { + entries.sort(options.legend.sorted); + } else if (options.legend.sorted == "reverse") { + entries.reverse(); + } else { + var ascending = options.legend.sorted != "descending"; + entries.sort(function(a, b) { + return a.label == b.label ? 0 : ( + (a.label < b.label) != ascending ? 1 : -1 // Logical XOR + ); + }); + } + } + + // Generate markup for the list of entries, in their final order + + for (var i = 0; i < entries.length; ++i) { + + var entry = entries[i]; + + if (i % options.legend.noColumns == 0) { + if (rowStarted) + fragments.push('</tr>'); + fragments.push('<tr>'); + rowStarted = true; + } + + fragments.push( + '<td class="legendColorBox"><div style="border:1px solid ' + options.legend.labelBoxBorderColor + ';padding:1px"><div style="width:4px;height:0;border:5px solid ' + entry.color + ';overflow:hidden"></div></div></td>' + + '<td class="legendLabel">' + entry.label + '</td>' + ); + } + + if (rowStarted) + fragments.push('</tr>'); + + if (fragments.length == 0) + return; + + var table = '<table style="font-size:smaller;color:' + options.grid.color + '">' + fragments.join("") + '</table>'; + if (options.legend.container != null) + $(options.legend.container).html(table); + else { + var pos = "", + p = options.legend.position, + m = options.legend.margin; + if (m[0] == null) + m = [m, m]; + if (p.charAt(0) == "n") + pos += 'top:' + (m[1] + plotOffset.top) + 'px;'; + else if (p.charAt(0) == "s") + pos += 'bottom:' + (m[1] + plotOffset.bottom) + 'px;'; + if (p.charAt(1) == "e") + pos += 'right:' + (m[0] + plotOffset.right) + 'px;'; + else if (p.charAt(1) == "w") + pos += 'left:' + (m[0] + plotOffset.left) + 'px;'; + var legend = $('<div class="legend">' + table.replace('style="', 'style="position:absolute;' + pos +';') + '</div>').appendTo(placeholder); + if (options.legend.backgroundOpacity != 0.0) { + // put in the transparent background + // separately to avoid blended labels and + // label boxes + var c = options.legend.backgroundColor; + if (c == null) { + c = options.grid.backgroundColor; + if (c && typeof c == "string") + c = $.color.parse(c); + else + c = $.color.extract(legend, 'background-color'); + c.a = 1; + c = c.toString(); + } + var div = legend.children(); + $('<div style="position:absolute;width:' + div.width() + 'px;height:' + div.height() + 'px;' + pos +'background-color:' + c + ';"> </div>').prependTo(legend).css('opacity', options.legend.backgroundOpacity); + } + } + } + + + // interactive features + + var highlights = [], + redrawTimeout = null; + + // returns the data item the mouse is over, or null if none is found + function findNearbyItem(mouseX, mouseY, seriesFilter) { + var maxDistance = options.grid.mouseActiveRadius, + smallestDistance = maxDistance * maxDistance + 1, + item = null, foundPoint = false, i, j, ps; + + for (i = series.length - 1; i >= 0; --i) { + if (!seriesFilter(series[i])) + continue; + + var s = series[i], + axisx = s.xaxis, + axisy = s.yaxis, + points = s.datapoints.points, + mx = axisx.c2p(mouseX), // precompute some stuff to make the loop faster + my = axisy.c2p(mouseY), + maxx = maxDistance / axisx.scale, + maxy = maxDistance / axisy.scale; + + ps = s.datapoints.pointsize; + // with inverse transforms, we can't use the maxx/maxy + // optimization, sadly + if (axisx.options.inverseTransform) + maxx = Number.MAX_VALUE; + if (axisy.options.inverseTransform) + maxy = Number.MAX_VALUE; + + if (s.lines.show || s.points.show) { + for (j = 0; j < points.length; j += ps) { + var x = points[j], y = points[j + 1]; + if (x == null) + continue; + + // For points and lines, the cursor must be within a + // certain distance to the data point + if (x - mx > maxx || x - mx < -maxx || + y - my > maxy || y - my < -maxy) + continue; + + // We have to calculate distances in pixels, not in + // data units, because the scales of the axes may be different + var dx = Math.abs(axisx.p2c(x) - mouseX), + dy = Math.abs(axisy.p2c(y) - mouseY), + dist = dx * dx + dy * dy; // we save the sqrt + + // use <= to ensure last point takes precedence + // (last generally means on top of) + if (dist < smallestDistance) { + smallestDistance = dist; + item = [i, j / ps]; + } + } + } + + if (s.bars.show && !item) { // no other point can be nearby + + var barLeft, barRight; + + switch (s.bars.align) { + case "left": + barLeft = 0; + break; + case "right": + barLeft = -s.bars.barWidth; + break; + default: + barLeft = -s.bars.barWidth / 2; + } + + barRight = barLeft + s.bars.barWidth; + + for (j = 0; j < points.length; j += ps) { + var x = points[j], y = points[j + 1], b = points[j + 2]; + if (x == null) + continue; + + // for a bar graph, the cursor must be inside the bar + if (series[i].bars.horizontal ? + (mx <= Math.max(b, x) && mx >= Math.min(b, x) && + my >= y + barLeft && my <= y + barRight) : + (mx >= x + barLeft && mx <= x + barRight && + my >= Math.min(b, y) && my <= Math.max(b, y))) + item = [i, j / ps]; + } + } + } + + if (item) { + i = item[0]; + j = item[1]; + ps = series[i].datapoints.pointsize; + + return { datapoint: series[i].datapoints.points.slice(j * ps, (j + 1) * ps), + dataIndex: j, + series: series[i], + seriesIndex: i }; + } + + return null; + } + + function onMouseMove(e) { + if (options.grid.hoverable) + triggerClickHoverEvent("plothover", e, + function (s) { return s["hoverable"] != false; }); + } + + function onMouseLeave(e) { + if (options.grid.hoverable) + triggerClickHoverEvent("plothover", e, + function (s) { return false; }); + } + + function onClick(e) { + triggerClickHoverEvent("plotclick", e, + function (s) { return s["clickable"] != false; }); + } + + // trigger click or hover event (they send the same parameters + // so we share their code) + function triggerClickHoverEvent(eventname, event, seriesFilter) { + var offset = eventHolder.offset(), + canvasX = event.pageX - offset.left - plotOffset.left, + canvasY = event.pageY - offset.top - plotOffset.top, + pos = canvasToAxisCoords({ left: canvasX, top: canvasY }); + + pos.pageX = event.pageX; + pos.pageY = event.pageY; + + var item = findNearbyItem(canvasX, canvasY, seriesFilter); + + if (item) { + // fill in mouse pos for any listeners out there + item.pageX = parseInt(item.series.xaxis.p2c(item.datapoint[0]) + offset.left + plotOffset.left, 10); + item.pageY = parseInt(item.series.yaxis.p2c(item.datapoint[1]) + offset.top + plotOffset.top, 10); + } + + if (options.grid.autoHighlight) { + // clear auto-highlights + for (var i = 0; i < highlights.length; ++i) { + var h = highlights[i]; + if (h.auto == eventname && + !(item && h.series == item.series && + h.point[0] == item.datapoint[0] && + h.point[1] == item.datapoint[1])) + unhighlight(h.series, h.point); + } + + if (item) + highlight(item.series, item.datapoint, eventname); + } + + placeholder.trigger(eventname, [ pos, item ]); + } + + function triggerRedrawOverlay() { + var t = options.interaction.redrawOverlayInterval; + if (t == -1) { // skip event queue + drawOverlay(); + return; + } + + if (!redrawTimeout) + redrawTimeout = setTimeout(drawOverlay, t); + } + + function drawOverlay() { + redrawTimeout = null; + + // draw highlights + octx.save(); + overlay.clear(); + octx.translate(plotOffset.left, plotOffset.top); + + var i, hi; + for (i = 0; i < highlights.length; ++i) { + hi = highlights[i]; + + if (hi.series.bars.show) + drawBarHighlight(hi.series, hi.point); + else + drawPointHighlight(hi.series, hi.point); + } + octx.restore(); + + executeHooks(hooks.drawOverlay, [octx]); + } + + function highlight(s, point, auto) { + if (typeof s == "number") + s = series[s]; + + if (typeof point == "number") { + var ps = s.datapoints.pointsize; + point = s.datapoints.points.slice(ps * point, ps * (point + 1)); + } + + var i = indexOfHighlight(s, point); + if (i == -1) { + highlights.push({ series: s, point: point, auto: auto }); + + triggerRedrawOverlay(); + } + else if (!auto) + highlights[i].auto = false; + } + + function unhighlight(s, point) { + if (s == null && point == null) { + highlights = []; + triggerRedrawOverlay(); + return; + } + + if (typeof s == "number") + s = series[s]; + + if (typeof point == "number") { + var ps = s.datapoints.pointsize; + point = s.datapoints.points.slice(ps * point, ps * (point + 1)); + } + + var i = indexOfHighlight(s, point); + if (i != -1) { + highlights.splice(i, 1); + + triggerRedrawOverlay(); + } + } + + function indexOfHighlight(s, p) { + for (var i = 0; i < highlights.length; ++i) { + var h = highlights[i]; + if (h.series == s && h.point[0] == p[0] + && h.point[1] == p[1]) + return i; + } + return -1; + } + + function drawPointHighlight(series, point) { + var x = point[0], y = point[1], + axisx = series.xaxis, axisy = series.yaxis, + highlightColor = (typeof series.highlightColor === "string") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString(); + + if (x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max) + return; + + var pointRadius = series.points.radius + series.points.lineWidth / 2; + octx.lineWidth = pointRadius; + octx.strokeStyle = highlightColor; + var radius = 1.5 * pointRadius; + x = axisx.p2c(x); + y = axisy.p2c(y); + + octx.beginPath(); + if (series.points.symbol == "circle") + octx.arc(x, y, radius, 0, 2 * Math.PI, false); + else + series.points.symbol(octx, x, y, radius, false); + octx.closePath(); + octx.stroke(); + } + + function drawBarHighlight(series, point) { + var highlightColor = (typeof series.highlightColor === "string") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString(), + fillStyle = highlightColor, + barLeft; + + switch (series.bars.align) { + case "left": + barLeft = 0; + break; + case "right": + barLeft = -series.bars.barWidth; + break; + default: + barLeft = -series.bars.barWidth / 2; + } + + octx.lineWidth = series.bars.lineWidth; + octx.strokeStyle = highlightColor; + + drawBar(point[0], point[1], point[2] || 0, barLeft, barLeft + series.bars.barWidth, + function () { return fillStyle; }, series.xaxis, series.yaxis, octx, series.bars.horizontal, series.bars.lineWidth); + } + + function getColorOrGradient(spec, bottom, top, defaultColor) { + if (typeof spec == "string") + return spec; + else { + // assume this is a gradient spec; IE currently only + // supports a simple vertical gradient properly, so that's + // what we support too + var gradient = ctx.createLinearGradient(0, top, 0, bottom); + + for (var i = 0, l = spec.colors.length; i < l; ++i) { + var c = spec.colors[i]; + if (typeof c != "string") { + var co = $.color.parse(defaultColor); + if (c.brightness != null) + co = co.scale('rgb', c.brightness); + if (c.opacity != null) + co.a *= c.opacity; + c = co.toString(); + } + gradient.addColorStop(i / (l - 1), c); + } + + return gradient; + } + } + } + + // Add the plot function to the top level of the jQuery object + + $.plot = function(placeholder, data, options) { + //var t0 = new Date(); + var plot = new Plot($(placeholder), data, options, $.plot.plugins); + //(window.console ? console.log : alert)("time used (msecs): " + ((new Date()).getTime() - t0.getTime())); + return plot; + }; + + $.plot.version = "0.8.3"; + + $.plot.plugins = []; + + // Also add the plot function as a chainable property + + $.fn.plot = function(data, options) { + return this.each(function() { + $.plot(this, data, options); + }); + }; + + // round to nearby lower multiple of base + function floorInBase(n, base) { + return base * Math.floor(n / base); + } + +})(jQuery); diff --git a/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.navigate.js b/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.navigate.js new file mode 100644 index 0000000000000000000000000000000000000000..13fb7f17d04b2463c6da2355e99de4e4fc08f631 --- /dev/null +++ b/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.navigate.js @@ -0,0 +1,346 @@ +/* Flot plugin for adding the ability to pan and zoom the plot. + +Copyright (c) 2007-2014 IOLA and Ole Laursen. +Licensed under the MIT license. + +The default behaviour is double click and scrollwheel up/down to zoom in, drag +to pan. The plugin defines plot.zoom({ center }), plot.zoomOut() and +plot.pan( offset ) so you easily can add custom controls. It also fires +"plotpan" and "plotzoom" events, useful for synchronizing plots. + +The plugin supports these options: + + zoom: { + interactive: false + trigger: "dblclick" // or "click" for single click + amount: 1.5 // 2 = 200% (zoom in), 0.5 = 50% (zoom out) + } + + pan: { + interactive: false + cursor: "move" // CSS mouse cursor value used when dragging, e.g. "pointer" + frameRate: 20 + } + + xaxis, yaxis, x2axis, y2axis: { + zoomRange: null // or [ number, number ] (min range, max range) or false + panRange: null // or [ number, number ] (min, max) or false + } + +"interactive" enables the built-in drag/click behaviour. If you enable +interactive for pan, then you'll have a basic plot that supports moving +around; the same for zoom. + +"amount" specifies the default amount to zoom in (so 1.5 = 150%) relative to +the current viewport. + +"cursor" is a standard CSS mouse cursor string used for visual feedback to the +user when dragging. + +"frameRate" specifies the maximum number of times per second the plot will +update itself while the user is panning around on it (set to null to disable +intermediate pans, the plot will then not update until the mouse button is +released). + +"zoomRange" is the interval in which zooming can happen, e.g. with zoomRange: +[1, 100] the zoom will never scale the axis so that the difference between min +and max is smaller than 1 or larger than 100. You can set either end to null +to ignore, e.g. [1, null]. If you set zoomRange to false, zooming on that axis +will be disabled. + +"panRange" confines the panning to stay within a range, e.g. with panRange: +[-10, 20] panning stops at -10 in one end and at 20 in the other. Either can +be null, e.g. [-10, null]. If you set panRange to false, panning on that axis +will be disabled. + +Example API usage: + + plot = $.plot(...); + + // zoom default amount in on the pixel ( 10, 20 ) + plot.zoom({ center: { left: 10, top: 20 } }); + + // zoom out again + plot.zoomOut({ center: { left: 10, top: 20 } }); + + // zoom 200% in on the pixel (10, 20) + plot.zoom({ amount: 2, center: { left: 10, top: 20 } }); + + // pan 100 pixels to the left and 20 down + plot.pan({ left: -100, top: 20 }) + +Here, "center" specifies where the center of the zooming should happen. Note +that this is defined in pixel space, not the space of the data points (you can +use the p2c helpers on the axes in Flot to help you convert between these). + +"amount" is the amount to zoom the viewport relative to the current range, so +1 is 100% (i.e. no change), 1.5 is 150% (zoom in), 0.7 is 70% (zoom out). You +can set the default in the options. + +*/ + +// First two dependencies, jquery.event.drag.js and +// jquery.mousewheel.js, we put them inline here to save people the +// effort of downloading them. + +/* +jquery.event.drag.js ~ v1.5 ~ Copyright (c) 2008, Three Dub Media (http://threedubmedia.com) +Licensed under the MIT License ~ http://threedubmedia.googlecode.com/files/MIT-LICENSE.txt +*/ +(function(a){function e(h){var k,j=this,l=h.data||{};if(l.elem)j=h.dragTarget=l.elem,h.dragProxy=d.proxy||j,h.cursorOffsetX=l.pageX-l.left,h.cursorOffsetY=l.pageY-l.top,h.offsetX=h.pageX-h.cursorOffsetX,h.offsetY=h.pageY-h.cursorOffsetY;else if(d.dragging||l.which>0&&h.which!=l.which||a(h.target).is(l.not))return;switch(h.type){case"mousedown":return a.extend(l,a(j).offset(),{elem:j,target:h.target,pageX:h.pageX,pageY:h.pageY}),b.add(document,"mousemove mouseup",e,l),i(j,!1),d.dragging=null,!1;case!d.dragging&&"mousemove":if(g(h.pageX-l.pageX)+g(h.pageY-l.pageY)<l.distance)break;h.target=l.target,k=f(h,"dragstart",j),k!==!1&&(d.dragging=j,d.proxy=h.dragProxy=a(k||j)[0]);case"mousemove":if(d.dragging){if(k=f(h,"drag",j),c.drop&&(c.drop.allowed=k!==!1,c.drop.handler(h)),k!==!1)break;h.type="mouseup"}case"mouseup":b.remove(document,"mousemove mouseup",e),d.dragging&&(c.drop&&c.drop.handler(h),f(h,"dragend",j)),i(j,!0),d.dragging=d.proxy=l.elem=!1}return!0}function f(b,c,d){b.type=c;var e=a.event.dispatch.call(d,b);return e===!1?!1:e||b.result}function g(a){return Math.pow(a,2)}function h(){return d.dragging===!1}function i(a,b){a&&(a.unselectable=b?"off":"on",a.onselectstart=function(){return b},a.style&&(a.style.MozUserSelect=b?"":"none"))}a.fn.drag=function(a,b,c){return b&&this.bind("dragstart",a),c&&this.bind("dragend",c),a?this.bind("drag",b?b:a):this.trigger("drag")};var b=a.event,c=b.special,d=c.drag={not:":input",distance:0,which:1,dragging:!1,setup:function(c){c=a.extend({distance:d.distance,which:d.which,not:d.not},c||{}),c.distance=g(c.distance),b.add(this,"mousedown",e,c),this.attachEvent&&this.attachEvent("ondragstart",h)},teardown:function(){b.remove(this,"mousedown",e),this===d.dragging&&(d.dragging=d.proxy=!1),i(this,!0),this.detachEvent&&this.detachEvent("ondragstart",h)}};c.dragstart=c.dragend={setup:function(){},teardown:function(){}}})(jQuery); + +/* jquery.mousewheel.min.js + * Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net) + * Licensed under the MIT License (LICENSE.txt). + * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers. + * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix. + * Thanks to: Seamus Leahy for adding deltaX and deltaY + * + * Version: 3.0.6 + * + * Requires: 1.2.2+ + */ +(function(d){function e(a){var b=a||window.event,c=[].slice.call(arguments,1),f=0,e=0,g=0,a=d.event.fix(b);a.type="mousewheel";b.wheelDelta&&(f=b.wheelDelta/120);b.detail&&(f=-b.detail/3);g=f;void 0!==b.axis&&b.axis===b.HORIZONTAL_AXIS&&(g=0,e=-1*f);void 0!==b.wheelDeltaY&&(g=b.wheelDeltaY/120);void 0!==b.wheelDeltaX&&(e=-1*b.wheelDeltaX/120);c.unshift(a,f,e,g);return(d.event.dispatch||d.event.handle).apply(this,c)}var c=["DOMMouseScroll","mousewheel"];if(d.event.fixHooks)for(var h=c.length;h;)d.event.fixHooks[c[--h]]=d.event.mouseHooks;d.event.special.mousewheel={setup:function(){if(this.addEventListener)for(var a=c.length;a;)this.addEventListener(c[--a],e,!1);else this.onmousewheel=e},teardown:function(){if(this.removeEventListener)for(var a=c.length;a;)this.removeEventListener(c[--a],e,!1);else this.onmousewheel=null}};d.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})})(jQuery); + + + + +(function ($) { + var options = { + xaxis: { + zoomRange: null, // or [number, number] (min range, max range) + panRange: null // or [number, number] (min, max) + }, + zoom: { + interactive: false, + trigger: "dblclick", // or "click" for single click + amount: 1.5 // how much to zoom relative to current position, 2 = 200% (zoom in), 0.5 = 50% (zoom out) + }, + pan: { + interactive: false, + cursor: "move", + frameRate: 20 + } + }; + + function init(plot) { + function onZoomClick(e, zoomOut) { + var c = plot.offset(); + c.left = e.pageX - c.left; + c.top = e.pageY - c.top; + if (zoomOut) + plot.zoomOut({ center: c }); + else + plot.zoom({ center: c }); + } + + function onMouseWheel(e, delta) { + e.preventDefault(); + onZoomClick(e, delta < 0); + return false; + } + + var prevCursor = 'default', prevPageX = 0, prevPageY = 0, + panTimeout = null; + + function onDragStart(e) { + if (e.which != 1) // only accept left-click + return false; + var c = plot.getPlaceholder().css('cursor'); + if (c) + prevCursor = c; + plot.getPlaceholder().css('cursor', plot.getOptions().pan.cursor); + prevPageX = e.pageX; + prevPageY = e.pageY; + } + + function onDrag(e) { + var frameRate = plot.getOptions().pan.frameRate; + if (panTimeout || !frameRate) + return; + + panTimeout = setTimeout(function () { + plot.pan({ left: prevPageX - e.pageX, + top: prevPageY - e.pageY }); + prevPageX = e.pageX; + prevPageY = e.pageY; + + panTimeout = null; + }, 1 / frameRate * 1000); + } + + function onDragEnd(e) { + if (panTimeout) { + clearTimeout(panTimeout); + panTimeout = null; + } + + plot.getPlaceholder().css('cursor', prevCursor); + plot.pan({ left: prevPageX - e.pageX, + top: prevPageY - e.pageY }); + } + + function bindEvents(plot, eventHolder) { + var o = plot.getOptions(); + if (o.zoom.interactive) { + eventHolder[o.zoom.trigger](onZoomClick); + eventHolder.mousewheel(onMouseWheel); + } + + if (o.pan.interactive) { + eventHolder.bind("dragstart", { distance: 10 }, onDragStart); + eventHolder.bind("drag", onDrag); + eventHolder.bind("dragend", onDragEnd); + } + } + + plot.zoomOut = function (args) { + if (!args) + args = {}; + + if (!args.amount) + args.amount = plot.getOptions().zoom.amount; + + args.amount = 1 / args.amount; + plot.zoom(args); + }; + + plot.zoom = function (args) { + if (!args) + args = {}; + + var c = args.center, + amount = args.amount || plot.getOptions().zoom.amount, + w = plot.width(), h = plot.height(); + + if (!c) + c = { left: w / 2, top: h / 2 }; + + var xf = c.left / w, + yf = c.top / h, + minmax = { + x: { + min: c.left - xf * w / amount, + max: c.left + (1 - xf) * w / amount + }, + y: { + min: c.top - yf * h / amount, + max: c.top + (1 - yf) * h / amount + } + }; + + $.each(plot.getAxes(), function(_, axis) { + var opts = axis.options, + min = minmax[axis.direction].min, + max = minmax[axis.direction].max, + zr = opts.zoomRange, + pr = opts.panRange; + + if (zr === false) // no zooming on this axis + return; + + min = axis.c2p(min); + max = axis.c2p(max); + if (min > max) { + // make sure min < max + var tmp = min; + min = max; + max = tmp; + } + + //Check that we are in panRange + if (pr) { + if (pr[0] != null && min < pr[0]) { + min = pr[0]; + } + if (pr[1] != null && max > pr[1]) { + max = pr[1]; + } + } + + var range = max - min; + if (zr && + ((zr[0] != null && range < zr[0] && amount >1) || + (zr[1] != null && range > zr[1] && amount <1))) + return; + + opts.min = min; + opts.max = max; + }); + + plot.setupGrid(); + plot.draw(); + + if (!args.preventEvent) + plot.getPlaceholder().trigger("plotzoom", [ plot, args ]); + }; + + plot.pan = function (args) { + var delta = { + x: +args.left, + y: +args.top + }; + + if (isNaN(delta.x)) + delta.x = 0; + if (isNaN(delta.y)) + delta.y = 0; + + $.each(plot.getAxes(), function (_, axis) { + var opts = axis.options, + min, max, d = delta[axis.direction]; + + min = axis.c2p(axis.p2c(axis.min) + d), + max = axis.c2p(axis.p2c(axis.max) + d); + + var pr = opts.panRange; + if (pr === false) // no panning on this axis + return; + + if (pr) { + // check whether we hit the wall + if (pr[0] != null && pr[0] > min) { + d = pr[0] - min; + min += d; + max += d; + } + + if (pr[1] != null && pr[1] < max) { + d = pr[1] - max; + min += d; + max += d; + } + } + + opts.min = min; + opts.max = max; + }); + + plot.setupGrid(); + plot.draw(); + + if (!args.preventEvent) + plot.getPlaceholder().trigger("plotpan", [ plot, args ]); + }; + + function shutdown(plot, eventHolder) { + eventHolder.unbind(plot.getOptions().zoom.trigger, onZoomClick); + eventHolder.unbind("mousewheel", onMouseWheel); + eventHolder.unbind("dragstart", onDragStart); + eventHolder.unbind("drag", onDrag); + eventHolder.unbind("dragend", onDragEnd); + if (panTimeout) + clearTimeout(panTimeout); + } + + plot.hooks.bindEvents.push(bindEvents); + plot.hooks.shutdown.push(shutdown); + } + + $.plot.plugins.push({ + init: init, + options: options, + name: 'navigate', + version: '1.3' + }); +})(jQuery); diff --git a/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.pie.js b/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.pie.js new file mode 100644 index 0000000000000000000000000000000000000000..9c19db998bbdcf21d88f58cf70edee6018b5f558 --- /dev/null +++ b/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.pie.js @@ -0,0 +1,820 @@ +/* Flot plugin for rendering pie charts. + +Copyright (c) 2007-2014 IOLA and Ole Laursen. +Licensed under the MIT license. + +The plugin assumes that each series has a single data value, and that each +value is a positive integer or zero. Negative numbers don't make sense for a +pie chart, and have unpredictable results. The values do NOT need to be +passed in as percentages; the plugin will calculate the total and per-slice +percentages internally. + +* Created by Brian Medendorp + +* Updated with contributions from btburnett3, Anthony Aragues and Xavi Ivars + +The plugin supports these options: + + series: { + pie: { + show: true/false + radius: 0-1 for percentage of fullsize, or a specified pixel length, or 'auto' + innerRadius: 0-1 for percentage of fullsize or a specified pixel length, for creating a donut effect + startAngle: 0-2 factor of PI used for starting angle (in radians) i.e 3/2 starts at the top, 0 and 2 have the same result + tilt: 0-1 for percentage to tilt the pie, where 1 is no tilt, and 0 is completely flat (nothing will show) + offset: { + top: integer value to move the pie up or down + left: integer value to move the pie left or right, or 'auto' + }, + stroke: { + color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#FFF') + width: integer pixel width of the stroke + }, + label: { + show: true/false, or 'auto' + formatter: a user-defined function that modifies the text/style of the label text + radius: 0-1 for percentage of fullsize, or a specified pixel length + background: { + color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#000') + opacity: 0-1 + }, + threshold: 0-1 for the percentage value at which to hide labels (if they're too small) + }, + combine: { + threshold: 0-1 for the percentage value at which to combine slices (if they're too small) + color: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#CCC'), if null, the plugin will automatically use the color of the first slice to be combined + label: any text value of what the combined slice should be labeled + } + highlight: { + opacity: 0-1 + } + } + } + +More detail and specific examples can be found in the included HTML file. + +*/ + +(function($) { + + // Maximum redraw attempts when fitting labels within the plot + + var REDRAW_ATTEMPTS = 10; + + // Factor by which to shrink the pie when fitting labels within the plot + + var REDRAW_SHRINK = 0.95; + + function init(plot) { + + var canvas = null, + target = null, + options = null, + maxRadius = null, + centerLeft = null, + centerTop = null, + processed = false, + ctx = null; + + // interactive variables + + var highlights = []; + + // add hook to determine if pie plugin in enabled, and then perform necessary operations + + plot.hooks.processOptions.push(function(plot, options) { + if (options.series.pie.show) { + + options.grid.show = false; + + // set labels.show + + if (options.series.pie.label.show == "auto") { + if (options.legend.show) { + options.series.pie.label.show = false; + } else { + options.series.pie.label.show = true; + } + } + + // set radius + + if (options.series.pie.radius == "auto") { + if (options.series.pie.label.show) { + options.series.pie.radius = 3/4; + } else { + options.series.pie.radius = 1; + } + } + + // ensure sane tilt + + if (options.series.pie.tilt > 1) { + options.series.pie.tilt = 1; + } else if (options.series.pie.tilt < 0) { + options.series.pie.tilt = 0; + } + } + }); + + plot.hooks.bindEvents.push(function(plot, eventHolder) { + var options = plot.getOptions(); + if (options.series.pie.show) { + if (options.grid.hoverable) { + eventHolder.unbind("mousemove").mousemove(onMouseMove); + } + if (options.grid.clickable) { + eventHolder.unbind("click").click(onClick); + } + } + }); + + plot.hooks.processDatapoints.push(function(plot, series, data, datapoints) { + var options = plot.getOptions(); + if (options.series.pie.show) { + processDatapoints(plot, series, data, datapoints); + } + }); + + plot.hooks.drawOverlay.push(function(plot, octx) { + var options = plot.getOptions(); + if (options.series.pie.show) { + drawOverlay(plot, octx); + } + }); + + plot.hooks.draw.push(function(plot, newCtx) { + var options = plot.getOptions(); + if (options.series.pie.show) { + draw(plot, newCtx); + } + }); + + function processDatapoints(plot, series, datapoints) { + if (!processed) { + processed = true; + canvas = plot.getCanvas(); + target = $(canvas).parent(); + options = plot.getOptions(); + plot.setData(combine(plot.getData())); + } + } + + function combine(data) { + + var total = 0, + combined = 0, + numCombined = 0, + color = options.series.pie.combine.color, + newdata = []; + + // Fix up the raw data from Flot, ensuring the data is numeric + + for (var i = 0; i < data.length; ++i) { + + var value = data[i].data; + + // If the data is an array, we'll assume that it's a standard + // Flot x-y pair, and are concerned only with the second value. + + // Note how we use the original array, rather than creating a + // new one; this is more efficient and preserves any extra data + // that the user may have stored in higher indexes. + + if ($.isArray(value) && value.length == 1) { + value = value[0]; + } + + if ($.isArray(value)) { + // Equivalent to $.isNumeric() but compatible with jQuery < 1.7 + if (!isNaN(parseFloat(value[1])) && isFinite(value[1])) { + value[1] = +value[1]; + } else { + value[1] = 0; + } + } else if (!isNaN(parseFloat(value)) && isFinite(value)) { + value = [1, +value]; + } else { + value = [1, 0]; + } + + data[i].data = [value]; + } + + // Sum up all the slices, so we can calculate percentages for each + + for (var i = 0; i < data.length; ++i) { + total += data[i].data[0][1]; + } + + // Count the number of slices with percentages below the combine + // threshold; if it turns out to be just one, we won't combine. + + for (var i = 0; i < data.length; ++i) { + var value = data[i].data[0][1]; + if (value / total <= options.series.pie.combine.threshold) { + combined += value; + numCombined++; + if (!color) { + color = data[i].color; + } + } + } + + for (var i = 0; i < data.length; ++i) { + var value = data[i].data[0][1]; + if (numCombined < 2 || value / total > options.series.pie.combine.threshold) { + newdata.push( + $.extend(data[i], { /* extend to allow keeping all other original data values + and using them e.g. in labelFormatter. */ + data: [[1, value]], + color: data[i].color, + label: data[i].label, + angle: value * Math.PI * 2 / total, + percent: value / (total / 100) + }) + ); + } + } + + if (numCombined > 1) { + newdata.push({ + data: [[1, combined]], + color: color, + label: options.series.pie.combine.label, + angle: combined * Math.PI * 2 / total, + percent: combined / (total / 100) + }); + } + + return newdata; + } + + function draw(plot, newCtx) { + + if (!target) { + return; // if no series were passed + } + + var canvasWidth = plot.getPlaceholder().width(), + canvasHeight = plot.getPlaceholder().height(), + legendWidth = target.children().filter(".legend").children().width() || 0; + + ctx = newCtx; + + // WARNING: HACK! REWRITE THIS CODE AS SOON AS POSSIBLE! + + // When combining smaller slices into an 'other' slice, we need to + // add a new series. Since Flot gives plugins no way to modify the + // list of series, the pie plugin uses a hack where the first call + // to processDatapoints results in a call to setData with the new + // list of series, then subsequent processDatapoints do nothing. + + // The plugin-global 'processed' flag is used to control this hack; + // it starts out false, and is set to true after the first call to + // processDatapoints. + + // Unfortunately this turns future setData calls into no-ops; they + // call processDatapoints, the flag is true, and nothing happens. + + // To fix this we'll set the flag back to false here in draw, when + // all series have been processed, so the next sequence of calls to + // processDatapoints once again starts out with a slice-combine. + // This is really a hack; in 0.9 we need to give plugins a proper + // way to modify series before any processing begins. + + processed = false; + + // calculate maximum radius and center point + + maxRadius = Math.min(canvasWidth, canvasHeight / options.series.pie.tilt) / 2; + centerTop = canvasHeight / 2 + options.series.pie.offset.top; + centerLeft = canvasWidth / 2; + + if (options.series.pie.offset.left == "auto") { + if (options.legend.position.match("w")) { + centerLeft += legendWidth / 2; + } else { + centerLeft -= legendWidth / 2; + } + if (centerLeft < maxRadius) { + centerLeft = maxRadius; + } else if (centerLeft > canvasWidth - maxRadius) { + centerLeft = canvasWidth - maxRadius; + } + } else { + centerLeft += options.series.pie.offset.left; + } + + var slices = plot.getData(), + attempts = 0; + + // Keep shrinking the pie's radius until drawPie returns true, + // indicating that all the labels fit, or we try too many times. + + do { + if (attempts > 0) { + maxRadius *= REDRAW_SHRINK; + } + attempts += 1; + clear(); + if (options.series.pie.tilt <= 0.8) { + drawShadow(); + } + } while (!drawPie() && attempts < REDRAW_ATTEMPTS) + + if (attempts >= REDRAW_ATTEMPTS) { + clear(); + target.prepend("<div class='error'>Could not draw pie with labels contained inside canvas</div>"); + } + + if (plot.setSeries && plot.insertLegend) { + plot.setSeries(slices); + plot.insertLegend(); + } + + // we're actually done at this point, just defining internal functions at this point + + function clear() { + ctx.clearRect(0, 0, canvasWidth, canvasHeight); + target.children().filter(".pieLabel, .pieLabelBackground").remove(); + } + + function drawShadow() { + + var shadowLeft = options.series.pie.shadow.left; + var shadowTop = options.series.pie.shadow.top; + var edge = 10; + var alpha = options.series.pie.shadow.alpha; + var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius; + + if (radius >= canvasWidth / 2 - shadowLeft || radius * options.series.pie.tilt >= canvasHeight / 2 - shadowTop || radius <= edge) { + return; // shadow would be outside canvas, so don't draw it + } + + ctx.save(); + ctx.translate(shadowLeft,shadowTop); + ctx.globalAlpha = alpha; + ctx.fillStyle = "#000"; + + // center and rotate to starting position + + ctx.translate(centerLeft,centerTop); + ctx.scale(1, options.series.pie.tilt); + + //radius -= edge; + + for (var i = 1; i <= edge; i++) { + ctx.beginPath(); + ctx.arc(0, 0, radius, 0, Math.PI * 2, false); + ctx.fill(); + radius -= i; + } + + ctx.restore(); + } + + function drawPie() { + + var startAngle = Math.PI * options.series.pie.startAngle; + var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius; + + // center and rotate to starting position + + ctx.save(); + ctx.translate(centerLeft,centerTop); + ctx.scale(1, options.series.pie.tilt); + //ctx.rotate(startAngle); // start at top; -- This doesn't work properly in Opera + + // draw slices + + ctx.save(); + var currentAngle = startAngle; + for (var i = 0; i < slices.length; ++i) { + slices[i].startAngle = currentAngle; + drawSlice(slices[i].angle, slices[i].color, true); + } + ctx.restore(); + + // draw slice outlines + + if (options.series.pie.stroke.width > 0) { + ctx.save(); + ctx.lineWidth = options.series.pie.stroke.width; + currentAngle = startAngle; + for (var i = 0; i < slices.length; ++i) { + drawSlice(slices[i].angle, options.series.pie.stroke.color, false); + } + ctx.restore(); + } + + // draw donut hole + + drawDonutHole(ctx); + + ctx.restore(); + + // Draw the labels, returning true if they fit within the plot + + if (options.series.pie.label.show) { + return drawLabels(); + } else return true; + + function drawSlice(angle, color, fill) { + + if (angle <= 0 || isNaN(angle)) { + return; + } + + if (fill) { + ctx.fillStyle = color; + } else { + ctx.strokeStyle = color; + ctx.lineJoin = "round"; + } + + ctx.beginPath(); + if (Math.abs(angle - Math.PI * 2) > 0.000000001) { + ctx.moveTo(0, 0); // Center of the pie + } + + //ctx.arc(0, 0, radius, 0, angle, false); // This doesn't work properly in Opera + ctx.arc(0, 0, radius,currentAngle, currentAngle + angle / 2, false); + ctx.arc(0, 0, radius,currentAngle + angle / 2, currentAngle + angle, false); + ctx.closePath(); + //ctx.rotate(angle); // This doesn't work properly in Opera + currentAngle += angle; + + if (fill) { + ctx.fill(); + } else { + ctx.stroke(); + } + } + + function drawLabels() { + + var currentAngle = startAngle; + var radius = options.series.pie.label.radius > 1 ? options.series.pie.label.radius : maxRadius * options.series.pie.label.radius; + + for (var i = 0; i < slices.length; ++i) { + if (slices[i].percent >= options.series.pie.label.threshold * 100) { + if (!drawLabel(slices[i], currentAngle, i)) { + return false; + } + } + currentAngle += slices[i].angle; + } + + return true; + + function drawLabel(slice, startAngle, index) { + + if (slice.data[0][1] == 0) { + return true; + } + + // format label text + + var lf = options.legend.labelFormatter, text, plf = options.series.pie.label.formatter; + + if (lf) { + text = lf(slice.label, slice); + } else { + text = slice.label; + } + + if (plf) { + text = plf(text, slice); + } + + var halfAngle = ((startAngle + slice.angle) + startAngle) / 2; + var x = centerLeft + Math.round(Math.cos(halfAngle) * radius); + var y = centerTop + Math.round(Math.sin(halfAngle) * radius) * options.series.pie.tilt; + + var html = "<span class='pieLabel' id='pieLabel" + index + "' style='position:absolute;top:" + y + "px;left:" + x + "px;'>" + text + "</span>"; + target.append(html); + + var label = target.children("#pieLabel" + index); + var labelTop = (y - label.height() / 2); + var labelLeft = (x - label.width() / 2); + + label.css("top", labelTop); + label.css("left", labelLeft); + + // check to make sure that the label is not outside the canvas + + if (0 - labelTop > 0 || 0 - labelLeft > 0 || canvasHeight - (labelTop + label.height()) < 0 || canvasWidth - (labelLeft + label.width()) < 0) { + return false; + } + + if (options.series.pie.label.background.opacity != 0) { + + // put in the transparent background separately to avoid blended labels and label boxes + + var c = options.series.pie.label.background.color; + + if (c == null) { + c = slice.color; + } + + var pos = "top:" + labelTop + "px;left:" + labelLeft + "px;"; + $("<div class='pieLabelBackground' style='position:absolute;width:" + label.width() + "px;height:" + label.height() + "px;" + pos + "background-color:" + c + ";'></div>") + .css("opacity", options.series.pie.label.background.opacity) + .insertBefore(label); + } + + return true; + } // end individual label function + } // end drawLabels function + } // end drawPie function + } // end draw function + + // Placed here because it needs to be accessed from multiple locations + + function drawDonutHole(layer) { + if (options.series.pie.innerRadius > 0) { + + // subtract the center + + layer.save(); + var innerRadius = options.series.pie.innerRadius > 1 ? options.series.pie.innerRadius : maxRadius * options.series.pie.innerRadius; + layer.globalCompositeOperation = "destination-out"; // this does not work with excanvas, but it will fall back to using the stroke color + layer.beginPath(); + layer.fillStyle = options.series.pie.stroke.color; + layer.arc(0, 0, innerRadius, 0, Math.PI * 2, false); + layer.fill(); + layer.closePath(); + layer.restore(); + + // add inner stroke + + layer.save(); + layer.beginPath(); + layer.strokeStyle = options.series.pie.stroke.color; + layer.arc(0, 0, innerRadius, 0, Math.PI * 2, false); + layer.stroke(); + layer.closePath(); + layer.restore(); + + // TODO: add extra shadow inside hole (with a mask) if the pie is tilted. + } + } + + //-- Additional Interactive related functions -- + + function isPointInPoly(poly, pt) { + for(var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i) + ((poly[i][1] <= pt[1] && pt[1] < poly[j][1]) || (poly[j][1] <= pt[1] && pt[1]< poly[i][1])) + && (pt[0] < (poly[j][0] - poly[i][0]) * (pt[1] - poly[i][1]) / (poly[j][1] - poly[i][1]) + poly[i][0]) + && (c = !c); + return c; + } + + function findNearbySlice(mouseX, mouseY) { + + var slices = plot.getData(), + options = plot.getOptions(), + radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius, + x, y; + + for (var i = 0; i < slices.length; ++i) { + + var s = slices[i]; + + if (s.pie.show) { + + ctx.save(); + ctx.beginPath(); + ctx.moveTo(0, 0); // Center of the pie + //ctx.scale(1, options.series.pie.tilt); // this actually seems to break everything when here. + ctx.arc(0, 0, radius, s.startAngle, s.startAngle + s.angle / 2, false); + ctx.arc(0, 0, radius, s.startAngle + s.angle / 2, s.startAngle + s.angle, false); + ctx.closePath(); + x = mouseX - centerLeft; + y = mouseY - centerTop; + + if (ctx.isPointInPath) { + if (ctx.isPointInPath(mouseX - centerLeft, mouseY - centerTop)) { + ctx.restore(); + return { + datapoint: [s.percent, s.data], + dataIndex: 0, + series: s, + seriesIndex: i + }; + } + } else { + + // excanvas for IE doesn;t support isPointInPath, this is a workaround. + + var p1X = radius * Math.cos(s.startAngle), + p1Y = radius * Math.sin(s.startAngle), + p2X = radius * Math.cos(s.startAngle + s.angle / 4), + p2Y = radius * Math.sin(s.startAngle + s.angle / 4), + p3X = radius * Math.cos(s.startAngle + s.angle / 2), + p3Y = radius * Math.sin(s.startAngle + s.angle / 2), + p4X = radius * Math.cos(s.startAngle + s.angle / 1.5), + p4Y = radius * Math.sin(s.startAngle + s.angle / 1.5), + p5X = radius * Math.cos(s.startAngle + s.angle), + p5Y = radius * Math.sin(s.startAngle + s.angle), + arrPoly = [[0, 0], [p1X, p1Y], [p2X, p2Y], [p3X, p3Y], [p4X, p4Y], [p5X, p5Y]], + arrPoint = [x, y]; + + // TODO: perhaps do some mathmatical trickery here with the Y-coordinate to compensate for pie tilt? + + if (isPointInPoly(arrPoly, arrPoint)) { + ctx.restore(); + return { + datapoint: [s.percent, s.data], + dataIndex: 0, + series: s, + seriesIndex: i + }; + } + } + + ctx.restore(); + } + } + + return null; + } + + function onMouseMove(e) { + triggerClickHoverEvent("plothover", e); + } + + function onClick(e) { + triggerClickHoverEvent("plotclick", e); + } + + // trigger click or hover event (they send the same parameters so we share their code) + + function triggerClickHoverEvent(eventname, e) { + + var offset = plot.offset(); + var canvasX = parseInt(e.pageX - offset.left); + var canvasY = parseInt(e.pageY - offset.top); + var item = findNearbySlice(canvasX, canvasY); + + if (options.grid.autoHighlight) { + + // clear auto-highlights + + for (var i = 0; i < highlights.length; ++i) { + var h = highlights[i]; + if (h.auto == eventname && !(item && h.series == item.series)) { + unhighlight(h.series); + } + } + } + + // highlight the slice + + if (item) { + highlight(item.series, eventname); + } + + // trigger any hover bind events + + var pos = { pageX: e.pageX, pageY: e.pageY }; + target.trigger(eventname, [pos, item]); + } + + function highlight(s, auto) { + //if (typeof s == "number") { + // s = series[s]; + //} + + var i = indexOfHighlight(s); + + if (i == -1) { + highlights.push({ series: s, auto: auto }); + plot.triggerRedrawOverlay(); + } else if (!auto) { + highlights[i].auto = false; + } + } + + function unhighlight(s) { + if (s == null) { + highlights = []; + plot.triggerRedrawOverlay(); + } + + //if (typeof s == "number") { + // s = series[s]; + //} + + var i = indexOfHighlight(s); + + if (i != -1) { + highlights.splice(i, 1); + plot.triggerRedrawOverlay(); + } + } + + function indexOfHighlight(s) { + for (var i = 0; i < highlights.length; ++i) { + var h = highlights[i]; + if (h.series == s) + return i; + } + return -1; + } + + function drawOverlay(plot, octx) { + + var options = plot.getOptions(); + + var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius; + + octx.save(); + octx.translate(centerLeft, centerTop); + octx.scale(1, options.series.pie.tilt); + + for (var i = 0; i < highlights.length; ++i) { + drawHighlight(highlights[i].series); + } + + drawDonutHole(octx); + + octx.restore(); + + function drawHighlight(series) { + + if (series.angle <= 0 || isNaN(series.angle)) { + return; + } + + //octx.fillStyle = parseColor(options.series.pie.highlight.color).scale(null, null, null, options.series.pie.highlight.opacity).toString(); + octx.fillStyle = "rgba(255, 255, 255, " + options.series.pie.highlight.opacity + ")"; // this is temporary until we have access to parseColor + octx.beginPath(); + if (Math.abs(series.angle - Math.PI * 2) > 0.000000001) { + octx.moveTo(0, 0); // Center of the pie + } + octx.arc(0, 0, radius, series.startAngle, series.startAngle + series.angle / 2, false); + octx.arc(0, 0, radius, series.startAngle + series.angle / 2, series.startAngle + series.angle, false); + octx.closePath(); + octx.fill(); + } + } + } // end init (plugin body) + + // define pie specific options and their default values + + var options = { + series: { + pie: { + show: false, + radius: "auto", // actual radius of the visible pie (based on full calculated radius if <=1, or hard pixel value) + innerRadius: 0, /* for donut */ + startAngle: 3/2, + tilt: 1, + shadow: { + left: 5, // shadow left offset + top: 15, // shadow top offset + alpha: 0.02 // shadow alpha + }, + offset: { + top: 0, + left: "auto" + }, + stroke: { + color: "#fff", + width: 1 + }, + label: { + show: "auto", + formatter: function(label, slice) { + return "<div style='font-size:x-small;text-align:center;padding:2px;color:" + slice.color + ";'>" + label + "<br/>" + Math.round(slice.percent) + "%</div>"; + }, // formatter function + radius: 1, // radius at which to place the labels (based on full calculated radius if <=1, or hard pixel value) + background: { + color: null, + opacity: 0 + }, + threshold: 0 // percentage at which to hide the label (i.e. the slice is too narrow) + }, + combine: { + threshold: -1, // percentage at which to combine little slices into one larger slice + color: null, // color to give the new slice (auto-generated if null) + label: "Other" // label to give the new slice + }, + highlight: { + //color: "#fff", // will add this functionality once parseColor is available + opacity: 0.5 + } + } + } + }; + + $.plot.plugins.push({ + init: init, + options: options, + name: "pie", + version: "1.1" + }); + +})(jQuery); diff --git a/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.resize.js b/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.resize.js new file mode 100644 index 0000000000000000000000000000000000000000..8a626dda0addbc98109ee217903ac1d3591d54a5 --- /dev/null +++ b/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.resize.js @@ -0,0 +1,59 @@ +/* Flot plugin for automatically redrawing plots as the placeholder resizes. + +Copyright (c) 2007-2014 IOLA and Ole Laursen. +Licensed under the MIT license. + +It works by listening for changes on the placeholder div (through the jQuery +resize event plugin) - if the size changes, it will redraw the plot. + +There are no options. If you need to disable the plugin for some plots, you +can just fix the size of their placeholders. + +*/ + +/* Inline dependency: + * jQuery resize event - v1.1 - 3/14/2010 + * http://benalman.com/projects/jquery-resize-plugin/ + * + * Copyright (c) 2010 "Cowboy" Ben Alman + * Dual licensed under the MIT and GPL licenses. + * http://benalman.com/about/license/ + */ +(function($,e,t){"$:nomunge";var i=[],n=$.resize=$.extend($.resize,{}),a,r=false,s="setTimeout",u="resize",m=u+"-special-event",o="pendingDelay",l="activeDelay",f="throttleWindow";n[o]=200;n[l]=20;n[f]=true;$.event.special[u]={setup:function(){if(!n[f]&&this[s]){return false}var e=$(this);i.push(this);e.data(m,{w:e.width(),h:e.height()});if(i.length===1){a=t;h()}},teardown:function(){if(!n[f]&&this[s]){return false}var e=$(this);for(var t=i.length-1;t>=0;t--){if(i[t]==this){i.splice(t,1);break}}e.removeData(m);if(!i.length){if(r){cancelAnimationFrame(a)}else{clearTimeout(a)}a=null}},add:function(e){if(!n[f]&&this[s]){return false}var i;function a(e,n,a){var r=$(this),s=r.data(m)||{};s.w=n!==t?n:r.width();s.h=a!==t?a:r.height();i.apply(this,arguments)}if($.isFunction(e)){i=e;return a}else{i=e.handler;e.handler=a}}};function h(t){if(r===true){r=t||1}for(var s=i.length-1;s>=0;s--){var l=$(i[s]);if(l[0]==e||l.is(":visible")){var f=l.width(),c=l.height(),d=l.data(m);if(d&&(f!==d.w||c!==d.h)){l.trigger(u,[d.w=f,d.h=c]);r=t||true}}else{d=l.data(m);d.w=0;d.h=0}}if(a!==null){if(r&&(t==null||t-r<1e3)){a=e.requestAnimationFrame(h)}else{a=setTimeout(h,n[o]);r=false}}}if(!e.requestAnimationFrame){e.requestAnimationFrame=function(){return e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame||e.oRequestAnimationFrame||e.msRequestAnimationFrame||function(t,i){return e.setTimeout(function(){t((new Date).getTime())},n[l])}}()}if(!e.cancelAnimationFrame){e.cancelAnimationFrame=function(){return e.webkitCancelRequestAnimationFrame||e.mozCancelRequestAnimationFrame||e.oCancelRequestAnimationFrame||e.msCancelRequestAnimationFrame||clearTimeout}()}})(jQuery,this); + +(function ($) { + var options = { }; // no options + + function init(plot) { + function onResize() { + var placeholder = plot.getPlaceholder(); + + // somebody might have hidden us and we can't plot + // when we don't have the dimensions + if (placeholder.width() == 0 || placeholder.height() == 0) + return; + + plot.resize(); + plot.setupGrid(); + plot.draw(); + } + + function bindEvents(plot, eventHolder) { + plot.getPlaceholder().resize(onResize); + } + + function shutdown(plot, eventHolder) { + plot.getPlaceholder().unbind("resize", onResize); + } + + plot.hooks.bindEvents.push(bindEvents); + plot.hooks.shutdown.push(shutdown); + } + + $.plot.plugins.push({ + init: init, + options: options, + name: 'resize', + version: '1.0' + }); +})(jQuery); diff --git a/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.selection.js b/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.selection.js new file mode 100644 index 0000000000000000000000000000000000000000..d3c20fa4e12f258bee0be8b751d092df016d09f2 --- /dev/null +++ b/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.selection.js @@ -0,0 +1,360 @@ +/* Flot plugin for selecting regions of a plot. + +Copyright (c) 2007-2014 IOLA and Ole Laursen. +Licensed under the MIT license. + +The plugin supports these options: + +selection: { + mode: null or "x" or "y" or "xy", + color: color, + shape: "round" or "miter" or "bevel", + minSize: number of pixels +} + +Selection support is enabled by setting the mode to one of "x", "y" or "xy". +In "x" mode, the user will only be able to specify the x range, similarly for +"y" mode. For "xy", the selection becomes a rectangle where both ranges can be +specified. "color" is color of the selection (if you need to change the color +later on, you can get to it with plot.getOptions().selection.color). "shape" +is the shape of the corners of the selection. + +"minSize" is the minimum size a selection can be in pixels. This value can +be customized to determine the smallest size a selection can be and still +have the selection rectangle be displayed. When customizing this value, the +fact that it refers to pixels, not axis units must be taken into account. +Thus, for example, if there is a bar graph in time mode with BarWidth set to 1 +minute, setting "minSize" to 1 will not make the minimum selection size 1 +minute, but rather 1 pixel. Note also that setting "minSize" to 0 will prevent +"plotunselected" events from being fired when the user clicks the mouse without +dragging. + +When selection support is enabled, a "plotselected" event will be emitted on +the DOM element you passed into the plot function. The event handler gets a +parameter with the ranges selected on the axes, like this: + + placeholder.bind( "plotselected", function( event, ranges ) { + alert("You selected " + ranges.xaxis.from + " to " + ranges.xaxis.to) + // similar for yaxis - with multiple axes, the extra ones are in + // x2axis, x3axis, ... + }); + +The "plotselected" event is only fired when the user has finished making the +selection. A "plotselecting" event is fired during the process with the same +parameters as the "plotselected" event, in case you want to know what's +happening while it's happening, + +A "plotunselected" event with no arguments is emitted when the user clicks the +mouse to remove the selection. As stated above, setting "minSize" to 0 will +destroy this behavior. + +The plugin allso adds the following methods to the plot object: + +- setSelection( ranges, preventEvent ) + + Set the selection rectangle. The passed in ranges is on the same form as + returned in the "plotselected" event. If the selection mode is "x", you + should put in either an xaxis range, if the mode is "y" you need to put in + an yaxis range and both xaxis and yaxis if the selection mode is "xy", like + this: + + setSelection({ xaxis: { from: 0, to: 10 }, yaxis: { from: 40, to: 60 } }); + + setSelection will trigger the "plotselected" event when called. If you don't + want that to happen, e.g. if you're inside a "plotselected" handler, pass + true as the second parameter. If you are using multiple axes, you can + specify the ranges on any of those, e.g. as x2axis/x3axis/... instead of + xaxis, the plugin picks the first one it sees. + +- clearSelection( preventEvent ) + + Clear the selection rectangle. Pass in true to avoid getting a + "plotunselected" event. + +- getSelection() + + Returns the current selection in the same format as the "plotselected" + event. If there's currently no selection, the function returns null. + +*/ + +(function ($) { + function init(plot) { + var selection = { + first: { x: -1, y: -1}, second: { x: -1, y: -1}, + show: false, + active: false + }; + + // FIXME: The drag handling implemented here should be + // abstracted out, there's some similar code from a library in + // the navigation plugin, this should be massaged a bit to fit + // the Flot cases here better and reused. Doing this would + // make this plugin much slimmer. + var savedhandlers = {}; + + var mouseUpHandler = null; + + function onMouseMove(e) { + if (selection.active) { + updateSelection(e); + + plot.getPlaceholder().trigger("plotselecting", [ getSelection() ]); + } + } + + function onMouseDown(e) { + if (e.which != 1) // only accept left-click + return; + + // cancel out any text selections + document.body.focus(); + + // prevent text selection and drag in old-school browsers + if (document.onselectstart !== undefined && savedhandlers.onselectstart == null) { + savedhandlers.onselectstart = document.onselectstart; + document.onselectstart = function () { return false; }; + } + if (document.ondrag !== undefined && savedhandlers.ondrag == null) { + savedhandlers.ondrag = document.ondrag; + document.ondrag = function () { return false; }; + } + + setSelectionPos(selection.first, e); + + selection.active = true; + + // this is a bit silly, but we have to use a closure to be + // able to whack the same handler again + mouseUpHandler = function (e) { onMouseUp(e); }; + + $(document).one("mouseup", mouseUpHandler); + } + + function onMouseUp(e) { + mouseUpHandler = null; + + // revert drag stuff for old-school browsers + if (document.onselectstart !== undefined) + document.onselectstart = savedhandlers.onselectstart; + if (document.ondrag !== undefined) + document.ondrag = savedhandlers.ondrag; + + // no more dragging + selection.active = false; + updateSelection(e); + + if (selectionIsSane()) + triggerSelectedEvent(); + else { + // this counts as a clear + plot.getPlaceholder().trigger("plotunselected", [ ]); + plot.getPlaceholder().trigger("plotselecting", [ null ]); + } + + return false; + } + + function getSelection() { + if (!selectionIsSane()) + return null; + + if (!selection.show) return null; + + var r = {}, c1 = selection.first, c2 = selection.second; + $.each(plot.getAxes(), function (name, axis) { + if (axis.used) { + var p1 = axis.c2p(c1[axis.direction]), p2 = axis.c2p(c2[axis.direction]); + r[name] = { from: Math.min(p1, p2), to: Math.max(p1, p2) }; + } + }); + return r; + } + + function triggerSelectedEvent() { + var r = getSelection(); + + plot.getPlaceholder().trigger("plotselected", [ r ]); + + // backwards-compat stuff, to be removed in future + if (r.xaxis && r.yaxis) + plot.getPlaceholder().trigger("selected", [ { x1: r.xaxis.from, y1: r.yaxis.from, x2: r.xaxis.to, y2: r.yaxis.to } ]); + } + + function clamp(min, value, max) { + return value < min ? min: (value > max ? max: value); + } + + function setSelectionPos(pos, e) { + var o = plot.getOptions(); + var offset = plot.getPlaceholder().offset(); + var plotOffset = plot.getPlotOffset(); + pos.x = clamp(0, e.pageX - offset.left - plotOffset.left, plot.width()); + pos.y = clamp(0, e.pageY - offset.top - plotOffset.top, plot.height()); + + if (o.selection.mode == "y") + pos.x = pos == selection.first ? 0 : plot.width(); + + if (o.selection.mode == "x") + pos.y = pos == selection.first ? 0 : plot.height(); + } + + function updateSelection(pos) { + if (pos.pageX == null) + return; + + setSelectionPos(selection.second, pos); + if (selectionIsSane()) { + selection.show = true; + plot.triggerRedrawOverlay(); + } + else + clearSelection(true); + } + + function clearSelection(preventEvent) { + if (selection.show) { + selection.show = false; + plot.triggerRedrawOverlay(); + if (!preventEvent) + plot.getPlaceholder().trigger("plotunselected", [ ]); + } + } + + // function taken from markings support in Flot + function extractRange(ranges, coord) { + var axis, from, to, key, axes = plot.getAxes(); + + for (var k in axes) { + axis = axes[k]; + if (axis.direction == coord) { + key = coord + axis.n + "axis"; + if (!ranges[key] && axis.n == 1) + key = coord + "axis"; // support x1axis as xaxis + if (ranges[key]) { + from = ranges[key].from; + to = ranges[key].to; + break; + } + } + } + + // backwards-compat stuff - to be removed in future + if (!ranges[key]) { + axis = coord == "x" ? plot.getXAxes()[0] : plot.getYAxes()[0]; + from = ranges[coord + "1"]; + to = ranges[coord + "2"]; + } + + // auto-reverse as an added bonus + if (from != null && to != null && from > to) { + var tmp = from; + from = to; + to = tmp; + } + + return { from: from, to: to, axis: axis }; + } + + function setSelection(ranges, preventEvent) { + var axis, range, o = plot.getOptions(); + + if (o.selection.mode == "y") { + selection.first.x = 0; + selection.second.x = plot.width(); + } + else { + range = extractRange(ranges, "x"); + + selection.first.x = range.axis.p2c(range.from); + selection.second.x = range.axis.p2c(range.to); + } + + if (o.selection.mode == "x") { + selection.first.y = 0; + selection.second.y = plot.height(); + } + else { + range = extractRange(ranges, "y"); + + selection.first.y = range.axis.p2c(range.from); + selection.second.y = range.axis.p2c(range.to); + } + + selection.show = true; + plot.triggerRedrawOverlay(); + if (!preventEvent && selectionIsSane()) + triggerSelectedEvent(); + } + + function selectionIsSane() { + var minSize = plot.getOptions().selection.minSize; + return Math.abs(selection.second.x - selection.first.x) >= minSize && + Math.abs(selection.second.y - selection.first.y) >= minSize; + } + + plot.clearSelection = clearSelection; + plot.setSelection = setSelection; + plot.getSelection = getSelection; + + plot.hooks.bindEvents.push(function(plot, eventHolder) { + var o = plot.getOptions(); + if (o.selection.mode != null) { + eventHolder.mousemove(onMouseMove); + eventHolder.mousedown(onMouseDown); + } + }); + + + plot.hooks.drawOverlay.push(function (plot, ctx) { + // draw selection + if (selection.show && selectionIsSane()) { + var plotOffset = plot.getPlotOffset(); + var o = plot.getOptions(); + + ctx.save(); + ctx.translate(plotOffset.left, plotOffset.top); + + var c = $.color.parse(o.selection.color); + + ctx.strokeStyle = c.scale('a', 0.8).toString(); + ctx.lineWidth = 1; + ctx.lineJoin = o.selection.shape; + ctx.fillStyle = c.scale('a', 0.4).toString(); + + var x = Math.min(selection.first.x, selection.second.x) + 0.5, + y = Math.min(selection.first.y, selection.second.y) + 0.5, + w = Math.abs(selection.second.x - selection.first.x) - 1, + h = Math.abs(selection.second.y - selection.first.y) - 1; + + ctx.fillRect(x, y, w, h); + ctx.strokeRect(x, y, w, h); + + ctx.restore(); + } + }); + + plot.hooks.shutdown.push(function (plot, eventHolder) { + eventHolder.unbind("mousemove", onMouseMove); + eventHolder.unbind("mousedown", onMouseDown); + + if (mouseUpHandler) + $(document).unbind("mouseup", mouseUpHandler); + }); + + } + + $.plot.plugins.push({ + init: init, + options: { + selection: { + mode: null, // one of null, "x", "y" or "xy" + color: "#e8cfac", + shape: "round", // one of "round", "miter", or "bevel" + minSize: 5 // minimum number of pixels + } + }, + name: 'selection', + version: '1.1' + }); +})(jQuery); diff --git a/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.stack.js b/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.stack.js new file mode 100644 index 0000000000000000000000000000000000000000..e75a7dfc07434facfec2cc73b3ab9c4fb7d21f39 --- /dev/null +++ b/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.stack.js @@ -0,0 +1,188 @@ +/* Flot plugin for stacking data sets rather than overlyaing them. + +Copyright (c) 2007-2014 IOLA and Ole Laursen. +Licensed under the MIT license. + +The plugin assumes the data is sorted on x (or y if stacking horizontally). +For line charts, it is assumed that if a line has an undefined gap (from a +null point), then the line above it should have the same gap - insert zeros +instead of "null" if you want another behaviour. This also holds for the start +and end of the chart. Note that stacking a mix of positive and negative values +in most instances doesn't make sense (so it looks weird). + +Two or more series are stacked when their "stack" attribute is set to the same +key (which can be any number or string or just "true"). To specify the default +stack, you can set the stack option like this: + + series: { + stack: null/false, true, or a key (number/string) + } + +You can also specify it for a single series, like this: + + $.plot( $("#placeholder"), [{ + data: [ ... ], + stack: true + }]) + +The stacking order is determined by the order of the data series in the array +(later series end up on top of the previous). + +Internally, the plugin modifies the datapoints in each series, adding an +offset to the y value. For line series, extra data points are inserted through +interpolation. If there's a second y value, it's also adjusted (e.g for bar +charts or filled areas). + +*/ + +(function ($) { + var options = { + series: { stack: null } // or number/string + }; + + function init(plot) { + function findMatchingSeries(s, allseries) { + var res = null; + for (var i = 0; i < allseries.length; ++i) { + if (s == allseries[i]) + break; + + if (allseries[i].stack == s.stack) + res = allseries[i]; + } + + return res; + } + + function stackData(plot, s, datapoints) { + if (s.stack == null || s.stack === false) + return; + + var other = findMatchingSeries(s, plot.getData()); + if (!other) + return; + + var ps = datapoints.pointsize, + points = datapoints.points, + otherps = other.datapoints.pointsize, + otherpoints = other.datapoints.points, + newpoints = [], + px, py, intery, qx, qy, bottom, + withlines = s.lines.show, + horizontal = s.bars.horizontal, + withbottom = ps > 2 && (horizontal ? datapoints.format[2].x : datapoints.format[2].y), + withsteps = withlines && s.lines.steps, + fromgap = true, + keyOffset = horizontal ? 1 : 0, + accumulateOffset = horizontal ? 0 : 1, + i = 0, j = 0, l, m; + + while (true) { + if (i >= points.length) + break; + + l = newpoints.length; + + if (points[i] == null) { + // copy gaps + for (m = 0; m < ps; ++m) + newpoints.push(points[i + m]); + i += ps; + } + else if (j >= otherpoints.length) { + // for lines, we can't use the rest of the points + if (!withlines) { + for (m = 0; m < ps; ++m) + newpoints.push(points[i + m]); + } + i += ps; + } + else if (otherpoints[j] == null) { + // oops, got a gap + for (m = 0; m < ps; ++m) + newpoints.push(null); + fromgap = true; + j += otherps; + } + else { + // cases where we actually got two points + px = points[i + keyOffset]; + py = points[i + accumulateOffset]; + qx = otherpoints[j + keyOffset]; + qy = otherpoints[j + accumulateOffset]; + bottom = 0; + + if (px == qx) { + for (m = 0; m < ps; ++m) + newpoints.push(points[i + m]); + + newpoints[l + accumulateOffset] += qy; + bottom = qy; + + i += ps; + j += otherps; + } + else if (px > qx) { + // we got past point below, might need to + // insert interpolated extra point + if (withlines && i > 0 && points[i - ps] != null) { + intery = py + (points[i - ps + accumulateOffset] - py) * (qx - px) / (points[i - ps + keyOffset] - px); + newpoints.push(qx); + newpoints.push(intery + qy); + for (m = 2; m < ps; ++m) + newpoints.push(points[i + m]); + bottom = qy; + } + + j += otherps; + } + else { // px < qx + if (fromgap && withlines) { + // if we come from a gap, we just skip this point + i += ps; + continue; + } + + for (m = 0; m < ps; ++m) + newpoints.push(points[i + m]); + + // we might be able to interpolate a point below, + // this can give us a better y + if (withlines && j > 0 && otherpoints[j - otherps] != null) + bottom = qy + (otherpoints[j - otherps + accumulateOffset] - qy) * (px - qx) / (otherpoints[j - otherps + keyOffset] - qx); + + newpoints[l + accumulateOffset] += bottom; + + i += ps; + } + + fromgap = false; + + if (l != newpoints.length && withbottom) + newpoints[l + 2] += bottom; + } + + // maintain the line steps invariant + if (withsteps && l != newpoints.length && l > 0 + && newpoints[l] != null + && newpoints[l] != newpoints[l - ps] + && newpoints[l + 1] != newpoints[l - ps + 1]) { + for (m = 0; m < ps; ++m) + newpoints[l + ps + m] = newpoints[l + m]; + newpoints[l + 1] = newpoints[l - ps + 1]; + } + } + + datapoints.points = newpoints; + } + + plot.hooks.processDatapoints.push(stackData); + } + + $.plot.plugins.push({ + init: init, + options: options, + name: 'stack', + version: '1.2' + }); +})(jQuery); diff --git a/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.symbol.js b/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.symbol.js new file mode 100644 index 0000000000000000000000000000000000000000..79f634971b6fa6acb9bc5ff373d160063d4aa033 --- /dev/null +++ b/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.symbol.js @@ -0,0 +1,71 @@ +/* Flot plugin that adds some extra symbols for plotting points. + +Copyright (c) 2007-2014 IOLA and Ole Laursen. +Licensed under the MIT license. + +The symbols are accessed as strings through the standard symbol options: + + series: { + points: { + symbol: "square" // or "diamond", "triangle", "cross" + } + } + +*/ + +(function ($) { + function processRawData(plot, series, datapoints) { + // we normalize the area of each symbol so it is approximately the + // same as a circle of the given radius + + var handlers = { + square: function (ctx, x, y, radius, shadow) { + // pi * r^2 = (2s)^2 => s = r * sqrt(pi)/2 + var size = radius * Math.sqrt(Math.PI) / 2; + ctx.rect(x - size, y - size, size + size, size + size); + }, + diamond: function (ctx, x, y, radius, shadow) { + // pi * r^2 = 2s^2 => s = r * sqrt(pi/2) + var size = radius * Math.sqrt(Math.PI / 2); + ctx.moveTo(x - size, y); + ctx.lineTo(x, y - size); + ctx.lineTo(x + size, y); + ctx.lineTo(x, y + size); + ctx.lineTo(x - size, y); + }, + triangle: function (ctx, x, y, radius, shadow) { + // pi * r^2 = 1/2 * s^2 * sin (pi / 3) => s = r * sqrt(2 * pi / sin(pi / 3)) + var size = radius * Math.sqrt(2 * Math.PI / Math.sin(Math.PI / 3)); + var height = size * Math.sin(Math.PI / 3); + ctx.moveTo(x - size/2, y + height/2); + ctx.lineTo(x + size/2, y + height/2); + if (!shadow) { + ctx.lineTo(x, y - height/2); + ctx.lineTo(x - size/2, y + height/2); + } + }, + cross: function (ctx, x, y, radius, shadow) { + // pi * r^2 = (2s)^2 => s = r * sqrt(pi)/2 + var size = radius * Math.sqrt(Math.PI) / 2; + ctx.moveTo(x - size, y - size); + ctx.lineTo(x + size, y + size); + ctx.moveTo(x - size, y + size); + ctx.lineTo(x + size, y - size); + } + }; + + var s = series.points.symbol; + if (handlers[s]) + series.points.symbol = handlers[s]; + } + + function init(plot) { + plot.hooks.processDatapoints.push(processRawData); + } + + $.plot.plugins.push({ + init: init, + name: 'symbols', + version: '1.0' + }); +})(jQuery); diff --git a/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.threshold.js b/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.threshold.js new file mode 100644 index 0000000000000000000000000000000000000000..8c99c401d87e5ae46f855c1885a0fef3aa31587e --- /dev/null +++ b/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.threshold.js @@ -0,0 +1,142 @@ +/* Flot plugin for thresholding data. + +Copyright (c) 2007-2014 IOLA and Ole Laursen. +Licensed under the MIT license. + +The plugin supports these options: + + series: { + threshold: { + below: number + color: colorspec + } + } + +It can also be applied to a single series, like this: + + $.plot( $("#placeholder"), [{ + data: [ ... ], + threshold: { ... } + }]) + +An array can be passed for multiple thresholding, like this: + + threshold: [{ + below: number1 + color: color1 + },{ + below: number2 + color: color2 + }] + +These multiple threshold objects can be passed in any order since they are +sorted by the processing function. + +The data points below "below" are drawn with the specified color. This makes +it easy to mark points below 0, e.g. for budget data. + +Internally, the plugin works by splitting the data into two series, above and +below the threshold. The extra series below the threshold will have its label +cleared and the special "originSeries" attribute set to the original series. +You may need to check for this in hover events. + +*/ + +(function ($) { + var options = { + series: { threshold: null } // or { below: number, color: color spec} + }; + + function init(plot) { + function thresholdData(plot, s, datapoints, below, color) { + var ps = datapoints.pointsize, i, x, y, p, prevp, + thresholded = $.extend({}, s); // note: shallow copy + + thresholded.datapoints = { points: [], pointsize: ps, format: datapoints.format }; + thresholded.label = null; + thresholded.color = color; + thresholded.threshold = null; + thresholded.originSeries = s; + thresholded.data = []; + + var origpoints = datapoints.points, + addCrossingPoints = s.lines.show; + + var threspoints = []; + var newpoints = []; + var m; + + for (i = 0; i < origpoints.length; i += ps) { + x = origpoints[i]; + y = origpoints[i + 1]; + + prevp = p; + if (y < below) + p = threspoints; + else + p = newpoints; + + if (addCrossingPoints && prevp != p && x != null + && i > 0 && origpoints[i - ps] != null) { + var interx = x + (below - y) * (x - origpoints[i - ps]) / (y - origpoints[i - ps + 1]); + prevp.push(interx); + prevp.push(below); + for (m = 2; m < ps; ++m) + prevp.push(origpoints[i + m]); + + p.push(null); // start new segment + p.push(null); + for (m = 2; m < ps; ++m) + p.push(origpoints[i + m]); + p.push(interx); + p.push(below); + for (m = 2; m < ps; ++m) + p.push(origpoints[i + m]); + } + + p.push(x); + p.push(y); + for (m = 2; m < ps; ++m) + p.push(origpoints[i + m]); + } + + datapoints.points = newpoints; + thresholded.datapoints.points = threspoints; + + if (thresholded.datapoints.points.length > 0) { + var origIndex = $.inArray(s, plot.getData()); + // Insert newly-generated series right after original one (to prevent it from becoming top-most) + plot.getData().splice(origIndex + 1, 0, thresholded); + } + + // FIXME: there are probably some edge cases left in bars + } + + function processThresholds(plot, s, datapoints) { + if (!s.threshold) + return; + + if (s.threshold instanceof Array) { + s.threshold.sort(function(a, b) { + return a.below - b.below; + }); + + $(s.threshold).each(function(i, th) { + thresholdData(plot, s, datapoints, th.below, th.color); + }); + } + else { + thresholdData(plot, s, datapoints, s.threshold.below, s.threshold.color); + } + } + + plot.hooks.processDatapoints.push(processThresholds); + } + + $.plot.plugins.push({ + init: init, + options: options, + name: 'threshold', + version: '1.2' + }); +})(jQuery); diff --git a/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.time.js b/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.time.js new file mode 100644 index 0000000000000000000000000000000000000000..34c1d121259a2ff18c4b04ec8ed7d773a732670c --- /dev/null +++ b/monitoring/monitoring_ui/src/3dparty/flot/jquery.flot.time.js @@ -0,0 +1,432 @@ +/* Pretty handling of time axes. + +Copyright (c) 2007-2014 IOLA and Ole Laursen. +Licensed under the MIT license. + +Set axis.mode to "time" to enable. See the section "Time series data" in +API.txt for details. + +*/ + +(function($) { + + var options = { + xaxis: { + timezone: null, // "browser" for local to the client or timezone for timezone-js + timeformat: null, // format string to use + twelveHourClock: false, // 12 or 24 time in time mode + monthNames: null // list of names of months + } + }; + + // round to nearby lower multiple of base + + function floorInBase(n, base) { + return base * Math.floor(n / base); + } + + // Returns a string with the date d formatted according to fmt. + // A subset of the Open Group's strftime format is supported. + + function formatDate(d, fmt, monthNames, dayNames) { + + if (typeof d.strftime == "function") { + return d.strftime(fmt); + } + + var leftPad = function(n, pad) { + n = "" + n; + pad = "" + (pad == null ? "0" : pad); + return n.length == 1 ? pad + n : n; + }; + + var r = []; + var escape = false; + var hours = d.getHours(); + var isAM = hours < 12; + + if (monthNames == null) { + monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; + } + + if (dayNames == null) { + dayNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; + } + + var hours12; + + if (hours > 12) { + hours12 = hours - 12; + } else if (hours == 0) { + hours12 = 12; + } else { + hours12 = hours; + } + + for (var i = 0; i < fmt.length; ++i) { + + var c = fmt.charAt(i); + + if (escape) { + switch (c) { + case 'a': c = "" + dayNames[d.getDay()]; break; + case 'b': c = "" + monthNames[d.getMonth()]; break; + case 'd': c = leftPad(d.getDate()); break; + case 'e': c = leftPad(d.getDate(), " "); break; + case 'h': // For back-compat with 0.7; remove in 1.0 + case 'H': c = leftPad(hours); break; + case 'I': c = leftPad(hours12); break; + case 'l': c = leftPad(hours12, " "); break; + case 'm': c = leftPad(d.getMonth() + 1); break; + case 'M': c = leftPad(d.getMinutes()); break; + // quarters not in Open Group's strftime specification + case 'q': + c = "" + (Math.floor(d.getMonth() / 3) + 1); break; + case 'S': c = leftPad(d.getSeconds()); break; + case 'y': c = leftPad(d.getFullYear() % 100); break; + case 'Y': c = "" + d.getFullYear(); break; + case 'p': c = (isAM) ? ("" + "am") : ("" + "pm"); break; + case 'P': c = (isAM) ? ("" + "AM") : ("" + "PM"); break; + case 'w': c = "" + d.getDay(); break; + } + r.push(c); + escape = false; + } else { + if (c == "%") { + escape = true; + } else { + r.push(c); + } + } + } + + return r.join(""); + } + + // To have a consistent view of time-based data independent of which time + // zone the client happens to be in we need a date-like object independent + // of time zones. This is done through a wrapper that only calls the UTC + // versions of the accessor methods. + + function makeUtcWrapper(d) { + + function addProxyMethod(sourceObj, sourceMethod, targetObj, targetMethod) { + sourceObj[sourceMethod] = function() { + return targetObj[targetMethod].apply(targetObj, arguments); + }; + }; + + var utc = { + date: d + }; + + // support strftime, if found + + if (d.strftime != undefined) { + addProxyMethod(utc, "strftime", d, "strftime"); + } + + addProxyMethod(utc, "getTime", d, "getTime"); + addProxyMethod(utc, "setTime", d, "setTime"); + + var props = ["Date", "Day", "FullYear", "Hours", "Milliseconds", "Minutes", "Month", "Seconds"]; + + for (var p = 0; p < props.length; p++) { + addProxyMethod(utc, "get" + props[p], d, "getUTC" + props[p]); + addProxyMethod(utc, "set" + props[p], d, "setUTC" + props[p]); + } + + return utc; + }; + + // select time zone strategy. This returns a date-like object tied to the + // desired timezone + + function dateGenerator(ts, opts) { + if (opts.timezone == "browser") { + return new Date(ts); + } else if (!opts.timezone || opts.timezone == "utc") { + return makeUtcWrapper(new Date(ts)); + } else if (typeof timezoneJS != "undefined" && typeof timezoneJS.Date != "undefined") { + var d = new timezoneJS.Date(); + // timezone-js is fickle, so be sure to set the time zone before + // setting the time. + d.setTimezone(opts.timezone); + d.setTime(ts); + return d; + } else { + return makeUtcWrapper(new Date(ts)); + } + } + + // map of app. size of time units in milliseconds + + var timeUnitSize = { + "second": 1000, + "minute": 60 * 1000, + "hour": 60 * 60 * 1000, + "day": 24 * 60 * 60 * 1000, + "month": 30 * 24 * 60 * 60 * 1000, + "quarter": 3 * 30 * 24 * 60 * 60 * 1000, + "year": 365.2425 * 24 * 60 * 60 * 1000 + }; + + // the allowed tick sizes, after 1 year we use + // an integer algorithm + + var baseSpec = [ + [1, "second"], [2, "second"], [5, "second"], [10, "second"], + [30, "second"], + [1, "minute"], [2, "minute"], [5, "minute"], [10, "minute"], + [30, "minute"], + [1, "hour"], [2, "hour"], [4, "hour"], + [8, "hour"], [12, "hour"], + [1, "day"], [2, "day"], [3, "day"], + [0.25, "month"], [0.5, "month"], [1, "month"], + [2, "month"] + ]; + + // we don't know which variant(s) we'll need yet, but generating both is + // cheap + + var specMonths = baseSpec.concat([[3, "month"], [6, "month"], + [1, "year"]]); + var specQuarters = baseSpec.concat([[1, "quarter"], [2, "quarter"], + [1, "year"]]); + + function init(plot) { + plot.hooks.processOptions.push(function (plot, options) { + $.each(plot.getAxes(), function(axisName, axis) { + + var opts = axis.options; + + if (opts.mode == "time") { + axis.tickGenerator = function(axis) { + + var ticks = []; + var d = dateGenerator(axis.min, opts); + var minSize = 0; + + // make quarter use a possibility if quarters are + // mentioned in either of these options + + var spec = (opts.tickSize && opts.tickSize[1] === + "quarter") || + (opts.minTickSize && opts.minTickSize[1] === + "quarter") ? specQuarters : specMonths; + + if (opts.minTickSize != null) { + if (typeof opts.tickSize == "number") { + minSize = opts.tickSize; + } else { + minSize = opts.minTickSize[0] * timeUnitSize[opts.minTickSize[1]]; + } + } + + for (var i = 0; i < spec.length - 1; ++i) { + if (axis.delta < (spec[i][0] * timeUnitSize[spec[i][1]] + + spec[i + 1][0] * timeUnitSize[spec[i + 1][1]]) / 2 + && spec[i][0] * timeUnitSize[spec[i][1]] >= minSize) { + break; + } + } + + var size = spec[i][0]; + var unit = spec[i][1]; + + // special-case the possibility of several years + + if (unit == "year") { + + // if given a minTickSize in years, just use it, + // ensuring that it's an integer + + if (opts.minTickSize != null && opts.minTickSize[1] == "year") { + size = Math.floor(opts.minTickSize[0]); + } else { + + var magn = Math.pow(10, Math.floor(Math.log(axis.delta / timeUnitSize.year) / Math.LN10)); + var norm = (axis.delta / timeUnitSize.year) / magn; + + if (norm < 1.5) { + size = 1; + } else if (norm < 3) { + size = 2; + } else if (norm < 7.5) { + size = 5; + } else { + size = 10; + } + + size *= magn; + } + + // minimum size for years is 1 + + if (size < 1) { + size = 1; + } + } + + axis.tickSize = opts.tickSize || [size, unit]; + var tickSize = axis.tickSize[0]; + unit = axis.tickSize[1]; + + var step = tickSize * timeUnitSize[unit]; + + if (unit == "second") { + d.setSeconds(floorInBase(d.getSeconds(), tickSize)); + } else if (unit == "minute") { + d.setMinutes(floorInBase(d.getMinutes(), tickSize)); + } else if (unit == "hour") { + d.setHours(floorInBase(d.getHours(), tickSize)); + } else if (unit == "month") { + d.setMonth(floorInBase(d.getMonth(), tickSize)); + } else if (unit == "quarter") { + d.setMonth(3 * floorInBase(d.getMonth() / 3, + tickSize)); + } else if (unit == "year") { + d.setFullYear(floorInBase(d.getFullYear(), tickSize)); + } + + // reset smaller components + + d.setMilliseconds(0); + + if (step >= timeUnitSize.minute) { + d.setSeconds(0); + } + if (step >= timeUnitSize.hour) { + d.setMinutes(0); + } + if (step >= timeUnitSize.day) { + d.setHours(0); + } + if (step >= timeUnitSize.day * 4) { + d.setDate(1); + } + if (step >= timeUnitSize.month * 2) { + d.setMonth(floorInBase(d.getMonth(), 3)); + } + if (step >= timeUnitSize.quarter * 2) { + d.setMonth(floorInBase(d.getMonth(), 6)); + } + if (step >= timeUnitSize.year) { + d.setMonth(0); + } + + var carry = 0; + var v = Number.NaN; + var prev; + + do { + + prev = v; + v = d.getTime(); + ticks.push(v); + + if (unit == "month" || unit == "quarter") { + if (tickSize < 1) { + + // a bit complicated - we'll divide the + // month/quarter up but we need to take + // care of fractions so we don't end up in + // the middle of a day + + d.setDate(1); + var start = d.getTime(); + d.setMonth(d.getMonth() + + (unit == "quarter" ? 3 : 1)); + var end = d.getTime(); + d.setTime(v + carry * timeUnitSize.hour + (end - start) * tickSize); + carry = d.getHours(); + d.setHours(0); + } else { + d.setMonth(d.getMonth() + + tickSize * (unit == "quarter" ? 3 : 1)); + } + } else if (unit == "year") { + d.setFullYear(d.getFullYear() + tickSize); + } else { + d.setTime(v + step); + } + } while (v < axis.max && v != prev); + + return ticks; + }; + + axis.tickFormatter = function (v, axis) { + + var d = dateGenerator(v, axis.options); + + // first check global format + + if (opts.timeformat != null) { + return formatDate(d, opts.timeformat, opts.monthNames, opts.dayNames); + } + + // possibly use quarters if quarters are mentioned in + // any of these places + + var useQuarters = (axis.options.tickSize && + axis.options.tickSize[1] == "quarter") || + (axis.options.minTickSize && + axis.options.minTickSize[1] == "quarter"); + + var t = axis.tickSize[0] * timeUnitSize[axis.tickSize[1]]; + var span = axis.max - axis.min; + var suffix = (opts.twelveHourClock) ? " %p" : ""; + var hourCode = (opts.twelveHourClock) ? "%I" : "%H"; + var fmt; + + if (t < timeUnitSize.minute) { + fmt = hourCode + ":%M:%S" + suffix; + } else if (t < timeUnitSize.day) { + if (span < 2 * timeUnitSize.day) { + fmt = hourCode + ":%M" + suffix; + } else { + fmt = "%b %d " + hourCode + ":%M" + suffix; + } + } else if (t < timeUnitSize.month) { + fmt = "%b %d"; + } else if ((useQuarters && t < timeUnitSize.quarter) || + (!useQuarters && t < timeUnitSize.year)) { + if (span < timeUnitSize.year) { + fmt = "%b"; + } else { + fmt = "%b %Y"; + } + } else if (useQuarters && t < timeUnitSize.year) { + if (span < timeUnitSize.year) { + fmt = "Q%q"; + } else { + fmt = "Q%q %Y"; + } + } else { + fmt = "%Y"; + } + + var rt = formatDate(d, fmt, opts.monthNames, opts.dayNames); + + return rt; + }; + } + }); + }); + } + + $.plot.plugins.push({ + init: init, + options: options, + name: 'time', + version: '1.0' + }); + + // Time-axis support used to be in Flot core, which exposed the + // formatDate function on the plot object. Various plugins depend + // on the function, so we need to re-expose it here. + + $.plot.formatDate = formatDate; + $.plot.dateGenerator = dateGenerator; + +})(jQuery); diff --git a/monitoring/monitoring_ui/src/3dparty/flot/jquery.js b/monitoring/monitoring_ui/src/3dparty/flot/jquery.js new file mode 100644 index 0000000000000000000000000000000000000000..8c24ffc610d6f5de6ffa9c992030800249612b9c --- /dev/null +++ b/monitoring/monitoring_ui/src/3dparty/flot/jquery.js @@ -0,0 +1,9472 @@ +/*! + * jQuery JavaScript Library v1.8.3 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: Tue Nov 13 2012 08:20:33 GMT-0500 (Eastern Standard Time) + */ +(function( window, undefined ) { +var + // A central reference to the root jQuery(document) + rootjQuery, + + // The deferred used on DOM ready + readyList, + + // Use the correct document accordingly with window argument (sandbox) + document = window.document, + location = window.location, + navigator = window.navigator, + + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$, + + // Save a reference to some core methods + core_push = Array.prototype.push, + core_slice = Array.prototype.slice, + core_indexOf = Array.prototype.indexOf, + core_toString = Object.prototype.toString, + core_hasOwn = Object.prototype.hasOwnProperty, + core_trim = String.prototype.trim, + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + return new jQuery.fn.init( selector, context, rootjQuery ); + }, + + // Used for matching numbers + core_pnum = /[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source, + + // Used for detecting and trimming whitespace + core_rnotwhite = /\S/, + core_rspace = /\s+/, + + // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE) + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // A simple way to check for HTML strings + // Prioritize #id over <tag> to avoid XSS via location.hash (#9521) + rquickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, + + // Match a standalone tag + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, + + // JSON RegExp + rvalidchars = /^[\],:{}\s]*$/, + rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, + rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g, + rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return ( letter + "" ).toUpperCase(); + }, + + // The ready event handler and self cleanup method + DOMContentLoaded = function() { + if ( document.addEventListener ) { + document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + jQuery.ready(); + } else if ( document.readyState === "complete" ) { + // we're here because readyState === "complete" in oldIE + // which is good enough for us to call the dom ready! + document.detachEvent( "onreadystatechange", DOMContentLoaded ); + jQuery.ready(); + } + }, + + // [[Class]] -> type pairs + class2type = {}; + +jQuery.fn = jQuery.prototype = { + constructor: jQuery, + init: function( selector, context, rootjQuery ) { + var match, elem, ret, doc; + + // Handle $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Handle $(DOMElement) + if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + doc = ( context && context.nodeType ? context.ownerDocument || context : document ); + + // scripts is true for back-compat + selector = jQuery.parseHTML( match[1], doc, true ); + if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + this.attr.call( selector, context, true ); + } + + return jQuery.merge( this, selector ); + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return rootjQuery.ready( selector ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }, + + // Start with an empty selector + selector: "", + + // The current version of jQuery being used + jquery: "1.8.3", + + // The default length of a jQuery object is 0 + length: 0, + + // The number of elements contained in the matched element set + size: function() { + return this.length; + }, + + toArray: function() { + return core_slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num == null ? + + // Return a 'clean' array + this.toArray() : + + // Return just the object + ( num < 0 ? this[ this.length + num ] : this[ num ] ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems, name, selector ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + ret.context = this.context; + + if ( name === "find" ) { + ret.selector = this.selector + ( this.selector ? " " : "" ) + selector; + } else if ( name ) { + ret.selector = this.selector + "." + name + "(" + selector + ")"; + } + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + ready: function( fn ) { + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; + }, + + eq: function( i ) { + i = +i; + return i === -1 ? + this.slice( i ) : + this.slice( i, i + 1 ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + slice: function() { + return this.pushStack( core_slice.apply( this, arguments ), + "slice", core_slice.call(arguments).join(",") ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: core_push, + sort: [].sort, + splice: [].splice +}; + +// Give the init function the jQuery prototype for later instantiation +jQuery.fn.init.prototype = jQuery.fn; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( length === i ) { + target = this; + --i; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + noConflict: function( deep ) { + if ( window.$ === jQuery ) { + window.$ = _$; + } + + if ( deep && window.jQuery === jQuery ) { + window.jQuery = _jQuery; + } + + return jQuery; + }, + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready, 1 ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.trigger ) { + jQuery( document ).trigger("ready").off("ready"); + } + }, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === "array"; + }, + + isWindow: function( obj ) { + return obj != null && obj == obj.window; + }, + + isNumeric: function( obj ) { + return !isNaN( parseFloat(obj) ) && isFinite( obj ); + }, + + type: function( obj ) { + return obj == null ? + String( obj ) : + class2type[ core_toString.call(obj) ] || "object"; + }, + + isPlainObject: function( obj ) { + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !core_hasOwn.call(obj, "constructor") && + !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + + var key; + for ( key in obj ) {} + + return key === undefined || core_hasOwn.call( obj, key ); + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + error: function( msg ) { + throw new Error( msg ); + }, + + // data: string of html + // context (optional): If specified, the fragment will be created in this context, defaults to document + // scripts (optional): If true, will include scripts passed in the html string + parseHTML: function( data, context, scripts ) { + var parsed; + if ( !data || typeof data !== "string" ) { + return null; + } + if ( typeof context === "boolean" ) { + scripts = context; + context = 0; + } + context = context || document; + + // Single tag + if ( (parsed = rsingleTag.exec( data )) ) { + return [ context.createElement( parsed[1] ) ]; + } + + parsed = jQuery.buildFragment( [ data ], context, scripts ? null : [] ); + return jQuery.merge( [], + (parsed.cacheable ? jQuery.clone( parsed.fragment ) : parsed.fragment).childNodes ); + }, + + parseJSON: function( data ) { + if ( !data || typeof data !== "string") { + return null; + } + + // Make sure leading/trailing whitespace is removed (IE can't handle it) + data = jQuery.trim( data ); + + // Attempt to parse using the native JSON parser first + if ( window.JSON && window.JSON.parse ) { + return window.JSON.parse( data ); + } + + // Make sure the incoming data is actual JSON + // Logic borrowed from http://json.org/json2.js + if ( rvalidchars.test( data.replace( rvalidescape, "@" ) + .replace( rvalidtokens, "]" ) + .replace( rvalidbraces, "")) ) { + + return ( new Function( "return " + data ) )(); + + } + jQuery.error( "Invalid JSON: " + data ); + }, + + // Cross-browser xml parsing + parseXML: function( data ) { + var xml, tmp; + if ( !data || typeof data !== "string" ) { + return null; + } + try { + if ( window.DOMParser ) { // Standard + tmp = new DOMParser(); + xml = tmp.parseFromString( data , "text/xml" ); + } else { // IE + xml = new ActiveXObject( "Microsoft.XMLDOM" ); + xml.async = "false"; + xml.loadXML( data ); + } + } catch( e ) { + xml = undefined; + } + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; + }, + + noop: function() {}, + + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && core_rnotwhite.test( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }, + + // args is for internal usage only + each: function( obj, callback, args ) { + var name, + i = 0, + length = obj.length, + isObj = length === undefined || jQuery.isFunction( obj ); + + if ( args ) { + if ( isObj ) { + for ( name in obj ) { + if ( callback.apply( obj[ name ], args ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.apply( obj[ i++ ], args ) === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isObj ) { + for ( name in obj ) { + if ( callback.call( obj[ name ], name, obj[ name ] ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.call( obj[ i ], i, obj[ i++ ] ) === false ) { + break; + } + } + } + } + + return obj; + }, + + // Use native String.trim function wherever possible + trim: core_trim && !core_trim.call("\uFEFF\xA0") ? + function( text ) { + return text == null ? + "" : + core_trim.call( text ); + } : + + // Otherwise use our own trimming functionality + function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var type, + ret = results || []; + + if ( arr != null ) { + // The window, strings (and functions) also have 'length' + // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 + type = jQuery.type( arr ); + + if ( arr.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( arr ) ) { + core_push.call( ret, arr ); + } else { + jQuery.merge( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + var len; + + if ( arr ) { + if ( core_indexOf ) { + return core_indexOf.call( arr, elem, i ); + } + + len = arr.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in arr && arr[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var l = second.length, + i = first.length, + j = 0; + + if ( typeof l === "number" ) { + for ( ; j < l; j++ ) { + first[ i++ ] = second[ j ]; + } + + } else { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, inv ) { + var retVal, + ret = [], + i = 0, + length = elems.length; + inv = !!inv; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + retVal = !!callback( elems[ i ], i ); + if ( inv !== retVal ) { + ret.push( elems[ i ] ); + } + } + + return ret; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, key, + ret = [], + i = 0, + length = elems.length, + // jquery objects are treated as arrays + isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ; + + // Go through the array, translating each of the items to their + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + + // Go through every key on the object, + } else { + for ( key in elems ) { + value = callback( elems[ key ], key, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + } + + // Flatten any nested arrays + return ret.concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var tmp, args, proxy; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = core_slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context, args.concat( core_slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; + }, + + // Multifunctional method to get and set values of a collection + // The value/s can optionally be executed if it's a function + access: function( elems, fn, key, value, chainable, emptyGet, pass ) { + var exec, + bulk = key == null, + i = 0, + length = elems.length; + + // Sets many values + if ( key && typeof key === "object" ) { + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], 1, emptyGet, value ); + } + chainable = 1; + + // Sets one value + } else if ( value !== undefined ) { + // Optionally, function values get executed if exec is true + exec = pass === undefined && jQuery.isFunction( value ); + + if ( bulk ) { + // Bulk operations only iterate when executing function values + if ( exec ) { + exec = fn; + fn = function( elem, key, value ) { + return exec.call( jQuery( elem ), value ); + }; + + // Otherwise they run against the entire set + } else { + fn.call( elems, value ); + fn = null; + } + } + + if ( fn ) { + for (; i < length; i++ ) { + fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); + } + } + + chainable = 1; + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[0], key ) : emptyGet; + }, + + now: function() { + return ( new Date() ).getTime(); + } +}); + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called after the browser event has already occurred. + // we once tried to use readyState "interactive" here, but it caused issues like the one + // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + setTimeout( jQuery.ready, 1 ); + + // Standards-based browsers support DOMContentLoaded + } else if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", jQuery.ready, false ); + + // If IE event model is used + } else { + // Ensure firing before onload, maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", DOMContentLoaded ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", jQuery.ready ); + + // If IE and not a frame + // continually check to see if the document is ready + var top = false; + + try { + top = window.frameElement == null && document.documentElement; + } catch(e) {} + + if ( top && top.doScroll ) { + (function doScrollCheck() { + if ( !jQuery.isReady ) { + + try { + // Use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + top.doScroll("left"); + } catch(e) { + return setTimeout( doScrollCheck, 50 ); + } + + // and execute any waiting functions + jQuery.ready(); + } + })(); + } + } + } + return readyList.promise( obj ); +}; + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +// All jQuery objects should point back to these +rootjQuery = jQuery(document); +// String to Object options format cache +var optionsCache = {}; + +// Convert String-formatted options into Object-formatted ones and store in cache +function createOptions( options ) { + var object = optionsCache[ options ] = {}; + jQuery.each( options.split( core_rspace ), function( _, flag ) { + object[ flag ] = true; + }); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + ( optionsCache[ options ] || createOptions( options ) ) : + jQuery.extend( {}, options ); + + var // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // Flag to know if list is currently firing + firing, + // First callback to fire (used internally by add and fireWith) + firingStart, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = !options.once && [], + // Fire callbacks + fire = function( data ) { + memory = options.memory && data; + fired = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + firing = true; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { + memory = false; // To prevent further calls using add + break; + } + } + firing = false; + if ( list ) { + if ( stack ) { + if ( stack.length ) { + fire( stack.shift() ); + } + } else if ( memory ) { + list = []; + } else { + self.disable(); + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + // First, we save the current length + var start = list.length; + (function add( args ) { + jQuery.each( args, function( _, arg ) { + var type = jQuery.type( arg ); + if ( type === "function" ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && type !== "string" ) { + // Inspect recursively + add( arg ); + } + }); + })( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away + } else if ( memory ) { + firingStart = start; + fire( memory ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + jQuery.each( arguments, function( _, arg ) { + var index; + while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + // Handle firing indexes + if ( firing ) { + if ( index <= firingLength ) { + firingLength--; + } + if ( index <= firingIndex ) { + firingIndex--; + } + } + } + }); + } + return this; + }, + // Control if a given callback is in the list + has: function( fn ) { + return jQuery.inArray( fn, list ) > -1; + }, + // Remove all callbacks from the list + empty: function() { + list = []; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + if ( list && ( !fired || stack ) ) { + if ( firing ) { + stack.push( args ); + } else { + fire( args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; +jQuery.extend({ + + Deferred: function( func ) { + var tuples = [ + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], + [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], + [ "notify", "progress", jQuery.Callbacks("memory") ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred(function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var action = tuple[ 0 ], + fn = fns[ i ]; + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[1] ]( jQuery.isFunction( fn ) ? + function() { + var returned = fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); + } + } : + newDefer[ action ] + ); + }); + fns = null; + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[1] ] = list.add; + + // Handle state + if ( stateString ) { + list.add(function() { + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] = list.fire + deferred[ tuple[0] ] = list.fire; + deferred[ tuple[0] + "With" ] = list.fireWith; + }); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = core_slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value; + if( values === progressValues ) { + deferred.notifyWith( contexts, values ); + } else if ( !( --remaining ) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ) + .progress( updateFunc( i, progressContexts, progressValues ) ); + } else { + --remaining; + } + } + } + + // if we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } +}); +jQuery.support = (function() { + + var support, + all, + a, + select, + opt, + input, + fragment, + eventName, + i, + isSupported, + clickFn, + div = document.createElement("div"); + + // Setup + div.setAttribute( "className", "t" ); + div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>"; + + // Support tests won't run in some limited or non-browser environments + all = div.getElementsByTagName("*"); + a = div.getElementsByTagName("a")[ 0 ]; + if ( !all || !a || !all.length ) { + return {}; + } + + // First batch of tests + select = document.createElement("select"); + opt = select.appendChild( document.createElement("option") ); + input = div.getElementsByTagName("input")[ 0 ]; + + a.style.cssText = "top:1px;float:left;opacity:.5"; + support = { + // IE strips leading whitespace when .innerHTML is used + leadingWhitespace: ( div.firstChild.nodeType === 3 ), + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + tbody: !div.getElementsByTagName("tbody").length, + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + htmlSerialize: !!div.getElementsByTagName("link").length, + + // Get the style information from getAttribute + // (IE uses .cssText instead) + style: /top/.test( a.getAttribute("style") ), + + // Make sure that URLs aren't manipulated + // (IE normalizes it by default) + hrefNormalized: ( a.getAttribute("href") === "/a" ), + + // Make sure that element opacity exists + // (IE uses filter instead) + // Use a regex to work around a WebKit issue. See #5145 + opacity: /^0.5/.test( a.style.opacity ), + + // Verify style float existence + // (IE uses styleFloat instead of cssFloat) + cssFloat: !!a.style.cssFloat, + + // Make sure that if no value is specified for a checkbox + // that it defaults to "on". + // (WebKit defaults to "" instead) + checkOn: ( input.value === "on" ), + + // Make sure that a selected-by-default option has a working selected property. + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) + optSelected: opt.selected, + + // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) + getSetAttribute: div.className !== "t", + + // Tests for enctype support on a form (#6743) + enctype: !!document.createElement("form").enctype, + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav></:nav>", + + // jQuery.support.boxModel DEPRECATED in 1.8 since we don't support Quirks Mode + boxModel: ( document.compatMode === "CSS1Compat" ), + + // Will be defined later + submitBubbles: true, + changeBubbles: true, + focusinBubbles: false, + deleteExpando: true, + noCloneEvent: true, + inlineBlockNeedsLayout: false, + shrinkWrapBlocks: false, + reliableMarginRight: true, + boxSizingReliable: true, + pixelPosition: false + }; + + // Make sure checked status is properly cloned + input.checked = true; + support.noCloneChecked = input.cloneNode( true ).checked; + + // Make sure that the options inside disabled selects aren't marked as disabled + // (WebKit marks them as disabled) + select.disabled = true; + support.optDisabled = !opt.disabled; + + // Test to see if it's possible to delete an expando from an element + // Fails in Internet Explorer + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + + if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { + div.attachEvent( "onclick", clickFn = function() { + // Cloning a node shouldn't copy over any + // bound event handlers (IE does this) + support.noCloneEvent = false; + }); + div.cloneNode( true ).fireEvent("onclick"); + div.detachEvent( "onclick", clickFn ); + } + + // Check if a radio maintains its value + // after being appended to the DOM + input = document.createElement("input"); + input.value = "t"; + input.setAttribute( "type", "radio" ); + support.radioValue = input.value === "t"; + + input.setAttribute( "checked", "checked" ); + + // #11217 - WebKit loses check when the name is after the checked attribute + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + fragment = document.createDocumentFragment(); + fragment.appendChild( div.lastChild ); + + // WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; + + fragment.removeChild( input ); + fragment.appendChild( div ); + + // Technique from Juriy Zaytsev + // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/ + // We only care about the case where non-standard event systems + // are used, namely in IE. Short-circuiting here helps us to + // avoid an eval call (in setAttribute) which can cause CSP + // to go haywire. See: https://developer.mozilla.org/en/Security/CSP + if ( div.attachEvent ) { + for ( i in { + submit: true, + change: true, + focusin: true + }) { + eventName = "on" + i; + isSupported = ( eventName in div ); + if ( !isSupported ) { + div.setAttribute( eventName, "return;" ); + isSupported = ( typeof div[ eventName ] === "function" ); + } + support[ i + "Bubbles" ] = isSupported; + } + } + + // Run tests that need a body at doc ready + jQuery(function() { + var container, div, tds, marginDiv, + divReset = "padding:0;margin:0;border:0;display:block;overflow:hidden;", + body = document.getElementsByTagName("body")[0]; + + if ( !body ) { + // Return for frameset docs that don't have a body + return; + } + + container = document.createElement("div"); + container.style.cssText = "visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px"; + body.insertBefore( container, body.firstChild ); + + // Construct the test element + div = document.createElement("div"); + container.appendChild( div ); + + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + // (only IE 8 fails this test) + div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>"; + tds = div.getElementsByTagName("td"); + tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none"; + isSupported = ( tds[ 0 ].offsetHeight === 0 ); + + tds[ 0 ].style.display = ""; + tds[ 1 ].style.display = "none"; + + // Check if empty table cells still have offsetWidth/Height + // (IE <= 8 fail this test) + support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); + + // Check box-sizing and margin behavior + div.innerHTML = ""; + div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;"; + support.boxSizing = ( div.offsetWidth === 4 ); + support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 ); + + // NOTE: To any future maintainer, we've window.getComputedStyle + // because jsdom on node.js will break without it. + if ( window.getComputedStyle ) { + support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%"; + support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px"; + + // Check if div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container. For more + // info see bug #3333 + // Fails in WebKit before Feb 2011 nightlies + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + marginDiv = document.createElement("div"); + marginDiv.style.cssText = div.style.cssText = divReset; + marginDiv.style.marginRight = marginDiv.style.width = "0"; + div.style.width = "1px"; + div.appendChild( marginDiv ); + support.reliableMarginRight = + !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight ); + } + + if ( typeof div.style.zoom !== "undefined" ) { + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + // (IE < 8 does this) + div.innerHTML = ""; + div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1"; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); + + // Check if elements with layout shrink-wrap their children + // (IE 6 does this) + div.style.display = "block"; + div.style.overflow = "visible"; + div.innerHTML = "<div></div>"; + div.firstChild.style.width = "5px"; + support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); + + container.style.zoom = 1; + } + + // Null elements to avoid leaks in IE + body.removeChild( container ); + container = div = tds = marginDiv = null; + }); + + // Null elements to avoid leaks in IE + fragment.removeChild( div ); + all = a = select = opt = input = fragment = div = null; + + return support; +})(); +var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, + rmultiDash = /([A-Z])/g; + +jQuery.extend({ + cache: {}, + + deletedIds: [], + + // Remove at next major release (1.9/2.0) + uuid: 0, + + // Unique for each copy of jQuery on the page + // Non-digits removed to match rinlinejQuery + expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), + + // The following elements throw uncatchable exceptions if you + // attempt to add expando properties to them. + noData: { + "embed": true, + // Ban all objects except for Flash (which handle expandos) + "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", + "applet": true + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, ret, + internalKey = jQuery.expando, + getByName = typeof name === "string", + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && getByName && data === undefined ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + elem[ internalKey ] = id = jQuery.deletedIds.pop() || jQuery.guid++; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + cache[ id ] = {}; + + // Avoids exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + if ( !isNode ) { + cache[ id ].toJSON = jQuery.noop; + } + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( getByName ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; + }, + + removeData: function( elem, name, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, l, + + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + id = isNode ? elem[ jQuery.expando ] : jQuery.expando; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split(" "); + } + } + } + + for ( i = 0, l = name.length; i < l; i++ ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject( cache[ id ] ) ) { + return; + } + } + + // Destroy the cache + if ( isNode ) { + jQuery.cleanData( [ elem ], true ); + + // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) + } else if ( jQuery.support.deleteExpando || cache != cache.window ) { + delete cache[ id ]; + + // When all else fails, null + } else { + cache[ id ] = null; + } + }, + + // For internal use only. + _data: function( elem, name, data ) { + return jQuery.data( elem, name, data, true ); + }, + + // A method for determining if a DOM node can handle the data expando + acceptData: function( elem ) { + var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ]; + + // nodes accept data unless otherwise specified; rejection can be conditional + return !noData || noData !== true && elem.getAttribute("classid") === noData; + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var parts, part, attr, name, l, + elem = this[0], + i = 0, + data = null; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = jQuery.data( elem ); + + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + attr = elem.attributes; + for ( l = attr.length; i < l; i++ ) { + name = attr[i].name; + + if ( !name.indexOf( "data-" ) ) { + name = jQuery.camelCase( name.substring(5) ); + + dataAttr( elem, name, data[ name ] ); + } + } + jQuery._data( elem, "parsedAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + parts = key.split( ".", 2 ); + parts[1] = parts[1] ? "." + parts[1] : ""; + part = parts[1] + "!"; + + return jQuery.access( this, function( value ) { + + if ( value === undefined ) { + data = this.triggerHandler( "getData" + part, [ parts[0] ] ); + + // Try to fetch any internally stored data first + if ( data === undefined && elem ) { + data = jQuery.data( elem, key ); + data = dataAttr( elem, key, data ); + } + + return data === undefined && parts[1] ? + this.data( parts[0] ) : + data; + } + + parts[1] = value; + this.each(function() { + var self = jQuery( this ); + + self.triggerHandler( "setData" + part, parts ); + jQuery.data( this, key, value ); + self.triggerHandler( "changeData" + part, parts ); + }); + }, null, value, arguments.length > 1, null, false ); + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + // Only convert to a number if it doesn't change the string + +data + "" === data ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + var name; + for ( name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} +jQuery.extend({ + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray(data) ) { + queue = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // not intended for public consumption - generates a queueHooks object, or returns the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return jQuery._data( elem, key ) || jQuery._data( elem, key, { + empty: jQuery.Callbacks("once memory").add(function() { + jQuery.removeData( elem, type + "queue", true ); + jQuery.removeData( elem, key, true ); + }) + }); + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + // ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + // Based off of the plugin by Clint Helfers, with permission. + // http://blindsignals.com/index.php/2009/07/jquery-delay/ + delay: function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while( i-- ) { + tmp = jQuery._data( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +}); +var nodeHook, boolHook, fixSpecified, + rclass = /[\t\r\n]/g, + rreturn = /\r/g, + rtype = /^(?:button|input)$/i, + rfocusable = /^(?:button|input|object|select|textarea)$/i, + rclickable = /^a(?:rea|)$/i, + rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, + getSetAttribute = jQuery.support.getSetAttribute; + +jQuery.fn.extend({ + attr: function( name, value ) { + return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + }, + + prop: function( name, value ) { + return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + name = jQuery.propFix[ name ] || name; + return this.each(function() { + // try/catch handles cases where IE balks (such as removing a property on window) + try { + this[ name ] = undefined; + delete this[ name ]; + } catch( e ) {} + }); + }, + + addClass: function( value ) { + var classNames, i, l, elem, + setClass, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).addClass( value.call(this, j, this.className) ); + }); + } + + if ( value && typeof value === "string" ) { + classNames = value.split( core_rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 ) { + if ( !elem.className && classNames.length === 1 ) { + elem.className = value; + + } else { + setClass = " " + elem.className + " "; + + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + if ( setClass.indexOf( " " + classNames[ c ] + " " ) < 0 ) { + setClass += classNames[ c ] + " "; + } + } + elem.className = jQuery.trim( setClass ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var removes, className, elem, c, cl, i, l; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).removeClass( value.call(this, j, this.className) ); + }); + } + if ( (value && typeof value === "string") || value === undefined ) { + removes = ( value || "" ).split( core_rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + if ( elem.nodeType === 1 && elem.className ) { + + className = (" " + elem.className + " ").replace( rclass, " " ); + + // loop over each item in the removal list + for ( c = 0, cl = removes.length; c < cl; c++ ) { + // Remove until there is nothing to remove, + while ( className.indexOf(" " + removes[ c ] + " ") >= 0 ) { + className = className.replace( " " + removes[ c ] + " " , " " ); + } + } + elem.className = value ? jQuery.trim( className ) : ""; + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isBool = typeof stateVal === "boolean"; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( i ) { + jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // toggle individual class names + var className, + i = 0, + self = jQuery( this ), + state = stateVal, + classNames = value.split( core_rspace ); + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space separated list + state = isBool ? state : !self.hasClass( className ); + self[ state ? "addClass" : "removeClass" ]( className ); + } + + } else if ( type === "undefined" || type === "boolean" ) { + if ( this.className ) { + // store className if set + jQuery._data( this, "__className__", this.className ); + } + + // toggle whole className + this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; + } + }); + }, + + hasClass: function( selector ) { + var className = " " + selector + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + var hooks, ret, isFunction, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + return ret; + } + + ret = elem.value; + + return typeof ret === "string" ? + // handle most common string cases + ret.replace(rreturn, "") : + // handle cases where value is null/undef or number + ret == null ? "" : ret; + } + + return; + } + + isFunction = jQuery.isFunction( value ); + + return this.each(function( i ) { + var val, + self = jQuery(this); + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, self.val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + } else if ( typeof val === "number" ) { + val += ""; + } else if ( jQuery.isArray( val ) ) { + val = jQuery.map(val, function ( value ) { + return value == null ? "" : value + ""; + }); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + }); + } +}); + +jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + // attributes.value is undefined in Blackberry 4.7 but + // uses .value. See #6932 + var val = elem.attributes.value; + return !val || val.specified ? elem.value : elem.text; + } + }, + select: { + get: function( elem ) { + var value, option, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one" || index < 0, + values = one ? null : [], + max = one ? index + 1 : options.length, + i = index < 0 ? + max : + one ? index : 0; + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // oldIE doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + // Don't return options that are disabled or in a disabled optgroup + ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) && + ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var values = jQuery.makeArray( value ); + + jQuery(elem).find("option").each(function() { + this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; + }); + + if ( !values.length ) { + elem.selectedIndex = -1; + } + return values; + } + } + }, + + // Unused in 1.8, left in so attrFn-stabbers won't die; remove in 1.9 + attrFn: {}, + + attr: function( elem, name, value, pass ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( pass && jQuery.isFunction( jQuery.fn[ name ] ) ) { + return jQuery( elem )[ name ]( value ); + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( notxml ) { + name = name.toLowerCase(); + hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + + } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, value + "" ); + return value; + } + + } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + + ret = elem.getAttribute( name ); + + // Non-existent attributes return null, we normalize to undefined + return ret === null ? + undefined : + ret; + } + }, + + removeAttr: function( elem, value ) { + var propName, attrNames, name, isBool, + i = 0; + + if ( value && elem.nodeType === 1 ) { + + attrNames = value.split( core_rspace ); + + for ( ; i < attrNames.length; i++ ) { + name = attrNames[ i ]; + + if ( name ) { + propName = jQuery.propFix[ name ] || name; + isBool = rboolean.test( name ); + + // See #9699 for explanation of this approach (setting first, then removal) + // Do not do this for boolean attributes (see #10870) + if ( !isBool ) { + jQuery.attr( elem, name, "" ); + } + elem.removeAttribute( getSetAttribute ? name : propName ); + + // Set corresponding property to false for boolean attributes + if ( isBool && propName in elem ) { + elem[ propName ] = false; + } + } + } + } + }, + + attrHooks: { + type: { + set: function( elem, value ) { + // We can't allow the type property to be changed (since it causes problems in IE) + if ( rtype.test( elem.nodeName ) && elem.parentNode ) { + jQuery.error( "type property can't be changed" ); + } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to it's default in case type is set after value + // This is for element creation + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + }, + // Use the value property for back compat + // Use the nodeHook for button elements in IE6/7 (#1954) + value: { + get: function( elem, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.get( elem, name ); + } + return name in elem ? + elem.value : + null; + }, + set: function( elem, value, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.set( elem, value, name ); + } + // Does not return so that setAttribute is also used + elem.value = value; + } + } + }, + + propFix: { + tabindex: "tabIndex", + readonly: "readOnly", + "for": "htmlFor", + "class": "className", + maxlength: "maxLength", + cellspacing: "cellSpacing", + cellpadding: "cellPadding", + rowspan: "rowSpan", + colspan: "colSpan", + usemap: "useMap", + frameborder: "frameBorder", + contenteditable: "contentEditable" + }, + + prop: function( elem, name, value ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + if ( notxml ) { + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + return ( elem[ name ] = value ); + } + + } else { + if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + return elem[ name ]; + } + } + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + var attributeNode = elem.getAttributeNode("tabindex"); + + return attributeNode && attributeNode.specified ? + parseInt( attributeNode.value, 10 ) : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + undefined; + } + } + } +}); + +// Hook for boolean attributes +boolHook = { + get: function( elem, name ) { + // Align boolean attributes with corresponding properties + // Fall back to attribute presence where some booleans are not supported + var attrNode, + property = jQuery.prop( elem, name ); + return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? + name.toLowerCase() : + undefined; + }, + set: function( elem, value, name ) { + var propName; + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + // value is true since we know at this point it's type boolean and not false + // Set boolean attributes to the same name and set the DOM property + propName = jQuery.propFix[ name ] || name; + if ( propName in elem ) { + // Only set the IDL specifically if it already exists on the element + elem[ propName ] = true; + } + + elem.setAttribute( name, name.toLowerCase() ); + } + return name; + } +}; + +// IE6/7 do not support getting/setting some attributes with get/setAttribute +if ( !getSetAttribute ) { + + fixSpecified = { + name: true, + id: true, + coords: true + }; + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = jQuery.valHooks.button = { + get: function( elem, name ) { + var ret; + ret = elem.getAttributeNode( name ); + return ret && ( fixSpecified[ name ] ? ret.value !== "" : ret.specified ) ? + ret.value : + undefined; + }, + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + ret = document.createAttribute( name ); + elem.setAttributeNode( ret ); + } + return ( ret.value = value + "" ); + } + }; + + // Set width and height to auto instead of 0 on empty string( Bug #8150 ) + // This is for removals + jQuery.each([ "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + set: function( elem, value ) { + if ( value === "" ) { + elem.setAttribute( name, "auto" ); + return value; + } + } + }); + }); + + // Set contenteditable to false on removals(#10429) + // Setting to empty string throws an error as an invalid value + jQuery.attrHooks.contenteditable = { + get: nodeHook.get, + set: function( elem, value, name ) { + if ( value === "" ) { + value = "false"; + } + nodeHook.set( elem, value, name ); + } + }; +} + + +// Some attributes require a special call on IE +if ( !jQuery.support.hrefNormalized ) { + jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + get: function( elem ) { + var ret = elem.getAttribute( name, 2 ); + return ret === null ? undefined : ret; + } + }); + }); +} + +if ( !jQuery.support.style ) { + jQuery.attrHooks.style = { + get: function( elem ) { + // Return undefined in the case of empty string + // Normalize to lowercase since IE uppercases css property names + return elem.style.cssText.toLowerCase() || undefined; + }, + set: function( elem, value ) { + return ( elem.style.cssText = value + "" ); + } + }; +} + +// Safari mis-reports the default selected property of an option +// Accessing the parent's selectedIndex property fixes it +if ( !jQuery.support.optSelected ) { + jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { + get: function( elem ) { + var parent = elem.parentNode; + + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + return null; + } + }); +} + +// IE6/7 call enctype encoding +if ( !jQuery.support.enctype ) { + jQuery.propFix.enctype = "encoding"; +} + +// Radios and checkboxes getter/setter +if ( !jQuery.support.checkOn ) { + jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + get: function( elem ) { + // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + } + }; + }); +} +jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { + set: function( elem, value ) { + if ( jQuery.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); + } + } + }); +}); +var rformElems = /^(?:textarea|input|select)$/i, + rtypenamespace = /^([^\.]*|)(?:\.(.+)|)$/, + rhoverHack = /(?:^|\s)hover(\.\S+|)\b/, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + hoverHack = function( events ) { + return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); + }; + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + add: function( elem, types, handler, data, selector ) { + + var elemData, eventHandle, events, + t, tns, type, namespaces, handleObj, + handleObjIn, handlers, special; + + // Don't attach events to noData or text/comment nodes (allow plain objects tho) + if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + events = elemData.events; + if ( !events ) { + elemData.events = events = {}; + } + eventHandle = elemData.handle; + if ( !eventHandle ) { + elemData.handle = eventHandle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + // jQuery(...).bind("mouseover mouseout", fn); + types = jQuery.trim( hoverHack(types) ).split( " " ); + for ( t = 0; t < types.length; t++ ) { + + tns = rtypenamespace.exec( types[t] ) || []; + type = tns[1]; + namespaces = ( tns[2] || "" ).split( "." ).sort(); + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: tns[1], + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + handlers = events[ type ]; + if ( !handlers ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + global: {}, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var t, tns, type, origType, namespaces, origCount, + j, events, special, eventType, handleObj, + elemData = jQuery.hasData( elem ) && jQuery._data( elem ); + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = jQuery.trim( hoverHack( types || "" ) ).split(" "); + for ( t = 0; t < types.length; t++ ) { + tns = rtypenamespace.exec( types[t] ) || []; + type = origType = tns[1]; + namespaces = tns[2]; + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector? special.delegateType : special.bindType ) || type; + eventType = events[ type ] || []; + origCount = eventType.length; + namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.|)") + "(\\.|$)") : null; + + // Remove matching events + for ( j = 0; j < eventType.length; j++ ) { + handleObj = eventType[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !namespaces || namespaces.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + eventType.splice( j--, 1 ); + + if ( handleObj.selector ) { + eventType.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( eventType.length === 0 && origCount !== eventType.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + delete elemData.handle; + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery.removeData( elem, "events", true ); + } + }, + + // Events that are safe to short-circuit if no handlers are attached. + // Native DOM events should not be added, they may have inline handlers. + customEvent: { + "getData": true, + "setData": true, + "changeData": true + }, + + trigger: function( event, data, elem, onlyHandlers ) { + // Don't do events on text and comment nodes + if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) { + return; + } + + // Event object or event type + var cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType, + type = event.type || event, + namespaces = []; + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "!" ) >= 0 ) { + // Exclusive events trigger only for the exact event (no namespaces) + type = type.slice(0, -1); + exclusive = true; + } + + if ( type.indexOf( "." ) >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + + if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { + // No jQuery handlers for this event type, and it can't have inline handlers + return; + } + + // Caller can pass in an Event, Object, or just an event type string + event = typeof event === "object" ? + // jQuery.Event object + event[ jQuery.expando ] ? event : + // Object literal + new jQuery.Event( type, event ) : + // Just the event type (string) + new jQuery.Event( type ); + + event.type = type; + event.isTrigger = true; + event.exclusive = exclusive; + event.namespace = namespaces.join( "." ); + event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") : null; + ontype = type.indexOf( ":" ) < 0 ? "on" + type : ""; + + // Handle a global trigger + if ( !elem ) { + + // TODO: Stop taunting the data cache; remove global events and always attach to document + cache = jQuery.cache; + for ( i in cache ) { + if ( cache[ i ].events && cache[ i ].events[ type ] ) { + jQuery.event.trigger( event, data, cache[ i ].handle.elem, true ); + } + } + return; + } + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data != null ? jQuery.makeArray( data ) : []; + data.unshift( event ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + eventPath = [[ elem, special.bindType || type ]]; + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode; + for ( old = elem; cur; cur = cur.parentNode ) { + eventPath.push([ cur, bubbleType ]); + old = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( old === (elem.ownerDocument || document) ) { + eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); + } + } + + // Fire handlers on the event path + for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) { + + cur = eventPath[i][0]; + event.type = eventPath[i][1]; + + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + // Note that this is a bare JS function and not a jQuery handler + handle = ontype && cur[ ontype ]; + if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) { + event.preventDefault(); + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) && + !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + // IE<9 dies on focus/blur to hidden element (#1486) + if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + old = elem[ ontype ]; + + if ( old ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + elem[ type ](); + jQuery.event.triggered = undefined; + + if ( old ) { + elem[ ontype ] = old; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event || window.event ); + + var i, j, cur, ret, selMatch, matched, matches, handleObj, sel, related, + handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), + delegateCount = handlers.delegateCount, + args = core_slice.call( arguments ), + run_all = !event.exclusive && !event.namespace, + special = jQuery.event.special[ event.type ] || {}, + handlerQueue = []; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers that should run if there are delegated events + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && !(event.button && event.type === "click") ) { + + for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { + + // Don't process clicks (ONLY) on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.disabled !== true || event.type !== "click" ) { + selMatch = {}; + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + sel = handleObj.selector; + + if ( selMatch[ sel ] === undefined ) { + selMatch[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) >= 0 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( selMatch[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, matches: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( handlers.length > delegateCount ) { + handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); + } + + // Run delegates first; they may want to stop propagation beneath us + for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { + matched = handlerQueue[ i ]; + event.currentTarget = matched.elem; + + for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { + handleObj = matched.matches[ j ]; + + // Triggered event must either 1) be non-exclusive and have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { + + event.data = handleObj.data; + event.handleObj = handleObj; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + event.result = ret; + if ( ret === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 *** + props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var eventDoc, doc, body, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, + originalEvent = event, + fixHook = jQuery.event.fixHooks[ event.type ] || {}, + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = jQuery.Event( originalEvent ); + + for ( i = copy.length; i; ) { + prop = copy[ --i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Target should not be a text node (#504, Safari) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // For mouse/key events, metaKey==false if it's undefined (#3368, #11328; IE6/7/8) + event.metaKey = !!event.metaKey; + + return fixHook.filter? fixHook.filter( event, originalEvent ) : event; + }, + + special: { + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + + focus: { + delegateType: "focusin" + }, + blur: { + delegateType: "focusout" + }, + + beforeunload: { + setup: function( data, namespaces, eventHandle ) { + // We only want to do this special case on windows + if ( jQuery.isWindow( this ) ) { + this.onbeforeunload = eventHandle; + } + }, + + teardown: function( namespaces, eventHandle ) { + if ( this.onbeforeunload === eventHandle ) { + this.onbeforeunload = null; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +// Some plugins are using, but it's undocumented/deprecated and will be removed. +// The 1.7 special event interface should provide all the hooks needed now. +jQuery.event.handle = jQuery.event.dispatch; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + var name = "on" + type; + + if ( elem.detachEvent ) { + + // #8545, #7054, preventing memory leaks for custom events in IE6-8 + // detachEvent needed property on element, by name of that event, to properly expose it to GC + if ( typeof elem[ name ] === "undefined" ) { + elem[ name ] = null; + } + + elem.detachEvent( name, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || + src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +function returnFalse() { + return false; +} +function returnTrue() { + return true; +} + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + preventDefault: function() { + this.isDefaultPrevented = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + + // if preventDefault exists run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // otherwise set the returnValue property of the original event to false (IE) + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + this.isPropagationStopped = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + // if stopPropagation exists run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + // otherwise set the cancelBubble property of the original event to true (IE) + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + }, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj, + selector = handleObj.selector; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !jQuery.support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !jQuery._data( form, "_submit_attached" ) ) { + jQuery.event.add( form, "submit._submit", function( event ) { + event._submit_bubble = true; + }); + jQuery._data( form, "_submit_attached", true ); + } + }); + // return undefined since we don't need an event listener + }, + + postDispatch: function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( event._submit_bubble ) { + delete event._submit_bubble; + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + } + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !jQuery.support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + } + // Allow triggered, simulated change events (#11500) + jQuery.event.simulate( "change", this, event, true ); + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "_change_attached" ) ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + jQuery._data( elem, "_change_attached", true ); + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return !rformElems.test( this.nodeName ); + } + }; +} + +// Create "bubbling" focus and blur events +if ( !jQuery.support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler while someone wants focusin/focusout + var attaches = 0, + handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + if ( attaches++ === 0 ) { + document.addEventListener( orig, handler, true ); + } + }, + teardown: function() { + if ( --attaches === 0 ) { + document.removeEventListener( orig, handler, true ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { // && selector != null + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + bind: function( types, data, fn ) { + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + return this.off( types, null, fn ); + }, + + live: function( types, data, fn ) { + jQuery( this.context ).on( types, this.selector, data, fn ); + return this; + }, + die: function( types, fn ) { + jQuery( this.context ).off( types, this.selector || "**", fn ); + return this; + }, + + delegate: function( selector, types, data, fn ) { + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + // ( namespace ) or ( selector, types [, fn] ) + return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn ); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + if ( this[0] ) { + return jQuery.event.trigger( type, data, this[0], true ); + } + }, + + toggle: function( fn ) { + // Save reference to arguments for access in closure + var args = arguments, + guid = fn.guid || jQuery.guid++, + i = 0, + toggler = function( event ) { + // Figure out which function to execute + var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; + jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); + + // Make sure that clicks stop + event.preventDefault(); + + // and execute the function + return args[ lastToggle ].apply( this, arguments ) || false; + }; + + // link all the functions, so any of them can unbind this click handler + toggler.guid = guid; + while ( i < args.length ) { + args[ i++ ].guid = guid; + } + + return this.click( toggler ); + }, + + hover: function( fnOver, fnOut ) { + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); + } +}); + +jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + + "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { + + // Handle event binding + jQuery.fn[ name ] = function( data, fn ) { + if ( fn == null ) { + fn = data; + data = null; + } + + return arguments.length > 0 ? + this.on( name, null, data, fn ) : + this.trigger( name ); + }; + + if ( rkeyEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; + } + + if ( rmouseEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; + } +}); +/*! + * Sizzle CSS Selector Engine + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license + * http://sizzlejs.com/ + */ +(function( window, undefined ) { + +var cachedruns, + assertGetIdNotName, + Expr, + getText, + isXML, + contains, + compile, + sortOrder, + hasDuplicate, + outermostContext, + + baseHasDuplicate = true, + strundefined = "undefined", + + expando = ( "sizcache" + Math.random() ).replace( ".", "" ), + + Token = String, + document = window.document, + docElem = document.documentElement, + dirruns = 0, + done = 0, + pop = [].pop, + push = [].push, + slice = [].slice, + // Use a stripped-down indexOf if a native one is unavailable + indexOf = [].indexOf || function( elem ) { + var i = 0, + len = this.length; + for ( ; i < len; i++ ) { + if ( this[i] === elem ) { + return i; + } + } + return -1; + }, + + // Augment a function for special use by Sizzle + markFunction = function( fn, value ) { + fn[ expando ] = value == null || value; + return fn; + }, + + createCache = function() { + var cache = {}, + keys = []; + + return markFunction(function( key, value ) { + // Only keep the most recent entries + if ( keys.push( key ) > Expr.cacheLength ) { + delete cache[ keys.shift() ]; + } + + // Retrieve with (key + " ") to avoid collision with native Object.prototype properties (see Issue #157) + return (cache[ key + " " ] = value); + }, cache ); + }, + + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + + // Regex + + // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + // http://www.w3.org/TR/css3-syntax/#characters + characterEncoding = "(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+", + + // Loosely modeled on CSS identifier characters + // An unquoted value should be a CSS identifier (http://www.w3.org/TR/css3-selectors/#attribute-selectors) + // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = characterEncoding.replace( "w", "w#" ), + + // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors + operators = "([*^$|!~]?=)", + attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace + + "*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]", + + // Prefer arguments not in parens/brackets, + // then attribute selectors and non-pseudos (denoted by :), + // then anything else + // These preferences are here to reduce the number of selectors + // needing tokenize in the PSEUDO preFilter + pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:" + attributes + ")|[^:]|\\\\.)*|.*))\\)|)", + + // For matchExpr.POS and matchExpr.needsContext + pos = ":(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*" ), + rpseudo = new RegExp( pseudos ), + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/, + + rnot = /^:not/, + rsibling = /[\x20\t\r\n\f]*[+~]/, + rendsWithNot = /:not\($/, + + rheader = /h\d/i, + rinputs = /input|select|textarea|button/i, + + rbackslash = /\\(?!\\)/g, + + matchExpr = { + "ID": new RegExp( "^#(" + characterEncoding + ")" ), + "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), + "NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ), + "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "POS": new RegExp( pos, "i" ), + "CHILD": new RegExp( "^:(only|nth|first|last)-child(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + // For use in libraries implementing .is() + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|" + pos, "i" ) + }, + + // Support + + // Used for testing something on an element + assert = function( fn ) { + var div = document.createElement("div"); + + try { + return fn( div ); + } catch (e) { + return false; + } finally { + // release memory in IE + div = null; + } + }, + + // Check if getElementsByTagName("*") returns only elements + assertTagNameNoComments = assert(function( div ) { + div.appendChild( document.createComment("") ); + return !div.getElementsByTagName("*").length; + }), + + // Check if getAttribute returns normalized href attributes + assertHrefNotNormalized = assert(function( div ) { + div.innerHTML = "<a href='#'></a>"; + return div.firstChild && typeof div.firstChild.getAttribute !== strundefined && + div.firstChild.getAttribute("href") === "#"; + }), + + // Check if attributes should be retrieved by attribute nodes + assertAttributes = assert(function( div ) { + div.innerHTML = "<select></select>"; + var type = typeof div.lastChild.getAttribute("multiple"); + // IE8 returns a string for some attributes even when not present + return type !== "boolean" && type !== "string"; + }), + + // Check if getElementsByClassName can be trusted + assertUsableClassName = assert(function( div ) { + // Opera can't find a second classname (in 9.6) + div.innerHTML = "<div class='hidden e'></div><div class='hidden'></div>"; + if ( !div.getElementsByClassName || !div.getElementsByClassName("e").length ) { + return false; + } + + // Safari 3.2 caches class attributes and doesn't catch changes + div.lastChild.className = "e"; + return div.getElementsByClassName("e").length === 2; + }), + + // Check if getElementById returns elements by name + // Check if getElementsByName privileges form controls or returns elements by ID + assertUsableName = assert(function( div ) { + // Inject content + div.id = expando + 0; + div.innerHTML = "<a name='" + expando + "'></a><div name='" + expando + "'></div>"; + docElem.insertBefore( div, docElem.firstChild ); + + // Test + var pass = document.getElementsByName && + // buggy browsers will return fewer than the correct 2 + document.getElementsByName( expando ).length === 2 + + // buggy browsers will return more than the correct 0 + document.getElementsByName( expando + 0 ).length; + assertGetIdNotName = !document.getElementById( expando ); + + // Cleanup + docElem.removeChild( div ); + + return pass; + }); + +// If slice is not available, provide a backup +try { + slice.call( docElem.childNodes, 0 )[0].nodeType; +} catch ( e ) { + slice = function( i ) { + var elem, + results = []; + for ( ; (elem = this[i]); i++ ) { + results.push( elem ); + } + return results; + }; +} + +function Sizzle( selector, context, results, seed ) { + results = results || []; + context = context || document; + var match, elem, xml, m, + nodeType = context.nodeType; + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + if ( nodeType !== 1 && nodeType !== 9 ) { + return []; + } + + xml = isXML( context ); + + if ( !xml && !seed ) { + if ( (match = rquickExpr.exec( selector )) ) { + // Speed-up: Sizzle("#ID") + if ( (m = match[1]) ) { + if ( nodeType === 9 ) { + elem = context.getElementById( m ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE, Opera, and Webkit return items + // by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + } else { + // Context is not a document + if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && + contains( context, elem ) && elem.id === m ) { + results.push( elem ); + return results; + } + } + + // Speed-up: Sizzle("TAG") + } else if ( match[2] ) { + push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) ); + return results; + + // Speed-up: Sizzle(".CLASS") + } else if ( (m = match[3]) && assertUsableClassName && context.getElementsByClassName ) { + push.apply( results, slice.call(context.getElementsByClassName( m ), 0) ); + return results; + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed, xml ); +} + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + return Sizzle( expr, null, null, [ elem ] ).length > 0; +}; + +// Returns a function to use in pseudos for input types +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +// Returns a function to use in pseudos for buttons +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +// Returns a function to use in pseudos for positionals +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( nodeType ) { + if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (see #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + } else { + + // If no nodeType, this is expected to be an array + for ( ; (node = elem[i]); i++ ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } + return ret; +}; + +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +// Element contains another +contains = Sizzle.contains = docElem.contains ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) ); + } : + docElem.compareDocumentPosition ? + function( a, b ) { + return b && !!( a.compareDocumentPosition( b ) & 16 ); + } : + function( a, b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + return false; + }; + +Sizzle.attr = function( elem, name ) { + var val, + xml = isXML( elem ); + + if ( !xml ) { + name = name.toLowerCase(); + } + if ( (val = Expr.attrHandle[ name ]) ) { + return val( elem ); + } + if ( xml || assertAttributes ) { + return elem.getAttribute( name ); + } + val = elem.getAttributeNode( name ); + return val ? + typeof elem[ name ] === "boolean" ? + elem[ name ] ? name : null : + val.specified ? val.value : null : + null; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + // IE6/7 return a modified href + attrHandle: assertHrefNotNormalized ? + {} : + { + "href": function( elem ) { + return elem.getAttribute( "href", 2 ); + }, + "type": function( elem ) { + return elem.getAttribute("type"); + } + }, + + find: { + "ID": assertGetIdNotName ? + function( id, context, xml ) { + if ( typeof context.getElementById !== strundefined && !xml ) { + var m = context.getElementById( id ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + } : + function( id, context, xml ) { + if ( typeof context.getElementById !== strundefined && !xml ) { + var m = context.getElementById( id ); + + return m ? + m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode("id").value === id ? + [m] : + undefined : + []; + } + }, + + "TAG": assertTagNameNoComments ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== strundefined ) { + return context.getElementsByTagName( tag ); + } + } : + function( tag, context ) { + var results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + var elem, + tmp = [], + i = 0; + + for ( ; (elem = results[i]); i++ ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }, + + "NAME": assertUsableName && function( tag, context ) { + if ( typeof context.getElementsByName !== strundefined ) { + return context.getElementsByName( name ); + } + }, + + "CLASS": assertUsableClassName && function( className, context, xml ) { + if ( typeof context.getElementsByClassName !== strundefined && !xml ) { + return context.getElementsByClassName( className ); + } + } + }, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( rbackslash, "" ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[4] || match[5] || "" ).replace( rbackslash, "" ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 3 xn-component of xn+y argument ([+-]?\d*n|) + 4 sign of xn-component + 5 x of xn-component + 6 sign of y-component + 7 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1] === "nth" ) { + // nth-child requires argument + if ( !match[2] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[3] = +( match[3] ? match[4] + (match[5] || 1) : 2 * ( match[2] === "even" || match[2] === "odd" ) ); + match[4] = +( ( match[6] + match[7] ) || match[2] === "odd" ); + + // other types prohibit arguments + } else if ( match[2] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var unquoted, excess; + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + if ( match[3] ) { + match[2] = match[3]; + } else if ( (unquoted = match[4]) ) { + // Only check arguments that contain a pseudo + if ( rpseudo.test(unquoted) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + unquoted = unquoted.slice( 0, excess ); + match[0] = match[0].slice( 0, excess ); + } + match[2] = unquoted; + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + "ID": assertGetIdNotName ? + function( id ) { + id = id.replace( rbackslash, "" ); + return function( elem ) { + return elem.getAttribute("id") === id; + }; + } : + function( id ) { + id = id.replace( rbackslash, "" ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); + return node && node.value === id; + }; + }, + + "TAG": function( nodeName ) { + if ( nodeName === "*" ) { + return function() { return true; }; + } + nodeName = nodeName.replace( rbackslash, "" ).toLowerCase(); + + return function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ expando ][ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem, context ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.substr( result.length - check.length ) === check : + operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.substr( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, argument, first, last ) { + + if ( type === "nth" ) { + return function( elem ) { + var node, diff, + parent = elem.parentNode; + + if ( first === 1 && last === 0 ) { + return true; + } + + if ( parent ) { + diff = 0; + for ( node = parent.firstChild; node; node = node.nextSibling ) { + if ( node.nodeType === 1 ) { + diff++; + if ( elem === node ) { + break; + } + } + } + } + + // Incorporate the offset (or cast to NaN), then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + }; + } + + return function( elem ) { + var node = elem; + + switch ( type ) { + case "only": + case "first": + while ( (node = node.previousSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + if ( type === "first" ) { + return true; + } + + node = elem; + + /* falls through */ + case "last": + while ( (node = node.nextSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + return true; + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf.call( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)), + // not comment, processing instructions, or others + // Thanks to Diego Perini for the nodeName shortcut + // Greater than "@" means alpha characters (specifically not starting with "#" or "?") + var nodeType; + elem = elem.firstChild; + while ( elem ) { + if ( elem.nodeName > "@" || (nodeType = elem.nodeType) === 3 || nodeType === 4 ) { + return false; + } + elem = elem.nextSibling; + } + return true; + }, + + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "text": function( elem ) { + var type, attr; + // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) + // use getAttribute instead to test this case + return elem.nodeName.toLowerCase() === "input" && + (type = elem.type) === "text" && + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === type ); + }, + + // Input types + "radio": createInputPseudo("radio"), + "checkbox": createInputPseudo("checkbox"), + "file": createInputPseudo("file"), + "password": createInputPseudo("password"), + "image": createInputPseudo("image"), + + "submit": createButtonPseudo("submit"), + "reset": createButtonPseudo("reset"), + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "focus": function( elem ) { + var doc = elem.ownerDocument; + return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + "active": function( elem ) { + return elem === elem.ownerDocument.activeElement; + }, + + // Positional types + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + for ( var i = 0; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + for ( var i = 1; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + for ( var i = argument < 0 ? argument + length : argument; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + for ( var i = argument < 0 ? argument + length : argument; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +function siblingCheck( a, b, ret ) { + if ( a === b ) { + return ret; + } + + var cur = a.nextSibling; + + while ( cur ) { + if ( cur === b ) { + return -1; + } + + cur = cur.nextSibling; + } + + return 1; +} + +sortOrder = docElem.compareDocumentPosition ? + function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + return ( !a.compareDocumentPosition || !b.compareDocumentPosition ? + a.compareDocumentPosition : + a.compareDocumentPosition(b) & 4 + ) ? -1 : 1; + } : + function( a, b ) { + // The nodes are identical, we can exit early + if ( a === b ) { + hasDuplicate = true; + return 0; + + // Fallback to using sourceIndex (in IE) if it's available on both nodes + } else if ( a.sourceIndex && b.sourceIndex ) { + return a.sourceIndex - b.sourceIndex; + } + + var al, bl, + ap = [], + bp = [], + aup = a.parentNode, + bup = b.parentNode, + cur = aup; + + // If the nodes are siblings (or identical) we can do a quick check + if ( aup === bup ) { + return siblingCheck( a, b ); + + // If no parents were found then the nodes are disconnected + } else if ( !aup ) { + return -1; + + } else if ( !bup ) { + return 1; + } + + // Otherwise they're somewhere else in the tree so we need + // to build up a full list of the parentNodes for comparison + while ( cur ) { + ap.unshift( cur ); + cur = cur.parentNode; + } + + cur = bup; + + while ( cur ) { + bp.unshift( cur ); + cur = cur.parentNode; + } + + al = ap.length; + bl = bp.length; + + // Start walking down the tree looking for a discrepancy + for ( var i = 0; i < al && i < bl; i++ ) { + if ( ap[i] !== bp[i] ) { + return siblingCheck( ap[i], bp[i] ); + } + } + + // We ended someplace up the tree so do a sibling check + return i === al ? + siblingCheck( a, bp[i], -1 ) : + siblingCheck( ap[i], b, 1 ); + }; + +// Always assume the presence of duplicates if sort doesn't +// pass them to our comparison function (as in Google Chrome). +[0, 0].sort( sortOrder ); +baseHasDuplicate = !hasDuplicate; + +// Document sorting and removing duplicates +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + i = 1, + j = 0; + + hasDuplicate = baseHasDuplicate; + results.sort( sortOrder ); + + if ( hasDuplicate ) { + for ( ; (elem = results[i]); i++ ) { + if ( elem === results[ i - 1 ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + return results; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +function tokenize( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ expando ][ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( tokens = [] ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + tokens.push( matched = new Token( match.shift() ) ); + soFar = soFar.slice( matched.length ); + + // Cast descendant combinators to space + matched.type = match[0].replace( rtrim, " " ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + + tokens.push( matched = new Token( match.shift() ) ); + soFar = soFar.slice( matched.length ); + matched.type = type; + matched.matches = match; + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && combinator.dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( checkNonElements || elem.nodeType === 1 ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + if ( !xml ) { + var cache, + dirkey = dirruns + " " + doneName + " ", + cachedkey = dirkey + cachedruns; + while ( (elem = elem[ dir ]) ) { + if ( checkNonElements || elem.nodeType === 1 ) { + if ( (cache = elem[ expando ]) === cachedkey ) { + return elem.sizset; + } else if ( typeof cache === "string" && cache.indexOf(dirkey) === 0 ) { + if ( elem.sizset ) { + return elem; + } + } else { + elem[ expando ] = cachedkey; + if ( matcher( elem, context, xml ) ) { + elem.sizset = true; + return elem; + } + elem.sizset = false; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( checkNonElements || elem.nodeType === 1 ) { + if ( matcher( elem, context, xml ) ) { + return elem; + } + } + } + } + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf.call( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && tokens.slice( 0, i - 1 ).join("").replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && tokens.join("") + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, expandContext ) { + var elem, j, matcher, + setMatched = [], + matchedCount = 0, + i = "0", + unmatched = seed && [], + outermost = expandContext != null, + contextBackup = outermostContext, + // We must always have either seed elements or context + elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ), + // Nested matchers should use non-integer dirruns + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.E); + + if ( outermost ) { + outermostContext = context !== document && context; + cachedruns = superMatcher.el; + } + + // Add elements passing elementMatchers directly to results + for ( ; (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + for ( j = 0; (matcher = elementMatchers[j]); j++ ) { + if ( matcher( elem, context, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + cachedruns = ++superMatcher.el; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // Apply set filters to unmatched elements + matchedCount += i; + if ( bySet && i !== matchedCount ) { + for ( j = 0; (matcher = setMatchers[j]); j++ ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + superMatcher.el = 0; + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ expando ][ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !group ) { + group = tokenize( selector ); + } + i = group.length; + while ( i-- ) { + cached = matcherFromTokens( group[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + } + return cached; +}; + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function select( selector, context, results, seed, xml ) { + var i, tokens, token, type, find, + match = tokenize( selector ), + j = match.length; + + if ( !seed ) { + // Try to minimize operations if there is only one group + if ( match.length === 1 ) { + + // Take a shortcut and set the context if the root selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + context.nodeType === 9 && !xml && + Expr.relative[ tokens[1].type ] ) { + + context = Expr.find["ID"]( token.matches[0].replace( rbackslash, "" ), context, xml )[0]; + if ( !context ) { + return results; + } + + selector = selector.slice( tokens.shift().length ); + } + + // Fetch a seed set for right-to-left matching + for ( i = matchExpr["POS"].test( selector ) ? -1 : tokens.length - 1; i >= 0; i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( rbackslash, "" ), + rsibling.test( tokens[0].type ) && context.parentNode || context, + xml + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && tokens.join(""); + if ( !selector ) { + push.apply( results, slice.call( seed, 0 ) ); + return results; + } + + break; + } + } + } + } + } + + // Compile and execute a filtering function + // Provide `match` to avoid retokenization if we modified the selector above + compile( selector, match )( + seed, + context, + xml, + results, + rsibling.test( selector ) + ); + return results; +} + +if ( document.querySelectorAll ) { + (function() { + var disconnectedMatch, + oldSelect = select, + rescape = /'|\\/g, + rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g, + + // qSa(:focus) reports false when true (Chrome 21), no need to also add to buggyMatches since matches checks buggyQSA + // A support test would require too much code (would include document ready) + rbuggyQSA = [ ":focus" ], + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + // A support test would require too much code (would include document ready) + // just skip matchesSelector for :active + rbuggyMatches = [ ":active" ], + matches = docElem.matchesSelector || + docElem.mozMatchesSelector || + docElem.webkitMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector; + + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explictly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + div.innerHTML = "<select><option selected=''></option></select>"; + + // IE8 - Some boolean attributes are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here (do not put tests after this one) + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + }); + + assert(function( div ) { + + // Opera 10-12/IE9 - ^= $= *= and empty values + // Should not select anything + div.innerHTML = "<p test=''></p>"; + if ( div.querySelectorAll("[test^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:\"\"|'')" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here (do not put tests after this one) + div.innerHTML = "<input type='hidden'/>"; + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push(":enabled", ":disabled"); + } + }); + + // rbuggyQSA always contains :focus, so no need for a length check + rbuggyQSA = /* rbuggyQSA.length && */ new RegExp( rbuggyQSA.join("|") ); + + select = function( selector, context, results, seed, xml ) { + // Only use querySelectorAll when not filtering, + // when this is not xml, + // and when no QSA bugs apply + if ( !seed && !xml && !rbuggyQSA.test( selector ) ) { + var groups, i, + old = true, + nid = expando, + newContext = context, + newSelector = context.nodeType === 9 && selector; + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + groups = tokenize( selector ); + + if ( (old = context.getAttribute("id")) ) { + nid = old.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", nid ); + } + nid = "[id='" + nid + "'] "; + + i = groups.length; + while ( i-- ) { + groups[i] = nid + groups[i].join(""); + } + newContext = rsibling.test( selector ) && context.parentNode || context; + newSelector = groups.join(","); + } + + if ( newSelector ) { + try { + push.apply( results, slice.call( newContext.querySelectorAll( + newSelector + ), 0 ) ); + return results; + } catch(qsaError) { + } finally { + if ( !old ) { + context.removeAttribute("id"); + } + } + } + } + + return oldSelect( selector, context, results, seed, xml ); + }; + + if ( matches ) { + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + try { + matches.call( div, "[test!='']:sizzle" ); + rbuggyMatches.push( "!=", pseudos ); + } catch ( e ) {} + }); + + // rbuggyMatches always contains :active and :focus, so no need for a length check + rbuggyMatches = /* rbuggyMatches.length && */ new RegExp( rbuggyMatches.join("|") ); + + Sizzle.matchesSelector = function( elem, expr ) { + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + // rbuggyMatches always contains :active, so no need for an existence check + if ( !isXML( elem ) && !rbuggyMatches.test( expr ) && !rbuggyQSA.test( expr ) ) { + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch(e) {} + } + + return Sizzle( expr, null, null, [ elem ] ).length > 0; + }; + } + })(); +} + +// Deprecated +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Back-compat +function setFilters() {} +Expr.filters = setFilters.prototype = Expr.pseudos; +Expr.setFilters = new setFilters(); + +// Override sizzle attribute retrieval +Sizzle.attr = jQuery.attr; +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.pseudos; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + +})( window ); +var runtil = /Until$/, + rparentsprev = /^(?:parents|prev(?:Until|All))/, + isSimple = /^.[^:#\[\.,]*$/, + rneedsContext = jQuery.expr.match.needsContext, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend({ + find: function( selector ) { + var i, l, length, n, r, ret, + self = this; + + if ( typeof selector !== "string" ) { + return jQuery( selector ).filter(function() { + for ( i = 0, l = self.length; i < l; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }); + } + + ret = this.pushStack( "", "find", selector ); + + for ( i = 0, l = this.length; i < l; i++ ) { + length = ret.length; + jQuery.find( selector, this[i], ret ); + + if ( i > 0 ) { + // Make sure that the results are unique + for ( n = length; n < ret.length; n++ ) { + for ( r = 0; r < length; r++ ) { + if ( ret[r] === ret[n] ) { + ret.splice(n--, 1); + break; + } + } + } + } + } + + return ret; + }, + + has: function( target ) { + var i, + targets = jQuery( target, this ), + len = targets.length; + + return this.filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + not: function( selector ) { + return this.pushStack( winnow(this, selector, false), "not", selector); + }, + + filter: function( selector ) { + return this.pushStack( winnow(this, selector, true), "filter", selector ); + }, + + is: function( selector ) { + return !!selector && ( + typeof selector === "string" ? + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + rneedsContext.test( selector ) ? + jQuery( selector, this.context ).index( this[0] ) >= 0 : + jQuery.filter( selector, this ).length > 0 : + this.filter( selector ).length > 0 ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + ret = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + cur = this[i]; + + while ( cur && cur.ownerDocument && cur !== context && cur.nodeType !== 11 ) { + if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { + ret.push( cur ); + break; + } + cur = cur.parentNode; + } + } + + ret = ret.length > 1 ? jQuery.unique( ret ) : ret; + + return this.pushStack( ret, "closest", selectors ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + var set = typeof selector === "string" ? + jQuery( selector, context ) : + jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), + all = jQuery.merge( this.get(), set ); + + return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? + all : + jQuery.unique( all ) ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter(selector) + ); + } +}); + +jQuery.fn.andSelf = jQuery.fn.addBack; + +// A painfully simple check to see if an element is disconnected +// from a document (should be improved, where feasible). +function isDisconnected( node ) { + return !node || !node.parentNode || node.parentNode.nodeType === 11; +} + +function sibling( cur, dir ) { + do { + cur = cur[ dir ]; + } while ( cur && cur.nodeType !== 1 ); + + return cur; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + if ( !runtil.test( name ) ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; + + if ( this.length > 1 && rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + + return this.pushStack( ret, name, core_slice.call( arguments ).join(",") ); + }; +}); + +jQuery.extend({ + filter: function( expr, elems, not ) { + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 ? + jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : + jQuery.find.matches(expr, elems); + }, + + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, keep ) { + + // Can't pass null or undefined to indexOf in Firefox 4 + // Set to 0 to skip string check + qualifier = qualifier || 0; + + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep(elements, function( elem, i ) { + var retVal = !!qualifier.call( elem, i, elem ); + return retVal === keep; + }); + + } else if ( qualifier.nodeType ) { + return jQuery.grep(elements, function( elem, i ) { + return ( elem === qualifier ) === keep; + }); + + } else if ( typeof qualifier === "string" ) { + var filtered = jQuery.grep(elements, function( elem ) { + return elem.nodeType === 1; + }); + + if ( isSimple.test( qualifier ) ) { + return jQuery.filter(qualifier, filtered, !keep); + } else { + qualifier = jQuery.filter( qualifier, filtered ); + } + } + + return jQuery.grep(elements, function( elem, i ) { + return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; + }); +} +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, + rtagName = /<([\w:]+)/, + rtbody = /<tbody/i, + rhtml = /<|&#?\w+;/, + rnoInnerhtml = /<(?:script|style|link)/i, + rnocache = /<(?:script|object|embed|option|style)/i, + rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"), + rcheckableType = /^(?:checkbox|radio)$/, + // checked="checked" or checked + rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, + rscriptType = /\/(java|ecma)script/i, + rcleanScript = /^\s*<!(?:\[CDATA\[|\-\-)|[\]\-]{2}>\s*$/g, + wrapMap = { + option: [ 1, "<select multiple='multiple'>", "</select>" ], + legend: [ 1, "<fieldset>", "</fieldset>" ], + thead: [ 1, "<table>", "</table>" ], + tr: [ 2, "<table><tbody>", "</tbody></table>" ], + td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], + col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ], + area: [ 1, "<map>", "</map>" ], + _default: [ 0, "", "" ] + }, + safeFragment = createSafeFragment( document ), + fragmentDiv = safeFragment.appendChild( document.createElement("div") ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, +// unless wrapped in a div with non-breaking characters in front of it. +if ( !jQuery.support.htmlSerialize ) { + wrapMap._default = [ 1, "X<div>", "</div>" ]; +} + +jQuery.fn.extend({ + text: function( value ) { + return jQuery.access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); + }, null, value, arguments.length ); + }, + + wrapAll: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapAll( html.call(this, i) ); + }); + } + + if ( this[0] ) { + // The elements to wrap the target around + var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); + + if ( this[0].parentNode ) { + wrap.insertBefore( this[0] ); + } + + wrap.map(function() { + var elem = this; + + while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { + elem = elem.firstChild; + } + + return elem; + }).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapInner( html.call(this, i) ); + }); + } + + return this.each(function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + }); + }, + + wrap: function( html ) { + var isFunction = jQuery.isFunction( html ); + + return this.each(function(i) { + jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); + }); + }, + + unwrap: function() { + return this.parent().each(function() { + if ( !jQuery.nodeName( this, "body" ) ) { + jQuery( this ).replaceWith( this.childNodes ); + } + }).end(); + }, + + append: function() { + return this.domManip(arguments, true, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 ) { + this.appendChild( elem ); + } + }); + }, + + prepend: function() { + return this.domManip(arguments, true, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 ) { + this.insertBefore( elem, this.firstChild ); + } + }); + }, + + before: function() { + if ( !isDisconnected( this[0] ) ) { + return this.domManip(arguments, false, function( elem ) { + this.parentNode.insertBefore( elem, this ); + }); + } + + if ( arguments.length ) { + var set = jQuery.clean( arguments ); + return this.pushStack( jQuery.merge( set, this ), "before", this.selector ); + } + }, + + after: function() { + if ( !isDisconnected( this[0] ) ) { + return this.domManip(arguments, false, function( elem ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + }); + } + + if ( arguments.length ) { + var set = jQuery.clean( arguments ); + return this.pushStack( jQuery.merge( this, set ), "after", this.selector ); + } + }, + + // keepData is for internal use only--do not document + remove: function( selector, keepData ) { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + if ( !selector || jQuery.filter( selector, [ elem ] ).length ) { + if ( !keepData && elem.nodeType === 1 ) { + jQuery.cleanData( elem.getElementsByTagName("*") ); + jQuery.cleanData( [ elem ] ); + } + + if ( elem.parentNode ) { + elem.parentNode.removeChild( elem ); + } + } + } + + return this; + }, + + empty: function() { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( elem.getElementsByTagName("*") ); + } + + // Remove any remaining nodes + while ( elem.firstChild ) { + elem.removeChild( elem.firstChild ); + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function () { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + }); + }, + + html: function( value ) { + return jQuery.access( this, function( value ) { + var elem = this[0] || {}, + i = 0, + l = this.length; + + if ( value === undefined ) { + return elem.nodeType === 1 ? + elem.innerHTML.replace( rinlinejQuery, "" ) : + undefined; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + ( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) ) && + ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && + !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) { + + value = value.replace( rxhtmlTag, "<$1></$2>" ); + + try { + for (; i < l; i++ ) { + // Remove element nodes and prevent memory leaks + elem = this[i] || {}; + if ( elem.nodeType === 1 ) { + jQuery.cleanData( elem.getElementsByTagName( "*" ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch(e) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function( value ) { + if ( !isDisconnected( this[0] ) ) { + // Make sure that the elements are removed from the DOM before they are inserted + // this can help fix replacing a parent with child elements + if ( jQuery.isFunction( value ) ) { + return this.each(function(i) { + var self = jQuery(this), old = self.html(); + self.replaceWith( value.call( this, i, old ) ); + }); + } + + if ( typeof value !== "string" ) { + value = jQuery( value ).detach(); + } + + return this.each(function() { + var next = this.nextSibling, + parent = this.parentNode; + + jQuery( this ).remove(); + + if ( next ) { + jQuery(next).before( value ); + } else { + jQuery(parent).append( value ); + } + }); + } + + return this.length ? + this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) : + this; + }, + + detach: function( selector ) { + return this.remove( selector, true ); + }, + + domManip: function( args, table, callback ) { + + // Flatten any nested arrays + args = [].concat.apply( [], args ); + + var results, first, fragment, iNoClone, + i = 0, + value = args[0], + scripts = [], + l = this.length; + + // We can't cloneNode fragments that contain checked, in WebKit + if ( !jQuery.support.checkClone && l > 1 && typeof value === "string" && rchecked.test( value ) ) { + return this.each(function() { + jQuery(this).domManip( args, table, callback ); + }); + } + + if ( jQuery.isFunction(value) ) { + return this.each(function(i) { + var self = jQuery(this); + args[0] = value.call( this, i, table ? self.html() : undefined ); + self.domManip( args, table, callback ); + }); + } + + if ( this[0] ) { + results = jQuery.buildFragment( args, this, scripts ); + fragment = results.fragment; + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + if ( first ) { + table = table && jQuery.nodeName( first, "tr" ); + + // Use the original fragment for the last item instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + // Fragments from the fragment cache must always be cloned and never used in place. + for ( iNoClone = results.cacheable || l - 1; i < l; i++ ) { + callback.call( + table && jQuery.nodeName( this[i], "table" ) ? + findOrAppend( this[i], "tbody" ) : + this[i], + i === iNoClone ? + fragment : + jQuery.clone( fragment, true, true ) + ); + } + } + + // Fix #11809: Avoid leaking memory + fragment = first = null; + + if ( scripts.length ) { + jQuery.each( scripts, function( i, elem ) { + if ( elem.src ) { + if ( jQuery.ajax ) { + jQuery.ajax({ + url: elem.src, + type: "GET", + dataType: "script", + async: false, + global: false, + "throws": true + }); + } else { + jQuery.error("no ajax"); + } + } else { + jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "" ) ); + } + + if ( elem.parentNode ) { + elem.parentNode.removeChild( elem ); + } + }); + } + } + + return this; + } +}); + +function findOrAppend( elem, tag ) { + return elem.getElementsByTagName( tag )[0] || elem.appendChild( elem.ownerDocument.createElement( tag ) ); +} + +function cloneCopyEvent( src, dest ) { + + if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { + return; + } + + var type, i, l, + oldData = jQuery._data( src ), + curData = jQuery._data( dest, oldData ), + events = oldData.events; + + if ( events ) { + delete curData.handle; + curData.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + + // make the cloned public data object a copy from the original + if ( curData.data ) { + curData.data = jQuery.extend( {}, curData.data ); + } +} + +function cloneFixAttributes( src, dest ) { + var nodeName; + + // We do not need to do anything for non-Elements + if ( dest.nodeType !== 1 ) { + return; + } + + // clearAttributes removes the attributes, which we don't want, + // but also removes the attachEvent events, which we *do* want + if ( dest.clearAttributes ) { + dest.clearAttributes(); + } + + // mergeAttributes, in contrast, only merges back on the + // original attributes, not the events + if ( dest.mergeAttributes ) { + dest.mergeAttributes( src ); + } + + nodeName = dest.nodeName.toLowerCase(); + + if ( nodeName === "object" ) { + // IE6-10 improperly clones children of object elements using classid. + // IE10 throws NoModificationAllowedError if parent is null, #12132. + if ( dest.parentNode ) { + dest.outerHTML = src.outerHTML; + } + + // This path appears unavoidable for IE9. When cloning an object + // element in IE9, the outerHTML strategy above is not sufficient. + // If the src has innerHTML and the destination does not, + // copy the src.innerHTML into the dest.innerHTML. #10324 + if ( jQuery.support.html5Clone && (src.innerHTML && !jQuery.trim(dest.innerHTML)) ) { + dest.innerHTML = src.innerHTML; + } + + } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + // IE6-8 fails to persist the checked state of a cloned checkbox + // or radio button. Worse, IE6-7 fail to give the cloned element + // a checked appearance if the defaultChecked value isn't also set + + dest.defaultChecked = dest.checked = src.checked; + + // IE6-7 get confused and end up setting the value of a cloned + // checkbox/radio button to an empty string instead of "on" + if ( dest.value !== src.value ) { + dest.value = src.value; + } + + // IE6-8 fails to return the selected option to the default selected + // state when cloning options + } else if ( nodeName === "option" ) { + dest.selected = src.defaultSelected; + + // IE6-8 fails to set the defaultValue to the correct value when + // cloning other types of input fields + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + + // IE blanks contents when cloning scripts + } else if ( nodeName === "script" && dest.text !== src.text ) { + dest.text = src.text; + } + + // Event data gets referenced instead of copied if the expando + // gets copied too + dest.removeAttribute( jQuery.expando ); +} + +jQuery.buildFragment = function( args, context, scripts ) { + var fragment, cacheable, cachehit, + first = args[ 0 ]; + + // Set context from what may come in as undefined or a jQuery collection or a node + // Updated to fix #12266 where accessing context[0] could throw an exception in IE9/10 & + // also doubles as fix for #8950 where plain objects caused createDocumentFragment exception + context = context || document; + context = !context.nodeType && context[0] || context; + context = context.ownerDocument || context; + + // Only cache "small" (1/2 KB) HTML strings that are associated with the main document + // Cloning options loses the selected state, so don't cache them + // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment + // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache + // Lastly, IE6,7,8 will not correctly reuse cached fragments that were created from unknown elems #10501 + if ( args.length === 1 && typeof first === "string" && first.length < 512 && context === document && + first.charAt(0) === "<" && !rnocache.test( first ) && + (jQuery.support.checkClone || !rchecked.test( first )) && + (jQuery.support.html5Clone || !rnoshimcache.test( first )) ) { + + // Mark cacheable and look for a hit + cacheable = true; + fragment = jQuery.fragments[ first ]; + cachehit = fragment !== undefined; + } + + if ( !fragment ) { + fragment = context.createDocumentFragment(); + jQuery.clean( args, context, fragment, scripts ); + + // Update the cache, but only store false + // unless this is a second parsing of the same content + if ( cacheable ) { + jQuery.fragments[ first ] = cachehit && fragment; + } + } + + return { fragment: fragment, cacheable: cacheable }; +}; + +jQuery.fragments = {}; + +jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + i = 0, + ret = [], + insert = jQuery( selector ), + l = insert.length, + parent = this.length === 1 && this[0].parentNode; + + if ( (parent == null || parent && parent.nodeType === 11 && parent.childNodes.length === 1) && l === 1 ) { + insert[ original ]( this[0] ); + return this; + } else { + for ( ; i < l; i++ ) { + elems = ( i > 0 ? this.clone(true) : this ).get(); + jQuery( insert[i] )[ original ]( elems ); + ret = ret.concat( elems ); + } + + return this.pushStack( ret, name, insert.selector ); + } + }; +}); + +function getAll( elem ) { + if ( typeof elem.getElementsByTagName !== "undefined" ) { + return elem.getElementsByTagName( "*" ); + + } else if ( typeof elem.querySelectorAll !== "undefined" ) { + return elem.querySelectorAll( "*" ); + + } else { + return []; + } +} + +// Used in clean, fixes the defaultChecked property +function fixDefaultChecked( elem ) { + if ( rcheckableType.test( elem.type ) ) { + elem.defaultChecked = elem.checked; + } +} + +jQuery.extend({ + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var srcElements, + destElements, + i, + clone; + + if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { + clone = elem.cloneNode( true ); + + // IE<=8 does not properly clone detached, unknown element nodes + } else { + fragmentDiv.innerHTML = elem.outerHTML; + fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); + } + + if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) && + (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { + // IE copies events bound via attachEvent when using cloneNode. + // Calling detachEvent on the clone will also remove the events + // from the original. In order to get around this, we use some + // proprietary methods to clear the events. Thanks to MooTools + // guys for this hotness. + + cloneFixAttributes( elem, clone ); + + // Using Sizzle here is crazy slow, so we use getElementsByTagName instead + srcElements = getAll( elem ); + destElements = getAll( clone ); + + // Weird iteration because IE will replace the length property + // with an element if you are cloning the body and one of the + // elements on the page has a name or id of "length" + for ( i = 0; srcElements[i]; ++i ) { + // Ensure that the destination node is not null; Fixes #9587 + if ( destElements[i] ) { + cloneFixAttributes( srcElements[i], destElements[i] ); + } + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + cloneCopyEvent( elem, clone ); + + if ( deepDataAndEvents ) { + srcElements = getAll( elem ); + destElements = getAll( clone ); + + for ( i = 0; srcElements[i]; ++i ) { + cloneCopyEvent( srcElements[i], destElements[i] ); + } + } + } + + srcElements = destElements = null; + + // Return the cloned set + return clone; + }, + + clean: function( elems, context, fragment, scripts ) { + var i, j, elem, tag, wrap, depth, div, hasBody, tbody, len, handleScript, jsTags, + safe = context === document && safeFragment, + ret = []; + + // Ensure that context is a document + if ( !context || typeof context.createDocumentFragment === "undefined" ) { + context = document; + } + + // Use the already-created safe fragment if context permits + for ( i = 0; (elem = elems[i]) != null; i++ ) { + if ( typeof elem === "number" ) { + elem += ""; + } + + if ( !elem ) { + continue; + } + + // Convert html string into DOM nodes + if ( typeof elem === "string" ) { + if ( !rhtml.test( elem ) ) { + elem = context.createTextNode( elem ); + } else { + // Ensure a safe container in which to render the html + safe = safe || createSafeFragment( context ); + div = context.createElement("div"); + safe.appendChild( div ); + + // Fix "XHTML"-style tags in all browsers + elem = elem.replace(rxhtmlTag, "<$1></$2>"); + + // Go to html and back, then peel off extra wrappers + tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + depth = wrap[0]; + div.innerHTML = wrap[1] + elem + wrap[2]; + + // Move to the right depth + while ( depth-- ) { + div = div.lastChild; + } + + // Remove IE's autoinserted <tbody> from table fragments + if ( !jQuery.support.tbody ) { + + // String was a <table>, *may* have spurious <tbody> + hasBody = rtbody.test(elem); + tbody = tag === "table" && !hasBody ? + div.firstChild && div.firstChild.childNodes : + + // String was a bare <thead> or <tfoot> + wrap[1] === "<table>" && !hasBody ? + div.childNodes : + []; + + for ( j = tbody.length - 1; j >= 0 ; --j ) { + if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) { + tbody[ j ].parentNode.removeChild( tbody[ j ] ); + } + } + } + + // IE completely kills leading whitespace when innerHTML is used + if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { + div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild ); + } + + elem = div.childNodes; + + // Take out of fragment container (we need a fresh div each time) + div.parentNode.removeChild( div ); + } + } + + if ( elem.nodeType ) { + ret.push( elem ); + } else { + jQuery.merge( ret, elem ); + } + } + + // Fix #11356: Clear elements from safeFragment + if ( div ) { + elem = div = safe = null; + } + + // Reset defaultChecked for any radios and checkboxes + // about to be appended to the DOM in IE 6/7 (#8060) + if ( !jQuery.support.appendChecked ) { + for ( i = 0; (elem = ret[i]) != null; i++ ) { + if ( jQuery.nodeName( elem, "input" ) ) { + fixDefaultChecked( elem ); + } else if ( typeof elem.getElementsByTagName !== "undefined" ) { + jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked ); + } + } + } + + // Append elements to a provided document fragment + if ( fragment ) { + // Special handling of each script element + handleScript = function( elem ) { + // Check if we consider it executable + if ( !elem.type || rscriptType.test( elem.type ) ) { + // Detach the script and store it in the scripts array (if provided) or the fragment + // Return truthy to indicate that it has been handled + return scripts ? + scripts.push( elem.parentNode ? elem.parentNode.removeChild( elem ) : elem ) : + fragment.appendChild( elem ); + } + }; + + for ( i = 0; (elem = ret[i]) != null; i++ ) { + // Check if we're done after handling an executable script + if ( !( jQuery.nodeName( elem, "script" ) && handleScript( elem ) ) ) { + // Append to fragment and handle embedded scripts + fragment.appendChild( elem ); + if ( typeof elem.getElementsByTagName !== "undefined" ) { + // handleScript alters the DOM, so use jQuery.merge to ensure snapshot iteration + jsTags = jQuery.grep( jQuery.merge( [], elem.getElementsByTagName("script") ), handleScript ); + + // Splice the scripts into ret after their former ancestor and advance our index beyond them + ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) ); + i += jsTags.length; + } + } + } + } + + return ret; + }, + + cleanData: function( elems, /* internal */ acceptData ) { + var data, id, elem, type, + i = 0, + internalKey = jQuery.expando, + cache = jQuery.cache, + deleteExpando = jQuery.support.deleteExpando, + special = jQuery.event.special; + + for ( ; (elem = elems[i]) != null; i++ ) { + + if ( acceptData || jQuery.acceptData( elem ) ) { + + id = elem[ internalKey ]; + data = id && cache[ id ]; + + if ( data ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Remove cache only if it was not already removed by jQuery.event.remove + if ( cache[ id ] ) { + + delete cache[ id ]; + + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( deleteExpando ) { + delete elem[ internalKey ]; + + } else if ( elem.removeAttribute ) { + elem.removeAttribute( internalKey ); + + } else { + elem[ internalKey ] = null; + } + + jQuery.deletedIds.push( id ); + } + } + } + } + } +}); +// Limit scope pollution from any deprecated API +(function() { + +var matched, browser; + +// Use of jQuery.browser is frowned upon. +// More details: http://api.jquery.com/jQuery.browser +// jQuery.uaMatch maintained for back-compat +jQuery.uaMatch = function( ua ) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) || + /(webkit)[ \/]([\w.]+)/.exec( ua ) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) || + /(msie) ([\w.]+)/.exec( ua ) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; +}; + +matched = jQuery.uaMatch( navigator.userAgent ); +browser = {}; + +if ( matched.browser ) { + browser[ matched.browser ] = true; + browser.version = matched.version; +} + +// Chrome is Webkit, but Webkit is also Safari. +if ( browser.chrome ) { + browser.webkit = true; +} else if ( browser.webkit ) { + browser.safari = true; +} + +jQuery.browser = browser; + +jQuery.sub = function() { + function jQuerySub( selector, context ) { + return new jQuerySub.fn.init( selector, context ); + } + jQuery.extend( true, jQuerySub, this ); + jQuerySub.superclass = this; + jQuerySub.fn = jQuerySub.prototype = this(); + jQuerySub.fn.constructor = jQuerySub; + jQuerySub.sub = this.sub; + jQuerySub.fn.init = function init( selector, context ) { + if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { + context = jQuerySub( context ); + } + + return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); + }; + jQuerySub.fn.init.prototype = jQuerySub.fn; + var rootjQuerySub = jQuerySub(document); + return jQuerySub; +}; + +})(); +var curCSS, iframe, iframeDoc, + ralpha = /alpha\([^)]*\)/i, + ropacity = /opacity=([^)]*)/, + rposition = /^(top|right|bottom|left)$/, + // swappable if display is none or starts with table except "table", "table-cell", or "table-caption" + // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rmargin = /^margin/, + rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ), + rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ), + rrelNum = new RegExp( "^([-+])=(" + core_pnum + ")", "i" ), + elemdisplay = { BODY: "block" }, + + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: 0, + fontWeight: 400 + }, + + cssExpand = [ "Top", "Right", "Bottom", "Left" ], + cssPrefixes = [ "Webkit", "O", "Moz", "ms" ], + + eventsToggle = jQuery.fn.toggle; + +// return a css property mapped to a potentially vendor prefixed property +function vendorPropName( style, name ) { + + // shortcut for names that are not vendor prefixed + if ( name in style ) { + return name; + } + + // check for vendor prefixed names + var capName = name.charAt(0).toUpperCase() + name.slice(1), + origName = name, + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in style ) { + return name; + } + } + + return origName; +} + +function isHidden( elem, el ) { + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); +} + +function showHide( elements, show ) { + var elem, display, + values = [], + index = 0, + length = elements.length; + + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + values[ index ] = jQuery._data( elem, "olddisplay" ); + if ( show ) { + // Reset the inline display of this element to learn if it is + // being hidden by cascaded rules or not + if ( !values[ index ] && elem.style.display === "none" ) { + elem.style.display = ""; + } + + // Set elements which have been overridden with display: none + // in a stylesheet to whatever the default browser style is + // for such an element + if ( elem.style.display === "" && isHidden( elem ) ) { + values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) ); + } + } else { + display = curCSS( elem, "display" ); + + if ( !values[ index ] && display !== "none" ) { + jQuery._data( elem, "olddisplay", display ); + } + } + } + + // Set the display of most of the elements in a second loop + // to avoid the constant reflow + for ( index = 0; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + if ( !show || elem.style.display === "none" || elem.style.display === "" ) { + elem.style.display = show ? values[ index ] || "" : "none"; + } + } + + return elements; +} + +jQuery.fn.extend({ + css: function( name, value ) { + return jQuery.access( this, function( elem, name, value ) { + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + }, + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state, fn2 ) { + var bool = typeof state === "boolean"; + + if ( jQuery.isFunction( state ) && jQuery.isFunction( fn2 ) ) { + return eventsToggle.apply( this, arguments ); + } + + return this.each(function() { + if ( bool ? state : isHidden( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + }); + } +}); + +jQuery.extend({ + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + + } + } + } + }, + + // Exclude the following css properties to add px + cssNumber: { + "fillOpacity": true, + "fontWeight": true, + "lineHeight": true, + "opacity": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: { + // normalize float css property + "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat" + }, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = jQuery.camelCase( name ), + style = elem.style; + + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // convert relative number strings (+= or -=) to relative numbers. #7345 + if ( type === "string" && (ret = rrelNum.exec( value )) ) { + value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) ); + // Fixes bug #9237 + type = "number"; + } + + // Make sure that NaN and null values aren't set. See: #7116 + if ( value == null || type === "number" && isNaN( value ) ) { + return; + } + + // If a number was passed in, add 'px' to the (except for certain CSS properties) + if ( type === "number" && !jQuery.cssNumber[ origName ] ) { + value += "px"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) { + // Wrapped to prevent IE from throwing errors when 'invalid' values are provided + // Fixes bug #5509 + try { + style[ name ] = value; + } catch(e) {} + } + + } else { + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, numeric, extra ) { + var val, num, hooks, + origName = jQuery.camelCase( name ); + + // Make sure that we're working with the right name + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name ); + } + + //convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Return, converting to number if forced or a qualifier was provided and val looks numeric + if ( numeric || extra !== undefined ) { + num = parseFloat( val ); + return numeric || jQuery.isNumeric( num ) ? num || 0 : val; + } + return val; + }, + + // A method for quickly swapping in/out CSS properties to get correct calculations + swap: function( elem, options, callback ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.call( elem ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; + } +}); + +// NOTE: To any future maintainer, we've window.getComputedStyle +// because jsdom on node.js will break without it. +if ( window.getComputedStyle ) { + curCSS = function( elem, name ) { + var ret, width, minWidth, maxWidth, + computed = window.getComputedStyle( elem, null ), + style = elem.style; + + if ( computed ) { + + // getPropertyValue is only needed for .css('filter') in IE9, see #12537 + ret = computed.getPropertyValue( name ) || computed[ name ]; + + if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right + // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels + // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values + if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) { + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret; + }; +} else if ( document.documentElement.currentStyle ) { + curCSS = function( elem, name ) { + var left, rsLeft, + ret = elem.currentStyle && elem.currentStyle[ name ], + style = elem.style; + + // Avoid setting ret to empty string here + // so we don't default to auto + if ( ret == null && style && style[ name ] ) { + ret = style[ name ]; + } + + // From the awesome hack by Dean Edwards + // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 + + // If we're not dealing with a regular pixel number + // but a number that has a weird ending, we need to convert it to pixels + // but not position css attributes, as those are proportional to the parent element instead + // and we can't measure the parent instead because it might trigger a "stacking dolls" problem + if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) { + + // Remember the original values + left = style.left; + rsLeft = elem.runtimeStyle && elem.runtimeStyle.left; + + // Put in the new values to get a computed value out + if ( rsLeft ) { + elem.runtimeStyle.left = elem.currentStyle.left; + } + style.left = name === "fontSize" ? "1em" : ret; + ret = style.pixelLeft + "px"; + + // Revert the changed values + style.left = left; + if ( rsLeft ) { + elem.runtimeStyle.left = rsLeft; + } + } + + return ret === "" ? "auto" : ret; + }; +} + +function setPositiveNumber( elem, value, subtract ) { + var matches = rnumsplit.exec( value ); + return matches ? + Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) : + value; +} + +function augmentWidthOrHeight( elem, name, extra, isBorderBox ) { + var i = extra === ( isBorderBox ? "border" : "content" ) ? + // If we already have the right measurement, avoid augmentation + 4 : + // Otherwise initialize for horizontal or vertical properties + name === "width" ? 1 : 0, + + val = 0; + + for ( ; i < 4; i += 2 ) { + // both box models exclude margin, so add it if we want it + if ( extra === "margin" ) { + // we use jQuery.css instead of curCSS here + // because of the reliableMarginRight CSS hook! + val += jQuery.css( elem, extra + cssExpand[ i ], true ); + } + + // From this point on we use curCSS for maximum performance (relevant in animations) + if ( isBorderBox ) { + // border-box includes padding, so remove it if we want content + if ( extra === "content" ) { + val -= parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0; + } + + // at this point, extra isn't border nor margin, so remove border + if ( extra !== "margin" ) { + val -= parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0; + } + } else { + // at this point, extra isn't content, so add padding + val += parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0; + + // at this point, extra isn't content nor padding, so add border + if ( extra !== "padding" ) { + val += parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0; + } + } + } + + return val; +} + +function getWidthOrHeight( elem, name, extra ) { + + // Start with offset property, which is equivalent to the border-box value + var val = name === "width" ? elem.offsetWidth : elem.offsetHeight, + valueIsBorderBox = true, + isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box"; + + // some non-html elements return undefined for offsetWidth, so check for null/undefined + // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 + // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 + if ( val <= 0 || val == null ) { + // Fall back to computed then uncomputed css if necessary + val = curCSS( elem, name ); + if ( val < 0 || val == null ) { + val = elem.style[ name ]; + } + + // Computed unit is not pixels. Stop here and return. + if ( rnumnonpx.test(val) ) { + return val; + } + + // we need the check for style in case a browser which returns unreliable values + // for getComputedStyle silently falls back to the reliable elem.style + valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] ); + + // Normalize "", auto, and prepare for extra + val = parseFloat( val ) || 0; + } + + // use the active box-sizing model to add/subtract irrelevant styles + return ( val + + augmentWidthOrHeight( + elem, + name, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox + ) + ) + "px"; +} + + +// Try to determine the default display value of an element +function css_defaultDisplay( nodeName ) { + if ( elemdisplay[ nodeName ] ) { + return elemdisplay[ nodeName ]; + } + + var elem = jQuery( "<" + nodeName + ">" ).appendTo( document.body ), + display = elem.css("display"); + elem.remove(); + + // If the simple way fails, + // get element's real default display by attaching it to a temp iframe + if ( display === "none" || display === "" ) { + // Use the already-created iframe if possible + iframe = document.body.appendChild( + iframe || jQuery.extend( document.createElement("iframe"), { + frameBorder: 0, + width: 0, + height: 0 + }) + ); + + // Create a cacheable copy of the iframe document on first call. + // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML + // document to it; WebKit & Firefox won't allow reusing the iframe document. + if ( !iframeDoc || !iframe.createElement ) { + iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document; + iframeDoc.write("<!doctype html><html><body>"); + iframeDoc.close(); + } + + elem = iframeDoc.body.appendChild( iframeDoc.createElement(nodeName) ); + + display = curCSS( elem, "display" ); + document.body.removeChild( iframe ); + } + + // Store the correct default display + elemdisplay[ nodeName ] = display; + + return display; +} + +jQuery.each([ "height", "width" ], function( i, name ) { + jQuery.cssHooks[ name ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + // certain elements can have dimension info if we invisibly show them + // however, it must have a current display style that would benefit from this + if ( elem.offsetWidth === 0 && rdisplayswap.test( curCSS( elem, "display" ) ) ) { + return jQuery.swap( elem, cssShow, function() { + return getWidthOrHeight( elem, name, extra ); + }); + } else { + return getWidthOrHeight( elem, name, extra ); + } + } + }, + + set: function( elem, value, extra ) { + return setPositiveNumber( elem, value, extra ? + augmentWidthOrHeight( + elem, + name, + extra, + jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box" + ) : 0 + ); + } + }; +}); + +if ( !jQuery.support.opacity ) { + jQuery.cssHooks.opacity = { + get: function( elem, computed ) { + // IE uses filters for opacity + return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ? + ( 0.01 * parseFloat( RegExp.$1 ) ) + "" : + computed ? "1" : ""; + }, + + set: function( elem, value ) { + var style = elem.style, + currentStyle = elem.currentStyle, + opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "", + filter = currentStyle && currentStyle.filter || style.filter || ""; + + // IE has trouble with opacity if it does not have layout + // Force it by setting the zoom level + style.zoom = 1; + + // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652 + if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" && + style.removeAttribute ) { + + // Setting style.filter to null, "" & " " still leave "filter:" in the cssText + // if "filter:" is present at all, clearType is disabled, we want to avoid this + // style.removeAttribute is IE Only, but so apparently is this code path... + style.removeAttribute( "filter" ); + + // if there there is no filter style applied in a css rule, we are done + if ( currentStyle && !currentStyle.filter ) { + return; + } + } + + // otherwise, set new filter values + style.filter = ralpha.test( filter ) ? + filter.replace( ralpha, opacity ) : + filter + " " + opacity; + } + }; +} + +// These hooks cannot be added until DOM ready because the support test +// for it is not run until after DOM ready +jQuery(function() { + if ( !jQuery.support.reliableMarginRight ) { + jQuery.cssHooks.marginRight = { + get: function( elem, computed ) { + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + // Work around by temporarily setting element display to inline-block + return jQuery.swap( elem, { "display": "inline-block" }, function() { + if ( computed ) { + return curCSS( elem, "marginRight" ); + } + }); + } + }; + } + + // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 + // getComputedStyle returns percent when specified for top/left/bottom/right + // rather than make the css module depend on the offset module, we just check for it here + if ( !jQuery.support.pixelPosition && jQuery.fn.position ) { + jQuery.each( [ "top", "left" ], function( i, prop ) { + jQuery.cssHooks[ prop ] = { + get: function( elem, computed ) { + if ( computed ) { + var ret = curCSS( elem, prop ); + // if curCSS returns percentage, fallback to offset + return rnumnonpx.test( ret ) ? jQuery( elem ).position()[ prop ] + "px" : ret; + } + } + }; + }); + } + +}); + +if ( jQuery.expr && jQuery.expr.filters ) { + jQuery.expr.filters.hidden = function( elem ) { + return ( elem.offsetWidth === 0 && elem.offsetHeight === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || curCSS( elem, "display" )) === "none"); + }; + + jQuery.expr.filters.visible = function( elem ) { + return !jQuery.expr.filters.hidden( elem ); + }; +} + +// These hooks are used by animate to expand properties +jQuery.each({ + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i, + + // assumes a single number if not a string + parts = typeof value === "string" ? value.split(" ") : [ value ], + expanded = {}; + + for ( i = 0; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( !rmargin.test( prefix ) ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +}); +var r20 = /%20/g, + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i, + rselectTextarea = /^(?:select|textarea)/i; + +jQuery.fn.extend({ + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map(function(){ + return this.elements ? jQuery.makeArray( this.elements ) : this; + }) + .filter(function(){ + return this.name && !this.disabled && + ( this.checked || rselectTextarea.test( this.nodeName ) || + rinput.test( this.type ) ); + }) + .map(function( i, elem ){ + var val = jQuery( this ).val(); + + return val == null ? + null : + jQuery.isArray( val ) ? + jQuery.map( val, function( val, i ){ + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + }) : + { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + }).get(); + } +}); + +//Serialize an array of form elements or a set of +//key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, value ) { + // If value is a function, invoke it and return its value + value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value ); + s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value ); + }; + + // Set traditional to true for jQuery <= 1.3.2 behavior. + if ( traditional === undefined ) { + traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional; + } + + // If an array was passed in, assume that it is an array of form elements. + if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + }); + + } else { + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ).replace( r20, "+" ); +}; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( jQuery.isArray( obj ) ) { + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + // If array item is non-scalar (array or object), encode its + // numeric index to resolve deserialization ambiguity issues. + // Note that rack (as of 1.0.0) can't currently deserialize + // nested arrays properly, and attempting to do so may cause + // a server error. Possible fixes are to modify rack's + // deserialization algorithm or to provide an option or flag + // to force array serialization to be shallow. + buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add ); + } + }); + + } else if ( !traditional && jQuery.type( obj ) === "object" ) { + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + // Serialize scalar item. + add( prefix, obj ); + } +} +var + // Document location + ajaxLocParts, + ajaxLocation, + + rhash = /#.*$/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + rquery = /\?/, + rscript = /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, + rts = /([?&])_=[^&]*/, + rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/, + + // Keep a copy of the old load method + _load = jQuery.fn.load, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = ["*/"] + ["*"]; + +// #8138, IE may throw an exception when accessing +// a field from window.location if document.domain has been set +try { + ajaxLocation = location.href; +} catch( e ) { + // Use the href attribute of an A element + // since IE will modify it given document.location + ajaxLocation = document.createElement( "a" ); + ajaxLocation.href = ""; + ajaxLocation = ajaxLocation.href; +} + +// Segment location into parts +ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || []; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, list, placeBefore, + dataTypes = dataTypeExpression.toLowerCase().split( core_rspace ), + i = 0, + length = dataTypes.length; + + if ( jQuery.isFunction( func ) ) { + // For each dataType in the dataTypeExpression + for ( ; i < length; i++ ) { + dataType = dataTypes[ i ]; + // We control if we're asked to add before + // any existing element + placeBefore = /^\+/.test( dataType ); + if ( placeBefore ) { + dataType = dataType.substr( 1 ) || "*"; + } + list = structure[ dataType ] = structure[ dataType ] || []; + // then we add to the structure accordingly + list[ placeBefore ? "unshift" : "push" ]( func ); + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR, + dataType /* internal */, inspected /* internal */ ) { + + dataType = dataType || options.dataTypes[ 0 ]; + inspected = inspected || {}; + + inspected[ dataType ] = true; + + var selection, + list = structure[ dataType ], + i = 0, + length = list ? list.length : 0, + executeOnly = ( structure === prefilters ); + + for ( ; i < length && ( executeOnly || !selection ); i++ ) { + selection = list[ i ]( options, originalOptions, jqXHR ); + // If we got redirected to another dataType + // we try there if executing only and not done already + if ( typeof selection === "string" ) { + if ( !executeOnly || inspected[ selection ] ) { + selection = undefined; + } else { + options.dataTypes.unshift( selection ); + selection = inspectPrefiltersOrTransports( + structure, options, originalOptions, jqXHR, selection, inspected ); + } + } + } + // If we're only executing or nothing was selected + // we try the catchall dataType if not done already + if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) { + selection = inspectPrefiltersOrTransports( + structure, options, originalOptions, jqXHR, "*", inspected ); + } + // unnecessary when only executing (prefilters) + // but it'll be ignored by the caller in that case + return selection; +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } +} + +jQuery.fn.load = function( url, params, callback ) { + if ( typeof url !== "string" && _load ) { + return _load.apply( this, arguments ); + } + + // Don't do a request if no elements are being requested + if ( !this.length ) { + return this; + } + + var selector, type, response, + self = this, + off = url.indexOf(" "); + + if ( off >= 0 ) { + selector = url.slice( off, url.length ); + url = url.slice( 0, off ); + } + + // If it's a function + if ( jQuery.isFunction( params ) ) { + + // We assume that it's the callback + callback = params; + params = undefined; + + // Otherwise, build a param string + } else if ( params && typeof params === "object" ) { + type = "POST"; + } + + // Request the remote document + jQuery.ajax({ + url: url, + + // if "type" variable is undefined, then "GET" method will be used + type: type, + dataType: "html", + data: params, + complete: function( jqXHR, status ) { + if ( callback ) { + self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] ); + } + } + }).done(function( responseText ) { + + // Save response for use in complete callback + response = arguments; + + // See if a selector was specified + self.html( selector ? + + // Create a dummy div to hold the results + jQuery("<div>") + + // inject the contents of the document in, removing the scripts + // to avoid any 'Permission Denied' errors in IE + .append( responseText.replace( rscript, "" ) ) + + // Locate the specified elements + .find( selector ) : + + // If not, just inject the full result + responseText ); + + }); + + return this; +}; + +// Attach a bunch of functions for handling common AJAX events +jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){ + jQuery.fn[ o ] = function( f ){ + return this.on( o, f ); + }; +}); + +jQuery.each( [ "get", "post" ], function( i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + // shift arguments if data argument was omitted + if ( jQuery.isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + return jQuery.ajax({ + type: method, + url: url, + data: data, + success: callback, + dataType: type + }); + }; +}); + +jQuery.extend({ + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + if ( settings ) { + // Building a settings object + ajaxExtend( target, jQuery.ajaxSettings ); + } else { + // Extending ajaxSettings + settings = target; + target = jQuery.ajaxSettings; + } + ajaxExtend( target, settings ); + return target; + }, + + ajaxSettings: { + url: ajaxLocation, + isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ), + global: true, + type: "GET", + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + processData: true, + async: true, + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + xml: "application/xml, text/xml", + html: "text/html", + text: "text/plain", + json: "application/json, text/javascript", + "*": allTypes + }, + + contents: { + xml: /xml/, + html: /html/, + json: /json/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText" + }, + + // List of data converters + // 1) key format is "source_type destination_type" (a single space in-between) + // 2) the catchall symbol "*" can be used for source_type + converters: { + + // Convert anything to text + "* text": window.String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": jQuery.parseJSON, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + context: true, + url: true + } + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var // ifModified key + ifModifiedKey, + // Response headers + responseHeadersString, + responseHeaders, + // transport + transport, + // timeout handle + timeoutTimer, + // Cross-domain detection vars + parts, + // To know if global events are to be dispatched + fireGlobals, + // Loop variable + i, + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + // Callbacks context + callbackContext = s.context || s, + // Context for global events + // It's the callbackContext if one was provided in the options + // and if it's a DOM node or a jQuery collection + globalEventContext = callbackContext !== s && + ( callbackContext.nodeType || callbackContext instanceof jQuery ) ? + jQuery( callbackContext ) : jQuery.event, + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + // Status-dependent callbacks + statusCode = s.statusCode || {}, + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + // The jqXHR state + state = 0, + // Default abort message + strAbort = "canceled", + // Fake xhr + jqXHR = { + + readyState: 0, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( !state ) { + var lname = name.toLowerCase(); + name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Raw string + getAllResponseHeaders: function() { + return state === 2 ? responseHeadersString : null; + }, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( state === 2 ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[1].toLowerCase() ] = match[ 2 ]; + } + } + match = responseHeaders[ key.toLowerCase() ]; + } + return match === undefined ? null : match; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( !state ) { + s.mimeType = type; + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + statusText = statusText || strAbort; + if ( transport ) { + transport.abort( statusText ); + } + done( 0, statusText ); + return this; + } + }; + + // Callback for when everything is done + // It is defined here because jslint complains if it is declared + // at the end of the function (which would be more logical and readable) + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Called once + if ( state === 2 ) { + return; + } + + // State is "done" now + state = 2; + + // Clear timeout if it exists + if ( timeoutTimer ) { + clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // If successful, handle type chaining + if ( status >= 200 && status < 300 || status === 304 ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + + modified = jqXHR.getResponseHeader("Last-Modified"); + if ( modified ) { + jQuery.lastModified[ ifModifiedKey ] = modified; + } + modified = jqXHR.getResponseHeader("Etag"); + if ( modified ) { + jQuery.etag[ ifModifiedKey ] = modified; + } + } + + // If not modified + if ( status === 304 ) { + + statusText = "notmodified"; + isSuccess = true; + + // If we have data + } else { + + isSuccess = ajaxConvert( s, response ); + statusText = isSuccess.state; + success = isSuccess.data; + error = isSuccess.error; + isSuccess = !error; + } + } else { + // We extract error from statusText + // then normalize statusText and status for non-aborts + error = statusText; + if ( !statusText || status ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ), + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + // Attach deferreds + deferred.promise( jqXHR ); + jqXHR.success = jqXHR.done; + jqXHR.error = jqXHR.fail; + jqXHR.complete = completeDeferred.add; + + // Status-dependent callbacks + jqXHR.statusCode = function( map ) { + if ( map ) { + var tmp; + if ( state < 2 ) { + for ( tmp in map ) { + statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ]; + } + } else { + tmp = map[ jqXHR.status ]; + jqXHR.always( tmp ); + } + } + return this; + }; + + // Remove hash character (#7531: and string promotion) + // Add protocol if not provided (#5866: IE7 issue with protocol-less urls) + // We also use the url parameter if available + s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); + + // Extract dataTypes list + s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( core_rspace ); + + // A cross-domain request is in order when we have a protocol:host:port mismatch + if ( s.crossDomain == null ) { + parts = rurl.exec( s.url.toLowerCase() ); + s.crossDomain = !!( parts && + ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] || + ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) != + ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) ) + ); + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( state === 2 ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + fireGlobals = s.global; + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // If data is available, append data to url + if ( s.data ) { + s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data; + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Get ifModifiedKey before adding the anti-cache parameter + ifModifiedKey = s.url; + + // Add anti-cache in url if needed + if ( s.cache === false ) { + + var ts = jQuery.now(), + // try replacing _= if it is there + ret = s.url.replace( rts, "$1_=" + ts ); + + // if nothing was replaced, add timestamp to the end + s.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + ifModifiedKey = ifModifiedKey || s.url; + if ( jQuery.lastModified[ ifModifiedKey ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] ); + } + if ( jQuery.etag[ ifModifiedKey ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] ); + } + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ? + s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { + // Abort if not done already and return + return jqXHR.abort(); + + } + + // aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + for ( i in { success: 1, error: 1, complete: 1 } ) { + jqXHR[ i ]( s[ i ] ); + } + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = setTimeout( function(){ + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + state = 1; + transport.send( requestHeaders, done ); + } catch (e) { + // Propagate exception as error if not done + if ( state < 2 ) { + done( -1, e ); + // Simply rethrow otherwise + } else { + throw e; + } + } + } + + return jqXHR; + }, + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {} + +}); + +/* Handles responses to an ajax request: + * - sets all responseXXX fields accordingly + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes, + responseFields = s.responseFields; + + // Fill responseXXX fields + for ( type in responseFields ) { + if ( type in responses ) { + jqXHR[ responseFields[type] ] = responses[ type ]; + } + } + + // Remove auto dataType and get content-type in the process + while( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "content-type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +// Chain conversions given the request and the original response +function ajaxConvert( s, response ) { + + var conv, conv2, current, tmp, + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(), + prev = dataTypes[ 0 ], + converters = {}, + i = 0; + + // Apply the dataFilter if provided + if ( s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + // Convert to each sequential dataType, tolerating list modification + for ( ; (current = dataTypes[++i]); ) { + + // There's only work to do if current dataType is non-auto + if ( current !== "*" ) { + + // Convert response if prev dataType is non-auto and differs from current + if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split(" "); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.splice( i--, 0, current ); + } + + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s["throws"] ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current }; + } + } + } + } + + // Update prev for next iteration + prev = current; + } + } + + return { state: "success", data: response }; +} +var oldCallbacks = [], + rquestion = /\?/, + rjsonp = /(=)\?(?=&|$)|\?\?/, + nonce = jQuery.now(); + +// Default jsonp settings +jQuery.ajaxSetup({ + jsonp: "callback", + jsonpCallback: function() { + var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) ); + this[ callback ] = true; + return callback; + } +}); + +// Detect, normalize options and install callbacks for jsonp requests +jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { + + var callbackName, overwritten, responseContainer, + data = s.data, + url = s.url, + hasCallback = s.jsonp !== false, + replaceInUrl = hasCallback && rjsonp.test( url ), + replaceInData = hasCallback && !replaceInUrl && typeof data === "string" && + !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && + rjsonp.test( data ); + + // Handle iff the expected data type is "jsonp" or we have a parameter to set + if ( s.dataTypes[ 0 ] === "jsonp" || replaceInUrl || replaceInData ) { + + // Get callback name, remembering preexisting value associated with it + callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ? + s.jsonpCallback() : + s.jsonpCallback; + overwritten = window[ callbackName ]; + + // Insert callback into url or form data + if ( replaceInUrl ) { + s.url = url.replace( rjsonp, "$1" + callbackName ); + } else if ( replaceInData ) { + s.data = data.replace( rjsonp, "$1" + callbackName ); + } else if ( hasCallback ) { + s.url += ( rquestion.test( url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; + } + + // Use data converter to retrieve json after script execution + s.converters["script json"] = function() { + if ( !responseContainer ) { + jQuery.error( callbackName + " was not called" ); + } + return responseContainer[ 0 ]; + }; + + // force json dataType + s.dataTypes[ 0 ] = "json"; + + // Install callback + window[ callbackName ] = function() { + responseContainer = arguments; + }; + + // Clean-up function (fires after converters) + jqXHR.always(function() { + // Restore preexisting value + window[ callbackName ] = overwritten; + + // Save back as free + if ( s[ callbackName ] ) { + // make sure that re-using the options doesn't screw things around + s.jsonpCallback = originalSettings.jsonpCallback; + + // save the callback name for future use + oldCallbacks.push( callbackName ); + } + + // Call if it was a function and we have a response + if ( responseContainer && jQuery.isFunction( overwritten ) ) { + overwritten( responseContainer[ 0 ] ); + } + + responseContainer = overwritten = undefined; + }); + + // Delegate to script + return "script"; + } +}); +// Install script dataType +jQuery.ajaxSetup({ + accepts: { + script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /javascript|ecmascript/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +}); + +// Handle cache's special case and global +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + s.global = false; + } +}); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function(s) { + + // This transport only deals with cross domain requests + if ( s.crossDomain ) { + + var script, + head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement; + + return { + + send: function( _, callback ) { + + script = document.createElement( "script" ); + + script.async = "async"; + + if ( s.scriptCharset ) { + script.charset = s.scriptCharset; + } + + script.src = s.url; + + // Attach handlers for all browsers + script.onload = script.onreadystatechange = function( _, isAbort ) { + + if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) { + + // Handle memory leak in IE + script.onload = script.onreadystatechange = null; + + // Remove the script + if ( head && script.parentNode ) { + head.removeChild( script ); + } + + // Dereference the script + script = undefined; + + // Callback if not abort + if ( !isAbort ) { + callback( 200, "success" ); + } + } + }; + // Use insertBefore instead of appendChild to circumvent an IE6 bug. + // This arises when a base node is used (#2709 and #4378). + head.insertBefore( script, head.firstChild ); + }, + + abort: function() { + if ( script ) { + script.onload( 0, 1 ); + } + } + }; + } +}); +var xhrCallbacks, + // #5280: Internet Explorer will keep connections alive if we don't abort on unload + xhrOnUnloadAbort = window.ActiveXObject ? function() { + // Abort all pending requests + for ( var key in xhrCallbacks ) { + xhrCallbacks[ key ]( 0, 1 ); + } + } : false, + xhrId = 0; + +// Functions to create xhrs +function createStandardXHR() { + try { + return new window.XMLHttpRequest(); + } catch( e ) {} +} + +function createActiveXHR() { + try { + return new window.ActiveXObject( "Microsoft.XMLHTTP" ); + } catch( e ) {} +} + +// Create the request object +// (This is still attached to ajaxSettings for backward compatibility) +jQuery.ajaxSettings.xhr = window.ActiveXObject ? + /* Microsoft failed to properly + * implement the XMLHttpRequest in IE7 (can't request local files), + * so we use the ActiveXObject when it is available + * Additionally XMLHttpRequest can be disabled in IE7/IE8 so + * we need a fallback. + */ + function() { + return !this.isLocal && createStandardXHR() || createActiveXHR(); + } : + // For all other browsers, use the standard XMLHttpRequest object + createStandardXHR; + +// Determine support properties +(function( xhr ) { + jQuery.extend( jQuery.support, { + ajax: !!xhr, + cors: !!xhr && ( "withCredentials" in xhr ) + }); +})( jQuery.ajaxSettings.xhr() ); + +// Create transport if the browser can provide an xhr +if ( jQuery.support.ajax ) { + + jQuery.ajaxTransport(function( s ) { + // Cross domain only allowed if supported through XMLHttpRequest + if ( !s.crossDomain || jQuery.support.cors ) { + + var callback; + + return { + send: function( headers, complete ) { + + // Get a new xhr + var handle, i, + xhr = s.xhr(); + + // Open the socket + // Passing null username, generates a login popup on Opera (#2865) + if ( s.username ) { + xhr.open( s.type, s.url, s.async, s.username, s.password ); + } else { + xhr.open( s.type, s.url, s.async ); + } + + // Apply custom fields if provided + if ( s.xhrFields ) { + for ( i in s.xhrFields ) { + xhr[ i ] = s.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( s.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( s.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !s.crossDomain && !headers["X-Requested-With"] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Need an extra try/catch for cross domain requests in Firefox 3 + try { + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + } catch( _ ) {} + + // Do send the request + // This may raise an exception which is actually + // handled in jQuery.ajax (so no try/catch here) + xhr.send( ( s.hasContent && s.data ) || null ); + + // Listener + callback = function( _, isAbort ) { + + var status, + statusText, + responseHeaders, + responses, + xml; + + // Firefox throws exceptions when accessing properties + // of an xhr when a network error occurred + // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE) + try { + + // Was never called and is aborted or complete + if ( callback && ( isAbort || xhr.readyState === 4 ) ) { + + // Only called once + callback = undefined; + + // Do not keep as active anymore + if ( handle ) { + xhr.onreadystatechange = jQuery.noop; + if ( xhrOnUnloadAbort ) { + delete xhrCallbacks[ handle ]; + } + } + + // If it's an abort + if ( isAbort ) { + // Abort it manually if needed + if ( xhr.readyState !== 4 ) { + xhr.abort(); + } + } else { + status = xhr.status; + responseHeaders = xhr.getAllResponseHeaders(); + responses = {}; + xml = xhr.responseXML; + + // Construct response list + if ( xml && xml.documentElement /* #4958 */ ) { + responses.xml = xml; + } + + // When requesting binary data, IE6-9 will throw an exception + // on any attempt to access responseText (#11426) + try { + responses.text = xhr.responseText; + } catch( e ) { + } + + // Firefox throws an exception when accessing + // statusText for faulty cross-domain requests + try { + statusText = xhr.statusText; + } catch( e ) { + // We normalize with Webkit giving an empty statusText + statusText = ""; + } + + // Filter status for non standard behaviors + + // If the request is local and we have data: assume a success + // (success with no data won't get notified, that's the best we + // can do given current implementations) + if ( !status && s.isLocal && !s.crossDomain ) { + status = responses.text ? 200 : 404; + // IE - #1450: sometimes returns 1223 when it should be 204 + } else if ( status === 1223 ) { + status = 204; + } + } + } + } catch( firefoxAccessException ) { + if ( !isAbort ) { + complete( -1, firefoxAccessException ); + } + } + + // Call complete if needed + if ( responses ) { + complete( status, statusText, responses, responseHeaders ); + } + }; + + if ( !s.async ) { + // if we're in sync mode we fire the callback + callback(); + } else if ( xhr.readyState === 4 ) { + // (IE6 & IE7) if it's in cache and has been + // retrieved directly we need to fire the callback + setTimeout( callback, 0 ); + } else { + handle = ++xhrId; + if ( xhrOnUnloadAbort ) { + // Create the active xhrs callbacks list if needed + // and attach the unload handler + if ( !xhrCallbacks ) { + xhrCallbacks = {}; + jQuery( window ).unload( xhrOnUnloadAbort ); + } + // Add to list of active xhrs callbacks + xhrCallbacks[ handle ] = callback; + } + xhr.onreadystatechange = callback; + } + }, + + abort: function() { + if ( callback ) { + callback(0,1); + } + } + }; + } + }); +} +var fxNow, timerId, + rfxtypes = /^(?:toggle|show|hide)$/, + rfxnum = new RegExp( "^(?:([-+])=|)(" + core_pnum + ")([a-z%]*)$", "i" ), + rrun = /queueHooks$/, + animationPrefilters = [ defaultPrefilter ], + tweeners = { + "*": [function( prop, value ) { + var end, unit, + tween = this.createTween( prop, value ), + parts = rfxnum.exec( value ), + target = tween.cur(), + start = +target || 0, + scale = 1, + maxIterations = 20; + + if ( parts ) { + end = +parts[2]; + unit = parts[3] || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + + // We need to compute starting value + if ( unit !== "px" && start ) { + // Iteratively approximate from a nonzero starting point + // Prefer the current property, because this process will be trivial if it uses the same units + // Fallback to end or a simple constant + start = jQuery.css( tween.elem, prop, true ) || end || 1; + + do { + // If previous iteration zeroed out, double until we get *something* + // Use a string for doubling factor so we don't accidentally see scale as unchanged below + scale = scale || ".5"; + + // Adjust and apply + start = start / scale; + jQuery.style( tween.elem, prop, start + unit ); + + // Update scale, tolerating zero or NaN from tween.cur() + // And breaking the loop if scale is unchanged or perfect, or if we've just had enough + } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations ); + } + + tween.unit = unit; + tween.start = start; + // If a +=/-= token was provided, we're doing a relative animation + tween.end = parts[1] ? start + ( parts[1] + 1 ) * end : end; + } + return tween; + }] + }; + +// Animations created synchronously will run synchronously +function createFxNow() { + setTimeout(function() { + fxNow = undefined; + }, 0 ); + return ( fxNow = jQuery.now() ); +} + +function createTweens( animation, props ) { + jQuery.each( props, function( prop, value ) { + var collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( collection[ index ].call( animation, prop, value ) ) { + + // we're done with this property + return; + } + } + }); +} + +function Animation( elem, properties, options ) { + var result, + index = 0, + tweenerIndex = 0, + length = animationPrefilters.length, + deferred = jQuery.Deferred().always( function() { + // don't match elem in the :animated selector + delete tick.elem; + }), + tick = function() { + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length ; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ]); + + if ( percent < 1 && length ) { + return remaining; + } else { + deferred.resolveWith( elem, [ animation ] ); + return false; + } + }, + animation = deferred.promise({ + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { specialEasing: {} }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end, easing ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + // if we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + + for ( ; index < length ; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // resolve when we played the last frame + // otherwise, reject + if ( gotoEnd ) { + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + }), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length ; index++ ) { + result = animationPrefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + return result; + } + } + + createTweens( animation, props ); + + if ( jQuery.isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + jQuery.fx.timer( + jQuery.extend( tick, { + anim: animation, + queue: animation.opts.queue, + elem: elem + }) + ); + + // attach callbacks from options + return animation.progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = jQuery.camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( jQuery.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // not quite $.extend, this wont overwrite keys already present. + // also - reusing 'index' from above because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweener: function( props, callback ) { + if ( jQuery.isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.split(" "); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length ; index++ ) { + prop = props[ index ]; + tweeners[ prop ] = tweeners[ prop ] || []; + tweeners[ prop ].unshift( callback ); + } + }, + + prefilter: function( callback, prepend ) { + if ( prepend ) { + animationPrefilters.unshift( callback ); + } else { + animationPrefilters.push( callback ); + } + } +}); + +function defaultPrefilter( elem, props, opts ) { + var index, prop, value, length, dataShow, toggle, tween, hooks, oldfire, + anim = this, + style = elem.style, + orig = {}, + handled = [], + hidden = elem.nodeType && isHidden( elem ); + + // handle queue: false promises + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always(function() { + // doing this makes sure that the complete handler will be called + // before this completes + anim.always(function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + }); + }); + } + + // height/width overflow pass + if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) { + // Make sure that nothing sneaks out + // Record all 3 overflow attributes because IE does not + // change the overflow attribute when overflowX and + // overflowY are set to the same value + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Set display property to inline-block for height/width + // animations on inline elements that are having width/height animated + if ( jQuery.css( elem, "display" ) === "inline" && + jQuery.css( elem, "float" ) === "none" ) { + + // inline-level elements accept inline-block; + // block-level elements need to be inline with layout + if ( !jQuery.support.inlineBlockNeedsLayout || css_defaultDisplay( elem.nodeName ) === "inline" ) { + style.display = "inline-block"; + + } else { + style.zoom = 1; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + if ( !jQuery.support.shrinkWrapBlocks ) { + anim.done(function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + }); + } + } + + + // show/hide pass + for ( index in props ) { + value = props[ index ]; + if ( rfxtypes.exec( value ) ) { + delete props[ index ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + continue; + } + handled.push( index ); + } + } + + length = handled.length; + if ( length ) { + dataShow = jQuery._data( elem, "fxshow" ) || jQuery._data( elem, "fxshow", {} ); + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + + // store state if its toggle - enables .stop().toggle() to "reverse" + if ( toggle ) { + dataShow.hidden = !hidden; + } + if ( hidden ) { + jQuery( elem ).show(); + } else { + anim.done(function() { + jQuery( elem ).hide(); + }); + } + anim.done(function() { + var prop; + jQuery.removeData( elem, "fxshow", true ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + }); + for ( index = 0 ; index < length ; index++ ) { + prop = handled[ index ]; + tween = anim.createTween( prop, hidden ? dataShow[ prop ] : 0 ); + orig[ prop ] = dataShow[ prop ] || jQuery.style( elem, prop ); + + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = tween.start; + if ( hidden ) { + tween.end = tween.start; + tween.start = prop === "width" || prop === "height" ? 1 : 0; + } + } + } + } +} + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || "swing"; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + if ( tween.elem[ tween.prop ] != null && + (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) { + return tween.elem[ tween.prop ]; + } + + // passing any value as a 4th parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails + // so, simple values such as "10px" are parsed to Float. + // complex values such as "rotate(1rad)" are returned as is. + result = jQuery.css( tween.elem, tween.prop, false, "" ); + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + // use step hook for back compat - use cssHook if its there - use .style if its + // available and use plain properties where available + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Remove in 2.0 - this supports IE8's panic based approach +// to setting things on disconnected nodes + +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.each([ "toggle", "show", "hide" ], function( i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" || + // special check for .toggle( handler, handler, ... ) + ( !i && jQuery.isFunction( speed ) && jQuery.isFunction( easing ) ) ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +}); + +jQuery.fn.extend({ + fadeTo: function( speed, to, easing, callback ) { + + // show any hidden elements after setting opacity to 0 + return this.filter( isHidden ).css( "opacity", 0 ).show() + + // animate to the value specified + .end().animate({ opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations resolve immediately + if ( empty ) { + anim.stop( true ); + } + }; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue && type !== false ) { + this.queue( type || "fx", [] ); + } + + return this.each(function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = jQuery._data( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) { + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // start the next in the queue if the last step wasn't forced + // timers currently will call their complete callbacks, which will dequeue + // but only if they were gotoEnd + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + }); + } +}); + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + attrs = { height: type }, + i = 0; + + // if we include width, step value is 1 to do all cssExpand values, + // if we don't include width, step value is 2 to skip over Left and Right + includeWidth = includeWidth? 1 : 0; + for( ; i < 4 ; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +// Generate shortcuts for custom animations +jQuery.each({ + slideDown: genFx("show"), + slideUp: genFx("hide"), + slideToggle: genFx("toggle"), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +}); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + jQuery.isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing + }; + + opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : + opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default; + + // normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( jQuery.isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p*Math.PI ) / 2; + } +}; + +jQuery.timers = []; +jQuery.fx = Tween.prototype.init; +jQuery.fx.tick = function() { + var timer, + timers = jQuery.timers, + i = 0; + + fxNow = jQuery.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + // Checks the timer has not already been removed + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + if ( timer() && jQuery.timers.push( timer ) && !timerId ) { + timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval ); + } +}; + +jQuery.fx.interval = 13; + +jQuery.fx.stop = function() { + clearInterval( timerId ); + timerId = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + // Default speed + _default: 400 +}; + +// Back Compat <1.8 extension point +jQuery.fx.step = {}; + +if ( jQuery.expr && jQuery.expr.filters ) { + jQuery.expr.filters.animated = function( elem ) { + return jQuery.grep(jQuery.timers, function( fn ) { + return elem === fn.elem; + }).length; + }; +} +var rroot = /^(?:body|html)$/i; + +jQuery.fn.offset = function( options ) { + if ( arguments.length ) { + return options === undefined ? + this : + this.each(function( i ) { + jQuery.offset.setOffset( this, options, i ); + }); + } + + var docElem, body, win, clientTop, clientLeft, scrollTop, scrollLeft, + box = { top: 0, left: 0 }, + elem = this[ 0 ], + doc = elem && elem.ownerDocument; + + if ( !doc ) { + return; + } + + if ( (body = doc.body) === elem ) { + return jQuery.offset.bodyOffset( elem ); + } + + docElem = doc.documentElement; + + // Make sure it's not a disconnected DOM node + if ( !jQuery.contains( docElem, elem ) ) { + return box; + } + + // If we don't have gBCR, just use 0,0 rather than error + // BlackBerry 5, iOS 3 (original iPhone) + if ( typeof elem.getBoundingClientRect !== "undefined" ) { + box = elem.getBoundingClientRect(); + } + win = getWindow( doc ); + clientTop = docElem.clientTop || body.clientTop || 0; + clientLeft = docElem.clientLeft || body.clientLeft || 0; + scrollTop = win.pageYOffset || docElem.scrollTop; + scrollLeft = win.pageXOffset || docElem.scrollLeft; + return { + top: box.top + scrollTop - clientTop, + left: box.left + scrollLeft - clientLeft + }; +}; + +jQuery.offset = { + + bodyOffset: function( body ) { + var top = body.offsetTop, + left = body.offsetLeft; + + if ( jQuery.support.doesNotIncludeMarginInBodyOffset ) { + top += parseFloat( jQuery.css(body, "marginTop") ) || 0; + left += parseFloat( jQuery.css(body, "marginLeft") ) || 0; + } + + return { top: top, left: left }; + }, + + setOffset: function( elem, options, i ) { + var position = jQuery.css( elem, "position" ); + + // set position first, in-case top/left are set even on static elem + if ( position === "static" ) { + elem.style.position = "relative"; + } + + var curElem = jQuery( elem ), + curOffset = curElem.offset(), + curCSSTop = jQuery.css( elem, "top" ), + curCSSLeft = jQuery.css( elem, "left" ), + calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1, + props = {}, curPosition = {}, curTop, curLeft; + + // need to be able to calculate position if either top or left is auto and position is either absolute or fixed + if ( calculatePosition ) { + curPosition = curElem.position(); + curTop = curPosition.top; + curLeft = curPosition.left; + } else { + curTop = parseFloat( curCSSTop ) || 0; + curLeft = parseFloat( curCSSLeft ) || 0; + } + + if ( jQuery.isFunction( options ) ) { + options = options.call( elem, i, curOffset ); + } + + if ( options.top != null ) { + props.top = ( options.top - curOffset.top ) + curTop; + } + if ( options.left != null ) { + props.left = ( options.left - curOffset.left ) + curLeft; + } + + if ( "using" in options ) { + options.using.call( elem, props ); + } else { + curElem.css( props ); + } + } +}; + + +jQuery.fn.extend({ + + position: function() { + if ( !this[0] ) { + return; + } + + var elem = this[0], + + // Get *real* offsetParent + offsetParent = this.offsetParent(), + + // Get correct offsets + offset = this.offset(), + parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset(); + + // Subtract element margins + // note: when an element has margin: auto the offsetLeft and marginLeft + // are the same in Safari causing offset.left to incorrectly be 0 + offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0; + offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0; + + // Add offsetParent borders + parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0; + parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0; + + // Subtract the two offsets + return { + top: offset.top - parentOffset.top, + left: offset.left - parentOffset.left + }; + }, + + offsetParent: function() { + return this.map(function() { + var offsetParent = this.offsetParent || document.body; + while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) { + offsetParent = offsetParent.offsetParent; + } + return offsetParent || document.body; + }); + } +}); + + +// Create scrollLeft and scrollTop methods +jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) { + var top = /Y/.test( prop ); + + jQuery.fn[ method ] = function( val ) { + return jQuery.access( this, function( elem, method, val ) { + var win = getWindow( elem ); + + if ( val === undefined ) { + return win ? (prop in win) ? win[ prop ] : + win.document.documentElement[ method ] : + elem[ method ]; + } + + if ( win ) { + win.scrollTo( + !top ? val : jQuery( win ).scrollLeft(), + top ? val : jQuery( win ).scrollTop() + ); + + } else { + elem[ method ] = val; + } + }, method, val, arguments.length, null ); + }; +}); + +function getWindow( elem ) { + return jQuery.isWindow( elem ) ? + elem : + elem.nodeType === 9 ? + elem.defaultView || elem.parentWindow : + false; +} +// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods +jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { + jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) { + // margin is only for outerHeight, outerWidth + jQuery.fn[ funcName ] = function( margin, value ) { + var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), + extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); + + return jQuery.access( this, function( elem, type, value ) { + var doc; + + if ( jQuery.isWindow( elem ) ) { + // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there + // isn't a whole lot we can do. See pull request at this URL for discussion: + // https://github.com/jquery/jquery/pull/764 + return elem.document.documentElement[ "client" + name ]; + } + + // Get document width or height + if ( elem.nodeType === 9 ) { + doc = elem.documentElement; + + // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest + // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it. + return Math.max( + elem.body[ "scroll" + name ], doc[ "scroll" + name ], + elem.body[ "offset" + name ], doc[ "offset" + name ], + doc[ "client" + name ] + ); + } + + return value === undefined ? + // Get width or height on the element, requesting but not forcing parseFloat + jQuery.css( elem, type, value, extra ) : + + // Set width or height on the element + jQuery.style( elem, type, value, extra ); + }, type, chainable ? margin : undefined, chainable, null ); + }; + }); +}); +// Expose jQuery to the global object +window.jQuery = window.$ = jQuery; + +// Expose jQuery as an AMD module, but only for AMD loaders that +// understand the issues with loading multiple versions of jQuery +// in a page that all might call define(). The loader will indicate +// they have special allowances for multiple jQuery versions by +// specifying define.amd.jQuery = true. Register as a named module, +// since jQuery can be concatenated with other files that may use define, +// but not use a proper concatenation script that understands anonymous +// AMD modules. A named AMD is safest and most robust way to register. +// Lowercase jquery is used because AMD module names are derived from +// file names, and jQuery is normally delivered in a lowercase file name. +// Do this after creating the global so that if an AMD module wants to call +// noConflict to hide this version of jQuery, it will work. +if ( typeof define === "function" && define.amd && define.amd.jQuery ) { + define( "jquery", [], function () { return jQuery; } ); +} + +})( window ); diff --git a/monitoring/monitoring_ui/src/3dparty/flot/package.json b/monitoring/monitoring_ui/src/3dparty/flot/package.json new file mode 100644 index 0000000000000000000000000000000000000000..deb9651778975ddc1c2f30af1706fb5833a33639 --- /dev/null +++ b/monitoring/monitoring_ui/src/3dparty/flot/package.json @@ -0,0 +1,11 @@ +{ + "name": "Flot", + "version": "0.8.3", + "main": "jquery.flot.js", + "scripts": { + "test": "make test" + }, + "devDependencies": { + "jshint": "0.9.1" + } +} diff --git a/monitoring/monitoring_ui/src/3dparty/flotPlugins/jquery.flot.byte.js b/monitoring/monitoring_ui/src/3dparty/flotPlugins/jquery.flot.byte.js new file mode 100644 index 0000000000000000000000000000000000000000..766e3ca6daf18a52e0c811776ed8012cf39a08d7 --- /dev/null +++ b/monitoring/monitoring_ui/src/3dparty/flotPlugins/jquery.flot.byte.js @@ -0,0 +1,130 @@ +// Source: https://github.com/whatbox/jquery.flot.byte +(function ($) { + "use strict"; + + var options = {}; + + //Round to nearby lower multiple of base + function floorInBase(n, base) { + return base * Math.floor(n / base); + } + + function init(plot) { + plot.hooks.processDatapoints.push(function (plot) { + $.each(plot.getAxes(), function(axisName, axis) { + var opts = axis.options; + + if (typeof opts.base === "number" && opts.base === 10) { + // Gigabytes, Terabytes + var EXTENSIONS = [ + 'B', + 'kB', + 'MB', + 'GB', + 'TB', + 'PB', + 'EB', + 'ZB', + 'YB', + ]; + var STEP_SIZE = 1000; + + } else { + // Gibibytes, Tebibytes + var EXTENSIONS = [ + 'B', + 'KiB', + 'MiB', + 'GiB', + 'TiB', + 'PiB', + 'EiB', + 'ZiB', + 'YiB', + ]; + var STEP_SIZE = 1024; + } + + + if (opts.mode === "byte" || opts.mode === "byteRate") { + axis.tickGenerator = function (axis) { + var returnTicks = [], + tickSize = 2, + delta = axis.delta, + steps = 0, + tickMin = 0, + tickVal, + tickCount = 0; + + //Enforce maximum tick Decimals + if (typeof opts.tickDecimals === "number") { + axis.tickDecimals = opts.tickDecimals; + } else { + axis.tickDecimals = 2; + } + + //Count the steps + while (Math.abs(delta) >= STEP_SIZE) { + steps++; + delta /= STEP_SIZE; + } + + //Set the tick size relative to the remaining delta + while (tickSize <= STEP_SIZE) { + if (delta <= tickSize) { + break; + } + tickSize *= 2; + } + + //Tell flot the tickSize we've calculated + if (typeof opts.minTickSize !== "undefined" && tickSize < opts.minTickSize) { + axis.tickSize = opts.minTickSize; + } else { + axis.tickSize = tickSize * Math.pow(STEP_SIZE, steps); + } + + //Calculate the new ticks + tickMin = floorInBase(axis.min, axis.tickSize); + do { + tickVal = tickMin + (tickCount++) * axis.tickSize; + returnTicks.push(tickVal); + } while (tickVal < axis.max); + + return returnTicks; + }; + + axis.tickFormatter = function(size, axis) { + var steps = 0; + + let tickDecimals = axis.tickDecimals; + if (size < 1024*1024*1024 && tickDecimals > 0) { + tickDecimals = 0; + } else if (tickDecimals < 0) { + tickDecimals = Math.abs(tickDecimals); + } + + while (Math.abs(size) >= STEP_SIZE) { + steps++; + size /= STEP_SIZE; + } + + var ext = ' ' + EXTENSIONS[steps]; + if (opts.mode === "byteRate") { + ext += "/s"; + } + + return (size.toFixed(tickDecimals) + ' ' + ext); + }; + } + }); + }); + } + + $.plot.plugins.push({ + init: init, + options: options, + name: "byte", + version: "0.1" + }); +})(jQuery); diff --git a/monitoring/monitoring_ui/src/App.vue b/monitoring/monitoring_ui/src/App.vue new file mode 100644 index 0000000000000000000000000000000000000000..14187cb64ae3f1dc25309a89952d468a8b4ba3ab --- /dev/null +++ b/monitoring/monitoring_ui/src/App.vue @@ -0,0 +1,44 @@ +<template> + <router-view /> + <Tooltip /> +</template> + + +<script lang="ts"> +import { Options, Vue } from 'vue-class-component'; +import Tooltip from './components/Tooltip.vue'; + +@Options({ + components: { + Tooltip + } +}) +export default class App extends Vue { +} + +</script> + +<style lang="css"> +/* +#app { + font-family: Avenir, Helvetica, Arial, sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-align: center; + color: #2c3e50; +} + +#nav { + padding: 30px; + + a { + font-weight: bold; + color: #2c3e50; + + &.router-link-exact-active { + color: #42b983; + } + } +} +*/ +</style> diff --git a/monitoring/monitoring_ui/src/assets/icons/refresh.svg b/monitoring/monitoring_ui/src/assets/icons/refresh.svg new file mode 100644 index 0000000000000000000000000000000000000000..5d218777c0f3401011db7e9001ed91bc2599bf9b --- /dev/null +++ b/monitoring/monitoring_ui/src/assets/icons/refresh.svg @@ -0,0 +1,7 @@ +<?xml version="1.0" ?> +<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'> +<svg enable-background="new 0 0 28.539 29.123" fill="white" height="29.123px" id="Capa_1" version="1.1" viewBox="0 0 28.539 29.123" width="28.539px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> + <g> + <path d="M7.63,7.938c3.215-3.215,8.132-3.674,11.847-1.402c-1.259,1.246-2.711,2.702-2.711,2.702 c-1.016,1.219,0.125,1.922,0.705,1.904l6.789-0.002c0.358,0,0.651,0.002,0.651,0.002s0.296,0,0.655,0h1.317 c0.359,0,0.651-0.293,0.652-0.653V1.154c0.042-0.854-0.896-1.682-1.864-0.729c0,0-1.602,1.561-2.708,2.657 C17.305-1.051,9.331-0.583,4.22,4.528C1.238,7.51-0.153,11.466,0.014,15.373h4.83C4.673,12.703,5.589,9.979,7.63,7.938z"/><path d="M23.695,13.75c0.171,2.67-0.745,5.394-2.786,7.435c-3.216,3.215-8.131,3.674-11.846,1.402 c1.258-1.246,2.71-2.702,2.71-2.702c1.016-1.219-0.125-1.922-0.705-1.903l-6.789,0.002c-0.358,0-0.651-0.002-0.651-0.002 s-0.296,0-0.655,0H1.654c-0.359,0-0.651,0.293-0.652,0.652v9.335c-0.041,0.853,0.896,1.681,1.865,0.728 c0,0,1.601-1.561,2.708-2.656c5.66,4.134,13.633,3.666,18.743-1.445c2.981-2.982,4.373-6.938,4.207-10.845H23.695z"/> + </g> +</svg> diff --git a/monitoring/monitoring_ui/src/assets/icons/single_refresh.svg b/monitoring/monitoring_ui/src/assets/icons/single_refresh.svg new file mode 100644 index 0000000000000000000000000000000000000000..9ea28059a767c638de3dd35cd4d8feaa94b639d8 --- /dev/null +++ b/monitoring/monitoring_ui/src/assets/icons/single_refresh.svg @@ -0,0 +1 @@ +<?xml version="1.0" ?><svg height="48" viewBox="0 0 48 48" width="48" xmlns="http://www.w3.org/2000/svg"><path d="M35.3 12.7c-2.89-2.9-6.88-4.7-11.3-4.7-8.84 0-15.98 7.16-15.98 16s7.14 16 15.98 16c7.45 0 13.69-5.1 15.46-12h-4.16c-1.65 4.66-6.07 8-11.3 8-6.63 0-12-5.37-12-12s5.37-12 12-12c3.31 0 6.28 1.38 8.45 3.55l-6.45 6.45h14v-14l-4.7 4.7z"/><path d="M0 0h48v48h-48z" fill="none"/></svg> \ No newline at end of file diff --git a/monitoring/monitoring_ui/src/assets/tailwind.css b/monitoring/monitoring_ui/src/assets/tailwind.css new file mode 100644 index 0000000000000000000000000000000000000000..7f393742af264b3fb6b519a019e576aca39dd8d7 --- /dev/null +++ b/monitoring/monitoring_ui/src/assets/tailwind.css @@ -0,0 +1,5 @@ +@tailwind base; + +@tailwind components; + +@tailwind utilities; diff --git a/monitoring/monitoring_ui/src/components/FilterSelector.vue b/monitoring/monitoring_ui/src/components/FilterSelector.vue new file mode 100644 index 0000000000000000000000000000000000000000..b38266ca573943692136f2551424d2ec68ded99a --- /dev/null +++ b/monitoring/monitoring_ui/src/components/FilterSelector.vue @@ -0,0 +1,234 @@ +<template> + <div class='border p-1 relative' :class="hasFilterError ? 'hasError' : ''"> + <div class="flex items-center" @click="togglePopup"> + <div class="flex flex-row"> + <p class="place-self-center mr-2">Filter:</p> + <div class="flex font-mono text-xs"> + <div class="mr-2"> + <table> + <tr> + <td>Source:</td> + <td>{{currentSourceFilterText}}</td> + </tr> + </table> + </div> + <div> + <table> + <tr> + <td>Receiver:</td> + <td>{{currentReceiverFilterText}}</td> + </tr> + <tr> + <td>Pipeline:</td> + <td>{{currentPipelineFilterText}}</td> + </tr> + </table> + </div> + </div> + </div> + <button class="text-white p-1 ml-2" :class="hasClearableFilter ? 'bg-red-700 hover:bg-red-800' : 'bg-gray-600'" @click.stop="clearFilter()" :disabled="!hasClearableFilter">Clear</button> + </div> + <div v-if="showPopup" class="absolute top-12 text-black p-2 bg-gray-300 border border-gray-600 z-10 w-max right-0"> + <div class="flex justify-between"> + <h1 class="font-bold text-lg">Select filter:</h1> + <button :disabled="isFetchingData" @click="reloadMetaDataOrToplogy()"> + <img src="../assets/icons/single_refresh.svg" class="w-8 h-8" :class="isFetchingData ? 'animate-spin' : ''" /> + </button> + </div> + <div class="flex flex-col"> + <div> + <label for="beamtime" class="inline-block w-20">Beamtime:</label> + <select name="Beamtime" id="beamtime" class="w-32" v-model="selectedBeamtime"> + <option v-for="beamtime in availableBeamtimes" :key="beamtime">{{beamtime}}</option> + </select> + <button @click="clearBeamtimeFilter()">X</button> + </div> + </div> + + <div class="mt-3 flex flex-col"> + <p class="font-bold">For metrics</p> + <div> + <label for="source" class="inline-block w-20">Source:</label> + <select name="Source" id="source" class="w-32" v-model="selectedSource"> + <option v-for="source in availableSources" :key="source">{{source}}</option> + </select> + <button @click="clearSourceFilter()">X</button> + </div> + </div> + <div class="mt-3 flex flex-col"> + <p class="font-bold">Pipeline connection</p> + <table> + <tr> + <td>From Step:</td> + <td><input type="text" id="source" disabled class="w-28" :value="currentPipelineStepFrom"></td> + </tr> + <!-- + <tr> + <td>Source:</td> + <td><input type="text" id="source" disabled class="w-28"></td> + </tr> + --> + <tr> + <td>To Step:</td> + <td><input type="text" id="source" disabled class="w-28" :value="currentPipelineStepTo"></td> + </tr> + </table> + </div> + </div> + </div> +</template> + +<script lang="ts"> +import { Options, Vue } from "vue-class-component"; +import { connection } from "../store/connectionStore"; +import { errorStore } from "../store/errorStore"; +import { selectionFilterStore } from "../store/selectionFilterStore"; +import { toplogyStore } from "../store/toplogyStore"; + +@Options({ + watch: { + selectedBeamtimeFromStore: { + handler(newValue: string | null): void { + this.selectedBeamtime = newValue; + }, + immediate: true, + }, + selectedBeamtime(newValue: string | null): void { + selectionFilterStore.setFilterBeamtime(newValue); + }, + currentBeamtimeFilterText(): void { + this.selectedBeamtime = selectionFilterStore.state.beamtime; + }, + selectedSourceFromStore(newValue: string | null): void { + this.selectedSource = newValue; + }, + selectedSource(newValue: string | null): void { + selectionFilterStore.setFilterSource(newValue); + }, + currentSourceFilterText(): void { + this.selectedSource = selectionFilterStore.state.source; + }, + } +}) +export default class FilterSelector extends Vue { + private selectedBeamtime: string | null = null; + private selectedSource: string | null = null; + private showPopup: boolean = false; + + private get selectedBeamtimeFromStore(): string | null { + return selectionFilterStore.state.beamtime; + } + private get selectedSourceFromStore(): string | null { + return selectionFilterStore.state.source; + } + + private get hasClearableFilter(): boolean { + return selectionFilterStore.hasClearableFilter; + } + + public get availableBeamtimes(): string[] { + return connection.state.availableBeamtimes; + } + + public get availableSources(): string[] { + return toplogyStore.getAvailableSources(); + } + + public mounted(): void { + document.addEventListener('click', this.onWindowClick); + } + + public beforeUnmount(): void { + document.removeEventListener('click', this.onWindowClick); + } + + private reloadMetaDataOrToplogy() { + connection.triggerMetaDataRefresh(); + if (selectionFilterStore.state.beamtime) { + connection.triggerToplogyRefresh(); + } + } + + private get isFetchingData(): boolean { + return connection.state.isFetchingMetaData || connection.state.isFetchingToplogyData; + } + + private togglePopup(): void { + this.showPopup = !this.showPopup; + } + + private onWindowClick(e: MouseEvent): void { + if (!(e as any).path.includes(this.$el)) { + this.showPopup = false; + } + } + + private clearFilter(): void { + selectionFilterStore.clearFilter(); + } + + private get hasFilterError(): boolean { + return !!errorStore.state.filterErrorText; + } + + private get currentBeamtimeFilterText(): string { + if (selectionFilterStore.state.beamtime) { + return selectionFilterStore.state.beamtime; + } + return '*'; + } + + private clearBeamtimeFilter(): void { + selectionFilterStore.setFilterBeamtime(null); + } + + private clearSourceFilter(): void { + selectionFilterStore.clearSourceFilter(); + } + + private get currentSourceFilterText(): string { + if (selectionFilterStore.state.source) { + return selectionFilterStore.state.source; + } + return '*'; + } + + private get currentReceiverFilterText(): string { + if (selectionFilterStore.state.receiverId) { + return selectionFilterStore.state.receiverId; + } + return '*'; + } + + private get currentPipelineStepFrom(): string | null { + if (selectionFilterStore.state.fromPipelineStepId) { + return selectionFilterStore.state.fromPipelineStepId; + } + return ''; + } + + private get currentPipelineStepTo(): string | null { + if (selectionFilterStore.state.toPipelineStepId) { + return selectionFilterStore.state.toPipelineStepId; + } + return ''; + } + + private get currentPipelineFilterText(): string { + if (this.currentPipelineStepFrom || this.currentPipelineStepTo) { + if (selectionFilterStore.state.pipelineFilterRelation === 'and') { + return `${this.currentPipelineStepFrom} ➜ ${this.currentPipelineStepTo}`; + } else { + return `${this.currentPipelineStepFrom}@${this.currentPipelineStepTo}`; + } + } + return ''; + } +} +</script> + +<style lang="scss" scoped> + .hasError { + @apply border-red-500; + } +</style> diff --git a/monitoring/monitoring_ui/src/components/GenericChart.vue b/monitoring/monitoring_ui/src/components/GenericChart.vue new file mode 100644 index 0000000000000000000000000000000000000000..b9db51b9596c41620095a61d8135490397ddd579 --- /dev/null +++ b/monitoring/monitoring_ui/src/components/GenericChart.vue @@ -0,0 +1,257 @@ +<template> + <div> + <div class="w-full h-full bg-gray-100 border border-gray-600 m-1 p-1"> + <div class="flex place-content-between"> + <p class="font-bold">{{chartInfo.title}}</p> + </div> + <div ref="diagram" style="width: 100%; height: 170px"></div> + <div> + <div class="mx-2 inline-block" v-for="(series) in chartInfo.series" :key="series.color" :title="series.description"> + <div class="inline-block w-4 h-3" :style="{backgroundColor: series.color}"></div> + <span class="text-xs ml-1">{{series.name}}</span> + </div> + </div> + </div> + </div> +</template> + +<script lang="ts"> +import { Options, Vue } from "vue-class-component"; +import $, { plot } from 'jquery'; +import Moment from 'moment'; +import { tooltipStore, TooltipTableInfo } from "../store/tooltipStore"; +import { chartCrosshairStore } from "../store/chartCrosshairStore"; + +interface SeriesInfo { + name: string; + description: string; + color: string; +} + +interface ChartInfo { + title: string; + yUnit: 'byteRate' | 'byte' | 'timeMs' | 'timeUs' | 'plainNumber'; + stacked: boolean; + series: SeriesInfo[]; +} + +type SeriesDataPoint = [number/* timestamp */, number /* datapoint */]; +type SeriesData = SeriesDataPoint[]; + +@Options({ + props: { + chartInfo: Object // ChartInfo + }, + watch: { + chartInfo(): void { + if (this.plot) { + const data = this.plot.getData(); + this.destroyPlot(); + this.setupPlot(); + this.setDataPoints(data); + } + }, + crosshairPosX(newX): void { + if (this.plot) { + if (newX) { + this.plot.setCrosshair({x: newX}); + } + else { + this.plot.clearCrosshair() + } + } + } + } +}) +export default class GenericChart extends Vue { + $plot!: JQuery<HTMLElement>; + plot!: jquery.flot.plot; + + public chartInfo!: ChartInfo; + + public mounted() { + this.setupPlot(); + } + + public beforeUnmount(): void { + this.destroyPlot(); + } + + public setDataPoints(data: SeriesData[]): void { + if (this.plot) { + this.plot.setData(data); + + if (data[0] && data[0][data[0].length - 1] && data[0][data[0].length - 1][0]) { + const lastTimestamp = data[0][data[0].length - 1][0]; + const timeDiffMs = Date.now() - new Date(lastTimestamp).getTime(); + const toBeDisplayedDiff = 8000 - timeDiffMs // ~ 8 sec + if (toBeDisplayedDiff > 0) { + this.plot.getOptions()!.grid!.markings = [ + { xaxis: { from: lastTimestamp - toBeDisplayedDiff }, color: "#a9a9a9" }, + ]; + } + } + + this.plot.setupGrid(); + this.plot.draw(); + } + } + + private get crosshairPosX(): number | null { + return chartCrosshairStore.state.xValue; + } + + private setupPlot(): void { + const options = { + // xaxis: is handeld by customXAxisTickGenerator and customXAxisTickFormatter + xaxis: { + timezone: null, // "browser" for local to the client or timezone for timezone-js + timeformat: null, // format string to use + twelveHourClock: false, // 12 or 24 time in time mode + monthNames: null, // list of names of months + timeBase: 'milliseconds' // are the values in given in mircoseconds, milliseconds or seconds + } as any, + yaxis: { + tickDecimals: 0, + labelWidth: 65, + min: 0.001, // Prevent 0 display + }, + series: { + stack: this.chartInfo.stacked, + lines: { + show: true, + fill: true, + }, + }, + crosshair: { + mode: 'x', + }, + grid: { + mouseActiveRadius: 0, + hoverable: true, + backgroundColor: '#f5f5f5', + }, + colors: this.chartInfo.series.map(s => s.color), + } as jquery.flot.plotOptions; + + if (this.chartInfo.yUnit == 'byteRate') { + options.yaxis!.mode = 'byteRate'; + options.yaxis!.tickDecimals = 1; + } else if (this.chartInfo.yUnit == 'byte') { + options.yaxis!.mode = 'byte'; + options.yaxis!.tickDecimals = 1; + } else if (this.chartInfo.yUnit == 'timeMs') { + options.yaxis!.tickFormatter = (t: number): string => `${t} ms`; + } else if (this.chartInfo.yUnit == 'timeUs') { + options.yaxis!.tickFormatter = (t: number): string => `${t} μs`; + } + + this.$plot = $(this.$refs.diagram as any); + this.plot = $.plot(this.$plot, [], options); + + (this.plot.getAxes().xaxis as any).tickGenerator = GenericChart.customXAxisTickGenerator; + (this.plot.getAxes().xaxis as any).tickFormatter = GenericChart.customXAxisTickFormatter; + + window.addEventListener('resize', this.redraw); + this.$plot.on('plothover', this.onPlotHover); + this.$plot.on('mouseout', this.onMouseLeave); + + this.redraw(); + } + + private destroyPlot(): void { + window.removeEventListener('resize', this.redraw); + if (this.$plot) { + this.$plot.off('plothover', this.onPlotHover); + this.$plot.off('mouseout', this.onMouseLeave); + } + } + + private redraw(): void { + this.plot.resize(); + this.plot.setupGrid(); + this.plot.draw(); + } + + private onPlotHover(jQueryEvent: any, mousePos: {x: number, y: number, pageX: number, pageY: number}): void { + const rawPlotData = this.plot.getData(); + if (rawPlotData[0]) { + const timelineX = Math.trunc(mousePos.x); + const timelineData = rawPlotData[0].data; + + if (timelineData.length < 1) { + return; + } + + let i; + for (i = 0; i < timelineData.length - 1; i++) { + const distanceToThis = Math.abs(timelineData[i][0] - timelineX); + const distanceToNext = Math.abs(timelineData[i + 1][0] - timelineX); + if (distanceToNext > distanceToThis) { + break; + } + } + + const timestamp = timelineData[i][0]; + + chartCrosshairStore.showAndUpdate(timestamp); + (this.plot as any).lockCrosshair({x: timestamp}); + + const axes = this.plot.getAxes(); + const xAxis = axes.xaxis; + const yAxis = axes.yaxis; + + const outLines = [] as TooltipTableInfo[]; + for (let seriesIndex = 0; seriesIndex < rawPlotData.length; seriesIndex++) { + const series = rawPlotData[seriesIndex]; + const value = series.data[i][1]; + + let yTextValue; + if (this.chartInfo.yUnit == 'byteRate' || this.chartInfo.yUnit == 'byte') { + yTextValue = yAxis.tickFormatter!(value, {tickDecimals: -2} as any); + } else { + yTextValue = yAxis.tickFormatter!(value, yAxis); + } + + outLines.push({ + name: this.chartInfo.series[seriesIndex].name, + value: yTextValue + }); + } + + const xTextValue = xAxis.tickFormatter!(timestamp, xAxis); + tooltipStore.showAndUpdate(mousePos.pageX, mousePos.pageY, xTextValue, outLines); + } + } + + private onMouseLeave(): void { + chartCrosshairStore.hide(); + tooltipStore.hide(); + } + + private static customXAxisTickGenerator(axis: any): any[] { + const tickAmount = 5; + const totalTimeRangeMs = axis.datamax - axis.datamin; + const deltaPerTick = totalTimeRangeMs / (tickAmount - 1); + + const tickPoints = Array(tickAmount); + for (let i = 0; i < tickAmount; i++) { + tickPoints[i] = axis.datamin + (deltaPerTick * i); + } + + return tickPoints.map((x) => [x, axis.tickFormatter(x, axis, totalTimeRangeMs < 120 * 1000)]); + } + + private static customXAxisTickFormatter(timestamp: number, axis: any, isDetails = true) { + if (isDetails) { + return Moment((timestamp || 0)).format('HH:mm:ss'); + } else { + return Moment((timestamp || 0)).format('HH:mm'); + } + } +} +</script> + +<style> + +</style> diff --git a/monitoring/monitoring_ui/src/components/GenericListChart.vue b/monitoring/monitoring_ui/src/components/GenericListChart.vue new file mode 100644 index 0000000000000000000000000000000000000000..680ffe475b53c39d2a7a07b0c24210a777c34826 --- /dev/null +++ b/monitoring/monitoring_ui/src/components/GenericListChart.vue @@ -0,0 +1,66 @@ +<template> + <div> + <div class="w-full h-full bg-gray-100 border border-gray-600 m-1 p-1"> + <div class="flex place-content-between"> + <p class="font-bold">{{label}}</p> + </div> + <ul class="overflow-y-scroll font-mono mt-1 bg-gray-100" style="width: 100%; height: 190px" :class="onElementClicked ? 'clickableList' : ''"> + <template v-if="onElementClicked"> + <li v-for="element in elements" :key="element" @click="onElementClicked(element)" :class="{'selected': isElementedSelectedFallback(element)}">{{element}}</li> + </template> + <template v-else> + <li v-for="element in elements" :key="element">{{element}}</li> + </template> + </ul> + </div> + </div> +</template> + +<script lang="ts"> +import { Options, Vue } from "vue-class-component"; + +@Options({ + props: { + label: String, + elements: Object, // string[] + + onElementClicked: Function, // optional: (element: string) => void; + isElementSelected: Function, // optional: (element: string) => boolean; + }, +}) +export default class GenericListChart extends Vue { + public label!: string; + public elements!: string[]; + + public onElementClicked?: (element: string) => void; + public isElementSelected?: (element: string) => boolean; + + private isElementedSelectedFallback(element: string): boolean { + if (!this.isElementSelected) { + return false; + } + return this.isElementSelected(element); + } +} + +</script> + +<style lang="scss" scoped> +li.selected::before { + content: '>'; +} +li::before { + content: '-'; +} + +.clickableList li { + @apply cursor-pointer text-blue-900 hover:text-blue-700; +} + +li { + @apply my-1 +} +li:nth-child(odd) { + @apply bg-gray-50; +} +</style> diff --git a/monitoring/monitoring_ui/src/components/LiveMessageLog.vue b/monitoring/monitoring_ui/src/components/LiveMessageLog.vue new file mode 100644 index 0000000000000000000000000000000000000000..887f3bd767c0a23e6e5941ba972b415d3656e13f --- /dev/null +++ b/monitoring/monitoring_ui/src/components/LiveMessageLog.vue @@ -0,0 +1,76 @@ +<template> + <div class="relative"> + <div class="absolute w-full h-full"> + <div class="font-mono" v-for="entry in logEntries" :key="entry.id"> + <p class="whitespace-pre" :style="{ backgroundColor: entry.color }">{{entry.time}} [{{entry.level}}]{{''.padEnd(5 - entry.level.length)}} {{entry.message}}</p> + </div> + </div> + <div class="absolute w-full h-full flex justify-center items-center" style="background-color: rgba(0,0,0,0.4);"> + <p class="text-white text-3xl">TODO: ElasicSearch log entries</p> + </div> + </div> +</template> + +<script lang="ts"> +import { Options, Vue } from "vue-class-component"; +import Moment from "moment"; + +export default class LiveMessageLog extends Vue { + private logEntries: { + id: string, + time: string, + level: string, + message: string, + color: string, + }[] = []; + + public mounted() { + this.logEntries.push({ + id: '121', + time: Moment(1622636450*1000+154).format('HH:mm:ss.S'), + level: 'INFO', + color: '#4caf50', + message: 'testMessage1', + }); + this.logEntries.push({ + id: '121', + time: Moment(1622636451*1000+15).format('HH:mm:ss.S'), + level: 'WARN', + color: '#ff7043', + message: 'testMessage2' + }); + this.logEntries.push({ + id: '121', + time: Moment(1622636451*1000+600).format('HH:mm:ss.S'), + level: 'ERROR', + color: '#ff1919', + message: 'testMessage3' + }); + + this.logEntries.push({ + id: '121', + time: Moment(1622636452*1000+154).format('HH:mm:ss.S'), + level: 'INFO', + color: '#4caf50', + message: 'testMessage4', + }); + this.logEntries.push({ + id: '121', + time: Moment(1622636453*1000+15).format('HH:mm:ss.S'), + level: 'WARN', + color: '#ff7043', + message: 'testMessage5' + }); + this.logEntries.push({ + id: '121', + time: Moment(1622636454*1000+600).format('HH:mm:ss.S'), + level: 'ERROR', + color: '#ff1919', + message: 'testMessage6' + }); + } +} +</script> + +<style scoped lang="scss"> +</style> diff --git a/monitoring/monitoring_ui/src/components/NavBar.vue b/monitoring/monitoring_ui/src/components/NavBar.vue new file mode 100644 index 0000000000000000000000000000000000000000..d2e42a9960e1bc4a28848fb763b64633ebed5f53 --- /dev/null +++ b/monitoring/monitoring_ui/src/components/NavBar.vue @@ -0,0 +1,66 @@ +<template> + <nav class="flex justify-between p-2 bg-gray-300 border-b border-gray-600"> + <!-- left --> + <div class="flex-1 flex items-center justify-between"> + <div> + <h1 title="TODO Version and build commit/data">ASAPO Monitoring</h1> + <p class="text-xs">Cluster: <span class="font-mono">{{clusterName}}</span></p> + </div> + <div class="ml-5 flex-1 text-red-600 font-bold" v-if="errorMessage"> + <p>{{errorMessage}}</p> + </div> + </div> + + <!-- center --> + <div class="flex flex-col items-center justify-center"> + <h1 class="font-bold text-xl">Dashboard</h1> + <p>For beamtime {{currentBeamtime}}</p> + </div> + + <!-- right --> + <div class="flex-1 flex items-center justify-end"> + <div class="flex items-center justify-end mx-2 bg-gray-300"> + <FilterSelector /> + </div> + <div class="flex items-center justify-end"> + <TimeSelector /> + </div> + </div> + </nav> +</template> + +<script lang="ts"> +import { Options, Vue } from "vue-class-component"; +import TimeSelector from '../components/TimeSelector.vue'; +import FilterSelector from '../components/FilterSelector.vue'; +import { errorStore } from "../store/errorStore"; +import { connection } from "../store/connectionStore"; +import { selectionFilterStore } from "../store/selectionFilterStore"; + +@Options({ + components: { + TimeSelector, + FilterSelector, + } +}) +export default class NavBar extends Vue { + private get currentBeamtime(): string | null { + if (selectionFilterStore.state.beamtime) { + return selectionFilterStore.state.beamtime; + } + return "<Must be set>"; + } + + private get errorMessage(): string | null { + return errorStore.errorText; + } + + private get clusterName(): string { + return connection.state.clusterName; + } +} +</script> + +<style> + +</style> diff --git a/monitoring/monitoring_ui/src/components/TimeSelector.vue b/monitoring/monitoring_ui/src/components/TimeSelector.vue new file mode 100644 index 0000000000000000000000000000000000000000..2a6e314aebeb98824067bb237da1994080e44539 --- /dev/null +++ b/monitoring/monitoring_ui/src/components/TimeSelector.vue @@ -0,0 +1,266 @@ +<template> + <div class="h-10 flex text-white border border-gray-400 "> + <div class="timeQuickView flex flex-col h-full"> + <button class="flex-1 px-1 bg-gray-900 hover:bg-gray-500 border-b border-gray-400" @click="toggleRefreshMenu"> + <p class="text-xs">{{refreshIntervalText}}</p> + </button> + <button class="flex-1 px-1 bg-gray-900 hover:bg-gray-500" @click="toggleRangeMenu"> + <p class="text-xs">{{timeRangeText}}</p> + </button> + </div> + <button title="Manually refresh metrics" @click="refresh()" class="max-h-full bg-gray-900 hover:bg-gray-500 p-1 border-l border-gray-400" :disabled="isFetchingData"> + <img class="refreshButtonImage" src="../assets/icons/refresh.svg" :class="isFetchingData ? 'animate-spin' : ''" /> + </button> + + <!-- TODO: Remove 'right-1' and make two divs for width --> + <div v-if="showDisplayMenu" class="menuWithButtons absolute right-1 top-12 text-black p-2 bg-gray-300 border border-gray-600 z-10"> + <div v-if="currentDisplayIsRefreshMenu" class="flex flex-col"> + <h1 class="font-bold">Select refresh interval</h1> + <button + v-for="intervalInSec, i in refreshIntervals" + :key="i" + :class="isThisSelectedRefreshInterval(intervalInSec) ? 'selected' : ''" + @click="setRefreshInterval(intervalInSec)"> + Every {{intervalInSec}} seconds + </button> + <div class="w-full border-b border-gray-400"></div> + <button + @click="setRefreshInterval(null)" + :class="isThisSelectedRefreshInterval(null) ? 'selected' : ''" + class="highlightColor"> + Manual mode + </button> + </div> + <div v-else-if="currentDisplayIsRangeMenu" class="flex flex-col"> + <h1 class="font-bold">Select range interval</h1> + <div class="flex flex-row"> + <div class="flex flex-col mr-3 place-items-start"> + <h1 class="font-bold">Custom range</h1> + <form class="flex flex-col "> + <div> + <label for="manul-time-from" class="w-12 inline-block">From:</label> + <input id="manul-time-from" class="w-24" v-model="inputTimeExpressionFrom" /> + </div> + <div> + <label for="manul-time-to" class="w-12 inline-block">To:</label> + <input id="manul-time-to" class="w-24" v-model="inputTimeExpressionTo"/> + </div> + + <button class="border-2 bg-gray-100 mt-2" + title="Evaulates the 'from' and 'to' expression and converts them to an absolute timestamp" + type="button" + @click.prevent="convertToAbsoluteTimeRange()"> + To absolute time + </button> + <button class="border-2 bg-gray-100 mt-1" + title="Applies to new time range" + type="submit" + @click.prevent="applyInputTimeRange()"> + Apply + </button> + </form> + </div> + <div class="flex flex-col ml-3"> + <h1 class="font-bold">Quick select</h1> + <button + v-for="range, i in quickSelectTimesConverted" + :key="i" + @click="setTimeRangeFromTemplate(range.from, range.to)" + :class="isThisSelectedTimeRange(range.from, range.to) ? 'selected' : ''"> + {{range.toHumanDescription()}} + </button> + </div> + </div> + </div> + </div> + </div> +</template> + +<script lang="ts"> +import { Options, Vue } from "vue-class-component"; +import { connection } from '../store/connectionStore'; +import { timeStore } from '../store/timeStore'; +import { TimeRange } from '../lib/TimeRange'; + +enum TimeMenu { + None, + RefreshMenu, + RangeMenu, +} + +@Options({ + watch: { + timeExpressionFrom: { + handler() { + this.inputTimeExpressionFrom = timeStore.state.timeExpressionFrom; + }, + immediate: true, + + }, + timeExpressionTo: { + handler() { + this.inputTimeExpressionTo = timeStore.state.timeExpressionTo; + }, + immediate: true, + + } + } +}) +export default class UpdateRateSelector extends Vue { + private static quickSelectTimes: string[] = [ + '1m', '2m', '5m', '10m', '15m', '30m', '1h', '3h', + ]; + private quickSelectTimesConverted = UpdateRateSelector.quickSelectTimes.map((s) => { + return new TimeRange(`now-${s}`, 'now'); + }); + + private refreshIntervals: number[] = [ + 5, 10, 30, 60, + ]; + + private currentMenu: TimeMenu = TimeMenu.None; + + private inputTimeExpressionFrom!: string; + private inputTimeExpressionTo!: string; + + private get timeExpressionFrom(): string { + return timeStore.state.timeExpressionFrom; + } + private get timeExpressionTo(): string { + return timeStore.state.timeExpressionTo; + } + + private get showDisplayMenu(): boolean { + return this.currentMenu != TimeMenu.None; + } + + private get currentDisplayIsRefreshMenu(): boolean { + return this.currentMenu == TimeMenu.RefreshMenu; + } + + private get currentDisplayIsRangeMenu(): boolean { + return this.currentMenu == TimeMenu.RangeMenu; + } + + public mounted(): void { + document.addEventListener('click', this.onWindowClick); + } + + public beforeUnmount(): void { + document.removeEventListener('click', this.onWindowClick); + } + + private onWindowClick(e: MouseEvent): void { + if (!(e as any).path.includes(this.$el)) { + this.closeMenu(); + } + } + + private toggleRefreshMenu(): void { + if (this.currentMenu == TimeMenu.RefreshMenu) { + this.currentMenu = TimeMenu.None; + } else { + this.currentMenu = TimeMenu.RefreshMenu; + } + } + + private toggleRangeMenu(): void { + if (this.currentMenu == TimeMenu.RangeMenu) { + this.currentMenu = TimeMenu.None; + } else { + this.currentMenu = TimeMenu.RangeMenu; + } + } + + private closeMenu(): void { + this.currentMenu = TimeMenu.None; + } + + private applyInputTimeRange(): void { + timeStore.setTimeRange(this.inputTimeExpressionFrom, this.inputTimeExpressionTo); + connection.triggerMetricsRefresh(); + } + + private convertToAbsoluteTimeRange(): void { + this.applyInputTimeRange(); + if (timeStore.evaluateAndVerify()) { + timeStore.setTimeRange(String(timeStore.state.lastFixedTimeRange.fromUnixSec), String(timeStore.state.lastFixedTimeRange.toUnixSec)); + connection.triggerMetricsRefresh(); + } + } + + private setTimeRangeFromTemplate(from: string, to: string): void { + timeStore.setTimeRange(from, to); + connection.triggerMetricsRefresh(); + } + + private isThisSelectedTimeRange(from: string, to: string): boolean { + return timeStore.state.timeExpressionFrom === from && timeStore.state.timeExpressionTo === to; + } + + private setRefreshInterval(seconds: number | null): void { + timeStore.setRefreshInterval(seconds); + if (seconds === null) { + connection.clearPendingMetricsTimeout(); + } else { + connection.triggerMetricsRefresh(); + } + } + + private isThisSelectedRefreshInterval(interval: number | null): boolean { + return timeStore.state.refreshIntervalInSec === interval; + } + + public get refreshIntervalInSec(): number | null { + return timeStore.state.refreshIntervalInSec; + } + + public get refreshIntervalText(): string { + if (this.refreshIntervalInSec == null) { + return `Manual refresh mode`; + } + return `Refresh every ${this.refreshIntervalInSec} sec`; + } + + public get timeRangeText(): string { + const timeRange = new TimeRange(timeStore.state.timeExpressionFrom, timeStore.state.timeExpressionTo); + return 'Range: ' + timeRange.toHumanDescription(); + } + + get isFetchingData(): boolean { + return connection.state.isFetchingData; + } + + private refresh(): void { + connection.triggerMetricsRefresh(); + } +} +</script> + +<style lang="scss" scoped> + .selected { + @apply underline; + } + + .highlightColor { + @apply text-yellow-800; + &:hover { + @apply text-red-900; + } + } + + .menuWithButtons button:not(.highlightColor) { + @apply text-blue-700; + &:hover { + @apply text-blue-900; + } + } + + .timeQuickView { + min-width: 10em; + } + + .refreshButtonImage { + height: 80%; + } +</style> \ No newline at end of file diff --git a/monitoring/monitoring_ui/src/components/Tooltip.vue b/monitoring/monitoring_ui/src/components/Tooltip.vue new file mode 100644 index 0000000000000000000000000000000000000000..45906c9bd44fa19db7f0e3e7a8221efeb11c09e3 --- /dev/null +++ b/monitoring/monitoring_ui/src/components/Tooltip.vue @@ -0,0 +1,55 @@ +<template> + <div + class="bg-gray-300 border border-gray-700 p-1 w-max" + :class="state.visible ? 'absolute' : 'hidden'" + :style="{left: `${posX}px`, top: `${posY}px`}"> + <p class="font-bold">{{titleLine}}</p> + <table> + <tr v-for="line in lines" :key="line.name"> + <td>{{line.name}}</td> + <td>{{line.value}}</td> + </tr> + </table> + </div> +</template> + +<script lang="ts"> +import { Vue } from "vue-class-component"; +import { tooltipStore, TooltipStoreState, TooltipTableInfo } from "../store/tooltipStore"; + +export default class Tooltip extends Vue { + + public static readonly offset = 10;//px4 + public static readonly overflowPrevention = 30;//px + + public get state(): TooltipStoreState { + return tooltipStore.state; + } + public get titleLine(): string { + return this.state.titleLine; + } + public get lines(): TooltipTableInfo[] { + return this.state.lines; + } + + public get posX(): number { + const intendedPosX = this.state.posX + Tooltip.offset; + + // overflow check + if (this.$el && (intendedPosX + this.$el.clientWidth + Tooltip.overflowPrevention) > window.innerWidth) { + return this.state.posX - Tooltip.offset - this.$el.clientWidth; + } + + return intendedPosX; + } + + public get posY(): number { + return this.state.posY + Tooltip.offset; + } +} + +</script> +1 +<style> + +</style> \ No newline at end of file diff --git a/monitoring/monitoring_ui/src/components/TopologyGraph.vue b/monitoring/monitoring_ui/src/components/TopologyGraph.vue new file mode 100644 index 0000000000000000000000000000000000000000..6cd5c3a7cbd0c1e66acc485884f6194f6efee15b --- /dev/null +++ b/monitoring/monitoring_ui/src/components/TopologyGraph.vue @@ -0,0 +1,269 @@ +<template> + <div class="w-full h-full"> + <div class="flex flex-row items-center"> + <p class="mr-2 font-bold">Topology</p> + <p class="mr-2">Time: {{updateDateText}}</p> + <button :disabled="isFetchingToplogyData" @click="reloadToplogy()"> + <img src="../assets/icons/single_refresh.svg" class="w-8 h-8" :class="isFetchingToplogyData ? 'animate-spin' : ''" /> + </button> + </div> + <div class="w-full h-full"> + <div class="w-full h-full bg-white" :ref="vueSetVisBody"> + </div> + </div> + </div> +</template> + +<script lang="ts"> +import { Options, Vue } from "vue-class-component"; +import { connection } from "../store/connectionStore"; +import { Pipeline } from "../lib/ToplogyPipelineDefinitions"; +import * as vis from 'vis-network'; +import { selectionFilterStore } from "../store/selectionFilterStore"; +import { toplogyStore } from "../store/toplogyStore"; +import moment from 'moment'; +import { FixedTimeRange } from "../lib/TimeRange"; + +@Options({ + watch: { + filterState: { + handler() { + this.filterChanged(); + }, + deep: true, + }, + toplogyStoreLastUpdate: { + handler() { + this.topologyChanged(); + }, + deep: true, + }, + } +}) +export default class TopologyGraph extends Vue { + private get filterState(): typeof selectionFilterStore.state { + return selectionFilterStore.state + } + private get toplogyStoreLastUpdate(): FixedTimeRange { + return toplogyStore.state.lastUpdateRange; + } + + private get updateDateText() { + return moment.unix(this.toplogyStoreLastUpdate.fromUnixSec).format('HH:mm:ss') + ' - ' + moment.unix(this.toplogyStoreLastUpdate.toUnixSec).format('HH:mm:ss') + } + + private visBody!: HTMLDivElement; + + public mounted() { + const visOptions: vis.Options = { + edges: { + smooth: { + enabled: true, + type: 'cubicBezier', + forceDirection: 'horizontal', + roundness: 0.4, + }, + color: '#000000', + arrows: { + to: { + enabled: true, + scaleFactor: 0.6, + }, + }, + font: { + size: 10, + } + }, + nodes: { + shape: 'custom', + color: '#d1d5db', + ctxRenderer: ({ ctx, x, y, state: { selected, hover }, style, label, id}: + {ctx: CanvasRenderingContext2D, x: number, y: number, state: { selected: boolean, hover: boolean}, style: any, label?: string, id: string}) => { + const width = 70; + const height = 42; + const labelMargin = 10; + const innerTextMargin = 5; + + return { + drawNode() { + ctx.save(); + + ctx.beginPath(); + ctx.fillStyle = style.color; + ctx.strokeStyle = style.borderColor; + ctx.lineWidth = style.borderWidth; + ctx.rect(x - (width/2), y - (height/2), width, height); + ctx.closePath(); + + ctx.fill(); + ctx.stroke(); + + ctx.restore(); + }, + drawExternalLabel() { + ctx.save(); + + ctx.fillStyle = '#000000'; + ctx.textBaseline = 'middle'; + + if (label) { + const fontPx = selected ? 14 : 10; + ctx.font = `${fontPx}px Arial`; + ctx.textAlign = 'center'; + ctx.fillText(label, x, y - (height/2) - labelMargin); + } + + const nodeInfo = toplogyStore.state.nodeMap[id]; + if (nodeInfo) { + ctx.font = 20 + "px monospace"; + ctx.textAlign = 'left'; + ctx.fillText(`${nodeInfo.consumers.length}`, x - (width/2) + innerTextMargin, y + 6); + ctx.font = 5 + "px monospace"; + ctx.fillText('consumers', x - (width/2) + innerTextMargin, y - 10); + + ctx.font = 20 + "px monospace"; + ctx.textAlign = 'right'; + ctx.fillText(`${nodeInfo.producers.length}`, x + (width/2) - innerTextMargin, y + 6); + ctx.font = 5 + "px monospace"; + ctx.fillText('producers', x + (width/2) - innerTextMargin, y - 10); + } + + ctx.restore(); + }, + nodeDimensions: { + width, + height, + }, + }; + } + } as any, + layout: { + hierarchical: { + direction: 'LR', + }, + }, + physics: false, + }; + + this.network = new vis.Network(this.visBody, {}, visOptions); + this.network.on('click', this.onNetworkClick); + + this.topologyChanged(); + } + + private static convertToVisData(pipeline: Pipeline): vis.Data { + const visNodes: vis.Node[] = []; + const visEdges: vis.Edge[] = []; + + for (const node of pipeline.nodes) { + visNodes.push({ + id: node.id, + label: node.id, + level: node.level, + }); + } + + for (const edge of pipeline.edges) { + visEdges.push({ + id: edge.id, + from: edge.fromId, + to: edge.toId, + label: edge.sourceName, // TODO: // + '\n' + edge.filesPerSec + 'f/s\n' + edge.miBPerSec + 'MiB/s', + }); + } + + return { + nodes: visNodes, + edges: visEdges, + }; + } + + private filterChanged(): void { + if (!selectionFilterStore.hasClearableFilter) { + this.network.setSelection({ + nodes: [], + edges: [], + }, {unselectAll: true, highlightEdges: false}); + return; + } + + let nodes = Object.values(toplogyStore.state.nodeMap); + if (selectionFilterStore.state.fromPipelineStepId && selectionFilterStore.state.toPipelineStepId) { + nodes = nodes.filter(node => node.id === selectionFilterStore.state.fromPipelineStepId || node.id === selectionFilterStore.state.toPipelineStepId); + } + + let edges = Object.values(toplogyStore.state.edgeMap) + + if (selectionFilterStore.state.source) { + edges = edges.filter(edge => edge.sourceName === selectionFilterStore.state.source); + } + if (selectionFilterStore.state.receiverId) { + edges = edges.filter(edge => edge.receivers.includes(selectionFilterStore.state.receiverId!)); + } + if (selectionFilterStore.state.fromPipelineStepId && selectionFilterStore.state.toPipelineStepId) { + edges = edges.filter(edge => edge.fromId === selectionFilterStore.state.fromPipelineStepId && edge.toId === selectionFilterStore.state.toPipelineStepId); + } + + + this.network.setSelection({ + nodes: nodes.map(node => node.id), + edges: edges.map(edge => edge.id), + }, {unselectAll: true, highlightEdges: false}) + } + + private topologyChanged(): void { + this.updateData(toplogyStore.state.pipeline); + } + + private onNetworkClick(props: any): void { + this.network.unselectAll(); + if (props.nodes.length === 1) { + // const node = (this.network as any).body.nodes[props.nodes[0]] as vis.Node; + selectionFilterStore.setFilterPipelineStep(props.nodes[0]); + } else if (props.edges.length === 1) { + //const edge = (this.network as any).body.edges[props.edges[0]] as vis.Edge; + const edge = toplogyStore.state.edgeMap[props.edges[0]]; + selectionFilterStore.setFilterSourceWithPipeline(edge.sourceName, edge.fromId, edge.toId); + } else { + selectionFilterStore.clearFilter(); + } + this.filterChanged(); + } + + private network!: vis.Network; + + public updateData(pipeline: Pipeline) { + const data = TopologyGraph.convertToVisData(pipeline); + + this.network.setData(data); + this.network.fit({ + minZoomLevel: 1.6, + maxZoomLevel: 1.6, + }); + } + + public beforeUnmount() { + this.network.destroy(); + } + + private vueSetVisBody(visBody: HTMLDivElement): void { + this.visBody = visBody; + } + + private get isFetchingToplogyData(): boolean { + return connection.state.isFetchingToplogyData; + } + + private reloadToplogy(): void { + return connection.triggerToplogyRefresh(); + } +} +</script> + +<style lang="scss"> +.customclass { + canvas { + position: absolute !important; + } +} +</style> \ No newline at end of file diff --git a/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringCommonService_pb.d.ts b/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringCommonService_pb.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..32c56d12cc9c5a2d9a0eb1444778de226a63014d --- /dev/null +++ b/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringCommonService_pb.d.ts @@ -0,0 +1,18 @@ +import * as jspb from 'google-protobuf' + + + +export class Empty extends jspb.Message { + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): Empty.AsObject; + static toObject(includeInstance: boolean, msg: Empty): Empty.AsObject; + static serializeBinaryToWriter(message: Empty, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): Empty; + static deserializeBinaryFromReader(message: Empty, reader: jspb.BinaryReader): Empty; +} + +export namespace Empty { + export type AsObject = { + } +} + diff --git a/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringCommonService_pb.js b/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringCommonService_pb.js new file mode 100644 index 0000000000000000000000000000000000000000..39d9b1634ffb5a7fb10c7cd6d40bf33a86ffeb51 --- /dev/null +++ b/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringCommonService_pb.js @@ -0,0 +1,141 @@ +// source: AsapoMonitoringCommonService.proto +/** + * @fileoverview + * @enhanceable + * @suppress {missingRequire} reports error on implicit type usages. + * @suppress {messageConventions} JS Compiler reports an error if a variable or + * field starts with 'MSG_' and isn't a translatable message. + * @public + */ +// GENERATED CODE -- DO NOT EDIT! +/* eslint-disable */ +// @ts-nocheck + +var jspb = require('google-protobuf'); +var goog = jspb; +var global = Function('return this')(); + +goog.exportSymbol('proto.Empty', null, global); +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.Empty = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.Empty, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.Empty.displayName = 'proto.Empty'; +} + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.Empty.prototype.toObject = function(opt_includeInstance) { + return proto.Empty.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.Empty} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.Empty.toObject = function(includeInstance, msg) { + var f, obj = { + + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.Empty} + */ +proto.Empty.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.Empty; + return proto.Empty.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.Empty} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.Empty} + */ +proto.Empty.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.Empty.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.Empty.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.Empty} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.Empty.serializeBinaryToWriter = function(message, writer) { + var f = undefined; +}; + + +goog.object.extend(exports, proto); diff --git a/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringIngestService_grpc_web_pb.d.ts b/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringIngestService_grpc_web_pb.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..9e389a7a050291d16839b477af8be515c7f1ce9c --- /dev/null +++ b/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringIngestService_grpc_web_pb.d.ts @@ -0,0 +1,56 @@ +import * as grpcWeb from 'grpc-web'; + +import * as AsapoMonitoringCommonService_pb from './AsapoMonitoringCommonService_pb'; +import * as AsapoMonitoringIngestService_pb from './AsapoMonitoringIngestService_pb'; + + +export class AsapoMonitoringIngestServiceClient { + constructor (hostname: string, + credentials?: null | { [index: string]: string; }, + options?: null | { [index: string]: any; }); + + insertReceiverDataPoints( + request: AsapoMonitoringIngestService_pb.ReceiverDataPointContainer, + metadata: grpcWeb.Metadata | undefined, + callback: (err: grpcWeb.Error, + response: AsapoMonitoringCommonService_pb.Empty) => void + ): grpcWeb.ClientReadableStream<AsapoMonitoringCommonService_pb.Empty>; + + insertBrokerDataPoints( + request: AsapoMonitoringIngestService_pb.BrokerDataPointContainer, + metadata: grpcWeb.Metadata | undefined, + callback: (err: grpcWeb.Error, + response: AsapoMonitoringCommonService_pb.Empty) => void + ): grpcWeb.ClientReadableStream<AsapoMonitoringCommonService_pb.Empty>; + + insertFtsDataPoints( + request: AsapoMonitoringIngestService_pb.FtsToConsumerDataPointContainer, + metadata: grpcWeb.Metadata | undefined, + callback: (err: grpcWeb.Error, + response: AsapoMonitoringCommonService_pb.Empty) => void + ): grpcWeb.ClientReadableStream<AsapoMonitoringCommonService_pb.Empty>; + +} + +export class AsapoMonitoringIngestServicePromiseClient { + constructor (hostname: string, + credentials?: null | { [index: string]: string; }, + options?: null | { [index: string]: any; }); + + insertReceiverDataPoints( + request: AsapoMonitoringIngestService_pb.ReceiverDataPointContainer, + metadata?: grpcWeb.Metadata + ): Promise<AsapoMonitoringCommonService_pb.Empty>; + + insertBrokerDataPoints( + request: AsapoMonitoringIngestService_pb.BrokerDataPointContainer, + metadata?: grpcWeb.Metadata + ): Promise<AsapoMonitoringCommonService_pb.Empty>; + + insertFtsDataPoints( + request: AsapoMonitoringIngestService_pb.FtsToConsumerDataPointContainer, + metadata?: grpcWeb.Metadata + ): Promise<AsapoMonitoringCommonService_pb.Empty>; + +} + diff --git a/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringIngestService_grpc_web_pb.js b/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringIngestService_grpc_web_pb.js new file mode 100644 index 0000000000000000000000000000000000000000..815265270ae714a9289678c9fba9f9f44d4fb340 --- /dev/null +++ b/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringIngestService_grpc_web_pb.js @@ -0,0 +1,315 @@ +/** + * @fileoverview gRPC-Web generated client stub for + * @enhanceable + * @public + */ + +// GENERATED CODE -- DO NOT EDIT! + + +/* eslint-disable */ +// @ts-nocheck + + + +const grpc = {}; +grpc.web = require('grpc-web'); + + +var AsapoMonitoringCommonService_pb = require('./AsapoMonitoringCommonService_pb.js') +const proto = require('./AsapoMonitoringIngestService_pb.js'); + +/** + * @param {string} hostname + * @param {?Object} credentials + * @param {?Object} options + * @constructor + * @struct + * @final + */ +proto.AsapoMonitoringIngestServiceClient = + function(hostname, credentials, options) { + if (!options) options = {}; + options['format'] = 'text'; + + /** + * @private @const {!grpc.web.GrpcWebClientBase} The client + */ + this.client_ = new grpc.web.GrpcWebClientBase(options); + + /** + * @private @const {string} The hostname + */ + this.hostname_ = hostname; + +}; + + +/** + * @param {string} hostname + * @param {?Object} credentials + * @param {?Object} options + * @constructor + * @struct + * @final + */ +proto.AsapoMonitoringIngestServicePromiseClient = + function(hostname, credentials, options) { + if (!options) options = {}; + options['format'] = 'text'; + + /** + * @private @const {!grpc.web.GrpcWebClientBase} The client + */ + this.client_ = new grpc.web.GrpcWebClientBase(options); + + /** + * @private @const {string} The hostname + */ + this.hostname_ = hostname; + +}; + + +/** + * @const + * @type {!grpc.web.MethodDescriptor< + * !proto.ReceiverDataPointContainer, + * !proto.Empty>} + */ +const methodDescriptor_AsapoMonitoringIngestService_InsertReceiverDataPoints = new grpc.web.MethodDescriptor( + '/AsapoMonitoringIngestService/InsertReceiverDataPoints', + grpc.web.MethodType.UNARY, + proto.ReceiverDataPointContainer, + AsapoMonitoringCommonService_pb.Empty, + /** + * @param {!proto.ReceiverDataPointContainer} request + * @return {!Uint8Array} + */ + function(request) { + return request.serializeBinary(); + }, + AsapoMonitoringCommonService_pb.Empty.deserializeBinary +); + + +/** + * @const + * @type {!grpc.web.AbstractClientBase.MethodInfo< + * !proto.ReceiverDataPointContainer, + * !proto.Empty>} + */ +const methodInfo_AsapoMonitoringIngestService_InsertReceiverDataPoints = new grpc.web.AbstractClientBase.MethodInfo( + AsapoMonitoringCommonService_pb.Empty, + /** + * @param {!proto.ReceiverDataPointContainer} request + * @return {!Uint8Array} + */ + function(request) { + return request.serializeBinary(); + }, + AsapoMonitoringCommonService_pb.Empty.deserializeBinary +); + + +/** + * @param {!proto.ReceiverDataPointContainer} request The + * request proto + * @param {?Object<string, string>} metadata User defined + * call metadata + * @param {function(?grpc.web.Error, ?proto.Empty)} + * callback The callback function(error, response) + * @return {!grpc.web.ClientReadableStream<!proto.Empty>|undefined} + * The XHR Node Readable Stream + */ +proto.AsapoMonitoringIngestServiceClient.prototype.insertReceiverDataPoints = + function(request, metadata, callback) { + return this.client_.rpcCall(this.hostname_ + + '/AsapoMonitoringIngestService/InsertReceiverDataPoints', + request, + metadata || {}, + methodDescriptor_AsapoMonitoringIngestService_InsertReceiverDataPoints, + callback); +}; + + +/** + * @param {!proto.ReceiverDataPointContainer} request The + * request proto + * @param {?Object<string, string>} metadata User defined + * call metadata + * @return {!Promise<!proto.Empty>} + * Promise that resolves to the response + */ +proto.AsapoMonitoringIngestServicePromiseClient.prototype.insertReceiverDataPoints = + function(request, metadata) { + return this.client_.unaryCall(this.hostname_ + + '/AsapoMonitoringIngestService/InsertReceiverDataPoints', + request, + metadata || {}, + methodDescriptor_AsapoMonitoringIngestService_InsertReceiverDataPoints); +}; + + +/** + * @const + * @type {!grpc.web.MethodDescriptor< + * !proto.BrokerDataPointContainer, + * !proto.Empty>} + */ +const methodDescriptor_AsapoMonitoringIngestService_InsertBrokerDataPoints = new grpc.web.MethodDescriptor( + '/AsapoMonitoringIngestService/InsertBrokerDataPoints', + grpc.web.MethodType.UNARY, + proto.BrokerDataPointContainer, + AsapoMonitoringCommonService_pb.Empty, + /** + * @param {!proto.BrokerDataPointContainer} request + * @return {!Uint8Array} + */ + function(request) { + return request.serializeBinary(); + }, + AsapoMonitoringCommonService_pb.Empty.deserializeBinary +); + + +/** + * @const + * @type {!grpc.web.AbstractClientBase.MethodInfo< + * !proto.BrokerDataPointContainer, + * !proto.Empty>} + */ +const methodInfo_AsapoMonitoringIngestService_InsertBrokerDataPoints = new grpc.web.AbstractClientBase.MethodInfo( + AsapoMonitoringCommonService_pb.Empty, + /** + * @param {!proto.BrokerDataPointContainer} request + * @return {!Uint8Array} + */ + function(request) { + return request.serializeBinary(); + }, + AsapoMonitoringCommonService_pb.Empty.deserializeBinary +); + + +/** + * @param {!proto.BrokerDataPointContainer} request The + * request proto + * @param {?Object<string, string>} metadata User defined + * call metadata + * @param {function(?grpc.web.Error, ?proto.Empty)} + * callback The callback function(error, response) + * @return {!grpc.web.ClientReadableStream<!proto.Empty>|undefined} + * The XHR Node Readable Stream + */ +proto.AsapoMonitoringIngestServiceClient.prototype.insertBrokerDataPoints = + function(request, metadata, callback) { + return this.client_.rpcCall(this.hostname_ + + '/AsapoMonitoringIngestService/InsertBrokerDataPoints', + request, + metadata || {}, + methodDescriptor_AsapoMonitoringIngestService_InsertBrokerDataPoints, + callback); +}; + + +/** + * @param {!proto.BrokerDataPointContainer} request The + * request proto + * @param {?Object<string, string>} metadata User defined + * call metadata + * @return {!Promise<!proto.Empty>} + * Promise that resolves to the response + */ +proto.AsapoMonitoringIngestServicePromiseClient.prototype.insertBrokerDataPoints = + function(request, metadata) { + return this.client_.unaryCall(this.hostname_ + + '/AsapoMonitoringIngestService/InsertBrokerDataPoints', + request, + metadata || {}, + methodDescriptor_AsapoMonitoringIngestService_InsertBrokerDataPoints); +}; + + +/** + * @const + * @type {!grpc.web.MethodDescriptor< + * !proto.FtsToConsumerDataPointContainer, + * !proto.Empty>} + */ +const methodDescriptor_AsapoMonitoringIngestService_InsertFtsDataPoints = new grpc.web.MethodDescriptor( + '/AsapoMonitoringIngestService/InsertFtsDataPoints', + grpc.web.MethodType.UNARY, + proto.FtsToConsumerDataPointContainer, + AsapoMonitoringCommonService_pb.Empty, + /** + * @param {!proto.FtsToConsumerDataPointContainer} request + * @return {!Uint8Array} + */ + function(request) { + return request.serializeBinary(); + }, + AsapoMonitoringCommonService_pb.Empty.deserializeBinary +); + + +/** + * @const + * @type {!grpc.web.AbstractClientBase.MethodInfo< + * !proto.FtsToConsumerDataPointContainer, + * !proto.Empty>} + */ +const methodInfo_AsapoMonitoringIngestService_InsertFtsDataPoints = new grpc.web.AbstractClientBase.MethodInfo( + AsapoMonitoringCommonService_pb.Empty, + /** + * @param {!proto.FtsToConsumerDataPointContainer} request + * @return {!Uint8Array} + */ + function(request) { + return request.serializeBinary(); + }, + AsapoMonitoringCommonService_pb.Empty.deserializeBinary +); + + +/** + * @param {!proto.FtsToConsumerDataPointContainer} request The + * request proto + * @param {?Object<string, string>} metadata User defined + * call metadata + * @param {function(?grpc.web.Error, ?proto.Empty)} + * callback The callback function(error, response) + * @return {!grpc.web.ClientReadableStream<!proto.Empty>|undefined} + * The XHR Node Readable Stream + */ +proto.AsapoMonitoringIngestServiceClient.prototype.insertFtsDataPoints = + function(request, metadata, callback) { + return this.client_.rpcCall(this.hostname_ + + '/AsapoMonitoringIngestService/InsertFtsDataPoints', + request, + metadata || {}, + methodDescriptor_AsapoMonitoringIngestService_InsertFtsDataPoints, + callback); +}; + + +/** + * @param {!proto.FtsToConsumerDataPointContainer} request The + * request proto + * @param {?Object<string, string>} metadata User defined + * call metadata + * @return {!Promise<!proto.Empty>} + * Promise that resolves to the response + */ +proto.AsapoMonitoringIngestServicePromiseClient.prototype.insertFtsDataPoints = + function(request, metadata) { + return this.client_.unaryCall(this.hostname_ + + '/AsapoMonitoringIngestService/InsertFtsDataPoints', + request, + metadata || {}, + methodDescriptor_AsapoMonitoringIngestService_InsertFtsDataPoints); +}; + + +module.exports = proto; + diff --git a/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringIngestService_pb.d.ts b/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringIngestService_pb.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..2af6b22ec9c58aa1fc67722489e204127b779c25 --- /dev/null +++ b/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringIngestService_pb.d.ts @@ -0,0 +1,331 @@ +import * as jspb from 'google-protobuf' + +import * as AsapoMonitoringCommonService_pb from './AsapoMonitoringCommonService_pb'; + + +export class ProducerToReceiverTransferDataPoint extends jspb.Message { + getPipelinestepid(): string; + setPipelinestepid(value: string): ProducerToReceiverTransferDataPoint; + + getProducerinstanceid(): string; + setProducerinstanceid(value: string): ProducerToReceiverTransferDataPoint; + + getBeamtime(): string; + setBeamtime(value: string): ProducerToReceiverTransferDataPoint; + + getSource(): string; + setSource(value: string): ProducerToReceiverTransferDataPoint; + + getStream(): string; + setStream(value: string): ProducerToReceiverTransferDataPoint; + + getFilecount(): number; + setFilecount(value: number): ProducerToReceiverTransferDataPoint; + + getTotalfilesize(): number; + setTotalfilesize(value: number): ProducerToReceiverTransferDataPoint; + + getTotaltransferreceivetimeinmicroseconds(): number; + setTotaltransferreceivetimeinmicroseconds(value: number): ProducerToReceiverTransferDataPoint; + + getTotalwriteiotimeinmicroseconds(): number; + setTotalwriteiotimeinmicroseconds(value: number): ProducerToReceiverTransferDataPoint; + + getTotaldbtimeinmicroseconds(): number; + setTotaldbtimeinmicroseconds(value: number): ProducerToReceiverTransferDataPoint; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): ProducerToReceiverTransferDataPoint.AsObject; + static toObject(includeInstance: boolean, msg: ProducerToReceiverTransferDataPoint): ProducerToReceiverTransferDataPoint.AsObject; + static serializeBinaryToWriter(message: ProducerToReceiverTransferDataPoint, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): ProducerToReceiverTransferDataPoint; + static deserializeBinaryFromReader(message: ProducerToReceiverTransferDataPoint, reader: jspb.BinaryReader): ProducerToReceiverTransferDataPoint; +} + +export namespace ProducerToReceiverTransferDataPoint { + export type AsObject = { + pipelinestepid: string, + producerinstanceid: string, + beamtime: string, + source: string, + stream: string, + filecount: number, + totalfilesize: number, + totaltransferreceivetimeinmicroseconds: number, + totalwriteiotimeinmicroseconds: number, + totaldbtimeinmicroseconds: number, + } +} + +export class BrokerRequestDataPoint extends jspb.Message { + getPipelinestepid(): string; + setPipelinestepid(value: string): BrokerRequestDataPoint; + + getConsumerinstanceid(): string; + setConsumerinstanceid(value: string): BrokerRequestDataPoint; + + getCommand(): string; + setCommand(value: string): BrokerRequestDataPoint; + + getBeamtime(): string; + setBeamtime(value: string): BrokerRequestDataPoint; + + getSource(): string; + setSource(value: string): BrokerRequestDataPoint; + + getStream(): string; + setStream(value: string): BrokerRequestDataPoint; + + getFilecount(): number; + setFilecount(value: number): BrokerRequestDataPoint; + + getTotalfilesize(): number; + setTotalfilesize(value: number): BrokerRequestDataPoint; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): BrokerRequestDataPoint.AsObject; + static toObject(includeInstance: boolean, msg: BrokerRequestDataPoint): BrokerRequestDataPoint.AsObject; + static serializeBinaryToWriter(message: BrokerRequestDataPoint, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): BrokerRequestDataPoint; + static deserializeBinaryFromReader(message: BrokerRequestDataPoint, reader: jspb.BinaryReader): BrokerRequestDataPoint; +} + +export namespace BrokerRequestDataPoint { + export type AsObject = { + pipelinestepid: string, + consumerinstanceid: string, + command: string, + beamtime: string, + source: string, + stream: string, + filecount: number, + totalfilesize: number, + } +} + +export class RdsMemoryDataPoint extends jspb.Message { + getBeamtime(): string; + setBeamtime(value: string): RdsMemoryDataPoint; + + getSource(): string; + setSource(value: string): RdsMemoryDataPoint; + + getStream(): string; + setStream(value: string): RdsMemoryDataPoint; + + getUsedbytes(): number; + setUsedbytes(value: number): RdsMemoryDataPoint; + + getTotalbytes(): number; + setTotalbytes(value: number): RdsMemoryDataPoint; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): RdsMemoryDataPoint.AsObject; + static toObject(includeInstance: boolean, msg: RdsMemoryDataPoint): RdsMemoryDataPoint.AsObject; + static serializeBinaryToWriter(message: RdsMemoryDataPoint, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): RdsMemoryDataPoint; + static deserializeBinaryFromReader(message: RdsMemoryDataPoint, reader: jspb.BinaryReader): RdsMemoryDataPoint; +} + +export namespace RdsMemoryDataPoint { + export type AsObject = { + beamtime: string, + source: string, + stream: string, + usedbytes: number, + totalbytes: number, + } +} + +export class RdsToConsumerDataPoint extends jspb.Message { + getPipelinestepid(): string; + setPipelinestepid(value: string): RdsToConsumerDataPoint; + + getConsumerinstanceid(): string; + setConsumerinstanceid(value: string): RdsToConsumerDataPoint; + + getBeamtime(): string; + setBeamtime(value: string): RdsToConsumerDataPoint; + + getSource(): string; + setSource(value: string): RdsToConsumerDataPoint; + + getStream(): string; + setStream(value: string): RdsToConsumerDataPoint; + + getHits(): number; + setHits(value: number): RdsToConsumerDataPoint; + + getMisses(): number; + setMisses(value: number): RdsToConsumerDataPoint; + + getTotalfilesize(): number; + setTotalfilesize(value: number): RdsToConsumerDataPoint; + + getTotaltransfersendtimeinmicroseconds(): number; + setTotaltransfersendtimeinmicroseconds(value: number): RdsToConsumerDataPoint; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): RdsToConsumerDataPoint.AsObject; + static toObject(includeInstance: boolean, msg: RdsToConsumerDataPoint): RdsToConsumerDataPoint.AsObject; + static serializeBinaryToWriter(message: RdsToConsumerDataPoint, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): RdsToConsumerDataPoint; + static deserializeBinaryFromReader(message: RdsToConsumerDataPoint, reader: jspb.BinaryReader): RdsToConsumerDataPoint; +} + +export namespace RdsToConsumerDataPoint { + export type AsObject = { + pipelinestepid: string, + consumerinstanceid: string, + beamtime: string, + source: string, + stream: string, + hits: number, + misses: number, + totalfilesize: number, + totaltransfersendtimeinmicroseconds: number, + } +} + +export class FdsToConsumerDataPoint extends jspb.Message { + getPipelinestepid(): string; + setPipelinestepid(value: string): FdsToConsumerDataPoint; + + getConsumerinstanceid(): string; + setConsumerinstanceid(value: string): FdsToConsumerDataPoint; + + getBeamtime(): string; + setBeamtime(value: string): FdsToConsumerDataPoint; + + getSource(): string; + setSource(value: string): FdsToConsumerDataPoint; + + getStream(): string; + setStream(value: string): FdsToConsumerDataPoint; + + getFilecount(): number; + setFilecount(value: number): FdsToConsumerDataPoint; + + getTotalfilesize(): number; + setTotalfilesize(value: number): FdsToConsumerDataPoint; + + getTotaltransfersendtimeinmicroseconds(): number; + setTotaltransfersendtimeinmicroseconds(value: number): FdsToConsumerDataPoint; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): FdsToConsumerDataPoint.AsObject; + static toObject(includeInstance: boolean, msg: FdsToConsumerDataPoint): FdsToConsumerDataPoint.AsObject; + static serializeBinaryToWriter(message: FdsToConsumerDataPoint, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): FdsToConsumerDataPoint; + static deserializeBinaryFromReader(message: FdsToConsumerDataPoint, reader: jspb.BinaryReader): FdsToConsumerDataPoint; +} + +export namespace FdsToConsumerDataPoint { + export type AsObject = { + pipelinestepid: string, + consumerinstanceid: string, + beamtime: string, + source: string, + stream: string, + filecount: number, + totalfilesize: number, + totaltransfersendtimeinmicroseconds: number, + } +} + +export class ReceiverDataPointContainer extends jspb.Message { + getReceivername(): string; + setReceivername(value: string): ReceiverDataPointContainer; + + getTimestampms(): number; + setTimestampms(value: number): ReceiverDataPointContainer; + + getGroupedp2rtransfersList(): Array<ProducerToReceiverTransferDataPoint>; + setGroupedp2rtransfersList(value: Array<ProducerToReceiverTransferDataPoint>): ReceiverDataPointContainer; + clearGroupedp2rtransfersList(): ReceiverDataPointContainer; + addGroupedp2rtransfers(value?: ProducerToReceiverTransferDataPoint, index?: number): ProducerToReceiverTransferDataPoint; + + getGroupedrds2ctransfersList(): Array<RdsToConsumerDataPoint>; + setGroupedrds2ctransfersList(value: Array<RdsToConsumerDataPoint>): ReceiverDataPointContainer; + clearGroupedrds2ctransfersList(): ReceiverDataPointContainer; + addGroupedrds2ctransfers(value?: RdsToConsumerDataPoint, index?: number): RdsToConsumerDataPoint; + + getGroupedmemorystatsList(): Array<RdsMemoryDataPoint>; + setGroupedmemorystatsList(value: Array<RdsMemoryDataPoint>): ReceiverDataPointContainer; + clearGroupedmemorystatsList(): ReceiverDataPointContainer; + addGroupedmemorystats(value?: RdsMemoryDataPoint, index?: number): RdsMemoryDataPoint; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): ReceiverDataPointContainer.AsObject; + static toObject(includeInstance: boolean, msg: ReceiverDataPointContainer): ReceiverDataPointContainer.AsObject; + static serializeBinaryToWriter(message: ReceiverDataPointContainer, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): ReceiverDataPointContainer; + static deserializeBinaryFromReader(message: ReceiverDataPointContainer, reader: jspb.BinaryReader): ReceiverDataPointContainer; +} + +export namespace ReceiverDataPointContainer { + export type AsObject = { + receivername: string, + timestampms: number, + groupedp2rtransfersList: Array<ProducerToReceiverTransferDataPoint.AsObject>, + groupedrds2ctransfersList: Array<RdsToConsumerDataPoint.AsObject>, + groupedmemorystatsList: Array<RdsMemoryDataPoint.AsObject>, + } +} + +export class BrokerDataPointContainer extends jspb.Message { + getBrokername(): string; + setBrokername(value: string): BrokerDataPointContainer; + + getTimestampms(): number; + setTimestampms(value: number): BrokerDataPointContainer; + + getGroupedbrokerrequestsList(): Array<BrokerRequestDataPoint>; + setGroupedbrokerrequestsList(value: Array<BrokerRequestDataPoint>): BrokerDataPointContainer; + clearGroupedbrokerrequestsList(): BrokerDataPointContainer; + addGroupedbrokerrequests(value?: BrokerRequestDataPoint, index?: number): BrokerRequestDataPoint; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): BrokerDataPointContainer.AsObject; + static toObject(includeInstance: boolean, msg: BrokerDataPointContainer): BrokerDataPointContainer.AsObject; + static serializeBinaryToWriter(message: BrokerDataPointContainer, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): BrokerDataPointContainer; + static deserializeBinaryFromReader(message: BrokerDataPointContainer, reader: jspb.BinaryReader): BrokerDataPointContainer; +} + +export namespace BrokerDataPointContainer { + export type AsObject = { + brokername: string, + timestampms: number, + groupedbrokerrequestsList: Array<BrokerRequestDataPoint.AsObject>, + } +} + +export class FtsToConsumerDataPointContainer extends jspb.Message { + getFtsname(): string; + setFtsname(value: string): FtsToConsumerDataPointContainer; + + getTimestampms(): number; + setTimestampms(value: number): FtsToConsumerDataPointContainer; + + getGroupedfdstransfersList(): Array<FdsToConsumerDataPoint>; + setGroupedfdstransfersList(value: Array<FdsToConsumerDataPoint>): FtsToConsumerDataPointContainer; + clearGroupedfdstransfersList(): FtsToConsumerDataPointContainer; + addGroupedfdstransfers(value?: FdsToConsumerDataPoint, index?: number): FdsToConsumerDataPoint; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): FtsToConsumerDataPointContainer.AsObject; + static toObject(includeInstance: boolean, msg: FtsToConsumerDataPointContainer): FtsToConsumerDataPointContainer.AsObject; + static serializeBinaryToWriter(message: FtsToConsumerDataPointContainer, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): FtsToConsumerDataPointContainer; + static deserializeBinaryFromReader(message: FtsToConsumerDataPointContainer, reader: jspb.BinaryReader): FtsToConsumerDataPointContainer; +} + +export namespace FtsToConsumerDataPointContainer { + export type AsObject = { + ftsname: string, + timestampms: number, + groupedfdstransfersList: Array<FdsToConsumerDataPoint.AsObject>, + } +} + diff --git a/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringIngestService_pb.js b/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringIngestService_pb.js new file mode 100644 index 0000000000000000000000000000000000000000..74007ae8ee9e708271df16b6059bdc37322c1ed0 --- /dev/null +++ b/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringIngestService_pb.js @@ -0,0 +1,2662 @@ +// source: AsapoMonitoringIngestService.proto +/** + * @fileoverview + * @enhanceable + * @suppress {missingRequire} reports error on implicit type usages. + * @suppress {messageConventions} JS Compiler reports an error if a variable or + * field starts with 'MSG_' and isn't a translatable message. + * @public + */ +// GENERATED CODE -- DO NOT EDIT! +/* eslint-disable */ +// @ts-nocheck + +var jspb = require('google-protobuf'); +var goog = jspb; +var global = Function('return this')(); + +var AsapoMonitoringCommonService_pb = require('./AsapoMonitoringCommonService_pb.js'); +goog.object.extend(proto, AsapoMonitoringCommonService_pb); +goog.exportSymbol('proto.BrokerDataPointContainer', null, global); +goog.exportSymbol('proto.BrokerRequestDataPoint', null, global); +goog.exportSymbol('proto.FdsToConsumerDataPoint', null, global); +goog.exportSymbol('proto.FtsToConsumerDataPointContainer', null, global); +goog.exportSymbol('proto.ProducerToReceiverTransferDataPoint', null, global); +goog.exportSymbol('proto.RdsMemoryDataPoint', null, global); +goog.exportSymbol('proto.RdsToConsumerDataPoint', null, global); +goog.exportSymbol('proto.ReceiverDataPointContainer', null, global); +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.ProducerToReceiverTransferDataPoint = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.ProducerToReceiverTransferDataPoint, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.ProducerToReceiverTransferDataPoint.displayName = 'proto.ProducerToReceiverTransferDataPoint'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.BrokerRequestDataPoint = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.BrokerRequestDataPoint, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.BrokerRequestDataPoint.displayName = 'proto.BrokerRequestDataPoint'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.RdsMemoryDataPoint = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.RdsMemoryDataPoint, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.RdsMemoryDataPoint.displayName = 'proto.RdsMemoryDataPoint'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.RdsToConsumerDataPoint = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.RdsToConsumerDataPoint, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.RdsToConsumerDataPoint.displayName = 'proto.RdsToConsumerDataPoint'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.FdsToConsumerDataPoint = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.FdsToConsumerDataPoint, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.FdsToConsumerDataPoint.displayName = 'proto.FdsToConsumerDataPoint'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.ReceiverDataPointContainer = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, proto.ReceiverDataPointContainer.repeatedFields_, null); +}; +goog.inherits(proto.ReceiverDataPointContainer, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.ReceiverDataPointContainer.displayName = 'proto.ReceiverDataPointContainer'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.BrokerDataPointContainer = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, proto.BrokerDataPointContainer.repeatedFields_, null); +}; +goog.inherits(proto.BrokerDataPointContainer, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.BrokerDataPointContainer.displayName = 'proto.BrokerDataPointContainer'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.FtsToConsumerDataPointContainer = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, proto.FtsToConsumerDataPointContainer.repeatedFields_, null); +}; +goog.inherits(proto.FtsToConsumerDataPointContainer, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.FtsToConsumerDataPointContainer.displayName = 'proto.FtsToConsumerDataPointContainer'; +} + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.ProducerToReceiverTransferDataPoint.prototype.toObject = function(opt_includeInstance) { + return proto.ProducerToReceiverTransferDataPoint.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.ProducerToReceiverTransferDataPoint} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.ProducerToReceiverTransferDataPoint.toObject = function(includeInstance, msg) { + var f, obj = { + pipelinestepid: jspb.Message.getFieldWithDefault(msg, 1, ""), + producerinstanceid: jspb.Message.getFieldWithDefault(msg, 2, ""), + beamtime: jspb.Message.getFieldWithDefault(msg, 3, ""), + source: jspb.Message.getFieldWithDefault(msg, 4, ""), + stream: jspb.Message.getFieldWithDefault(msg, 5, ""), + filecount: jspb.Message.getFieldWithDefault(msg, 6, 0), + totalfilesize: jspb.Message.getFieldWithDefault(msg, 7, 0), + totaltransferreceivetimeinmicroseconds: jspb.Message.getFieldWithDefault(msg, 8, 0), + totalwriteiotimeinmicroseconds: jspb.Message.getFieldWithDefault(msg, 9, 0), + totaldbtimeinmicroseconds: jspb.Message.getFieldWithDefault(msg, 10, 0) + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.ProducerToReceiverTransferDataPoint} + */ +proto.ProducerToReceiverTransferDataPoint.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.ProducerToReceiverTransferDataPoint; + return proto.ProducerToReceiverTransferDataPoint.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.ProducerToReceiverTransferDataPoint} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.ProducerToReceiverTransferDataPoint} + */ +proto.ProducerToReceiverTransferDataPoint.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {string} */ (reader.readString()); + msg.setPipelinestepid(value); + break; + case 2: + var value = /** @type {string} */ (reader.readString()); + msg.setProducerinstanceid(value); + break; + case 3: + var value = /** @type {string} */ (reader.readString()); + msg.setBeamtime(value); + break; + case 4: + var value = /** @type {string} */ (reader.readString()); + msg.setSource(value); + break; + case 5: + var value = /** @type {string} */ (reader.readString()); + msg.setStream(value); + break; + case 6: + var value = /** @type {number} */ (reader.readUint64()); + msg.setFilecount(value); + break; + case 7: + var value = /** @type {number} */ (reader.readUint64()); + msg.setTotalfilesize(value); + break; + case 8: + var value = /** @type {number} */ (reader.readUint64()); + msg.setTotaltransferreceivetimeinmicroseconds(value); + break; + case 9: + var value = /** @type {number} */ (reader.readUint64()); + msg.setTotalwriteiotimeinmicroseconds(value); + break; + case 10: + var value = /** @type {number} */ (reader.readUint64()); + msg.setTotaldbtimeinmicroseconds(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.ProducerToReceiverTransferDataPoint.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.ProducerToReceiverTransferDataPoint.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.ProducerToReceiverTransferDataPoint} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.ProducerToReceiverTransferDataPoint.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getPipelinestepid(); + if (f.length > 0) { + writer.writeString( + 1, + f + ); + } + f = message.getProducerinstanceid(); + if (f.length > 0) { + writer.writeString( + 2, + f + ); + } + f = message.getBeamtime(); + if (f.length > 0) { + writer.writeString( + 3, + f + ); + } + f = message.getSource(); + if (f.length > 0) { + writer.writeString( + 4, + f + ); + } + f = message.getStream(); + if (f.length > 0) { + writer.writeString( + 5, + f + ); + } + f = message.getFilecount(); + if (f !== 0) { + writer.writeUint64( + 6, + f + ); + } + f = message.getTotalfilesize(); + if (f !== 0) { + writer.writeUint64( + 7, + f + ); + } + f = message.getTotaltransferreceivetimeinmicroseconds(); + if (f !== 0) { + writer.writeUint64( + 8, + f + ); + } + f = message.getTotalwriteiotimeinmicroseconds(); + if (f !== 0) { + writer.writeUint64( + 9, + f + ); + } + f = message.getTotaldbtimeinmicroseconds(); + if (f !== 0) { + writer.writeUint64( + 10, + f + ); + } +}; + + +/** + * optional string pipelineStepId = 1; + * @return {string} + */ +proto.ProducerToReceiverTransferDataPoint.prototype.getPipelinestepid = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); +}; + + +/** + * @param {string} value + * @return {!proto.ProducerToReceiverTransferDataPoint} returns this + */ +proto.ProducerToReceiverTransferDataPoint.prototype.setPipelinestepid = function(value) { + return jspb.Message.setProto3StringField(this, 1, value); +}; + + +/** + * optional string producerInstanceId = 2; + * @return {string} + */ +proto.ProducerToReceiverTransferDataPoint.prototype.getProducerinstanceid = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, "")); +}; + + +/** + * @param {string} value + * @return {!proto.ProducerToReceiverTransferDataPoint} returns this + */ +proto.ProducerToReceiverTransferDataPoint.prototype.setProducerinstanceid = function(value) { + return jspb.Message.setProto3StringField(this, 2, value); +}; + + +/** + * optional string beamtime = 3; + * @return {string} + */ +proto.ProducerToReceiverTransferDataPoint.prototype.getBeamtime = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, "")); +}; + + +/** + * @param {string} value + * @return {!proto.ProducerToReceiverTransferDataPoint} returns this + */ +proto.ProducerToReceiverTransferDataPoint.prototype.setBeamtime = function(value) { + return jspb.Message.setProto3StringField(this, 3, value); +}; + + +/** + * optional string source = 4; + * @return {string} + */ +proto.ProducerToReceiverTransferDataPoint.prototype.getSource = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, "")); +}; + + +/** + * @param {string} value + * @return {!proto.ProducerToReceiverTransferDataPoint} returns this + */ +proto.ProducerToReceiverTransferDataPoint.prototype.setSource = function(value) { + return jspb.Message.setProto3StringField(this, 4, value); +}; + + +/** + * optional string stream = 5; + * @return {string} + */ +proto.ProducerToReceiverTransferDataPoint.prototype.getStream = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, "")); +}; + + +/** + * @param {string} value + * @return {!proto.ProducerToReceiverTransferDataPoint} returns this + */ +proto.ProducerToReceiverTransferDataPoint.prototype.setStream = function(value) { + return jspb.Message.setProto3StringField(this, 5, value); +}; + + +/** + * optional uint64 fileCount = 6; + * @return {number} + */ +proto.ProducerToReceiverTransferDataPoint.prototype.getFilecount = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 6, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.ProducerToReceiverTransferDataPoint} returns this + */ +proto.ProducerToReceiverTransferDataPoint.prototype.setFilecount = function(value) { + return jspb.Message.setProto3IntField(this, 6, value); +}; + + +/** + * optional uint64 totalFileSize = 7; + * @return {number} + */ +proto.ProducerToReceiverTransferDataPoint.prototype.getTotalfilesize = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 7, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.ProducerToReceiverTransferDataPoint} returns this + */ +proto.ProducerToReceiverTransferDataPoint.prototype.setTotalfilesize = function(value) { + return jspb.Message.setProto3IntField(this, 7, value); +}; + + +/** + * optional uint64 totalTransferReceiveTimeInMicroseconds = 8; + * @return {number} + */ +proto.ProducerToReceiverTransferDataPoint.prototype.getTotaltransferreceivetimeinmicroseconds = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 8, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.ProducerToReceiverTransferDataPoint} returns this + */ +proto.ProducerToReceiverTransferDataPoint.prototype.setTotaltransferreceivetimeinmicroseconds = function(value) { + return jspb.Message.setProto3IntField(this, 8, value); +}; + + +/** + * optional uint64 totalWriteIoTimeInMicroseconds = 9; + * @return {number} + */ +proto.ProducerToReceiverTransferDataPoint.prototype.getTotalwriteiotimeinmicroseconds = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 9, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.ProducerToReceiverTransferDataPoint} returns this + */ +proto.ProducerToReceiverTransferDataPoint.prototype.setTotalwriteiotimeinmicroseconds = function(value) { + return jspb.Message.setProto3IntField(this, 9, value); +}; + + +/** + * optional uint64 totalDbTimeInMicroseconds = 10; + * @return {number} + */ +proto.ProducerToReceiverTransferDataPoint.prototype.getTotaldbtimeinmicroseconds = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 10, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.ProducerToReceiverTransferDataPoint} returns this + */ +proto.ProducerToReceiverTransferDataPoint.prototype.setTotaldbtimeinmicroseconds = function(value) { + return jspb.Message.setProto3IntField(this, 10, value); +}; + + + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.BrokerRequestDataPoint.prototype.toObject = function(opt_includeInstance) { + return proto.BrokerRequestDataPoint.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.BrokerRequestDataPoint} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.BrokerRequestDataPoint.toObject = function(includeInstance, msg) { + var f, obj = { + pipelinestepid: jspb.Message.getFieldWithDefault(msg, 1, ""), + consumerinstanceid: jspb.Message.getFieldWithDefault(msg, 2, ""), + command: jspb.Message.getFieldWithDefault(msg, 3, ""), + beamtime: jspb.Message.getFieldWithDefault(msg, 4, ""), + source: jspb.Message.getFieldWithDefault(msg, 5, ""), + stream: jspb.Message.getFieldWithDefault(msg, 6, ""), + filecount: jspb.Message.getFieldWithDefault(msg, 7, 0), + totalfilesize: jspb.Message.getFieldWithDefault(msg, 8, 0) + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.BrokerRequestDataPoint} + */ +proto.BrokerRequestDataPoint.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.BrokerRequestDataPoint; + return proto.BrokerRequestDataPoint.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.BrokerRequestDataPoint} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.BrokerRequestDataPoint} + */ +proto.BrokerRequestDataPoint.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {string} */ (reader.readString()); + msg.setPipelinestepid(value); + break; + case 2: + var value = /** @type {string} */ (reader.readString()); + msg.setConsumerinstanceid(value); + break; + case 3: + var value = /** @type {string} */ (reader.readString()); + msg.setCommand(value); + break; + case 4: + var value = /** @type {string} */ (reader.readString()); + msg.setBeamtime(value); + break; + case 5: + var value = /** @type {string} */ (reader.readString()); + msg.setSource(value); + break; + case 6: + var value = /** @type {string} */ (reader.readString()); + msg.setStream(value); + break; + case 7: + var value = /** @type {number} */ (reader.readUint64()); + msg.setFilecount(value); + break; + case 8: + var value = /** @type {number} */ (reader.readUint64()); + msg.setTotalfilesize(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.BrokerRequestDataPoint.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.BrokerRequestDataPoint.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.BrokerRequestDataPoint} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.BrokerRequestDataPoint.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getPipelinestepid(); + if (f.length > 0) { + writer.writeString( + 1, + f + ); + } + f = message.getConsumerinstanceid(); + if (f.length > 0) { + writer.writeString( + 2, + f + ); + } + f = message.getCommand(); + if (f.length > 0) { + writer.writeString( + 3, + f + ); + } + f = message.getBeamtime(); + if (f.length > 0) { + writer.writeString( + 4, + f + ); + } + f = message.getSource(); + if (f.length > 0) { + writer.writeString( + 5, + f + ); + } + f = message.getStream(); + if (f.length > 0) { + writer.writeString( + 6, + f + ); + } + f = message.getFilecount(); + if (f !== 0) { + writer.writeUint64( + 7, + f + ); + } + f = message.getTotalfilesize(); + if (f !== 0) { + writer.writeUint64( + 8, + f + ); + } +}; + + +/** + * optional string pipelineStepId = 1; + * @return {string} + */ +proto.BrokerRequestDataPoint.prototype.getPipelinestepid = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); +}; + + +/** + * @param {string} value + * @return {!proto.BrokerRequestDataPoint} returns this + */ +proto.BrokerRequestDataPoint.prototype.setPipelinestepid = function(value) { + return jspb.Message.setProto3StringField(this, 1, value); +}; + + +/** + * optional string consumerInstanceId = 2; + * @return {string} + */ +proto.BrokerRequestDataPoint.prototype.getConsumerinstanceid = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, "")); +}; + + +/** + * @param {string} value + * @return {!proto.BrokerRequestDataPoint} returns this + */ +proto.BrokerRequestDataPoint.prototype.setConsumerinstanceid = function(value) { + return jspb.Message.setProto3StringField(this, 2, value); +}; + + +/** + * optional string command = 3; + * @return {string} + */ +proto.BrokerRequestDataPoint.prototype.getCommand = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, "")); +}; + + +/** + * @param {string} value + * @return {!proto.BrokerRequestDataPoint} returns this + */ +proto.BrokerRequestDataPoint.prototype.setCommand = function(value) { + return jspb.Message.setProto3StringField(this, 3, value); +}; + + +/** + * optional string beamtime = 4; + * @return {string} + */ +proto.BrokerRequestDataPoint.prototype.getBeamtime = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, "")); +}; + + +/** + * @param {string} value + * @return {!proto.BrokerRequestDataPoint} returns this + */ +proto.BrokerRequestDataPoint.prototype.setBeamtime = function(value) { + return jspb.Message.setProto3StringField(this, 4, value); +}; + + +/** + * optional string source = 5; + * @return {string} + */ +proto.BrokerRequestDataPoint.prototype.getSource = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, "")); +}; + + +/** + * @param {string} value + * @return {!proto.BrokerRequestDataPoint} returns this + */ +proto.BrokerRequestDataPoint.prototype.setSource = function(value) { + return jspb.Message.setProto3StringField(this, 5, value); +}; + + +/** + * optional string stream = 6; + * @return {string} + */ +proto.BrokerRequestDataPoint.prototype.getStream = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, "")); +}; + + +/** + * @param {string} value + * @return {!proto.BrokerRequestDataPoint} returns this + */ +proto.BrokerRequestDataPoint.prototype.setStream = function(value) { + return jspb.Message.setProto3StringField(this, 6, value); +}; + + +/** + * optional uint64 fileCount = 7; + * @return {number} + */ +proto.BrokerRequestDataPoint.prototype.getFilecount = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 7, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.BrokerRequestDataPoint} returns this + */ +proto.BrokerRequestDataPoint.prototype.setFilecount = function(value) { + return jspb.Message.setProto3IntField(this, 7, value); +}; + + +/** + * optional uint64 totalFileSize = 8; + * @return {number} + */ +proto.BrokerRequestDataPoint.prototype.getTotalfilesize = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 8, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.BrokerRequestDataPoint} returns this + */ +proto.BrokerRequestDataPoint.prototype.setTotalfilesize = function(value) { + return jspb.Message.setProto3IntField(this, 8, value); +}; + + + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.RdsMemoryDataPoint.prototype.toObject = function(opt_includeInstance) { + return proto.RdsMemoryDataPoint.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.RdsMemoryDataPoint} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.RdsMemoryDataPoint.toObject = function(includeInstance, msg) { + var f, obj = { + beamtime: jspb.Message.getFieldWithDefault(msg, 1, ""), + source: jspb.Message.getFieldWithDefault(msg, 2, ""), + stream: jspb.Message.getFieldWithDefault(msg, 3, ""), + usedbytes: jspb.Message.getFieldWithDefault(msg, 4, 0), + totalbytes: jspb.Message.getFieldWithDefault(msg, 5, 0) + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.RdsMemoryDataPoint} + */ +proto.RdsMemoryDataPoint.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.RdsMemoryDataPoint; + return proto.RdsMemoryDataPoint.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.RdsMemoryDataPoint} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.RdsMemoryDataPoint} + */ +proto.RdsMemoryDataPoint.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {string} */ (reader.readString()); + msg.setBeamtime(value); + break; + case 2: + var value = /** @type {string} */ (reader.readString()); + msg.setSource(value); + break; + case 3: + var value = /** @type {string} */ (reader.readString()); + msg.setStream(value); + break; + case 4: + var value = /** @type {number} */ (reader.readUint64()); + msg.setUsedbytes(value); + break; + case 5: + var value = /** @type {number} */ (reader.readUint64()); + msg.setTotalbytes(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.RdsMemoryDataPoint.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.RdsMemoryDataPoint.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.RdsMemoryDataPoint} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.RdsMemoryDataPoint.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getBeamtime(); + if (f.length > 0) { + writer.writeString( + 1, + f + ); + } + f = message.getSource(); + if (f.length > 0) { + writer.writeString( + 2, + f + ); + } + f = message.getStream(); + if (f.length > 0) { + writer.writeString( + 3, + f + ); + } + f = message.getUsedbytes(); + if (f !== 0) { + writer.writeUint64( + 4, + f + ); + } + f = message.getTotalbytes(); + if (f !== 0) { + writer.writeUint64( + 5, + f + ); + } +}; + + +/** + * optional string beamtime = 1; + * @return {string} + */ +proto.RdsMemoryDataPoint.prototype.getBeamtime = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); +}; + + +/** + * @param {string} value + * @return {!proto.RdsMemoryDataPoint} returns this + */ +proto.RdsMemoryDataPoint.prototype.setBeamtime = function(value) { + return jspb.Message.setProto3StringField(this, 1, value); +}; + + +/** + * optional string source = 2; + * @return {string} + */ +proto.RdsMemoryDataPoint.prototype.getSource = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, "")); +}; + + +/** + * @param {string} value + * @return {!proto.RdsMemoryDataPoint} returns this + */ +proto.RdsMemoryDataPoint.prototype.setSource = function(value) { + return jspb.Message.setProto3StringField(this, 2, value); +}; + + +/** + * optional string stream = 3; + * @return {string} + */ +proto.RdsMemoryDataPoint.prototype.getStream = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, "")); +}; + + +/** + * @param {string} value + * @return {!proto.RdsMemoryDataPoint} returns this + */ +proto.RdsMemoryDataPoint.prototype.setStream = function(value) { + return jspb.Message.setProto3StringField(this, 3, value); +}; + + +/** + * optional uint64 usedBytes = 4; + * @return {number} + */ +proto.RdsMemoryDataPoint.prototype.getUsedbytes = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.RdsMemoryDataPoint} returns this + */ +proto.RdsMemoryDataPoint.prototype.setUsedbytes = function(value) { + return jspb.Message.setProto3IntField(this, 4, value); +}; + + +/** + * optional uint64 totalBytes = 5; + * @return {number} + */ +proto.RdsMemoryDataPoint.prototype.getTotalbytes = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 5, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.RdsMemoryDataPoint} returns this + */ +proto.RdsMemoryDataPoint.prototype.setTotalbytes = function(value) { + return jspb.Message.setProto3IntField(this, 5, value); +}; + + + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.RdsToConsumerDataPoint.prototype.toObject = function(opt_includeInstance) { + return proto.RdsToConsumerDataPoint.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.RdsToConsumerDataPoint} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.RdsToConsumerDataPoint.toObject = function(includeInstance, msg) { + var f, obj = { + pipelinestepid: jspb.Message.getFieldWithDefault(msg, 1, ""), + consumerinstanceid: jspb.Message.getFieldWithDefault(msg, 2, ""), + beamtime: jspb.Message.getFieldWithDefault(msg, 3, ""), + source: jspb.Message.getFieldWithDefault(msg, 4, ""), + stream: jspb.Message.getFieldWithDefault(msg, 5, ""), + hits: jspb.Message.getFieldWithDefault(msg, 6, 0), + misses: jspb.Message.getFieldWithDefault(msg, 7, 0), + totalfilesize: jspb.Message.getFieldWithDefault(msg, 8, 0), + totaltransfersendtimeinmicroseconds: jspb.Message.getFieldWithDefault(msg, 9, 0) + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.RdsToConsumerDataPoint} + */ +proto.RdsToConsumerDataPoint.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.RdsToConsumerDataPoint; + return proto.RdsToConsumerDataPoint.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.RdsToConsumerDataPoint} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.RdsToConsumerDataPoint} + */ +proto.RdsToConsumerDataPoint.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {string} */ (reader.readString()); + msg.setPipelinestepid(value); + break; + case 2: + var value = /** @type {string} */ (reader.readString()); + msg.setConsumerinstanceid(value); + break; + case 3: + var value = /** @type {string} */ (reader.readString()); + msg.setBeamtime(value); + break; + case 4: + var value = /** @type {string} */ (reader.readString()); + msg.setSource(value); + break; + case 5: + var value = /** @type {string} */ (reader.readString()); + msg.setStream(value); + break; + case 6: + var value = /** @type {number} */ (reader.readUint64()); + msg.setHits(value); + break; + case 7: + var value = /** @type {number} */ (reader.readUint64()); + msg.setMisses(value); + break; + case 8: + var value = /** @type {number} */ (reader.readUint64()); + msg.setTotalfilesize(value); + break; + case 9: + var value = /** @type {number} */ (reader.readUint64()); + msg.setTotaltransfersendtimeinmicroseconds(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.RdsToConsumerDataPoint.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.RdsToConsumerDataPoint.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.RdsToConsumerDataPoint} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.RdsToConsumerDataPoint.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getPipelinestepid(); + if (f.length > 0) { + writer.writeString( + 1, + f + ); + } + f = message.getConsumerinstanceid(); + if (f.length > 0) { + writer.writeString( + 2, + f + ); + } + f = message.getBeamtime(); + if (f.length > 0) { + writer.writeString( + 3, + f + ); + } + f = message.getSource(); + if (f.length > 0) { + writer.writeString( + 4, + f + ); + } + f = message.getStream(); + if (f.length > 0) { + writer.writeString( + 5, + f + ); + } + f = message.getHits(); + if (f !== 0) { + writer.writeUint64( + 6, + f + ); + } + f = message.getMisses(); + if (f !== 0) { + writer.writeUint64( + 7, + f + ); + } + f = message.getTotalfilesize(); + if (f !== 0) { + writer.writeUint64( + 8, + f + ); + } + f = message.getTotaltransfersendtimeinmicroseconds(); + if (f !== 0) { + writer.writeUint64( + 9, + f + ); + } +}; + + +/** + * optional string pipelineStepId = 1; + * @return {string} + */ +proto.RdsToConsumerDataPoint.prototype.getPipelinestepid = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); +}; + + +/** + * @param {string} value + * @return {!proto.RdsToConsumerDataPoint} returns this + */ +proto.RdsToConsumerDataPoint.prototype.setPipelinestepid = function(value) { + return jspb.Message.setProto3StringField(this, 1, value); +}; + + +/** + * optional string consumerInstanceId = 2; + * @return {string} + */ +proto.RdsToConsumerDataPoint.prototype.getConsumerinstanceid = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, "")); +}; + + +/** + * @param {string} value + * @return {!proto.RdsToConsumerDataPoint} returns this + */ +proto.RdsToConsumerDataPoint.prototype.setConsumerinstanceid = function(value) { + return jspb.Message.setProto3StringField(this, 2, value); +}; + + +/** + * optional string beamtime = 3; + * @return {string} + */ +proto.RdsToConsumerDataPoint.prototype.getBeamtime = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, "")); +}; + + +/** + * @param {string} value + * @return {!proto.RdsToConsumerDataPoint} returns this + */ +proto.RdsToConsumerDataPoint.prototype.setBeamtime = function(value) { + return jspb.Message.setProto3StringField(this, 3, value); +}; + + +/** + * optional string source = 4; + * @return {string} + */ +proto.RdsToConsumerDataPoint.prototype.getSource = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, "")); +}; + + +/** + * @param {string} value + * @return {!proto.RdsToConsumerDataPoint} returns this + */ +proto.RdsToConsumerDataPoint.prototype.setSource = function(value) { + return jspb.Message.setProto3StringField(this, 4, value); +}; + + +/** + * optional string stream = 5; + * @return {string} + */ +proto.RdsToConsumerDataPoint.prototype.getStream = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, "")); +}; + + +/** + * @param {string} value + * @return {!proto.RdsToConsumerDataPoint} returns this + */ +proto.RdsToConsumerDataPoint.prototype.setStream = function(value) { + return jspb.Message.setProto3StringField(this, 5, value); +}; + + +/** + * optional uint64 hits = 6; + * @return {number} + */ +proto.RdsToConsumerDataPoint.prototype.getHits = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 6, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.RdsToConsumerDataPoint} returns this + */ +proto.RdsToConsumerDataPoint.prototype.setHits = function(value) { + return jspb.Message.setProto3IntField(this, 6, value); +}; + + +/** + * optional uint64 misses = 7; + * @return {number} + */ +proto.RdsToConsumerDataPoint.prototype.getMisses = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 7, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.RdsToConsumerDataPoint} returns this + */ +proto.RdsToConsumerDataPoint.prototype.setMisses = function(value) { + return jspb.Message.setProto3IntField(this, 7, value); +}; + + +/** + * optional uint64 totalFileSize = 8; + * @return {number} + */ +proto.RdsToConsumerDataPoint.prototype.getTotalfilesize = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 8, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.RdsToConsumerDataPoint} returns this + */ +proto.RdsToConsumerDataPoint.prototype.setTotalfilesize = function(value) { + return jspb.Message.setProto3IntField(this, 8, value); +}; + + +/** + * optional uint64 totalTransferSendTimeInMicroseconds = 9; + * @return {number} + */ +proto.RdsToConsumerDataPoint.prototype.getTotaltransfersendtimeinmicroseconds = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 9, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.RdsToConsumerDataPoint} returns this + */ +proto.RdsToConsumerDataPoint.prototype.setTotaltransfersendtimeinmicroseconds = function(value) { + return jspb.Message.setProto3IntField(this, 9, value); +}; + + + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.FdsToConsumerDataPoint.prototype.toObject = function(opt_includeInstance) { + return proto.FdsToConsumerDataPoint.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.FdsToConsumerDataPoint} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.FdsToConsumerDataPoint.toObject = function(includeInstance, msg) { + var f, obj = { + pipelinestepid: jspb.Message.getFieldWithDefault(msg, 1, ""), + consumerinstanceid: jspb.Message.getFieldWithDefault(msg, 2, ""), + beamtime: jspb.Message.getFieldWithDefault(msg, 3, ""), + source: jspb.Message.getFieldWithDefault(msg, 4, ""), + stream: jspb.Message.getFieldWithDefault(msg, 5, ""), + filecount: jspb.Message.getFieldWithDefault(msg, 6, 0), + totalfilesize: jspb.Message.getFieldWithDefault(msg, 7, 0), + totaltransfersendtimeinmicroseconds: jspb.Message.getFieldWithDefault(msg, 8, 0) + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.FdsToConsumerDataPoint} + */ +proto.FdsToConsumerDataPoint.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.FdsToConsumerDataPoint; + return proto.FdsToConsumerDataPoint.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.FdsToConsumerDataPoint} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.FdsToConsumerDataPoint} + */ +proto.FdsToConsumerDataPoint.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {string} */ (reader.readString()); + msg.setPipelinestepid(value); + break; + case 2: + var value = /** @type {string} */ (reader.readString()); + msg.setConsumerinstanceid(value); + break; + case 3: + var value = /** @type {string} */ (reader.readString()); + msg.setBeamtime(value); + break; + case 4: + var value = /** @type {string} */ (reader.readString()); + msg.setSource(value); + break; + case 5: + var value = /** @type {string} */ (reader.readString()); + msg.setStream(value); + break; + case 6: + var value = /** @type {number} */ (reader.readUint64()); + msg.setFilecount(value); + break; + case 7: + var value = /** @type {number} */ (reader.readUint64()); + msg.setTotalfilesize(value); + break; + case 8: + var value = /** @type {number} */ (reader.readUint64()); + msg.setTotaltransfersendtimeinmicroseconds(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.FdsToConsumerDataPoint.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.FdsToConsumerDataPoint.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.FdsToConsumerDataPoint} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.FdsToConsumerDataPoint.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getPipelinestepid(); + if (f.length > 0) { + writer.writeString( + 1, + f + ); + } + f = message.getConsumerinstanceid(); + if (f.length > 0) { + writer.writeString( + 2, + f + ); + } + f = message.getBeamtime(); + if (f.length > 0) { + writer.writeString( + 3, + f + ); + } + f = message.getSource(); + if (f.length > 0) { + writer.writeString( + 4, + f + ); + } + f = message.getStream(); + if (f.length > 0) { + writer.writeString( + 5, + f + ); + } + f = message.getFilecount(); + if (f !== 0) { + writer.writeUint64( + 6, + f + ); + } + f = message.getTotalfilesize(); + if (f !== 0) { + writer.writeUint64( + 7, + f + ); + } + f = message.getTotaltransfersendtimeinmicroseconds(); + if (f !== 0) { + writer.writeUint64( + 8, + f + ); + } +}; + + +/** + * optional string pipelineStepId = 1; + * @return {string} + */ +proto.FdsToConsumerDataPoint.prototype.getPipelinestepid = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); +}; + + +/** + * @param {string} value + * @return {!proto.FdsToConsumerDataPoint} returns this + */ +proto.FdsToConsumerDataPoint.prototype.setPipelinestepid = function(value) { + return jspb.Message.setProto3StringField(this, 1, value); +}; + + +/** + * optional string consumerInstanceId = 2; + * @return {string} + */ +proto.FdsToConsumerDataPoint.prototype.getConsumerinstanceid = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, "")); +}; + + +/** + * @param {string} value + * @return {!proto.FdsToConsumerDataPoint} returns this + */ +proto.FdsToConsumerDataPoint.prototype.setConsumerinstanceid = function(value) { + return jspb.Message.setProto3StringField(this, 2, value); +}; + + +/** + * optional string beamtime = 3; + * @return {string} + */ +proto.FdsToConsumerDataPoint.prototype.getBeamtime = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, "")); +}; + + +/** + * @param {string} value + * @return {!proto.FdsToConsumerDataPoint} returns this + */ +proto.FdsToConsumerDataPoint.prototype.setBeamtime = function(value) { + return jspb.Message.setProto3StringField(this, 3, value); +}; + + +/** + * optional string source = 4; + * @return {string} + */ +proto.FdsToConsumerDataPoint.prototype.getSource = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, "")); +}; + + +/** + * @param {string} value + * @return {!proto.FdsToConsumerDataPoint} returns this + */ +proto.FdsToConsumerDataPoint.prototype.setSource = function(value) { + return jspb.Message.setProto3StringField(this, 4, value); +}; + + +/** + * optional string stream = 5; + * @return {string} + */ +proto.FdsToConsumerDataPoint.prototype.getStream = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, "")); +}; + + +/** + * @param {string} value + * @return {!proto.FdsToConsumerDataPoint} returns this + */ +proto.FdsToConsumerDataPoint.prototype.setStream = function(value) { + return jspb.Message.setProto3StringField(this, 5, value); +}; + + +/** + * optional uint64 fileCount = 6; + * @return {number} + */ +proto.FdsToConsumerDataPoint.prototype.getFilecount = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 6, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.FdsToConsumerDataPoint} returns this + */ +proto.FdsToConsumerDataPoint.prototype.setFilecount = function(value) { + return jspb.Message.setProto3IntField(this, 6, value); +}; + + +/** + * optional uint64 totalFileSize = 7; + * @return {number} + */ +proto.FdsToConsumerDataPoint.prototype.getTotalfilesize = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 7, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.FdsToConsumerDataPoint} returns this + */ +proto.FdsToConsumerDataPoint.prototype.setTotalfilesize = function(value) { + return jspb.Message.setProto3IntField(this, 7, value); +}; + + +/** + * optional uint64 totalTransferSendTimeInMicroseconds = 8; + * @return {number} + */ +proto.FdsToConsumerDataPoint.prototype.getTotaltransfersendtimeinmicroseconds = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 8, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.FdsToConsumerDataPoint} returns this + */ +proto.FdsToConsumerDataPoint.prototype.setTotaltransfersendtimeinmicroseconds = function(value) { + return jspb.Message.setProto3IntField(this, 8, value); +}; + + + +/** + * List of repeated fields within this message type. + * @private {!Array<number>} + * @const + */ +proto.ReceiverDataPointContainer.repeatedFields_ = [3,4,5]; + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.ReceiverDataPointContainer.prototype.toObject = function(opt_includeInstance) { + return proto.ReceiverDataPointContainer.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.ReceiverDataPointContainer} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.ReceiverDataPointContainer.toObject = function(includeInstance, msg) { + var f, obj = { + receivername: jspb.Message.getFieldWithDefault(msg, 1, ""), + timestampms: jspb.Message.getFieldWithDefault(msg, 2, 0), + groupedp2rtransfersList: jspb.Message.toObjectList(msg.getGroupedp2rtransfersList(), + proto.ProducerToReceiverTransferDataPoint.toObject, includeInstance), + groupedrds2ctransfersList: jspb.Message.toObjectList(msg.getGroupedrds2ctransfersList(), + proto.RdsToConsumerDataPoint.toObject, includeInstance), + groupedmemorystatsList: jspb.Message.toObjectList(msg.getGroupedmemorystatsList(), + proto.RdsMemoryDataPoint.toObject, includeInstance) + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.ReceiverDataPointContainer} + */ +proto.ReceiverDataPointContainer.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.ReceiverDataPointContainer; + return proto.ReceiverDataPointContainer.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.ReceiverDataPointContainer} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.ReceiverDataPointContainer} + */ +proto.ReceiverDataPointContainer.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {string} */ (reader.readString()); + msg.setReceivername(value); + break; + case 2: + var value = /** @type {number} */ (reader.readUint64()); + msg.setTimestampms(value); + break; + case 3: + var value = new proto.ProducerToReceiverTransferDataPoint; + reader.readMessage(value,proto.ProducerToReceiverTransferDataPoint.deserializeBinaryFromReader); + msg.addGroupedp2rtransfers(value); + break; + case 4: + var value = new proto.RdsToConsumerDataPoint; + reader.readMessage(value,proto.RdsToConsumerDataPoint.deserializeBinaryFromReader); + msg.addGroupedrds2ctransfers(value); + break; + case 5: + var value = new proto.RdsMemoryDataPoint; + reader.readMessage(value,proto.RdsMemoryDataPoint.deserializeBinaryFromReader); + msg.addGroupedmemorystats(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.ReceiverDataPointContainer.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.ReceiverDataPointContainer.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.ReceiverDataPointContainer} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.ReceiverDataPointContainer.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getReceivername(); + if (f.length > 0) { + writer.writeString( + 1, + f + ); + } + f = message.getTimestampms(); + if (f !== 0) { + writer.writeUint64( + 2, + f + ); + } + f = message.getGroupedp2rtransfersList(); + if (f.length > 0) { + writer.writeRepeatedMessage( + 3, + f, + proto.ProducerToReceiverTransferDataPoint.serializeBinaryToWriter + ); + } + f = message.getGroupedrds2ctransfersList(); + if (f.length > 0) { + writer.writeRepeatedMessage( + 4, + f, + proto.RdsToConsumerDataPoint.serializeBinaryToWriter + ); + } + f = message.getGroupedmemorystatsList(); + if (f.length > 0) { + writer.writeRepeatedMessage( + 5, + f, + proto.RdsMemoryDataPoint.serializeBinaryToWriter + ); + } +}; + + +/** + * optional string receiverName = 1; + * @return {string} + */ +proto.ReceiverDataPointContainer.prototype.getReceivername = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); +}; + + +/** + * @param {string} value + * @return {!proto.ReceiverDataPointContainer} returns this + */ +proto.ReceiverDataPointContainer.prototype.setReceivername = function(value) { + return jspb.Message.setProto3StringField(this, 1, value); +}; + + +/** + * optional uint64 timestampMs = 2; + * @return {number} + */ +proto.ReceiverDataPointContainer.prototype.getTimestampms = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.ReceiverDataPointContainer} returns this + */ +proto.ReceiverDataPointContainer.prototype.setTimestampms = function(value) { + return jspb.Message.setProto3IntField(this, 2, value); +}; + + +/** + * repeated ProducerToReceiverTransferDataPoint groupedP2rTransfers = 3; + * @return {!Array<!proto.ProducerToReceiverTransferDataPoint>} + */ +proto.ReceiverDataPointContainer.prototype.getGroupedp2rtransfersList = function() { + return /** @type{!Array<!proto.ProducerToReceiverTransferDataPoint>} */ ( + jspb.Message.getRepeatedWrapperField(this, proto.ProducerToReceiverTransferDataPoint, 3)); +}; + + +/** + * @param {!Array<!proto.ProducerToReceiverTransferDataPoint>} value + * @return {!proto.ReceiverDataPointContainer} returns this +*/ +proto.ReceiverDataPointContainer.prototype.setGroupedp2rtransfersList = function(value) { + return jspb.Message.setRepeatedWrapperField(this, 3, value); +}; + + +/** + * @param {!proto.ProducerToReceiverTransferDataPoint=} opt_value + * @param {number=} opt_index + * @return {!proto.ProducerToReceiverTransferDataPoint} + */ +proto.ReceiverDataPointContainer.prototype.addGroupedp2rtransfers = function(opt_value, opt_index) { + return jspb.Message.addToRepeatedWrapperField(this, 3, opt_value, proto.ProducerToReceiverTransferDataPoint, opt_index); +}; + + +/** + * Clears the list making it empty but non-null. + * @return {!proto.ReceiverDataPointContainer} returns this + */ +proto.ReceiverDataPointContainer.prototype.clearGroupedp2rtransfersList = function() { + return this.setGroupedp2rtransfersList([]); +}; + + +/** + * repeated RdsToConsumerDataPoint groupedRds2cTransfers = 4; + * @return {!Array<!proto.RdsToConsumerDataPoint>} + */ +proto.ReceiverDataPointContainer.prototype.getGroupedrds2ctransfersList = function() { + return /** @type{!Array<!proto.RdsToConsumerDataPoint>} */ ( + jspb.Message.getRepeatedWrapperField(this, proto.RdsToConsumerDataPoint, 4)); +}; + + +/** + * @param {!Array<!proto.RdsToConsumerDataPoint>} value + * @return {!proto.ReceiverDataPointContainer} returns this +*/ +proto.ReceiverDataPointContainer.prototype.setGroupedrds2ctransfersList = function(value) { + return jspb.Message.setRepeatedWrapperField(this, 4, value); +}; + + +/** + * @param {!proto.RdsToConsumerDataPoint=} opt_value + * @param {number=} opt_index + * @return {!proto.RdsToConsumerDataPoint} + */ +proto.ReceiverDataPointContainer.prototype.addGroupedrds2ctransfers = function(opt_value, opt_index) { + return jspb.Message.addToRepeatedWrapperField(this, 4, opt_value, proto.RdsToConsumerDataPoint, opt_index); +}; + + +/** + * Clears the list making it empty but non-null. + * @return {!proto.ReceiverDataPointContainer} returns this + */ +proto.ReceiverDataPointContainer.prototype.clearGroupedrds2ctransfersList = function() { + return this.setGroupedrds2ctransfersList([]); +}; + + +/** + * repeated RdsMemoryDataPoint groupedMemoryStats = 5; + * @return {!Array<!proto.RdsMemoryDataPoint>} + */ +proto.ReceiverDataPointContainer.prototype.getGroupedmemorystatsList = function() { + return /** @type{!Array<!proto.RdsMemoryDataPoint>} */ ( + jspb.Message.getRepeatedWrapperField(this, proto.RdsMemoryDataPoint, 5)); +}; + + +/** + * @param {!Array<!proto.RdsMemoryDataPoint>} value + * @return {!proto.ReceiverDataPointContainer} returns this +*/ +proto.ReceiverDataPointContainer.prototype.setGroupedmemorystatsList = function(value) { + return jspb.Message.setRepeatedWrapperField(this, 5, value); +}; + + +/** + * @param {!proto.RdsMemoryDataPoint=} opt_value + * @param {number=} opt_index + * @return {!proto.RdsMemoryDataPoint} + */ +proto.ReceiverDataPointContainer.prototype.addGroupedmemorystats = function(opt_value, opt_index) { + return jspb.Message.addToRepeatedWrapperField(this, 5, opt_value, proto.RdsMemoryDataPoint, opt_index); +}; + + +/** + * Clears the list making it empty but non-null. + * @return {!proto.ReceiverDataPointContainer} returns this + */ +proto.ReceiverDataPointContainer.prototype.clearGroupedmemorystatsList = function() { + return this.setGroupedmemorystatsList([]); +}; + + + +/** + * List of repeated fields within this message type. + * @private {!Array<number>} + * @const + */ +proto.BrokerDataPointContainer.repeatedFields_ = [3]; + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.BrokerDataPointContainer.prototype.toObject = function(opt_includeInstance) { + return proto.BrokerDataPointContainer.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.BrokerDataPointContainer} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.BrokerDataPointContainer.toObject = function(includeInstance, msg) { + var f, obj = { + brokername: jspb.Message.getFieldWithDefault(msg, 1, ""), + timestampms: jspb.Message.getFieldWithDefault(msg, 2, 0), + groupedbrokerrequestsList: jspb.Message.toObjectList(msg.getGroupedbrokerrequestsList(), + proto.BrokerRequestDataPoint.toObject, includeInstance) + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.BrokerDataPointContainer} + */ +proto.BrokerDataPointContainer.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.BrokerDataPointContainer; + return proto.BrokerDataPointContainer.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.BrokerDataPointContainer} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.BrokerDataPointContainer} + */ +proto.BrokerDataPointContainer.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {string} */ (reader.readString()); + msg.setBrokername(value); + break; + case 2: + var value = /** @type {number} */ (reader.readUint64()); + msg.setTimestampms(value); + break; + case 3: + var value = new proto.BrokerRequestDataPoint; + reader.readMessage(value,proto.BrokerRequestDataPoint.deserializeBinaryFromReader); + msg.addGroupedbrokerrequests(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.BrokerDataPointContainer.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.BrokerDataPointContainer.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.BrokerDataPointContainer} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.BrokerDataPointContainer.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getBrokername(); + if (f.length > 0) { + writer.writeString( + 1, + f + ); + } + f = message.getTimestampms(); + if (f !== 0) { + writer.writeUint64( + 2, + f + ); + } + f = message.getGroupedbrokerrequestsList(); + if (f.length > 0) { + writer.writeRepeatedMessage( + 3, + f, + proto.BrokerRequestDataPoint.serializeBinaryToWriter + ); + } +}; + + +/** + * optional string brokerName = 1; + * @return {string} + */ +proto.BrokerDataPointContainer.prototype.getBrokername = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); +}; + + +/** + * @param {string} value + * @return {!proto.BrokerDataPointContainer} returns this + */ +proto.BrokerDataPointContainer.prototype.setBrokername = function(value) { + return jspb.Message.setProto3StringField(this, 1, value); +}; + + +/** + * optional uint64 timestampMs = 2; + * @return {number} + */ +proto.BrokerDataPointContainer.prototype.getTimestampms = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.BrokerDataPointContainer} returns this + */ +proto.BrokerDataPointContainer.prototype.setTimestampms = function(value) { + return jspb.Message.setProto3IntField(this, 2, value); +}; + + +/** + * repeated BrokerRequestDataPoint groupedBrokerRequests = 3; + * @return {!Array<!proto.BrokerRequestDataPoint>} + */ +proto.BrokerDataPointContainer.prototype.getGroupedbrokerrequestsList = function() { + return /** @type{!Array<!proto.BrokerRequestDataPoint>} */ ( + jspb.Message.getRepeatedWrapperField(this, proto.BrokerRequestDataPoint, 3)); +}; + + +/** + * @param {!Array<!proto.BrokerRequestDataPoint>} value + * @return {!proto.BrokerDataPointContainer} returns this +*/ +proto.BrokerDataPointContainer.prototype.setGroupedbrokerrequestsList = function(value) { + return jspb.Message.setRepeatedWrapperField(this, 3, value); +}; + + +/** + * @param {!proto.BrokerRequestDataPoint=} opt_value + * @param {number=} opt_index + * @return {!proto.BrokerRequestDataPoint} + */ +proto.BrokerDataPointContainer.prototype.addGroupedbrokerrequests = function(opt_value, opt_index) { + return jspb.Message.addToRepeatedWrapperField(this, 3, opt_value, proto.BrokerRequestDataPoint, opt_index); +}; + + +/** + * Clears the list making it empty but non-null. + * @return {!proto.BrokerDataPointContainer} returns this + */ +proto.BrokerDataPointContainer.prototype.clearGroupedbrokerrequestsList = function() { + return this.setGroupedbrokerrequestsList([]); +}; + + + +/** + * List of repeated fields within this message type. + * @private {!Array<number>} + * @const + */ +proto.FtsToConsumerDataPointContainer.repeatedFields_ = [3]; + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.FtsToConsumerDataPointContainer.prototype.toObject = function(opt_includeInstance) { + return proto.FtsToConsumerDataPointContainer.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.FtsToConsumerDataPointContainer} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.FtsToConsumerDataPointContainer.toObject = function(includeInstance, msg) { + var f, obj = { + ftsname: jspb.Message.getFieldWithDefault(msg, 1, ""), + timestampms: jspb.Message.getFieldWithDefault(msg, 2, 0), + groupedfdstransfersList: jspb.Message.toObjectList(msg.getGroupedfdstransfersList(), + proto.FdsToConsumerDataPoint.toObject, includeInstance) + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.FtsToConsumerDataPointContainer} + */ +proto.FtsToConsumerDataPointContainer.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.FtsToConsumerDataPointContainer; + return proto.FtsToConsumerDataPointContainer.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.FtsToConsumerDataPointContainer} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.FtsToConsumerDataPointContainer} + */ +proto.FtsToConsumerDataPointContainer.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {string} */ (reader.readString()); + msg.setFtsname(value); + break; + case 2: + var value = /** @type {number} */ (reader.readUint64()); + msg.setTimestampms(value); + break; + case 3: + var value = new proto.FdsToConsumerDataPoint; + reader.readMessage(value,proto.FdsToConsumerDataPoint.deserializeBinaryFromReader); + msg.addGroupedfdstransfers(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.FtsToConsumerDataPointContainer.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.FtsToConsumerDataPointContainer.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.FtsToConsumerDataPointContainer} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.FtsToConsumerDataPointContainer.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getFtsname(); + if (f.length > 0) { + writer.writeString( + 1, + f + ); + } + f = message.getTimestampms(); + if (f !== 0) { + writer.writeUint64( + 2, + f + ); + } + f = message.getGroupedfdstransfersList(); + if (f.length > 0) { + writer.writeRepeatedMessage( + 3, + f, + proto.FdsToConsumerDataPoint.serializeBinaryToWriter + ); + } +}; + + +/** + * optional string ftsName = 1; + * @return {string} + */ +proto.FtsToConsumerDataPointContainer.prototype.getFtsname = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); +}; + + +/** + * @param {string} value + * @return {!proto.FtsToConsumerDataPointContainer} returns this + */ +proto.FtsToConsumerDataPointContainer.prototype.setFtsname = function(value) { + return jspb.Message.setProto3StringField(this, 1, value); +}; + + +/** + * optional uint64 timestampMs = 2; + * @return {number} + */ +proto.FtsToConsumerDataPointContainer.prototype.getTimestampms = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.FtsToConsumerDataPointContainer} returns this + */ +proto.FtsToConsumerDataPointContainer.prototype.setTimestampms = function(value) { + return jspb.Message.setProto3IntField(this, 2, value); +}; + + +/** + * repeated FdsToConsumerDataPoint groupedFdsTransfers = 3; + * @return {!Array<!proto.FdsToConsumerDataPoint>} + */ +proto.FtsToConsumerDataPointContainer.prototype.getGroupedfdstransfersList = function() { + return /** @type{!Array<!proto.FdsToConsumerDataPoint>} */ ( + jspb.Message.getRepeatedWrapperField(this, proto.FdsToConsumerDataPoint, 3)); +}; + + +/** + * @param {!Array<!proto.FdsToConsumerDataPoint>} value + * @return {!proto.FtsToConsumerDataPointContainer} returns this +*/ +proto.FtsToConsumerDataPointContainer.prototype.setGroupedfdstransfersList = function(value) { + return jspb.Message.setRepeatedWrapperField(this, 3, value); +}; + + +/** + * @param {!proto.FdsToConsumerDataPoint=} opt_value + * @param {number=} opt_index + * @return {!proto.FdsToConsumerDataPoint} + */ +proto.FtsToConsumerDataPointContainer.prototype.addGroupedfdstransfers = function(opt_value, opt_index) { + return jspb.Message.addToRepeatedWrapperField(this, 3, opt_value, proto.FdsToConsumerDataPoint, opt_index); +}; + + +/** + * Clears the list making it empty but non-null. + * @return {!proto.FtsToConsumerDataPointContainer} returns this + */ +proto.FtsToConsumerDataPointContainer.prototype.clearGroupedfdstransfersList = function() { + return this.setGroupedfdstransfersList([]); +}; + + +goog.object.extend(exports, proto); diff --git a/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringQueryService_grpc_web_pb.d.ts b/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringQueryService_grpc_web_pb.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..9cf0303ad5c20b969e1ff629757da3cf301237e8 --- /dev/null +++ b/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringQueryService_grpc_web_pb.d.ts @@ -0,0 +1,56 @@ +import * as grpcWeb from 'grpc-web'; + +import * as AsapoMonitoringCommonService_pb from './AsapoMonitoringCommonService_pb'; +import * as AsapoMonitoringQueryService_pb from './AsapoMonitoringQueryService_pb'; + + +export class AsapoMonitoringQueryServiceClient { + constructor (hostname: string, + credentials?: null | { [index: string]: string; }, + options?: null | { [index: string]: any; }); + + getMetadata( + request: AsapoMonitoringCommonService_pb.Empty, + metadata: grpcWeb.Metadata | undefined, + callback: (err: grpcWeb.Error, + response: AsapoMonitoringQueryService_pb.MetadataResponse) => void + ): grpcWeb.ClientReadableStream<AsapoMonitoringQueryService_pb.MetadataResponse>; + + getTopology( + request: AsapoMonitoringQueryService_pb.ToplogyQuery, + metadata: grpcWeb.Metadata | undefined, + callback: (err: grpcWeb.Error, + response: AsapoMonitoringQueryService_pb.TopologyResponse) => void + ): grpcWeb.ClientReadableStream<AsapoMonitoringQueryService_pb.TopologyResponse>; + + getDataPoints( + request: AsapoMonitoringQueryService_pb.DataPointsQuery, + metadata: grpcWeb.Metadata | undefined, + callback: (err: grpcWeb.Error, + response: AsapoMonitoringQueryService_pb.DataPointsResponse) => void + ): grpcWeb.ClientReadableStream<AsapoMonitoringQueryService_pb.DataPointsResponse>; + +} + +export class AsapoMonitoringQueryServicePromiseClient { + constructor (hostname: string, + credentials?: null | { [index: string]: string; }, + options?: null | { [index: string]: any; }); + + getMetadata( + request: AsapoMonitoringCommonService_pb.Empty, + metadata?: grpcWeb.Metadata + ): Promise<AsapoMonitoringQueryService_pb.MetadataResponse>; + + getTopology( + request: AsapoMonitoringQueryService_pb.ToplogyQuery, + metadata?: grpcWeb.Metadata + ): Promise<AsapoMonitoringQueryService_pb.TopologyResponse>; + + getDataPoints( + request: AsapoMonitoringQueryService_pb.DataPointsQuery, + metadata?: grpcWeb.Metadata + ): Promise<AsapoMonitoringQueryService_pb.DataPointsResponse>; + +} + diff --git a/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringQueryService_grpc_web_pb.js b/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringQueryService_grpc_web_pb.js new file mode 100644 index 0000000000000000000000000000000000000000..5243339d99c51883d019c756e83b073cd61b2109 --- /dev/null +++ b/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringQueryService_grpc_web_pb.js @@ -0,0 +1,315 @@ +/** + * @fileoverview gRPC-Web generated client stub for + * @enhanceable + * @public + */ + +// GENERATED CODE -- DO NOT EDIT! + + +/* eslint-disable */ +// @ts-nocheck + + + +const grpc = {}; +grpc.web = require('grpc-web'); + + +var AsapoMonitoringCommonService_pb = require('./AsapoMonitoringCommonService_pb.js') +const proto = require('./AsapoMonitoringQueryService_pb.js'); + +/** + * @param {string} hostname + * @param {?Object} credentials + * @param {?Object} options + * @constructor + * @struct + * @final + */ +proto.AsapoMonitoringQueryServiceClient = + function(hostname, credentials, options) { + if (!options) options = {}; + options['format'] = 'text'; + + /** + * @private @const {!grpc.web.GrpcWebClientBase} The client + */ + this.client_ = new grpc.web.GrpcWebClientBase(options); + + /** + * @private @const {string} The hostname + */ + this.hostname_ = hostname; + +}; + + +/** + * @param {string} hostname + * @param {?Object} credentials + * @param {?Object} options + * @constructor + * @struct + * @final + */ +proto.AsapoMonitoringQueryServicePromiseClient = + function(hostname, credentials, options) { + if (!options) options = {}; + options['format'] = 'text'; + + /** + * @private @const {!grpc.web.GrpcWebClientBase} The client + */ + this.client_ = new grpc.web.GrpcWebClientBase(options); + + /** + * @private @const {string} The hostname + */ + this.hostname_ = hostname; + +}; + + +/** + * @const + * @type {!grpc.web.MethodDescriptor< + * !proto.Empty, + * !proto.MetadataResponse>} + */ +const methodDescriptor_AsapoMonitoringQueryService_GetMetadata = new grpc.web.MethodDescriptor( + '/AsapoMonitoringQueryService/GetMetadata', + grpc.web.MethodType.UNARY, + AsapoMonitoringCommonService_pb.Empty, + proto.MetadataResponse, + /** + * @param {!proto.Empty} request + * @return {!Uint8Array} + */ + function(request) { + return request.serializeBinary(); + }, + proto.MetadataResponse.deserializeBinary +); + + +/** + * @const + * @type {!grpc.web.AbstractClientBase.MethodInfo< + * !proto.Empty, + * !proto.MetadataResponse>} + */ +const methodInfo_AsapoMonitoringQueryService_GetMetadata = new grpc.web.AbstractClientBase.MethodInfo( + proto.MetadataResponse, + /** + * @param {!proto.Empty} request + * @return {!Uint8Array} + */ + function(request) { + return request.serializeBinary(); + }, + proto.MetadataResponse.deserializeBinary +); + + +/** + * @param {!proto.Empty} request The + * request proto + * @param {?Object<string, string>} metadata User defined + * call metadata + * @param {function(?grpc.web.Error, ?proto.MetadataResponse)} + * callback The callback function(error, response) + * @return {!grpc.web.ClientReadableStream<!proto.MetadataResponse>|undefined} + * The XHR Node Readable Stream + */ +proto.AsapoMonitoringQueryServiceClient.prototype.getMetadata = + function(request, metadata, callback) { + return this.client_.rpcCall(this.hostname_ + + '/AsapoMonitoringQueryService/GetMetadata', + request, + metadata || {}, + methodDescriptor_AsapoMonitoringQueryService_GetMetadata, + callback); +}; + + +/** + * @param {!proto.Empty} request The + * request proto + * @param {?Object<string, string>} metadata User defined + * call metadata + * @return {!Promise<!proto.MetadataResponse>} + * Promise that resolves to the response + */ +proto.AsapoMonitoringQueryServicePromiseClient.prototype.getMetadata = + function(request, metadata) { + return this.client_.unaryCall(this.hostname_ + + '/AsapoMonitoringQueryService/GetMetadata', + request, + metadata || {}, + methodDescriptor_AsapoMonitoringQueryService_GetMetadata); +}; + + +/** + * @const + * @type {!grpc.web.MethodDescriptor< + * !proto.ToplogyQuery, + * !proto.TopologyResponse>} + */ +const methodDescriptor_AsapoMonitoringQueryService_GetTopology = new grpc.web.MethodDescriptor( + '/AsapoMonitoringQueryService/GetTopology', + grpc.web.MethodType.UNARY, + proto.ToplogyQuery, + proto.TopologyResponse, + /** + * @param {!proto.ToplogyQuery} request + * @return {!Uint8Array} + */ + function(request) { + return request.serializeBinary(); + }, + proto.TopologyResponse.deserializeBinary +); + + +/** + * @const + * @type {!grpc.web.AbstractClientBase.MethodInfo< + * !proto.ToplogyQuery, + * !proto.TopologyResponse>} + */ +const methodInfo_AsapoMonitoringQueryService_GetTopology = new grpc.web.AbstractClientBase.MethodInfo( + proto.TopologyResponse, + /** + * @param {!proto.ToplogyQuery} request + * @return {!Uint8Array} + */ + function(request) { + return request.serializeBinary(); + }, + proto.TopologyResponse.deserializeBinary +); + + +/** + * @param {!proto.ToplogyQuery} request The + * request proto + * @param {?Object<string, string>} metadata User defined + * call metadata + * @param {function(?grpc.web.Error, ?proto.TopologyResponse)} + * callback The callback function(error, response) + * @return {!grpc.web.ClientReadableStream<!proto.TopologyResponse>|undefined} + * The XHR Node Readable Stream + */ +proto.AsapoMonitoringQueryServiceClient.prototype.getTopology = + function(request, metadata, callback) { + return this.client_.rpcCall(this.hostname_ + + '/AsapoMonitoringQueryService/GetTopology', + request, + metadata || {}, + methodDescriptor_AsapoMonitoringQueryService_GetTopology, + callback); +}; + + +/** + * @param {!proto.ToplogyQuery} request The + * request proto + * @param {?Object<string, string>} metadata User defined + * call metadata + * @return {!Promise<!proto.TopologyResponse>} + * Promise that resolves to the response + */ +proto.AsapoMonitoringQueryServicePromiseClient.prototype.getTopology = + function(request, metadata) { + return this.client_.unaryCall(this.hostname_ + + '/AsapoMonitoringQueryService/GetTopology', + request, + metadata || {}, + methodDescriptor_AsapoMonitoringQueryService_GetTopology); +}; + + +/** + * @const + * @type {!grpc.web.MethodDescriptor< + * !proto.DataPointsQuery, + * !proto.DataPointsResponse>} + */ +const methodDescriptor_AsapoMonitoringQueryService_GetDataPoints = new grpc.web.MethodDescriptor( + '/AsapoMonitoringQueryService/GetDataPoints', + grpc.web.MethodType.UNARY, + proto.DataPointsQuery, + proto.DataPointsResponse, + /** + * @param {!proto.DataPointsQuery} request + * @return {!Uint8Array} + */ + function(request) { + return request.serializeBinary(); + }, + proto.DataPointsResponse.deserializeBinary +); + + +/** + * @const + * @type {!grpc.web.AbstractClientBase.MethodInfo< + * !proto.DataPointsQuery, + * !proto.DataPointsResponse>} + */ +const methodInfo_AsapoMonitoringQueryService_GetDataPoints = new grpc.web.AbstractClientBase.MethodInfo( + proto.DataPointsResponse, + /** + * @param {!proto.DataPointsQuery} request + * @return {!Uint8Array} + */ + function(request) { + return request.serializeBinary(); + }, + proto.DataPointsResponse.deserializeBinary +); + + +/** + * @param {!proto.DataPointsQuery} request The + * request proto + * @param {?Object<string, string>} metadata User defined + * call metadata + * @param {function(?grpc.web.Error, ?proto.DataPointsResponse)} + * callback The callback function(error, response) + * @return {!grpc.web.ClientReadableStream<!proto.DataPointsResponse>|undefined} + * The XHR Node Readable Stream + */ +proto.AsapoMonitoringQueryServiceClient.prototype.getDataPoints = + function(request, metadata, callback) { + return this.client_.rpcCall(this.hostname_ + + '/AsapoMonitoringQueryService/GetDataPoints', + request, + metadata || {}, + methodDescriptor_AsapoMonitoringQueryService_GetDataPoints, + callback); +}; + + +/** + * @param {!proto.DataPointsQuery} request The + * request proto + * @param {?Object<string, string>} metadata User defined + * call metadata + * @return {!Promise<!proto.DataPointsResponse>} + * Promise that resolves to the response + */ +proto.AsapoMonitoringQueryServicePromiseClient.prototype.getDataPoints = + function(request, metadata) { + return this.client_.unaryCall(this.hostname_ + + '/AsapoMonitoringQueryService/GetDataPoints', + request, + metadata || {}, + methodDescriptor_AsapoMonitoringQueryService_GetDataPoints); +}; + + +module.exports = proto; + diff --git a/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringQueryService_pb.d.ts b/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringQueryService_pb.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..c0268750ce019be7d06ea82688a4055bd35720e9 --- /dev/null +++ b/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringQueryService_pb.d.ts @@ -0,0 +1,356 @@ +import * as jspb from 'google-protobuf' + +import * as AsapoMonitoringCommonService_pb from './AsapoMonitoringCommonService_pb'; + + +export class DataPointsQuery extends jspb.Message { + getFromtimestamp(): number; + setFromtimestamp(value: number): DataPointsQuery; + + getTotimestamp(): number; + setTotimestamp(value: number): DataPointsQuery; + + getBeamtimefilter(): string; + setBeamtimefilter(value: string): DataPointsQuery; + + getSourcefilter(): string; + setSourcefilter(value: string): DataPointsQuery; + + getStreamfilter(): string; + setStreamfilter(value: string): DataPointsQuery; + + getReceiverfilter(): string; + setReceiverfilter(value: string): DataPointsQuery; + + getFrompipelinestepfilter(): string; + setFrompipelinestepfilter(value: string): DataPointsQuery; + + getTopipelinestepfilter(): string; + setTopipelinestepfilter(value: string): DataPointsQuery; + + getPipelinequerymode(): ipelineConnectionQueryMode; + setPipelinequerymode(value: ipelineConnectionQueryMode): DataPointsQuery; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): DataPointsQuery.AsObject; + static toObject(includeInstance: boolean, msg: DataPointsQuery): DataPointsQuery.AsObject; + static serializeBinaryToWriter(message: DataPointsQuery, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): DataPointsQuery; + static deserializeBinaryFromReader(message: DataPointsQuery, reader: jspb.BinaryReader): DataPointsQuery; +} + +export namespace DataPointsQuery { + export type AsObject = { + fromtimestamp: number, + totimestamp: number, + beamtimefilter: string, + sourcefilter: string, + streamfilter: string, + receiverfilter: string, + frompipelinestepfilter: string, + topipelinestepfilter: string, + pipelinequerymode: ipelineConnectionQueryMode, + } +} + +export class TotalTransferRateDataPoint extends jspb.Message { + getTotalbytespersecrecv(): number; + setTotalbytespersecrecv(value: number): TotalTransferRateDataPoint; + + getTotalbytespersecsend(): number; + setTotalbytespersecsend(value: number): TotalTransferRateDataPoint; + + getTotalbytespersecrdssend(): number; + setTotalbytespersecrdssend(value: number): TotalTransferRateDataPoint; + + getTotalbytespersecftssend(): number; + setTotalbytespersecftssend(value: number): TotalTransferRateDataPoint; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): TotalTransferRateDataPoint.AsObject; + static toObject(includeInstance: boolean, msg: TotalTransferRateDataPoint): TotalTransferRateDataPoint.AsObject; + static serializeBinaryToWriter(message: TotalTransferRateDataPoint, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): TotalTransferRateDataPoint; + static deserializeBinaryFromReader(message: TotalTransferRateDataPoint, reader: jspb.BinaryReader): TotalTransferRateDataPoint; +} + +export namespace TotalTransferRateDataPoint { + export type AsObject = { + totalbytespersecrecv: number, + totalbytespersecsend: number, + totalbytespersecrdssend: number, + totalbytespersecftssend: number, + } +} + +export class TotalFileRateDataPoint extends jspb.Message { + getTotalrequests(): number; + setTotalrequests(value: number): TotalFileRateDataPoint; + + getCachemisses(): number; + setCachemisses(value: number): TotalFileRateDataPoint; + + getFromcache(): number; + setFromcache(value: number): TotalFileRateDataPoint; + + getFromdisk(): number; + setFromdisk(value: number): TotalFileRateDataPoint; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): TotalFileRateDataPoint.AsObject; + static toObject(includeInstance: boolean, msg: TotalFileRateDataPoint): TotalFileRateDataPoint.AsObject; + static serializeBinaryToWriter(message: TotalFileRateDataPoint, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): TotalFileRateDataPoint; + static deserializeBinaryFromReader(message: TotalFileRateDataPoint, reader: jspb.BinaryReader): TotalFileRateDataPoint; +} + +export namespace TotalFileRateDataPoint { + export type AsObject = { + totalrequests: number, + cachemisses: number, + fromcache: number, + fromdisk: number, + } +} + +export class TaskTimeDataPoint extends jspb.Message { + getReceiveiotimeus(): number; + setReceiveiotimeus(value: number): TaskTimeDataPoint; + + getWritetodisktimeus(): number; + setWritetodisktimeus(value: number): TaskTimeDataPoint; + + getWritetodatabasetimeus(): number; + setWritetodatabasetimeus(value: number): TaskTimeDataPoint; + + getRdssendtoconsumertimeus(): number; + setRdssendtoconsumertimeus(value: number): TaskTimeDataPoint; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): TaskTimeDataPoint.AsObject; + static toObject(includeInstance: boolean, msg: TaskTimeDataPoint): TaskTimeDataPoint.AsObject; + static serializeBinaryToWriter(message: TaskTimeDataPoint, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): TaskTimeDataPoint; + static deserializeBinaryFromReader(message: TaskTimeDataPoint, reader: jspb.BinaryReader): TaskTimeDataPoint; +} + +export namespace TaskTimeDataPoint { + export type AsObject = { + receiveiotimeus: number, + writetodisktimeus: number, + writetodatabasetimeus: number, + rdssendtoconsumertimeus: number, + } +} + +export class RdsMemoryUsageDataPoint extends jspb.Message { + getTotalusedmemory(): number; + setTotalusedmemory(value: number): RdsMemoryUsageDataPoint; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): RdsMemoryUsageDataPoint.AsObject; + static toObject(includeInstance: boolean, msg: RdsMemoryUsageDataPoint): RdsMemoryUsageDataPoint.AsObject; + static serializeBinaryToWriter(message: RdsMemoryUsageDataPoint, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): RdsMemoryUsageDataPoint; + static deserializeBinaryFromReader(message: RdsMemoryUsageDataPoint, reader: jspb.BinaryReader): RdsMemoryUsageDataPoint; +} + +export namespace RdsMemoryUsageDataPoint { + export type AsObject = { + totalusedmemory: number, + } +} + +export class DataPointsResponse extends jspb.Message { + getStarttimestampinsec(): number; + setStarttimestampinsec(value: number): DataPointsResponse; + + getTimeintervalinsec(): number; + setTimeintervalinsec(value: number): DataPointsResponse; + + getTransferratesList(): Array<TotalTransferRateDataPoint>; + setTransferratesList(value: Array<TotalTransferRateDataPoint>): DataPointsResponse; + clearTransferratesList(): DataPointsResponse; + addTransferrates(value?: TotalTransferRateDataPoint, index?: number): TotalTransferRateDataPoint; + + getFileratesList(): Array<TotalFileRateDataPoint>; + setFileratesList(value: Array<TotalFileRateDataPoint>): DataPointsResponse; + clearFileratesList(): DataPointsResponse; + addFilerates(value?: TotalFileRateDataPoint, index?: number): TotalFileRateDataPoint; + + getTasktimesList(): Array<TaskTimeDataPoint>; + setTasktimesList(value: Array<TaskTimeDataPoint>): DataPointsResponse; + clearTasktimesList(): DataPointsResponse; + addTasktimes(value?: TaskTimeDataPoint, index?: number): TaskTimeDataPoint; + + getMemoryusagesList(): Array<RdsMemoryUsageDataPoint>; + setMemoryusagesList(value: Array<RdsMemoryUsageDataPoint>): DataPointsResponse; + clearMemoryusagesList(): DataPointsResponse; + addMemoryusages(value?: RdsMemoryUsageDataPoint, index?: number): RdsMemoryUsageDataPoint; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): DataPointsResponse.AsObject; + static toObject(includeInstance: boolean, msg: DataPointsResponse): DataPointsResponse.AsObject; + static serializeBinaryToWriter(message: DataPointsResponse, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): DataPointsResponse; + static deserializeBinaryFromReader(message: DataPointsResponse, reader: jspb.BinaryReader): DataPointsResponse; +} + +export namespace DataPointsResponse { + export type AsObject = { + starttimestampinsec: number, + timeintervalinsec: number, + transferratesList: Array<TotalTransferRateDataPoint.AsObject>, + fileratesList: Array<TotalFileRateDataPoint.AsObject>, + tasktimesList: Array<TaskTimeDataPoint.AsObject>, + memoryusagesList: Array<RdsMemoryUsageDataPoint.AsObject>, + } +} + +export class MetadataResponse extends jspb.Message { + getClustername(): string; + setClustername(value: string): MetadataResponse; + + getAvailablebeamtimesList(): Array<string>; + setAvailablebeamtimesList(value: Array<string>): MetadataResponse; + clearAvailablebeamtimesList(): MetadataResponse; + addAvailablebeamtimes(value: string, index?: number): MetadataResponse; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): MetadataResponse.AsObject; + static toObject(includeInstance: boolean, msg: MetadataResponse): MetadataResponse.AsObject; + static serializeBinaryToWriter(message: MetadataResponse, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): MetadataResponse; + static deserializeBinaryFromReader(message: MetadataResponse, reader: jspb.BinaryReader): MetadataResponse; +} + +export namespace MetadataResponse { + export type AsObject = { + clustername: string, + availablebeamtimesList: Array<string>, + } +} + +export class ToplogyQuery extends jspb.Message { + getFromtimestamp(): number; + setFromtimestamp(value: number): ToplogyQuery; + + getTotimestamp(): number; + setTotimestamp(value: number): ToplogyQuery; + + getBeamtimefilter(): string; + setBeamtimefilter(value: string): ToplogyQuery; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): ToplogyQuery.AsObject; + static toObject(includeInstance: boolean, msg: ToplogyQuery): ToplogyQuery.AsObject; + static serializeBinaryToWriter(message: ToplogyQuery, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): ToplogyQuery; + static deserializeBinaryFromReader(message: ToplogyQuery, reader: jspb.BinaryReader): ToplogyQuery; +} + +export namespace ToplogyQuery { + export type AsObject = { + fromtimestamp: number, + totimestamp: number, + beamtimefilter: string, + } +} + +export class TopologyResponseNode extends jspb.Message { + getNodeid(): string; + setNodeid(value: string): TopologyResponseNode; + + getLevel(): number; + setLevel(value: number): TopologyResponseNode; + + getConsumerinstancesList(): Array<string>; + setConsumerinstancesList(value: Array<string>): TopologyResponseNode; + clearConsumerinstancesList(): TopologyResponseNode; + addConsumerinstances(value: string, index?: number): TopologyResponseNode; + + getProducerinstancesList(): Array<string>; + setProducerinstancesList(value: Array<string>): TopologyResponseNode; + clearProducerinstancesList(): TopologyResponseNode; + addProducerinstances(value: string, index?: number): TopologyResponseNode; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): TopologyResponseNode.AsObject; + static toObject(includeInstance: boolean, msg: TopologyResponseNode): TopologyResponseNode.AsObject; + static serializeBinaryToWriter(message: TopologyResponseNode, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): TopologyResponseNode; + static deserializeBinaryFromReader(message: TopologyResponseNode, reader: jspb.BinaryReader): TopologyResponseNode; +} + +export namespace TopologyResponseNode { + export type AsObject = { + nodeid: string, + level: number, + consumerinstancesList: Array<string>, + producerinstancesList: Array<string>, + } +} + +export class TopologyResponseEdge extends jspb.Message { + getFromnodeid(): string; + setFromnodeid(value: string): TopologyResponseEdge; + + getTonodeid(): string; + setTonodeid(value: string): TopologyResponseEdge; + + getSourcename(): string; + setSourcename(value: string): TopologyResponseEdge; + + getInvolvedreceiversList(): Array<string>; + setInvolvedreceiversList(value: Array<string>): TopologyResponseEdge; + clearInvolvedreceiversList(): TopologyResponseEdge; + addInvolvedreceivers(value: string, index?: number): TopologyResponseEdge; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): TopologyResponseEdge.AsObject; + static toObject(includeInstance: boolean, msg: TopologyResponseEdge): TopologyResponseEdge.AsObject; + static serializeBinaryToWriter(message: TopologyResponseEdge, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): TopologyResponseEdge; + static deserializeBinaryFromReader(message: TopologyResponseEdge, reader: jspb.BinaryReader): TopologyResponseEdge; +} + +export namespace TopologyResponseEdge { + export type AsObject = { + fromnodeid: string, + tonodeid: string, + sourcename: string, + involvedreceiversList: Array<string>, + } +} + +export class TopologyResponse extends jspb.Message { + getNodesList(): Array<TopologyResponseNode>; + setNodesList(value: Array<TopologyResponseNode>): TopologyResponse; + clearNodesList(): TopologyResponse; + addNodes(value?: TopologyResponseNode, index?: number): TopologyResponseNode; + + getEdgesList(): Array<TopologyResponseEdge>; + setEdgesList(value: Array<TopologyResponseEdge>): TopologyResponse; + clearEdgesList(): TopologyResponse; + addEdges(value?: TopologyResponseEdge, index?: number): TopologyResponseEdge; + + serializeBinary(): Uint8Array; + toObject(includeInstance?: boolean): TopologyResponse.AsObject; + static toObject(includeInstance: boolean, msg: TopologyResponse): TopologyResponse.AsObject; + static serializeBinaryToWriter(message: TopologyResponse, writer: jspb.BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): TopologyResponse; + static deserializeBinaryFromReader(message: TopologyResponse, reader: jspb.BinaryReader): TopologyResponse; +} + +export namespace TopologyResponse { + export type AsObject = { + nodesList: Array<TopologyResponseNode.AsObject>, + edgesList: Array<TopologyResponseEdge.AsObject>, + } +} + +export enum PipelineConnectionQueryMode { + INVALID_QUERY_MODE = 0, + EXACTPATH = 1, + JUSTRELATEDTOSTEP = 2, +} diff --git a/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringQueryService_pb.js b/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringQueryService_pb.js new file mode 100644 index 0000000000000000000000000000000000000000..cad97bb60ada849f9f2322e1f190a5c425dcd7bd --- /dev/null +++ b/monitoring/monitoring_ui/src/generated_proto/AsapoMonitoringQueryService_pb.js @@ -0,0 +1,2911 @@ +// source: AsapoMonitoringQueryService.proto +/** + * @fileoverview + * @enhanceable + * @suppress {missingRequire} reports error on implicit type usages. + * @suppress {messageConventions} JS Compiler reports an error if a variable or + * field starts with 'MSG_' and isn't a translatable message. + * @public + */ +// GENERATED CODE -- DO NOT EDIT! +/* eslint-disable */ +// @ts-nocheck + +var jspb = require('google-protobuf'); +var goog = jspb; +var global = Function('return this')(); + +var AsapoMonitoringCommonService_pb = require('./AsapoMonitoringCommonService_pb.js'); +goog.object.extend(proto, AsapoMonitoringCommonService_pb); +goog.exportSymbol('proto.DataPointsQuery', null, global); +goog.exportSymbol('proto.DataPointsResponse', null, global); +goog.exportSymbol('proto.MetadataResponse', null, global); +goog.exportSymbol('proto.PipelineConnectionQueryMode', null, global); +goog.exportSymbol('proto.RdsMemoryUsageDataPoint', null, global); +goog.exportSymbol('proto.TaskTimeDataPoint', null, global); +goog.exportSymbol('proto.ToplogyQuery', null, global); +goog.exportSymbol('proto.TopologyResponse', null, global); +goog.exportSymbol('proto.TopologyResponseEdge', null, global); +goog.exportSymbol('proto.TopologyResponseNode', null, global); +goog.exportSymbol('proto.TotalFileRateDataPoint', null, global); +goog.exportSymbol('proto.TotalTransferRateDataPoint', null, global); +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.DataPointsQuery = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.DataPointsQuery, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.DataPointsQuery.displayName = 'proto.DataPointsQuery'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.TotalTransferRateDataPoint = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.TotalTransferRateDataPoint, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.TotalTransferRateDataPoint.displayName = 'proto.TotalTransferRateDataPoint'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.TotalFileRateDataPoint = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.TotalFileRateDataPoint, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.TotalFileRateDataPoint.displayName = 'proto.TotalFileRateDataPoint'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.TaskTimeDataPoint = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.TaskTimeDataPoint, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.TaskTimeDataPoint.displayName = 'proto.TaskTimeDataPoint'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.RdsMemoryUsageDataPoint = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.RdsMemoryUsageDataPoint, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.RdsMemoryUsageDataPoint.displayName = 'proto.RdsMemoryUsageDataPoint'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.DataPointsResponse = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, proto.DataPointsResponse.repeatedFields_, null); +}; +goog.inherits(proto.DataPointsResponse, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.DataPointsResponse.displayName = 'proto.DataPointsResponse'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.MetadataResponse = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, proto.MetadataResponse.repeatedFields_, null); +}; +goog.inherits(proto.MetadataResponse, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.MetadataResponse.displayName = 'proto.MetadataResponse'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.ToplogyQuery = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, null, null); +}; +goog.inherits(proto.ToplogyQuery, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.ToplogyQuery.displayName = 'proto.ToplogyQuery'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.TopologyResponseNode = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, proto.TopologyResponseNode.repeatedFields_, null); +}; +goog.inherits(proto.TopologyResponseNode, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.TopologyResponseNode.displayName = 'proto.TopologyResponseNode'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.TopologyResponseEdge = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, proto.TopologyResponseEdge.repeatedFields_, null); +}; +goog.inherits(proto.TopologyResponseEdge, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.TopologyResponseEdge.displayName = 'proto.TopologyResponseEdge'; +} +/** + * Generated by JsPbCodeGenerator. + * @param {Array=} opt_data Optional initial data array, typically from a + * server response, or constructed directly in Javascript. The array is used + * in place and becomes part of the constructed object. It is not cloned. + * If no data is provided, the constructed object will be empty, but still + * valid. + * @extends {jspb.Message} + * @constructor + */ +proto.TopologyResponse = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, proto.TopologyResponse.repeatedFields_, null); +}; +goog.inherits(proto.TopologyResponse, jspb.Message); +if (goog.DEBUG && !COMPILED) { + /** + * @public + * @override + */ + proto.TopologyResponse.displayName = 'proto.TopologyResponse'; +} + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.DataPointsQuery.prototype.toObject = function(opt_includeInstance) { + return proto.DataPointsQuery.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.DataPointsQuery} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.DataPointsQuery.toObject = function(includeInstance, msg) { + var f, obj = { + fromtimestamp: jspb.Message.getFieldWithDefault(msg, 1, 0), + totimestamp: jspb.Message.getFieldWithDefault(msg, 2, 0), + beamtimefilter: jspb.Message.getFieldWithDefault(msg, 4, ""), + sourcefilter: jspb.Message.getFieldWithDefault(msg, 5, ""), + streamfilter: jspb.Message.getFieldWithDefault(msg, 6, ""), + receiverfilter: jspb.Message.getFieldWithDefault(msg, 7, ""), + frompipelinestepfilter: jspb.Message.getFieldWithDefault(msg, 8, ""), + topipelinestepfilter: jspb.Message.getFieldWithDefault(msg, 9, ""), + pipelinequerymode: jspb.Message.getFieldWithDefault(msg, 10, 0) + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.DataPointsQuery} + */ +proto.DataPointsQuery.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.DataPointsQuery; + return proto.DataPointsQuery.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.DataPointsQuery} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.DataPointsQuery} + */ +proto.DataPointsQuery.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {number} */ (reader.readUint64()); + msg.setFromtimestamp(value); + break; + case 2: + var value = /** @type {number} */ (reader.readUint64()); + msg.setTotimestamp(value); + break; + case 4: + var value = /** @type {string} */ (reader.readString()); + msg.setBeamtimefilter(value); + break; + case 5: + var value = /** @type {string} */ (reader.readString()); + msg.setSourcefilter(value); + break; + case 6: + var value = /** @type {string} */ (reader.readString()); + msg.setStreamfilter(value); + break; + case 7: + var value = /** @type {string} */ (reader.readString()); + msg.setReceiverfilter(value); + break; + case 8: + var value = /** @type {string} */ (reader.readString()); + msg.setFrompipelinestepfilter(value); + break; + case 9: + var value = /** @type {string} */ (reader.readString()); + msg.setTopipelinestepfilter(value); + break; + case 10: + var value = /** @type {!proto.PipelineConnectionQueryMode} */ (reader.readEnum()); + msg.setPipelinequerymode(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.DataPointsQuery.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.DataPointsQuery.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.DataPointsQuery} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.DataPointsQuery.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getFromtimestamp(); + if (f !== 0) { + writer.writeUint64( + 1, + f + ); + } + f = message.getTotimestamp(); + if (f !== 0) { + writer.writeUint64( + 2, + f + ); + } + f = message.getBeamtimefilter(); + if (f.length > 0) { + writer.writeString( + 4, + f + ); + } + f = message.getSourcefilter(); + if (f.length > 0) { + writer.writeString( + 5, + f + ); + } + f = message.getStreamfilter(); + if (f.length > 0) { + writer.writeString( + 6, + f + ); + } + f = message.getReceiverfilter(); + if (f.length > 0) { + writer.writeString( + 7, + f + ); + } + f = message.getFrompipelinestepfilter(); + if (f.length > 0) { + writer.writeString( + 8, + f + ); + } + f = message.getTopipelinestepfilter(); + if (f.length > 0) { + writer.writeString( + 9, + f + ); + } + f = message.getPipelinequerymode(); + if (f !== 0.0) { + writer.writeEnum( + 10, + f + ); + } +}; + + +/** + * optional uint64 fromTimestamp = 1; + * @return {number} + */ +proto.DataPointsQuery.prototype.getFromtimestamp = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.DataPointsQuery} returns this + */ +proto.DataPointsQuery.prototype.setFromtimestamp = function(value) { + return jspb.Message.setProto3IntField(this, 1, value); +}; + + +/** + * optional uint64 toTimestamp = 2; + * @return {number} + */ +proto.DataPointsQuery.prototype.getTotimestamp = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.DataPointsQuery} returns this + */ +proto.DataPointsQuery.prototype.setTotimestamp = function(value) { + return jspb.Message.setProto3IntField(this, 2, value); +}; + + +/** + * optional string beamtimeFilter = 4; + * @return {string} + */ +proto.DataPointsQuery.prototype.getBeamtimefilter = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, "")); +}; + + +/** + * @param {string} value + * @return {!proto.DataPointsQuery} returns this + */ +proto.DataPointsQuery.prototype.setBeamtimefilter = function(value) { + return jspb.Message.setProto3StringField(this, 4, value); +}; + + +/** + * optional string sourceFilter = 5; + * @return {string} + */ +proto.DataPointsQuery.prototype.getSourcefilter = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, "")); +}; + + +/** + * @param {string} value + * @return {!proto.DataPointsQuery} returns this + */ +proto.DataPointsQuery.prototype.setSourcefilter = function(value) { + return jspb.Message.setProto3StringField(this, 5, value); +}; + + +/** + * optional string streamFilter = 6; + * @return {string} + */ +proto.DataPointsQuery.prototype.getStreamfilter = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, "")); +}; + + +/** + * @param {string} value + * @return {!proto.DataPointsQuery} returns this + */ +proto.DataPointsQuery.prototype.setStreamfilter = function(value) { + return jspb.Message.setProto3StringField(this, 6, value); +}; + + +/** + * optional string receiverFilter = 7; + * @return {string} + */ +proto.DataPointsQuery.prototype.getReceiverfilter = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 7, "")); +}; + + +/** + * @param {string} value + * @return {!proto.DataPointsQuery} returns this + */ +proto.DataPointsQuery.prototype.setReceiverfilter = function(value) { + return jspb.Message.setProto3StringField(this, 7, value); +}; + + +/** + * optional string fromPipelineStepFilter = 8; + * @return {string} + */ +proto.DataPointsQuery.prototype.getFrompipelinestepfilter = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 8, "")); +}; + + +/** + * @param {string} value + * @return {!proto.DataPointsQuery} returns this + */ +proto.DataPointsQuery.prototype.setFrompipelinestepfilter = function(value) { + return jspb.Message.setProto3StringField(this, 8, value); +}; + + +/** + * optional string toPipelineStepFilter = 9; + * @return {string} + */ +proto.DataPointsQuery.prototype.getTopipelinestepfilter = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 9, "")); +}; + + +/** + * @param {string} value + * @return {!proto.DataPointsQuery} returns this + */ +proto.DataPointsQuery.prototype.setTopipelinestepfilter = function(value) { + return jspb.Message.setProto3StringField(this, 9, value); +}; + + +/** + * optional PipelineConnectionQueryMode pipelineQueryMode = 10; + * @return {!proto.PipelineConnectionQueryMode} + */ +proto.DataPointsQuery.prototype.getPipelinequerymode = function() { + return /** @type {!proto.PipelineConnectionQueryMode} */ (jspb.Message.getFieldWithDefault(this, 10, 0)); +}; + + +/** + * @param {!proto.PipelineConnectionQueryMode} value + * @return {!proto.DataPointsQuery} returns this + */ +proto.DataPointsQuery.prototype.setPipelinequerymode = function(value) { + return jspb.Message.setProto3EnumField(this, 10, value); +}; + + + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.TotalTransferRateDataPoint.prototype.toObject = function(opt_includeInstance) { + return proto.TotalTransferRateDataPoint.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.TotalTransferRateDataPoint} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.TotalTransferRateDataPoint.toObject = function(includeInstance, msg) { + var f, obj = { + totalbytespersecrecv: jspb.Message.getFieldWithDefault(msg, 1, 0), + totalbytespersecsend: jspb.Message.getFieldWithDefault(msg, 2, 0), + totalbytespersecrdssend: jspb.Message.getFieldWithDefault(msg, 3, 0), + totalbytespersecftssend: jspb.Message.getFieldWithDefault(msg, 4, 0) + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.TotalTransferRateDataPoint} + */ +proto.TotalTransferRateDataPoint.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.TotalTransferRateDataPoint; + return proto.TotalTransferRateDataPoint.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.TotalTransferRateDataPoint} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.TotalTransferRateDataPoint} + */ +proto.TotalTransferRateDataPoint.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {number} */ (reader.readUint64()); + msg.setTotalbytespersecrecv(value); + break; + case 2: + var value = /** @type {number} */ (reader.readUint64()); + msg.setTotalbytespersecsend(value); + break; + case 3: + var value = /** @type {number} */ (reader.readUint64()); + msg.setTotalbytespersecrdssend(value); + break; + case 4: + var value = /** @type {number} */ (reader.readUint64()); + msg.setTotalbytespersecftssend(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.TotalTransferRateDataPoint.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.TotalTransferRateDataPoint.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.TotalTransferRateDataPoint} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.TotalTransferRateDataPoint.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getTotalbytespersecrecv(); + if (f !== 0) { + writer.writeUint64( + 1, + f + ); + } + f = message.getTotalbytespersecsend(); + if (f !== 0) { + writer.writeUint64( + 2, + f + ); + } + f = message.getTotalbytespersecrdssend(); + if (f !== 0) { + writer.writeUint64( + 3, + f + ); + } + f = message.getTotalbytespersecftssend(); + if (f !== 0) { + writer.writeUint64( + 4, + f + ); + } +}; + + +/** + * optional uint64 totalBytesPerSecRecv = 1; + * @return {number} + */ +proto.TotalTransferRateDataPoint.prototype.getTotalbytespersecrecv = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.TotalTransferRateDataPoint} returns this + */ +proto.TotalTransferRateDataPoint.prototype.setTotalbytespersecrecv = function(value) { + return jspb.Message.setProto3IntField(this, 1, value); +}; + + +/** + * optional uint64 totalBytesPerSecSend = 2; + * @return {number} + */ +proto.TotalTransferRateDataPoint.prototype.getTotalbytespersecsend = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.TotalTransferRateDataPoint} returns this + */ +proto.TotalTransferRateDataPoint.prototype.setTotalbytespersecsend = function(value) { + return jspb.Message.setProto3IntField(this, 2, value); +}; + + +/** + * optional uint64 totalBytesPerSecRdsSend = 3; + * @return {number} + */ +proto.TotalTransferRateDataPoint.prototype.getTotalbytespersecrdssend = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.TotalTransferRateDataPoint} returns this + */ +proto.TotalTransferRateDataPoint.prototype.setTotalbytespersecrdssend = function(value) { + return jspb.Message.setProto3IntField(this, 3, value); +}; + + +/** + * optional uint64 totalBytesPerSecFtsSend = 4; + * @return {number} + */ +proto.TotalTransferRateDataPoint.prototype.getTotalbytespersecftssend = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.TotalTransferRateDataPoint} returns this + */ +proto.TotalTransferRateDataPoint.prototype.setTotalbytespersecftssend = function(value) { + return jspb.Message.setProto3IntField(this, 4, value); +}; + + + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.TotalFileRateDataPoint.prototype.toObject = function(opt_includeInstance) { + return proto.TotalFileRateDataPoint.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.TotalFileRateDataPoint} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.TotalFileRateDataPoint.toObject = function(includeInstance, msg) { + var f, obj = { + totalrequests: jspb.Message.getFieldWithDefault(msg, 1, 0), + cachemisses: jspb.Message.getFieldWithDefault(msg, 2, 0), + fromcache: jspb.Message.getFieldWithDefault(msg, 3, 0), + fromdisk: jspb.Message.getFieldWithDefault(msg, 4, 0) + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.TotalFileRateDataPoint} + */ +proto.TotalFileRateDataPoint.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.TotalFileRateDataPoint; + return proto.TotalFileRateDataPoint.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.TotalFileRateDataPoint} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.TotalFileRateDataPoint} + */ +proto.TotalFileRateDataPoint.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {number} */ (reader.readUint32()); + msg.setTotalrequests(value); + break; + case 2: + var value = /** @type {number} */ (reader.readUint32()); + msg.setCachemisses(value); + break; + case 3: + var value = /** @type {number} */ (reader.readUint32()); + msg.setFromcache(value); + break; + case 4: + var value = /** @type {number} */ (reader.readUint32()); + msg.setFromdisk(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.TotalFileRateDataPoint.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.TotalFileRateDataPoint.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.TotalFileRateDataPoint} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.TotalFileRateDataPoint.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getTotalrequests(); + if (f !== 0) { + writer.writeUint32( + 1, + f + ); + } + f = message.getCachemisses(); + if (f !== 0) { + writer.writeUint32( + 2, + f + ); + } + f = message.getFromcache(); + if (f !== 0) { + writer.writeUint32( + 3, + f + ); + } + f = message.getFromdisk(); + if (f !== 0) { + writer.writeUint32( + 4, + f + ); + } +}; + + +/** + * optional uint32 totalRequests = 1; + * @return {number} + */ +proto.TotalFileRateDataPoint.prototype.getTotalrequests = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.TotalFileRateDataPoint} returns this + */ +proto.TotalFileRateDataPoint.prototype.setTotalrequests = function(value) { + return jspb.Message.setProto3IntField(this, 1, value); +}; + + +/** + * optional uint32 cacheMisses = 2; + * @return {number} + */ +proto.TotalFileRateDataPoint.prototype.getCachemisses = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.TotalFileRateDataPoint} returns this + */ +proto.TotalFileRateDataPoint.prototype.setCachemisses = function(value) { + return jspb.Message.setProto3IntField(this, 2, value); +}; + + +/** + * optional uint32 fromCache = 3; + * @return {number} + */ +proto.TotalFileRateDataPoint.prototype.getFromcache = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.TotalFileRateDataPoint} returns this + */ +proto.TotalFileRateDataPoint.prototype.setFromcache = function(value) { + return jspb.Message.setProto3IntField(this, 3, value); +}; + + +/** + * optional uint32 fromDisk = 4; + * @return {number} + */ +proto.TotalFileRateDataPoint.prototype.getFromdisk = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.TotalFileRateDataPoint} returns this + */ +proto.TotalFileRateDataPoint.prototype.setFromdisk = function(value) { + return jspb.Message.setProto3IntField(this, 4, value); +}; + + + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.TaskTimeDataPoint.prototype.toObject = function(opt_includeInstance) { + return proto.TaskTimeDataPoint.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.TaskTimeDataPoint} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.TaskTimeDataPoint.toObject = function(includeInstance, msg) { + var f, obj = { + receiveiotimeus: jspb.Message.getFieldWithDefault(msg, 1, 0), + writetodisktimeus: jspb.Message.getFieldWithDefault(msg, 2, 0), + writetodatabasetimeus: jspb.Message.getFieldWithDefault(msg, 3, 0), + rdssendtoconsumertimeus: jspb.Message.getFieldWithDefault(msg, 4, 0) + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.TaskTimeDataPoint} + */ +proto.TaskTimeDataPoint.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.TaskTimeDataPoint; + return proto.TaskTimeDataPoint.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.TaskTimeDataPoint} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.TaskTimeDataPoint} + */ +proto.TaskTimeDataPoint.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {number} */ (reader.readUint32()); + msg.setReceiveiotimeus(value); + break; + case 2: + var value = /** @type {number} */ (reader.readUint32()); + msg.setWritetodisktimeus(value); + break; + case 3: + var value = /** @type {number} */ (reader.readUint32()); + msg.setWritetodatabasetimeus(value); + break; + case 4: + var value = /** @type {number} */ (reader.readUint32()); + msg.setRdssendtoconsumertimeus(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.TaskTimeDataPoint.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.TaskTimeDataPoint.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.TaskTimeDataPoint} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.TaskTimeDataPoint.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getReceiveiotimeus(); + if (f !== 0) { + writer.writeUint32( + 1, + f + ); + } + f = message.getWritetodisktimeus(); + if (f !== 0) { + writer.writeUint32( + 2, + f + ); + } + f = message.getWritetodatabasetimeus(); + if (f !== 0) { + writer.writeUint32( + 3, + f + ); + } + f = message.getRdssendtoconsumertimeus(); + if (f !== 0) { + writer.writeUint32( + 4, + f + ); + } +}; + + +/** + * optional uint32 receiveIoTimeUs = 1; + * @return {number} + */ +proto.TaskTimeDataPoint.prototype.getReceiveiotimeus = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.TaskTimeDataPoint} returns this + */ +proto.TaskTimeDataPoint.prototype.setReceiveiotimeus = function(value) { + return jspb.Message.setProto3IntField(this, 1, value); +}; + + +/** + * optional uint32 writeToDiskTimeUs = 2; + * @return {number} + */ +proto.TaskTimeDataPoint.prototype.getWritetodisktimeus = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.TaskTimeDataPoint} returns this + */ +proto.TaskTimeDataPoint.prototype.setWritetodisktimeus = function(value) { + return jspb.Message.setProto3IntField(this, 2, value); +}; + + +/** + * optional uint32 writeToDatabaseTimeUs = 3; + * @return {number} + */ +proto.TaskTimeDataPoint.prototype.getWritetodatabasetimeus = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 3, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.TaskTimeDataPoint} returns this + */ +proto.TaskTimeDataPoint.prototype.setWritetodatabasetimeus = function(value) { + return jspb.Message.setProto3IntField(this, 3, value); +}; + + +/** + * optional uint32 rdsSendToConsumerTimeUs = 4; + * @return {number} + */ +proto.TaskTimeDataPoint.prototype.getRdssendtoconsumertimeus = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 4, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.TaskTimeDataPoint} returns this + */ +proto.TaskTimeDataPoint.prototype.setRdssendtoconsumertimeus = function(value) { + return jspb.Message.setProto3IntField(this, 4, value); +}; + + + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.RdsMemoryUsageDataPoint.prototype.toObject = function(opt_includeInstance) { + return proto.RdsMemoryUsageDataPoint.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.RdsMemoryUsageDataPoint} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.RdsMemoryUsageDataPoint.toObject = function(includeInstance, msg) { + var f, obj = { + totalusedmemory: jspb.Message.getFieldWithDefault(msg, 1, 0) + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.RdsMemoryUsageDataPoint} + */ +proto.RdsMemoryUsageDataPoint.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.RdsMemoryUsageDataPoint; + return proto.RdsMemoryUsageDataPoint.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.RdsMemoryUsageDataPoint} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.RdsMemoryUsageDataPoint} + */ +proto.RdsMemoryUsageDataPoint.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {number} */ (reader.readUint64()); + msg.setTotalusedmemory(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.RdsMemoryUsageDataPoint.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.RdsMemoryUsageDataPoint.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.RdsMemoryUsageDataPoint} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.RdsMemoryUsageDataPoint.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getTotalusedmemory(); + if (f !== 0) { + writer.writeUint64( + 1, + f + ); + } +}; + + +/** + * optional uint64 totalUsedMemory = 1; + * @return {number} + */ +proto.RdsMemoryUsageDataPoint.prototype.getTotalusedmemory = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.RdsMemoryUsageDataPoint} returns this + */ +proto.RdsMemoryUsageDataPoint.prototype.setTotalusedmemory = function(value) { + return jspb.Message.setProto3IntField(this, 1, value); +}; + + + +/** + * List of repeated fields within this message type. + * @private {!Array<number>} + * @const + */ +proto.DataPointsResponse.repeatedFields_ = [3,4,5,6]; + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.DataPointsResponse.prototype.toObject = function(opt_includeInstance) { + return proto.DataPointsResponse.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.DataPointsResponse} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.DataPointsResponse.toObject = function(includeInstance, msg) { + var f, obj = { + starttimestampinsec: jspb.Message.getFieldWithDefault(msg, 1, 0), + timeintervalinsec: jspb.Message.getFieldWithDefault(msg, 2, 0), + transferratesList: jspb.Message.toObjectList(msg.getTransferratesList(), + proto.TotalTransferRateDataPoint.toObject, includeInstance), + fileratesList: jspb.Message.toObjectList(msg.getFileratesList(), + proto.TotalFileRateDataPoint.toObject, includeInstance), + tasktimesList: jspb.Message.toObjectList(msg.getTasktimesList(), + proto.TaskTimeDataPoint.toObject, includeInstance), + memoryusagesList: jspb.Message.toObjectList(msg.getMemoryusagesList(), + proto.RdsMemoryUsageDataPoint.toObject, includeInstance) + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.DataPointsResponse} + */ +proto.DataPointsResponse.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.DataPointsResponse; + return proto.DataPointsResponse.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.DataPointsResponse} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.DataPointsResponse} + */ +proto.DataPointsResponse.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {number} */ (reader.readUint64()); + msg.setStarttimestampinsec(value); + break; + case 2: + var value = /** @type {number} */ (reader.readUint32()); + msg.setTimeintervalinsec(value); + break; + case 3: + var value = new proto.TotalTransferRateDataPoint; + reader.readMessage(value,proto.TotalTransferRateDataPoint.deserializeBinaryFromReader); + msg.addTransferrates(value); + break; + case 4: + var value = new proto.TotalFileRateDataPoint; + reader.readMessage(value,proto.TotalFileRateDataPoint.deserializeBinaryFromReader); + msg.addFilerates(value); + break; + case 5: + var value = new proto.TaskTimeDataPoint; + reader.readMessage(value,proto.TaskTimeDataPoint.deserializeBinaryFromReader); + msg.addTasktimes(value); + break; + case 6: + var value = new proto.RdsMemoryUsageDataPoint; + reader.readMessage(value,proto.RdsMemoryUsageDataPoint.deserializeBinaryFromReader); + msg.addMemoryusages(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.DataPointsResponse.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.DataPointsResponse.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.DataPointsResponse} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.DataPointsResponse.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getStarttimestampinsec(); + if (f !== 0) { + writer.writeUint64( + 1, + f + ); + } + f = message.getTimeintervalinsec(); + if (f !== 0) { + writer.writeUint32( + 2, + f + ); + } + f = message.getTransferratesList(); + if (f.length > 0) { + writer.writeRepeatedMessage( + 3, + f, + proto.TotalTransferRateDataPoint.serializeBinaryToWriter + ); + } + f = message.getFileratesList(); + if (f.length > 0) { + writer.writeRepeatedMessage( + 4, + f, + proto.TotalFileRateDataPoint.serializeBinaryToWriter + ); + } + f = message.getTasktimesList(); + if (f.length > 0) { + writer.writeRepeatedMessage( + 5, + f, + proto.TaskTimeDataPoint.serializeBinaryToWriter + ); + } + f = message.getMemoryusagesList(); + if (f.length > 0) { + writer.writeRepeatedMessage( + 6, + f, + proto.RdsMemoryUsageDataPoint.serializeBinaryToWriter + ); + } +}; + + +/** + * optional uint64 startTimestampInSec = 1; + * @return {number} + */ +proto.DataPointsResponse.prototype.getStarttimestampinsec = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.DataPointsResponse} returns this + */ +proto.DataPointsResponse.prototype.setStarttimestampinsec = function(value) { + return jspb.Message.setProto3IntField(this, 1, value); +}; + + +/** + * optional uint32 timeIntervalInSec = 2; + * @return {number} + */ +proto.DataPointsResponse.prototype.getTimeintervalinsec = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.DataPointsResponse} returns this + */ +proto.DataPointsResponse.prototype.setTimeintervalinsec = function(value) { + return jspb.Message.setProto3IntField(this, 2, value); +}; + + +/** + * repeated TotalTransferRateDataPoint transferRates = 3; + * @return {!Array<!proto.TotalTransferRateDataPoint>} + */ +proto.DataPointsResponse.prototype.getTransferratesList = function() { + return /** @type{!Array<!proto.TotalTransferRateDataPoint>} */ ( + jspb.Message.getRepeatedWrapperField(this, proto.TotalTransferRateDataPoint, 3)); +}; + + +/** + * @param {!Array<!proto.TotalTransferRateDataPoint>} value + * @return {!proto.DataPointsResponse} returns this +*/ +proto.DataPointsResponse.prototype.setTransferratesList = function(value) { + return jspb.Message.setRepeatedWrapperField(this, 3, value); +}; + + +/** + * @param {!proto.TotalTransferRateDataPoint=} opt_value + * @param {number=} opt_index + * @return {!proto.TotalTransferRateDataPoint} + */ +proto.DataPointsResponse.prototype.addTransferrates = function(opt_value, opt_index) { + return jspb.Message.addToRepeatedWrapperField(this, 3, opt_value, proto.TotalTransferRateDataPoint, opt_index); +}; + + +/** + * Clears the list making it empty but non-null. + * @return {!proto.DataPointsResponse} returns this + */ +proto.DataPointsResponse.prototype.clearTransferratesList = function() { + return this.setTransferratesList([]); +}; + + +/** + * repeated TotalFileRateDataPoint fileRates = 4; + * @return {!Array<!proto.TotalFileRateDataPoint>} + */ +proto.DataPointsResponse.prototype.getFileratesList = function() { + return /** @type{!Array<!proto.TotalFileRateDataPoint>} */ ( + jspb.Message.getRepeatedWrapperField(this, proto.TotalFileRateDataPoint, 4)); +}; + + +/** + * @param {!Array<!proto.TotalFileRateDataPoint>} value + * @return {!proto.DataPointsResponse} returns this +*/ +proto.DataPointsResponse.prototype.setFileratesList = function(value) { + return jspb.Message.setRepeatedWrapperField(this, 4, value); +}; + + +/** + * @param {!proto.TotalFileRateDataPoint=} opt_value + * @param {number=} opt_index + * @return {!proto.TotalFileRateDataPoint} + */ +proto.DataPointsResponse.prototype.addFilerates = function(opt_value, opt_index) { + return jspb.Message.addToRepeatedWrapperField(this, 4, opt_value, proto.TotalFileRateDataPoint, opt_index); +}; + + +/** + * Clears the list making it empty but non-null. + * @return {!proto.DataPointsResponse} returns this + */ +proto.DataPointsResponse.prototype.clearFileratesList = function() { + return this.setFileratesList([]); +}; + + +/** + * repeated TaskTimeDataPoint taskTimes = 5; + * @return {!Array<!proto.TaskTimeDataPoint>} + */ +proto.DataPointsResponse.prototype.getTasktimesList = function() { + return /** @type{!Array<!proto.TaskTimeDataPoint>} */ ( + jspb.Message.getRepeatedWrapperField(this, proto.TaskTimeDataPoint, 5)); +}; + + +/** + * @param {!Array<!proto.TaskTimeDataPoint>} value + * @return {!proto.DataPointsResponse} returns this +*/ +proto.DataPointsResponse.prototype.setTasktimesList = function(value) { + return jspb.Message.setRepeatedWrapperField(this, 5, value); +}; + + +/** + * @param {!proto.TaskTimeDataPoint=} opt_value + * @param {number=} opt_index + * @return {!proto.TaskTimeDataPoint} + */ +proto.DataPointsResponse.prototype.addTasktimes = function(opt_value, opt_index) { + return jspb.Message.addToRepeatedWrapperField(this, 5, opt_value, proto.TaskTimeDataPoint, opt_index); +}; + + +/** + * Clears the list making it empty but non-null. + * @return {!proto.DataPointsResponse} returns this + */ +proto.DataPointsResponse.prototype.clearTasktimesList = function() { + return this.setTasktimesList([]); +}; + + +/** + * repeated RdsMemoryUsageDataPoint memoryUsages = 6; + * @return {!Array<!proto.RdsMemoryUsageDataPoint>} + */ +proto.DataPointsResponse.prototype.getMemoryusagesList = function() { + return /** @type{!Array<!proto.RdsMemoryUsageDataPoint>} */ ( + jspb.Message.getRepeatedWrapperField(this, proto.RdsMemoryUsageDataPoint, 6)); +}; + + +/** + * @param {!Array<!proto.RdsMemoryUsageDataPoint>} value + * @return {!proto.DataPointsResponse} returns this +*/ +proto.DataPointsResponse.prototype.setMemoryusagesList = function(value) { + return jspb.Message.setRepeatedWrapperField(this, 6, value); +}; + + +/** + * @param {!proto.RdsMemoryUsageDataPoint=} opt_value + * @param {number=} opt_index + * @return {!proto.RdsMemoryUsageDataPoint} + */ +proto.DataPointsResponse.prototype.addMemoryusages = function(opt_value, opt_index) { + return jspb.Message.addToRepeatedWrapperField(this, 6, opt_value, proto.RdsMemoryUsageDataPoint, opt_index); +}; + + +/** + * Clears the list making it empty but non-null. + * @return {!proto.DataPointsResponse} returns this + */ +proto.DataPointsResponse.prototype.clearMemoryusagesList = function() { + return this.setMemoryusagesList([]); +}; + + + +/** + * List of repeated fields within this message type. + * @private {!Array<number>} + * @const + */ +proto.MetadataResponse.repeatedFields_ = [2]; + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.MetadataResponse.prototype.toObject = function(opt_includeInstance) { + return proto.MetadataResponse.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.MetadataResponse} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.MetadataResponse.toObject = function(includeInstance, msg) { + var f, obj = { + clustername: jspb.Message.getFieldWithDefault(msg, 1, ""), + availablebeamtimesList: (f = jspb.Message.getRepeatedField(msg, 2)) == null ? undefined : f + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.MetadataResponse} + */ +proto.MetadataResponse.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.MetadataResponse; + return proto.MetadataResponse.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.MetadataResponse} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.MetadataResponse} + */ +proto.MetadataResponse.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {string} */ (reader.readString()); + msg.setClustername(value); + break; + case 2: + var value = /** @type {string} */ (reader.readString()); + msg.addAvailablebeamtimes(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.MetadataResponse.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.MetadataResponse.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.MetadataResponse} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.MetadataResponse.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getClustername(); + if (f.length > 0) { + writer.writeString( + 1, + f + ); + } + f = message.getAvailablebeamtimesList(); + if (f.length > 0) { + writer.writeRepeatedString( + 2, + f + ); + } +}; + + +/** + * optional string clusterName = 1; + * @return {string} + */ +proto.MetadataResponse.prototype.getClustername = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); +}; + + +/** + * @param {string} value + * @return {!proto.MetadataResponse} returns this + */ +proto.MetadataResponse.prototype.setClustername = function(value) { + return jspb.Message.setProto3StringField(this, 1, value); +}; + + +/** + * repeated string availableBeamtimes = 2; + * @return {!Array<string>} + */ +proto.MetadataResponse.prototype.getAvailablebeamtimesList = function() { + return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 2)); +}; + + +/** + * @param {!Array<string>} value + * @return {!proto.MetadataResponse} returns this + */ +proto.MetadataResponse.prototype.setAvailablebeamtimesList = function(value) { + return jspb.Message.setField(this, 2, value || []); +}; + + +/** + * @param {string} value + * @param {number=} opt_index + * @return {!proto.MetadataResponse} returns this + */ +proto.MetadataResponse.prototype.addAvailablebeamtimes = function(value, opt_index) { + return jspb.Message.addToRepeatedField(this, 2, value, opt_index); +}; + + +/** + * Clears the list making it empty but non-null. + * @return {!proto.MetadataResponse} returns this + */ +proto.MetadataResponse.prototype.clearAvailablebeamtimesList = function() { + return this.setAvailablebeamtimesList([]); +}; + + + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.ToplogyQuery.prototype.toObject = function(opt_includeInstance) { + return proto.ToplogyQuery.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.ToplogyQuery} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.ToplogyQuery.toObject = function(includeInstance, msg) { + var f, obj = { + fromtimestamp: jspb.Message.getFieldWithDefault(msg, 1, 0), + totimestamp: jspb.Message.getFieldWithDefault(msg, 2, 0), + beamtimefilter: jspb.Message.getFieldWithDefault(msg, 3, "") + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.ToplogyQuery} + */ +proto.ToplogyQuery.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.ToplogyQuery; + return proto.ToplogyQuery.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.ToplogyQuery} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.ToplogyQuery} + */ +proto.ToplogyQuery.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {number} */ (reader.readUint64()); + msg.setFromtimestamp(value); + break; + case 2: + var value = /** @type {number} */ (reader.readUint64()); + msg.setTotimestamp(value); + break; + case 3: + var value = /** @type {string} */ (reader.readString()); + msg.setBeamtimefilter(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.ToplogyQuery.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.ToplogyQuery.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.ToplogyQuery} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.ToplogyQuery.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getFromtimestamp(); + if (f !== 0) { + writer.writeUint64( + 1, + f + ); + } + f = message.getTotimestamp(); + if (f !== 0) { + writer.writeUint64( + 2, + f + ); + } + f = message.getBeamtimefilter(); + if (f.length > 0) { + writer.writeString( + 3, + f + ); + } +}; + + +/** + * optional uint64 fromTimestamp = 1; + * @return {number} + */ +proto.ToplogyQuery.prototype.getFromtimestamp = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.ToplogyQuery} returns this + */ +proto.ToplogyQuery.prototype.setFromtimestamp = function(value) { + return jspb.Message.setProto3IntField(this, 1, value); +}; + + +/** + * optional uint64 toTimestamp = 2; + * @return {number} + */ +proto.ToplogyQuery.prototype.getTotimestamp = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.ToplogyQuery} returns this + */ +proto.ToplogyQuery.prototype.setTotimestamp = function(value) { + return jspb.Message.setProto3IntField(this, 2, value); +}; + + +/** + * optional string beamtimeFilter = 3; + * @return {string} + */ +proto.ToplogyQuery.prototype.getBeamtimefilter = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, "")); +}; + + +/** + * @param {string} value + * @return {!proto.ToplogyQuery} returns this + */ +proto.ToplogyQuery.prototype.setBeamtimefilter = function(value) { + return jspb.Message.setProto3StringField(this, 3, value); +}; + + + +/** + * List of repeated fields within this message type. + * @private {!Array<number>} + * @const + */ +proto.TopologyResponseNode.repeatedFields_ = [3,4]; + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.TopologyResponseNode.prototype.toObject = function(opt_includeInstance) { + return proto.TopologyResponseNode.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.TopologyResponseNode} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.TopologyResponseNode.toObject = function(includeInstance, msg) { + var f, obj = { + nodeid: jspb.Message.getFieldWithDefault(msg, 1, ""), + level: jspb.Message.getFieldWithDefault(msg, 2, 0), + consumerinstancesList: (f = jspb.Message.getRepeatedField(msg, 3)) == null ? undefined : f, + producerinstancesList: (f = jspb.Message.getRepeatedField(msg, 4)) == null ? undefined : f + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.TopologyResponseNode} + */ +proto.TopologyResponseNode.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.TopologyResponseNode; + return proto.TopologyResponseNode.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.TopologyResponseNode} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.TopologyResponseNode} + */ +proto.TopologyResponseNode.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {string} */ (reader.readString()); + msg.setNodeid(value); + break; + case 2: + var value = /** @type {number} */ (reader.readUint32()); + msg.setLevel(value); + break; + case 3: + var value = /** @type {string} */ (reader.readString()); + msg.addConsumerinstances(value); + break; + case 4: + var value = /** @type {string} */ (reader.readString()); + msg.addProducerinstances(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.TopologyResponseNode.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.TopologyResponseNode.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.TopologyResponseNode} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.TopologyResponseNode.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getNodeid(); + if (f.length > 0) { + writer.writeString( + 1, + f + ); + } + f = message.getLevel(); + if (f !== 0) { + writer.writeUint32( + 2, + f + ); + } + f = message.getConsumerinstancesList(); + if (f.length > 0) { + writer.writeRepeatedString( + 3, + f + ); + } + f = message.getProducerinstancesList(); + if (f.length > 0) { + writer.writeRepeatedString( + 4, + f + ); + } +}; + + +/** + * optional string nodeId = 1; + * @return {string} + */ +proto.TopologyResponseNode.prototype.getNodeid = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); +}; + + +/** + * @param {string} value + * @return {!proto.TopologyResponseNode} returns this + */ +proto.TopologyResponseNode.prototype.setNodeid = function(value) { + return jspb.Message.setProto3StringField(this, 1, value); +}; + + +/** + * optional uint32 level = 2; + * @return {number} + */ +proto.TopologyResponseNode.prototype.getLevel = function() { + return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 2, 0)); +}; + + +/** + * @param {number} value + * @return {!proto.TopologyResponseNode} returns this + */ +proto.TopologyResponseNode.prototype.setLevel = function(value) { + return jspb.Message.setProto3IntField(this, 2, value); +}; + + +/** + * repeated string consumerInstances = 3; + * @return {!Array<string>} + */ +proto.TopologyResponseNode.prototype.getConsumerinstancesList = function() { + return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 3)); +}; + + +/** + * @param {!Array<string>} value + * @return {!proto.TopologyResponseNode} returns this + */ +proto.TopologyResponseNode.prototype.setConsumerinstancesList = function(value) { + return jspb.Message.setField(this, 3, value || []); +}; + + +/** + * @param {string} value + * @param {number=} opt_index + * @return {!proto.TopologyResponseNode} returns this + */ +proto.TopologyResponseNode.prototype.addConsumerinstances = function(value, opt_index) { + return jspb.Message.addToRepeatedField(this, 3, value, opt_index); +}; + + +/** + * Clears the list making it empty but non-null. + * @return {!proto.TopologyResponseNode} returns this + */ +proto.TopologyResponseNode.prototype.clearConsumerinstancesList = function() { + return this.setConsumerinstancesList([]); +}; + + +/** + * repeated string producerInstances = 4; + * @return {!Array<string>} + */ +proto.TopologyResponseNode.prototype.getProducerinstancesList = function() { + return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 4)); +}; + + +/** + * @param {!Array<string>} value + * @return {!proto.TopologyResponseNode} returns this + */ +proto.TopologyResponseNode.prototype.setProducerinstancesList = function(value) { + return jspb.Message.setField(this, 4, value || []); +}; + + +/** + * @param {string} value + * @param {number=} opt_index + * @return {!proto.TopologyResponseNode} returns this + */ +proto.TopologyResponseNode.prototype.addProducerinstances = function(value, opt_index) { + return jspb.Message.addToRepeatedField(this, 4, value, opt_index); +}; + + +/** + * Clears the list making it empty but non-null. + * @return {!proto.TopologyResponseNode} returns this + */ +proto.TopologyResponseNode.prototype.clearProducerinstancesList = function() { + return this.setProducerinstancesList([]); +}; + + + +/** + * List of repeated fields within this message type. + * @private {!Array<number>} + * @const + */ +proto.TopologyResponseEdge.repeatedFields_ = [4]; + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.TopologyResponseEdge.prototype.toObject = function(opt_includeInstance) { + return proto.TopologyResponseEdge.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.TopologyResponseEdge} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.TopologyResponseEdge.toObject = function(includeInstance, msg) { + var f, obj = { + fromnodeid: jspb.Message.getFieldWithDefault(msg, 1, ""), + tonodeid: jspb.Message.getFieldWithDefault(msg, 2, ""), + sourcename: jspb.Message.getFieldWithDefault(msg, 3, ""), + involvedreceiversList: (f = jspb.Message.getRepeatedField(msg, 4)) == null ? undefined : f + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.TopologyResponseEdge} + */ +proto.TopologyResponseEdge.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.TopologyResponseEdge; + return proto.TopologyResponseEdge.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.TopologyResponseEdge} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.TopologyResponseEdge} + */ +proto.TopologyResponseEdge.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = /** @type {string} */ (reader.readString()); + msg.setFromnodeid(value); + break; + case 2: + var value = /** @type {string} */ (reader.readString()); + msg.setTonodeid(value); + break; + case 3: + var value = /** @type {string} */ (reader.readString()); + msg.setSourcename(value); + break; + case 4: + var value = /** @type {string} */ (reader.readString()); + msg.addInvolvedreceivers(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.TopologyResponseEdge.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.TopologyResponseEdge.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.TopologyResponseEdge} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.TopologyResponseEdge.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getFromnodeid(); + if (f.length > 0) { + writer.writeString( + 1, + f + ); + } + f = message.getTonodeid(); + if (f.length > 0) { + writer.writeString( + 2, + f + ); + } + f = message.getSourcename(); + if (f.length > 0) { + writer.writeString( + 3, + f + ); + } + f = message.getInvolvedreceiversList(); + if (f.length > 0) { + writer.writeRepeatedString( + 4, + f + ); + } +}; + + +/** + * optional string fromNodeId = 1; + * @return {string} + */ +proto.TopologyResponseEdge.prototype.getFromnodeid = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); +}; + + +/** + * @param {string} value + * @return {!proto.TopologyResponseEdge} returns this + */ +proto.TopologyResponseEdge.prototype.setFromnodeid = function(value) { + return jspb.Message.setProto3StringField(this, 1, value); +}; + + +/** + * optional string toNodeId = 2; + * @return {string} + */ +proto.TopologyResponseEdge.prototype.getTonodeid = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, "")); +}; + + +/** + * @param {string} value + * @return {!proto.TopologyResponseEdge} returns this + */ +proto.TopologyResponseEdge.prototype.setTonodeid = function(value) { + return jspb.Message.setProto3StringField(this, 2, value); +}; + + +/** + * optional string sourceName = 3; + * @return {string} + */ +proto.TopologyResponseEdge.prototype.getSourcename = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, "")); +}; + + +/** + * @param {string} value + * @return {!proto.TopologyResponseEdge} returns this + */ +proto.TopologyResponseEdge.prototype.setSourcename = function(value) { + return jspb.Message.setProto3StringField(this, 3, value); +}; + + +/** + * repeated string involvedReceivers = 4; + * @return {!Array<string>} + */ +proto.TopologyResponseEdge.prototype.getInvolvedreceiversList = function() { + return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 4)); +}; + + +/** + * @param {!Array<string>} value + * @return {!proto.TopologyResponseEdge} returns this + */ +proto.TopologyResponseEdge.prototype.setInvolvedreceiversList = function(value) { + return jspb.Message.setField(this, 4, value || []); +}; + + +/** + * @param {string} value + * @param {number=} opt_index + * @return {!proto.TopologyResponseEdge} returns this + */ +proto.TopologyResponseEdge.prototype.addInvolvedreceivers = function(value, opt_index) { + return jspb.Message.addToRepeatedField(this, 4, value, opt_index); +}; + + +/** + * Clears the list making it empty but non-null. + * @return {!proto.TopologyResponseEdge} returns this + */ +proto.TopologyResponseEdge.prototype.clearInvolvedreceiversList = function() { + return this.setInvolvedreceiversList([]); +}; + + + +/** + * List of repeated fields within this message type. + * @private {!Array<number>} + * @const + */ +proto.TopologyResponse.repeatedFields_ = [1,2]; + + + +if (jspb.Message.GENERATE_TO_OBJECT) { +/** + * Creates an object representation of this proto. + * Field names that are reserved in JavaScript and will be renamed to pb_name. + * Optional fields that are not set will be set to undefined. + * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default. + * For the list of reserved names please see: + * net/proto2/compiler/js/internal/generator.cc#kKeyword. + * @param {boolean=} opt_includeInstance Deprecated. whether to include the + * JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @return {!Object} + */ +proto.TopologyResponse.prototype.toObject = function(opt_includeInstance) { + return proto.TopologyResponse.toObject(opt_includeInstance, this); +}; + + +/** + * Static version of the {@see toObject} method. + * @param {boolean|undefined} includeInstance Deprecated. Whether to include + * the JSPB instance for transitional soy proto support: + * http://goto/soy-param-migration + * @param {!proto.TopologyResponse} msg The msg instance to transform. + * @return {!Object} + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.TopologyResponse.toObject = function(includeInstance, msg) { + var f, obj = { + nodesList: jspb.Message.toObjectList(msg.getNodesList(), + proto.TopologyResponseNode.toObject, includeInstance), + edgesList: jspb.Message.toObjectList(msg.getEdgesList(), + proto.TopologyResponseEdge.toObject, includeInstance) + }; + + if (includeInstance) { + obj.$jspbMessageInstance = msg; + } + return obj; +}; +} + + +/** + * Deserializes binary data (in protobuf wire format). + * @param {jspb.ByteSource} bytes The bytes to deserialize. + * @return {!proto.TopologyResponse} + */ +proto.TopologyResponse.deserializeBinary = function(bytes) { + var reader = new jspb.BinaryReader(bytes); + var msg = new proto.TopologyResponse; + return proto.TopologyResponse.deserializeBinaryFromReader(msg, reader); +}; + + +/** + * Deserializes binary data (in protobuf wire format) from the + * given reader into the given message object. + * @param {!proto.TopologyResponse} msg The message object to deserialize into. + * @param {!jspb.BinaryReader} reader The BinaryReader to use. + * @return {!proto.TopologyResponse} + */ +proto.TopologyResponse.deserializeBinaryFromReader = function(msg, reader) { + while (reader.nextField()) { + if (reader.isEndGroup()) { + break; + } + var field = reader.getFieldNumber(); + switch (field) { + case 1: + var value = new proto.TopologyResponseNode; + reader.readMessage(value,proto.TopologyResponseNode.deserializeBinaryFromReader); + msg.addNodes(value); + break; + case 2: + var value = new proto.TopologyResponseEdge; + reader.readMessage(value,proto.TopologyResponseEdge.deserializeBinaryFromReader); + msg.addEdges(value); + break; + default: + reader.skipField(); + break; + } + } + return msg; +}; + + +/** + * Serializes the message to binary data (in protobuf wire format). + * @return {!Uint8Array} + */ +proto.TopologyResponse.prototype.serializeBinary = function() { + var writer = new jspb.BinaryWriter(); + proto.TopologyResponse.serializeBinaryToWriter(this, writer); + return writer.getResultBuffer(); +}; + + +/** + * Serializes the given message to binary data (in protobuf wire + * format), writing to the given BinaryWriter. + * @param {!proto.TopologyResponse} message + * @param {!jspb.BinaryWriter} writer + * @suppress {unusedLocalVariables} f is only used for nested messages + */ +proto.TopologyResponse.serializeBinaryToWriter = function(message, writer) { + var f = undefined; + f = message.getNodesList(); + if (f.length > 0) { + writer.writeRepeatedMessage( + 1, + f, + proto.TopologyResponseNode.serializeBinaryToWriter + ); + } + f = message.getEdgesList(); + if (f.length > 0) { + writer.writeRepeatedMessage( + 2, + f, + proto.TopologyResponseEdge.serializeBinaryToWriter + ); + } +}; + + +/** + * repeated TopologyResponseNode nodes = 1; + * @return {!Array<!proto.TopologyResponseNode>} + */ +proto.TopologyResponse.prototype.getNodesList = function() { + return /** @type{!Array<!proto.TopologyResponseNode>} */ ( + jspb.Message.getRepeatedWrapperField(this, proto.TopologyResponseNode, 1)); +}; + + +/** + * @param {!Array<!proto.TopologyResponseNode>} value + * @return {!proto.TopologyResponse} returns this +*/ +proto.TopologyResponse.prototype.setNodesList = function(value) { + return jspb.Message.setRepeatedWrapperField(this, 1, value); +}; + + +/** + * @param {!proto.TopologyResponseNode=} opt_value + * @param {number=} opt_index + * @return {!proto.TopologyResponseNode} + */ +proto.TopologyResponse.prototype.addNodes = function(opt_value, opt_index) { + return jspb.Message.addToRepeatedWrapperField(this, 1, opt_value, proto.TopologyResponseNode, opt_index); +}; + + +/** + * Clears the list making it empty but non-null. + * @return {!proto.TopologyResponse} returns this + */ +proto.TopologyResponse.prototype.clearNodesList = function() { + return this.setNodesList([]); +}; + + +/** + * repeated TopologyResponseEdge edges = 2; + * @return {!Array<!proto.TopologyResponseEdge>} + */ +proto.TopologyResponse.prototype.getEdgesList = function() { + return /** @type{!Array<!proto.TopologyResponseEdge>} */ ( + jspb.Message.getRepeatedWrapperField(this, proto.TopologyResponseEdge, 2)); +}; + + +/** + * @param {!Array<!proto.TopologyResponseEdge>} value + * @return {!proto.TopologyResponse} returns this +*/ +proto.TopologyResponse.prototype.setEdgesList = function(value) { + return jspb.Message.setRepeatedWrapperField(this, 2, value); +}; + + +/** + * @param {!proto.TopologyResponseEdge=} opt_value + * @param {number=} opt_index + * @return {!proto.TopologyResponseEdge} + */ +proto.TopologyResponse.prototype.addEdges = function(opt_value, opt_index) { + return jspb.Message.addToRepeatedWrapperField(this, 2, opt_value, proto.TopologyResponseEdge, opt_index); +}; + + +/** + * Clears the list making it empty but non-null. + * @return {!proto.TopologyResponse} returns this + */ +proto.TopologyResponse.prototype.clearEdgesList = function() { + return this.setEdgesList([]); +}; + + +/** + * @enum {number} + */ +proto.PipelineConnectionQueryMode = { + INVALID_QUERY_MODE: 0, + EXACTPATH: 1, + JUSTRELATEDTOSTEP: 2 +}; + +goog.object.extend(exports, proto); diff --git a/monitoring/monitoring_ui/src/index.css b/monitoring/monitoring_ui/src/index.css new file mode 100644 index 0000000000000000000000000000000000000000..ae140754fdd0214d10a6b8f91bbd389aa29e7fa0 --- /dev/null +++ b/monitoring/monitoring_ui/src/index.css @@ -0,0 +1,8 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +html, body, #app { + width: 100%; + height: 100%; +} diff --git a/monitoring/monitoring_ui/src/lib/TimeRange.ts b/monitoring/monitoring_ui/src/lib/TimeRange.ts new file mode 100644 index 0000000000000000000000000000000000000000..aa590f6e8a65503ccd4621718f987ed0300da220 --- /dev/null +++ b/monitoring/monitoring_ui/src/lib/TimeRange.ts @@ -0,0 +1,81 @@ +import moment from 'moment'; +import * as relativeTimeParser from 'relative-time-parser'; +import { errorStore } from '../store/errorStore'; + +/** + * Contains a fixed unix time range + */ +export interface FixedTimeRange { + fromUnixSec: number; + toUnixSec: number; +} + +/** + * Contains a time range where the "from" and "to" values are just expressions + * like from: "now-5m" to: "now" + */ +export class TimeRange { + private static nowKeyword = 'now'; + + public readonly from: string; + public readonly to: string; + + public constructor(from: string | number, to: string | number) { + this.from = String(from); + this.to = String(to); + } + + /** + * Evaluates the time range expression + * @returns {FixedTimeRange} A FixedUnix time that was evaluated by this expression + */ + public evaluate(): FixedTimeRange { + return { + fromUnixSec: TimeRange.fromHumanExpressionToUnix(this.from), + toUnixSec: TimeRange.fromHumanExpressionToUnix(this.to) + }; + } + + /** + * Evaluates and converts the current object to a human readable description. + * e.g. + * {from: 'now-5m', to: 'now'} => 'Last 5 minutes' + * {from: '156423578', to: '159663578'} => '156423578 to 159663578' + * @returns {String} The human readable description + */ + public toHumanDescription(): string { + const timeRange = this.evaluate(); + if (this.to === TimeRange.nowKeyword) { + return `Last ${moment.duration(moment(timeRange.toUnixSec * 1000).diff(timeRange.fromUnixSec * 1000)).humanize()}`; + } + return this.from + ' to ' + this.to; + } + + /** + * Converts a relative time string to an unix timestamp + * example: 'now-5s' => 1627403052 + * example: '-5s' => 1627403052 + * @param {string} input the expression + * @returns {number} a unix time stamp + */ + private static fromHumanExpressionToUnix(input: string): number { + let realRelativeTime = input.replace(/\s/g, ''); // remove all spaces + + if (!relativeTimeParser().isRelativeTimeFormat(realRelativeTime)) { + return Number(realRelativeTime); + } + + const nowPosition = realRelativeTime.indexOf(TimeRange.nowKeyword); + const backupRealRelativeTime = realRelativeTime; + if (nowPosition === 0) { // The expression starts with "now" + realRelativeTime = realRelativeTime.substring(nowPosition + TimeRange.nowKeyword.length); + } + + if (realRelativeTime === '') { // there is nothing after now + realRelativeTime = backupRealRelativeTime; + } + + const resultAsMomentObject = relativeTimeParser().relativeTime(realRelativeTime); + return resultAsMomentObject.unix(); + } +} diff --git a/monitoring/monitoring_ui/src/lib/ToplogyPipelineDefinitions.ts b/monitoring/monitoring_ui/src/lib/ToplogyPipelineDefinitions.ts new file mode 100644 index 0000000000000000000000000000000000000000..5e5089dc5e688385fcebd0e6a687df8ddc5c0095 --- /dev/null +++ b/monitoring/monitoring_ui/src/lib/ToplogyPipelineDefinitions.ts @@ -0,0 +1,23 @@ +export interface PipelineNode { + id: string; + level: number; + + consumers: string[]; + producers: string[]; +} + +export interface PipelineEdge { + id: string; + + fromId: string; + toId: string; + sourceName: string; + + receivers: string[]; +} + +export interface Pipeline { + nodes: PipelineNode[]; + edges: PipelineEdge[]; +} + diff --git a/monitoring/monitoring_ui/src/main.ts b/monitoring/monitoring_ui/src/main.ts new file mode 100644 index 0000000000000000000000000000000000000000..e3a1093fc6f5e5cb2f5085fe06adf64818a31289 --- /dev/null +++ b/monitoring/monitoring_ui/src/main.ts @@ -0,0 +1,43 @@ +import { createApp, nextTick } from 'vue'; +import App from './App.vue';; +import router from './router'; + +import './index.css'; + +import 'jquery'; +import 'flot/jquery.flot'; +import 'flot/jquery.flot.stack'; +import 'flot/jquery.flot.crosshair'; +import 'flotPlugins/jquery.flot.byte' + +import moment from 'moment'; + +// Add and use a precise time format +// Otherwise it would show: 'a few seconds' instead of '3 seconds' +moment.defineLocale('precise-en', { + relativeTime : { + future : 'in %s', + past : '%s ago', + s : '%d seconds', + ss : '%d seconds', + m : '%d minute', + mm : '%d minutes', + h : '%d hour', + hh : '%d hours', + d : '%d day', + dd : '%d days', + M : '%d month', + MM : '%d months', + y : '%d year', + yy : '%d years', + }, +}); + +createApp(App) + .use(router) + .mount('#app'); + + +nextTick(() => { + document.title = 'ASAPO Monitoring'; +}); \ No newline at end of file diff --git a/monitoring/monitoring_ui/src/router/index.ts b/monitoring/monitoring_ui/src/router/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..b8abbb47a930d4ad44b37c636f323d3ab0e7bbce --- /dev/null +++ b/monitoring/monitoring_ui/src/router/index.ts @@ -0,0 +1,20 @@ +import { createRouter, createWebHistory, RouteRecordRaw } from "vue-router"; +import Dashboard from "../views/Dashboard.vue"; + +const publicPath = "/tv" + +// Possible lazy load with: component: () => import("../views/SomePage.vue"), +const routes: Array<RouteRecordRaw> = [ + { + path: publicPath, + name: "Dashboard", + component: Dashboard, + } +]; + +const router = createRouter({ + history: createWebHistory(), + routes, +}); + +export default router; diff --git a/monitoring/monitoring_ui/src/shim-relative-time-parser.d.ts b/monitoring/monitoring_ui/src/shim-relative-time-parser.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..edadeff0d08f687d68d796f5a6c26e9a6c24514f --- /dev/null +++ b/monitoring/monitoring_ui/src/shim-relative-time-parser.d.ts @@ -0,0 +1,4 @@ +declare module 'relative-time-parser' { + const func: any; + export = func; +} diff --git a/monitoring/monitoring_ui/src/shims-vue.d.ts b/monitoring/monitoring_ui/src/shims-vue.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..f803e5c1c3b6cf84f5184143758f5561954e1f77 --- /dev/null +++ b/monitoring/monitoring_ui/src/shims-vue.d.ts @@ -0,0 +1,5 @@ +declare module '*.vue' { + import { DefineComponent } from 'vue' + const component: DefineComponent<{}, {}, any> + export default component +} diff --git a/monitoring/monitoring_ui/src/store/chartCrosshairStore.ts b/monitoring/monitoring_ui/src/store/chartCrosshairStore.ts new file mode 100644 index 0000000000000000000000000000000000000000..f699355f98098b1229e24a68e1aa15756b95ad2b --- /dev/null +++ b/monitoring/monitoring_ui/src/store/chartCrosshairStore.ts @@ -0,0 +1,25 @@ +import { reactive } from "vue"; + +export interface ChartCrosshairStoreState { + xValue: number | null; +} + +class ChartCrosshairStore { + private internalState: ChartCrosshairStoreState = reactive({ + xValue: null, + }); + + public get state(): Readonly<ChartCrosshairStoreState> { + return this.internalState; + } + + public showAndUpdate(xValue: number) { + this.internalState.xValue = xValue; + } + + public hide() { + this.internalState.xValue = null; + } +} + +export const chartCrosshairStore = new ChartCrosshairStore(); diff --git a/monitoring/monitoring_ui/src/store/connectionStore.ts b/monitoring/monitoring_ui/src/store/connectionStore.ts new file mode 100644 index 0000000000000000000000000000000000000000..e442b897c9e025f7174d5a443c5e6a8d3b9e6939 --- /dev/null +++ b/monitoring/monitoring_ui/src/store/connectionStore.ts @@ -0,0 +1,243 @@ +interface HitMissDataPoint { + timestamp: number; + hit: number; + miss: number; +} + +interface TransferTimePoint { + timestamp: number; + fromProducerToReceiverMs: number; + receiverStaleTimeMs: number; + fromReceiverToConsumerMs: number; +} + +interface TotalTransferSpeedPoint { + timestamp: number; + avgBytesPerSecRecv: number; + avgBytesPerSecSend: number; +} + +interface TotalCacheMemoryUsagePoint { + timestamp: number; + totalUntouchedMemory: number; + totalTouchedMemory: number; +} + +export interface ToplogyStage { + sourceName: string; + totalFileRateRequested: number; + totalGbRateRequested: number; + + receivers: ReceiverInfo[]; +} + +export interface ReceiverInfo { + receiverId: string; + fileRateIncoming: number; + gbRateIncoming: number; + usedMemory: number; + totalMemory: number; +} + +import { DataPointsQuery, DataPointsResponse, MetadataResponse, PipelineConnectionQueryMode, ToplogyQuery } from '../generated_proto/AsapoMonitoringQueryService_pb'; +import { Empty } from '../generated_proto/AsapoMonitoringCommonService_pb'; +import { timeStore } from './timeStore'; +import { selectionFilterStore } from './selectionFilterStore'; + +interface ConnectionStoreState { + isFetchingMetaData: boolean; + isFetchingData: boolean; + isFetchingToplogyData: boolean; + + // metadata + clusterName: string; + availableBeamtimes: string[]; +} + + +import { reactive } from 'vue'; +import { AsapoMonitoringQueryServiceClient } from '../generated_proto/AsapoMonitoringQueryService_grpc_web_pb'; +import { errorStore } from './errorStore'; +import { toplogyStore } from './toplogyStore'; +import { metricData } from './metricDataStore'; + +console.log('AsapoMonitoringQueryServicePromiseClient'); +const client = new AsapoMonitoringQueryServiceClient('/tv-api', null); + +class ConnectionStore { + private pendingDataRefreshTimeoutHandle?: number; + + private internalState: ConnectionStoreState = reactive({ + isFetchingMetaData: false, + isFetchingData: false, + isFetchingToplogyData: false, + + clusterName: '<NOT SET>', + availableBeamtimes: [], + }); + + public get state(): Readonly<ConnectionStoreState> { + return this.internalState; + } + + public setMetadata(initialData: MetadataResponse): void { + this.internalState.clusterName = initialData.getClustername(); + this.internalState.availableBeamtimes = initialData.getAvailablebeamtimesList(); + } + + public setIsFetchingData(mode: boolean): void { + this.internalState.isFetchingData = mode; + } + + public setIsFetchingMetaData(mode: boolean): void { + this.internalState.isFetchingMetaData = mode; + } + + public setIsFetchingToplogyData(mode: boolean): void { + this.internalState.isFetchingToplogyData = mode; + } + + public triggerToplogyRefresh(): void { + if (this.state.isFetchingToplogyData) { + console.warn('Unable to fetch toplogy: Already fetching toplogy data.'); + return; // already fetching data + } + + if (!selectionFilterStore.isValidFilterOrSetError()) { + return; + } + + this.setIsFetchingToplogyData(true); + + const query = new ToplogyQuery(); + + const range = timeStore.state.lastFixedTimeRange; + query.setFromtimestamp(range.fromUnixSec); + query.setTotimestamp(range.toUnixSec); + query.setBeamtimefilter(selectionFilterStore.state.beamtime!); + + errorStore.clearToplogyConnectionError(); + client.getTopology(query, undefined, (err, toplogyData) => { + if (err) { + errorStore.setToplogyConnectionErrorText(err.message); + console.error('getTopology error: ', err); + this.setIsFetchingToplogyData(false); + return; + } + + try { + toplogyStore.parseServerResponse(toplogyData); + } + catch(e) { + errorStore.setToplogyConnectionErrorText('internal: ' + e.message); + console.error('getTopology internal error: ', e); + } + finally { + this.setIsFetchingToplogyData(false); + } + + }); + } + + public triggerMetaDataRefresh(): void { + if (this.state.isFetchingMetaData) { + console.warn('Unable to fetch metadata: Already fetching metadata.'); + return; // already fetching data + } + + this.setIsFetchingMetaData(true); + + errorStore.clearMetadataConnectionError(); + client.getMetadata(new Empty(), undefined, (err, metaData) => { + if (err) { + errorStore.setMetadataConnectionErrorText(err.message); + console.error('getMetadata error: ', err); + this.setIsFetchingMetaData(false); + return; + } + + this.setMetadata(metaData); + this.setIsFetchingMetaData(false); + }); + } + + public clearPendingMetricsTimeout(): void { + if (this.pendingDataRefreshTimeoutHandle !== undefined) { // remove pending delay + clearTimeout(this.pendingDataRefreshTimeoutHandle); + this.pendingDataRefreshTimeoutHandle = undefined; + } + } + + public triggerMetricsRefresh(reevaluateTime = true): void { + if (this.state.isFetchingData) { + console.warn('Unable to fetch data: Already fetching data.'); + return; // already fetching data + } + this.clearPendingMetricsTimeout(); + if (!selectionFilterStore.isValidFilterOrSetError()) { + return; + } + + if (reevaluateTime) { + if (!timeStore.evaluateAndVerify()) { + return; + } + } + + if (toplogyStore.couldBeOutdated()) { + this.triggerToplogyRefresh(); + } + + this.setIsFetchingData(true); + + const query = new DataPointsQuery(); + + query.setFromtimestamp(timeStore.state.lastFixedTimeRange.fromUnixSec); + query.setTotimestamp(timeStore.state.lastFixedTimeRange.toUnixSec); + + if (selectionFilterStore.state.beamtime) { + query.setBeamtimefilter(selectionFilterStore.state.beamtime); + } + if (selectionFilterStore.state.source) { + query.setSourcefilter(selectionFilterStore.state.source); + } + if (selectionFilterStore.state.fromPipelineStepId) { + query.setFrompipelinestepfilter(selectionFilterStore.state.fromPipelineStepId); + } + if (selectionFilterStore.state.toPipelineStepId) { + query.setTopipelinestepfilter(selectionFilterStore.state.toPipelineStepId); + } + if (selectionFilterStore.state.fromPipelineStepId || selectionFilterStore.state.toPipelineStepId) { + query.setPipelinequerymode(selectionFilterStore.state.pipelineFilterRelation === 'and' ? PipelineConnectionQueryMode.EXACTPATH : PipelineConnectionQueryMode.JUSTRELATEDTOSTEP); + } + if (selectionFilterStore.state.receiverId) { + query.setReceiverfilter(selectionFilterStore.state.receiverId); + } + + errorStore.clearMetricsConnectionError(); + client.getDataPoints(query, undefined, (err, data) => { + if (err) { + errorStore.setMetricsConnectionErrorText(err.message); + console.error('getDataPoints error: ', err); + this.setIsFetchingData(false); + return; + } + + metricData.parseServerResponse(data); + if (timeStore.state.refreshIntervalInSec) { + this.pendingDataRefreshTimeoutHandle = setTimeout(() => this.triggerMetricsRefresh(), timeStore.state.refreshIntervalInSec * 1000); + } + this.setIsFetchingData(false); + }); + } +} + +// Singelton instance +export const connection = new ConnectionStore(); + +connection.triggerMetaDataRefresh(); +if (selectionFilterStore.state.beamtime) { + connection.triggerMetricsRefresh(); + connection.triggerToplogyRefresh(); +} + diff --git a/monitoring/monitoring_ui/src/store/errorStore.ts b/monitoring/monitoring_ui/src/store/errorStore.ts new file mode 100644 index 0000000000000000000000000000000000000000..8a70ae2571a5958669e71ccfed9398ced7afaf25 --- /dev/null +++ b/monitoring/monitoring_ui/src/store/errorStore.ts @@ -0,0 +1,83 @@ +import { reactive } from "vue"; + +export interface ErrorStoreState { + connectionMetadataErrorText: string | null; + connectionMetricsErrorText: string | null; + connectionToplogyErrorText: string | null; + filterErrorText: string | null; + timeErrorText: string | null; +} + +class ErrorStore { + private internalState: ErrorStoreState = reactive({ + connectionMetadataErrorText: null, + connectionMetricsErrorText: null, + connectionToplogyErrorText: null, + filterErrorText: null, + timeErrorText: null, + }); + + public get state(): Readonly<ErrorStoreState> { + return this.internalState; + } + + public setMetadataConnectionErrorText(text: string): void { + this.internalState.connectionMetadataErrorText = text; + } + public clearMetadataConnectionError(): void { + this.internalState.connectionMetadataErrorText = null; + } + + public setMetricsConnectionErrorText(text: string): void { + this.internalState.connectionMetricsErrorText = text; + } + public clearMetricsConnectionError(): void { + this.internalState.connectionMetricsErrorText = null; + } + + public setToplogyConnectionErrorText(text: string): void { + this.internalState.connectionToplogyErrorText = text; + } + public clearToplogyConnectionError(): void { + this.internalState.connectionToplogyErrorText = null; + } + + public setFilterErrorText(text: string): void { + this.internalState.filterErrorText = text; + } + public clearFilterErrorText(): void { + this.internalState.filterErrorText = null; + } + + public setTimeErrorText(text: string): void { + this.internalState.timeErrorText = text; + } + public clearTimeErrorText(): void { + this.internalState.timeErrorText = null; + } + + public get errorText(): string | null { + if (this.state.filterErrorText) { + return `Filter Error: ${this.state.filterErrorText}`; + } + if (this.state.timeErrorText) { + return `Time: ${this.state.timeErrorText}`; + } + + if (this.state.connectionMetadataErrorText) { + return `Metadata: ${this.state.connectionMetadataErrorText}`; + } + if (this.state.connectionMetricsErrorText) { + return `Metrics: ${this.state.connectionMetricsErrorText}`; + } + if (this.state.connectionToplogyErrorText) { + return `Toplogy: ${this.state.connectionToplogyErrorText}`; + } + + // possible other errors here + + return null; + } +} + +export const errorStore = new ErrorStore(); diff --git a/monitoring/monitoring_ui/src/store/metricDataStore.ts b/monitoring/monitoring_ui/src/store/metricDataStore.ts new file mode 100644 index 0000000000000000000000000000000000000000..54a56e1b26bfd5c8d408a9765252ffb82e34ada5 --- /dev/null +++ b/monitoring/monitoring_ui/src/store/metricDataStore.ts @@ -0,0 +1,114 @@ +import { reactive } from "vue"; +import { DataPointsResponse } from "../generated_proto/AsapoMonitoringQueryService_pb"; + +export type MetricDataPoint = [number/*Timestamp*/, number/*Value*/] +export type MetricDataSeries = MetricDataPoint[/*timestamp index*/] +export type MetricDataComplete = MetricDataSeries[/*series index*/] + +export interface MetricDataStoreState { + transferSpeedChartData: MetricDataComplete; + detailedTransferSpeedChartData: MetricDataComplete; + fileRateChartData: MetricDataComplete; + receiverTimePerTaskChartData: MetricDataComplete; + receiverRamUsageChartData: MetricDataComplete; +} + +class MetricDataStore { + private internalState: MetricDataStoreState = reactive({ + transferSpeedChartData: [], + detailedTransferSpeedChartData: [], + fileRateChartData: [], + receiverTimePerTaskChartData: [], + receiverRamUsageChartData: [], + }); + + public get state(): Readonly<MetricDataStoreState> { + return this.internalState; + } + + public parseServerResponse(data: DataPointsResponse): void { + const interval = data.getTimeintervalinsec() + + // transferSpeed & detailedTransferSpeed + { + let currentTime = data.getStarttimestampinsec(); + const transferSpeedRecv = [] as MetricDataSeries; + const transferSpeedSend = [] as MetricDataSeries; + const transferSpeedRdsSend = [] as MetricDataSeries; + const transferSpeedFtsSend = [] as MetricDataSeries; + for (const point of data.getTransferratesList()) { + transferSpeedRecv.push([currentTime * 1000, point.getTotalbytespersecrecv()]); + transferSpeedSend.push([currentTime * 1000, point.getTotalbytespersecsend()]); + transferSpeedRdsSend.push([currentTime * 1000, point.getTotalbytespersecrdssend()]); + transferSpeedFtsSend.push([currentTime * 1000, point.getTotalbytespersecftssend()]); + + currentTime += interval; + } + + this.internalState.transferSpeedChartData = [transferSpeedRecv, transferSpeedSend]; + this.internalState.detailedTransferSpeedChartData = [transferSpeedRecv, transferSpeedRdsSend, transferSpeedFtsSend]; + } + + // fileRate + { + let currentTime = data.getStarttimestampinsec(); + const unknown = [] as MetricDataSeries; + const miss = [] as MetricDataSeries; + const fromCache = [] as MetricDataSeries; + const fromDisk = [] as MetricDataSeries; + for (const point of data.getFileratesList()) { + const knownSum = point.getFromcache() + point.getFromdisk(); + unknown.push([currentTime * 1000, Math.max(0, point.getTotalrequests() - knownSum)]); + fromCache.push([currentTime * 1000, point.getFromcache()]); + fromDisk.push([currentTime * 1000, point.getFromdisk()]); + + miss.push([currentTime * 1000, point.getCachemisses()]); + /* + if (miss.length > 2 && !miss[miss.length - 1][1] && !miss[miss.length - 2][1] && point.getCachemisses() === 0) { + miss[miss.length - 1][1] = undefined as any; + miss.push([currentTime * 1000, 0]); + } else { + miss.push([currentTime * 1000, point.getCachemisses()]); + }*/ + + currentTime += interval; + } + + this.internalState.fileRateChartData = [unknown, miss, fromCache, fromDisk]; + } + + // receiverTimePerTask + { + let currentTime = data.getStarttimestampinsec(); + const receiveIo = [] as [number, number][]; + const writeIo = [] as [number, number][]; + const databaseIo = [] as [number, number][]; + for (const point of data.getTasktimesList()) { + + receiveIo.push([currentTime * 1000, point.getReceiveiotimeus()]); + writeIo.push([currentTime * 1000, point.getWritetodisktimeus()]); + databaseIo.push([currentTime * 1000, point.getWritetodatabasetimeus()]); + + currentTime += interval; + } + + this.internalState.receiverTimePerTaskChartData = [receiveIo, writeIo, databaseIo]; + } + + // receiverRamUsage + { + let currentTime = data.getStarttimestampinsec(); + const memoryUsed = [] as [number, number][]; + for (const point of data.getMemoryusagesList()) { + + memoryUsed.push([currentTime * 1000, point.getTotalusedmemory()]); + + currentTime += interval; + } + + this.internalState.receiverRamUsageChartData = [memoryUsed]; + } + } +} + +export const metricData = new MetricDataStore(); diff --git a/monitoring/monitoring_ui/src/store/selectionFilterStore.ts b/monitoring/monitoring_ui/src/store/selectionFilterStore.ts new file mode 100644 index 0000000000000000000000000000000000000000..21076600530da1fda8ff60ef4a123e0c8d5f3b85 --- /dev/null +++ b/monitoring/monitoring_ui/src/store/selectionFilterStore.ts @@ -0,0 +1,128 @@ +import { reactive } from "vue"; +import { connection } from "./connectionStore"; +import { errorStore } from "./errorStore"; + +const localStorageLastBeamtimeKey = 'selected-beamtime'; + +export interface SelectionFilterStoreState { + beamtime: string | null; + + source: string | null; + + fromPipelineStepId: string | null; + toPipelineStepId: string | null; + pipelineFilterRelation: 'and' | 'or'; + receiverId: string | null; +} + +class SelectionFilterStore { + private internalState: SelectionFilterStoreState = reactive({ + beamtime: null, + source: null, + fromPipelineStepId: null, + toPipelineStepId: null, + pipelineFilterRelation: 'and', + receiverId: null, + }); + + public get state(): Readonly<SelectionFilterStoreState> { + return this.internalState; + } + + public get hasClearableFilter(): boolean { + return !!(this.state.receiverId || this.state.source || this.state.fromPipelineStepId || this.state.toPipelineStepId); + } + + public setFilterBeamtime(beamtime: string | null, isInitial = false): void { + this.internalState.beamtime = beamtime; + this.internalState.source = null; + this.internalState.receiverId = null; + + if (beamtime != null) { + localStorage.setItem(localStorageLastBeamtimeKey, beamtime); + } else { + localStorage.removeItem(localStorageLastBeamtimeKey); + } + + if (!isInitial) { // otherwise we would get a dependency error if we access the connection to early + this.validateAndRefreshMetrics(); + } + } + + public clearSourceFilter(): void { + this.internalState.source = null; + this.internalState.fromPipelineStepId = null; + this.internalState.toPipelineStepId = null; + this.internalState.pipelineFilterRelation = 'and'; + this.internalState.receiverId = null; + } + + public setFilterSource(source: string | null): void { + if (source == null) { + this.clearSourceFilter(); + return; + } + this.internalState.source = source; + this.internalState.fromPipelineStepId = null; + this.internalState.toPipelineStepId = null; + this.internalState.pipelineFilterRelation = 'or'; + this.internalState.receiverId = null; + } + + public setFilterSourceWithPipeline(source: string, fromPipelineStepId: string, toPipelineStepId: string): void { + this.internalState.source = source; + this.internalState.fromPipelineStepId = fromPipelineStepId; + this.internalState.toPipelineStepId = toPipelineStepId; + this.internalState.pipelineFilterRelation = 'and'; + this.internalState.receiverId = null; + this.validateAndRefreshMetrics(); + } + + public setFilterPipelineStep(pipelineStepId: string): void { + this.internalState.source = null; + this.internalState.fromPipelineStepId = pipelineStepId; + this.internalState.toPipelineStepId = pipelineStepId; + this.internalState.pipelineFilterRelation = 'or'; + this.internalState.receiverId = null; + this.validateAndRefreshMetrics(); + } + + public setFilterReceiverId(receiverId: string): void { + this.internalState.receiverId = receiverId; + this.validateAndRefreshMetrics(); + } + + public clearFilter(): void { + // we do not reset the beamtime id + this.internalState.source = null; + this.internalState.fromPipelineStepId = null; + this.internalState.toPipelineStepId = null; + this.internalState.receiverId = null; + this.validateAndRefreshMetrics(); + } + + private validateAndRefreshMetrics(): void { + if (this.isValidFilterOrSetError()) { + connection.triggerMetricsRefresh(false /* do not reevaluate time*/); + } + } + + public isValidFilterOrSetError(): boolean { + errorStore.clearFilterErrorText(); + if (!this.state.beamtime) { + errorStore.setFilterErrorText('Beamtime must be set'); + return false; + } + return true; + } +} + +export const selectionFilterStore = new SelectionFilterStore(); + +(function loadLastBeamtimeFromStorage() { + const lastBeamtime = localStorage.getItem(localStorageLastBeamtimeKey); + if (lastBeamtime) { + selectionFilterStore.setFilterBeamtime(lastBeamtime, true); + } +})(); + diff --git a/monitoring/monitoring_ui/src/store/timeStore.ts b/monitoring/monitoring_ui/src/store/timeStore.ts new file mode 100644 index 0000000000000000000000000000000000000000..7d2feb51e6beb1b84e0791b7322a9266e72a2d54 --- /dev/null +++ b/monitoring/monitoring_ui/src/store/timeStore.ts @@ -0,0 +1,56 @@ +import { reactive } from "vue"; +import { FixedTimeRange, TimeRange } from "../lib/TimeRange"; +import { errorStore } from "./errorStore"; + +export interface TimeStoreState { + refreshIntervalInSec: number | null; + + timeExpressionFrom: string; + timeExpressionTo: string; + + lastFixedTimeRange: FixedTimeRange; +} + +class TimeStore { + private internalState: TimeStoreState = reactive({ + refreshIntervalInSec: 5, + + timeExpressionFrom: 'now-10m', + timeExpressionTo: 'now', + + lastFixedTimeRange: { + fromUnixSec: 0, + toUnixSec: 0, + } + }); + + public get state(): Readonly<TimeStoreState> { + return this.internalState; + } + + public setRefreshInterval(intervalInSec: number | null): void { + this.internalState.refreshIntervalInSec = intervalInSec; + } + + public setTimeRange(from: string, to: string): void { + this.internalState.timeExpressionFrom = from; + this.internalState.timeExpressionTo = to; + } + + public evaluateAndVerify(): boolean { + const range = new TimeRange(this.state.timeExpressionFrom, this.state.timeExpressionTo); + errorStore.clearTimeErrorText(); + const evaled = range.evaluate(); + + if (isNaN(evaled.fromUnixSec) || isNaN(evaled.toUnixSec)) { + errorStore.setTimeErrorText('Invalid time format'); + return false; + } + + this.internalState.lastFixedTimeRange.fromUnixSec = evaled.fromUnixSec; + this.internalState.lastFixedTimeRange.toUnixSec = evaled.toUnixSec; + return true; + } +} + +export const timeStore = new TimeStore(); diff --git a/monitoring/monitoring_ui/src/store/tooltipStore.ts b/monitoring/monitoring_ui/src/store/tooltipStore.ts new file mode 100644 index 0000000000000000000000000000000000000000..570a96067ce96a4503471dc45981ee82a24b4669 --- /dev/null +++ b/monitoring/monitoring_ui/src/store/tooltipStore.ts @@ -0,0 +1,46 @@ +import { reactive } from "vue"; + +export interface TooltipTableInfo { + name: string; + value: string; +} + +export interface TooltipStoreState { + visible: boolean; + + posX: number; + posY: number; + + titleLine: string; + lines: TooltipTableInfo[]; +} + +class TooltipStore { + private internalState: TooltipStoreState = reactive({ + visible: false, + + posX: 0, + posY: 0, + + titleLine: '', + lines: [], + }); + + public get state(): Readonly<TooltipStoreState> { + return this.internalState; + } + + public showAndUpdate(posX: number, posY: number, titleLine: string, lines: TooltipTableInfo[]) { + this.internalState.visible = true; + this.internalState.posX = posX; + this.internalState.posY = posY; + this.internalState.titleLine = titleLine; + this.internalState.lines = lines; + } + + public hide() { + this.internalState.visible = false; + } +} + +export const tooltipStore = new TooltipStore(); diff --git a/monitoring/monitoring_ui/src/store/toplogyStore.ts b/monitoring/monitoring_ui/src/store/toplogyStore.ts new file mode 100644 index 0000000000000000000000000000000000000000..325d36209100e842aa9eaede1d5bf9764ee61233 --- /dev/null +++ b/monitoring/monitoring_ui/src/store/toplogyStore.ts @@ -0,0 +1,96 @@ +import { reactive } from "vue"; +import { TopologyResponse } from "../generated_proto/AsapoMonitoringQueryService_pb"; +import { FixedTimeRange } from "../lib/TimeRange"; +import { Pipeline, PipelineNode, PipelineEdge } from "../lib/ToplogyPipelineDefinitions"; +import { timeStore } from "./timeStore"; + +export interface ToplogyStoreState { + lastUpdateRange: FixedTimeRange, + pipeline: Pipeline; + nodeMap: NodeMap; + edgeMap: EdgeMap; +} + +type NodeMap = {[nodeId: string]: PipelineNode}; +type EdgeMap = {[edgeId: string]: PipelineEdge}; + +class ToplogyStore { + private internalState: ToplogyStoreState = reactive({ + lastUpdateRange: { + fromUnixSec: 0, + toUnixSec: 0 + }, + pipeline: { + nodes: [], + edges: [], + }, + nodeMap: {}, + edgeMap: {}, + }); + + public get state(): Readonly<ToplogyStoreState> { + return this.internalState; + } + + public parseServerResponse(toplogyData: TopologyResponse): void { + const newNodes: PipelineNode[] = []; + const newNodeMap: NodeMap = {}; + for(const node of toplogyData.getNodesList()) { + const newNode = { + id: node.getNodeid(), + level: node.getLevel(), + + producers: node.getProducerinstancesList(), + consumers: node.getConsumerinstancesList(), + }; + newNodes.push(newNode); + newNodeMap[newNode.id] = newNode; + } + + const newEdges: PipelineEdge[] = []; + const newedgeMap: EdgeMap = {}; + for(const edge of toplogyData.getEdgesList()) { + const newEdge = { + id: '', + fromId: edge.getFromnodeid(), + toId: edge.getTonodeid(), + + receivers: edge.getInvolvedreceiversList(), + sourceName: edge.getSourcename(), + }; + + newEdge.id = `${newEdge.fromId}~>${newEdge.sourceName}~>${newEdge.toId}`; + newEdges.push(newEdge); + newedgeMap[newEdge.id] = newEdge; + } + + this.internalState.nodeMap = newNodeMap; + this.internalState.edgeMap = newedgeMap; + this.internalState.pipeline = { + nodes: newNodes, + edges: newEdges, + }; + + this.internalState.lastUpdateRange.fromUnixSec = timeStore.state.lastFixedTimeRange.fromUnixSec; + this.internalState.lastUpdateRange.toUnixSec = timeStore.state.lastFixedTimeRange.toUnixSec; + } + + public couldBeOutdated(): boolean { + const maxPipelineToplogyOldnessInSec = 60; + + return Math.abs(this.internalState.lastUpdateRange.fromUnixSec - timeStore.state.lastFixedTimeRange.fromUnixSec) > maxPipelineToplogyOldnessInSec || + Math.abs(this.internalState.lastUpdateRange.toUnixSec - timeStore.state.lastFixedTimeRange.toUnixSec) > maxPipelineToplogyOldnessInSec + } + + public getAvailableSources(): string[] { + const set = new Set<string>(); + + for (const edge of this.state.pipeline.edges) { + set.add(edge.sourceName); + } + + return [...set]; + } +} + +export const toplogyStore = new ToplogyStore(); diff --git a/monitoring/monitoring_ui/src/views/Dashboard.vue b/monitoring/monitoring_ui/src/views/Dashboard.vue new file mode 100644 index 0000000000000000000000000000000000000000..7a6575f96f34f934bc1d46687aa32a9c8ec91e76 --- /dev/null +++ b/monitoring/monitoring_ui/src/views/Dashboard.vue @@ -0,0 +1,229 @@ +<template> + <div id="dashboard" class="w-full h-full flex flex-col"> + <NavBar /> + <main class="flex-1 flex m-2"> + <div class="flex-1 flex flex-col"><!-- left side --> + <!--flex-grow: 1; --> + <TopologyGraph style="height: 97%" /> + <!--<LiveMessageLog style=" height: 33.333%;" />--> + </div> + <div class="flex-1"><!-- right side --> + <div class="graph-group"> + <GenericChart class="inline-flex" ref="transferSpeedChart" :chartInfo="{ + title: 'Total transfer speed', + yUnit: 'byteRate', + stacked: false, + series: [ + { name: 'Produced', description: 'Total input bytes per seconds for all selected receivers', color: '#edc240' }, + { name: 'Consumed (requested)', description: 'Total requested outgoing bytes (consumer requested broker)', color: '#afd8f8' }, + ]}" /> + <GenericChart class="inline-flex" ref="fileRateChart" :chartInfo="{ + title: 'Total file rate', + yUnit: 'plainNumber', + stacked: true, + series: [ + { name: 'Unknown', description: 'Requested but unknown how they were resolved (possible local FS)', color: '#6d6d6d' }, + { name: 'Cache Miss', description: 'The Receiver Data Service got an request but was not able to find this file in the cache', color: '#ed6240' }, + { name: 'From cache', description: 'The Receiver Data Service got an request and was able to serve the file', color: '#4dc240' }, + { name: 'From disk (FTS)', description: 'The File Transfer Service got an request and was able to serve the file', color: '#2196f3' }, + ]}" /> + <GenericListChart class="inline-flex" label="Producers" :elements="involvedProducers" /> + <GenericListChart class="inline-flex" label="Consumers" :elements="involvedConsumers" /> + </div> + + <h2 class="ml-1 mt-2">Advanced stats</h2> + <div class="graph-group"> + <GenericListChart class="inline-flex" label="Involved Receviers" :elements="involvedReceiverList" :onElementClicked="onReceiverSelected" :isElementSelected="isReceiverSelected" /> + <GenericChart class="inline-flex" ref="detailedTransferSpeedChart" :chartInfo="{ + title: 'Total transfer speed by service', + yUnit: 'byteRate', + stacked: false, + series: [ + { name: 'Input', description: 'Total input bytes per seconds for all selected receivers', color: '#edc240' }, + { name: 'RDS Output', description: 'Total (RDS)output bytes per seconds for all selected receivers', color: '#4dc240' }, + { name: 'FTS Output', description: 'Total (FTS)output bytes per seconds', color: '#2196f3' }, + ]}" /> + <GenericChart class="inline-flex w-full" ref="receiverTimePerTaskChart" :chartInfo="{ + title: 'Receiver: Average time per task', + yUnit: 'timeUs', + stacked: true, + series: [ + { name: 'Receive IO', description: 'Time it took to transfer the file from the consumer to the receiver', color: '#edc240' }, + { name: 'Write IO', description: 'Time it took to write the file to the disk', color: '#c7619a' }, + { name: 'Database', description: 'Time it took to write the file-metadata to the database', color: '#6d7cd0' }, + { name: 'RDS: Send IO', description: 'Time it took to send the file to a consumer (decoupled from other values)', color: '#4dc240' }, + ]}" /> + <GenericChart class="inline-flex" ref="receiverRamUsageChart" :chartInfo="{ + title: 'Receiver: Cache memory usage', + yUnit: 'byte', + stacked: true, + series: [ + { name: 'Used', description: 'Memory used by current selection', color: '#673ab7' }, + ]}" /> + </div> + </div> + </main> + </div> +</template> + +<script lang="ts"> +import { Options, Vue } from 'vue-class-component'; +import NavBar from '../components/NavBar.vue'; +import TopologyGraph from '../components/TopologyGraph.vue'; +import GenericChart from '../components/GenericChart.vue'; +import GenericListChart from '../components/GenericListChart.vue'; +import { connection } from '../store/connectionStore'; +import { DataPointsResponse } from '../generated_proto/AsapoMonitoringQueryService_pb'; +import { selectionFilterStore } from '../store/selectionFilterStore'; +import { toplogyStore } from '../store/toplogyStore'; +import { metricData, MetricDataComplete } from '../store/metricDataStore'; + + +@Options({ + components: { + NavBar, + + TopologyGraph, + GenericChart, + GenericListChart, + }, + watch: { + storeData() { + if (this.storeData != null) { + this.onUpdateData(this.storeData); + } + }, + transferSpeedChartData() { + this.onTransferSpeedChartDataChanged(); + }, + detailedTransferSpeedChartData() { + this.onDetailedTransferSpeedChartDataChanged(); + }, + fileRateChartData() { + this.onFileRateChartDataChanged(); + }, + receiverTimePerTaskChartData() { + this.onReceiverTimePerTaskChartDataChanged(); + }, + receiverRamUsageChartData() { + this.onReceiverRamUsageChartDataChanged(); + }, + } +}) +export default class Dashboard extends Vue { + public get transferSpeedChartData(): MetricDataComplete { + return metricData.state.transferSpeedChartData; + } + public get detailedTransferSpeedChartData(): MetricDataComplete { + return metricData.state.detailedTransferSpeedChartData; + } + public get fileRateChartData(): MetricDataComplete { + return metricData.state.fileRateChartData; + } + public get receiverTimePerTaskChartData(): MetricDataComplete { + return metricData.state.receiverTimePerTaskChartData; + } + public get receiverRamUsageChartData(): MetricDataComplete { + return metricData.state.receiverRamUsageChartData; + } + + private get involvedProducers(): string[] { + let nodes = toplogyStore.state.pipeline.nodes; + + if (selectionFilterStore.state.fromPipelineStepId && selectionFilterStore.state.toPipelineStepId) { + nodes = nodes.filter(node => node.id === selectionFilterStore.state.fromPipelineStepId || node.id === selectionFilterStore.state.toPipelineStepId); + } + + return nodes.flatMap(node => node.producers); + } + + private get involvedConsumers(): string[] { + let nodes = toplogyStore.state.pipeline.nodes; + + if (selectionFilterStore.state.fromPipelineStepId && selectionFilterStore.state.toPipelineStepId) { + nodes = nodes.filter(node => node.id === selectionFilterStore.state.fromPipelineStepId || node.id === selectionFilterStore.state.toPipelineStepId); + } + + return nodes.flatMap(node => node.consumers); + } + + private get involvedReceiverList(): string[] { + let edges = toplogyStore.state.pipeline.edges; + + if (selectionFilterStore.state.source) { + edges = edges.filter(edge => edge.sourceName === selectionFilterStore.state.source); + } + if (selectionFilterStore.state.receiverId) { + edges = edges.filter(edge => edge.receivers.includes(selectionFilterStore.state.receiverId!)); + } + if (selectionFilterStore.state.fromPipelineStepId && selectionFilterStore.state.toPipelineStepId) { + edges = edges.filter(edge => edge.fromId === selectionFilterStore.state.fromPipelineStepId && edge.toId === selectionFilterStore.state.toPipelineStepId); + } + + const receiverIds = edges.flatMap(edge => edge.receivers); + + return [...new Set(receiverIds)]; // Make unique + } + + private onReceiverSelected(receiverId: string): void { + selectionFilterStore.setFilterReceiverId(receiverId); + } + + private isReceiverSelected(receiverId: string): boolean { + return selectionFilterStore.state.receiverId === receiverId; + } + + private onTransferSpeedChartDataChanged(): void { + const chartRef = this.$refs['transferSpeedChart'] as GenericChart; + chartRef.setDataPoints(this.transferSpeedChartData); + } + private onDetailedTransferSpeedChartDataChanged(): void { + const chartRef = this.$refs['detailedTransferSpeedChart'] as GenericChart; + chartRef.setDataPoints(this.detailedTransferSpeedChartData); + } + private onFileRateChartDataChanged(): void { + const chartRef = this.$refs['fileRateChart'] as GenericChart; + chartRef.setDataPoints(this.fileRateChartData); + } + private onReceiverTimePerTaskChartDataChanged(): void { + const chartRef = this.$refs['receiverTimePerTaskChart'] as GenericChart; + chartRef.setDataPoints(this.receiverTimePerTaskChartData); + } + private onReceiverRamUsageChartDataChanged(): void { + const chartRef = this.$refs['receiverRamUsageChart'] as GenericChart; + chartRef.setDataPoints(this.receiverRamUsageChartData); + } +} +</script> + +<!-- Add "scoped" attribute to limit CSS to this component only --> +<style scoped lang="scss"> +h3 { + margin: 40px 0 0; + span { + color: red; + } +} +ul { + list-style-type: none; + padding: 0; +} +li { + display: inline-block; + margin: 0 10px; +} +a { + color: #42b983; +} + +@media (min-width: 1200px) { + .graph-group > * { + width: 50%; + } +} +@media (max-width: 1200px) { + .graph-group > * { + width: 100%; + } +} +</style> diff --git a/monitoring/monitoring_ui/tailwind.config.js b/monitoring/monitoring_ui/tailwind.config.js new file mode 100644 index 0000000000000000000000000000000000000000..6904f56ee1bd7b7c7b8065cf6ab7247320f4fdc5 --- /dev/null +++ b/monitoring/monitoring_ui/tailwind.config.js @@ -0,0 +1,963 @@ +const colors = require('tailwindcss/colors') + +module.exports = { + purge: { content: ['./public/**/*.html', './src/**/*.vue'] }, + presets: [], + darkMode: false, // or 'media' or 'class' + theme: { + screens: { + sm: '640px', + md: '768px', + lg: '1024px', + xl: '1280px', + '2xl': '1536px', + }, + colors: { + transparent: 'transparent', + current: 'currentColor', + + black: colors.black, + white: colors.white, + gray: colors.coolGray, + red: colors.red, + yellow: colors.amber, + green: colors.emerald, + blue: colors.blue, + indigo: colors.indigo, + purple: colors.violet, + pink: colors.pink, + }, + spacing: { + px: '1px', + 0: '0px', + 0.5: '0.125rem', + 1: '0.25rem', + 1.5: '0.375rem', + 2: '0.5rem', + 2.5: '0.625rem', + 3: '0.75rem', + 3.5: '0.875rem', + 4: '1rem', + 5: '1.25rem', + 6: '1.5rem', + 7: '1.75rem', + 8: '2rem', + 9: '2.25rem', + 10: '2.5rem', + 11: '2.75rem', + 12: '3rem', + 14: '3.5rem', + 16: '4rem', + 20: '5rem', + 24: '6rem', + 28: '7rem', + 32: '8rem', + 36: '9rem', + 40: '10rem', + 44: '11rem', + 48: '12rem', + 52: '13rem', + 56: '14rem', + 60: '15rem', + 64: '16rem', + 72: '18rem', + 80: '20rem', + 96: '24rem', + }, + animation: { + none: 'none', + spin: 'spin 1s linear infinite', + ping: 'ping 1s cubic-bezier(0, 0, 0.2, 1) infinite', + pulse: 'pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite', + bounce: 'bounce 1s infinite', + }, + backdropBlur: (theme) => theme('blur'), + backdropBrightness: (theme) => theme('brightness'), + backdropContrast: (theme) => theme('contrast'), + backdropGrayscale: (theme) => theme('grayscale'), + backdropHueRotate: (theme) => theme('hueRotate'), + backdropInvert: (theme) => theme('invert'), + backdropOpacity: (theme) => theme('opacity'), + backdropSaturate: (theme) => theme('saturate'), + backdropSepia: (theme) => theme('sepia'), + backgroundColor: (theme) => theme('colors'), + backgroundImage: { + none: 'none', + 'gradient-to-t': 'linear-gradient(to top, var(--tw-gradient-stops))', + 'gradient-to-tr': 'linear-gradient(to top right, var(--tw-gradient-stops))', + 'gradient-to-r': 'linear-gradient(to right, var(--tw-gradient-stops))', + 'gradient-to-br': 'linear-gradient(to bottom right, var(--tw-gradient-stops))', + 'gradient-to-b': 'linear-gradient(to bottom, var(--tw-gradient-stops))', + 'gradient-to-bl': 'linear-gradient(to bottom left, var(--tw-gradient-stops))', + 'gradient-to-l': 'linear-gradient(to left, var(--tw-gradient-stops))', + 'gradient-to-tl': 'linear-gradient(to top left, var(--tw-gradient-stops))', + }, + backgroundOpacity: (theme) => theme('opacity'), + backgroundPosition: { + bottom: 'bottom', + center: 'center', + left: 'left', + 'left-bottom': 'left bottom', + 'left-top': 'left top', + right: 'right', + 'right-bottom': 'right bottom', + 'right-top': 'right top', + top: 'top', + }, + backgroundSize: { + auto: 'auto', + cover: 'cover', + contain: 'contain', + }, + blur: { + 0: '0', + sm: '4px', + DEFAULT: '8px', + md: '12px', + lg: '16px', + xl: '24px', + '2xl': '40px', + '3xl': '64px', + }, + brightness: { + 0: '0', + 50: '.5', + 75: '.75', + 90: '.9', + 95: '.95', + 100: '1', + 105: '1.05', + 110: '1.1', + 125: '1.25', + 150: '1.5', + 200: '2', + }, + borderColor: (theme) => ({ + ...theme('colors'), + DEFAULT: theme('colors.gray.200', 'currentColor'), + }), + borderOpacity: (theme) => theme('opacity'), + borderRadius: { + none: '0px', + sm: '0.125rem', + DEFAULT: '0.25rem', + md: '0.375rem', + lg: '0.5rem', + xl: '0.75rem', + '2xl': '1rem', + '3xl': '1.5rem', + full: '9999px', + }, + borderWidth: { + DEFAULT: '1px', + 0: '0px', + 2: '2px', + 4: '4px', + 8: '8px', + }, + boxShadow: { + sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)', + DEFAULT: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)', + md: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)', + lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)', + xl: '0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)', + '2xl': '0 25px 50px -12px rgba(0, 0, 0, 0.25)', + inner: 'inset 0 2px 4px 0 rgba(0, 0, 0, 0.06)', + none: 'none', + }, + contrast: { + 0: '0', + 50: '.5', + 75: '.75', + 100: '1', + 125: '1.25', + 150: '1.5', + 200: '2', + }, + container: {}, + cursor: { + auto: 'auto', + default: 'default', + pointer: 'pointer', + wait: 'wait', + text: 'text', + move: 'move', + help: 'help', + 'not-allowed': 'not-allowed', + }, + divideColor: (theme) => theme('borderColor'), + divideOpacity: (theme) => theme('borderOpacity'), + divideWidth: (theme) => theme('borderWidth'), + dropShadow: { + sm: '0 1px 1px rgba(0,0,0,0.05)', + DEFAULT: ['0 1px 2px rgba(0, 0, 0, 0.1)', '0 1px 1px rgba(0, 0, 0, 0.06)'], + md: ['0 4px 3px rgba(0, 0, 0, 0.07)', '0 2px 2px rgba(0, 0, 0, 0.06)'], + lg: ['0 10px 8px rgba(0, 0, 0, 0.04)', '0 4px 3px rgba(0, 0, 0, 0.1)'], + xl: ['0 20px 13px rgba(0, 0, 0, 0.03)', '0 8px 5px rgba(0, 0, 0, 0.08)'], + '2xl': '0 25px 25px rgba(0, 0, 0, 0.15)', + none: '0 0 #0000', + }, + fill: { current: 'currentColor' }, + grayscale: { + 0: '0', + DEFAULT: '100%', + }, + hueRotate: { + '-180': '-180deg', + '-90': '-90deg', + '-60': '-60deg', + '-30': '-30deg', + '-15': '-15deg', + 0: '0deg', + 15: '15deg', + 30: '30deg', + 60: '60deg', + 90: '90deg', + 180: '180deg', + }, + invert: { + 0: '0', + DEFAULT: '100%', + }, + flex: { + 1: '1 1 0%', + auto: '1 1 auto', + initial: '0 1 auto', + none: 'none', + }, + flexGrow: { + 0: '0', + DEFAULT: '1', + }, + flexShrink: { + 0: '0', + DEFAULT: '1', + }, + fontFamily: { + sans: [ + 'ui-sans-serif', + 'system-ui', + '-apple-system', + 'BlinkMacSystemFont', + '"Segoe UI"', + 'Roboto', + '"Helvetica Neue"', + 'Arial', + '"Noto Sans"', + 'sans-serif', + '"Apple Color Emoji"', + '"Segoe UI Emoji"', + '"Segoe UI Symbol"', + '"Noto Color Emoji"', + ], + serif: ['ui-serif', 'Georgia', 'Cambria', '"Times New Roman"', 'Times', 'serif'], + mono: [ + 'ui-monospace', + 'SFMono-Regular', + 'Menlo', + 'Monaco', + 'Consolas', + '"Liberation Mono"', + '"Courier New"', + 'monospace', + ], + }, + fontSize: { + xs: ['0.75rem', { lineHeight: '1rem' }], + sm: ['0.875rem', { lineHeight: '1.25rem' }], + base: ['1rem', { lineHeight: '1.5rem' }], + lg: ['1.125rem', { lineHeight: '1.75rem' }], + xl: ['1.25rem', { lineHeight: '1.75rem' }], + '2xl': ['1.5rem', { lineHeight: '2rem' }], + '3xl': ['1.875rem', { lineHeight: '2.25rem' }], + '4xl': ['2.25rem', { lineHeight: '2.5rem' }], + '5xl': ['3rem', { lineHeight: '1' }], + '6xl': ['3.75rem', { lineHeight: '1' }], + '7xl': ['4.5rem', { lineHeight: '1' }], + '8xl': ['6rem', { lineHeight: '1' }], + '9xl': ['8rem', { lineHeight: '1' }], + }, + fontWeight: { + thin: '100', + extralight: '200', + light: '300', + normal: '400', + medium: '500', + semibold: '600', + bold: '700', + extrabold: '800', + black: '900', + }, + gap: (theme) => theme('spacing'), + gradientColorStops: (theme) => theme('colors'), + gridAutoColumns: { + auto: 'auto', + min: 'min-content', + max: 'max-content', + fr: 'minmax(0, 1fr)', + }, + gridAutoRows: { + auto: 'auto', + min: 'min-content', + max: 'max-content', + fr: 'minmax(0, 1fr)', + }, + gridColumn: { + auto: 'auto', + 'span-1': 'span 1 / span 1', + 'span-2': 'span 2 / span 2', + 'span-3': 'span 3 / span 3', + 'span-4': 'span 4 / span 4', + 'span-5': 'span 5 / span 5', + 'span-6': 'span 6 / span 6', + 'span-7': 'span 7 / span 7', + 'span-8': 'span 8 / span 8', + 'span-9': 'span 9 / span 9', + 'span-10': 'span 10 / span 10', + 'span-11': 'span 11 / span 11', + 'span-12': 'span 12 / span 12', + 'span-full': '1 / -1', + }, + gridColumnEnd: { + auto: 'auto', + 1: '1', + 2: '2', + 3: '3', + 4: '4', + 5: '5', + 6: '6', + 7: '7', + 8: '8', + 9: '9', + 10: '10', + 11: '11', + 12: '12', + 13: '13', + }, + gridColumnStart: { + auto: 'auto', + 1: '1', + 2: '2', + 3: '3', + 4: '4', + 5: '5', + 6: '6', + 7: '7', + 8: '8', + 9: '9', + 10: '10', + 11: '11', + 12: '12', + 13: '13', + }, + gridRow: { + auto: 'auto', + 'span-1': 'span 1 / span 1', + 'span-2': 'span 2 / span 2', + 'span-3': 'span 3 / span 3', + 'span-4': 'span 4 / span 4', + 'span-5': 'span 5 / span 5', + 'span-6': 'span 6 / span 6', + 'span-full': '1 / -1', + }, + gridRowStart: { + auto: 'auto', + 1: '1', + 2: '2', + 3: '3', + 4: '4', + 5: '5', + 6: '6', + 7: '7', + }, + gridRowEnd: { + auto: 'auto', + 1: '1', + 2: '2', + 3: '3', + 4: '4', + 5: '5', + 6: '6', + 7: '7', + }, + gridTemplateColumns: { + none: 'none', + 1: 'repeat(1, minmax(0, 1fr))', + 2: 'repeat(2, minmax(0, 1fr))', + 3: 'repeat(3, minmax(0, 1fr))', + 4: 'repeat(4, minmax(0, 1fr))', + 5: 'repeat(5, minmax(0, 1fr))', + 6: 'repeat(6, minmax(0, 1fr))', + 7: 'repeat(7, minmax(0, 1fr))', + 8: 'repeat(8, minmax(0, 1fr))', + 9: 'repeat(9, minmax(0, 1fr))', + 10: 'repeat(10, minmax(0, 1fr))', + 11: 'repeat(11, minmax(0, 1fr))', + 12: 'repeat(12, minmax(0, 1fr))', + }, + gridTemplateRows: { + none: 'none', + 1: 'repeat(1, minmax(0, 1fr))', + 2: 'repeat(2, minmax(0, 1fr))', + 3: 'repeat(3, minmax(0, 1fr))', + 4: 'repeat(4, minmax(0, 1fr))', + 5: 'repeat(5, minmax(0, 1fr))', + 6: 'repeat(6, minmax(0, 1fr))', + }, + height: (theme) => ({ + auto: 'auto', + ...theme('spacing'), + '1/2': '50%', + '1/3': '33.333333%', + '2/3': '66.666667%', + '1/4': '25%', + '2/4': '50%', + '3/4': '75%', + '1/5': '20%', + '2/5': '40%', + '3/5': '60%', + '4/5': '80%', + '1/6': '16.666667%', + '2/6': '33.333333%', + '3/6': '50%', + '4/6': '66.666667%', + '5/6': '83.333333%', + full: '100%', + screen: '100vh', + }), + inset: (theme, { negative }) => ({ + auto: 'auto', + ...theme('spacing'), + ...negative(theme('spacing')), + '1/2': '50%', + '1/3': '33.333333%', + '2/3': '66.666667%', + '1/4': '25%', + '2/4': '50%', + '3/4': '75%', + full: '100%', + '-1/2': '-50%', + '-1/3': '-33.333333%', + '-2/3': '-66.666667%', + '-1/4': '-25%', + '-2/4': '-50%', + '-3/4': '-75%', + '-full': '-100%', + }), + keyframes: { + spin: { + to: { + transform: 'rotate(360deg)', + }, + }, + ping: { + '75%, 100%': { + transform: 'scale(2)', + opacity: '0', + }, + }, + pulse: { + '50%': { + opacity: '.5', + }, + }, + bounce: { + '0%, 100%': { + transform: 'translateY(-25%)', + animationTimingFunction: 'cubic-bezier(0.8,0,1,1)', + }, + '50%': { + transform: 'none', + animationTimingFunction: 'cubic-bezier(0,0,0.2,1)', + }, + }, + }, + letterSpacing: { + tighter: '-0.05em', + tight: '-0.025em', + normal: '0em', + wide: '0.025em', + wider: '0.05em', + widest: '0.1em', + }, + lineHeight: { + none: '1', + tight: '1.25', + snug: '1.375', + normal: '1.5', + relaxed: '1.625', + loose: '2', + 3: '.75rem', + 4: '1rem', + 5: '1.25rem', + 6: '1.5rem', + 7: '1.75rem', + 8: '2rem', + 9: '2.25rem', + 10: '2.5rem', + }, + listStyleType: { + none: 'none', + disc: 'disc', + decimal: 'decimal', + }, + margin: (theme, { negative }) => ({ + auto: 'auto', + ...theme('spacing'), + ...negative(theme('spacing')), + }), + maxHeight: (theme) => ({ + ...theme('spacing'), + full: '100%', + screen: '100vh', + }), + maxWidth: (theme, { breakpoints }) => ({ + none: 'none', + 0: '0rem', + xs: '20rem', + sm: '24rem', + md: '28rem', + lg: '32rem', + xl: '36rem', + '2xl': '42rem', + '3xl': '48rem', + '4xl': '56rem', + '5xl': '64rem', + '6xl': '72rem', + '7xl': '80rem', + full: '100%', + min: 'min-content', + max: 'max-content', + prose: '65ch', + ...breakpoints(theme('screens')), + }), + minHeight: { + 0: '0px', + full: '100%', + screen: '100vh', + }, + minWidth: { + 0: '0px', + full: '100%', + min: 'min-content', + max: 'max-content', + }, + objectPosition: { + bottom: 'bottom', + center: 'center', + left: 'left', + 'left-bottom': 'left bottom', + 'left-top': 'left top', + right: 'right', + 'right-bottom': 'right bottom', + 'right-top': 'right top', + top: 'top', + }, + opacity: { + 0: '0', + 5: '0.05', + 10: '0.1', + 20: '0.2', + 25: '0.25', + 30: '0.3', + 40: '0.4', + 50: '0.5', + 60: '0.6', + 70: '0.7', + 75: '0.75', + 80: '0.8', + 90: '0.9', + 95: '0.95', + 100: '1', + }, + order: { + first: '-9999', + last: '9999', + none: '0', + 1: '1', + 2: '2', + 3: '3', + 4: '4', + 5: '5', + 6: '6', + 7: '7', + 8: '8', + 9: '9', + 10: '10', + 11: '11', + 12: '12', + }, + outline: { + none: ['2px solid transparent', '2px'], + white: ['2px dotted white', '2px'], + black: ['2px dotted black', '2px'], + }, + padding: (theme) => theme('spacing'), + placeholderColor: (theme) => theme('colors'), + placeholderOpacity: (theme) => theme('opacity'), + ringColor: (theme) => ({ + DEFAULT: theme('colors.blue.500', '#3b82f6'), + ...theme('colors'), + }), + ringOffsetColor: (theme) => theme('colors'), + ringOffsetWidth: { + 0: '0px', + 1: '1px', + 2: '2px', + 4: '4px', + 8: '8px', + }, + ringOpacity: (theme) => ({ + DEFAULT: '0.5', + ...theme('opacity'), + }), + ringWidth: { + DEFAULT: '3px', + 0: '0px', + 1: '1px', + 2: '2px', + 4: '4px', + 8: '8px', + }, + rotate: { + '-180': '-180deg', + '-90': '-90deg', + '-45': '-45deg', + '-12': '-12deg', + '-6': '-6deg', + '-3': '-3deg', + '-2': '-2deg', + '-1': '-1deg', + 0: '0deg', + 1: '1deg', + 2: '2deg', + 3: '3deg', + 6: '6deg', + 12: '12deg', + 45: '45deg', + 90: '90deg', + 180: '180deg', + }, + saturate: { + 0: '0', + 50: '.5', + 100: '1', + 150: '1.5', + 200: '2', + }, + scale: { + 0: '0', + 50: '.5', + 75: '.75', + 90: '.9', + 95: '.95', + 100: '1', + 105: '1.05', + 110: '1.1', + 125: '1.25', + 150: '1.5', + }, + sepia: { + 0: '0', + DEFAULT: '100%', + }, + skew: { + '-12': '-12deg', + '-6': '-6deg', + '-3': '-3deg', + '-2': '-2deg', + '-1': '-1deg', + 0: '0deg', + 1: '1deg', + 2: '2deg', + 3: '3deg', + 6: '6deg', + 12: '12deg', + }, + space: (theme, { negative }) => ({ + ...theme('spacing'), + ...negative(theme('spacing')), + }), + stroke: { + current: 'currentColor', + }, + strokeWidth: { + 0: '0', + 1: '1', + 2: '2', + }, + textColor: (theme) => theme('colors'), + textOpacity: (theme) => theme('opacity'), + transformOrigin: { + center: 'center', + top: 'top', + 'top-right': 'top right', + right: 'right', + 'bottom-right': 'bottom right', + bottom: 'bottom', + 'bottom-left': 'bottom left', + left: 'left', + 'top-left': 'top left', + }, + transitionDelay: { + 75: '75ms', + 100: '100ms', + 150: '150ms', + 200: '200ms', + 300: '300ms', + 500: '500ms', + 700: '700ms', + 1000: '1000ms', + }, + transitionDuration: { + DEFAULT: '150ms', + 75: '75ms', + 100: '100ms', + 150: '150ms', + 200: '200ms', + 300: '300ms', + 500: '500ms', + 700: '700ms', + 1000: '1000ms', + }, + transitionProperty: { + none: 'none', + all: 'all', + DEFAULT: + 'background-color, border-color, color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter', + colors: 'background-color, border-color, color, fill, stroke', + opacity: 'opacity', + shadow: 'box-shadow', + transform: 'transform', + }, + transitionTimingFunction: { + DEFAULT: 'cubic-bezier(0.4, 0, 0.2, 1)', + linear: 'linear', + in: 'cubic-bezier(0.4, 0, 1, 1)', + out: 'cubic-bezier(0, 0, 0.2, 1)', + 'in-out': 'cubic-bezier(0.4, 0, 0.2, 1)', + }, + translate: (theme, { negative }) => ({ + ...theme('spacing'), + ...negative(theme('spacing')), + '1/2': '50%', + '1/3': '33.333333%', + '2/3': '66.666667%', + '1/4': '25%', + '2/4': '50%', + '3/4': '75%', + full: '100%', + '-1/2': '-50%', + '-1/3': '-33.333333%', + '-2/3': '-66.666667%', + '-1/4': '-25%', + '-2/4': '-50%', + '-3/4': '-75%', + '-full': '-100%', + }), + width: (theme) => ({ + auto: 'auto', + ...theme('spacing'), + '1/2': '50%', + '1/3': '33.333333%', + '2/3': '66.666667%', + '1/4': '25%', + '2/4': '50%', + '3/4': '75%', + '1/5': '20%', + '2/5': '40%', + '3/5': '60%', + '4/5': '80%', + '1/6': '16.666667%', + '2/6': '33.333333%', + '3/6': '50%', + '4/6': '66.666667%', + '5/6': '83.333333%', + '1/12': '8.333333%', + '2/12': '16.666667%', + '3/12': '25%', + '4/12': '33.333333%', + '5/12': '41.666667%', + '6/12': '50%', + '7/12': '58.333333%', + '8/12': '66.666667%', + '9/12': '75%', + '10/12': '83.333333%', + '11/12': '91.666667%', + full: '100%', + screen: '100vw', + min: 'min-content', + max: 'max-content', + }), + zIndex: { + auto: 'auto', + 0: '0', + 10: '10', + 20: '20', + 30: '30', + 40: '40', + 50: '50', + }, + }, + variantOrder: [ + 'first', + 'last', + 'odd', + 'even', + 'visited', + 'checked', + 'group-hover', + 'group-focus', + 'focus-within', + 'hover', + 'focus', + 'focus-visible', + 'active', + 'disabled', + ], + variants: { + accessibility: ['responsive', 'focus-within', 'focus'], + alignContent: ['responsive'], + alignItems: ['responsive'], + alignSelf: ['responsive'], + animation: ['responsive'], + appearance: ['responsive'], + backdropBlur: ['responsive'], + backdropBrightness: ['responsive'], + backdropContrast: ['responsive'], + backdropDropShadow: ['responsive'], + backdropFilter: ['responsive'], + backdropGrayscale: ['responsive'], + backdropHueRotate: ['responsive'], + backdropInvert: ['responsive'], + backdropSaturate: ['responsive'], + backdropSepia: ['responsive'], + backgroundAttachment: ['responsive'], + backgroundBlendMode: ['responsive'], + backgroundClip: ['responsive'], + backgroundColor: ['responsive', 'dark', 'group-hover', 'focus-within', 'hover', 'focus'], + backgroundImage: ['responsive'], + backgroundOpacity: ['responsive', 'dark', 'group-hover', 'focus-within', 'hover', 'focus'], + backgroundPosition: ['responsive'], + backgroundRepeat: ['responsive'], + backgroundSize: ['responsive'], + blur: ['responsive'], + borderCollapse: ['responsive'], + borderColor: ['responsive', 'dark', 'group-hover', 'focus-within', 'hover', 'focus'], + borderOpacity: ['responsive', 'dark', 'group-hover', 'focus-within', 'hover', 'focus'], + borderRadius: ['responsive'], + borderStyle: ['responsive'], + borderWidth: ['responsive'], + boxDecorationBreak: ['responsive'], + boxShadow: ['responsive', 'group-hover', 'focus-within', 'hover', 'focus'], + boxSizing: ['responsive'], + brightness: ['responsive'], + clear: ['responsive'], + container: ['responsive'], + contrast: ['responsive'], + cursor: ['responsive'], + display: ['responsive'], + divideColor: ['responsive', 'dark'], + divideOpacity: ['responsive', 'dark'], + divideStyle: ['responsive'], + divideWidth: ['responsive'], + dropShadow: ['responsive'], + fill: ['responsive'], + filter: ['responsive'], + flex: ['responsive'], + flexDirection: ['responsive'], + flexGrow: ['responsive'], + flexShrink: ['responsive'], + flexWrap: ['responsive'], + float: ['responsive'], + fontFamily: ['responsive'], + fontSize: ['responsive'], + fontSmoothing: ['responsive'], + fontStyle: ['responsive'], + fontVariantNumeric: ['responsive'], + fontWeight: ['responsive'], + gap: ['responsive'], + gradientColorStops: ['responsive', 'dark', 'hover', 'focus'], + grayscale: ['responsive'], + gridAutoColumns: ['responsive'], + gridAutoFlow: ['responsive'], + gridAutoRows: ['responsive'], + gridColumn: ['responsive'], + gridColumnEnd: ['responsive'], + gridColumnStart: ['responsive'], + gridRow: ['responsive'], + gridRowEnd: ['responsive'], + gridRowStart: ['responsive'], + gridTemplateColumns: ['responsive'], + gridTemplateRows: ['responsive'], + height: ['responsive'], + hueRotate: ['responsive'], + inset: ['responsive'], + invert: ['responsive'], + isolation: ['responsive'], + justifyContent: ['responsive'], + justifyItems: ['responsive'], + justifySelf: ['responsive'], + letterSpacing: ['responsive'], + lineHeight: ['responsive'], + listStylePosition: ['responsive'], + listStyleType: ['responsive'], + margin: ['responsive'], + maxHeight: ['responsive'], + maxWidth: ['responsive'], + minHeight: ['responsive'], + minWidth: ['responsive'], + mixBlendMode: ['responsive'], + objectFit: ['responsive'], + objectPosition: ['responsive'], + opacity: ['responsive', 'group-hover', 'focus-within', 'hover', 'focus'], + order: ['responsive'], + outline: ['responsive', 'focus-within', 'focus'], + overflow: ['responsive'], + overscrollBehavior: ['responsive'], + padding: ['responsive'], + placeContent: ['responsive'], + placeItems: ['responsive'], + placeSelf: ['responsive'], + placeholderColor: ['responsive', 'dark', 'focus'], + placeholderOpacity: ['responsive', 'dark', 'focus'], + pointerEvents: ['responsive'], + position: ['responsive'], + resize: ['responsive'], + ringColor: ['responsive', 'dark', 'focus-within', 'focus'], + ringOffsetColor: ['responsive', 'dark', 'focus-within', 'focus'], + ringOffsetWidth: ['responsive', 'focus-within', 'focus'], + ringOpacity: ['responsive', 'dark', 'focus-within', 'focus'], + ringWidth: ['responsive', 'focus-within', 'focus'], + rotate: ['responsive', 'hover', 'focus'], + saturate: ['responsive'], + scale: ['responsive', 'hover', 'focus'], + sepia: ['responsive'], + skew: ['responsive', 'hover', 'focus'], + space: ['responsive'], + stroke: ['responsive'], + strokeWidth: ['responsive'], + tableLayout: ['responsive'], + textAlign: ['responsive'], + textColor: ['responsive', 'dark', 'group-hover', 'focus-within', 'hover', 'focus'], + textDecoration: ['responsive', 'group-hover', 'focus-within', 'hover', 'focus'], + textOpacity: ['responsive', 'dark', 'group-hover', 'focus-within', 'hover', 'focus'], + textOverflow: ['responsive'], + textTransform: ['responsive'], + transform: ['responsive'], + transformOrigin: ['responsive'], + transitionDelay: ['responsive'], + transitionDuration: ['responsive'], + transitionProperty: ['responsive'], + transitionTimingFunction: ['responsive'], + translate: ['responsive', 'hover', 'focus'], + userSelect: ['responsive'], + verticalAlign: ['responsive'], + visibility: ['responsive'], + whitespace: ['responsive'], + width: ['responsive'], + wordBreak: ['responsive'], + zIndex: ['responsive', 'focus-within', 'focus'], + }, + plugins: [], +} diff --git a/monitoring/monitoring_ui/tsconfig.json b/monitoring/monitoring_ui/tsconfig.json new file mode 100644 index 0000000000000000000000000000000000000000..272401ccac374a8d59dfc419e0d76e211c8f8701 --- /dev/null +++ b/monitoring/monitoring_ui/tsconfig.json @@ -0,0 +1,32 @@ +{ + "compilerOptions": { + "target": "esnext", + "module": "esnext", + "moduleResolution": "node", + "strict": true, + "jsx": "preserve", + "sourceMap": true, + "resolveJsonModule": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "experimentalDecorators": true, + "lib": [ + "esnext", + "dom", + "dom.iterable", + "scripthost" + ], + "types": [ + "jquery" + ], + }, + "include": [ + "src/**/*.ts", + "src/**/*.d.ts", + "src/**/*.tsx", + "src/**/*.vue" + ], + "exclude": [ + "node_modules" + ] +} diff --git a/monitoring/monitoring_ui/vue.config.js b/monitoring/monitoring_ui/vue.config.js new file mode 100644 index 0000000000000000000000000000000000000000..1529722c73e024034b5afd57a63d848c9bdab2f7 --- /dev/null +++ b/monitoring/monitoring_ui/vue.config.js @@ -0,0 +1,30 @@ +const path = require('path'); +const webpack = require('webpack'); + +module.exports = { + publicPath: '/tv/', // change it in src/router/index.js as well, I could not find how to do that automatically + configureWebpack: { + resolve: { + alias: { + flot: path.resolve(__dirname, './src/3dparty/flot'), + flotPlugins: path.resolve(__dirname, './src/3dparty/flotPlugins'), + } + }, + plugins: [ + new webpack.ProvidePlugin({ + $: 'jquery', + jQuery: 'jquery', + }), + ], + }, + devServer: { + proxy: { + "^/tv-api": { + target: "http://127.0.0.1:5020", + changeOrigin: true, + logLevel: "debug", + pathRewrite: { "^/tv-api": "/" } + } + } + } +}; diff --git a/monitoring/removeDevDatabaseContainer.sh b/monitoring/removeDevDatabaseContainer.sh new file mode 100755 index 0000000000000000000000000000000000000000..8484025daab07fdf238db4d2df64de50c1d4e92f --- /dev/null +++ b/monitoring/removeDevDatabaseContainer.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +docker rm -f asapo-monitoring-influxdb + +sudo rm -rf $HOME/asapoInfluxdbData diff --git a/monitoring/rpc_proxy/Dockerfile b/monitoring/rpc_proxy/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..2625f3f794c57830d91f0dcaeb7f75dc81e884a4 --- /dev/null +++ b/monitoring/rpc_proxy/Dockerfile @@ -0,0 +1,5 @@ +FROM envoyproxy/envoy:v1.17.0 + +COPY ./envoy.yaml /etc/envoy/envoy.yaml + +CMD /usr/local/bin/envoy -c /etc/envoy/envoy.yaml -l trace diff --git a/monitoring/rpc_proxy/docker-compose.yml b/monitoring/rpc_proxy/docker-compose.yml new file mode 100644 index 0000000000000000000000000000000000000000..ceaccabff5c433572f69025e44a333be889f86b9 --- /dev/null +++ b/monitoring/rpc_proxy/docker-compose.yml @@ -0,0 +1,13 @@ +version: '3' +services: + envoy: + build: + context: ./ + dockerfile: ./Dockerfile + image: grpcweb/envoy + ports: + - "5020:8080" + - "9901:9901" + extra_hosts: + dockerhost: ${DOCKER_HOST_IP} + diff --git a/monitoring/rpc_proxy/envoy.yaml b/monitoring/rpc_proxy/envoy.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e4e406f0f0d48b4722774bc61c3ec7aadefcae0d --- /dev/null +++ b/monitoring/rpc_proxy/envoy.yaml @@ -0,0 +1,55 @@ +admin: + access_log_path: /tmp/admin_access.log + address: + socket_address: { address: 0.0.0.0, port_value: 9901 } + +static_resources: + listeners: + - name: listener_0 + address: + socket_address: { address: 0.0.0.0, port_value: 8080 } + filter_chains: + - filters: + - name: envoy.filters.network.http_connection_manager + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager + codec_type: auto + stat_prefix: ingress_http + route_config: + name: local_route + virtual_hosts: + - name: local_service + domains: ["*"] + routes: + - match: { prefix: "/" } + route: + cluster: echo_service + timeout: 0s + max_stream_duration: + grpc_timeout_header_max: 0s + cors: + allow_origin_string_match: + - prefix: "*" + allow_methods: GET, PUT, DELETE, POST, OPTIONS + allow_headers: keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,custom-header-1,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout + max_age: "1728000" + expose_headers: custom-header-1,grpc-status,grpc-message + http_filters: + - name: envoy.filters.http.grpc_web + - name: envoy.filters.http.cors + - name: envoy.filters.http.router + clusters: + - name: echo_service + connect_timeout: 0.25s + type: logical_dns + http2_protocol_options: {} + lb_policy: round_robin + load_assignment: + cluster_name: cluster_0 + endpoints: + - lb_endpoints: + - endpoint: + address: + socket_address: + address: dockerhost + port_value: 50051 diff --git a/monitoring/rpc_proxy/start_dev_envoy_proxy.sh b/monitoring/rpc_proxy/start_dev_envoy_proxy.sh new file mode 100755 index 0000000000000000000000000000000000000000..2e9d0d2fbb065b314d2a119f53687df4c8a84973 --- /dev/null +++ b/monitoring/rpc_proxy/start_dev_envoy_proxy.sh @@ -0,0 +1,5 @@ +#!/bin/sh + + +DOCKER_HOST_IP=`hostname -I | awk '{print $1}'` docker-compose up --build + diff --git a/monitoring/startDevDatabaseContainer.sh b/monitoring/startDevDatabaseContainer.sh new file mode 100755 index 0000000000000000000000000000000000000000..22629a84c0fa65d23946c29e43784073c7b838af --- /dev/null +++ b/monitoring/startDevDatabaseContainer.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +docker run -d -p 8086:8086 \ + --name asapo-monitoring-influxdb \ + -v $HOME/asapoInfluxdbData/data:/var/lib/influxdb2 \ + -v $HOME/asapoInfluxdbData/config:/etc/influxdb2 \ + -e DOCKER_INFLUXDB_INIT_MODE=setup \ + -e DOCKER_INFLUXDB_INIT_USERNAME=user \ + -e DOCKER_INFLUXDB_INIT_PASSWORD=password \ + -e DOCKER_INFLUXDB_INIT_ORG=asapo \ + -e DOCKER_INFLUXDB_INIT_BUCKET=asapo-monitoring \ + influxdb:2.0.7 diff --git a/producer/api/cpp/include/asapo/producer/producer.h b/producer/api/cpp/include/asapo/producer/producer.h index 6876202b773f64e1ee1115d8c85be60a3207b1bc..0dfdf60e4355eaa9f03a53315c9cceefe9d70f4e 100644 --- a/producer/api/cpp/include/asapo/producer/producer.h +++ b/producer/api/cpp/include/asapo/producer/producer.h @@ -161,14 +161,13 @@ class Producer { //! Set beamtime id which producer will use to send data virtual Error SetCredentials(SourceCredentials source_cred) = 0; //! Get current size of the requests queue (number of requests pending/being processed) - virtual uint64_t GetRequestsQueueSize() = 0; + virtual uint64_t GetRequestsQueueSize() = 0; //! Get current volume of the requests queue (total memory of occupied by pending/being processed requests) - virtual uint64_t GetRequestsQueueVolumeMb() = 0; + virtual uint64_t GetRequestsQueueVolumeMb() = 0; //! Set maximum size of the requests queue (0 for unlimited, default 0) and volume in Megabytes (0 for unlimited, default 0) - virtual void SetRequestsQueueLimits(uint64_t size, uint64_t volume) = 0; + virtual void SetRequestsQueueLimits(uint64_t size, uint64_t volume) = 0; //! Wait until all current requests are processed or timeout virtual Error WaitRequestsFinished(uint64_t timeout_ms) = 0; - }; } diff --git a/producer/api/cpp/src/producer_impl.cpp b/producer/api/cpp/src/producer_impl.cpp index a0b68f07018a2281f5df907387107f5164b3e3f2..abe31f8faa5e19624ed7763e9e1dfe9116a4cef2 100644 --- a/producer/api/cpp/src/producer_impl.cpp +++ b/producer/api/cpp/src/producer_impl.cpp @@ -11,6 +11,7 @@ #include "asapo/request/request_pool_error.h" #include "asapo/http_client/http_client.h" #include "asapo/common/internal/version.h" +#include <asapo/io/io_factory.h> namespace asapo { @@ -18,7 +19,7 @@ const size_t ProducerImpl::kDiscoveryServiceUpdateFrequencyMs = 10000; // 10s ProducerImpl::ProducerImpl(std::string endpoint, uint8_t n_processing_threads, uint64_t timeout_ms, asapo::RequestHandlerType type) : - log__{GetDefaultProducerLogger()}, httpclient__{DefaultHttpClient()}, timeout_ms_{timeout_ms}, endpoint_{endpoint} { + log__{GetDefaultProducerLogger()}, io__{GenerateDefaultIO()}, httpclient__{DefaultHttpClient()}, timeout_ms_{timeout_ms}, endpoint_{endpoint} { switch (type) { case RequestHandlerType::kTcp: discovery_service_.reset(new ReceiverDiscoveryService{endpoint, @@ -30,6 +31,7 @@ ProducerImpl::ProducerImpl(std::string endpoint, uint8_t n_processing_threads, u break; } request_pool__.reset(new RequestPool{n_processing_threads, request_handler_factory_.get(), log__}); + } GenericRequestHeader ProducerImpl::GenerateNextSendRequest(const MessageHeader& message_header, std::string stream, @@ -188,9 +190,10 @@ Error ProducerImpl::Send(const MessageHeader& message_header, err = request_pool__->AddRequest(std::unique_ptr<ProducerRequest> { new ProducerRequest{ - source_cred_string_, std::move(request_header), - std::move(data), std::move(message_header.user_metadata), std::move(full_path), callback, - manage_data_memory, timeout_ms_} + source_cred_string_, + std::move(request_header), std::move(data), std::move(message_header.user_metadata), + std::move(full_path), callback, + manage_data_memory, timeout_ms_} }); return HandleErrorFromPool(std::move(err), manage_data_memory); @@ -250,12 +253,27 @@ void ProducerImpl::EnableRemoteLog(bool enable) { } Error ProducerImpl::SetCredentials(SourceCredentials source_cred) { - if (!source_cred_string_.empty()) { log__->Error("credentials already set"); return ProducerErrorTemplates::kWrongInput.Generate("credentials already set"); } + Error err = RefreshSourceCredentialString(source_cred); + if (!err) { + last_creds_.reset(new SourceCredentials{source_cred}); + } + return err; +} + +Error ProducerImpl::RefreshSourceCredentialString(SourceCredentials source_cred) { + if (source_cred.instance_id.empty()) { + source_cred.instance_id = SourceCredentials::kDefaultInstanceId; + } + + if (source_cred.pipeline_step.empty()) { + source_cred.pipeline_step = SourceCredentials::kDefaultPipelineStep; + } + if (source_cred.data_source.empty()) { source_cred.data_source = SourceCredentials::kDefaultDataSource; } @@ -269,19 +287,29 @@ Error ProducerImpl::SetCredentials(SourceCredentials source_cred) { } if (source_cred.beamtime_id == SourceCredentials::kDefaultBeamtimeId - && source_cred.beamline == SourceCredentials::kDefaultBeamline) { + && source_cred.beamline == SourceCredentials::kDefaultBeamline) { log__->Error("beamtime or beamline should be set"); source_cred_string_ = ""; return ProducerErrorTemplates::kWrongInput.Generate("beamtime or beamline should be set"); } - source_cred_string_ = source_cred.GetString(); - if (source_cred_string_.size() + source_cred.user_token.size() > kMaxMessageSize) { - log__->Error("credentials string is too long - " + source_cred_string_); - source_cred_string_ = ""; - return ProducerErrorTemplates::kWrongInput.Generate("credentials string is too long"); + if (source_cred.instance_id == SourceCredentials::kDefaultInstanceId) { + Error err; + std::string hostname = io__->GetHostName(&err); + + if (err) { + hostname = "hostnameerror"; + } + + source_cred.instance_id = hostname + "_" + std::to_string(io__->GetCurrentPid()); } + if (source_cred.pipeline_step == SourceCredentials::kDefaultPipelineStep) { + source_cred.pipeline_step = "DefaultStep"; + } + + source_cred_string_ = source_cred.GetString(); + return nullptr; } @@ -397,12 +425,12 @@ std::string ProducerImpl::BlockingRequest(GenericRequestHeader header, uint64_t *err = request_pool__->AddRequest(std::unique_ptr<ProducerRequest> { new ProducerRequest{ - source_cred_string_, std::move(header), - nullptr, "", "", - unwrap_callback( + source_cred_string_, std::move(header), + nullptr, "", "", + unwrap_callback( ActivatePromiseForReceiverResponse, std::move(promise)), true, - timeout_ms} + timeout_ms} }, true); if (*err) { return ""; @@ -551,4 +579,4 @@ std::string ProducerImpl::GetMeta(const std::string& stream, uint64_t timeout_ms return response; } -} \ No newline at end of file +} diff --git a/producer/api/cpp/src/producer_impl.h b/producer/api/cpp/src/producer_impl.h index 018db26be2668e3917b4ff304e9042315aaf4cca..3e20d453b2747a00ecba4fb6119ed8eed5cc1459 100644 --- a/producer/api/cpp/src/producer_impl.h +++ b/producer/api/cpp/src/producer_impl.h @@ -61,6 +61,7 @@ class ProducerImpl : public Producer { Error DeleteStream(std::string stream, uint64_t timeout_ms, DeleteStreamOptions options) const override; AbstractLogger* log__; + std::unique_ptr<IO> io__; std::unique_ptr<HttpClient> httpclient__; std::unique_ptr<RequestPool> request_pool__; @@ -92,6 +93,7 @@ class ProducerImpl : public Producer { RequestCallback callback, bool manage_data_memory); GenericRequestHeader GenerateNextSendRequest(const MessageHeader& message_header, std::string stream, uint64_t ingest_mode); + std::unique_ptr<SourceCredentials> last_creds_; std::string source_cred_string_; uint64_t timeout_ms_; std::string endpoint_; @@ -99,6 +101,7 @@ class ProducerImpl : public Producer { bool* supported) const; std::string GetMeta(const std::string& stream, uint64_t timeout_ms, Error* err) const; + Error RefreshSourceCredentialString(SourceCredentials source_cred); }; struct ReceiverResponse { diff --git a/producer/api/cpp/src/producer_request.cpp b/producer/api/cpp/src/producer_request.cpp index 0ae7b1bf3218cc50b7deda671935ce845b70b78c..3b6d584c4c12f119bdf5ea36785b6d1cd6f1c479 100644 --- a/producer/api/cpp/src/producer_request.cpp +++ b/producer/api/cpp/src/producer_request.cpp @@ -11,7 +11,8 @@ bool ProducerRequest::DataFromFile() const { return true; } -ProducerRequest::ProducerRequest(std::string source_credentials, +ProducerRequest::ProducerRequest( + std::string source_credentials, GenericRequestHeader h, MessageData data, std::string metadata, @@ -19,19 +20,18 @@ ProducerRequest::ProducerRequest(std::string source_credentials, RequestCallback callback, bool manage_data_memory, uint64_t timeout_ms) : GenericRequest(std::move(h), timeout_ms), - source_credentials{std::move(source_credentials)}, - metadata{std::move(metadata)}, - data{std::move(data)}, - original_filepath{std::move(original_filepath)}, - callback{callback}, - manage_data_memory{manage_data_memory} { + source_credentials{std::move(source_credentials)}, + metadata{std::move(metadata)}, + data{std::move(data)}, + original_filepath{std::move(original_filepath)}, + callback{callback}, + manage_data_memory{manage_data_memory} { if (kProducerProtocol.GetReceiverVersion().size() < kMaxVersionSize) { strcpy(header.api_version, kProducerProtocol.GetReceiverVersion().c_str()); } else { strcpy(header.api_version, "v0.0"); } - } bool ProducerRequest::NeedSend() const { @@ -65,4 +65,4 @@ Error ProducerRequest::UpdateDataSizeFromFileIfNeeded(const IO* io) { return nullptr; } -} \ No newline at end of file +} diff --git a/producer/api/cpp/src/producer_request.h b/producer/api/cpp/src/producer_request.h index 130a296e7823b9d4b8ebff15956c79609e41766b..6c403d4d55e0472c2ed823caedfab338c867be56 100644 --- a/producer/api/cpp/src/producer_request.h +++ b/producer/api/cpp/src/producer_request.h @@ -12,7 +12,10 @@ namespace asapo { class ProducerRequest : public GenericRequest { public: ~ProducerRequest(); - ProducerRequest(std::string source_credentials, GenericRequestHeader header, MessageData data, + ProducerRequest( + std::string source_credentials, + GenericRequestHeader header, + MessageData data, std::string metadata, std::string original_filepath, RequestCallback callback, diff --git a/producer/api/cpp/src/receiver_discovery_service.cpp b/producer/api/cpp/src/receiver_discovery_service.cpp index 45e7c4195869acada195dcb2760ff4b341c8ab8e..3b307a6f7bfa0ccbb46da9663fc0b0918bd34766 100644 --- a/producer/api/cpp/src/receiver_discovery_service.cpp +++ b/producer/api/cpp/src/receiver_discovery_service.cpp @@ -41,15 +41,17 @@ Error ReceiverDiscoveryService::UpdateFromEndpoint(ReceiversList* list, uint64_t Error err; HttpCode code; - auto responce = httpclient__->Get(endpoint_, &code, &err); + auto response = httpclient__->Get(endpoint_, &code, &err); if (err != nullptr) { return err; } if (code != HttpCode::OK) { - return GeneralErrorTemplates::kSimpleError.Generate(responce); + return GeneralErrorTemplates::kSimpleError.Generate(response); } - return ParseResponse(responce, list, max_connections); - + if (response.empty()) { + return GeneralErrorTemplates::kSimpleError.Generate("Empty response from discovery service"); + } + return ParseResponse(response, list, max_connections); } void ReceiverDiscoveryService::LogUriList(const ReceiversList& uris) { diff --git a/producer/api/cpp/src/request_handler_tcp.cpp b/producer/api/cpp/src/request_handler_tcp.cpp index defaa31a51e326d0c4329bf9fba0c6f6212b19e3..53cc9e4c4f0f056ce5436a4188d369326bea663a 100644 --- a/producer/api/cpp/src/request_handler_tcp.cpp +++ b/producer/api/cpp/src/request_handler_tcp.cpp @@ -4,6 +4,8 @@ #include "asapo/io/io_factory.h" #include "producer_request.h" +#include "asapo/common/internal/version.h" + namespace asapo { RequestHandlerTcp::RequestHandlerTcp(ReceiverDiscoveryService* discovery_service, uint64_t thread_id, @@ -17,6 +19,7 @@ RequestHandlerTcp::RequestHandlerTcp(ReceiverDiscoveryService* discovery_service Error RequestHandlerTcp::Authorize(const std::string& source_credentials) { GenericRequestHeader header{kOpcodeAuthorize, 0, 0, source_credentials.size(), ""}; + strcpy(header.api_version, kProducerProtocol.GetReceiverVersion().c_str()); Error err; io__->Send(sd_, &header, sizeof(header), &err); if (err) { @@ -237,7 +240,7 @@ bool ImmediateCallbackAfterError(const Error& err) { } bool RequestHandlerTcp::SendToOneOfTheReceivers(ProducerRequest* request, bool* retry) { - for (auto receiver_uri : receivers_list_) { + for (const auto& receiver_uri : receivers_list_) { if (Disconnected()) { auto err = ConnectToReceiver(request->source_credentials, receiver_uri); if (ImmediateCallbackAfterError(err)) { diff --git a/producer/api/cpp/unittests/test_producer.cpp b/producer/api/cpp/unittests/test_producer.cpp index 61443083639034797ddc11453f31bc0df52bf9f5..3bda9094b75c04010555bb43d0f8dcebafc141cf 100644 --- a/producer/api/cpp/unittests/test_producer.cpp +++ b/producer/api/cpp/unittests/test_producer.cpp @@ -15,60 +15,56 @@ namespace { TEST(CreateProducer, TcpProducer) { asapo::Error err; std::unique_ptr<asapo::Producer> producer = asapo::Producer::Create("endpoint", 4, asapo::RequestHandlerType::kTcp, - SourceCredentials{asapo::SourceType::kRaw, "bt", "", "", ""}, 3600000, &err); - ASSERT_THAT(dynamic_cast<asapo::ProducerImpl*>(producer.get()), Ne(nullptr)); - ASSERT_THAT(err, Eq(nullptr)); -} + SourceCredentials{asapo::SourceType::kRaw, "", "", "b", "", "", ""}, 3600000, &err); -TEST(CreateProducer, ErrorBeamtime) { - asapo::Error err; - std::string expected_beamtimeid(asapo::kMaxMessageSize * 10, 'a'); - std::unique_ptr<asapo::Producer> producer = asapo::Producer::Create("endpoint", 4, asapo::RequestHandlerType::kTcp, - SourceCredentials{asapo::SourceType::kRaw, expected_beamtimeid, "", "", ""}, 3600000, &err); - ASSERT_THAT(producer, Eq(nullptr)); - ASSERT_THAT(err, Eq(asapo::ProducerErrorTemplates::kWrongInput)); + EXPECT_THAT(err, Eq(nullptr)); + EXPECT_THAT(dynamic_cast<asapo::ProducerImpl*>(producer.get()), Ne(nullptr)); } TEST(CreateProducer, ErrorOnBothAutoBeamlineBeamtime) { - asapo::SourceCredentials creds{asapo::SourceType::kRaw, "auto", "auto", "subname", "token"}; + asapo::SourceCredentials creds{asapo::SourceType::kRaw, "instance", "step", "auto", "auto", "subname", "token"}; asapo::Error err; std::unique_ptr<asapo::Producer> producer = asapo::Producer::Create("endpoint", 4, asapo::RequestHandlerType::kTcp, creds, 3600000, &err); - ASSERT_THAT(producer, Eq(nullptr)); - ASSERT_THAT(err, Eq(asapo::ProducerErrorTemplates::kWrongInput)); + + EXPECT_THAT(err, Eq(asapo::ProducerErrorTemplates::kWrongInput)); + EXPECT_THAT(producer, Eq(nullptr)); } TEST(CreateProducer, TooManyThreads) { asapo::Error err; std::unique_ptr<asapo::Producer> producer = asapo::Producer::Create("", asapo::kMaxProcessingThreads + 1, - asapo::RequestHandlerType::kTcp, SourceCredentials{asapo::SourceType::kRaw, "bt", "", "", ""}, 3600000, &err); - ASSERT_THAT(producer, Eq(nullptr)); - ASSERT_THAT(err, Eq(asapo::ProducerErrorTemplates::kWrongInput)); + asapo::RequestHandlerType::kTcp, SourceCredentials{asapo::SourceType::kRaw, "", "", "", "", "", ""}, 3600000, &err); + + EXPECT_THAT(err, Eq(asapo::ProducerErrorTemplates::kWrongInput)); + EXPECT_THAT(producer, Eq(nullptr)); } TEST(CreateProducer, ZeroThreads) { asapo::Error err; std::unique_ptr<asapo::Producer> producer = asapo::Producer::Create("", 0, - asapo::RequestHandlerType::kTcp, SourceCredentials{asapo::SourceType::kRaw, "bt", "", "", ""}, 3600000, &err); - ASSERT_THAT(producer, Eq(nullptr)); - ASSERT_THAT(err, Eq(asapo::ProducerErrorTemplates::kWrongInput)); + asapo::RequestHandlerType::kTcp, SourceCredentials{asapo::SourceType::kRaw, "", "", "bt", "", "", ""}, 3600000, &err); + + EXPECT_THAT(err, Eq(asapo::ProducerErrorTemplates::kWrongInput)); + EXPECT_THAT(producer, Eq(nullptr)); } TEST(Producer, SimpleWorkflowWihoutConnection) { asapo::Error err; std::unique_ptr<asapo::Producer> producer = asapo::Producer::Create("hello", 5, asapo::RequestHandlerType::kTcp, - SourceCredentials{asapo::SourceType::kRaw, "bt", "", "", ""}, 3600000, + SourceCredentials{asapo::SourceType::kRaw, "", "", "bt", "", "", ""}, 3600000, &err); + EXPECT_THAT(err, Eq(nullptr)); + ASSERT_THAT(producer, Ne(nullptr)); + asapo::MessageHeader message_header{1, 1, "test"}; auto err_send = producer->Send(message_header, nullptr, asapo::kTransferMetaDataOnly, "stream", nullptr); std::this_thread::sleep_for(std::chrono::milliseconds(100)); - ASSERT_THAT(producer, Ne(nullptr)); - ASSERT_THAT(err, Eq(nullptr)); - ASSERT_THAT(err_send, Eq(nullptr)); + EXPECT_THAT(err_send, Eq(nullptr)); } diff --git a/producer/api/cpp/unittests/test_producer_impl.cpp b/producer/api/cpp/unittests/test_producer_impl.cpp index c307cbf1d64e3a707018ca308b7d88b1e4383e3c..f7edb0eaf0e59b594a8bb38f2c01288d357b5825 100644 --- a/producer/api/cpp/unittests/test_producer_impl.cpp +++ b/producer/api/cpp/unittests/test_producer_impl.cpp @@ -86,14 +86,11 @@ class ProducerImplTests : public testing::Test { char expected_stream[asapo::kMaxMessageSize] = "test_stream"; std::string expected_next_stream = "next_stream"; - asapo::SourceCredentials expected_credentials{asapo::SourceType::kRaw, "beamtime_id", "beamline", "subname", "token" - }; - asapo::SourceCredentials expected_default_credentials{ - asapo::SourceType::kProcessed, "beamtime_id", "", "", "token" - }; + asapo::SourceCredentials expected_credentials{asapo::SourceType::kRaw, "instance", "step", "beamtime_id", "beamline", "subname", "token"}; + asapo::SourceCredentials expected_default_credentials{asapo::SourceType::kProcessed, "instance", "step", "beamtime_id", "", "", "token"}; - std::string expected_credentials_str = "raw%beamtime_id%beamline%subname%token"; - std::string expected_default_credentials_str = "processed%beamtime_id%auto%detector%token"; + std::string expected_credentials_str = "raw%instance%step%beamtime_id%beamline%subname%token"; + std::string expected_default_credentials_str = "processed%instance%step%beamtime_id%auto%detector%token"; std::string expected_metadata = "meta"; std::string expected_fullpath = "filename"; @@ -220,17 +217,39 @@ TEST_F(ProducerImplTests, OKSendingSendRequestWithStream) { producer.SetCredentials(expected_credentials); EXPECT_CALL(mock_pull, AddRequest_t(M_CheckSendRequest(asapo::kOpcodeTransferData, - expected_credentials_str, - expected_metadata, - expected_id, - expected_size, - expected_name, - expected_stream, - expected_ingest_mode, - 0, - 0 - ), false)).WillOnce(Return( - nullptr)); + expected_credentials_str, + expected_metadata, + expected_id, + expected_size, + expected_name, + expected_stream, + expected_ingest_mode, + 0, + 0 + ), false)).WillOnce(Return( + nullptr)); + + asapo::MessageHeader message_header{expected_id, expected_size, expected_name, expected_metadata}; + auto err = producer.Send(message_header, nullptr, expected_ingest_mode, expected_stream, nullptr); + + ASSERT_THAT(err, Eq(nullptr)); +} + +TEST_F(ProducerImplTests, OKSendingSendRequestWithStream_PreSet) { + producer.SetCredentials(expected_credentials); + + EXPECT_CALL(mock_pull, AddRequest_t(M_CheckSendRequest(asapo::kOpcodeTransferData, + expected_credentials_str, + expected_metadata, + expected_id, + expected_size, + expected_name, + expected_stream, + expected_ingest_mode, + 0, + 0 + ), false)).WillOnce(Return( + nullptr)); asapo::MessageHeader message_header{expected_id, expected_size, expected_name, expected_metadata}; auto err = producer.Send(message_header, nullptr, expected_ingest_mode, expected_stream, nullptr); @@ -448,21 +467,11 @@ TEST_F(ProducerImplTests, OKSendingSendFileRequestWithStream) { ASSERT_THAT(err, Eq(nullptr)); } -TEST_F(ProducerImplTests, ErrorSettingBeamtime) { - std::string long_str(asapo::kMaxMessageSize * 10, 'a'); - expected_credentials = asapo::SourceCredentials{asapo::SourceType::kRaw, long_str, "", "", ""}; - EXPECT_CALL(mock_logger, Error(testing::HasSubstr("too long"))); - - auto err = producer.SetCredentials(expected_credentials); - - ASSERT_THAT(err, Eq(asapo::ProducerErrorTemplates::kWrongInput)); -} - TEST_F(ProducerImplTests, ErrorSettingSecondTime) { EXPECT_CALL(mock_logger, Error(testing::HasSubstr("already"))); - producer.SetCredentials(asapo::SourceCredentials{asapo::SourceType::kRaw, "1", "", "2", "3"}); - auto err = producer.SetCredentials(asapo::SourceCredentials{asapo::SourceType::kRaw, "4", "", "5", "6"}); + producer.SetCredentials(asapo::SourceCredentials{asapo::SourceType::kRaw, "instance", "step", "1", "", "2", "3"}); + auto err = producer.SetCredentials(asapo::SourceCredentials{asapo::SourceType::kRaw, "instance", "step", "4", "", "5", "6"}); ASSERT_THAT(err, Eq(asapo::ProducerErrorTemplates::kWrongInput)); } @@ -606,7 +615,7 @@ TEST_F(ProducerImplTests, GetVersionInfoWithServer) { R"({"softwareVersion":"21.06.0, build 7a9294ad","clientSupported":"no", "clientProtocol":{"versionInfo":"v0.4"}})"; EXPECT_CALL(*mock_http_client, Get_t(HasSubstr(expected_server_uri + - "/asapo-discovery/v0.1/version?client=producer&protocol=v0.5"), _, _)).WillOnce(DoAll( + "/asapo-discovery/v0.1/version?client=producer&protocol=v0.6"), _, _)).WillOnce(DoAll( SetArgPointee<1>(asapo::HttpCode::OK), SetArgPointee<2>(nullptr), Return(result))); diff --git a/producer/api/cpp/unittests/test_producer_request.cpp b/producer/api/cpp/unittests/test_producer_request.cpp index ae0e560cfa20250982c9cadd2de151a23ed33950..89bb3edcd21437b3b577b91b423de866e6064e15 100644 --- a/producer/api/cpp/unittests/test_producer_request.cpp +++ b/producer/api/cpp/unittests/test_producer_request.cpp @@ -40,7 +40,7 @@ TEST(ProducerRequest, Constructor) { uint64_t expected_file_size = 1337; uint64_t expected_meta_size = 137; std::string expected_meta = "meta"; - std::string expected_api_version = "v0.5"; + std::string expected_api_version = "v0.6"; asapo::Opcode expected_op_code = asapo::kOpcodeTransferData; asapo::GenericRequestHeader header{expected_op_code, expected_file_id, expected_file_size, diff --git a/producer/api/cpp/unittests/test_receiver_discovery_service.cpp b/producer/api/cpp/unittests/test_receiver_discovery_service.cpp index 9b8be27b06e82e02ec4f05a62d1dd81ee195dc6c..224d8eba97c3222cccb4cd48fc79978e1f8b2627 100644 --- a/producer/api/cpp/unittests/test_receiver_discovery_service.cpp +++ b/producer/api/cpp/unittests/test_receiver_discovery_service.cpp @@ -48,7 +48,7 @@ class ReceiversStatusTests : public Test { NiceMock<asapo::MockLogger> mock_logger; NiceMock<MockHttpClient>* mock_http_client; - std::string expected_endpoint{"endpoint/asapo-discovery/v0.1/asapo-receiver?protocol=v0.5"}; + std::string expected_endpoint{"endpoint/asapo-discovery/v0.1/asapo-receiver?protocol=v0.6"}; ReceiverDiscoveryService status{"endpoint", 20}; void SetUp() override { diff --git a/producer/api/cpp/unittests/test_request_handler_tcp.cpp b/producer/api/cpp/unittests/test_request_handler_tcp.cpp index 30eb79579dcf7e31f925ad2473a7397269374fb7..7051f3a8868e564861e242fd0d252370deb1c387 100644 --- a/producer/api/cpp/unittests/test_request_handler_tcp.cpp +++ b/producer/api/cpp/unittests/test_request_handler_tcp.cpp @@ -38,8 +38,8 @@ TEST(RequestHandlerTcp, Constructor) { MockDiscoveryService ds; asapo::RequestHandlerTcp request{&ds, 1, nullptr}; - ASSERT_THAT(dynamic_cast<const asapo::IO*>(request.io__.get()), Ne(nullptr)); - ASSERT_THAT(dynamic_cast<const asapo::AbstractLogger*>(request.log__), Ne(nullptr)); + ASSERT_THAT(dynamic_cast<const asapo::IO *>(request.io__.get()), Ne(nullptr)); + ASSERT_THAT(dynamic_cast<const asapo::AbstractLogger *>(request.log__), Ne(nullptr)); ASSERT_THAT(request.discovery_service__, Eq(&ds)); } @@ -47,145 +47,146 @@ std::string expected_auth_message = {"12345"}; asapo::Opcode expected_op_code = asapo::kOpcodeTransferData; class RequestHandlerTcpTests : public testing::Test { - public: - NiceMock<asapo::MockIO> mock_io; - NiceMock<MockDiscoveryService> mock_discovery_service; - - uint64_t expected_file_id = 42; - uint64_t expected_file_size = 1337; - uint64_t expected_meta_size = 4; - std::string expected_metadata = "meta"; - std::string expected_warning = "warning"; - std::string expected_response = "response"; - - char expected_file_name[asapo::kMaxMessageSize] = "test_name"; - char expected_beamtime_id[asapo::kMaxMessageSize] = "test_beamtime_id"; - char expected_stream[asapo::kMaxMessageSize] = "test_stream"; - - uint64_t expected_thread_id = 2; - - asapo::Error callback_err; - asapo::GenericRequestHeader header{expected_op_code, expected_file_id, expected_file_size, - expected_meta_size, expected_file_name, expected_stream}; - asapo::GenericRequestHeader header_fromfile{expected_op_code, expected_file_id, 0, expected_meta_size, - expected_file_name, expected_stream}; - bool callback_called = false; - asapo::GenericRequestHeader callback_header; - std::string callback_response; - uint8_t expected_callback_data = 2; - asapo::MessageData expected_data{[this]() { - auto a = new uint8_t[expected_file_size]; - for (uint64_t i = 0; i < expected_file_size; i++) { - a[i] = expected_callback_data; - } - return a; - } - ()}; - asapo::MessageData callback_data; - - asapo::ProducerRequest request{expected_beamtime_id, header, std::move(expected_data), expected_metadata, "", - [this](asapo::RequestCallbackPayload payload, asapo::Error err) { - callback_called = true; - callback_err = std::move(err); - callback_header = payload.original_header; - callback_response = payload.response; - callback_data = std::move(payload.data); - }, true, 0}; - - std::string expected_origin_fullpath = std::string("origin/") + expected_file_name; - asapo::ProducerRequest request_filesend{expected_beamtime_id, header_fromfile, nullptr, expected_metadata, - expected_origin_fullpath, - [this](asapo::RequestCallbackPayload payload, asapo::Error err) { - callback_called = true; - callback_err = std::move(err); - callback_header = payload.original_header; - callback_response = payload.response; - callback_data = std::move(payload.data); - }, true, 0}; - - asapo::ProducerRequest - request_nocallback{expected_beamtime_id, header, nullptr, expected_metadata, "", nullptr, true, 0}; - testing::NiceMock<asapo::MockLogger> mock_logger; - uint64_t n_connections{0}; - asapo::RequestHandlerTcp request_handler{&mock_discovery_service, expected_thread_id, &n_connections}; - - std::string expected_address1 = {"127.0.0.1:9090"}; - std::string expected_address2 = {"127.0.0.1:9091"}; - asapo::ReceiversList receivers_list{expected_address1, expected_address2}; - asapo::ReceiversList receivers_list2{expected_address2, expected_address1}; - - asapo::ReceiversList receivers_list_single{expected_address1}; - - std::vector<asapo::SocketDescriptor> expected_sds{83942, 83943}; - - bool retry; - Sequence seq_receive[2]; - void ExpectFailConnect(bool only_once = false); - void ExpectFailAuthorize(asapo::NetworkErrorCode error_code); - void ExpectOKAuthorize(bool only_once = false); - void ExpectFailSendHeader(bool only_once = false); - void ExpectFailSend(uint64_t expected_size, bool only_once); - void ExpectFailSend(bool only_once = false); - void ExpectFailSendMetaData(bool only_once = false); - void ExpectOKConnect(bool only_once = false); - void ExpectOKSendHeader(bool only_once = false, asapo::Opcode code = expected_op_code); - void ExpectOKSend(uint64_t expected_size, bool only_once); - void ExpectOKSendAll(bool only_once); - void ExpectGetFileSize(bool ok); - void ExpectOKSend(bool only_once = false); - void ExpectOKSendFile(bool only_once = false); - void ExpectFailSendFile(const asapo::ProducerErrorTemplate& err_template, bool client_error = false); - void ExpectOKSendMetaData(bool only_once = false); - void ExpectFailReceive(bool only_once = false); - void ExpectOKReceive(bool only_once = true, asapo::NetworkErrorCode code = asapo::kNetErrorNoError, - std::string message = ""); - void DoSingleSend(bool connect = true, bool success = true); - void AssertImmediatelyCallBack(asapo::NetworkErrorCode error_code, const asapo::ProducerErrorTemplate& err_template); - void SetUp() override { - request_handler.log__ = &mock_logger; - request_handler.io__.reset(&mock_io); - request.header.custom_data[asapo::kPosIngestMode] = asapo::kDefaultIngestMode; - request_filesend.header.custom_data[asapo::kPosIngestMode] = asapo::kDefaultIngestMode; - request_nocallback.header.custom_data[asapo::kPosIngestMode] = asapo::kDefaultIngestMode; - ON_CALL(mock_discovery_service, RotatedUriList(_)). - WillByDefault(Return(receivers_list)); - - } - void TearDown() override { - request_handler.io__.release(); + public: + NiceMock<asapo::MockIO> mock_io; + NiceMock<MockDiscoveryService> mock_discovery_service; + + uint64_t expected_file_id = 42; + uint64_t expected_file_size = 1337; + uint64_t expected_meta_size = 4; + std::string expected_metadata = "meta"; + std::string expected_warning = "warning"; + std::string expected_response = "response"; + + char expected_file_name[asapo::kMaxMessageSize] = "test_name"; + char expected_beamtime_id[asapo::kMaxMessageSize] = "test_beamtime_id"; + char expected_stream[asapo::kMaxMessageSize] = "test_stream"; + + uint64_t expected_thread_id = 2; + + asapo::Error callback_err; + asapo::GenericRequestHeader header{expected_op_code, expected_file_id, expected_file_size, + expected_meta_size, expected_file_name, expected_stream}; + asapo::GenericRequestHeader header_fromfile{expected_op_code, expected_file_id, 0, expected_meta_size, + expected_file_name, expected_stream}; + bool callback_called = false; + asapo::GenericRequestHeader callback_header; + std::string callback_response; + uint8_t expected_callback_data = 2; + asapo::MessageData expected_data1{[this]() { + auto a = new uint8_t[expected_file_size]; + for (uint64_t i = 0; i < expected_file_size; i++) { + a[i] = expected_callback_data; } + return a; + } + ()}; + asapo::MessageData callback_data; + + asapo::ProducerRequest request{expected_beamtime_id, header, std::move(expected_data1), expected_metadata, "", + [this](asapo::RequestCallbackPayload payload, asapo::Error err) { + callback_called = true; + callback_err = std::move(err); + callback_header = payload.original_header; + callback_response = payload.response; + callback_data = std::move(payload.data); + }, true, 0}; + + std::string expected_origin_fullpath = std::string("origin/") + expected_file_name; + asapo::ProducerRequest request_filesend{expected_beamtime_id, header_fromfile, nullptr, expected_metadata, + expected_origin_fullpath, + [this](asapo::RequestCallbackPayload payload, asapo::Error err) { + callback_called = true; + callback_err = std::move(err); + callback_header = payload.original_header; + callback_response = payload.response; + callback_data = std::move(payload.data); + }, true, 0}; + + asapo::ProducerRequest + request_nocallback{expected_beamtime_id, header, nullptr, expected_metadata, "", nullptr, true, 0}; + testing::NiceMock<asapo::MockLogger> mock_logger; + uint64_t n_connections{0}; + asapo::RequestHandlerTcp request_handler{&mock_discovery_service, expected_thread_id, &n_connections}; + + std::string expected_address1 = {"127.0.0.1:9090"}; + std::string expected_address2 = {"127.0.0.1:9091"}; + asapo::ReceiversList receivers_list{expected_address1, expected_address2}; + asapo::ReceiversList receivers_list2{expected_address2, expected_address1}; + + asapo::ReceiversList receivers_list_single{expected_address1}; + + std::vector<asapo::SocketDescriptor> expected_sds{83942, 83943}; + + bool retry; + Sequence seq_receive[2]; + void ExpectFailConnect(bool only_once = false); + void ExpectFailAuthorize(asapo::NetworkErrorCode error_code); + void ExpectOKAuthorize(bool only_once = false); + void ExpectFailSendHeader(bool only_once = false); + void ExpectFailSend(uint64_t expected_size, bool only_once); + void ExpectFailSend(bool only_once = false); + void ExpectFailSendMetaData(bool only_once = false); + void ExpectOKConnect(bool only_once = false); + void ExpectOKSendHeader(bool only_once = false, asapo::Opcode code = expected_op_code); + void ExpectOKSend(uint64_t expected_size, bool only_once); + void ExpectOKSendAll(bool only_once); + void ExpectGetFileSize(bool ok); + void ExpectOKSend(bool only_once = false); + void ExpectOKSendFile(bool only_once = false); + void ExpectFailSendFile(const asapo::ProducerErrorTemplate &err_template, bool client_error = false); + void ExpectOKSendMetaData(bool only_once = false); + void ExpectFailReceive(bool only_once = false); + void ExpectOKReceive(bool only_once = true, asapo::NetworkErrorCode code = asapo::kNetErrorNoError, + std::string message = ""); + void DoSingleSend(bool connect = true, bool success = true); + void AssertImmediatelyCallBack(asapo::NetworkErrorCode error_code, const asapo::ProducerErrorTemplate &err_template); + void SetUp() override { + request_handler.log__ = &mock_logger; + request_handler.io__.reset(&mock_io); + request.header.custom_data[asapo::kPosIngestMode] = asapo::kDefaultIngestMode; + request_filesend.header.custom_data[asapo::kPosIngestMode] = asapo::kDefaultIngestMode; + request_nocallback.header.custom_data[asapo::kPosIngestMode] = asapo::kDefaultIngestMode; + ON_CALL(mock_discovery_service, RotatedUriList(_)). + WillByDefault(Return(receivers_list)); + + } + void TearDown() override { + request_handler.io__.release(); + } }; ACTION_P2(A_WriteSendResponse, error_code, message) { - ((asapo::SendResponse*) arg1)->op_code = asapo::kOpcodeTransferData; - ((asapo::SendResponse*) arg1)->error_code = error_code; - strcpy(((asapo::SendResponse*) arg1)->message, message.c_str()); + ((asapo::SendResponse *) arg1)->op_code = asapo::kOpcodeTransferData; + ((asapo::SendResponse *) arg1)->error_code = error_code; + strcpy(((asapo::SendResponse *) arg1)->message, message.c_str()); } MATCHER_P5(M_CheckSendRequest, op_code, file_id, file_size, message, stream, "Checks if a valid GenericRequestHeader was Send") { - return ((asapo::GenericRequestHeader*) arg)->op_code == op_code - && ((asapo::GenericRequestHeader*) arg)->data_id == uint64_t(file_id) - && ((asapo::GenericRequestHeader*) arg)->data_size == uint64_t(file_size) - && strcmp(((asapo::GenericRequestHeader*) arg)->message, message) == 0 - && strcmp(((asapo::GenericRequestHeader*) arg)->stream, stream) == 0; - +// actually, arg may be not GenericRequestHeader, so it should exit on check of op_code. Not very good solution, maybe pass size of GenericRequestHeader and compare it + return ((asapo::GenericRequestHeader *) arg)->op_code == op_code && + ((asapo::GenericRequestHeader *) arg)->data_id == uint64_t(file_id) && + ((asapo::GenericRequestHeader *) arg)->data_size == uint64_t(file_size) && + strcmp(((asapo::GenericRequestHeader *) arg)->message, message) == 0 && + strcmp(((asapo::GenericRequestHeader *) arg)->api_version, "v0.6") == 0 && + strcmp(((asapo::GenericRequestHeader *) arg)->stream, stream) == 0; } void RequestHandlerTcpTests::ExpectFailConnect(bool only_once) { - for (auto expected_address : receivers_list) { + for (auto expected_address: receivers_list) { EXPECT_CALL(mock_io, CreateAndConnectIPTCPSocket_t(expected_address, _)) - .WillOnce( - DoAll( - testing::SetArgPointee<1>(asapo::IOErrorTemplates::kInvalidAddressFormat.Generate().release()), - Return(asapo::kDisconnectedSocketDescriptor) - )); + .WillOnce( + DoAll( + testing::SetArgPointee<1>(asapo::IOErrorTemplates::kInvalidAddressFormat.Generate().release()), + Return(asapo::kDisconnectedSocketDescriptor) + )); if (only_once) EXPECT_CALL(mock_logger, Debug(AllOf( HasSubstr("cannot connect"), HasSubstr(expected_address) ) - )); + )); if (only_once) break; } @@ -195,113 +196,121 @@ void RequestHandlerTcpTests::ExpectFailConnect(bool only_once) { void RequestHandlerTcpTests::ExpectFailAuthorize(asapo::NetworkErrorCode error_code) { auto expected_sd = expected_sds[0]; EXPECT_CALL(mock_io, - Send_t(expected_sd, M_CheckSendRequest(asapo::kOpcodeAuthorize, 0, 0, "", - ""), - sizeof(asapo::GenericRequestHeader), _)) - .WillOnce( - DoAll( - testing::SetArgPointee<3>(nullptr), - Return(sizeof(asapo::GenericRequestHeader)) - )); + Send_t(expected_sd, + M_CheckSendRequest(asapo::kOpcodeAuthorize, + 0, + 0, + "", + ""), + sizeof(asapo::GenericRequestHeader), + _)) + .WillOnce( + DoAll( + testing::SetArgPointee<3>(nullptr), + Return(sizeof(asapo::GenericRequestHeader)) + )); EXPECT_CALL(mock_io, Send_t(expected_sd, _, strlen(expected_beamtime_id), _)) - .WillOnce( - DoAll( - testing::SetArgPointee<3>(nullptr), - Return(strlen(expected_beamtime_id)) - )); + .WillOnce( + DoAll( + testing::SetArgPointee<3>(nullptr), + Return(strlen(expected_beamtime_id)) + )); EXPECT_CALL(mock_io, Receive_t(expected_sd, _, sizeof(asapo::SendResponse), _)) - .InSequence(seq_receive[0]) - .WillOnce( - DoAll( - testing::SetArgPointee<3>(nullptr), - A_WriteSendResponse(error_code, expected_auth_message), - testing::ReturnArg<2>() - )); + .InSequence(seq_receive[0]) + .WillOnce( + DoAll( + testing::SetArgPointee<3>(nullptr), + A_WriteSendResponse(error_code, expected_auth_message), + testing::ReturnArg<2>() + )); EXPECT_CALL(mock_io, CloseSocket_t(expected_sd, _)); EXPECT_CALL(mock_logger, Debug(AllOf( HasSubstr("disconnected"), HasSubstr(receivers_list[0]) ) - )); + )); EXPECT_CALL(mock_logger, Error(AllOf( HasSubstr("authorization"), HasSubstr(expected_auth_message), HasSubstr(receivers_list[0]) ) - )); + )); } - void RequestHandlerTcpTests::ExpectOKAuthorize(bool only_once) { size_t i = 0; - for (auto expected_sd : expected_sds) { + for (auto expected_sd: expected_sds) { EXPECT_CALL(mock_io, - Send_t(expected_sd, M_CheckSendRequest(asapo::kOpcodeAuthorize, 0, 0, "", - ""), - sizeof(asapo::GenericRequestHeader), _)) - .WillOnce( - DoAll( - testing::SetArgPointee<3>(nullptr), - Return(sizeof(asapo::GenericRequestHeader)) - )); + Send_t(expected_sd, + M_CheckSendRequest(asapo::kOpcodeAuthorize, + 0, + 0, + "", + ""), + sizeof(asapo::GenericRequestHeader), + _)) + .WillOnce( + DoAll( + testing::SetArgPointee<3>(nullptr), + Return(sizeof(asapo::GenericRequestHeader)) + )); EXPECT_CALL(mock_io, Send_t(expected_sd, _, strlen(expected_beamtime_id), _)) - .WillOnce( - DoAll( - testing::SetArgPointee<3>(nullptr), - Return(strlen(expected_beamtime_id)) - )); + .WillOnce( + DoAll( + testing::SetArgPointee<3>(nullptr), + Return(strlen(expected_beamtime_id)) + )); EXPECT_CALL(mock_io, Receive_t(expected_sd, _, sizeof(asapo::SendResponse), _)) - .InSequence(seq_receive[i]) - .WillOnce( - DoAll( - testing::SetArgPointee<3>(nullptr), - A_WriteSendResponse(asapo::kNetErrorNoError, expected_auth_message), - testing::ReturnArg<2>() - )); + .InSequence(seq_receive[i]) + .WillOnce( + DoAll( + testing::SetArgPointee<3>(nullptr), + A_WriteSendResponse(asapo::kNetErrorNoError, expected_auth_message), + testing::ReturnArg<2>() + )); if (only_once) { EXPECT_CALL(mock_logger, Info(AllOf( HasSubstr("authorized"), HasSubstr(receivers_list[i]) ) - )); + )); } if (only_once) break; i++; } - } void RequestHandlerTcpTests::ExpectFailSendHeader(bool only_once) { size_t i = 0; - for (auto expected_sd : expected_sds) { + for (auto expected_sd: expected_sds) { EXPECT_CALL(mock_io, Send_t(expected_sd, M_CheckSendRequest(expected_op_code, - expected_file_id, - expected_file_size, - expected_file_name, - expected_stream), + expected_file_id, + expected_file_size, + expected_file_name, + expected_stream), sizeof(asapo::GenericRequestHeader), _)) - .WillOnce( - DoAll( - testing::SetArgPointee<3>(asapo::IOErrorTemplates::kBadFileNumber.Generate().release()), - Return(-1) - )); + .WillOnce( + DoAll( + testing::SetArgPointee<3>(asapo::IOErrorTemplates::kBadFileNumber.Generate().release()), + Return(-1) + )); if (only_once) { EXPECT_CALL(mock_logger, Debug(AllOf( HasSubstr("disconnected"), HasSubstr(receivers_list[i]) ) - )); + )); EXPECT_CALL(mock_logger, Warning(AllOf( HasSubstr("cannot send"), HasSubstr(receivers_list[i]) ) - )); + )); } EXPECT_CALL(mock_io, CloseSocket_t(expected_sd, _)); if (only_once) break; @@ -312,14 +321,14 @@ void RequestHandlerTcpTests::ExpectFailSendHeader(bool only_once) { } } -void RequestHandlerTcpTests::ExpectFailSendFile(const asapo::ProducerErrorTemplate& err_template, bool client_error) { +void RequestHandlerTcpTests::ExpectFailSendFile(const asapo::ProducerErrorTemplate &err_template, bool client_error) { size_t i = 0; - for (auto expected_sd : expected_sds) { + for (auto expected_sd: expected_sds) { EXPECT_CALL(mock_io, SendFile_t(expected_sd, expected_origin_fullpath, (size_t) expected_file_size)) - .Times(1) - .WillOnce( - Return(err_template.Generate().release()) - ); + .Times(1) + .WillOnce( + Return(err_template.Generate().release()) + ); if (client_error) { @@ -327,11 +336,11 @@ void RequestHandlerTcpTests::ExpectFailSendFile(const asapo::ProducerErrorTempla HasSubstr("disconnected"), HasSubstr(receivers_list[i]) ) - )); + )); EXPECT_CALL(mock_logger, Error(AllOf( - HasSubstr("cannot send"), - HasSubstr(receivers_list[i])) - )); + HasSubstr("cannot send"), + HasSubstr(receivers_list[i])) + )); } @@ -347,26 +356,26 @@ void RequestHandlerTcpTests::ExpectFailSendFile(const asapo::ProducerErrorTempla void RequestHandlerTcpTests::ExpectFailSend(uint64_t expected_size, bool only_once) { size_t i = 0; - for (auto expected_sd : expected_sds) { + for (auto expected_sd: expected_sds) { EXPECT_CALL(mock_io, Send_t(expected_sd, _, (size_t) expected_size, _)) - .Times(1) - .WillOnce( - DoAll( - testing::SetArgPointee<3>(asapo::IOErrorTemplates::kBadFileNumber.Generate().release()), - Return(-1) - )); + .Times(1) + .WillOnce( + DoAll( + testing::SetArgPointee<3>(asapo::IOErrorTemplates::kBadFileNumber.Generate().release()), + Return(-1) + )); if (only_once) { EXPECT_CALL(mock_logger, Debug(AllOf( HasSubstr("disconnected"), HasSubstr(receivers_list[i]) ) - )); + )); EXPECT_CALL(mock_logger, Warning(AllOf( HasSubstr("cannot send"), HasSubstr(receivers_list[i]) ) - )); + )); } EXPECT_CALL(mock_io, CloseSocket_t(expected_sd, _)); @@ -386,25 +395,25 @@ void RequestHandlerTcpTests::ExpectFailSendMetaData(bool only_once) { void RequestHandlerTcpTests::ExpectFailReceive(bool only_once) { size_t i = 0; - for (auto expected_sd : expected_sds) { + for (auto expected_sd: expected_sds) { EXPECT_CALL(mock_io, Receive_t(expected_sd, _, sizeof(asapo::SendResponse), _)) - .InSequence(seq_receive[i]) - .WillOnce( - DoAll( - testing::SetArgPointee<3>(asapo::IOErrorTemplates::kBadFileNumber.Generate().release()), - testing::Return(-1) - )); + .InSequence(seq_receive[i]) + .WillOnce( + DoAll( + testing::SetArgPointee<3>(asapo::IOErrorTemplates::kBadFileNumber.Generate().release()), + testing::Return(-1) + )); EXPECT_CALL(mock_logger, Debug(AllOf( HasSubstr("disconnected"), HasSubstr(receivers_list[i]) ) - )); + )); EXPECT_CALL(mock_logger, Warning(AllOf( HasSubstr("cannot send"), HasSubstr(receivers_list[i]) ) - )); + )); EXPECT_CALL(mock_io, CloseSocket_t(expected_sd, _)); if (only_once) break; i++; @@ -420,14 +429,14 @@ void RequestHandlerTcpTests::ExpectOKSendAll(bool only_once) { } void RequestHandlerTcpTests::ExpectOKSend(uint64_t expected_size, bool only_once) { - for (auto expected_sd : expected_sds) { + for (auto expected_sd: expected_sds) { EXPECT_CALL(mock_io, Send_t(expected_sd, _, (size_t) expected_size, _)) - .Times(1) - .WillOnce( - DoAll( - testing::SetArgPointee<3>(nullptr), - Return((size_t) expected_file_size) - )); + .Times(1) + .WillOnce( + DoAll( + testing::SetArgPointee<3>(nullptr), + Return((size_t) expected_file_size) + )); if (only_once) break; } } @@ -441,27 +450,27 @@ void RequestHandlerTcpTests::ExpectOKSend(bool only_once) { } void RequestHandlerTcpTests::ExpectOKSendFile(bool only_once) { - for (auto expected_sd : expected_sds) { + for (auto expected_sd: expected_sds) { EXPECT_CALL(mock_io, SendFile_t(expected_sd, expected_origin_fullpath, (size_t) expected_file_size)) - .Times(1) - .WillOnce(Return(nullptr)); + .Times(1) + .WillOnce(Return(nullptr)); if (only_once) break; } } void RequestHandlerTcpTests::ExpectOKSendHeader(bool only_once, asapo::Opcode opcode) { - for (auto expected_sd : expected_sds) { + for (auto expected_sd: expected_sds) { EXPECT_CALL(mock_io, Send_t(expected_sd, M_CheckSendRequest(opcode, - expected_file_id, - expected_file_size, - expected_file_name, - expected_stream), + expected_file_id, + expected_file_size, + expected_file_name, + expected_stream), sizeof(asapo::GenericRequestHeader), _)) - .WillOnce( - DoAll( - testing::SetArgPointee<3>(nullptr), - Return(sizeof(asapo::GenericRequestHeader)) - )); + .WillOnce( + DoAll( + testing::SetArgPointee<3>(nullptr), + Return(sizeof(asapo::GenericRequestHeader)) + )); if (only_once) break; } @@ -469,19 +478,19 @@ void RequestHandlerTcpTests::ExpectOKSendHeader(bool only_once, asapo::Opcode op void RequestHandlerTcpTests::ExpectOKConnect(bool only_once) { size_t i = 0; - for (auto expected_address : receivers_list) { + for (auto expected_address: receivers_list) { EXPECT_CALL(mock_io, CreateAndConnectIPTCPSocket_t(expected_address, _)) - .WillOnce( - DoAll( - testing::SetArgPointee<1>(nullptr), - Return(expected_sds[i]) - )); + .WillOnce( + DoAll( + testing::SetArgPointee<1>(nullptr), + Return(expected_sds[i]) + )); if (only_once) { EXPECT_CALL(mock_logger, Debug(AllOf( HasSubstr("connected to"), HasSubstr(expected_address) ) - )); + )); } if (only_once) break; i++; @@ -490,21 +499,21 @@ void RequestHandlerTcpTests::ExpectOKConnect(bool only_once) { void RequestHandlerTcpTests::ExpectOKReceive(bool only_once, asapo::NetworkErrorCode code, std::string message) { size_t i = 0; - for (auto expected_sd : expected_sds) { + for (auto expected_sd: expected_sds) { EXPECT_CALL(mock_io, Receive_t(expected_sd, _, sizeof(asapo::SendResponse), _)) - .InSequence(seq_receive[i]) - .WillOnce( - DoAll( - testing::SetArgPointee<3>(nullptr), - A_WriteSendResponse(code, message), - testing::ReturnArg<2>() - )); + .InSequence(seq_receive[i]) + .WillOnce( + DoAll( + testing::SetArgPointee<3>(nullptr), + A_WriteSendResponse(code, message), + testing::ReturnArg<2>() + )); if (only_once) { EXPECT_CALL(mock_logger, Debug(AllOf( HasSubstr("sent data"), HasSubstr(receivers_list[i]) ) - )); + )); } if (only_once) break; i++; @@ -526,7 +535,7 @@ void RequestHandlerTcpTests::DoSingleSend(bool connect, bool success) { if (connect) { EXPECT_CALL(mock_discovery_service, RotatedUriList(_)). - WillOnce(Return(receivers_list_single)); + WillOnce(Return(receivers_list_single)); } request_handler.PrepareProcessingRequestLocked(); @@ -624,10 +633,10 @@ TEST_F(RequestHandlerTcpTests, DoesNotTryConnectWhenConnected) { DoSingleSend(); EXPECT_CALL(mock_discovery_service, RotatedUriList(_)). - WillOnce(Return(receivers_list_single)); + WillOnce(Return(receivers_list_single)); EXPECT_CALL(mock_io, CreateAndConnectIPTCPSocket_t(_, _)) - .Times(0); + .Times(0); ExpectFailSendHeader(true); @@ -657,7 +666,7 @@ TEST_F(RequestHandlerTcpTests, CloseConnectionWhenRebalance) { std::this_thread::sleep_for(std::chrono::milliseconds(10)); EXPECT_CALL(mock_discovery_service, RotatedUriList(_)). - WillOnce(Return(asapo::ReceiversList{})); + WillOnce(Return(asapo::ReceiversList{})); EXPECT_CALL(mock_io, CloseSocket_t(_, _)); @@ -712,7 +721,7 @@ TEST_F(RequestHandlerTcpTests, ErrorWhenCannotSendMetaData) { TEST_F(RequestHandlerTcpTests, ErrorWhenCannotReceiveData) { EXPECT_CALL(mock_discovery_service, RotatedUriList(_)). - WillOnce(Return(receivers_list_single)); + WillOnce(Return(receivers_list_single)); ExpectOKConnect(true); ExpectOKAuthorize(true); @@ -728,30 +737,30 @@ TEST_F(RequestHandlerTcpTests, ErrorWhenCannotReceiveData) { } void RequestHandlerTcpTests::AssertImmediatelyCallBack(asapo::NetworkErrorCode error_code, - const asapo::ProducerErrorTemplate& err_template) { + const asapo::ProducerErrorTemplate &err_template) { ExpectOKConnect(true); ExpectOKAuthorize(true); ExpectOKSendAll(true); EXPECT_CALL(mock_io, Receive_t(expected_sds[0], _, sizeof(asapo::SendResponse), _)) - .InSequence(seq_receive[0]) - .WillOnce( - DoAll( - testing::SetArgPointee<3>(nullptr), - A_WriteSendResponse(error_code, expected_auth_message), - testing::ReturnArg<2>() - )); + .InSequence(seq_receive[0]) + .WillOnce( + DoAll( + testing::SetArgPointee<3>(nullptr), + A_WriteSendResponse(error_code, expected_auth_message), + testing::ReturnArg<2>() + )); EXPECT_CALL(mock_logger, Debug(AllOf( HasSubstr("disconnected"), HasSubstr(receivers_list[0]) ) - )); + )); EXPECT_CALL(mock_logger, Error(AllOf( HasSubstr("cannot send"), HasSubstr(receivers_list[0]) ) - )); + )); request_handler.PrepareProcessingRequestLocked(); auto success = request_handler.ProcessRequestUnlocked(&request, &retry); @@ -779,12 +788,10 @@ TEST_F(RequestHandlerTcpTests, ImmediatelyCallBackErrorIfAuthorizationFailure) { AssertImmediatelyCallBack(asapo::kNetAuthorizationError, asapo::ProducerErrorTemplates::kWrongInput); } - TEST_F(RequestHandlerTcpTests, ImmediatelyCallBackErrorIfNotSupportedfailure) { AssertImmediatelyCallBack(asapo::kNetErrorNotSupported, asapo::ProducerErrorTemplates::kUnsupportedClient); } - TEST_F(RequestHandlerTcpTests, ImmediatelyCallBackErrorIfWrongMetadata) { AssertImmediatelyCallBack(asapo::kNetErrorWrongRequest, asapo::ProducerErrorTemplates::kWrongInput); } @@ -971,9 +978,9 @@ TEST_F(RequestHandlerTcpTests, SendMetaOnlyForFileReadOK) { TEST_F(RequestHandlerTcpTests, TimeoutCallsCallback) { EXPECT_CALL(mock_logger, Error(AllOf( - HasSubstr("timeout"), - HasSubstr("stream")) - )); + HasSubstr("timeout"), + HasSubstr("stream")) + )); request_handler.ProcessRequestTimeoutUnlocked(&request); @@ -990,9 +997,9 @@ TEST_F(RequestHandlerTcpTests, SendWithWarning) { ExpectOKReceive(true, asapo::kNetErrorWarning, expected_warning); EXPECT_CALL(mock_logger, Warning(AllOf( - HasSubstr("server"), - HasSubstr(expected_warning)) - )); + HasSubstr("server"), + HasSubstr(expected_warning)) + )); request_handler.PrepareProcessingRequestLocked(); auto success = request_handler.ProcessRequestUnlocked(&request, &retry); diff --git a/producer/api/python/asapo_producer.pxd b/producer/api/python/asapo_producer.pxd index 0ac9cf4ccc1d2e5b6d8952e8ed56f84ccd5c3909..359758a8ad1265dcfd6f7d45daffabc2b8645ad6 100644 --- a/producer/api/python/asapo_producer.pxd +++ b/producer/api/python/asapo_producer.pxd @@ -61,6 +61,8 @@ cdef extern from "asapo/asapo_producer.h" namespace "asapo": pass cdef Error GetSourceTypeFromString(string types,SourceType * type) struct SourceCredentials: + string instance_id + string pipeline_step string beamtime_id string beamline string data_source @@ -112,8 +114,9 @@ cdef extern from "asapo/asapo_producer.h" namespace "asapo" nogil: Error Send__(const MessageHeader& message_header, void* data, uint64_t ingest_mode, string stream, RequestCallback callback) void StopThreads__() void SetLogLevel(LogLevel level) - uint64_t GetRequestsQueueSize() - uint64_t GetRequestsQueueVolumeMb() + uint64_t GetRequestsQueueSize() + uint64_t GetRequestsQueueVolumeMb() + Error DisableMonitoring(bool enabled) void SetRequestsQueueLimits(uint64_t size, uint64_t volume) Error WaitRequestsFinished(uint64_t timeout_ms) Error SendStreamFinishedFlag(string stream, uint64_t last_id, string next_stream, RequestCallback callback) diff --git a/producer/api/python/asapo_producer.pyx.in b/producer/api/python/asapo_producer.pyx.in index 059a4c812fb26f684284f916dcab7e7c6df83be0..f41e7024a0625e768a1c0215933a90ae3f5e1d34 100644 --- a/producer/api/python/asapo_producer.pyx.in +++ b/producer/api/python/asapo_producer.pyx.in @@ -464,7 +464,7 @@ cdef class PyProducer: if self.c_producer.get() is not NULL: self.c_producer.get().StopThreads__() @staticmethod - def __create_producer(endpoint,type,beamtime_id,beamline,data_source,token,nthreads,timeout_ms): + def __create_producer(endpoint,type,instance_id,pipeline_step,beamtime_id,beamline,data_source,token,nthreads,timeout_ms): pyProd = PyProducer() cdef Error err cdef SourceType source_type @@ -472,6 +472,8 @@ cdef class PyProducer: if err: throw_exception(err) cdef SourceCredentials source + source.instance_id = instance_id + source.pipeline_step = pipeline_step source.beamtime_id = beamtime_id source.beamline = beamline source.user_token = token @@ -482,14 +484,12 @@ cdef class PyProducer: throw_exception(err) return pyProd -def create_producer(endpoint,type,beamtime_id,beamline,data_source,token,nthreads,timeout_ms): +def create_producer(endpoint,type,beamtime_id,beamline,data_source,token,nthreads,timeout_ms,instance_id='auto',pipeline_step='auto'): """ :param endpoint: server endpoint (url:port) :type endpoint: string :param type: source type, "raw" to write to "raw" folder in beamline filesystem,"processed" to write to "processed" folder in core filesystem :type type: string - :param beamtime_id: beamtime id, can be "auto" if beamline is given, will automatically select the current beamtime id - :type beamtime_id: string :param beamline: beamline name, can be "auto" if beamtime_id is given :type beamline: string :param data_source: name of the data source that produces data @@ -500,11 +500,15 @@ def create_producer(endpoint,type,beamtime_id,beamline,data_source,token,nthread :type nthreads: int :param timeout_ms: send requests timeout in milliseconds :type timeout_ms: int + :param instance_id: instance id, can be "auto" (default), will create a combination out of hostname and pid + :type instance_id: string + :param pipeline_step: pipeline step id, can be "auto" (default), "DefaultStep" is used then + :type pipeline_step: string :raises: AsapoWrongInputError: wrong input (number of threads, ,,,) AsapoProducerError: actually should not happen """ - return PyProducer.__create_producer(_bytes(endpoint),_bytes(type),_bytes(beamtime_id),_bytes(beamline),_bytes(data_source),_bytes(token),nthreads,timeout_ms) + return PyProducer.__create_producer(_bytes(endpoint),_bytes(type),_bytes(instance_id),_bytes(pipeline_step),_bytes(beamtime_id),_bytes(beamline),_bytes(data_source),_bytes(token),nthreads,timeout_ms) __version__ = "@PYTHON_ASAPO_VERSION@@ASAPO_VERSION_COMMIT@" diff --git a/producer/event_monitor_producer/src/eventmon_config.h b/producer/event_monitor_producer/src/eventmon_config.h index 3f404ed36b7bf5abf58969f15acfe1ebbe033958..0c0aad62b521e110d45abf49e7440d2d91ad2694 100644 --- a/producer/event_monitor_producer/src/eventmon_config.h +++ b/producer/event_monitor_producer/src/eventmon_config.h @@ -20,6 +20,8 @@ struct EventMonConfig { LogLevel log_level = LogLevel::Info; std::string tag; uint64_t nthreads = 1; + std::string instance_id; + std::string pipeline_step = "filemon"; std::string beamtime_id; RequestHandlerType mode = RequestHandlerType::kTcp; std::string root_monitored_folder; diff --git a/producer/event_monitor_producer/src/main_eventmon.cpp b/producer/event_monitor_producer/src/main_eventmon.cpp index 26064f3094294539b7bf5e7907ef7b816d479a65..04f13d3e5c74c8e5d1383d94bd64d717ff628ec1 100644 --- a/producer/event_monitor_producer/src/main_eventmon.cpp +++ b/producer/event_monitor_producer/src/main_eventmon.cpp @@ -39,7 +39,7 @@ std::unique_ptr<Producer> CreateProducer() { Error err; auto producer = Producer::Create(config->asapo_endpoint, (uint8_t) config->nthreads, - config->mode, asapo::SourceCredentials{asapo::SourceType::kProcessed, config->beamtime_id, "", config->data_source, ""}, + config->mode, asapo::SourceCredentials{asapo::SourceType::kProcessed, config->instance_id, config->pipeline_step, config->beamtime_id, "", config->data_source, ""}, 3600000, &err); if(err) { std::cerr << "cannot create producer: " << err << std::endl; diff --git a/receiver/CMakeLists.txt b/receiver/CMakeLists.txt index 92e0b87ca8180b53ac70f1c44e8b5caa0646803f..f64ef8866b5c05a30ffcda2440d33764734a85a0 100644 --- a/receiver/CMakeLists.txt +++ b/receiver/CMakeLists.txt @@ -7,10 +7,13 @@ set(RECEIVER_CORE_FILES src/request.cpp src/receiver_config.cpp src/receiver_logger.cpp + src/statistics/receiver_statistics.cpp src/statistics/statistics.cpp src/statistics/statistics_sender_influx_db.cpp src/statistics/statistics_sender_fluentd.cpp + src/statistics/instanced_statistics_provider.cpp + src/request_handler/requests_dispatcher.cpp src/request_handler/request_handler_file_process.cpp src/request_handler/request_handler_db_write.cpp @@ -29,6 +32,7 @@ set(RECEIVER_CORE_FILES src/request_handler/request_handler_kafka_notify.cpp src/request_handler/request_factory.cpp src/request_handler/request_handler_db.cpp + src/request_handler/request_handler_monitoring.cpp src/request_handler/file_processors/write_file_processor.cpp src/request_handler/file_processors/file_processor.cpp src/request_handler/file_processors/receive_file_processor.cpp @@ -47,13 +51,76 @@ set(RDS_FILES src/receiver_data_server/request_handler/receiver_data_server_request_handler.cpp ) +################################ +# Protobuf +################################ + +set(MONITORING_FILES + src/monitoring/receiver_monitoring_client.cpp + src/monitoring/receiver_monitoring_client_noop.cpp + ) + +if (ENABLE_NEW_RECEIVER_MONITORING) + add_definitions(-DNEW_RECEIVER_MONITORING_ENABLED) + include(../CMakeIncludes/grpc_common.cmake) + + get_filename_component(proto_in_dir "../common/networking/monitoring" ABSOLUTE) + set(proto_file_common ${proto_in_dir}/AsapoMonitoringCommonService.proto) + set(proto_file_ingest ${proto_in_dir}/AsapoMonitoringIngestService.proto) + + set(proto_out_dir ${CMAKE_CURRENT_BINARY_DIR}) + set(proto_ingest_c "${proto_out_dir}/AsapoMonitoringIngestService.pb.cc") + set(proto_ingest_h "${proto_out_dir}/AsapoMonitoringIngestService.pb.h") + set(proto_common_c "${proto_out_dir}/AsapoMonitoringCommonService.pb.cc") + set(proto_common_h "${proto_out_dir}/AsapoMonitoringCommonService.pb.h") + set(grpc_c "${proto_out_dir}/AsapoMonitoringIngestService.grpc.pb.cc") + set(grpc_h "${proto_out_dir}/AsapoMonitoringIngestService.grpc.pb.h") + + add_custom_command( + OUTPUT "${proto_ingest_c}" "${proto_ingest_h}" "${proto_common_c}" "${proto_common_h}" "${grpc_c}" "${grpc_h}" + COMMAND ${_PROTOBUF_PROTOC} + ARGS --grpc_out "${proto_out_dir}" + --cpp_out "${proto_out_dir}" + -I "${proto_in_dir}" + --plugin=protoc-gen-grpc="${_GRPC_CPP_PLUGIN_EXECUTABLE}" + "${proto_file_common}" "${proto_file_ingest}" + DEPENDS "${proto_file_common}" "${proto_file_ingest}") + + add_library(grpc_ingest_service_proto + ${proto_ingest_c} + ${proto_ingest_h} + ${proto_common_c} + ${proto_common_h} + ${grpc_c} + ${grpc_h}) + IF(NOT WIN32) + target_compile_options(grpc_ingest_service_proto PUBLIC "-Wno-error") + ENDIF() + target_link_libraries(grpc_ingest_service_proto + ${_REFLECTION} + ${_GRPC_GRPCPP} + ${_PROTOBUF_LIBPROTOBUF}) + find_package(gRPC CONFIG REQUIRED) + + # Include generated *.pb.h files + include_directories(SYSTEM "${CMAKE_CURRENT_BINARY_DIR}") + + set(MONITORING_FILES + ${MONITORING_FILES} + src/monitoring/receiver_monitoring_client_impl.cpp + ) +endif() + +################################ +# Building +################################ set(SOURCE_FILES ${RECEIVER_CORE_FILES} ${RDS_FILES} + ${MONITORING_FILES} ) - ################################ # Library ################################ @@ -66,6 +133,9 @@ target_include_directories(${TARGET_NAME} PUBLIC ${ASAPO_CXX_COMMON_INCLUDE_DIR} target_include_directories(${TARGET_NAME} SYSTEM PUBLIC ${LIBFABRIC_INCLUDE_DIR} ${RDKAFKA_INCLUDE_DIR}) target_link_libraries(${TARGET_NAME} CURL::libcurl ${RDKAFKA_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} database asapo-fabric ${ASAPO_COMMON_FABRIC_LIBRARIES}) +if (ENABLE_NEW_RECEIVER_MONITORING) +target_link_libraries(${TARGET_NAME} grpc_ingest_service_proto ${_REFLECTION} ${_GRPC_GRPCPP} ${_PROTOBUF_LIBPROTOBUF}) +endif() add_executable(${TARGET_NAME}-bin src/main.cpp) @@ -99,6 +169,7 @@ set(TEST_SOURCE_FILES unittests/statistics/test_receiver_statistics.cpp unittests/test_config.cpp unittests/test_request.cpp + unittests/request_handler/test_request_factory.cpp unittests/request_handler/test_request_handler_file_process.cpp unittests/request_handler/test_request_handler_db_writer.cpp @@ -114,9 +185,12 @@ set(TEST_SOURCE_FILES unittests/request_handler/test_request_handler_receive_metadata.cpp unittests/request_handler/test_request_handler_delete_stream.cpp unittests/request_handler/test_request_handler_db_get_meta.cpp + unittests/request_handler/test_request_handler_monitoring.cpp + unittests/request_handler/test_request_handler_kafka_notify.cpp unittests/statistics/test_statistics_sender_influx_db.cpp unittests/statistics/test_statistics_sender_fluentd.cpp + unittests/mock_receiver_config.cpp unittests/request_handler/test_requests_dispatcher.cpp unittests/test_datacache.cpp @@ -124,12 +198,23 @@ set(TEST_SOURCE_FILES unittests/request_handler/file_processors/test_file_processor.cpp unittests/request_handler/file_processors/test_receive_file_processor.cpp ) + +if (ENABLE_NEW_RECEIVER_MONITORING) + set(TEST_SOURCE_FILES + ${TEST_SOURCE_FILES} + + unittests/monitoring/test_monitoring_client.cpp + unittests/monitoring/test_monitoring_client_to_be_send_data.cpp + ) +endif() # set(TEST_LIBRARIES "${TARGET_NAME};system_io") gtest(${TARGET_NAME} "${TEST_SOURCE_FILES}" "${TEST_LIBRARIES}" ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/receiver_data_server/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/receiver_data_server/*.h + ${CMAKE_CURRENT_BINARY_DIR}/*.h + ${CMAKE_CURRENT_BINARY_DIR}/*.cc ${CMAKE_CURRENT_SOURCE_DIR}/src/receiver_data_server/net_server/*.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/receiver_data_server/net_server/*.h ${CMAKE_CURRENT_SOURCE_DIR}/src/receiver_data_server/request_handler/*.cpp diff --git a/receiver/src/connection.cpp b/receiver/src/connection.cpp index aa0a1e028271d9ec590058857333317e46280818..9064c642b44244ab7e0534e3f9b26d55c9575035 100644 --- a/receiver/src/connection.cpp +++ b/receiver/src/connection.cpp @@ -1,4 +1,5 @@ #include <cstring> +#include <utility> #include <assert.h> #include "connection.h" #include "receiver_error.h" @@ -8,16 +9,16 @@ namespace asapo { -Connection::Connection(SocketDescriptor socket_fd, const std::string& address, +Connection::Connection(SocketDescriptor socket_fd, const std::string& address,SharedReceiverMonitoringClient monitoring, SharedCache cache, KafkaClient* kafkaClient, std::string receiver_tag) : io__{GenerateDefaultIO()}, statistics__{new ReceiverStatistics}, log__{GetDefaultReceiverLogger()}, -requests_dispatcher__{new RequestsDispatcher{socket_fd, address, statistics__.get(), cache, kafkaClient}} { +requests_dispatcher__{new RequestsDispatcher{socket_fd, address, statistics__.get(),std::move(monitoring), cache,kafkaClient}} { socket_fd_ = socket_fd; address_ = address; statistics__->AddTag("connection_from", address); - statistics__->AddTag("receiver_tag", std::move(receiver_tag)); + statistics__->AddTag("receiver_tag", receiver_tag); } void Connection::ProcessStatisticsAfterRequest(const std::unique_ptr<Request>& request) const noexcept { diff --git a/receiver/src/connection.h b/receiver/src/connection.h index 88af2a4ec6001cbf58e32c88e940bfbf24f476a1..29c158181cb9507f5b6c145ed3ebf7c4abca9a12 100644 --- a/receiver/src/connection.h +++ b/receiver/src/connection.h @@ -14,6 +14,7 @@ #include "asapo/common/networking.h" #include "asapo/io/io.h" #include "request.h" +#include "monitoring/receiver_monitoring_client.h" #include "statistics/receiver_statistics.h" #include "asapo/logger/logger.h" #include "request_handler/requests_dispatcher.h" @@ -28,7 +29,7 @@ class Connection { int socket_fd_; public: - Connection(SocketDescriptor socket_fd, const std::string& address, SharedCache cache, KafkaClient* kafkaClient, std::string receiver_tag); + Connection(SocketDescriptor socket_fd, const std::string& address, SharedReceiverMonitoringClient monitoring, SharedCache cache,KafkaClient* kafkaClient, std::string receiver_tag); ~Connection() = default; void Listen() const noexcept; diff --git a/receiver/src/data_cache.cpp b/receiver/src/data_cache.cpp index 1ad50f54008be00942f522d0a6951ea69833f94c..fbfd65d953672a648b5f24fc69bab80b59eb47e9 100644 --- a/receiver/src/data_cache.cpp +++ b/receiver/src/data_cache.cpp @@ -3,6 +3,8 @@ #include <iostream> #include <chrono> #include <algorithm> +#include <cstdint> +#include <utility> #include "receiver_error.h" @@ -36,7 +38,8 @@ void* DataCache::AllocateSlot(uint64_t size,CacheMeta** blocking_meta) { } return addr; } -void* DataCache::GetFreeSlotAndLock(uint64_t size, CacheMeta** meta, Error* err) { + +void* DataCache::GetFreeSlotAndLock(uint64_t size, CacheMeta** meta,std::string beamtime, std::string source, std::string stream,Error* err) { std::lock_guard<std::mutex> lock{mutex_}; *meta = nullptr; if (!CheckAllocationSize(size)) { @@ -58,7 +61,7 @@ void* DataCache::GetFreeSlotAndLock(uint64_t size, CacheMeta** meta, Error* err) auto id = GetNextId(); - *meta = new CacheMeta{id, addr, size, 1}; + *meta = new CacheMeta{id, addr, size, 1, std::move(beamtime), std::move(source), std::move(stream)}; meta_.emplace_back(std::unique_ptr<CacheMeta> {*meta}); *err = nullptr; @@ -147,4 +150,26 @@ bool DataCache::UnlockSlot(CacheMeta* meta) { return true; } +std::vector<std::shared_ptr<const CacheMeta>> DataCache::AllMetaInfosAsVector() const { + // This function is used in case of a complete scan of the metadata info, but not blocking + + std::vector<std::shared_ptr<const CacheMeta>> result; + result.reserve(meta_.size()); + + { // Lock - block + std::lock_guard<std::mutex> lock{mutex_}; + + for (const auto& element : meta_) { + result.emplace_back(element); + } + } + + // return will not copy the list: https://stackoverflow.com/a/53520381/ + return result; +} + +uint64_t DataCache::GetCacheSize() const { + return cache_size_; +} + } diff --git a/receiver/src/data_cache.h b/receiver/src/data_cache.h index 6015439bf876975295974ffa1127a539520ec004..e58c460abfd64436ce09de9f902f1bf4d58d5abf 100644 --- a/receiver/src/data_cache.h +++ b/receiver/src/data_cache.h @@ -1,10 +1,11 @@ #ifndef ASAPO_DATA_CACHE_H #define ASAPO_DATA_CACHE_H -#include <stdint.h> +#include <cstdint> #include <memory> #include <mutex> #include <deque> +#include <vector> #include "asapo/preprocessor/definitions.h" #include "asapo/common/error.h" @@ -16,12 +17,18 @@ struct CacheMeta { void* addr; uint64_t size; int lock; + std::string beamtime; + std::string source; + std::string stream; }; class DataCache { public: explicit DataCache(uint64_t cache_size_gb, float keepunlocked_ratio); - ASAPO_VIRTUAL void* GetFreeSlotAndLock(uint64_t size, CacheMeta** meta, Error* err); + ASAPO_VIRTUAL void* GetFreeSlotAndLock(uint64_t size, CacheMeta** meta, + std::string beamtime, std::string source, std::string stream, Error* err); + ASAPO_VIRTUAL std::vector<std::shared_ptr<const CacheMeta>> AllMetaInfosAsVector() const; + ASAPO_VIRTUAL uint64_t GetCacheSize() const; ASAPO_VIRTUAL void* GetSlotToReadAndLock(uint64_t id, uint64_t data_size, CacheMeta** meta); ASAPO_VIRTUAL bool UnlockSlot(CacheMeta* meta); ASAPO_VIRTUAL ~DataCache() = default; @@ -31,8 +38,8 @@ class DataCache { uint32_t counter_; uint64_t cur_pointer_ = 0; std::unique_ptr<uint8_t[]> cache_; - std::mutex mutex_; - std::deque<std::unique_ptr<CacheMeta>> meta_; + mutable std::mutex mutex_; + std::deque<std::shared_ptr<CacheMeta>> meta_; bool SlotTooCloseToCurrentPointer(const CacheMeta* meta); bool CleanOldSlots(uint64_t size,CacheMeta** blocking_meta); void* AllocateSlot(uint64_t size,CacheMeta** blocking_meta); diff --git a/receiver/src/main.cpp b/receiver/src/main.cpp index 77410e80e81e7007826b44871f722578d2bb22ee..c2b9c63bde0c7fcaf1be97c6eddf09f5b6004de4 100644 --- a/receiver/src/main.cpp +++ b/receiver/src/main.cpp @@ -11,6 +11,7 @@ #include "receiver_data_server/receiver_data_server.h" #include "receiver_data_server/net_server/rds_tcp_server.h" #include "receiver_data_server/net_server/rds_fabric_server.h" +#include "monitoring/receiver_monitoring_client.h" #include "metrics/receiver_prometheus_metrics.h" #include "metrics/receiver_mongoose_server.h" @@ -28,7 +29,8 @@ void ReadConfigFile(int argc, char* argv[]) { } } -void AddDataServers(const asapo::ReceiverConfig* config, asapo::SharedCache, +void AddDataServers(const asapo::ReceiverConfig* config, const asapo::SharedCache&, + const asapo::SharedReceiverMonitoringClient& monitoring, std::vector<asapo::RdsNetServerPtr>& netServers) { auto logger = asapo::GetDefaultReceiverDataServerLogger(); logger->SetLogLevel(config->log_level); @@ -37,21 +39,29 @@ void AddDataServers(const asapo::ReceiverConfig* config, asapo::SharedCache, auto networkingMode = ds_config.network_mode; if (std::find(networkingMode.begin(), networkingMode.end(), "tcp") != networkingMode.end()) { // Add TCP - netServers.emplace_back(new asapo::RdsTcpServer("0.0.0.0:" + std::to_string(ds_config.listen_port), logger)); + netServers.emplace_back(new asapo::RdsTcpServer("0.0.0.0:" + std::to_string(ds_config.listen_port), logger, monitoring)); } if (std::find(networkingMode.begin(), networkingMode.end(), "fabric") != networkingMode.end()) { // Add Fabric - netServers.emplace_back(new asapo::RdsFabricServer(ds_config.advertise_uri, logger)); + netServers.emplace_back(new asapo::RdsFabricServer(ds_config.advertise_uri, logger, monitoring)); } } +asapo::SharedReceiverMonitoringClient StartMonitoringClient(const asapo::ReceiverConfig* config, asapo::SharedCache cache, asapo::Error* error) { + bool useNoopImpl = !config->monitor_performance; + auto monitoring = asapo::SharedReceiverMonitoringClient(asapo::GenerateDefaultReceiverMonitoringClient(cache, useNoopImpl)); + monitoring->StartMonitoring(); + *error = nullptr; + return monitoring; +} + std::vector<std::thread> StartDataServers(const asapo::ReceiverConfig* config, asapo::SharedCache cache, - asapo::Error* error) { + asapo::SharedReceiverMonitoringClient monitoring, asapo::Error* error) { std::vector<asapo::RdsNetServerPtr> netServers; std::vector<std::thread> dataServerThreads; - AddDataServers(config, cache, netServers); + AddDataServers(config, cache, monitoring, netServers); for (auto& server : netServers) { *error = server->Initialize(); @@ -78,11 +88,12 @@ std::vector<std::thread> StartDataServers(const asapo::ReceiverConfig* config, a } int StartReceiver(const asapo::ReceiverConfig* config, asapo::SharedCache cache, - asapo::KafkaClient* kafkaClient, asapo::AbstractLogger* logger) { + asapo::SharedReceiverMonitoringClient monitoring,asapo::KafkaClient* kafkaClient,asapo::AbstractLogger* logger) { static const std::string address = "0.0.0.0:" + std::to_string(config->listen_port); logger->Info(std::string("starting receiver, version ") + asapo::kVersion); - auto receiver = std::unique_ptr<asapo::Receiver>{new asapo::Receiver(cache, kafkaClient)}; + auto receiver = std::unique_ptr<asapo::Receiver>{new asapo::Receiver(cache,monitoring, kafkaClient)}; + logger->Info("listening on " + address); asapo::Error err; @@ -121,6 +132,9 @@ int main(int argc, char* argv[]) { auto config = asapo::GetReceiverConfig(); logger->SetLogLevel(config->log_level); + const auto& monitoringLogger = asapo::GetDefaultReceiverMonitoringLogger(); + monitoringLogger->SetLogLevel(config->log_level); + asapo::SharedCache cache = nullptr; if (config->use_datacache) { cache.reset(new asapo::DataCache{config->datacache_size_gb * 1024 * 1024 * 1024, @@ -128,7 +142,8 @@ int main(int argc, char* argv[]) { } asapo::Error err; - auto dataServerThreads = StartDataServers(config, cache, &err); + auto monitoring = StartMonitoringClient(config, cache, &err); + auto dataServerThreads = StartDataServers(config, cache, monitoring, &err); if (err) { logger->Error("cannot start data server: " + err->Explain()); return EXIT_FAILURE; @@ -148,7 +163,7 @@ int main(int argc, char* argv[]) { logger->Info("kafka notifications disabled."); } - auto exit_code = StartReceiver(config, cache, kafkaClient.get(), logger); + auto exit_code = StartReceiver(config, cache,monitoring, kafkaClient.get(), logger); // todo: implement graceful exit, currently it never reaches this point return exit_code; } diff --git a/receiver/src/monitoring/receiver_monitoring_client.cpp b/receiver/src/monitoring/receiver_monitoring_client.cpp new file mode 100644 index 0000000000000000000000000000000000000000..300e286a143bef1f479bd200988226724c8e1fac --- /dev/null +++ b/receiver/src/monitoring/receiver_monitoring_client.cpp @@ -0,0 +1,29 @@ +#include "receiver_monitoring_client.h" +#include "receiver_monitoring_client_noop.h" + +#ifdef NEW_RECEIVER_MONITORING_ENABLED +#include "receiver_monitoring_client_impl.h" +#endif + +using namespace asapo; + +SharedReceiverMonitoringClient asapo::GenerateDefaultReceiverMonitoringClient(SharedCache cache, bool forceNoopImplementation) { +#ifdef NEW_RECEIVER_MONITORING_ENABLED + if (!forceNoopImplementation) { + return SharedReceiverMonitoringClient{new ReceiverMonitoringClientImpl{cache}}; + } +#else + (void)(cache); + (void)(forceNoopImplementation); +#endif + return SharedReceiverMonitoringClient{new ReceiverMonitoringClientNoop}; +} + +std::chrono::high_resolution_clock::time_point asapo::ReceiverMonitoringClient::HelperTimeNow() { + return std::chrono::high_resolution_clock::now(); +} + +uint64_t asapo::ReceiverMonitoringClient::HelperTimeDiffInMicroseconds(std::chrono::high_resolution_clock::time_point startTime) { + auto now = HelperTimeNow(); + return static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::microseconds>(now - startTime).count()); +} diff --git a/receiver/src/monitoring/receiver_monitoring_client.h b/receiver/src/monitoring/receiver_monitoring_client.h new file mode 100644 index 0000000000000000000000000000000000000000..cfdfd0d96f883ce6c8813d679940f94814895a23 --- /dev/null +++ b/receiver/src/monitoring/receiver_monitoring_client.h @@ -0,0 +1,53 @@ +#ifndef ASAPO_RECEIVER_MONITORING_CLIENT_H +#define ASAPO_RECEIVER_MONITORING_CLIENT_H + +#include <chrono> +#include <string> +#include <memory> +#include "../data_cache.h" + +namespace asapo { + +class ReceiverMonitoringClient { +protected: + ReceiverMonitoringClient() = default; +public: + static std::chrono::high_resolution_clock::time_point HelperTimeNow(); + static uint64_t HelperTimeDiffInMicroseconds(std::chrono::high_resolution_clock::time_point startTime); + + ReceiverMonitoringClient(const ReceiverMonitoringClient&) = delete; + ReceiverMonitoringClient& operator=(const ReceiverMonitoringClient&) = delete; + virtual void StartMonitoring() = 0; + virtual void SendProducerToReceiverTransferDataPoint(const std::string& pipelineStepId, + const std::string& producerInstanceId, + const std::string& beamtime, + const std::string& source, + const std::string& stream, + uint64_t fileSize, + uint64_t transferTimeInMicroseconds, + uint64_t writeIoTimeInMicroseconds, + uint64_t dbTimeInMicroseconds) = 0; + + virtual void SendRdsRequestWasMissDataPoint(const std::string& pipelineStepId, + const std::string& consumerInstanceId, + const std::string& beamtime, + const std::string& source, + const std::string& stream) = 0; + + virtual void SendReceiverRequestDataPoint(const std::string& pipelineStepId, + const std::string& consumerInstanceId, + const std::string& beamtime, + const std::string& source, const std::string& stream, + uint64_t fileSize, + uint64_t transferTimeInMicroseconds) = 0; + + virtual void FillMemoryStats() = 0; + virtual ~ReceiverMonitoringClient() = default; +}; + +using SharedReceiverMonitoringClient = std::shared_ptr<asapo::ReceiverMonitoringClient>; + +SharedReceiverMonitoringClient GenerateDefaultReceiverMonitoringClient(SharedCache cache, bool forceNoopImplementation); + +} +#endif //ASAPO_RECEIVER_MONITORING_CLIENT_H diff --git a/receiver/src/monitoring/receiver_monitoring_client_impl.cpp b/receiver/src/monitoring/receiver_monitoring_client_impl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ce47f6f72b8f5159beaa59d0bf44ea4d816e2358 --- /dev/null +++ b/receiver/src/monitoring/receiver_monitoring_client_impl.cpp @@ -0,0 +1,362 @@ +#include <chrono> +#include <utility> +#include <asapo/io/io_factory.h> +#include "receiver_monitoring_client_impl.h" +#include "../receiver_logger.h" +#include "./AsapoMonitoringIngestService.pb.h" +#include "../receiver_config.h" +#include "../receiver_error.h" + +using namespace asapo; + +static const int kUniversalSendingIntervalMs = 5000; + +uint64_t NowUnixTimestampMs() { + return static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count()); +} + +asapo::ReceiverMonitoringClientImpl::ReceiverMonitoringClientImpl(asapo::SharedCache cache) : cache_(cache), io__{GenerateDefaultIO()}, log__{GetDefaultReceiverMonitoringLogger()}, http_client__{DefaultHttpClient()}, toBeSendData__{ + new ToBeSendData +} +{ + Error err; + std::string hostname = io__->GetHostName(&err); + if (err) { + hostname = "hostnameerror"; + } + receiverName_ = "receiver_" + hostname + "_" + std::to_string(io__->GetCurrentPid()); + + +} + +void ReceiverMonitoringClientImpl::StartMonitoring() { + ReinitializeClient(); + StartSendingThread(); +} + + +void asapo::ReceiverMonitoringClientImpl::StartSendingThread() { + if (sendingThreadRunning__) { + return; + } + + if (!client_) { + log__->Warning("Tried to start monitoring sending thread, but client is not successfully initialized"); + return; + } + + log__->Info("Starting sending thread"); + sendingThreadRunning__ = true; + sendingThread_ = std::unique_ptr<std::thread>(io__->NewThread("MonitoringSender", [this]() { + SendingThreadFunction(); + })); +} + +void asapo::ReceiverMonitoringClientImpl::StopSendingThread() { + if (!sendingThreadRunning__) { + log__->Info("sending thread already stopped"); + return; + } + + log__->Info("Stopping sending thread"); + sendingThreadRunning__ = false; + if (sendingThread_.get() && sendingThread_->joinable()) { + sendingThread_->join(); + sendingThread_=nullptr; + } + log__->Info("Stopped sending thread"); +} + +void asapo::ReceiverMonitoringClientImpl::SendingThreadFunction() { + auto globalStartTime = ReceiverMonitoringClient::HelperTimeNow(); + + std::unique_ptr<ToBeSendData> localToBeSend{new ToBeSendData}; + while(sendingThreadRunning__) { + auto iterationStart = ReceiverMonitoringClient::HelperTimeNow(); + FillMemoryStats(); + + // Clear and swap data + localToBeSend->container.Clear(); + { + std::lock_guard<std::mutex> lockGuard(toBeSendData_mutex_); + toBeSendData__.swap(localToBeSend); + } + + Error err = SendData(&(localToBeSend->container)); + if (err) { + log__->Info("Sending of all monitoring data failed: " + err->Explain()); + ReinitializeClient(); + + err = SendData(&(localToBeSend->container)); + if (err) { + log__->Info("Sending of all monitoring data failed AGAIN. Discarding data " + err->Explain()); + } + } + + size_t size = localToBeSend->container.ByteSizeLong(); + + uint64_t sleepDurationInMs = WaitTimeMsUntilNextInterval(globalStartTime); + auto tookTimeMs = ReceiverMonitoringClient::HelperTimeDiffInMicroseconds(iterationStart) / 1000; + + if (tookTimeMs > kUniversalSendingIntervalMs) { + sleepDurationInMs = 0; + } + + auto tookInMsStr = std::to_string(tookTimeMs); + + if (!err) { + log__->Debug("Sending of all monitoring data(" + std::to_string(size) + " byte) took " + tookInMsStr+ "ms (sleeping for " + std::to_string(sleepDurationInMs) + "ms)"); + } else { + log__->Info("Error took " + tookInMsStr + "ms, will try again in " + std::to_string(sleepDurationInMs) + "ms"); + } + + std::this_thread::sleep_for(std::chrono::milliseconds(sleepDurationInMs)); + } +} + +void asapo::ReceiverMonitoringClientImpl::SendProducerToReceiverTransferDataPoint(const std::string& pipelineStepId, + const std::string& producerInstanceId, + const std::string& beamtime, + const std::string& source, + const std::string& stream, + uint64_t fileSize, + uint64_t transferTimeInMicroseconds, + uint64_t writeIoTimeInMicroseconds, + uint64_t dbTimeInMicroseconds) { + if (!sendingThreadRunning__) { + return; + } + + { // LockGuard block + std::lock_guard<std::mutex> lockGuard(toBeSendData_mutex_); + + auto dataPoint = toBeSendData__->GetProducerToReceiverTransfer(pipelineStepId, producerInstanceId, beamtime, source, stream); + + dataPoint->set_filecount(dataPoint->filecount() + 1); + dataPoint->set_totalfilesize(dataPoint->totalfilesize() + fileSize); + + dataPoint->set_totaltransferreceivetimeinmicroseconds(dataPoint->totaltransferreceivetimeinmicroseconds() + transferTimeInMicroseconds); + dataPoint->set_totalwriteiotimeinmicroseconds(dataPoint->totalwriteiotimeinmicroseconds() + writeIoTimeInMicroseconds); + dataPoint->set_totaldbtimeinmicroseconds(dataPoint->totaldbtimeinmicroseconds() + dbTimeInMicroseconds); + } +} + +void asapo::ReceiverMonitoringClientImpl::SendRdsRequestWasMissDataPoint(const std::string& pipelineStepId, + const std::string& consumerInstanceId, + const std::string& beamtime, + const std::string& source, + const std::string& stream) { + if (!sendingThreadRunning__) { + return; + } + + { // LockGuard block + std::lock_guard<std::mutex> lockGuard(toBeSendData_mutex_); + + auto dataPoint = toBeSendData__->GetReceiverDataServerToConsumer(pipelineStepId, consumerInstanceId, beamtime, source, stream); + + dataPoint->set_misses(dataPoint->misses() + 1); + } +} + +void asapo::ReceiverMonitoringClientImpl::SendReceiverRequestDataPoint(const std::string& pipelineStepId, + const std::string& consumerInstanceId, + const std::string& beamtime, + const std::string& source, const std::string& stream, + uint64_t fileSize, + uint64_t transferTimeInMicroseconds) { + if (!sendingThreadRunning__) { + return; + } + + { // LockGuard block + std::lock_guard<std::mutex> lockGuard(toBeSendData_mutex_); + + auto dataPoint = toBeSendData__->GetReceiverDataServerToConsumer(pipelineStepId, consumerInstanceId, beamtime, source, stream); + + dataPoint->set_hits(dataPoint->hits() + 1); + dataPoint->set_totalfilesize(dataPoint->totalfilesize() + fileSize); + dataPoint->set_totaltransfersendtimeinmicroseconds(dataPoint->totaltransfersendtimeinmicroseconds() + transferTimeInMicroseconds); + } +} + +void asapo::ReceiverMonitoringClientImpl::FillMemoryStats() { + if (cache_ == nullptr) { + return; + } + + auto metaVector = cache_->AllMetaInfosAsVector(); + + { + std::lock_guard<std::mutex> lockGuard(toBeSendData_mutex_); + for (const auto& meta : metaVector) { + auto mDataPoint = toBeSendData__->GetMemoryDataPoint(meta->beamtime, meta->source, meta->stream); + mDataPoint->set_usedbytes(mDataPoint->usedbytes() + meta->size); + } + + for (auto& group : *(toBeSendData__->container.mutable_groupedmemorystats())) { + group.set_totalbytes(cache_->GetCacheSize()); + } + } +} + +asapo::Error asapo::ReceiverMonitoringClientImpl::SendData(ReceiverDataPointContainer* container) { + container->set_receivername(receiverName_); + + uint64_t baseTimestamp = NowUnixTimestampMs(); + container->set_timestampms(baseTimestamp); + + grpc::ClientContext context; + Empty response; + + auto deadline = std::chrono::system_clock::now() + std::chrono::seconds(5); + context.set_deadline(deadline); + grpc::Status status = client_->InsertReceiverDataPoints(&context, *container, &response); + + if (!status.ok()) { + return GeneralErrorTemplates::kSimpleError.Generate("Monitoring gRPC Send Error " + status.error_message() + " Details: " + status.error_details()); + } + + return nullptr; +} + +asapo::Error asapo::ReceiverMonitoringClientImpl::ReinitializeClient() { + std::string url; + Error err = GetMonitoringServerUrl(&url); + if (err) { + return err; + } + + log__->Debug("MonitoringServer address: '" + url + "'"); + + auto newChannel = std::shared_ptr<grpc::Channel>(grpc::CreateChannel(url, grpc::InsecureChannelCredentials())); + auto newClient = std::unique_ptr<AsapoMonitoringIngestService::Stub>(AsapoMonitoringIngestService::NewStub(newChannel)); + + // TODO: verify connection + { + client_.swap(newClient); + channel_.swap(newChannel); + + newClient.reset(); // delete client first + newChannel.reset(); + } + return nullptr; +} + +asapo::Error asapo::ReceiverMonitoringClientImpl::GetMonitoringServerUrl(std::string* url) const { + if (GetReceiverConfig()->monitoring_server_url != "auto") { + *url = GetReceiverConfig()->monitoring_server_url; + return nullptr; + } + + HttpCode code; + Error http_err; + *url = http_client__->Get(GetReceiverConfig()->discovery_server + "/asapo-monitoring", &code, &http_err); + if (http_err) { + log__->Error( + std::string{"http error while trying to discover monitoring server from"} + GetReceiverConfig()->discovery_server + + " : " + http_err->Explain()); + return ReceiverErrorTemplates::kInternalServerError.Generate("http error while trying to discover monitoring server" + + http_err->Explain()); + } + + if (code != HttpCode::OK) { + log__->Error( + std::string{"http status code error while trying to discover monitoring server from "} + GetReceiverConfig()->discovery_server + + " : http code" + std::to_string((int) code)); + return ReceiverErrorTemplates::kInternalServerError.Generate("http status code error while trying to discover monitoring server"); + } + + return nullptr; +} + +ProducerToReceiverTransferDataPoint* +asapo::ReceiverMonitoringClientImpl::ToBeSendData::GetProducerToReceiverTransfer(const std::string& pipelineStepId, + const std::string& producerInstanceId, + const std::string& beamtime, + const std::string& source, + const std::string& stream) { + + for (auto& item : *(container.mutable_groupedp2rtransfers())) { + if (item.pipelinestepid() == pipelineStepId && + item.producerinstanceid() == producerInstanceId && + item.beamtime() == beamtime && + item.source() == source && + item.stream() == stream) { + return &item; + } + } + + auto newItem = container.mutable_groupedp2rtransfers()->Add(); + + *(newItem->mutable_pipelinestepid()) = pipelineStepId; + *(newItem->mutable_producerinstanceid()) = producerInstanceId; + *(newItem->mutable_beamtime()) = beamtime; + *(newItem->mutable_source()) = source; + *(newItem->mutable_stream()) = stream; + + return newItem; +} + +RdsToConsumerDataPoint* +asapo::ReceiverMonitoringClientImpl::ToBeSendData::GetReceiverDataServerToConsumer(const std::string& pipelineStepId, + const std::string& consumerInstanceId, + const std::string& beamtime, + const std::string& source, + const std::string& stream) { + for (auto& item : *(container.mutable_groupedrds2ctransfers())) { + if (item.pipelinestepid() == pipelineStepId && + item.consumerinstanceid() == consumerInstanceId && + item.beamtime() == beamtime && + item.source() == source && + item.stream() == stream) { + return &item; + } + } + + auto newItem = container.mutable_groupedrds2ctransfers()->Add(); + + *(newItem->mutable_pipelinestepid()) = pipelineStepId; + *(newItem->mutable_consumerinstanceid()) = consumerInstanceId; + *(newItem->mutable_beamtime()) = beamtime; + *(newItem->mutable_source()) = source; + *(newItem->mutable_stream()) = stream; + + return newItem; +} + +RdsMemoryDataPoint* asapo::ReceiverMonitoringClientImpl::ToBeSendData::GetMemoryDataPoint(const std::string& beamtime, + const std::string& source, + const std::string& stream) { + for (auto& item : *(container.mutable_groupedmemorystats())) { + if (item.beamtime() == beamtime && + item.source() == source && + item.stream() == stream) { + return &item; + } + } + + auto newItem = container.mutable_groupedmemorystats()->Add(); + + *(newItem->mutable_beamtime()) = beamtime; + *(newItem->mutable_source()) = source; + *(newItem->mutable_stream()) = stream; + + return newItem; +} + +uint64_t asapo::ReceiverMonitoringClientImpl::WaitTimeMsUntilNextInterval(std::chrono::high_resolution_clock::time_point startTime) { + auto now = std::chrono::high_resolution_clock::now(); + auto delta = now - startTime; + auto interval = std::chrono::milliseconds(kUniversalSendingIntervalMs); + + auto result = (uint64_t) std::chrono::duration_cast<std::chrono::milliseconds>(interval - (delta % interval)).count(); + return result; +} + +ReceiverMonitoringClientImpl::~ReceiverMonitoringClientImpl() { + StopSendingThread(); +} + + + diff --git a/receiver/src/monitoring/receiver_monitoring_client_impl.h b/receiver/src/monitoring/receiver_monitoring_client_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..18600fbe113af4e9ec25de82d5f2295f5fdbaa3e --- /dev/null +++ b/receiver/src/monitoring/receiver_monitoring_client_impl.h @@ -0,0 +1,111 @@ +#ifndef ASAPO_RECEIVER_MONITORING_CLIENT_IMPL_H +#define ASAPO_RECEIVER_MONITORING_CLIENT_IMPL_H + +#include "receiver_monitoring_client.h" +#include <AsapoMonitoringIngestService.pb.h> +#include "asapo/logger/logger.h" +#include <grpc/grpc.h> +#include <grpcpp/channel.h> +#include <grpcpp/client_context.h> +#include <grpcpp/create_channel.h> +#include <AsapoMonitoringIngestService.grpc.pb.h> +#include <asapo/http_client/http_client.h> +#include <asapo/io/io.h> + +namespace asapo { + +class ReceiverMonitoringClientImpl : public ReceiverMonitoringClient { +public: + // Defined below + class ToBeSendData; + private: + std::unique_ptr<std::thread> sendingThread_; + + void SendingThreadFunction(); + Error SendData(ReceiverDataPointContainer* container); + + std::string receiverName_; + + std::shared_ptr<grpc::Channel> channel_; + std::unique_ptr<AsapoMonitoringIngestService::Stub> client_; + + std::mutex toBeSendData_mutex_; + + SharedCache cache_; +public: + std::unique_ptr<IO> io__; + AbstractLogger* log__; + std::unique_ptr<HttpClient> http_client__; + + std::unique_ptr<ToBeSendData> toBeSendData__; + mutable bool sendingThreadRunning__ = false; + + explicit ReceiverMonitoringClientImpl(SharedCache cache); + ReceiverMonitoringClientImpl(const ReceiverMonitoringClientImpl&) = delete; + ReceiverMonitoringClientImpl& operator=(const ReceiverMonitoringClientImpl&) = delete; + ~ReceiverMonitoringClientImpl(); + void StartSendingThread(); + void StopSendingThread(); + void StartMonitoring() override; + void SendProducerToReceiverTransferDataPoint(const std::string& pipelineStepId, + const std::string& producerInstanceId, + const std::string& beamtime, + const std::string& source, + const std::string& stream, + uint64_t fileSize, + uint64_t transferTimeInMicroseconds, + uint64_t writeIoTimeInMicroseconds, + uint64_t dbTimeInMicroseconds) override; + + void SendRdsRequestWasMissDataPoint(const std::string& pipelineStepId, + const std::string& consumerInstanceId, + const std::string& beamtime, + const std::string& source, + const std::string& stream) override; + + void SendReceiverRequestDataPoint(const std::string& pipelineStepId, + const std::string& consumerInstanceId, + const std::string& beamtime, + const std::string& source, const std::string& stream, + uint64_t fileSize, + uint64_t transferTimeInMicroseconds) override; + + void FillMemoryStats() override; + +private: + Error ReinitializeClient(); + Error GetMonitoringServerUrl(std::string* url) const; + + static uint64_t WaitTimeMsUntilNextInterval(std::chrono::high_resolution_clock::time_point startTime); + +public: + // Internal struct + class ToBeSendData { + public: + //std::mutex mutex; + ReceiverDataPointContainer container; + ASAPO_VIRTUAL ~ToBeSendData()=default; + ASAPO_VIRTUAL ProducerToReceiverTransferDataPoint* GetProducerToReceiverTransfer( + const std::string& pipelineStepId, + const std::string& producerInstanceId, + const std::string& beamtime, + const std::string& source, + const std::string& stream); + + ASAPO_VIRTUAL RdsToConsumerDataPoint* GetReceiverDataServerToConsumer( + const std::string& pipelineStepId, + const std::string& consumerInstanceId, + const std::string& beamtime, + const std::string& source, + const std::string& stream); + + ASAPO_VIRTUAL RdsMemoryDataPoint* GetMemoryDataPoint( + const std::string& beamtime, + const std::string& source, + const std::string& stream); + }; +}; + +} + +#endif //ASAPO_RECEIVER_MONITORING_CLIENT_IMPL_H diff --git a/receiver/src/monitoring/receiver_monitoring_client_noop.cpp b/receiver/src/monitoring/receiver_monitoring_client_noop.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1208c444e50fae15e24f780b8eacdb6ef62c8a4f --- /dev/null +++ b/receiver/src/monitoring/receiver_monitoring_client_noop.cpp @@ -0,0 +1,58 @@ + +#include <cstdint> +#include "receiver_monitoring_client_noop.h" + +void asapo::ReceiverMonitoringClientNoop::SendProducerToReceiverTransferDataPoint(const std::string& pipelineStepId, + const std::string& producerInstanceId, + const std::string& beamtime, + const std::string& source, + const std::string& stream, + uint64_t fileSize, + uint64_t transferTimeInMicroseconds, + uint64_t writeIoTimeInMicroseconds, + uint64_t dbTimeInMicroseconds) { + (void)(pipelineStepId); + (void)(producerInstanceId); + (void)(beamtime); + (void)(source); + (void)(stream); + (void)(fileSize); + (void)(transferTimeInMicroseconds); + (void)(writeIoTimeInMicroseconds); + (void)(dbTimeInMicroseconds); +} + +void asapo::ReceiverMonitoringClientNoop::SendRdsRequestWasMissDataPoint(const std::string& pipelineStepId, + const std::string& consumerInstanceId, + const std::string& beamtime, + const std::string& source, + const std::string& stream) { + (void)(pipelineStepId); + (void)(consumerInstanceId); + (void)(beamtime); + (void)(source); + (void)(stream); +} + +void asapo::ReceiverMonitoringClientNoop::SendReceiverRequestDataPoint(const std::string& pipelineStepId, + const std::string& consumerInstanceId, + const std::string& beamtime, + const std::string& source, + const std::string& stream, uint64_t fileSize, + uint64_t transferTimeInMicroseconds) { + (void)(pipelineStepId); + (void)(consumerInstanceId); + (void)(beamtime); + (void)(source); + (void)(stream); + (void)(fileSize); + (void)(transferTimeInMicroseconds); +} + +void asapo::ReceiverMonitoringClientNoop::FillMemoryStats() { + +} + +void asapo::ReceiverMonitoringClientNoop::StartMonitoring() { + +} diff --git a/receiver/src/monitoring/receiver_monitoring_client_noop.h b/receiver/src/monitoring/receiver_monitoring_client_noop.h new file mode 100644 index 0000000000000000000000000000000000000000..a95dca0d6a0db6808df168bc8f3e5eebe1b2ee1d --- /dev/null +++ b/receiver/src/monitoring/receiver_monitoring_client_noop.h @@ -0,0 +1,30 @@ +#ifndef ASAPO_RECEIVER_MONITORING_CLIENT_NOOP_H +#define ASAPO_RECEIVER_MONITORING_CLIENT_NOOP_H + +#include "receiver_monitoring_client.h" + +namespace asapo { + class ReceiverMonitoringClientNoop : public ReceiverMonitoringClient { + public: + void StartMonitoring() override; + void SendProducerToReceiverTransferDataPoint(const std::string& pipelineStepId, + const std::string& producerInstanceId, const std::string& beamtime, + const std::string& source, const std::string& stream, + uint64_t fileSize, uint64_t transferTimeInMicroseconds, + uint64_t writeIoTimeInMicroseconds, + uint64_t dbTimeInMicroseconds) override; + + void SendRdsRequestWasMissDataPoint(const std::string& pipelineStepId, const std::string& consumerInstanceId, + const std::string& beamtime, const std::string& source, + const std::string& stream) override; + + void SendReceiverRequestDataPoint(const std::string& pipelineStepId, const std::string& consumerInstanceId, + const std::string& beamtime, const std::string& source, + const std::string& stream, uint64_t fileSize, + uint64_t transferTimeInMicroseconds) override; + + void FillMemoryStats() override; + }; +} + +#endif //ASAPO_RECEIVER_MONITORING_CLIENT_NOOP_H diff --git a/receiver/src/receiver.cpp b/receiver/src/receiver.cpp index 8dc7f7733f7d811870f687acf61b0c75e3e0cead..0cb9b6dc30c6c8ca771b2e303b33b8ee0b2b8232 100644 --- a/receiver/src/receiver.cpp +++ b/receiver/src/receiver.cpp @@ -1,4 +1,5 @@ #include <iostream> +#include <utility> #include "receiver.h" #include "receiver_error.h" #include "connection.h" @@ -8,10 +9,9 @@ namespace asapo { - const int Receiver::kMaxUnacceptedConnectionsBacklog = 5; -Receiver::Receiver(SharedCache cache, KafkaClient* kafkaClient): cache_{cache}, kafka_client_{kafkaClient}, io__{GenerateDefaultIO()}, log__{GetDefaultReceiverLogger()} { +Receiver::Receiver(SharedCache cache, SharedReceiverMonitoringClient monitoring,KafkaClient* kafkaClient): cache_{cache},monitoring_{monitoring}, kafka_client_{kafkaClient}, io__{GenerateDefaultIO()}, log__{GetDefaultReceiverLogger()} { } @@ -55,7 +55,7 @@ void Receiver::StartNewConnectionInSeparateThread(int connection_socket_fd, cons log__->Info(LogMessageWithFields("new connection with producer").Append("origin", HostFromUri(address))); auto thread = io__->NewThread("ConFd:" + std::to_string(connection_socket_fd), [connection_socket_fd, address, this] { - auto connection = std::unique_ptr<Connection>(new Connection(connection_socket_fd, address, cache_, kafka_client_.get(), GetReceiverConfig()->tag)); + auto connection = std::unique_ptr<Connection>(new Connection(connection_socket_fd, address,monitoring_, cache_,kafka_client_.get(), GetReceiverConfig()->tag)); connection->Listen(); }); diff --git a/receiver/src/receiver.h b/receiver/src/receiver.h index a0ff2bb13703ee3c46f3d1f08f113cc1140de7bd..5af25a2351cf8a7eb6987c5500a25c7bbbd7cd85 100644 --- a/receiver/src/receiver.h +++ b/receiver/src/receiver.h @@ -9,6 +9,7 @@ #include "connection.h" #include "receiver_logger.h" #include "data_cache.h" +#include "monitoring/receiver_monitoring_client.h" namespace asapo { @@ -20,12 +21,13 @@ class Receiver { void ProcessConnections(Error* err); std::vector<std::unique_ptr<std::thread>> threads_; SharedCache cache_; + SharedReceiverMonitoringClient monitoring_; std::unique_ptr<KafkaClient> kafka_client_; public: static const int kMaxUnacceptedConnectionsBacklog;//TODO: Read from config Receiver(const Receiver&) = delete; Receiver& operator=(const Receiver&) = delete; - Receiver(SharedCache cache, KafkaClient* kafkaClient); + Receiver(SharedCache cache,SharedReceiverMonitoringClient monitoring,KafkaClient* kafkaClient); void Listen(std::string listener_address, Error* err, bool exit_after_first_connection = false); std::unique_ptr<IO> io__; diff --git a/receiver/src/receiver_config.cpp b/receiver/src/receiver_config.cpp index d6f7ca0ac6fad3809fc392754c49e2bf2fa63d54..6466d39a040f82cd6f8f60f64f44a0520d5a2959 100644 --- a/receiver/src/receiver_config.cpp +++ b/receiver/src/receiver_config.cpp @@ -19,6 +19,8 @@ Error ReceiverConfigManager::ReadConfigFromFile(std::string file_name) { std::vector<std::string> kafkaTopics; + // New monitoring + (err = parser.GetString("MonitoringServer", &config.monitoring_server_url)) || (err = parser.GetString("PerformanceDbServer", &config.performance_db_uri)) || (err = parser.GetBool("MonitorPerformance", &config.monitor_performance)) || (err = parser.GetUInt64("ListenPort", &config.listen_port)) || diff --git a/receiver/src/receiver_config.h b/receiver/src/receiver_config.h index d065ed2958921e21441a4bc28ef5c5217c7e3af5..728f6d81c698f4bfd41e98477f1c943dfd3bf334 100644 --- a/receiver/src/receiver_config.h +++ b/receiver/src/receiver_config.h @@ -14,6 +14,7 @@ namespace asapo { struct ReceiverConfig { std::string performance_db_uri; std::string performance_db_name; + std::string monitoring_server_url; bool monitor_performance = false; std::string database_uri; uint64_t listen_port = 0; diff --git a/receiver/src/receiver_data_server/net_server/fabric_rds_request.cpp b/receiver/src/receiver_data_server/net_server/fabric_rds_request.cpp index 0edde1019f0301655b758ddc76a82b46074ec85f..583e589d4b168f8f43642a7fcd773fef5cbcfcef 100644 --- a/receiver/src/receiver_data_server/net_server/fabric_rds_request.cpp +++ b/receiver/src/receiver_data_server/net_server/fabric_rds_request.cpp @@ -1,10 +1,12 @@ #include "fabric_rds_request.h" +#include <utility> + using namespace asapo; FabricRdsRequest::FabricRdsRequest(const GenericRequestHeader& header, - fabric::FabricAddress sourceId, fabric::FabricMessageId messageId) - : ReceiverDataServerRequest(header, sourceId), message_id{messageId} { + fabric::FabricAddress sourceId, fabric::FabricMessageId messageId, RequestStatisticsPtr statistics) + : ReceiverDataServerRequest(header, sourceId, std::move(statistics)), message_id{messageId} { } diff --git a/receiver/src/receiver_data_server/net_server/fabric_rds_request.h b/receiver/src/receiver_data_server/net_server/fabric_rds_request.h index dbf05690ac7038b0cbce25f061959df9868e5ee7..2925221399b33abd2f32097af88dff94263ea7a0 100644 --- a/receiver/src/receiver_data_server/net_server/fabric_rds_request.h +++ b/receiver/src/receiver_data_server/net_server/fabric_rds_request.h @@ -9,7 +9,7 @@ namespace asapo { class FabricRdsRequest : public ReceiverDataServerRequest { public: explicit FabricRdsRequest(const GenericRequestHeader& header, fabric::FabricAddress source_id, - fabric::FabricMessageId messageId); + fabric::FabricMessageId messageId, RequestStatisticsPtr statistics); fabric::FabricMessageId message_id; const fabric::MemoryRegionDetails* GetMemoryRegion() const; }; diff --git a/receiver/src/receiver_data_server/net_server/rds_fabric_server.cpp b/receiver/src/receiver_data_server/net_server/rds_fabric_server.cpp index 4df46716de5beb55056628bdbe6784685b255b9a..07b37856ab0bd46631ad833e9186ef28adf4e9b7 100644 --- a/receiver/src/receiver_data_server/net_server/rds_fabric_server.cpp +++ b/receiver/src/receiver_data_server/net_server/rds_fabric_server.cpp @@ -8,8 +8,8 @@ using namespace asapo; RdsFabricServer::RdsFabricServer(std::string listenAddress, - const AbstractLogger* logger): factory__(fabric::GenerateDefaultFabricFactory()), io__{GenerateDefaultIO()}, - log__{logger}, listenAddress_(std::move(listenAddress)) { + const AbstractLogger* logger, asapo::SharedReceiverMonitoringClient monitoring): factory__(fabric::GenerateDefaultFabricFactory()), io__{GenerateDefaultIO()}, + log__{logger}, listenAddress_(std::move(listenAddress)), monitoring_{monitoring} { } @@ -40,12 +40,16 @@ GenericRequests RdsFabricServer::GetNewRequests(Error* err) { fabric::FabricAddress srcAddress; fabric::FabricMessageId messageId; + RequestStatisticsPtr statistics{new RequestStatistics}; + // We cannot measure time here, since it is a blocking call :/ + GenericRequestHeader header; server__->RecvAny(&srcAddress, &messageId, &header, sizeof(header), err); if (*err) { return {}; // empty result } - auto requestPtr = new FabricRdsRequest(header, srcAddress, messageId); + statistics->AddIncomingBytes(sizeof(header)); + auto requestPtr = new FabricRdsRequest(header, srcAddress, messageId, std::move(statistics)); GenericRequests genericRequests; genericRequests.emplace_back(GenericRequestPtr(requestPtr)); @@ -77,3 +81,7 @@ Error RdsFabricServer::SendResponseAndSlotData(const ReceiverDataServerRequest* void RdsFabricServer::HandleAfterError(uint64_t) { /* Do nothing? */ } + +SharedReceiverMonitoringClient RdsFabricServer::Monitoring() { + return monitoring_; +} diff --git a/receiver/src/receiver_data_server/net_server/rds_fabric_server.h b/receiver/src/receiver_data_server/net_server/rds_fabric_server.h index 7114670bde5545588fd847b76cd36a2b0b9d5b25..b8d67ed54e2202f482efed32a319fd71131c3535 100644 --- a/receiver/src/receiver_data_server/net_server/rds_fabric_server.h +++ b/receiver/src/receiver_data_server/net_server/rds_fabric_server.h @@ -8,7 +8,7 @@ namespace asapo { class RdsFabricServer : public RdsNetServer { public: - explicit RdsFabricServer(std::string listenAddress, const AbstractLogger* logger); + explicit RdsFabricServer(std::string listenAddress, const AbstractLogger* logger, asapo::SharedReceiverMonitoringClient monitoring); ~RdsFabricServer() override; // modified in testings to mock system calls, otherwise do not touch @@ -18,6 +18,7 @@ class RdsFabricServer : public RdsNetServer { std::unique_ptr<fabric::FabricServer> server__; private: std::string listenAddress_; + SharedReceiverMonitoringClient monitoring_; public: // NetServer implementation Error Initialize() override; @@ -29,6 +30,8 @@ class RdsFabricServer : public RdsNetServer { const CacheMeta* cache_slot) override; void HandleAfterError(uint64_t source_id) override; + + SharedReceiverMonitoringClient Monitoring() override; }; } diff --git a/receiver/src/receiver_data_server/net_server/rds_net_server.h b/receiver/src/receiver_data_server/net_server/rds_net_server.h index 83deeb823d45386178b6fb381412fb364835543f..3d9c908e80bd46ebca4fd81786fc665eff90815f 100644 --- a/receiver/src/receiver_data_server/net_server/rds_net_server.h +++ b/receiver/src/receiver_data_server/net_server/rds_net_server.h @@ -4,6 +4,7 @@ #include "../../data_cache.h" #include "asapo/common/error.h" #include "../receiver_data_server_request.h" +#include "../../monitoring/receiver_monitoring_client.h" namespace asapo { @@ -21,6 +22,8 @@ class RdsNetServer { const CacheMeta* cache_slot) = 0; virtual void HandleAfterError(uint64_t source_id) = 0; virtual ~RdsNetServer() = default; + + virtual SharedReceiverMonitoringClient Monitoring() = 0; }; using RdsNetServerPtr = std::unique_ptr<asapo::RdsNetServer>; diff --git a/receiver/src/receiver_data_server/net_server/rds_tcp_server.cpp b/receiver/src/receiver_data_server/net_server/rds_tcp_server.cpp index 6f24fc62a6555b94540efb41a01d1c11b0794cc2..57b75e23ded55c582b1a81f3e5bf12b7fe753019 100644 --- a/receiver/src/receiver_data_server/net_server/rds_tcp_server.cpp +++ b/receiver/src/receiver_data_server/net_server/rds_tcp_server.cpp @@ -1,4 +1,6 @@ #include "rds_tcp_server.h" + +#include <utility> #include "../receiver_data_server_logger.h" #include "../receiver_data_server_error.h" @@ -7,9 +9,9 @@ namespace asapo { -RdsTcpServer::RdsTcpServer(std::string address, const AbstractLogger *logger) : io__{GenerateDefaultIO()}, + RdsTcpServer::RdsTcpServer(std::string address, const AbstractLogger* logger, asapo::SharedReceiverMonitoringClient monitoring) : io__{GenerateDefaultIO()}, log__{logger}, - address_{std::move(address)} {} + address_{std::move(address)}, monitoring_{std::move(monitoring)} {} Error RdsTcpServer::Initialize() { if (master_socket_ != kDisconnectedSocketDescriptor) { @@ -28,7 +30,7 @@ Error RdsTcpServer::Initialize() { return nullptr; } -ListSocketDescriptors RdsTcpServer::GetActiveSockets(Error *err) { +ListSocketDescriptors RdsTcpServer::GetActiveSockets(Error* err) { std::vector<std::string> new_connections; auto sockets = io__->WaitSocketsActivity(master_socket_, &sockets_to_listen_, &new_connections, err); for (auto &connection: new_connections) { @@ -44,12 +46,18 @@ void RdsTcpServer::CloseSocket(SocketDescriptor socket) { io__->CloseSocket(socket, nullptr); } -ReceiverDataServerRequestPtr RdsTcpServer::ReadRequest(SocketDescriptor socket, Error *err) { +ReceiverDataServerRequestPtr RdsTcpServer::ReadRequest(SocketDescriptor socket, Error* err) { GenericRequestHeader header; + Error io_err; *err = nullptr; - io__->Receive(socket, &header, - sizeof(GenericRequestHeader), &io_err); + + RequestStatisticsPtr statistics{new RequestStatistics}; + statistics->StartTimer(kNetworkIncoming); + uint64_t bytesReceived = io__->Receive(socket, &header, sizeof(GenericRequestHeader), &io_err); + statistics->StopTimer(); + statistics->AddIncomingBytes(bytesReceived); + if (io_err == GeneralErrorTemplates::kEndOfFile) { *err = std::move(io_err); CloseSocket(socket); @@ -59,12 +67,12 @@ ReceiverDataServerRequestPtr RdsTcpServer::ReadRequest(SocketDescriptor socket, (*err)->AddDetails("origin",io__->AddressFromSocket(socket)); return nullptr; } - return ReceiverDataServerRequestPtr{new ReceiverDataServerRequest{header, (uint64_t) socket}}; + return ReceiverDataServerRequestPtr{new ReceiverDataServerRequest{header, (uint64_t) socket, std::move(statistics)}}; } -GenericRequests RdsTcpServer::ReadRequests(const ListSocketDescriptors &sockets) { +GenericRequests RdsTcpServer::ReadRequests(const ListSocketDescriptors& sockets) { GenericRequests requests; - for (auto client: sockets) { + for (auto client : sockets) { Error err; auto request = ReadRequest(client, &err); if (err) { @@ -78,7 +86,7 @@ GenericRequests RdsTcpServer::ReadRequests(const ListSocketDescriptors &sockets) return requests; } -GenericRequests RdsTcpServer::GetNewRequests(Error *err) { +GenericRequests RdsTcpServer::GetNewRequests(Error* err) { auto sockets = GetActiveSockets(err); if (*err) { return {}; @@ -89,7 +97,7 @@ GenericRequests RdsTcpServer::GetNewRequests(Error *err) { RdsTcpServer::~RdsTcpServer() { if (!io__) return; // need for test that override io__ to run - for (auto client: sockets_to_listen_) { + for (auto client : sockets_to_listen_) { io__->CloseSocket(client, nullptr); } io__->CloseSocket(master_socket_, nullptr); @@ -128,4 +136,8 @@ RdsTcpServer::SendResponseAndSlotData(const ReceiverDataServerRequest *request, return err; } +SharedReceiverMonitoringClient RdsTcpServer::Monitoring() { + return monitoring_; +} + } diff --git a/receiver/src/receiver_data_server/net_server/rds_tcp_server.h b/receiver/src/receiver_data_server/net_server/rds_tcp_server.h index a142ff833f2f8eefcf6dd64b18b834fabdb0cc6e..bac28d27155f05024a40c791f15da6991aeb8eb9 100644 --- a/receiver/src/receiver_data_server/net_server/rds_tcp_server.h +++ b/receiver/src/receiver_data_server/net_server/rds_tcp_server.h @@ -11,7 +11,7 @@ const int kMaxPendingConnections = 5; class RdsTcpServer : public RdsNetServer { public: - explicit RdsTcpServer(std::string address, const AbstractLogger* logger); + explicit RdsTcpServer(std::string address, const AbstractLogger* logger, asapo::SharedReceiverMonitoringClient monitoring); ~RdsTcpServer() override; Error Initialize() override; @@ -22,6 +22,9 @@ class RdsTcpServer : public RdsNetServer { Error SendResponseAndSlotData(const ReceiverDataServerRequest* request, const GenericNetworkResponse* response, const CacheMeta* cache_slot) override; void HandleAfterError(uint64_t source_id) override; + + SharedReceiverMonitoringClient Monitoring() override; + std::unique_ptr<IO> io__; const AbstractLogger* log__; private: @@ -32,6 +35,7 @@ class RdsTcpServer : public RdsNetServer { SocketDescriptor master_socket_{kDisconnectedSocketDescriptor}; ListSocketDescriptors sockets_to_listen_; std::string address_; + asapo::SharedReceiverMonitoringClient monitoring_; }; } diff --git a/receiver/src/receiver_data_server/receiver_data_server_request.cpp b/receiver/src/receiver_data_server/receiver_data_server_request.cpp index 41d1477c0f29aba325e247190c4ef431d0e3a1fd..399efd1c86f4529b8c00349de99b625074305d9b 100644 --- a/receiver/src/receiver_data_server/receiver_data_server_request.cpp +++ b/receiver/src/receiver_data_server/receiver_data_server_request.cpp @@ -1,13 +1,15 @@ #include "receiver_data_server_request.h" + +#include <utility> #include "receiver_data_server.h" namespace asapo { -ReceiverDataServerRequest::ReceiverDataServerRequest(GenericRequestHeader header, uint64_t source_id) : - GenericRequest(header, 0), - source_id{source_id} { +ReceiverDataServerRequest::ReceiverDataServerRequest(const GenericRequestHeader& header, uint64_t source_id, RequestStatisticsPtr statistics) : + GenericRequest(header, 0), statistics_{std::move(statistics)}, source_id{source_id} { } - - +RequestStatistics* ReceiverDataServerRequest::GetStatistics() { + return statistics_.get(); +} } diff --git a/receiver/src/receiver_data_server/receiver_data_server_request.h b/receiver/src/receiver_data_server/receiver_data_server_request.h index 12331467fceb1e4a90cbc3071700dd3b76ad8cea..e1f8435d83524126fa0e814109571016322aba0f 100644 --- a/receiver/src/receiver_data_server/receiver_data_server_request.h +++ b/receiver/src/receiver_data_server/receiver_data_server_request.h @@ -4,17 +4,22 @@ #include "asapo/common/networking.h" #include "asapo/request/request.h" +#include "../statistics/instanced_statistics_provider.h" namespace asapo { class RdsNetServer; class ReceiverDataServerRequest : public GenericRequest { + private: + RequestStatisticsPtr statistics_; public: - explicit ReceiverDataServerRequest(GenericRequestHeader header, uint64_t source_id); + explicit ReceiverDataServerRequest(const GenericRequestHeader& header, uint64_t source_id, RequestStatisticsPtr statistics); + ~ReceiverDataServerRequest() override = default; + const uint64_t source_id; - ~ReceiverDataServerRequest() = default; + RequestStatistics* GetStatistics(); }; using ReceiverDataServerRequestPtr = std::unique_ptr<ReceiverDataServerRequest>; diff --git a/receiver/src/receiver_data_server/request_handler/receiver_data_server_request_handler.cpp b/receiver/src/receiver_data_server/request_handler/receiver_data_server_request_handler.cpp index 3ecec5d8811bb8551e6c671e08dc8befa9a2ecab..b0abe166176f7bdadf41de31b3ac009c4f565a6d 100644 --- a/receiver/src/receiver_data_server/request_handler/receiver_data_server_request_handler.cpp +++ b/receiver/src/receiver_data_server/request_handler/receiver_data_server_request_handler.cpp @@ -2,6 +2,8 @@ #include "../receiver_data_server_error.h" #include "asapo/common/internal/version.h" +#include <sstream> + namespace asapo { ReceiverDataServerRequestHandler::ReceiverDataServerRequestHandler(RdsNetServer* server, @@ -10,7 +12,6 @@ ReceiverDataServerRequestHandler::ReceiverDataServerRequestHandler(RdsNetServer* } - bool ReceiverDataServerRequestHandler::CheckRequest(const ReceiverDataServerRequest* request, NetworkErrorCode* code) { if (request->header.op_code != kOpcodeGetBufferData) { *code = kNetErrorWrongRequest; @@ -62,14 +63,39 @@ bool ReceiverDataServerRequestHandler::ProcessRequestUnlocked(GenericRequest* re return true; } + auto startTime = ReceiverMonitoringClient::HelperTimeNow(); CacheMeta* meta = GetSlotAndLock(receiver_request); if (!meta) { SendResponse(receiver_request, kNetErrorNoData); - return true; + } else { + HandleValidRequest(receiver_request, meta); + data_cache_->UnlockSlot(meta); + } + auto timeTookToSend = ReceiverMonitoringClient::HelperTimeDiffInMicroseconds(startTime); + + auto requestSenderDetails = ExtractMonitoringInfoFromRequest(request); + if (requestSenderDetails) { + auto monitoring = server_->Monitoring(); + if (meta) { + monitoring->SendReceiverRequestDataPoint( + requestSenderDetails->pipeline_step_id, + requestSenderDetails->instance_id, + requestSenderDetails->beamtime, + requestSenderDetails->source, + requestSenderDetails->stream, + meta->size, + timeTookToSend + ); + } else { + monitoring->SendRdsRequestWasMissDataPoint( + requestSenderDetails->pipeline_step_id, + requestSenderDetails->instance_id, + requestSenderDetails->beamtime, + requestSenderDetails->source, + requestSenderDetails->stream); + } } - HandleValidRequest(receiver_request, meta); - data_cache_->UnlockSlot(meta); return true; } @@ -122,4 +148,38 @@ void ReceiverDataServerRequestHandler::HandleValidRequest(const ReceiverDataServ } } +// https://stackoverflow.com/a/46931770/ +std::vector<std::string> split(const std::string& s, const std::string& delimiter) { + size_t pos_start = 0, pos_end, delim_len = delimiter.length(); + std::string token; + std::vector<std::string> res; + + while ((pos_end = s.find (delimiter, pos_start)) != std::string::npos) { + token = s.substr (pos_start, pos_end - pos_start); + pos_start = pos_end + delim_len; + res.push_back (token); + } + + res.push_back (s.substr (pos_start)); + return res; +} +std::unique_ptr<RequestSenderDetails> ReceiverDataServerRequestHandler::ExtractMonitoringInfoFromRequest(const GenericRequest* request) { + std::string details(request->header.stream); + + // Format: "instanceId§piplineStepId§beamtime§source§stream" + std::vector<std::string> detailsParts = split(details, "§"); + + if (detailsParts.size() != 5) { + return nullptr; + } + + return std::unique_ptr<RequestSenderDetails>(new RequestSenderDetails{ + detailsParts[0], + detailsParts[1], + detailsParts[2], + detailsParts[3], + detailsParts[4] + }); +} + } diff --git a/receiver/src/receiver_data_server/request_handler/receiver_data_server_request_handler.h b/receiver/src/receiver_data_server/request_handler/receiver_data_server_request_handler.h index 71d63ad22d01a4e19d3004938cf456ad6ba1a8d7..a3abd237e67e3967543def491cc4fa6620f94b97 100644 --- a/receiver/src/receiver_data_server/request_handler/receiver_data_server_request_handler.h +++ b/receiver/src/receiver_data_server/request_handler/receiver_data_server_request_handler.h @@ -10,6 +10,15 @@ namespace asapo { +// this information comes from the consumer +struct RequestSenderDetails { + std::string instance_id; + std::string pipeline_step_id; + std::string beamtime; + std::string source; + std::string stream; // from the broker from the database (extra record) +}; + class ReceiverDataServerRequestHandler: public RequestHandler { public: explicit ReceiverDataServerRequestHandler(RdsNetServer* server, DataCache* data_cache, Statistics* statistics); @@ -32,6 +41,8 @@ class ReceiverDataServerRequestHandler: public RequestHandler { void HandleInvalidRequest(const ReceiverDataServerRequest* receiver_request, NetworkErrorCode code); void HandleValidRequest(const ReceiverDataServerRequest* receiver_request, const CacheMeta* meta); + + static std::unique_ptr<RequestSenderDetails> ExtractMonitoringInfoFromRequest(const GenericRequest* request); }; } diff --git a/receiver/src/receiver_logger.cpp b/receiver/src/receiver_logger.cpp index 05edc430a5d22542e9d7e6029214fb01a32f8326..02139f7d926bc98303c64271d34a1b4714c9f274 100644 --- a/receiver/src/receiver_logger.cpp +++ b/receiver/src/receiver_logger.cpp @@ -11,6 +11,11 @@ AbstractLogger* GetDefaultReceiverLogger() { return logger.get(); } +AbstractLogger* GetDefaultReceiverMonitoringLogger() { + static Logger logger = asapo::CreateDefaultLoggerBin("receiver_monitoring"); + return logger.get(); +} + void AppendIdToLogMessageIfNeeded(const Request* request, LogMessageWithFields* msg) { switch (request->GetOpCode()) { diff --git a/receiver/src/receiver_logger.h b/receiver/src/receiver_logger.h index e1cd160448d8ff500df6549ee0f8c316f48c535d..f745d51a7ddac8147c246780022755a80746fcc3 100644 --- a/receiver/src/receiver_logger.h +++ b/receiver/src/receiver_logger.h @@ -9,6 +9,7 @@ struct AuthorizationData; class Request; AbstractLogger* GetDefaultReceiverLogger(); +AbstractLogger* GetDefaultReceiverMonitoringLogger(); LogMessageWithFields RequestLog(std::string message, const Request* request); LogMessageWithFields AuthorizationLog(std::string message, const Request* request, const AuthorizationData* data); diff --git a/receiver/src/request.cpp b/receiver/src/request.cpp index fc43846aad597f95f93ddf8c39de796dc1ffba8d..35ee43bd5c7aec3aeee7f2c26c6e3e82f6005a5f 100644 --- a/receiver/src/request.cpp +++ b/receiver/src/request.cpp @@ -1,4 +1,6 @@ #include "request.h" + +#include <utility> #include "asapo/io/io_factory.h" #include "request_handler/request_handler_db_check_request.h" #include "receiver_logger.h" @@ -7,10 +9,11 @@ namespace asapo { Request::Request(const GenericRequestHeader& header, SocketDescriptor socket_fd, std::string origin_uri, DataCache* cache, - const RequestHandlerDbCheckRequest* db_check_handler) : io__{GenerateDefaultIO()}, - cache__{cache}, log__{GetDefaultReceiverLogger()},request_header_(header), - socket_fd_{socket_fd}, origin_uri_{std::move(origin_uri)}, - check_duplicate_request_handler_{db_check_handler} { + const RequestHandlerDbCheckRequest* db_check_handler, + RequestStatisticsPtr statistics) : io__{GenerateDefaultIO()}, + cache__{cache}, log__{GetDefaultReceiverLogger()}, statistics_{std::move(statistics)}, request_header_(header), + socket_fd_{socket_fd}, origin_uri_{std::move(origin_uri)}, + check_duplicate_request_handler_{db_check_handler} { origin_host_ = HostFromUri(origin_uri_); } @@ -29,7 +32,7 @@ Error Request::PrepareDataBufferFromMemory() { Error Request::PrepareDataBufferFromCache() { Error err; CacheMeta* slot; - data_ptr = cache__->GetFreeSlotAndLock(request_header_.data_size, &slot, &err); + data_ptr = cache__->GetFreeSlotAndLock(request_header_.data_size, &slot, GetBeamtimeId(), GetDataSource(), GetStream(), &err); if (err == nullptr) { slot_meta_ = slot; } else { @@ -47,21 +50,26 @@ Error Request::PrepareDataBufferAndLockIfNeeded() { auto err = PrepareDataBufferFromCache(); if (err) { log__->Warning(LogMessageWithFields(err).Append(RequestLog("", this))); + cache__ = nullptr; return PrepareDataBufferFromMemory(); } return nullptr; } -Error Request::Handle(ReceiverStatistics* statistics) { +Error Request::Handle() { Error err; for (auto handler : handlers_) { - statistics->StartTimer(handler->GetStatisticEntity()); + if (statistics_) { + statistics_->StartTimer(handler->GetStatisticEntity()); + } err = handler->ProcessRequest(this); + if (statistics_) { + statistics_->StopTimer(); + } if (err) { break; } - statistics->StopTimer(); } UnlockDataBufferIfNeeded(); return err; @@ -114,6 +122,20 @@ std::string Request::GetApiVersion() const { return request_header_.api_version; } +const std::string& Request::GetProducerInstanceId() const { + return producer_instance_id_; +} +void Request::SetProducerInstanceId(std::string producer_instance_id) { + producer_instance_id_ = std::move(producer_instance_id); +} + +const std::string& Request::GetPipelineStepId() const { + return pipeline_step_id_; +} +void Request::SetPipelineStepId(std::string pipeline_step_id) { + pipeline_step_id_ = std::move(pipeline_step_id); +} + const std::string& Request::GetOriginUri() const { return origin_uri_; } @@ -124,6 +146,7 @@ void Request::SetBeamtimeId(std::string beamtime_id) { beamtime_id_ = std::move(beamtime_id); } + Opcode Request::GetOpCode() const { return request_header_.op_code; } @@ -225,6 +248,14 @@ SourceType Request::GetSourceType() const { return source_type_; } +RequestStatistics* Request::GetStatistics() { + if (statistics_) { + return statistics_.get(); + } else { + return nullptr; + } +} + const std::string& Request::GetOriginHost() const { return origin_host_; } diff --git a/receiver/src/request.h b/receiver/src/request.h index ba5bb3e17c77e4324d2d2c31ebdc7d8ea92784e6..4d1cf79c19d9538c087431592fbe20c69218135b 100644 --- a/receiver/src/request.h +++ b/receiver/src/request.h @@ -12,6 +12,7 @@ #include "data_cache.h" #include "asapo/preprocessor/definitions.h" +#include "statistics/instanced_statistics_provider.h" #include "asapo/logger/logger.h" namespace asapo { @@ -27,11 +28,12 @@ class RequestHandlerDbCheckRequest; class Request { public: - ASAPO_VIRTUAL Error Handle(ReceiverStatistics*); + ASAPO_VIRTUAL Error Handle(); ASAPO_VIRTUAL ~Request() = default; Request() = delete; Request(const GenericRequestHeader& request_header, SocketDescriptor socket_fd, std::string origin_uri, - DataCache* cache, const RequestHandlerDbCheckRequest* db_check_handler); + DataCache* cache, const RequestHandlerDbCheckRequest* db_check_handler, + RequestStatisticsPtr statistics); ASAPO_VIRTUAL void AddHandler(const ReceiverRequestHandler*); ASAPO_VIRTUAL const RequestHandlerList& GetListHandlers() const; ASAPO_VIRTUAL uint64_t GetDataSize() const; @@ -44,6 +46,10 @@ class Request { ASAPO_VIRTUAL Opcode GetOpCode() const; ASAPO_VIRTUAL const char* GetMessage() const; + ASAPO_VIRTUAL const std::string& GetProducerInstanceId() const; + ASAPO_VIRTUAL void SetProducerInstanceId(std::string producer_instance_id); + ASAPO_VIRTUAL const std::string& GetPipelineStepId() const; + ASAPO_VIRTUAL void SetPipelineStepId(std::string pipeline_step_id); ASAPO_VIRTUAL const std::string& GetOriginUri() const; ASAPO_VIRTUAL const std::string& GetOriginHost() const; ASAPO_VIRTUAL const std::string& GetMetaData() const; @@ -77,15 +83,20 @@ class Request { ASAPO_VIRTUAL ResponseMessageType GetResponseMessageType() const; ASAPO_VIRTUAL const std::string& GetResponseMessage() const; ASAPO_VIRTUAL Error CheckForDuplicates(); + ASAPO_VIRTUAL RequestStatistics* GetStatistics(); const AbstractLogger* log__; private: Error PrepareDataBufferFromMemory(); Error PrepareDataBufferFromCache(); + private: + RequestStatisticsPtr statistics_; const GenericRequestHeader request_header_; const SocketDescriptor socket_fd_; MessageData data_buffer_; void* data_ptr; RequestHandlerList handlers_; + std::string producer_instance_id_; + std::string pipeline_step_id_; std::string origin_uri_; std::string origin_host_; std::string beamtime_id_; diff --git a/receiver/src/request_handler/authorization_client.cpp b/receiver/src/request_handler/authorization_client.cpp index 2a4ab650ee005ebc3bc949e60409bed9f96e99f6..c0e876d93c45f22b237187c064aa9231d88843bf 100644 --- a/receiver/src/request_handler/authorization_client.cpp +++ b/receiver/src/request_handler/authorization_client.cpp @@ -4,6 +4,8 @@ #include "asapo/json_parser/json_parser.h" +#include "asapo/common/internal/version.h" + #include "../receiver_config.h" #include "../receiver_logger.h" #include "../request.h" @@ -11,8 +13,18 @@ namespace asapo { std::string GetRequestString(const Request *request, const std::string &source_credentials) { - std::string request_string = std::string("{\"SourceCredentials\":\"") + - source_credentials + "\",\"OriginHost\":\"" + request->GetOriginUri() + "\"}"; + auto api_version = VersionToNumber(request->GetApiVersion()); + std::string request_string; + if (api_version < 6) { // old approach, need to add instanceId and step, deprecates 01.03.2023 + std::string updated_source_credentials_prefix = source_credentials; + std::string uri = request->GetOriginUri(); + updated_source_credentials_prefix.insert(source_credentials.find("%")+1,uri+"%DefaultStep%"); + request_string = std::string("{\"SourceCredentials\":\"") + + updated_source_credentials_prefix + "\",\"OriginHost\":\"" + uri + "\"}"; + } else { + request_string = std::string("{\"SourceCredentials\":\"") + + source_credentials + "\",\"OriginHost\":\"" + request->GetOriginUri() + "\"}"; + } return request_string; } @@ -69,6 +81,8 @@ Error ParseServerResponse(const std::string &response, (err = parser.GetString("source-type", &stype)) || (err = parser.GetArrayString("access-types", access_types)) || (err = GetSourceTypeFromString(stype, &data->source_type)) || + (err = parser.GetString("instanceId", &data->producer_instance_id)) || + (err = parser.GetString("pipelineStep", &data->pipeline_step_id)) || (err = parser.GetString("beamline", &data->beamline)); if (err) { return ErrorFromAuthorizationServerResponse(std::move(err), response, code); diff --git a/receiver/src/request_handler/request_factory.cpp b/receiver/src/request_handler/request_factory.cpp index c281e71f1dfa5774c90ea36bb2435beaece35aca..b40207a5b030bc104cf2ed28cb0eb8e0c1754e03 100644 --- a/receiver/src/request_handler/request_factory.cpp +++ b/receiver/src/request_handler/request_factory.cpp @@ -1,5 +1,7 @@ #include "request_factory.h" +#include <utility> + #include "../receiver_config.h" namespace asapo { @@ -68,6 +70,7 @@ Error RequestFactory::AddHandlersToRequest(std::unique_ptr<Request>& request, if (NeedDbHandler(request_header)) { request->AddHandler(&request_handler_dbwrite_); } + request->AddHandler(&request_handler_monitoring_); break; } case Opcode::kOpcodeTransferMetaData: { @@ -111,9 +114,9 @@ Error RequestFactory::AddHandlersToRequest(std::unique_ptr<Request>& request, std::unique_ptr<Request> RequestFactory::GenerateRequest(const GenericRequestHeader& request_header, SocketDescriptor socket_fd, std::string origin_uri, - Error* err) const noexcept { + RequestStatisticsPtr statistics, Error* err) const noexcept { auto request = std::unique_ptr<Request> {new Request{request_header, socket_fd, std::move(origin_uri), cache_.get(), - &request_handler_db_check_} + &request_handler_db_check_, std::move(statistics)} }; *err = AddHandlersToRequest(request, request_header); if (*err) { @@ -122,7 +125,10 @@ std::unique_ptr<Request> RequestFactory::GenerateRequest(const GenericRequestHea return request; } -RequestFactory::RequestFactory(SharedCache cache, KafkaClient* kafka_client) : request_handler_kafka_notify_{kafka_client}, cache_{cache} { +RequestFactory::RequestFactory(SharedReceiverMonitoringClient monitoring, SharedCache cache, KafkaClient* kafka_client) : + monitoring_{std::move(monitoring)},cache_{cache}, + request_handler_monitoring_{monitoring_}, + request_handler_kafka_notify_{kafka_client} { } } diff --git a/receiver/src/request_handler/request_factory.h b/receiver/src/request_handler/request_factory.h index 578e2b342c89ba65754424e46dfab61ddd93a7cf..75c39aa91c08427175d2154d866feac8380a7291 100644 --- a/receiver/src/request_handler/request_factory.h +++ b/receiver/src/request_handler/request_factory.h @@ -8,6 +8,7 @@ #include "request_handler_db_last_stream.h" #include "request_handler_db_delete_stream.h" #include "request_handler_db_get_meta.h" +#include "request_handler_monitoring.h" #include "request_handler_kafka_notify.h" #include "request_handler_file_process.h" @@ -24,13 +25,19 @@ namespace asapo { class RequestFactory { public: - explicit RequestFactory (SharedCache cache, KafkaClient* kafka_client); + explicit RequestFactory (SharedReceiverMonitoringClient monitoring, SharedCache cache, KafkaClient* kafka_client); virtual std::unique_ptr<Request> GenerateRequest(const GenericRequestHeader& request_header, - SocketDescriptor socket_fd, std::string origin_uri, Error* err) const noexcept; + SocketDescriptor socket_fd, std::string origin_uri, + RequestStatisticsPtr statistics, Error* err) const noexcept; virtual ~RequestFactory() = default; private: Error AddHandlersToRequest(std::unique_ptr<Request>& request, const GenericRequestHeader& request_header) const; Error AddReceiveWriteHandlers(std::unique_ptr<Request>& request, const GenericRequestHeader& request_header) const; + + SharedReceiverMonitoringClient monitoring_; + AuthorizationData shared_auth_cache_; + SharedCache cache_; + WriteFileProcessor write_file_processor_; ReceiveFileProcessor receive_file_processor_; RequestHandlerFileProcess request_handler_filewrite_{&write_file_processor_}; @@ -38,6 +45,7 @@ class RequestFactory { RequestHandlerReceiveData request_handler_receivedata_; RequestHandlerReceiveMetaData request_handler_receive_metadata_; RequestHandlerDbWrite request_handler_dbwrite_{kDBDataCollectionNamePrefix}; + RequestHandlerMonitoring request_handler_monitoring_; RequestHandlerDbStreamInfo request_handler_db_stream_info_{kDBDataCollectionNamePrefix}; RequestHandlerDbDeleteStream request_handler_delete_stream_{kDBDataCollectionNamePrefix}; RequestHandlerDbLastStream request_handler_db_last_stream_{kDBDataCollectionNamePrefix}; @@ -46,9 +54,8 @@ class RequestFactory { RequestHandlerInitialAuthorization request_handler_initial_authorize_{&shared_auth_cache_}; RequestHandlerSecondaryAuthorization request_handler_secondary_authorize_{&shared_auth_cache_}; RequestHandlerDbCheckRequest request_handler_db_check_{kDBDataCollectionNamePrefix}; + RequestHandlerKafkaNotify request_handler_kafka_notify_; - SharedCache cache_; - AuthorizationData shared_auth_cache_; bool ReceiveDirectToFile(const GenericRequestHeader& request_header) const; Error AddReceiveDirectToFileHandler(std::unique_ptr<Request>& request, const GenericRequestHeader& request_header) const; diff --git a/receiver/src/request_handler/request_handler_authorize.cpp b/receiver/src/request_handler/request_handler_authorize.cpp index bb158c38e4d168ea1d71292edc79091f196e02a7..d996c997873a30097f5913574dfe009c7ff57327 100644 --- a/receiver/src/request_handler/request_handler_authorize.cpp +++ b/receiver/src/request_handler/request_handler_authorize.cpp @@ -26,10 +26,12 @@ RequestHandlerAuthorize::RequestHandlerAuthorize(AuthorizationData* authorizatio } StatisticEntity RequestHandlerAuthorize::GetStatisticEntity() const { - return StatisticEntity::kNetwork; + return StatisticEntity::kNetworkIncoming; } void RequestHandlerAuthorize::SetRequestFields(Request* request) const { + request->SetPipelineStepId(authorization_cache_->pipeline_step_id); + request->SetProducerInstanceId(authorization_cache_->producer_instance_id); request->SetBeamtimeId(authorization_cache_->beamtime_id); request->SetBeamline(authorization_cache_->beamline); request->SetDataSource(authorization_cache_->data_source); diff --git a/receiver/src/request_handler/request_handler_db_write.cpp b/receiver/src/request_handler/request_handler_db_write.cpp index 14e348395aae1e424ff2407c92e71099a833d76a..c4d4529d30369c88144ae9b1808310d630d25f05 100644 --- a/receiver/src/request_handler/request_handler_db_write.cpp +++ b/receiver/src/request_handler/request_handler_db_write.cpp @@ -79,6 +79,7 @@ MessageMeta RequestHandlerDbWrite::PrepareMessageMeta(const Request* request) co message_meta.size = request->GetDataSize(); message_meta.id = request->GetDataID(); message_meta.buf_id = request->GetSlotId(); + message_meta.stream = request->GetStream(); message_meta.source = GetReceiverConfig()->dataserver.advertise_uri; message_meta.metadata = request->GetMetaData(); message_meta.timestamp = std::chrono::system_clock::now(); diff --git a/receiver/src/request_handler/request_handler_kafka_notify.cpp b/receiver/src/request_handler/request_handler_kafka_notify.cpp index 7ab5373b9961bfe2b23523c27a68403d24c05b21..d99cc2bef4d8b9be0fcbc630af2969c9ea4f8269 100644 --- a/receiver/src/request_handler/request_handler_kafka_notify.cpp +++ b/receiver/src/request_handler/request_handler_kafka_notify.cpp @@ -25,7 +25,7 @@ Error RequestHandlerKafkaNotify::ProcessRequest(Request* request) const { } StatisticEntity RequestHandlerKafkaNotify::GetStatisticEntity() const { - return StatisticEntity::kNetwork; + return StatisticEntity::kNetworkOutgoing; } RequestHandlerKafkaNotify::RequestHandlerKafkaNotify(KafkaClient* kafka_client) : kafka_client_{kafka_client} { diff --git a/receiver/src/request_handler/request_handler_monitoring.cpp b/receiver/src/request_handler/request_handler_monitoring.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7ba548dd812d40c85b7474f19d040c00dc7de2f8 --- /dev/null +++ b/receiver/src/request_handler/request_handler_monitoring.cpp @@ -0,0 +1,35 @@ +#include "request_handler_monitoring.h" +#include "../request.h" + +#include <utility> + +namespace asapo { + +RequestHandlerMonitoring::RequestHandlerMonitoring(asapo::SharedReceiverMonitoringClient monitoring) : monitoring_{monitoring} { +} + +StatisticEntity RequestHandlerMonitoring::GetStatisticEntity() const { + return kMonitoring; +} + +Error RequestHandlerMonitoring::ProcessRequest(Request* request) const { + auto stats = request->GetStatistics(); + if (!stats) { + return nullptr; + } + monitoring_->SendProducerToReceiverTransferDataPoint( + request->GetPipelineStepId(), + request->GetProducerInstanceId(), + request->GetBeamtimeId(), + request->GetDataSource(), + request->GetStream(), + stats->GetIncomingBytes(), + stats->GetElapsedMicrosecondsCount(StatisticEntity::kNetworkIncoming), + stats->GetElapsedMicrosecondsCount(StatisticEntity::kDisk), + stats->GetElapsedMicrosecondsCount(StatisticEntity::kDatabase) + ); + + return nullptr; +} + +} diff --git a/receiver/src/request_handler/request_handler_monitoring.h b/receiver/src/request_handler/request_handler_monitoring.h new file mode 100644 index 0000000000000000000000000000000000000000..005486c83f7d50080bf75d0eb1cc64388b22b263 --- /dev/null +++ b/receiver/src/request_handler/request_handler_monitoring.h @@ -0,0 +1,28 @@ +#ifndef ASAPO_REQUEST_HANDLER_SEND_MONITORING_H +#define ASAPO_REQUEST_HANDLER_SEND_MONITORING_H + +#include "request_handler.h" +#include "asapo/logger/logger.h" + +#include "asapo/io/io.h" +#include "../monitoring/receiver_monitoring_client.h" + +namespace asapo { + + class RequestHandlerMonitoring final: public ReceiverRequestHandler { + private: + SharedReceiverMonitoringClient monitoring_; + public: + RequestHandlerMonitoring(SharedReceiverMonitoringClient monitoring); + RequestHandlerMonitoring(const RequestHandlerMonitoring&) = delete; + RequestHandlerMonitoring& operator=(const RequestHandlerMonitoring&) = delete; + + StatisticEntity GetStatisticEntity() const override; + Error ProcessRequest(Request* request) const override; + std::unique_ptr<IO> io__; + const AbstractLogger* log__{}; + }; + +} + +#endif //ASAPO_REQUEST_HANDLER_SEND_MONITORING_H diff --git a/receiver/src/request_handler/request_handler_receive_data.cpp b/receiver/src/request_handler/request_handler_receive_data.cpp index ebd6706dcfea49d8a1ea5debf3bf98c3e914eb6e..94e1946265f5a9106d74a085678e6c0d18077677 100644 --- a/receiver/src/request_handler/request_handler_receive_data.cpp +++ b/receiver/src/request_handler/request_handler_receive_data.cpp @@ -19,7 +19,10 @@ Error RequestHandlerReceiveData::ProcessRequest(Request* request) const { return err; } Error io_err; - io__->Receive(request->GetSocket(), request->GetData(), (size_t) request->GetDataSize(), &io_err); + uint64_t byteCount = io__->Receive(request->GetSocket(), request->GetData(), (size_t) request->GetDataSize(), &io_err); + if (request->GetStatistics()) { + request->GetStatistics()->AddIncomingBytes(byteCount); + } if (io_err) { err = ReceiverErrorTemplates::kProcessingError.Generate("cannot receive data",std::move(io_err)); } @@ -35,7 +38,7 @@ RequestHandlerReceiveData::RequestHandlerReceiveData() : io__{GenerateDefaultIO( } StatisticEntity RequestHandlerReceiveData::GetStatisticEntity() const { - return StatisticEntity::kNetwork; + return StatisticEntity::kNetworkIncoming; } diff --git a/receiver/src/request_handler/request_handler_receive_metadata.cpp b/receiver/src/request_handler/request_handler_receive_metadata.cpp index 6e0826a15012a7875853109d90cf6933d7c3b93f..df783b61a9db2d5135a8f416a7d2076ba7385f68 100644 --- a/receiver/src/request_handler/request_handler_receive_metadata.cpp +++ b/receiver/src/request_handler/request_handler_receive_metadata.cpp @@ -13,7 +13,10 @@ Error RequestHandlerReceiveMetaData::ProcessRequest(Request* request) const { Error err; auto buf = std::unique_ptr<uint8_t[]> {new uint8_t[meta_size]}; - io__->Receive(request->GetSocket(), (void*) buf.get(), meta_size, &err); + uint64_t byteCount = io__->Receive(request->GetSocket(), (void*) buf.get(), meta_size, &err); + if (request->GetStatistics()) { + request->GetStatistics()->AddIncomingBytes(byteCount); + } if (err) { return ReceiverErrorTemplates::kProcessingError.Generate("cannot receive metadata",std::move(err)); } @@ -27,7 +30,7 @@ RequestHandlerReceiveMetaData::RequestHandlerReceiveMetaData() : io__{GenerateDe } StatisticEntity RequestHandlerReceiveMetaData::GetStatisticEntity() const { - return StatisticEntity::kNetwork; + return StatisticEntity::kNetworkIncoming; } diff --git a/receiver/src/request_handler/request_handler_secondary_authorization.cpp b/receiver/src/request_handler/request_handler_secondary_authorization.cpp index 55ded2f08531dfb3e2d3f05f322e016175f2f24e..55d4a6884920890d1f0a6352b78599178c6145da 100644 --- a/receiver/src/request_handler/request_handler_secondary_authorization.cpp +++ b/receiver/src/request_handler/request_handler_secondary_authorization.cpp @@ -30,6 +30,8 @@ bool RequestHandlerSecondaryAuthorization::NeedReauthorize() const { } void RequestHandlerSecondaryAuthorization::SetRequestFields(Request* request) const { + request->SetProducerInstanceId(authorization_cache_->producer_instance_id); + request->SetPipelineStepId(authorization_cache_->pipeline_step_id); request->SetBeamtimeId(authorization_cache_->beamtime_id); request->SetBeamline(authorization_cache_->beamline); request->SetDataSource(authorization_cache_->data_source); diff --git a/receiver/src/request_handler/requests_dispatcher.cpp b/receiver/src/request_handler/requests_dispatcher.cpp index e416ede4b3c670a41674f27e0eaa137a0e93395c..068e816508f2dad1c4b9653647076c1c5af1351a 100644 --- a/receiver/src/request_handler/requests_dispatcher.cpp +++ b/receiver/src/request_handler/requests_dispatcher.cpp @@ -1,17 +1,20 @@ #include "requests_dispatcher.h" + +#include <utility> +#include "../request.h" #include "asapo/io/io_factory.h" #include "../receiver_logger.h" #include "asapo/database/db_error.h" namespace asapo { RequestsDispatcher::RequestsDispatcher(SocketDescriptor socket_fd, std::string address, - ReceiverStatistics* statistics, SharedCache cache, KafkaClient* kafka_client) : statistics__{statistics}, + ReceiverStatistics* statistics,SharedReceiverMonitoringClient monitoring, SharedCache cache,KafkaClient* kafka_client) : statistics__{statistics}, io__{GenerateDefaultIO()}, log__{ GetDefaultReceiverLogger()}, request_factory__{ new RequestFactory{ - cache, kafka_client}}, + std::move(monitoring),cache,kafka_client}}, socket_fd_{socket_fd}, producer_uri_{ std::move(address)} { @@ -55,7 +58,10 @@ GenericNetworkResponse RequestsDispatcher::CreateResponseToRequest(const std::un Error RequestsDispatcher::HandleRequest(const std::unique_ptr<Request>& request) const { log__->Debug(RequestLog("got new request", request.get())); Error handle_err; - handle_err = request->Handle(statistics__); + handle_err = request->Handle(); + if (request->GetStatistics()) { + statistics__->ApplyTimeFrom(request->GetStatistics()); + } if (handle_err) { if (handle_err == ReceiverErrorTemplates::kReAuthorizationFailure) { log__->Warning(LogMessageWithFields(handle_err).Append(RequestLog("", request.get()))); @@ -90,10 +96,11 @@ Error RequestsDispatcher::ProcessRequest(const std::unique_ptr<Request>& request std::unique_ptr<Request> RequestsDispatcher::GetNextRequest(Error* err) const noexcept { //TODO: to be overwritten with MessagePack (or similar) GenericRequestHeader generic_request_header; - statistics__->StartTimer(StatisticEntity::kNetwork); + RequestStatisticsPtr statistics{new RequestStatistics}; + + statistics->StartTimer(StatisticEntity::kNetworkIncoming); Error io_err; - io__->Receive(socket_fd_, &generic_request_header, - sizeof(GenericRequestHeader), &io_err); + io__-> Receive(socket_fd_, &generic_request_header, sizeof(GenericRequestHeader), &io_err); if (io_err) { *err = ReceiverErrorTemplates::kProcessingError.Generate("cannot get next request",std::move(io_err)); if ((*err)->GetCause() != GeneralErrorTemplates::kEndOfFile) { @@ -101,8 +108,8 @@ std::unique_ptr<Request> RequestsDispatcher::GetNextRequest(Error* err) const no } return nullptr; } - statistics__->StopTimer(); - auto request = request_factory__->GenerateRequest(generic_request_header, socket_fd_, producer_uri_, err); + statistics->StopTimer(); + auto request = request_factory__->GenerateRequest(generic_request_header, socket_fd_, producer_uri_, std::move(statistics), err); if (*err) { log__->Error(LogMessageWithFields(*err).Append("origin", HostFromUri(producer_uri_))); } diff --git a/receiver/src/request_handler/requests_dispatcher.h b/receiver/src/request_handler/requests_dispatcher.h index 67d9169df8007d87700480acd4d1783ddcad9f2a..e942b5888314c521108519f46197dfaccab35383 100644 --- a/receiver/src/request_handler/requests_dispatcher.h +++ b/receiver/src/request_handler/requests_dispatcher.h @@ -14,7 +14,7 @@ namespace asapo { class RequestsDispatcher { public: - RequestsDispatcher(SocketDescriptor socket_fd, std::string address, ReceiverStatistics* statistics, SharedCache cache, KafkaClient* kafka_client); + RequestsDispatcher(SocketDescriptor socket_fd, std::string address, ReceiverStatistics* statistics,SharedReceiverMonitoringClient monitoring, SharedCache cache, KafkaClient* kafka_client); ASAPO_VIRTUAL Error ProcessRequest(const std::unique_ptr<Request>& request) const noexcept; ASAPO_VIRTUAL std::unique_ptr<Request> GetNextRequest(Error* err) const noexcept; ASAPO_VIRTUAL ~RequestsDispatcher() = default; diff --git a/receiver/src/request_handler/structs.h b/receiver/src/request_handler/structs.h index 80bd533af2f92a04247d4c63d0d41851f5ad2235..6dd233a69fd879e71dcc7c8e3f2562d8c7cdb56e 100644 --- a/receiver/src/request_handler/structs.h +++ b/receiver/src/request_handler/structs.h @@ -8,6 +8,8 @@ namespace asapo { struct AuthorizationData { + std::string producer_instance_id; + std::string pipeline_step_id; std::string beamtime_id; std::string data_source; std::string beamline; diff --git a/receiver/src/statistics/instanced_statistics_provider.cpp b/receiver/src/statistics/instanced_statistics_provider.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ae2b74ba176a774ee21e8481e093eda624a70e7c --- /dev/null +++ b/receiver/src/statistics/instanced_statistics_provider.cpp @@ -0,0 +1,38 @@ +#include "instanced_statistics_provider.h" + +using namespace asapo; +using namespace std::chrono; + +void RequestStatistics::StartTimer(StatisticEntity entity) { + current_statistic_entity_ = entity; + current_timer_last_timepoint_ = system_clock::now(); +} + +void RequestStatistics::StopTimer() { + auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(system_clock::now() - current_timer_last_timepoint_); + time_counters_[current_statistic_entity_] += elapsed; +} + +std::chrono::nanoseconds RequestStatistics::GetElapsed(StatisticEntity entity) const { + return time_counters_[entity]; +} + +uint64_t RequestStatistics::GetElapsedMicrosecondsCount(StatisticEntity entity) const { + return static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::microseconds>(time_counters_[entity]).count()); +} + +void RequestStatistics::AddIncomingBytes(uint64_t incomingByteCount) { + incomingBytes_ += incomingByteCount; +} + +void RequestStatistics::AddOutgoingBytes(uint64_t outgoingByteCount) { + outgoingBytes_ += outgoingByteCount; +} + +uint64_t RequestStatistics::GetIncomingBytes() const { + return incomingBytes_; +} + +uint64_t RequestStatistics::GetOutgoingBytes() const { + return outgoingBytes_; +} diff --git a/receiver/src/statistics/instanced_statistics_provider.h b/receiver/src/statistics/instanced_statistics_provider.h new file mode 100644 index 0000000000000000000000000000000000000000..7d2ed9acd08db97630dd7c3f49061028e90179ea --- /dev/null +++ b/receiver/src/statistics/instanced_statistics_provider.h @@ -0,0 +1,40 @@ +#ifndef ASAPO_INSTANCED_STATISTICS_PROVIDER_H +#define ASAPO_INSTANCED_STATISTICS_PROVIDER_H + +#include <chrono> +#include <asapo/preprocessor/definitions.h> +#include <memory> +#include "receiver_statistics_entry_type.h" + +namespace asapo { + +class RequestStatistics { +private: + std::chrono::system_clock::time_point current_timer_last_timepoint_; + StatisticEntity current_statistic_entity_ = StatisticEntity::kDatabase; + std::chrono::nanoseconds time_counters_[kNStatisticEntities] {std::chrono::nanoseconds(0)}; + + uint64_t incomingBytes_ = 0; + uint64_t outgoingBytes_ = 0; +public: + ASAPO_VIRTUAL void StartTimer(StatisticEntity entity); + ASAPO_VIRTUAL void StopTimer(); + + ASAPO_VIRTUAL void AddIncomingBytes(uint64_t incomingByteCount); + ASAPO_VIRTUAL void AddOutgoingBytes(uint64_t outgoingByteCount); + + ASAPO_VIRTUAL uint64_t GetIncomingBytes() const; + ASAPO_VIRTUAL uint64_t GetOutgoingBytes() const; + + ASAPO_VIRTUAL std::chrono::nanoseconds GetElapsed(StatisticEntity entity) const; + ASAPO_VIRTUAL uint64_t GetElapsedMicrosecondsCount(StatisticEntity entity) const; + + ASAPO_VIRTUAL ~RequestStatistics() = default; + +}; + +using RequestStatisticsPtr = std::unique_ptr<RequestStatistics>; + +} + +#endif //ASAPO_INSTANCED_STATISTICS_PROVIDER_H diff --git a/receiver/src/statistics/receiver_statistics.cpp b/receiver/src/statistics/receiver_statistics.cpp index 59e467517d9e12ccf3d23ee30ed48b749b602c9a..bfff6ed68b75e6bc0c78602fa7f2772074d381c5 100644 --- a/receiver/src/statistics/receiver_statistics.cpp +++ b/receiver/src/statistics/receiver_statistics.cpp @@ -4,8 +4,6 @@ namespace asapo { using std::chrono::system_clock; - - ReceiverStatistics::ReceiverStatistics(unsigned int write_interval) : Statistics(write_interval) { for (size_t i = 0; i < kNStatisticEntities; i++) { time_counters_[i] = std::chrono::nanoseconds{0}; @@ -31,17 +29,10 @@ void ReceiverStatistics::ResetStatistics() noexcept { } } -void ReceiverStatistics::StartTimer(const StatisticEntity& entity) noexcept { - current_statistic_entity_ = entity; - current_timer_last_timepoint_ = system_clock::now(); +void ReceiverStatistics::ApplyTimeFrom(const RequestStatistics* stats) { + for (size_t i = 0; i < kNStatisticEntities; i++) { + time_counters_[i] += stats->GetElapsed((StatisticEntity) i); + } } - -void ReceiverStatistics::StopTimer() noexcept { - auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds> - (system_clock::now() - current_timer_last_timepoint_); - time_counters_[current_statistic_entity_] += elapsed; } - - -} \ No newline at end of file diff --git a/receiver/src/statistics/receiver_statistics.h b/receiver/src/statistics/receiver_statistics.h index fed59994b622f125f20600f75f4df26b3b5f83fd..96ee773393ef239783d76192cb27f4494836ea74 100644 --- a/receiver/src/statistics/receiver_statistics.h +++ b/receiver/src/statistics/receiver_statistics.h @@ -2,29 +2,27 @@ #define ASAPO_RECEIVER_STATISTICS_H #include "statistics.h" +#include "receiver_statistics_entry_type.h" +#include "instanced_statistics_provider.h" namespace asapo { -static const size_t kNStatisticEntities = 3; -enum StatisticEntity : int { - kDatabase = 0, - kDisk, - kNetwork, +static const std::vector<std::string> kStatisticEntityNames = { + "db_share", + "disk_share", + "network_incoming_share", + "network_outgoing_share", + "monitoring" }; -static const std::vector<std::string> kStatisticEntityNames = {"db_share", "disk_share", "network_share"}; - class ReceiverStatistics : public Statistics { - public: +public: ReceiverStatistics(unsigned int write_interval = kDefaultStatisticWriteIntervalMs); - ASAPO_VIRTUAL void StartTimer(const StatisticEntity& entity) noexcept; - ASAPO_VIRTUAL void StopTimer() noexcept; - private: + void ApplyTimeFrom(const RequestStatistics* stats); +private: StatisticsToSend PrepareStatisticsToSend() const noexcept override; void ResetStatistics() noexcept override; uint64_t GetElapsedMs(StatisticEntity entity) const noexcept; - std::chrono::system_clock::time_point current_timer_last_timepoint_; - StatisticEntity current_statistic_entity_ = StatisticEntity::kDatabase; std::chrono::nanoseconds time_counters_[kNStatisticEntities]; }; diff --git a/receiver/src/statistics/receiver_statistics_entry_type.h b/receiver/src/statistics/receiver_statistics_entry_type.h new file mode 100644 index 0000000000000000000000000000000000000000..805bcfa8188b9511c1e2eb6781f2df4ca886d9a4 --- /dev/null +++ b/receiver/src/statistics/receiver_statistics_entry_type.h @@ -0,0 +1,17 @@ +#ifndef ASAPO_RECEIVER_STATISTICS_ENTRY_TYPE_H +#define ASAPO_RECEIVER_STATISTICS_ENTRY_TYPE_H + +namespace asapo { + +static const size_t kNStatisticEntities = 5; +enum StatisticEntity : int { + kDatabase = 0, + kDisk, + kNetworkIncoming, + kNetworkOutgoing, + kMonitoring, +}; + +} + +#endif //ASAPO_RECEIVER_STATISTICS_ENTRY_TYPE_H diff --git a/receiver/unittests/mock_receiver_config.cpp b/receiver/unittests/mock_receiver_config.cpp index ba0bbfb05ea9cebc2e9acef646b0026d7b86bb58..026eeb66891154a9eb1eb3298b9a63a931ce89bf 100644 --- a/receiver/unittests/mock_receiver_config.cpp +++ b/receiver/unittests/mock_receiver_config.cpp @@ -9,6 +9,8 @@ using testing::_; using testing::Return; using testing::SetArgPointee; +using ::testing::Test; +using ::testing::Eq; namespace asapo { @@ -17,33 +19,33 @@ std::string Key(std::string value, std::string error_field) { return "\"" + val + "\":"; } -Error SetReceiverConfig (const ReceiverConfig& config, std::string error_field) { +Error SetReceiverConfigWithError (const ReceiverConfig& config, std::string error_field) { MockIO mock_io; ReceiverConfigManager config_manager; config_manager.io__ = std::unique_ptr<IO> {&mock_io}; std::string log_level; switch (config.log_level) { - case LogLevel::Error: - log_level = "error"; - break; - case LogLevel::Warning: - log_level = "warning"; - break; - case LogLevel::Info: - log_level = "info"; - break; - case LogLevel::Debug: - log_level = "debug"; - break; - case LogLevel::None: - log_level = "none"; - break; + case LogLevel::Error: + log_level = "error"; + break; + case LogLevel::Warning: + log_level = "warning"; + break; + case LogLevel::Info: + log_level = "info"; + break; + case LogLevel::Debug: + log_level = "debug"; + break; + case LogLevel::None: + log_level = "none"; + break; } - auto config_string = std::string("{") + Key("PerformanceDbServer", - error_field) + "\"" + config.performance_db_uri + "\""; + auto config_string = std::string("{") + Key("PerformanceDbServer", error_field) + "\"" + config.performance_db_uri + "\""; config_string += "," + Key("PerformanceDbName", error_field) + "\"" + config.performance_db_name + "\""; + config_string += "," + Key("MonitoringServer", error_field) + "\"" + config.monitoring_server_url + "\""; config_string += "," + Key("MonitorPerformance", error_field) + (config.monitor_performance ? "true" : "false"); config_string += "," + Key("DatabaseServer", error_field) + "\"" + config.database_uri + "\""; config_string += "," + Key("DiscoveryServer", error_field) + "\"" + config.discovery_server + "\""; @@ -87,8 +89,8 @@ Error SetReceiverConfig (const ReceiverConfig& config, std::string error_field) EXPECT_CALL(mock_io, ReadFileToString_t("fname", _)).WillOnce( - testing::Return(config_string) - ); + testing::Return(config_string) + ); auto err = config_manager.ReadConfigFromFile("fname"); @@ -97,6 +99,10 @@ Error SetReceiverConfig (const ReceiverConfig& config, std::string error_field) return err; } +void SetReceiverConfig (const ReceiverConfig& config, std::string error_field) { + SetReceiverConfigWithError(config, error_field); +} + } diff --git a/receiver/unittests/mock_receiver_config.h b/receiver/unittests/mock_receiver_config.h index 5ad7850819325f4177bd4661ad57faf72927b5f6..ff37a70b3d316a01feae9430851ddcc51c78b725 100644 --- a/receiver/unittests/mock_receiver_config.h +++ b/receiver/unittests/mock_receiver_config.h @@ -6,7 +6,8 @@ namespace asapo { -Error SetReceiverConfig (const ReceiverConfig& config, std::string error_field); +Error SetReceiverConfigWithError (const ReceiverConfig& config, std::string error_field); +void SetReceiverConfig (const ReceiverConfig& config, std::string error_field); } diff --git a/receiver/unittests/monitoring/receiver_monitoring_mocking.h b/receiver/unittests/monitoring/receiver_monitoring_mocking.h new file mode 100644 index 0000000000000000000000000000000000000000..53094572dd846944b709b3d6e9186ae2d8f7962b --- /dev/null +++ b/receiver/unittests/monitoring/receiver_monitoring_mocking.h @@ -0,0 +1,60 @@ +#ifndef ASAPO_RECEIVER_MONITORING_MOCKING_H +#define ASAPO_RECEIVER_MONITORING_MOCKING_H + +#include "../../src/monitoring/receiver_monitoring_client.h" +#ifdef NEW_RECEIVER_MONITORING_ENABLED +#include "../../src/monitoring/receiver_monitoring_client_impl.h" +#endif + +namespace asapo { + +class MockReceiverMonitoringClient : public asapo::ReceiverMonitoringClient { +public: + void StartMonitoring() override {}; + MOCK_METHOD9(SendProducerToReceiverTransferDataPoint, void(const std::string& pipelineStepId, const std::string& producerInstanceId, + const std::string& beamtime, const std::string& source, + const std::string& stream, uint64_t fileSize, + uint64_t transferTimeInMicroseconds, uint64_t writeIoTimeInMicroseconds, + uint64_t dbTimeInMicroseconds)); + + MOCK_METHOD5(SendRdsRequestWasMissDataPoint, void(const std::string& pipelineStepId, const std::string& consumerInstanceId, + const std::string& beamtime, const std::string& source, + const std::string& stream)); + + MOCK_METHOD7(SendReceiverRequestDataPoint, void(const std::string& pipelineStepId, const std::string& consumerInstanceId, + const std::string& beamtime, const std::string& source, const std::string& stream, + uint64_t fileSize, uint64_t transferTimeInMicroseconds)); + + MOCK_METHOD0(FillMemoryStats, void()); +}; + +#ifdef NEW_RECEIVER_MONITORING_ENABLED +class MockReceiverMonitoringClientImpl_ToBeSendData : public asapo::ReceiverMonitoringClientImpl::ToBeSendData { +public: + MOCK_METHOD5(GetProducerToReceiverTransfer, ProducerToReceiverTransferDataPoint* ( + const std::string& pipelineStepId, + const std::string& producerInstanceId, + const std::string& beamtime, + const std::string& source, + const std::string& stream)); + + MOCK_METHOD5(GetReceiverDataServerToConsumer, RdsToConsumerDataPoint* ( + const std::string& pipelineStepId, + const std::string& producerInstanceId, + const std::string& beamtime, + const std::string& source, + const std::string& stream + )); + + MOCK_METHOD3(GetMemoryDataPoint, RdsMemoryDataPoint* ( + const std::string& beamtime, + const std::string& source, + const std::string& stream + )); + +}; +#endif + +} + +#endif //ASAPO_RECEIVER_MONITORING_MOCKING_H diff --git a/receiver/unittests/monitoring/test_monitoring_client.cpp b/receiver/unittests/monitoring/test_monitoring_client.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ce904b5cb83d92700e4d66c1a02e1cf206304756 --- /dev/null +++ b/receiver/unittests/monitoring/test_monitoring_client.cpp @@ -0,0 +1,203 @@ +#include <gtest/gtest.h> +#include <gmock/gmock.h> +#include <asapo/database/db_error.h> + +#include "asapo/unittests/MockIO.h" +#include "asapo/unittests/MockDatabase.h" +#include "asapo/unittests/MockLogger.h" + +#include "../../src/receiver_error.h" +#include "../../src/request.h" +#include "../../src/request_handler/request_factory.h" +#include "../../src/request_handler/request_handler.h" +#include "../../src/request_handler/request_handler_monitoring.h" + +#include "../mock_receiver_config.h" +#include "asapo/common/data_structs.h" +#include "asapo/common/networking.h" +#include "../receiver_mocking.h" +#include "../monitoring/receiver_monitoring_mocking.h" +#include "../../src/monitoring/receiver_monitoring_client_noop.h" + +using asapo::MockRequest; +using asapo::MessageMeta; +using ::testing::Test; +using ::testing::Return; +using ::testing::ReturnRef; +using ::testing::_; +using ::testing::DoAll; +using ::testing::SetArgReferee; +using ::testing::Gt; +using ::testing::Eq; +using ::testing::Ne; +using ::testing::Mock; +using ::testing::NiceMock; +using ::testing::StrictMock; +using ::testing::InSequence; +using ::testing::SetArgPointee; +using ::testing::AllOf; +using ::testing::HasSubstr; + + +using ::asapo::Error; +using ::asapo::ErrorInterface; +using ::asapo::FileDescriptor; +using ::asapo::SocketDescriptor; +using ::asapo::MockIO; +using asapo::Request; +using asapo::RequestHandlerDbGetMeta; +using ::asapo::GenericRequestHeader; + +using asapo::MockDatabase; +using asapo::RequestFactory; +using asapo::SetReceiverConfig; +using asapo::ReceiverConfig; + + +namespace { + + class MonitoringClientTest : public Test { + public: + std::shared_ptr<NiceMock<asapo::MockDataCache>> mock_cache; + NiceMock<asapo::MockReceiverMonitoringClientImpl_ToBeSendData>* mock_toBeSend; + std::unique_ptr<asapo::ReceiverMonitoringClientImpl> monitoring; + void SetUp() override { + mock_cache.reset(new NiceMock<asapo::MockDataCache>); + monitoring.reset(new asapo::ReceiverMonitoringClientImpl{mock_cache}); + mock_toBeSend = new NiceMock<asapo::MockReceiverMonitoringClientImpl_ToBeSendData>; + monitoring->toBeSendData__.reset(mock_toBeSend); + } + void TearDown() override { + } + }; + + TEST_F(MonitoringClientTest, DefaultGenerator) { + std::shared_ptr<StrictMock<asapo::MockDataCache>> mock_cache; + asapo::SharedReceiverMonitoringClient monitoring_l = asapo::GenerateDefaultReceiverMonitoringClient(mock_cache, false); + asapo::ReceiverMonitoringClientImpl* monitoring_l_impl = dynamic_cast<asapo::ReceiverMonitoringClientImpl*>(monitoring_l.get()); + EXPECT_THAT(monitoring_l_impl, Ne(nullptr)); + EXPECT_THAT(monitoring_l_impl->log__, Ne(nullptr)); + EXPECT_THAT(monitoring_l_impl->io__, Ne(nullptr)); + EXPECT_THAT(monitoring_l_impl->toBeSendData__.get(), Ne(nullptr)); + EXPECT_THAT(monitoring_l_impl->sendingThreadRunning__, Eq(false)); + } + + TEST_F(MonitoringClientTest, DefaultGenerator_Noop) { + std::shared_ptr<StrictMock<asapo::MockDataCache>> mock_cache; + asapo::SharedReceiverMonitoringClient monitoring_l = asapo::GenerateDefaultReceiverMonitoringClient(mock_cache, true); + + asapo::ReceiverMonitoringClientNoop* monitoring_l_noop = dynamic_cast<asapo::ReceiverMonitoringClientNoop*>(monitoring_l.get()); + + EXPECT_THAT(monitoring_l_noop, Ne(nullptr)); + } + + TEST_F(MonitoringClientTest, GetProducerToReceiverTransfer_Init) { + asapo::ReceiverMonitoringClientImpl monitoring_l{nullptr}; + + EXPECT_THAT(monitoring_l.log__, Ne(nullptr)); + EXPECT_THAT(monitoring_l.io__, Ne(nullptr)); + EXPECT_THAT(monitoring_l.toBeSendData__.get(), Ne(nullptr)); + EXPECT_THAT(monitoring_l.sendingThreadRunning__, Eq(false)); + } + + TEST_F(MonitoringClientTest, GetProducerToReceiverTransfer_SendProducerToReceiverTransferDataPoint) { + std::unique_ptr<ProducerToReceiverTransferDataPoint> x{ new ProducerToReceiverTransferDataPoint}; + x->set_totalfilesize(100); + x->set_totaltransferreceivetimeinmicroseconds(200); + x->set_totalwriteiotimeinmicroseconds(300); + x->set_totaldbtimeinmicroseconds(400); + EXPECT_CALL(*mock_toBeSend, GetProducerToReceiverTransfer( + "p1", "i1", "b1", "so1", "st1" + )).WillOnce(Return(x.get())); + + monitoring->sendingThreadRunning__ = true; // to trick client and initiata data transfer + monitoring->SendProducerToReceiverTransferDataPoint("p1", "i1", "b1", "so1", "st1", 1, 2, 3, 4); + + EXPECT_THAT(x->totalfilesize(), Eq(101)); + EXPECT_THAT(x->totaltransferreceivetimeinmicroseconds(), Eq(202)); + EXPECT_THAT(x->totalwriteiotimeinmicroseconds(), Eq(303)); + EXPECT_THAT(x->totaldbtimeinmicroseconds(), Eq(404)); + } + + TEST_F(MonitoringClientTest, GetProducerToReceiverTransfer_SendRdsRequestWasMissDataPoint) { + std::unique_ptr<RdsToConsumerDataPoint> x {new RdsToConsumerDataPoint}; + x->set_totalfilesize(100); + x->set_hits(200); + x->set_misses(300); + x->set_totaltransfersendtimeinmicroseconds(400); + EXPECT_CALL(*mock_toBeSend, GetReceiverDataServerToConsumer( + "p1", "i1", "b1", "so1", "st1" + )).WillOnce(Return(x.get())); + + monitoring->sendingThreadRunning__ = true; // to trick client and initiata data transfer + monitoring->SendRdsRequestWasMissDataPoint("p1", "i1", "b1", "so1", "st1"); + + EXPECT_THAT(x->totalfilesize(), Eq(100)); + EXPECT_THAT(x->hits(), Eq(200)); + EXPECT_THAT(x->misses(), Eq(301)); + EXPECT_THAT(x->totaltransfersendtimeinmicroseconds(), Eq(400)); + } + + TEST_F(MonitoringClientTest, GetProducerToReceiverTransfer_SendReceiverRequestDataPoint) { + std::unique_ptr<RdsToConsumerDataPoint> x{new RdsToConsumerDataPoint}; + x->set_totalfilesize(100); + x->set_hits(200); + x->set_misses(300); + x->set_totaltransfersendtimeinmicroseconds(400); + EXPECT_CALL(*mock_toBeSend, GetReceiverDataServerToConsumer( + "p1", "i1", "b1", "so1", "st1" + )).WillOnce(Return(x.get())); + + monitoring->sendingThreadRunning__ = true; // to trick client and initiata data transfer + monitoring->SendReceiverRequestDataPoint("p1", "i1", "b1", "so1", "st1", 2, 3); + + EXPECT_THAT(x->totalfilesize(), Eq(102)); + EXPECT_THAT(x->hits(), Eq(201)); + EXPECT_THAT(x->misses(), Eq(300)); + EXPECT_THAT(x->totaltransfersendtimeinmicroseconds(), Eq(403)); + } + + TEST_F(MonitoringClientTest, FillMemoryStats) { + // using mock_toBeSend->container.mutable_groupedmemorystats()->Add(); + // and not "new" here, since the FillMemoryStats will access the container directly + + auto x1 = mock_toBeSend->container.mutable_groupedmemorystats()->Add(); + x1->set_totalbytes(100); + x1->set_usedbytes(200); + EXPECT_CALL(*mock_toBeSend, GetMemoryDataPoint( + "b1", "so1", "st1" + )).WillOnce(Return(x1)); + + auto x2 = mock_toBeSend->container.mutable_groupedmemorystats()->Add(); + x2->set_totalbytes(300); + x2->set_usedbytes(400); + EXPECT_CALL(*mock_toBeSend, GetMemoryDataPoint( + "b1", "so1", "st2" + )).WillRepeatedly(Return(x2)); + + auto x3 = mock_toBeSend->container.mutable_groupedmemorystats()->Add(); + x3->set_totalbytes(500); + x3->set_usedbytes(600); + EXPECT_CALL(*mock_toBeSend, GetMemoryDataPoint( + "b3", "so3", "st3" + )).WillOnce(Return(x3)); + + std::vector<std::shared_ptr<const asapo::CacheMeta>> result; + result.emplace_back(new asapo::CacheMeta{1, nullptr,5,1,"b1","so1","st1"}); + result.emplace_back(new asapo::CacheMeta{1, nullptr,6,1,"b1","so1","st2"}); + result.emplace_back(new asapo::CacheMeta{1, nullptr,7,1,"b3","so3","st3"}); + result.emplace_back(new asapo::CacheMeta{1, nullptr,8,1,"b1","so1","st2"}); + + EXPECT_CALL(*mock_cache, AllMetaInfosAsVector()).WillRepeatedly(Return(result)); + EXPECT_CALL(*mock_cache, GetCacheSize()).WillRepeatedly(Return(123456)); + + monitoring->FillMemoryStats(); + + EXPECT_THAT(x1->totalbytes(), Eq(123456)); + EXPECT_THAT(x1->usedbytes(), Eq(205)); + EXPECT_THAT(x2->totalbytes(), Eq(123456)); + EXPECT_THAT(x2->usedbytes(), Eq(414)); + EXPECT_THAT(x3->totalbytes(), Eq(123456)); + EXPECT_THAT(x3->usedbytes(), Eq(607)); + } +} diff --git a/receiver/unittests/monitoring/test_monitoring_client_to_be_send_data.cpp b/receiver/unittests/monitoring/test_monitoring_client_to_be_send_data.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f1d9e7f8a13dc857296306946f64e62f194a9d40 --- /dev/null +++ b/receiver/unittests/monitoring/test_monitoring_client_to_be_send_data.cpp @@ -0,0 +1,367 @@ +#include <gtest/gtest.h> +#include <gmock/gmock.h> +#include <asapo/database/db_error.h> + +#include "asapo/unittests/MockIO.h" +#include "asapo/unittests/MockDatabase.h" +#include "asapo/unittests/MockLogger.h" + +#include "../../src/receiver_error.h" +#include "../../src/request.h" +#include "../../src/request_handler/request_factory.h" +#include "../../src/request_handler/request_handler.h" +#include "../../src/request_handler/request_handler_monitoring.h" + +#include "../mock_receiver_config.h" +#include "asapo/common/data_structs.h" +#include "asapo/common/networking.h" +#include "../receiver_mocking.h" +#include "../monitoring/receiver_monitoring_mocking.h" + +using asapo::MockRequest; +using asapo::MessageMeta; +using ::testing::Test; +using ::testing::Return; +using ::testing::ReturnRef; +using ::testing::_; +using ::testing::DoAll; +using ::testing::SetArgReferee; +using ::testing::Gt; +using ::testing::Eq; +using ::testing::Ne; +using ::testing::Mock; +using ::testing::NiceMock; +using ::testing::StrictMock; +using ::testing::InSequence; +using ::testing::SetArgPointee; +using ::testing::AllOf; +using ::testing::HasSubstr; + + +using ::asapo::Error; +using ::asapo::ErrorInterface; +using ::asapo::FileDescriptor; +using ::asapo::SocketDescriptor; +using ::asapo::MockIO; +using asapo::Request; +using asapo::RequestHandlerDbGetMeta; +using ::asapo::GenericRequestHeader; + +using asapo::MockDatabase; +using asapo::RequestFactory; +using asapo::SetReceiverConfig; +using asapo::ReceiverConfig; + + +namespace { + + class MonitoringClient_ToBeSendDataTest : public Test { + void SetUp() override { + } + void TearDown() override { + } + }; + TEST_F(MonitoringClient_ToBeSendDataTest, GetProducerToReceiverTransfer_InitCorrectly) { + asapo::ReceiverMonitoringClientImpl::ToBeSendData data; + + auto p2r = data.GetProducerToReceiverTransfer( + "pipeline1", + "instance1", + "test-beamtime", + "test-source", + "test-stream"); + + ASSERT_THAT(p2r, Ne(nullptr)); + ASSERT_THAT(p2r->pipelinestepid(), Eq("pipeline1")); + ASSERT_THAT(p2r->producerinstanceid(), Eq("instance1")); + ASSERT_THAT(p2r->beamtime(), Eq("test-beamtime")); + ASSERT_THAT(p2r->source(), Eq("test-source")); + ASSERT_THAT(p2r->stream(), Eq("test-stream")); + + ASSERT_THAT(p2r->filecount(), Eq(0)); + ASSERT_THAT(p2r->totalfilesize(), Eq(0)); + ASSERT_THAT(p2r->totaltransferreceivetimeinmicroseconds(), Eq(0)); + ASSERT_THAT(p2r->totalwriteiotimeinmicroseconds(), Eq(0)); + ASSERT_THAT(p2r->totaldbtimeinmicroseconds(), Eq(0)); + } + + TEST_F(MonitoringClient_ToBeSendDataTest, GetReceiverDataServerToConsumer_InitCorrectly) { + asapo::ReceiverMonitoringClientImpl::ToBeSendData data; + + auto r2c = data.GetReceiverDataServerToConsumer( + "pipeline1", + "instance1", + "test-beamtime", + "test-source", + "test-stream"); + + ASSERT_THAT(r2c, Ne(nullptr)); + ASSERT_THAT(r2c->pipelinestepid(), Eq("pipeline1")); + ASSERT_THAT(r2c->consumerinstanceid(), Eq("instance1")); + ASSERT_THAT(r2c->beamtime(), Eq("test-beamtime")); + ASSERT_THAT(r2c->source(), Eq("test-source")); + ASSERT_THAT(r2c->stream(), Eq("test-stream")); + + ASSERT_THAT(r2c->totaltransfersendtimeinmicroseconds(), Eq(0)); + ASSERT_THAT(r2c->totalfilesize(), Eq(0)); + } + + TEST_F(MonitoringClient_ToBeSendDataTest, GetMemoryDataPoint_InitCorrectly) { + asapo::ReceiverMonitoringClientImpl::ToBeSendData data; + + auto m = data.GetMemoryDataPoint( + "test-beamtime", + "test-source", + "test-stream"); + + ASSERT_THAT(m, Ne(nullptr)); + ASSERT_THAT(m->beamtime(), Eq("test-beamtime")); + ASSERT_THAT(m->source(), Eq("test-source")); + ASSERT_THAT(m->stream(), Eq("test-stream")); + + ASSERT_THAT(m->totalbytes(), Eq(0)); + ASSERT_THAT(m->usedbytes(), Eq(0)); + } + + TEST_F(MonitoringClient_ToBeSendDataTest, GetProducerToReceiverTransfer_PointsAreSame) { + asapo::ReceiverMonitoringClientImpl::ToBeSendData data; + + auto p2r1 = data.GetProducerToReceiverTransfer( + "pipeline1", + "instance1", + "test-beamtime", + "test-source", + "test-stream"); + ASSERT_THAT(p2r1, Ne(nullptr)); + p2r1->set_filecount(2); + p2r1->set_totalfilesize(3); + p2r1->set_totaltransferreceivetimeinmicroseconds(4); + p2r1->set_totalwriteiotimeinmicroseconds(5); + p2r1->set_totaldbtimeinmicroseconds(6); + + auto p2r2 = data.GetProducerToReceiverTransfer( + "pipeline1", + "instance1", + "test-beamtime", + "test-source", + "test-stream"); + ASSERT_THAT(p2r2, Ne(nullptr)); + ASSERT_THAT(p2r2->filecount(), Eq(2)); + ASSERT_THAT(p2r2->totalfilesize(), Eq(3)); + ASSERT_THAT(p2r2->totaltransferreceivetimeinmicroseconds(), Eq(4)); + ASSERT_THAT(p2r2->totalwriteiotimeinmicroseconds(), Eq(5)); + ASSERT_THAT(p2r2->totaldbtimeinmicroseconds(), Eq(6)); + p2r2->set_filecount(10); + p2r2->set_totalfilesize(11); + p2r2->set_totaltransferreceivetimeinmicroseconds(12); + p2r2->set_totalwriteiotimeinmicroseconds(13); + p2r2->set_totaldbtimeinmicroseconds(14); + + auto p2r3 = data.GetProducerToReceiverTransfer( + "pipeline1", + "instance1", + "test-beamtime", + "test-source", + "test-stream"); + ASSERT_THAT(p2r3, Ne(nullptr)); + ASSERT_THAT(p2r3->filecount(), Eq(10)); + ASSERT_THAT(p2r3->totalfilesize(), Eq(11)); + ASSERT_THAT(p2r3->totaltransferreceivetimeinmicroseconds(), Eq(12)); + ASSERT_THAT(p2r3->totalwriteiotimeinmicroseconds(), Eq(13)); + ASSERT_THAT(p2r3->totaldbtimeinmicroseconds(), Eq(14)); + } + + TEST_F(MonitoringClient_ToBeSendDataTest, GetReceiverDataServerToConsumer_PointsAreSame) { + asapo::ReceiverMonitoringClientImpl::ToBeSendData data; + + auto r2c1 = data.GetReceiverDataServerToConsumer( + "pipeline1", + "instance1", + "test-beamtime", + "test-source", + "test-stream"); + ASSERT_THAT(r2c1, Ne(nullptr)); + r2c1->set_totaltransfersendtimeinmicroseconds(2); + r2c1->set_totalfilesize(3); + + auto r2c2 = data.GetReceiverDataServerToConsumer( + "pipeline1", + "instance1", + "test-beamtime", + "test-source", + "test-stream"); + ASSERT_THAT(r2c2, Ne(nullptr)); + ASSERT_THAT(r2c2->totaltransfersendtimeinmicroseconds(), Eq(2)); + ASSERT_THAT(r2c2->totalfilesize(), Eq(3)); + r2c2->set_totaltransfersendtimeinmicroseconds(5); + r2c2->set_totalfilesize(6); + + auto r2c3 = data.GetReceiverDataServerToConsumer( + "pipeline1", + "instance1", + "test-beamtime", + "test-source", + "test-stream"); + ASSERT_THAT(r2c3, Ne(nullptr)); + ASSERT_THAT(r2c3->totaltransfersendtimeinmicroseconds(), Eq(5)); + ASSERT_THAT(r2c3->totalfilesize(), Eq(6)); + } + + TEST_F(MonitoringClient_ToBeSendDataTest, GetMemoryDataPoint_PointsAreSame) { + asapo::ReceiverMonitoringClientImpl::ToBeSendData data; + + auto m1 = data.GetMemoryDataPoint("test-beamtime", "test-source", "test-stream"); + ASSERT_THAT(m1, Ne(nullptr)); + m1->set_usedbytes(10); + m1->set_totalbytes(20); + + auto m2 = data.GetMemoryDataPoint("test-beamtime", "test-source", "test-stream"); + ASSERT_THAT(m2, Ne(nullptr)); + ASSERT_THAT(m2->usedbytes(), Eq(10)); + ASSERT_THAT(m2->totalbytes(), Eq(20)); + m1->set_usedbytes(30); + m1->set_totalbytes(40); + + auto m3 = data.GetMemoryDataPoint("test-beamtime", "test-source", "test-stream"); + ASSERT_THAT(m3, Ne(nullptr)); + ASSERT_THAT(m3->usedbytes(), Eq(30)); + ASSERT_THAT(m3->totalbytes(), Eq(40)); + } + + + TEST_F(MonitoringClient_ToBeSendDataTest, GetProducerToReceiverTransfer_Grouping) { + asapo::ReceiverMonitoringClientImpl::ToBeSendData data; + + { + auto p2r1 = data.GetProducerToReceiverTransfer("p1","i1","b1","so1","st1"); + ASSERT_THAT(p2r1->filecount(), Eq(0)); + p2r1->set_filecount(1); + + auto p2r2 = data.GetProducerToReceiverTransfer("p2","i1","b1","so1","st1"); + ASSERT_THAT(p2r2->filecount(), Eq(0)); + p2r2->set_filecount(2); + + auto p2r3 = data.GetProducerToReceiverTransfer("p1","i2","b1","so1","st1"); + ASSERT_THAT(p2r3->filecount(), Eq(0)); + p2r3->set_filecount(3); + + auto p2r4 = data.GetProducerToReceiverTransfer("p1","i1","b2","so1","st1"); + ASSERT_THAT(p2r4->filecount(), Eq(0)); + p2r4->set_filecount(4); + + auto p2r5 = data.GetProducerToReceiverTransfer("p1","i1","b1","so2","st1"); + ASSERT_THAT(p2r5->filecount(), Eq(0)); + p2r5->set_filecount(5); + + auto p2r6 = data.GetProducerToReceiverTransfer("p1","i1","b1","so1","st2"); + ASSERT_THAT(p2r6->filecount(), Eq(0)); + p2r6->set_filecount(6); + } + { + + auto p2r1 = data.GetProducerToReceiverTransfer("p1","i1","b1","so1","st1"); + ASSERT_THAT(p2r1->filecount(), Eq(1)); + + auto p2r2 = data.GetProducerToReceiverTransfer("p2","i1","b1","so1","st1"); + ASSERT_THAT(p2r2->filecount(), Eq(2)); + + auto p2r3 = data.GetProducerToReceiverTransfer("p1","i2","b1","so1","st1"); + ASSERT_THAT(p2r3->filecount(), Eq(3)); + + auto p2r4 = data.GetProducerToReceiverTransfer("p1","i1","b2","so1","st1"); + ASSERT_THAT(p2r4->filecount(), Eq(4)); + + auto p2r5 = data.GetProducerToReceiverTransfer("p1","i1","b1","so2","st1"); + ASSERT_THAT(p2r5->filecount(), Eq(5)); + + auto p2r6 = data.GetProducerToReceiverTransfer("p1","i1","b1","so1","st2"); + ASSERT_THAT(p2r6->filecount(), Eq(6)); + } + } + + TEST_F(MonitoringClient_ToBeSendDataTest, GetReceiverDataServerToConsumer_Grouping) { + asapo::ReceiverMonitoringClientImpl::ToBeSendData data; + + { + auto r2c1 = data.GetReceiverDataServerToConsumer("p1","i1","b1","so1","st1"); + ASSERT_THAT(r2c1->hits(), Eq(0)); + r2c1->set_hits(1); + + auto r2c2 = data.GetReceiverDataServerToConsumer("p2","i1","b1","so1","st1"); + ASSERT_THAT(r2c2->hits(), Eq(0)); + r2c2->set_hits(2); + + auto r2c3 = data.GetReceiverDataServerToConsumer("p1","i2","b1","so1","st1"); + ASSERT_THAT(r2c3->hits(), Eq(0)); + r2c3->set_hits(3); + + auto r2c4 = data.GetReceiverDataServerToConsumer("p1","i1","b2","so1","st1"); + ASSERT_THAT(r2c4->hits(), Eq(0)); + r2c4->set_hits(4); + + auto r2c5 = data.GetReceiverDataServerToConsumer("p1","i1","b1","so2","st1"); + ASSERT_THAT(r2c5->hits(), Eq(0)); + r2c5->set_hits(5); + + auto r2c6 = data.GetReceiverDataServerToConsumer("p1","i1","b1","so1","st2"); + ASSERT_THAT(r2c6->hits(), Eq(0)); + r2c6->set_hits(6); + } + { + + auto r2c1 = data.GetReceiverDataServerToConsumer("p1","i1","b1","so1","st1"); + ASSERT_THAT(r2c1->hits(), Eq(1)); + + auto r2c2 = data.GetReceiverDataServerToConsumer("p2","i1","b1","so1","st1"); + ASSERT_THAT(r2c2->hits(), Eq(2)); + + auto r2c3 = data.GetReceiverDataServerToConsumer("p1","i2","b1","so1","st1"); + ASSERT_THAT(r2c3->hits(), Eq(3)); + + auto r2c4 = data.GetReceiverDataServerToConsumer("p1","i1","b2","so1","st1"); + ASSERT_THAT(r2c4->hits(), Eq(4)); + + auto r2c5 = data.GetReceiverDataServerToConsumer("p1","i1","b1","so2","st1"); + ASSERT_THAT(r2c5->hits(), Eq(5)); + + auto r2c6 = data.GetReceiverDataServerToConsumer("p1","i1","b1","so1","st2"); + ASSERT_THAT(r2c6->hits(), Eq(6)); + } + } + + TEST_F(MonitoringClient_ToBeSendDataTest, GetMemoryDataPoint_Grouping) { + asapo::ReceiverMonitoringClientImpl::ToBeSendData data; + + { + auto m1 = data.GetMemoryDataPoint("b1", "so1", "st1"); + ASSERT_THAT(m1->totalbytes(), Eq(0)); + m1->set_totalbytes(1); + + auto m2 = data.GetMemoryDataPoint("b2", "so1", "st1"); + ASSERT_THAT(m2->totalbytes(), Eq(0)); + m2->set_totalbytes(2); + + auto m3 = data.GetMemoryDataPoint("b1", "so2", "st1"); + ASSERT_THAT(m3->totalbytes(), Eq(0)); + m3->set_totalbytes(3); + + auto m4 = data.GetMemoryDataPoint("b1", "so2", "st2"); + ASSERT_THAT(m4->totalbytes(), Eq(0)); + m4->set_totalbytes(4); + } + { + auto m1 = data.GetMemoryDataPoint("b1", "so1", "st1"); + ASSERT_THAT(m1->totalbytes(), Eq(1)); + + auto m2 = data.GetMemoryDataPoint("b2", "so1", "st1"); + ASSERT_THAT(m2->totalbytes(), Eq(2)); + + auto m3 = data.GetMemoryDataPoint("b1", "so2", "st1"); + ASSERT_THAT(m3->totalbytes(), Eq(3)); + + auto m4 = data.GetMemoryDataPoint("b1", "so2", "st2"); + ASSERT_THAT(m4->totalbytes(), Eq(4)); + } + } + +} diff --git a/receiver/unittests/receiver_data_server/net_server/test_rds_fabric_server.cpp b/receiver/unittests/receiver_data_server/net_server/test_rds_fabric_server.cpp index 6b7dd8c873ac13a9dd1823be465a13efa0b3874f..1818568aa92c723a476687194581c4bed214f7df 100644 --- a/receiver/unittests/receiver_data_server/net_server/test_rds_fabric_server.cpp +++ b/receiver/unittests/receiver_data_server/net_server/test_rds_fabric_server.cpp @@ -7,6 +7,8 @@ #include "../../../src/receiver_data_server/net_server/rds_fabric_server.h" #include "../../../src/receiver_data_server/net_server/fabric_rds_request.h" #include "../../../../common/cpp/src/system_io/system_io.h" +#include "../../receiver_mocking.h" +#include "../../monitoring/receiver_monitoring_mocking.h" using ::testing::Ne; using ::testing::Eq; @@ -24,29 +26,38 @@ std::string expected_address = "somehost:123"; TEST(RdsFabricServer, Constructor) { NiceMock<MockLogger> mock_logger; - RdsFabricServer fabric_server("", &mock_logger); + std::shared_ptr<StrictMock<MockReceiverMonitoringClient>> mock_monitoring{new StrictMock<MockReceiverMonitoringClient>}; + RdsFabricServer fabric_server("", &mock_logger, mock_monitoring); ASSERT_THAT(dynamic_cast<SystemIO*>(fabric_server.io__.get()), Ne(nullptr)); ASSERT_THAT(dynamic_cast<fabric::FabricFactory*>(fabric_server.factory__.get()), Ne(nullptr)); ASSERT_THAT(fabric_server.log__, Eq(&mock_logger)); + ASSERT_THAT(fabric_server.Monitoring(), Eq(mock_monitoring)); } class RdsFabricServerTests : public Test { public: - RdsFabricServer rds_server{expected_address, &mock_logger}; NiceMock<MockLogger> mock_logger; StrictMock<MockIO> mock_io; StrictMock<fabric::MockFabricFactory> mock_fabric_factory; StrictMock<fabric::MockFabricServer> mock_fabric_server; + std::shared_ptr<StrictMock<MockReceiverMonitoringClient>> mock_monitoring; + std::unique_ptr<RdsFabricServer> rds_server_ptr; void SetUp() override { - rds_server.log__ = &mock_logger; - rds_server.io__ = std::unique_ptr<IO> {&mock_io}; - rds_server.factory__ = std::unique_ptr<fabric::FabricFactory> {&mock_fabric_factory}; + mock_monitoring.reset(new StrictMock<MockReceiverMonitoringClient>); + RdsFabricServer XX{expected_address, &mock_logger, mock_monitoring}; + + rds_server_ptr.reset(new RdsFabricServer {expected_address, &mock_logger, mock_monitoring}); + + rds_server_ptr->log__ = &mock_logger; + rds_server_ptr->io__ = std::unique_ptr<IO> {&mock_io}; + rds_server_ptr->factory__ = std::unique_ptr<fabric::FabricFactory> {&mock_fabric_factory}; } + void TearDown() override { - rds_server.io__.release(); - rds_server.factory__.release(); - rds_server.server__.release(); + rds_server_ptr->io__.release(); + rds_server_ptr->factory__.release(); + rds_server_ptr->server__.release(); } public: @@ -63,7 +74,7 @@ void RdsFabricServerTests::InitServer() { Return(&mock_fabric_server) )); - Error err = rds_server.Initialize(); + Error err = rds_server_ptr->Initialize(); ASSERT_THAT(err, Eq(fabric::FabricErrorTemplates::kInternalError)); } @@ -82,9 +93,9 @@ TEST_F(RdsFabricServerTests, Initialize_Error_CreateAndBindServer) { Return(nullptr) )); - Error err = rds_server.Initialize(); + Error err = rds_server_ptr->Initialize(); - ASSERT_THAT(rds_server.server__, Eq(nullptr)); + ASSERT_THAT(rds_server_ptr->server__, Eq(nullptr)); ASSERT_THAT(err, Eq(fabric::FabricErrorTemplates::kInternalError)); } @@ -101,12 +112,12 @@ TEST_F(RdsFabricServerTests, Initialize_Error_DoubleInitialize) { "TestAddress" )); - Error err = rds_server.Initialize(); - ASSERT_THAT(rds_server.server__, Ne(nullptr)); + Error err = rds_server_ptr->Initialize(); + ASSERT_THAT(rds_server_ptr->server__, Ne(nullptr)); ASSERT_THAT(err, Eq(nullptr)); - err = rds_server.Initialize(); - ASSERT_THAT(rds_server.server__, Ne(nullptr)); + err = rds_server_ptr->Initialize(); + ASSERT_THAT(rds_server_ptr->server__, Ne(nullptr)); ASSERT_THAT(err, Ne(nullptr)); } @@ -132,7 +143,7 @@ TEST_F(RdsFabricServerTests, GetNewRequests_Ok) { )); Error err; - GenericRequests requests = rds_server.GetNewRequests(&err); + GenericRequests requests = rds_server_ptr->GetNewRequests(&err); ASSERT_THAT(err, Eq(nullptr)); ASSERT_THAT(requests.size(), Eq(1)); @@ -155,7 +166,7 @@ TEST_F(RdsFabricServerTests, GetNewRequests_Error_RecvAny_InternalError) { ); Error err; - GenericRequests requests = rds_server.GetNewRequests(&err); + GenericRequests requests = rds_server_ptr->GetNewRequests(&err); ASSERT_THAT(err, Eq(fabric::FabricErrorTemplates::kInternalError)); ASSERT_THAT(requests.size(), Eq(0)); @@ -170,7 +181,7 @@ TEST_F(RdsFabricServerTests, GetNewRequests_Error_RecvAny_Timeout) { ); Error err; - GenericRequests requests = rds_server.GetNewRequests(&err); + GenericRequests requests = rds_server_ptr->GetNewRequests(&err); ASSERT_THAT(err, Eq(IOErrorTemplates::kTimeout)); ASSERT_THAT(requests.size(), Eq(0)); @@ -179,12 +190,12 @@ TEST_F(RdsFabricServerTests, GetNewRequests_Error_RecvAny_Timeout) { TEST_F(RdsFabricServerTests, SendResponse_Ok) { InitServer(); - FabricRdsRequest request(GenericRequestHeader{}, 41, 87); + FabricRdsRequest request(GenericRequestHeader{}, 41, 87, nullptr); GenericNetworkResponse response; EXPECT_CALL(mock_fabric_server, Send_t(41, 87, &response, sizeof(response), _/*err*/)).Times(1); - Error err = rds_server.SendResponse(&request, &response); + Error err = rds_server_ptr->SendResponse(&request, &response); ASSERT_THAT(err, Eq(nullptr)); } @@ -192,14 +203,14 @@ TEST_F(RdsFabricServerTests, SendResponse_Ok) { TEST_F(RdsFabricServerTests, SendResponse_Error_SendError) { InitServer(); - FabricRdsRequest request(GenericRequestHeader{}, 41, 87); + FabricRdsRequest request(GenericRequestHeader{}, 41, 87, nullptr); GenericNetworkResponse response; EXPECT_CALL(mock_fabric_server, Send_t(41, 87, &response, sizeof(response), _/*err*/)).WillOnce( SetArgPointee<4>(fabric::FabricErrorTemplates::kInternalError.Generate().release()) ); - Error err = rds_server.SendResponse(&request, &response); + Error err = rds_server_ptr->SendResponse(&request, &response); ASSERT_THAT(err, Eq(fabric::FabricErrorTemplates::kInternalError)); } @@ -207,7 +218,8 @@ TEST_F(RdsFabricServerTests, SendResponse_Error_SendError) { TEST_F(RdsFabricServerTests, SendResponseAndSlotData_Ok) { InitServer(); - FabricRdsRequest request(GenericRequestHeader{}, 41, 87); + GenericRequestHeader dummyHeader{}; + FabricRdsRequest request(GenericRequestHeader{}, 41, 87, nullptr); GenericNetworkResponse response; CacheMeta cacheSlot; cacheSlot.addr = (void*)0xABC; @@ -216,7 +228,7 @@ TEST_F(RdsFabricServerTests, SendResponseAndSlotData_Ok) { EXPECT_CALL(mock_fabric_server, RdmaWrite_t(41, request.GetMemoryRegion(), (void*)0xABC, 200, _/*err*/)).Times(1); EXPECT_CALL(mock_fabric_server, Send_t(41, 87, &response, sizeof(response), _/*err*/)).Times(1); - Error err = rds_server.SendResponseAndSlotData(&request, &response, &cacheSlot); + Error err = rds_server_ptr->SendResponseAndSlotData(&request, &response, &cacheSlot); ASSERT_THAT(err, Eq(nullptr)); } @@ -224,7 +236,8 @@ TEST_F(RdsFabricServerTests, SendResponseAndSlotData_Ok) { TEST_F(RdsFabricServerTests, SendResponseAndSlotData_RdmaWrite_Error) { InitServer(); - FabricRdsRequest request(GenericRequestHeader{}, 41, 87); + GenericRequestHeader dummyHeader{}; + FabricRdsRequest request(GenericRequestHeader{}, 41, 87, nullptr); GenericNetworkResponse response; CacheMeta cacheSlot; cacheSlot.addr = (void*)0xABC; @@ -234,7 +247,7 @@ TEST_F(RdsFabricServerTests, SendResponseAndSlotData_RdmaWrite_Error) { SetArgPointee<4>(fabric::FabricErrorTemplates::kInternalError.Generate().release()) ); - Error err = rds_server.SendResponseAndSlotData(&request, &response, &cacheSlot); + Error err = rds_server_ptr->SendResponseAndSlotData(&request, &response, &cacheSlot); ASSERT_THAT(err, Eq(fabric::FabricErrorTemplates::kInternalError)); } @@ -242,7 +255,8 @@ TEST_F(RdsFabricServerTests, SendResponseAndSlotData_RdmaWrite_Error) { TEST_F(RdsFabricServerTests, SendResponseAndSlotData_Send_Error) { InitServer(); - FabricRdsRequest request(GenericRequestHeader{}, 41, 87); + GenericRequestHeader dummyHeader{}; + FabricRdsRequest request(GenericRequestHeader{}, 41, 87, nullptr); GenericNetworkResponse response; CacheMeta cacheSlot; cacheSlot.addr = (void*)0xABC; @@ -253,12 +267,12 @@ TEST_F(RdsFabricServerTests, SendResponseAndSlotData_Send_Error) { SetArgPointee<4>(fabric::FabricErrorTemplates::kInternalError.Generate().release()) ); - Error err = rds_server.SendResponseAndSlotData(&request, &response, &cacheSlot); + Error err = rds_server_ptr->SendResponseAndSlotData(&request, &response, &cacheSlot); ASSERT_THAT(err, Eq(fabric::FabricErrorTemplates::kInternalError)); } TEST_F(RdsFabricServerTests, HandleAfterError) { InitServer(); - rds_server.HandleAfterError(2); /* Function does nothing */ + rds_server_ptr->HandleAfterError(2); /* Function does nothing */ } diff --git a/receiver/unittests/receiver_data_server/net_server/test_rds_tcp_server.cpp b/receiver/unittests/receiver_data_server/net_server/test_rds_tcp_server.cpp index a80f9f0c86dc125a5c4c33531633bb379dbc80e2..30eae2115101932cf2eef385d1eeee3549643109 100644 --- a/receiver/unittests/receiver_data_server/net_server/test_rds_tcp_server.cpp +++ b/receiver/unittests/receiver_data_server/net_server/test_rds_tcp_server.cpp @@ -6,6 +6,8 @@ #include "asapo/unittests/MockIO.h" #include "asapo/io/io_factory.h" #include "../../../src/receiver_data_server/net_server/rds_tcp_server.h" +#include "../../receiver_mocking.h" +#include "../../monitoring/receiver_monitoring_mocking.h" using ::testing::Test; using ::testing::Gt; @@ -18,6 +20,7 @@ using ::testing::Return; using ::testing::_; using ::testing::SetArgPointee; using ::testing::NiceMock; +using ::testing::StrictMock; using ::testing::HasSubstr; using ::testing::Contains; using ::testing::IsEmpty; @@ -29,28 +32,38 @@ using asapo::MockIO; using asapo::MockLogger; using asapo::Error; using asapo::ListSocketDescriptors; +using asapo::MockReceiverMonitoringClient; + namespace { TEST(RdsTCPServer, Constructor) { NiceMock<MockLogger> mock_logger; - RdsTcpServer tcp_server("", &mock_logger); + std::shared_ptr<StrictMock<MockReceiverMonitoringClient>> mock_monitoring{new StrictMock<MockReceiverMonitoringClient>}; + RdsTcpServer tcp_server("", &mock_logger, mock_monitoring); ASSERT_THAT(dynamic_cast<asapo::IO*>(tcp_server.io__.get()), Ne(nullptr)); ASSERT_THAT(tcp_server.log__, Eq(&mock_logger)); - + ASSERT_THAT(tcp_server.Monitoring(), Eq(mock_monitoring)); } std::string expected_address = "somehost:123"; class RdsTCPServerTests : public Test { public: - RdsTcpServer tcp_server {expected_address, &mock_logger}; NiceMock<MockIO> mock_io; NiceMock<asapo::MockLogger> mock_logger; asapo::SocketDescriptor expected_master_socket = 1; ListSocketDescriptors expected_client_sockets{2, 3, 4}; std::vector<std::string> expected_new_connections = {"test1", "test2"}; + + std::shared_ptr<StrictMock<asapo::MockReceiverMonitoringClient>> mock_monitoring; + + std::unique_ptr<RdsTcpServer> tcp_server_ptr; + void SetUp() override { - tcp_server.io__ = std::unique_ptr<asapo::IO> {&mock_io}; + mock_monitoring.reset(new StrictMock<asapo::MockReceiverMonitoringClient>); + tcp_server_ptr.reset(new RdsTcpServer{expected_address, &mock_logger, mock_monitoring}); + + tcp_server_ptr->io__ = std::unique_ptr<asapo::IO> {&mock_io}; for (auto conn : expected_client_sockets) { std::string connected_uri = std::to_string(conn); ON_CALL(mock_io, AddressFromSocket_t(conn)).WillByDefault(Return(connected_uri)); @@ -58,7 +71,7 @@ class RdsTCPServerTests : public Test { } void TearDown() override { - tcp_server.io__.release(); + tcp_server_ptr->io__.release(); } void ExpectTcpBind(bool ok); void WaitSockets(bool ok, ListSocketDescriptors clients = {}); @@ -97,13 +110,13 @@ void RdsTCPServerTests::WaitSockets(bool ok, ListSocketDescriptors clients) { void RdsTCPServerTests::InitMasterServer() { ExpectTcpBind(true); - ASSERT_THAT(tcp_server.Initialize(), Eq(nullptr)); + ASSERT_THAT(tcp_server_ptr->Initialize(), Eq(nullptr)); } TEST_F(RdsTCPServerTests, Initialize_Error) { ExpectTcpBind(false); - Error err = tcp_server.Initialize(); + Error err = tcp_server_ptr->Initialize(); ASSERT_THAT(err, Ne(nullptr)); } @@ -112,10 +125,10 @@ TEST_F(RdsTCPServerTests, Initialize_ErrorDoubleInitialize) { Error err; ExpectTcpBind(true); - err = tcp_server.Initialize(); + err = tcp_server_ptr->Initialize(); ASSERT_THAT(err, Eq(nullptr)); - err = tcp_server.Initialize(); + err = tcp_server_ptr->Initialize(); ASSERT_THAT(err, Ne(nullptr)); } @@ -168,7 +181,7 @@ TEST_F(RdsTCPServerTests, GetNewRequestsWaitsSocketActivitiesError) { InitMasterServer(); WaitSockets(false); - auto requests = tcp_server.GetNewRequests(&err); + auto requests = tcp_server_ptr->GetNewRequests(&err); ASSERT_THAT(err, Ne(nullptr)); ASSERT_THAT(requests, IsEmpty()); @@ -180,7 +193,7 @@ TEST_F(RdsTCPServerTests, GetNewRequestsWaitsSocketReceiveFailure) { WaitSockets(true); MockReceiveRequest(false); - auto requests = tcp_server.GetNewRequests(&err); + auto requests = tcp_server_ptr->GetNewRequests(&err); ASSERT_THAT(err, Eq(nullptr)); ASSERT_THAT(requests, IsEmpty()); @@ -188,7 +201,7 @@ TEST_F(RdsTCPServerTests, GetNewRequestsWaitsSocketReceiveFailure) { Mock::VerifyAndClearExpectations(&mock_io); WaitSockets(false, expected_client_sockets); - tcp_server.GetNewRequests(&err); + tcp_server_ptr->GetNewRequests(&err); } @@ -198,7 +211,7 @@ TEST_F(RdsTCPServerTests, GetNewRequestsReadEof) { WaitSockets(true); ExpectReceiveRequestEof(); - auto requests = tcp_server.GetNewRequests(&err); + auto requests = tcp_server_ptr->GetNewRequests(&err); ASSERT_THAT(err, Eq(nullptr)); ASSERT_THAT(requests, IsEmpty()); @@ -207,7 +220,7 @@ TEST_F(RdsTCPServerTests, GetNewRequestsReadEof) { WaitSockets(false, {}); - tcp_server.GetNewRequests(&err); + tcp_server_ptr->GetNewRequests(&err); } @@ -217,7 +230,7 @@ TEST_F(RdsTCPServerTests, GetNewRequestsReadOk) { WaitSockets(true); ExpectReceiveOk(); - auto requests = tcp_server.GetNewRequests(&err); + auto requests = tcp_server_ptr->GetNewRequests(&err); ASSERT_THAT(err, Eq(nullptr)); ASSERT_THAT(requests.size(), Eq(3)); @@ -235,7 +248,7 @@ TEST_F(RdsTCPServerTests, GetNewRequestsReadOk) { TEST_F(RdsTCPServerTests, SendResponse) { asapo::GenericNetworkResponse tmp {}; - asapo::ReceiverDataServerRequest expectedRequest {{}, 30}; + asapo::ReceiverDataServerRequest expectedRequest {{}, 30, nullptr}; EXPECT_CALL(mock_io, Send_t(30, &tmp, sizeof(asapo::GenericNetworkResponse), _)) .WillOnce( @@ -244,7 +257,7 @@ TEST_F(RdsTCPServerTests, SendResponse) { Return(1) )); - auto err = tcp_server.SendResponse(&expectedRequest, &tmp); + auto err = tcp_server_ptr->SendResponse(&expectedRequest, &tmp); ASSERT_THAT(err, Ne(nullptr)); } @@ -253,7 +266,7 @@ TEST_F(RdsTCPServerTests, SendResponseAndSlotData_SendResponseError) { asapo::GenericNetworkResponse tmp {}; - asapo::ReceiverDataServerRequest expectedRequest {{}, 30}; + asapo::ReceiverDataServerRequest expectedRequest {{}, 30, nullptr}; asapo::CacheMeta expectedMeta {}; expectedMeta.id = 20; expectedMeta.addr = (void*)0x9234; @@ -265,7 +278,7 @@ TEST_F(RdsTCPServerTests, SendResponseAndSlotData_SendResponseError) { testing::SetArgPointee<3>(asapo::IOErrorTemplates::kUnknownIOError.Generate().release()), Return(0) )); - auto err = tcp_server.SendResponseAndSlotData(&expectedRequest, &tmp, &expectedMeta); + auto err = tcp_server_ptr->SendResponseAndSlotData(&expectedRequest, &tmp, &expectedMeta); ASSERT_THAT(err, Ne(nullptr)); } @@ -273,7 +286,7 @@ TEST_F(RdsTCPServerTests, SendResponseAndSlotData_SendResponseError) { TEST_F(RdsTCPServerTests, SendResponseAndSlotData_SendError) { asapo::GenericNetworkResponse tmp {}; - asapo::ReceiverDataServerRequest expectedRequest {{}, 30}; + asapo::ReceiverDataServerRequest expectedRequest {{}, 30, nullptr}; asapo::CacheMeta expectedMeta {}; expectedMeta.id = 20; expectedMeta.addr = (void*)0x9234; @@ -289,7 +302,7 @@ TEST_F(RdsTCPServerTests, SendResponseAndSlotData_SendError) { Return(0) )); - auto err = tcp_server.SendResponseAndSlotData(&expectedRequest, &tmp, &expectedMeta); + auto err = tcp_server_ptr->SendResponseAndSlotData(&expectedRequest, &tmp, &expectedMeta); ASSERT_THAT(err, Ne(nullptr)); } @@ -297,7 +310,7 @@ TEST_F(RdsTCPServerTests, SendResponseAndSlotData_SendError) { TEST_F(RdsTCPServerTests, SendResponseAndSlotData_Ok) { asapo::GenericNetworkResponse tmp {}; - asapo::ReceiverDataServerRequest expectedRequest {{}, 30}; + asapo::ReceiverDataServerRequest expectedRequest {{}, 30, nullptr}; asapo::CacheMeta expectedMeta {}; expectedMeta.id = 20; expectedMeta.addr = (void*)0x9234; @@ -309,14 +322,14 @@ TEST_F(RdsTCPServerTests, SendResponseAndSlotData_Ok) { EXPECT_CALL(mock_io, Send_t(30, expectedMeta.addr, expectedMeta.size, _)) .WillOnce(Return(expectedMeta.size)); - auto err = tcp_server.SendResponseAndSlotData(&expectedRequest, &tmp, &expectedMeta); + auto err = tcp_server_ptr->SendResponseAndSlotData(&expectedRequest, &tmp, &expectedMeta); ASSERT_THAT(err, Eq(nullptr)); } TEST_F(RdsTCPServerTests, HandleAfterError) { EXPECT_CALL(mock_io, CloseSocket_t(expected_client_sockets[0], _)); - tcp_server.HandleAfterError(static_cast<uint64_t>(expected_client_sockets[0])); + tcp_server_ptr->HandleAfterError(static_cast<uint64_t>(expected_client_sockets[0])); } } diff --git a/receiver/unittests/receiver_data_server/receiver_dataserver_mocking.h b/receiver/unittests/receiver_data_server/receiver_dataserver_mocking.h index 397f2b19769306cd3dad06320e4ac66858442e11..99354692fdd469746281c7a07e1279c67501280c 100644 --- a/receiver/unittests/receiver_data_server/receiver_dataserver_mocking.h +++ b/receiver/unittests/receiver_data_server/receiver_dataserver_mocking.h @@ -19,17 +19,17 @@ class MockNetServer : public RdsNetServer { GenericRequests GetNewRequests(Error* err) override { ErrorInterface* error = nullptr; - auto reqs = GetNewRequests_t(&error); + auto& reqs = GetNewRequests_t(&error); err->reset(error); GenericRequests res; for (const auto& preq : reqs) { - ReceiverDataServerRequestPtr ptr = ReceiverDataServerRequestPtr{new ReceiverDataServerRequest{preq.header, preq.source_id}}; + ReceiverDataServerRequestPtr ptr = ReceiverDataServerRequestPtr{new ReceiverDataServerRequest{preq.header, preq.source_id, nullptr }}; res.push_back(std::move(ptr)); } return res; } - MOCK_METHOD1(GetNewRequests_t, std::vector<ReceiverDataServerRequest> (ErrorInterface** + MOCK_METHOD1(GetNewRequests_t, std::vector<ReceiverDataServerRequest>& (ErrorInterface** error)); Error SendResponse(const ReceiverDataServerRequest* request, @@ -52,6 +52,8 @@ class MockNetServer : public RdsNetServer { } MOCK_METHOD1(HandleAfterError_t, void (uint64_t source_id)); + + MOCK_METHOD0(Monitoring, SharedReceiverMonitoringClient()); }; class MockPool : public RequestPool { diff --git a/receiver/unittests/receiver_data_server/request_handler/test_request_handler.cpp b/receiver/unittests/receiver_data_server/request_handler/test_request_handler.cpp index b6a0951a3ccba60c097091aecabfb2306396c3ca..9eb82c129c709a3f4a289b47f6bb6d6d56492083 100644 --- a/receiver/unittests/receiver_data_server/request_handler/test_request_handler.cpp +++ b/receiver/unittests/receiver_data_server/request_handler/test_request_handler.cpp @@ -10,6 +10,7 @@ #include "../receiver_dataserver_mocking.h" #include "../../../src/receiver_data_server/receiver_data_server_error.h" #include "asapo/common/io_error.h" +#include "../../monitoring/receiver_monitoring_mocking.h" using ::testing::Test; using ::testing::Gt; @@ -22,6 +23,7 @@ using ::testing::Return; using ::testing::_; using ::testing::SetArgPointee; using ::testing::NiceMock; +using ::testing::StrictMock; using ::testing::HasSubstr; using ::testing::DoAll; @@ -46,11 +48,14 @@ TEST(RequestHandlerTest, Constructor) { class RequestHandlerTests : public Test { public: - asapo::MockNetServer mock_net; + std::unique_ptr<StrictMock<asapo::MockNetServer>> mock_net_ptr; + std::shared_ptr<StrictMock<asapo::MockReceiverMonitoringClient>> mock_monitoring_ptr; + + std::unique_ptr<ReceiverDataServerRequestHandler> handler_ptr; + std::unique_ptr<ReceiverDataServerRequestHandler> handler_no_cache_ptr; + asapo::MockDataCache mock_cache; NiceMock<asapo::MockStatistics> mock_stat; - ReceiverDataServerRequestHandler handler{&mock_net, &mock_cache, &mock_stat}; - ReceiverDataServerRequestHandler handler_no_cache{&mock_net, nullptr, &mock_stat}; NiceMock<asapo::MockLogger> mock_logger; uint64_t expected_data_size = 1001243214; uint64_t expected_meta_size = 100; @@ -59,16 +64,25 @@ class RequestHandlerTests : public Test { asapo::CacheMeta expected_meta; bool retry; asapo::GenericRequestHeader header{asapo::kOpcodeGetBufferData, expected_buf_id, expected_data_size, - expected_meta_size, ""}; - asapo::ReceiverDataServerRequest request{std::move(header), expected_source_id}; + expected_meta_size, "", "instanceId§pipelineStepId§bt§source§stream"}; + + asapo::ReceiverDataServerRequest request{std::move(header), expected_source_id, nullptr}; uint8_t tmp; void SetUp() override { - handler.log__ = &mock_logger; + mock_net_ptr.reset(new StrictMock<asapo::MockNetServer>); + mock_monitoring_ptr.reset(new StrictMock<asapo::MockReceiverMonitoringClient>); + + ON_CALL(*mock_net_ptr, Monitoring()).WillByDefault(Return(mock_monitoring_ptr)); + + handler_ptr.reset(new ReceiverDataServerRequestHandler{mock_net_ptr.get(), &mock_cache, &mock_stat}); + handler_ptr->log__ = &mock_logger; + handler_no_cache_ptr.reset(new ReceiverDataServerRequestHandler{mock_net_ptr.get(), nullptr, &mock_stat}); + handler_no_cache_ptr->log__ = &mock_logger; } void TearDown() override { } void MockGetSlotAndUnlockIt(bool return_without_error = true); - void MockSendResponse(asapo::NetworkErrorCode expected_response_code, bool return_without_error); + void MockSendResponse(asapo::NetworkErrorCode expected_response_code, bool return_without_error, bool expect_monitoring); void MockSendResponseAndSlotData(asapo::NetworkErrorCode expected_response_code, bool return_without_error); @@ -84,8 +98,13 @@ void RequestHandlerTests::MockGetSlotAndUnlockIt(bool return_without_error) { } } -void RequestHandlerTests::MockSendResponse(asapo::NetworkErrorCode expected_response_code, bool return_without_error) { - EXPECT_CALL(mock_net, SendResponse_t( +void RequestHandlerTests::MockSendResponse(asapo::NetworkErrorCode expected_response_code, bool return_without_error, bool expect_monitoring) { + if (expect_monitoring) { + EXPECT_CALL(*mock_net_ptr, Monitoring()); + EXPECT_CALL(*mock_monitoring_ptr, SendRdsRequestWasMissDataPoint("pipelineStepId", "instanceId", "bt", "source", "stream")); + } + + EXPECT_CALL(*mock_net_ptr, SendResponse_t( &request, M_CheckResponse(asapo::kOpcodeGetBufferData, expected_response_code, "") )).WillOnce( @@ -95,7 +114,11 @@ void RequestHandlerTests::MockSendResponse(asapo::NetworkErrorCode expected_resp void RequestHandlerTests::MockSendResponseAndSlotData(asapo::NetworkErrorCode expected_response_code, bool return_without_error) { - EXPECT_CALL(mock_net, SendResponseAndSlotData_t( + + EXPECT_CALL(*mock_net_ptr, Monitoring()); + EXPECT_CALL(*mock_monitoring_ptr, SendReceiverRequestDataPoint("pipelineStepId", "instanceId", "bt", "source", "stream", _, _)); + + EXPECT_CALL(*mock_net_ptr, SendResponseAndSlotData_t( &request, M_CheckResponse(asapo::kOpcodeGetBufferData, expected_response_code, ""), &expected_meta @@ -105,39 +128,39 @@ void RequestHandlerTests::MockSendResponseAndSlotData(asapo::NetworkErrorCode ex } TEST_F(RequestHandlerTests, RequestAlwaysReady) { - auto res = handler.ReadyProcessRequest(); + auto res = handler_ptr->ReadyProcessRequest(); ASSERT_THAT(res, Eq(true)); } TEST_F(RequestHandlerTests, ProcessRequest_WrongOpCode) { request.header.op_code = asapo::kOpcodeUnknownOp; - MockSendResponse(asapo::kNetErrorWrongRequest, true); - EXPECT_CALL(mock_net, HandleAfterError_t(expected_source_id)); + MockSendResponse(asapo::kNetErrorWrongRequest, true, false); // TODO why return without error? + EXPECT_CALL(*mock_net_ptr, HandleAfterError_t(expected_source_id)); EXPECT_CALL(mock_logger, Error(HasSubstr("wrong request"))); - auto success = handler.ProcessRequestUnlocked(&request, &retry); + auto success = handler_ptr->ProcessRequestUnlocked(&request, &retry); ASSERT_THAT(success, Eq(true)); } TEST_F(RequestHandlerTests, ProcessRequest_WrongClientVersion) { - strcpy(request.header.api_version, "v0.2"); - MockSendResponse(asapo::kNetErrorNotSupported, true); - EXPECT_CALL(mock_net, HandleAfterError_t(expected_source_id)); + strcpy(request.header.api_version, "v0.2"); // TODO: Why 0.2 + MockSendResponse(asapo::kNetErrorNotSupported, true, false); // TODO why return without error? + EXPECT_CALL(*mock_net_ptr, HandleAfterError_t(expected_source_id)); EXPECT_CALL(mock_logger, Error(HasSubstr("unsupported client"))); - auto success = handler.ProcessRequestUnlocked(&request, &retry); + auto success = handler_ptr->ProcessRequestUnlocked(&request, &retry); ASSERT_THAT(success, Eq(true)); } TEST_F(RequestHandlerTests, ProcessRequest_ReturnsNoDataWhenCacheNotUsed) { - MockSendResponse(asapo::kNetErrorNoData, true); + MockSendResponse(asapo::kNetErrorNoData, true, true); - auto success = handler_no_cache.ProcessRequestUnlocked(&request, &retry); + auto success = handler_no_cache_ptr->ProcessRequestUnlocked(&request, &retry); EXPECT_CALL(mock_logger, Debug(_)).Times(0); ASSERT_THAT(success, Eq(true)); @@ -145,10 +168,10 @@ TEST_F(RequestHandlerTests, ProcessRequest_ReturnsNoDataWhenCacheNotUsed) { TEST_F(RequestHandlerTests, ProcessRequest_ReadSlotReturnsNull) { MockGetSlotAndUnlockIt(false); - MockSendResponse(asapo::kNetErrorNoData, true); + MockSendResponse(asapo::kNetErrorNoData, true, true); EXPECT_CALL(mock_logger, Debug(HasSubstr("not found"))); - auto success = handler.ProcessRequestUnlocked(&request, &retry); + auto success = handler_ptr->ProcessRequestUnlocked(&request, &retry); ASSERT_THAT(success, Eq(true)); } @@ -156,9 +179,9 @@ TEST_F(RequestHandlerTests, ProcessRequest_ReadSlotReturnsNull) { TEST_F(RequestHandlerTests, ProcessRequest_ReadSlotErrorSendingResponse) { MockGetSlotAndUnlockIt(true); MockSendResponseAndSlotData(asapo::kNetErrorNoError, false); - EXPECT_CALL(mock_net, HandleAfterError_t(_)); + EXPECT_CALL(*mock_net_ptr, HandleAfterError_t(_)); - auto success = handler.ProcessRequestUnlocked(&request, &retry); + auto success = handler_ptr->ProcessRequestUnlocked(&request, &retry); ASSERT_THAT(success, Eq(true)); } @@ -168,7 +191,7 @@ TEST_F(RequestHandlerTests, ProcessRequest_Ok) { MockSendResponseAndSlotData(asapo::kNetErrorNoError, true); EXPECT_CALL(mock_stat, IncreaseRequestCounter_t()); EXPECT_CALL(mock_stat, IncreaseRequestDataVolume_t(expected_data_size)); - auto success = handler.ProcessRequestUnlocked(&request, &retry); + auto success = handler_ptr->ProcessRequestUnlocked(&request, &retry); ASSERT_THAT(success, Eq(true)); } diff --git a/receiver/unittests/receiver_data_server/test_receiver_data_server.cpp b/receiver/unittests/receiver_data_server/test_receiver_data_server.cpp index 004915c1f8694fa9150574ddc61a48e4d491d10e..8037ab370588632a13e3b863ed99640dfb2a313f 100644 --- a/receiver/unittests/receiver_data_server/test_receiver_data_server.cpp +++ b/receiver/unittests/receiver_data_server/test_receiver_data_server.cpp @@ -22,6 +22,7 @@ using ::testing::Eq; using ::testing::Ne; using ::testing::Ref; using ::testing::Return; +using ::testing::ReturnRef; using ::testing::_; using ::testing::SetArgPointee; using ::testing::NiceMock; @@ -78,13 +79,14 @@ class ReceiverDataServerTests : public Test { }; TEST_F(ReceiverDataServerTests, TimeoutGetNewRequests) { + auto reqs = std::vector<ReceiverDataServerRequest> {}; EXPECT_CALL(mock_net, GetNewRequests_t(_)).WillOnce( DoAll(SetArgPointee<0>(asapo::IOErrorTemplates::kTimeout.Generate().release()), - Return(std::vector<ReceiverDataServerRequest> {}) + ReturnRef(reqs) ) ).WillOnce( DoAll(SetArgPointee<0>(asapo::IOErrorTemplates::kUnknownIOError.Generate().release()), - Return(std::vector<ReceiverDataServerRequest> {}) + ReturnRef(reqs) ) ); @@ -95,9 +97,10 @@ TEST_F(ReceiverDataServerTests, TimeoutGetNewRequests) { } TEST_F(ReceiverDataServerTests, ErrorGetNewRequests) { + auto reqs = std::vector<ReceiverDataServerRequest> {}; EXPECT_CALL(mock_net, GetNewRequests_t(_)).WillOnce( DoAll(SetArgPointee<0>(asapo::IOErrorTemplates::kUnknownIOError.Generate().release()), - Return(std::vector<ReceiverDataServerRequest> {}) + ReturnRef(reqs) ) ); @@ -107,9 +110,10 @@ TEST_F(ReceiverDataServerTests, ErrorGetNewRequests) { } TEST_F(ReceiverDataServerTests, ErrorAddingRequests) { + auto reqs = std::vector<ReceiverDataServerRequest> {}; EXPECT_CALL(mock_net, GetNewRequests_t(_)).WillOnce( DoAll(SetArgPointee<0>(nullptr), - Return(std::vector<ReceiverDataServerRequest> {}) + ReturnRef(reqs) ) ); @@ -123,13 +127,14 @@ TEST_F(ReceiverDataServerTests, ErrorAddingRequests) { } TEST_F(ReceiverDataServerTests, Ok) { + auto reqs = std::vector<ReceiverDataServerRequest> {}; EXPECT_CALL(mock_net, GetNewRequests_t(_)).WillOnce( DoAll(SetArgPointee<0>(nullptr), - Return(std::vector<ReceiverDataServerRequest> {}) + ReturnRef(reqs) ) ).WillOnce( DoAll(SetArgPointee<0>(asapo::IOErrorTemplates::kUnknownIOError.Generate().release()), - Return(std::vector<ReceiverDataServerRequest> {}) + ReturnRef(reqs) ) ); diff --git a/receiver/unittests/receiver_mocking.h b/receiver/unittests/receiver_mocking.h index dd2b21353bc7ff09b1a066aa167b2c44a3ae917b..f47ddde586e44e6568fbb186f649d563ddfc2be8 100644 --- a/receiver/unittests/receiver_mocking.h +++ b/receiver/unittests/receiver_mocking.h @@ -19,26 +19,36 @@ class MockStatistics : public asapo::ReceiverStatistics { SendIfNeeded_t(send_always); } - void IncreaseRequestCounter() noexcept override { IncreaseRequestCounter_t(); } - void StartTimer(const asapo::StatisticEntity& entity) noexcept override { - StartTimer_t(entity); - } void IncreaseRequestDataVolume(uint64_t transferred_data_volume) noexcept override { IncreaseRequestDataVolume_t(transferred_data_volume); } - void StopTimer() noexcept override { - StopTimer_t(); - } - MOCK_METHOD(void, SendIfNeeded_t, (bool send_always), ()); - MOCK_METHOD(void, IncreaseRequestCounter_t, (), ()); - MOCK_METHOD(void, StopTimer_t, (), ()); - MOCK_METHOD(void, IncreaseRequestDataVolume_t, (uint64_t transferred_data_volume), ()); - MOCK_METHOD(void, StartTimer_t, (const asapo::StatisticEntity& entity), ()); + MOCK_METHOD1(SendIfNeeded_t, void(bool send_always)); + MOCK_METHOD0(IncreaseRequestCounter_t, void()); + MOCK_METHOD1(IncreaseRequestDataVolume_t, void (uint64_t transferred_data_volume)); + +}; + +class MockInstancedStatistics : public asapo::RequestStatistics { +public: + MOCK_METHOD1(StartTimer, void(StatisticEntity entity)); + MOCK_METHOD0(StopTimer, void()); + MOCK_METHOD1(AddIncomingBytes, void(uint64_t incomingByteCount)); + MOCK_METHOD1(AddOutgoingBytes, void(uint64_t outgoingByteCount)); + + MOCK_CONST_METHOD0(GetIncomingBytes, uint64_t()); + MOCK_CONST_METHOD0(GetOutgoingBytes, uint64_t()); + + MOCK_CONST_METHOD1(GetOutgoingBytes, std::chrono::nanoseconds(StatisticEntity entity)); + MOCK_CONST_METHOD1(GetElapsedMicrosecondsCount, uint64_t(StatisticEntity entity)); + + MOCK_METHOD1(SendIfNeeded, void(bool send_always)); + MOCK_METHOD0(IncreaseRequestCounter_t, void()); + MOCK_METHOD1(IncreaseRequestDataVolume_t, void (uint64_t transferred_data_volume)); }; class MockHandlerDbCheckRequest : public asapo::RequestHandlerDbCheckRequest { @@ -61,8 +71,8 @@ class MockHandlerDbCheckRequest : public asapo::RequestHandlerDbCheckRequest { class MockRequest: public Request { public: MockRequest(const GenericRequestHeader& request_header, SocketDescriptor socket_fd, std::string origin_uri, - const RequestHandlerDbCheckRequest* db_check_handler ): - Request(request_header, socket_fd, std::move(origin_uri), nullptr, db_check_handler) {}; + const RequestHandlerDbCheckRequest* db_check_handler, RequestStatisticsPtr statistics): + Request(request_header, socket_fd, std::move(origin_uri), nullptr, db_check_handler, std::move(statistics)) {}; // MOCK_METHOD(, ), (const,override), (override)); MOCK_METHOD(std::string, GetFileName, (), (const, override)); @@ -74,6 +84,8 @@ class MockRequest: public Request { MOCK_METHOD(uint64_t, GetDataID, (), (const, override)); MOCK_METHOD(uint64_t, GetSlotId, (), (const, override)); MOCK_METHOD(void*, GetData, (), (const, override)); + MOCK_CONST_METHOD0(GetPipelineStepId, const std::string & ()); + MOCK_CONST_METHOD0(GetProducerInstanceId, const std::string & ()); MOCK_METHOD(const std::string &, GetBeamtimeId, (), (const, override)); MOCK_METHOD(const std::string &, GetDataSource, (), (const, override)); MOCK_METHOD(const std::string &, GetMetaData, (), (const, override)); @@ -84,6 +96,8 @@ class MockRequest: public Request { MOCK_METHOD(const std::string &, GetOnlinePath, (), (const, override)); MOCK_METHOD(const std::string &, GetOfflinePath, (), (const, override)); + MOCK_METHOD0(GetStatistics, RequestStatistics*()); + // not nice casting, but mocking GetCustomData directly does not compile on Windows. const CustomRequestData& GetCustomData() const override { return (CustomRequestData&) * GetCustomData_t(); @@ -91,6 +105,8 @@ class MockRequest: public Request { MOCK_METHOD(const uint64_t*, GetCustomData_t, (), (const)); MOCK_METHOD(const char*, GetMessage, (), (const)); //override does not compile on windows, not clear why () + MOCK_METHOD1(SetProducerInstanceId, void (std::string)); + MOCK_METHOD1(SetPipelineStepId, void (std::string)); MOCK_METHOD(void, SetBeamtimeId, (std::string), (override)); MOCK_METHOD(void, SetDataSource, (std::string), (override)); MOCK_METHOD(void, SetBeamline, (std::string), (override)); @@ -121,20 +137,20 @@ class MockRequest: public Request { class MockDataCache: public DataCache { public: MockDataCache(): DataCache(0, 0) {}; - - void* GetFreeSlotAndLock(uint64_t size, CacheMeta** meta, Error* err) override{ + void* GetFreeSlotAndLock(uint64_t size, CacheMeta** meta,std::string beamtime, std::string source, std::string stream, Error* err) override{ ErrorInterface* error = nullptr; - auto data = GetFreeSlotAndLock_t(size, meta, &error); + auto data = GetFreeSlotAndLock_t(size, meta,beamtime,source,stream, &error); err->reset(error); return data; } - MOCK_METHOD(void*, GetFreeSlotAndLock_t, (uint64_t size, CacheMeta** meta,ErrorInterface** err)); + MOCK_METHOD(void*, GetFreeSlotAndLock_t, (uint64_t size, CacheMeta** meta,std::string beamtime, std::string source, std::string stream,ErrorInterface** err)); MOCK_METHOD(bool, UnlockSlot, (CacheMeta* meta), (override)); + MOCK_CONST_METHOD0(AllMetaInfosAsVector, std::vector<std::shared_ptr<const CacheMeta>>()); + MOCK_CONST_METHOD0(GetCacheSize, uint64_t()); MOCK_METHOD(void*, GetSlotToReadAndLock, (uint64_t id, uint64_t data_size, CacheMeta** meta), (override)); }; - class MockStatisticsSender: public StatisticsSender { public: void SendStatistics(const StatisticsToSend& statistics) const noexcept override { diff --git a/receiver/unittests/request_handler/file_processors/test_file_processor.cpp b/receiver/unittests/request_handler/file_processors/test_file_processor.cpp index f8c7e562dfb89cdec4262e105e33693e5f5754cf..632ee2be4a4f44da48c750d599b83536f574e637 100644 --- a/receiver/unittests/request_handler/file_processors/test_file_processor.cpp +++ b/receiver/unittests/request_handler/file_processors/test_file_processor.cpp @@ -30,7 +30,7 @@ class FileProcessorTests : public Test { request_header.data_id = 2; asapo::ReceiverConfig test_config; asapo::SetReceiverConfig(test_config, "none"); - mock_request.reset(new MockRequest{request_header, 1, "", nullptr}); + mock_request.reset(new MockRequest{request_header, 1, "", nullptr, nullptr}); } void TearDown() override { } diff --git a/receiver/unittests/request_handler/file_processors/test_receive_file_processor.cpp b/receiver/unittests/request_handler/file_processors/test_receive_file_processor.cpp index 518ef7d189c458066af15c17d7af883ce99db193..9c42615c9c165c96b20f6406b09a22f666861fc4 100644 --- a/receiver/unittests/request_handler/file_processors/test_receive_file_processor.cpp +++ b/receiver/unittests/request_handler/file_processors/test_receive_file_processor.cpp @@ -54,7 +54,7 @@ class ReceiveFileProcessorTests : public Test { asapo::ReceiverConfig test_config; asapo::SetReceiverConfig(test_config, "none"); processor.log__ = &mock_logger; - mock_request.reset(new NiceMock<MockRequest>{request_header, 1, "", nullptr}); + mock_request.reset(new NiceMock<MockRequest>{request_header, 1, "", nullptr, nullptr}); processor.io__ = std::unique_ptr<asapo::IO> {&mock_io}; SetDefaultRequestCalls(mock_request.get(),expected_beamtime_id); diff --git a/receiver/unittests/request_handler/file_processors/test_write_file_processor.cpp b/receiver/unittests/request_handler/file_processors/test_write_file_processor.cpp index 5a4e77115230a99db29e52e9e3edd96d0179daf4..207d1121e11ee94f1631671ddd11eba1dc72ddfd 100644 --- a/receiver/unittests/request_handler/file_processors/test_write_file_processor.cpp +++ b/receiver/unittests/request_handler/file_processors/test_write_file_processor.cpp @@ -53,7 +53,7 @@ class WriteFileProcessorTests : public Test { asapo::ReceiverConfig test_config; asapo::SetReceiverConfig(test_config, "none"); processor.log__ = &mock_logger; - mock_request.reset(new NiceMock<MockRequest>{request_header, 1, "", nullptr}); + mock_request.reset(new NiceMock<MockRequest>{request_header, 1, "", nullptr, nullptr}); processor.io__ = std::unique_ptr<asapo::IO> {&mock_io}; SetDefaultRequestCalls(mock_request.get(),expected_beamtime_id); diff --git a/receiver/unittests/request_handler/test_authorization_client.cpp b/receiver/unittests/request_handler/test_authorization_client.cpp index 1bff5c3fc5aff1e4f1510c8fec6629af16f89b44..70e48a2a0ad9c47289af326cd02190c3b1cee97e 100644 --- a/receiver/unittests/request_handler/test_authorization_client.cpp +++ b/receiver/unittests/request_handler/test_authorization_client.cpp @@ -8,6 +8,7 @@ #include "asapo/common/networking.h" #include "../mock_receiver_config.h" #include "asapo/preprocessor/definitions.h" +#include "asapo/common/internal/version.h" #include "../receiver_mocking.h" @@ -43,23 +44,30 @@ class AuthorizerClientTests : public Test { std::string expected_beamline = "beamline"; std::string expected_beamline_path = "/beamline/p01/current"; std::string expected_core_path = "/gpfs/blabla"; + std::string expected_pipeline_step_id = "pipeline_step_id"; + std::string expected_producer_instance_id = "producer_instance_id"; + std::string expected_producer_uri = "producer_uri"; std::string expected_authorization_server = "authorizer_host"; std::string expect_request_string; + std::string expect_request_string_old; std::string expected_source_credentials; + std::string expected_source_credentials_old; asapo::SourceType expected_source_type = asapo::SourceType::kProcessed; - std::string expected_source_type_str = "processed"; std::string expected_access_type_str = "[\"write\"]"; void SetUp() override { GenericRequestHeader request_header; - expected_source_credentials = "processed%" + expected_beamtime_id + "%source%token"; + expected_source_credentials = "processed%" + expected_producer_instance_id+"%"+expected_pipeline_step_id+"%"+expected_beamtime_id + "%source%token"; + expected_source_credentials_old = "processed%"+expected_beamtime_id + "%source%token"; expected_auth_data.source_credentials = expected_source_credentials; expect_request_string = std::string("{\"SourceCredentials\":\"") + expected_source_credentials + "\",\"OriginHost\":\"" + expected_producer_uri + "\"}"; - - mock_request.reset(new NiceMock<MockRequest>{request_header, 1, expected_producer_uri, nullptr}); + expect_request_string_old = std::string("{\"SourceCredentials\":\"") + "processed%" + expected_producer_uri+"%DefaultStep%"+expected_beamtime_id + "%source%token" + + "\",\"OriginHost\":\"" + + expected_producer_uri + "\"}"; + mock_request.reset(new NiceMock<MockRequest>{request_header, 1, expected_producer_uri, nullptr, nullptr}); client.http_client__ = std::unique_ptr<asapo::HttpClient> {&mock_http_client}; client.log__ = &mock_logger; config.authorization_server = expected_authorization_server; @@ -70,7 +78,9 @@ class AuthorizerClientTests : public Test { void TearDown() override { client.http_client__.release(); } - void MockAuthRequest(bool error, HttpCode code = HttpCode::OK) { + void MockAuthRequest(bool error, HttpCode code = HttpCode::OK, bool oldVersion = false) { + EXPECT_CALL(*mock_request, + GetApiVersion()).WillOnce(Return(oldVersion?"v0.5":asapo::GetReceiverApiVersion())); EXPECT_CALL(*mock_request, GetOriginUri()).WillOnce(ReturnRef(expected_producer_uri)); if (error) { @@ -82,17 +92,20 @@ class AuthorizerClientTests : public Test { )); } else { EXPECT_CALL(mock_http_client, - Post_t(expected_authorization_server + "/authorize", _, expect_request_string, _, _)). + Post_t(expected_authorization_server + "/authorize", _, oldVersion?expect_request_string_old:expect_request_string, _, _)). WillOnce( DoAll(SetArgPointee<4>(nullptr), SetArgPointee<3>(code), Return("{\"beamtimeId\":\"" + expected_beamtime_id + - "\",\"dataSource\":" + "\"" + expected_data_source + - "\",\"beamline-path\":" + "\"" + expected_beamline_path + - "\",\"corePath\":" + "\"" + expected_core_path + - "\",\"source-type\":" + "\"" + expected_source_type_str + - "\",\"beamline\":" + "\"" + expected_beamline + - "\",\"access-types\":" + expected_access_type_str + "}") + "\",\"dataSource\":\"" + expected_data_source + + "\",\"beamline-path\":\"" + expected_beamline_path + + "\",\"corePath\":\"" + expected_core_path + + "\",\"source-type\":\"" + expected_source_type_str + + "\",\"beamline\":\"" + expected_beamline + + "\",\"access-types\":" + expected_access_type_str + + ",\"instanceId\":\"" + (oldVersion?expected_producer_uri:expected_producer_instance_id) + + "\",\"pipelineStep\":\"" + (oldVersion?"DefaultStep":expected_pipeline_step_id) + + "\"}") )); } } @@ -134,7 +147,23 @@ TEST_F(AuthorizerClientTests, AuthorizeOk) { ASSERT_THAT(expected_auth_data.online_path, Eq(expected_beamline_path)); ASSERT_THAT(expected_auth_data.last_update, Gt(std::chrono::system_clock::time_point{})); ASSERT_THAT(expected_auth_data.source_credentials, Eq(expected_source_credentials)); + ASSERT_THAT(expected_auth_data.pipeline_step_id, Eq(expected_pipeline_step_id)); + ASSERT_THAT(expected_auth_data.producer_instance_id, Eq(expected_producer_instance_id)); +} + +TEST_F(AuthorizerClientTests, AuthorizeOkOldVersion) { + MockAuthRequest(false, HttpCode::OK, true); + EXPECT_CALL(mock_logger, Debug(AllOf(HasSubstr("authorized"), + HasSubstr(expected_beamtime_id) + ))); + + expected_auth_data.source_credentials = expected_source_credentials_old; + auto err = client.Authorize(mock_request.get(), &expected_auth_data); + + ASSERT_THAT(err, Eq(nullptr)); + ASSERT_THAT(expected_auth_data.pipeline_step_id, Eq("DefaultStep")); + ASSERT_THAT(expected_auth_data.producer_instance_id, Eq(expected_producer_uri)); } TEST_F(AuthorizerClientTests, AuthorizeFailsOnWrongAccessType) { diff --git a/receiver/unittests/request_handler/test_request_factory.cpp b/receiver/unittests/request_handler/test_request_factory.cpp index ed58fe68f7736d45af13259595510141bb24c559..60865b2d543b075bbd4974e80be7c2bb76e352d4 100644 --- a/receiver/unittests/request_handler/test_request_factory.cpp +++ b/receiver/unittests/request_handler/test_request_factory.cpp @@ -16,6 +16,8 @@ #include "../receiver_mocking.h" #include "../mock_receiver_config.h" +#include "../monitoring/receiver_monitoring_mocking.h" +#include "../../src/monitoring/receiver_monitoring_client_noop.h" using namespace testing; @@ -27,7 +29,7 @@ namespace { class FactoryTests : public Test { public: asapo::MockKafkaClient kafkaClient; - RequestFactory factory{nullptr, &kafkaClient}; + RequestFactory factory{nullptr,nullptr, &kafkaClient}; Error err{nullptr}; GenericRequestHeader generic_request_header; ReceiverConfig config; @@ -43,7 +45,7 @@ class FactoryTests : public Test { TEST_F(FactoryTests, ErrorOnWrongCode) { generic_request_header.op_code = asapo::Opcode::kOpcodeUnknownOp; - auto request = factory.GenerateRequest(generic_request_header, 1, origin_uri, &err); + auto request = factory.GenerateRequest(generic_request_header, 1, origin_uri, nullptr, &err); ASSERT_THAT(err, Ne(nullptr)); } @@ -54,17 +56,20 @@ TEST_F(FactoryTests, ReturnsDataRequestOnkNetOpcodeSendCode) { for (auto code : std::vector<asapo::Opcode> {asapo::Opcode::kOpcodeTransferData, asapo::Opcode::kOpcodeTransferDatasetData}) { generic_request_header.op_code = code; - auto request = factory.GenerateRequest(generic_request_header, 1, origin_uri, &err); + auto request = factory.GenerateRequest(generic_request_header, 1, origin_uri,nullptr, &err); + + ASSERT_THAT(err, Eq(nullptr)); ASSERT_THAT(dynamic_cast<asapo::Request*>(request.get()), Ne(nullptr)); - ASSERT_THAT(request->GetListHandlers().size(), Eq(6)); + ASSERT_THAT(request->GetListHandlers().size(), Eq(7)); ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerSecondaryAuthorization*>(request->GetListHandlers()[0]), Ne(nullptr)); ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerReceiveMetaData*>(request->GetListHandlers()[1]), Ne(nullptr)); ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerReceiveData*>(request->GetListHandlers()[2]), Ne(nullptr)); ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerFileProcess*>(request->GetListHandlers()[3]), Ne(nullptr)); ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerKafkaNotify*>(request->GetListHandlers()[4]), Ne(nullptr)); - ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerDbWrite*>(request->GetListHandlers().back()), Ne(nullptr)); + ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerDbWrite*>(request->GetListHandlers()[5]), Ne(nullptr)); + ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerMonitoring*>(request->GetListHandlers().back()), Ne(nullptr)); } } @@ -76,24 +81,26 @@ TEST_F(FactoryTests, ReturnsDataRequestOnkNetOpcodeSendCodeLargeFile) { SetReceiverConfig(config, "none"); generic_request_header.data_size = 1; - auto request = factory.GenerateRequest(generic_request_header, 1, origin_uri, &err); + auto request = factory.GenerateRequest(generic_request_header, 1, origin_uri, nullptr, &err); ASSERT_THAT(err, Eq(nullptr)); ASSERT_THAT(dynamic_cast<asapo::Request*>(request.get()), Ne(nullptr)); - ASSERT_THAT(request->GetListHandlers().size(), Eq(5)); + ASSERT_THAT(request->GetListHandlers().size(), Eq(6)); ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerSecondaryAuthorization*>(request->GetListHandlers()[0]), Ne(nullptr)); ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerReceiveMetaData*>(request->GetListHandlers()[1]), Ne(nullptr)); ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerFileProcess*>(request->GetListHandlers()[2]), Ne(nullptr)); ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerKafkaNotify*>(request->GetListHandlers()[3]), Ne(nullptr)); - ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerDbWrite*>(request->GetListHandlers().back()), Ne(nullptr)); + ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerDbWrite*>(request->GetListHandlers()[4]), Ne(nullptr)); + ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerMonitoring*>(request->GetListHandlers().back()), Ne(nullptr)); + } } TEST_F(FactoryTests, ReturnsDataRequestForAuthorizationCode) { generic_request_header.op_code = asapo::Opcode::kOpcodeAuthorize; - auto request = factory.GenerateRequest(generic_request_header, 1, origin_uri, &err); + auto request = factory.GenerateRequest(generic_request_header, 1, origin_uri, nullptr, &err); ASSERT_THAT(err, Eq(nullptr)); ASSERT_THAT(dynamic_cast<asapo::Request*>(request.get()), Ne(nullptr)); @@ -103,11 +110,13 @@ TEST_F(FactoryTests, ReturnsDataRequestForAuthorizationCode) { TEST_F(FactoryTests, DoNotAddDiskAndDbWriterIfNotWantedInRequest) { generic_request_header.custom_data[asapo::kPosIngestMode] = asapo::IngestModeFlags::kTransferData; - auto request = factory.GenerateRequest(generic_request_header, 1, origin_uri, &err); + auto request = factory.GenerateRequest(generic_request_header, 1, origin_uri, nullptr, &err); ASSERT_THAT(err, Eq(nullptr)); - ASSERT_THAT(request->GetListHandlers().size(), Eq(3)); - ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerSecondaryAuthorization*>(request->GetListHandlers()[0]), - Ne(nullptr)); + ASSERT_THAT(request->GetListHandlers().size(), Eq(4)); + ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerSecondaryAuthorization*>(request->GetListHandlers()[0]), Ne(nullptr)); + ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerReceiveMetaData*>(request->GetListHandlers()[1]), Ne(nullptr)); + ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerReceiveData*>(request->GetListHandlers()[2]), Ne(nullptr)); + ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerMonitoring*>(request->GetListHandlers()[3]), Ne(nullptr)); } TEST_F(FactoryTests, DoNotAddDbWriterIfNotWanted) { @@ -117,9 +126,9 @@ TEST_F(FactoryTests, DoNotAddDbWriterIfNotWanted) { config.kafka_config.enabled = true; SetReceiverConfig(config, "none"); - auto request = factory.GenerateRequest(generic_request_header, 1, origin_uri, &err); + auto request = factory.GenerateRequest(generic_request_header, 1, origin_uri,nullptr, &err); ASSERT_THAT(err, Eq(nullptr)); - ASSERT_THAT(request->GetListHandlers().size(), Eq(5)); + ASSERT_THAT(request->GetListHandlers().size(), Eq(6)); ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerSecondaryAuthorization*>(request->GetListHandlers()[0]), Ne(nullptr)); ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerReceiveMetaData*>(request->GetListHandlers()[1]), Ne(nullptr)); @@ -135,50 +144,49 @@ TEST_F(FactoryTests, DoNotAddKafkaIfNotWanted) { config.kafka_config.enabled = false; SetReceiverConfig(config, "none"); - auto request = factory.GenerateRequest(generic_request_header, 1, origin_uri, &err); + auto request = factory.GenerateRequest(generic_request_header, 1, origin_uri, nullptr, &err); ASSERT_THAT(err, Eq(nullptr)); - ASSERT_THAT(request->GetListHandlers().size(), Eq(4)); - ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerSecondaryAuthorization*>(request->GetListHandlers()[0]), - Ne(nullptr)); + ASSERT_THAT(request->GetListHandlers().size(), Eq(5)); + ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerSecondaryAuthorization*>(request->GetListHandlers()[0]), Ne(nullptr)); ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerReceiveMetaData*>(request->GetListHandlers()[1]), Ne(nullptr)); ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerReceiveData*>(request->GetListHandlers()[2]), Ne(nullptr)); ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerFileProcess*>(request->GetListHandlers()[3]), Ne(nullptr)); + ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerMonitoring*>(request->GetListHandlers()[4]), Ne(nullptr)); } TEST_F(FactoryTests, CachePassedToRequest) { - RequestFactory factory{std::shared_ptr<asapo::DataCache>{new asapo::DataCache{0, 0}}, nullptr}; - - auto request = factory.GenerateRequest(generic_request_header, 1, origin_uri, &err); + auto cache = asapo::SharedCache{new asapo::DataCache{0, 0}}; + RequestFactory factory{asapo::SharedReceiverMonitoringClient{new asapo::ReceiverMonitoringClientNoop{}}, cache,nullptr}; + auto request = factory.GenerateRequest(generic_request_header, 1, origin_uri, nullptr, &err); ASSERT_THAT(err, Eq(nullptr)); - ASSERT_THAT(request->cache__, Ne(nullptr)); + ASSERT_THAT(request->cache__, Eq(cache.get())); } TEST_F(FactoryTests, ReturnsMetaDataRequestOnTransferMetaDataOnly) { generic_request_header.custom_data[asapo::kPosIngestMode] = asapo::IngestModeFlags::kTransferMetaDataOnly; - auto request = factory.GenerateRequest(generic_request_header, 1, origin_uri, &err); + auto request = factory.GenerateRequest(generic_request_header, 1, origin_uri, nullptr, &err); ASSERT_THAT(err, Eq(nullptr)); ASSERT_THAT(dynamic_cast<asapo::Request*>(request.get()), Ne(nullptr)); - ASSERT_THAT(request->GetListHandlers().size(), Eq(4)); - ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerSecondaryAuthorization*>(request->GetListHandlers()[0]), - Ne(nullptr)); + ASSERT_THAT(request->GetListHandlers().size(), Eq(5)); + ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerSecondaryAuthorization*>(request->GetListHandlers()[0]), Ne(nullptr)); ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerReceiveMetaData*>(request->GetListHandlers()[1]), Ne(nullptr)); ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerReceiveData*>(request->GetListHandlers()[2]), Ne(nullptr)); ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerDbWrite*>(request->GetListHandlers()[3]), Ne(nullptr)); + ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerMonitoring*>(request->GetListHandlers()[4]), Ne(nullptr)); } TEST_F(FactoryTests, ReturnsMetaDataRequestOnkOpcodeTransferMetaData) { generic_request_header.custom_data[asapo::kPosIngestMode] = asapo::IngestModeFlags::kTransferData | asapo::IngestModeFlags::kStoreInDatabase; generic_request_header.op_code = asapo::Opcode::kOpcodeTransferMetaData; - auto request = factory.GenerateRequest(generic_request_header, 1, origin_uri, &err); + auto request = factory.GenerateRequest(generic_request_header, 1, origin_uri, nullptr, &err); ASSERT_THAT(err, Eq(nullptr)); ASSERT_THAT(dynamic_cast<asapo::Request*>(request.get()), Ne(nullptr)); ASSERT_THAT(dynamic_cast<asapo::Request*>(request->cache__), Eq(nullptr)); - ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerSecondaryAuthorization*>(request->GetListHandlers()[0]), - Ne(nullptr)); + ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerSecondaryAuthorization*>(request->GetListHandlers()[0]), Ne(nullptr)); ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerReceiveData*>(request->GetListHandlers()[1]), Ne(nullptr)); ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerDbMetaWrite*>(request->GetListHandlers().back()), Ne(nullptr)); } @@ -191,48 +199,44 @@ TEST_F(FactoryTests, DonNotGenerateRequestIfIngestModeIsWrong) { generic_request_header.custom_data[asapo::kPosIngestMode] = asapo::kTransferData; generic_request_header.data_size = 1; - auto request = factory.GenerateRequest(generic_request_header, 1, origin_uri, &err); + auto request = factory.GenerateRequest(generic_request_header, 1, origin_uri, nullptr, &err); ASSERT_THAT(err, Eq(asapo::ReceiverErrorTemplates::kBadRequest)); } TEST_F(FactoryTests, StreamInfoRequest) { generic_request_header.op_code = asapo::Opcode::kOpcodeStreamInfo; - auto request = factory.GenerateRequest(generic_request_header, 1, origin_uri, &err); + auto request = factory.GenerateRequest(generic_request_header, 1, origin_uri, nullptr, &err); ASSERT_THAT(err, Eq(nullptr)); ASSERT_THAT(request->GetListHandlers().size(), Eq(2)); - ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerSecondaryAuthorization*>(request->GetListHandlers()[0]), - Ne(nullptr)); + ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerSecondaryAuthorization*>(request->GetListHandlers()[0]), Ne(nullptr)); ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerDbStreamInfo*>(request->GetListHandlers()[1]), Ne(nullptr)); } TEST_F(FactoryTests, LastStreamRequest) { generic_request_header.op_code = asapo::Opcode::kOpcodeLastStream; - auto request = factory.GenerateRequest(generic_request_header, 1, origin_uri, &err); + auto request = factory.GenerateRequest(generic_request_header, 1, origin_uri, nullptr, &err); ASSERT_THAT(err, Eq(nullptr)); ASSERT_THAT(request->GetListHandlers().size(), Eq(2)); - ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerSecondaryAuthorization*>(request->GetListHandlers()[0]), - Ne(nullptr)); + ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerSecondaryAuthorization*>(request->GetListHandlers()[0]), Ne(nullptr)); ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerDbLastStream*>(request->GetListHandlers()[1]), Ne(nullptr)); } TEST_F(FactoryTests, DeleteStreamRequest) { generic_request_header.op_code = asapo::Opcode::kOpcodeDeleteStream; - auto request = factory.GenerateRequest(generic_request_header, 1, origin_uri, &err); + auto request = factory.GenerateRequest(generic_request_header, 1, origin_uri, nullptr, &err); ASSERT_THAT(err, Eq(nullptr)); ASSERT_THAT(request->GetListHandlers().size(), Eq(2)); - ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerSecondaryAuthorization*>(request->GetListHandlers()[0]), - Ne(nullptr)); + ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerSecondaryAuthorization*>(request->GetListHandlers()[0]), Ne(nullptr)); ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerDbDeleteStream*>(request->GetListHandlers()[1]), Ne(nullptr)); } TEST_F(FactoryTests, GetMetamRequest) { generic_request_header.op_code = asapo::Opcode::kOpcodeGetMeta; - auto request = factory.GenerateRequest(generic_request_header, 1, origin_uri, &err); + auto request = factory.GenerateRequest(generic_request_header, 1, origin_uri, nullptr, &err); ASSERT_THAT(err, Eq(nullptr)); ASSERT_THAT(request->GetListHandlers().size(), Eq(2)); - ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerSecondaryAuthorization*>(request->GetListHandlers()[0]), - Ne(nullptr)); + ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerSecondaryAuthorization*>(request->GetListHandlers()[0]), Ne(nullptr)); ASSERT_THAT(dynamic_cast<const asapo::RequestHandlerDbGetMeta*>(request->GetListHandlers()[1]), Ne(nullptr)); } diff --git a/receiver/unittests/request_handler/test_request_handler_db.cpp b/receiver/unittests/request_handler/test_request_handler_db.cpp index d56fe78f79566b2c2a8be316b3e62c0f875645c8..51a8fb64ed24c6358729a9c43eaf801fff7786d6 100644 --- a/receiver/unittests/request_handler/test_request_handler_db.cpp +++ b/receiver/unittests/request_handler/test_request_handler_db.cpp @@ -46,7 +46,7 @@ class DbHandlerTests : public Test { handler.db_client__ = std::unique_ptr<asapo::Database> {&mock_db}; handler.log__ = &mock_logger; handler.http_client__ = std::unique_ptr<asapo::HttpClient> {&mock_http_client}; - mock_request.reset(new NiceMock<MockRequest> {request_header, 1, "", nullptr}); + mock_request.reset(new NiceMock<MockRequest> {request_header, 1, "", nullptr, nullptr}); ON_CALL(*mock_request, GetBeamtimeId()).WillByDefault(ReturnRef(expected_beamtime_id)); ON_CALL(*mock_request, GetDataSource()).WillByDefault(ReturnRef(expected_stream)); diff --git a/receiver/unittests/request_handler/test_request_handler_db_check_request.cpp b/receiver/unittests/request_handler/test_request_handler_db_check_request.cpp index eb83c4f822c4830830cdf6a095c8fd1d2eda7dc1..64eb44d4e605936d2a999b9f5e3e3dab248afbd1 100644 --- a/receiver/unittests/request_handler/test_request_handler_db_check_request.cpp +++ b/receiver/unittests/request_handler/test_request_handler_db_check_request.cpp @@ -64,7 +64,7 @@ class DbCheckRequestHandlerTests : public Test { request_header.op_code = asapo::Opcode::kOpcodeTransferData; handler.db_client__ = std::unique_ptr<asapo::Database> {&mock_db}; handler.log__ = &mock_logger; - mock_request.reset(new NiceMock<MockRequest> {request_header, 1, "", nullptr}); + mock_request.reset(new NiceMock<MockRequest> {request_header, 1, "", nullptr, nullptr}); config.database_uri = "127.0.0.1:27017"; config.dataserver.advertise_uri = expected_host_uri; config.dataserver.listen_port = expected_port; diff --git a/receiver/unittests/request_handler/test_request_handler_db_get_meta.cpp b/receiver/unittests/request_handler/test_request_handler_db_get_meta.cpp index 8f5e390eda3a6c5727d996a5c2f0a8d2c5dfebb0..f73a40dffca4cb442b45e58038376413a51e0fc3 100644 --- a/receiver/unittests/request_handler/test_request_handler_db_get_meta.cpp +++ b/receiver/unittests/request_handler/test_request_handler_db_get_meta.cpp @@ -39,7 +39,7 @@ class DbMetaGetMetaTests : public Test { GenericRequestHeader request_header; handler.db_client__ = std::unique_ptr<asapo::Database> {&mock_db}; handler.log__ = &mock_logger; - mock_request.reset(new NiceMock<MockRequest> {request_header, 1, "", nullptr}); + mock_request.reset(new NiceMock<MockRequest> {request_header, 1, "", nullptr, nullptr}); SetDefaultRequestCalls(mock_request.get(),expected_beamtime_id); } void TearDown() override { diff --git a/receiver/unittests/request_handler/test_request_handler_db_last_stream.cpp b/receiver/unittests/request_handler/test_request_handler_db_last_stream.cpp index 3c56e9d3d22c54d24c6970fdd8d1849c16c68e1c..abd8ddd6fd97b808b7a7aab0ad32afeb273d2d38 100644 --- a/receiver/unittests/request_handler/test_request_handler_db_last_stream.cpp +++ b/receiver/unittests/request_handler/test_request_handler_db_last_stream.cpp @@ -47,7 +47,7 @@ class DbMetaLastStreamTests : public Test { request_header.data_id = 0; handler.db_client__ = std::unique_ptr<asapo::Database> {&mock_db}; handler.log__ = &mock_logger; - mock_request.reset(new NiceMock<MockRequest> {request_header, 1, "", nullptr}); + mock_request.reset(new NiceMock<MockRequest> {request_header, 1, "", nullptr, nullptr}); SetDefaultRequestCalls(mock_request.get(),expected_beamtime_id); } void TearDown() override { diff --git a/receiver/unittests/request_handler/test_request_handler_db_meta_writer.cpp b/receiver/unittests/request_handler/test_request_handler_db_meta_writer.cpp index b8f9eb4983742b6f45cfeacf4e685932423a5f1b..f72bfad1ca26dabe4573859581ed8996e6edad26 100644 --- a/receiver/unittests/request_handler/test_request_handler_db_meta_writer.cpp +++ b/receiver/unittests/request_handler/test_request_handler_db_meta_writer.cpp @@ -45,7 +45,7 @@ class DbMetaWriterHandlerTests : public Test { request_header.data_id = 0; handler.db_client__ = std::unique_ptr<asapo::Database> {&mock_db}; handler.log__ = &mock_logger; - mock_request.reset(new NiceMock<MockRequest> {request_header, 1, "", nullptr}); + mock_request.reset(new NiceMock<MockRequest> {request_header, 1, "", nullptr, nullptr}); SetDefaultRequestCalls(mock_request.get(),expected_beamtime_id); } void TearDown() override { diff --git a/receiver/unittests/request_handler/test_request_handler_db_stream_info.cpp b/receiver/unittests/request_handler/test_request_handler_db_stream_info.cpp index 2257c44f753ad57da26067bc140640f8aa5b3527..a559fbf4bde592c55e84d9dcbea54054779a78a3 100644 --- a/receiver/unittests/request_handler/test_request_handler_db_stream_info.cpp +++ b/receiver/unittests/request_handler/test_request_handler_db_stream_info.cpp @@ -47,7 +47,7 @@ class DbMetaStreamInfoTests : public Test { request_header.data_id = 0; handler.db_client__ = std::unique_ptr<asapo::Database> {&mock_db}; handler.log__ = &mock_logger; - mock_request.reset(new NiceMock<MockRequest> {request_header, 1, "", nullptr}); + mock_request.reset(new NiceMock<MockRequest> {request_header, 1, "", nullptr, nullptr}); SetDefaultRequestCalls(mock_request.get(),expected_beamtime_id); } void TearDown() override { diff --git a/receiver/unittests/request_handler/test_request_handler_db_writer.cpp b/receiver/unittests/request_handler/test_request_handler_db_writer.cpp index 97102f50c5d07e3528d0cb6ee44391257385d740..22a8558f73b477be773881e653396912edc8a17f 100644 --- a/receiver/unittests/request_handler/test_request_handler_db_writer.cpp +++ b/receiver/unittests/request_handler/test_request_handler_db_writer.cpp @@ -63,7 +63,7 @@ class DbWriterHandlerTests : public Test { request_header.op_code = asapo::Opcode::kOpcodeTransferData; handler.db_client__ = std::unique_ptr<asapo::Database> {&mock_db}; handler.log__ = &mock_logger; - mock_request.reset(new NiceMock<MockRequest> {request_header, 1, "", &mock_db_check_handler}); + mock_request.reset(new NiceMock<MockRequest> {request_header, 1, "", &mock_db_check_handler, nullptr}); config.database_uri = "127.0.0.1:27017"; config.dataserver.advertise_uri = expected_host_ip + ":" + std::to_string(expected_port); config.dataserver.listen_port = expected_port; @@ -88,6 +88,7 @@ MATCHER_P(CompareMessageMeta, file, "") { if (arg.buf_id != file.buf_id) return false; if (arg.dataset_substream != file.dataset_substream) return false; if (arg.name != file.name) return false; + if (arg.stream != file.stream) return false; if (arg.id != file.id) return false; if (arg.metadata != file.metadata) return false; @@ -169,6 +170,7 @@ MessageMeta DbWriterHandlerTests::PrepareMessageMeta(bool substream) { } message_meta.buf_id = expected_buf_id; message_meta.source = expected_host_ip + ":" + std::to_string(expected_port); + message_meta.stream = expected_stream; message_meta.metadata = expected_metadata; return message_meta; } diff --git a/receiver/unittests/request_handler/test_request_handler_delete_stream.cpp b/receiver/unittests/request_handler/test_request_handler_delete_stream.cpp index a98675580e68f109115d8a2295443af7810ff89e..16dc07e87c60094b0b434f6ea88489c8de7386f2 100644 --- a/receiver/unittests/request_handler/test_request_handler_delete_stream.cpp +++ b/receiver/unittests/request_handler/test_request_handler_delete_stream.cpp @@ -39,7 +39,7 @@ class DbMetaDeleteStreamTests : public Test { GenericRequestHeader request_header; handler.db_client__ = std::unique_ptr<asapo::Database> {&mock_db}; handler.log__ = &mock_logger; - mock_request.reset(new NiceMock<MockRequest> {request_header, 1, "", nullptr}); + mock_request.reset(new NiceMock<MockRequest> {request_header, 1, "", nullptr, nullptr}); SetDefaultRequestCalls(mock_request.get(),expected_beamtime_id); } void TearDown() override { diff --git a/receiver/unittests/request_handler/test_request_handler_file_process.cpp b/receiver/unittests/request_handler/test_request_handler_file_process.cpp index d058fab903c193eec12fbeae9ddaf1becf4384d8..de008b8cc8c0adf5344f0d02a309083769e6b06e 100644 --- a/receiver/unittests/request_handler/test_request_handler_file_process.cpp +++ b/receiver/unittests/request_handler/test_request_handler_file_process.cpp @@ -35,7 +35,7 @@ class FileWriteHandlerTests : public Test { void ExpecFileProcess(const asapo::ErrorTemplateInterface* error_template, bool overwrite); void SetUp() override { GenericRequestHeader request_header; - mock_request.reset(new NiceMock<MockRequest>{request_header, 1, "", nullptr}); + mock_request.reset(new NiceMock<MockRequest>{request_header, 1, "", nullptr, nullptr}); handler.io__ = std::unique_ptr<asapo::IO> {&mock_io}; handler.log__ = &mock_logger; SetDefaultRequestCalls(mock_request.get(),""); diff --git a/receiver/unittests/request_handler/test_request_handler_initial_authorization.cpp b/receiver/unittests/request_handler/test_request_handler_initial_authorization.cpp index e758290ddb4d70cb59cbcfbf0308884022e0786c..5fb6efb6412221adfd2a5188d7231aedb74df360 100644 --- a/receiver/unittests/request_handler/test_request_handler_initial_authorization.cpp +++ b/receiver/unittests/request_handler/test_request_handler_initial_authorization.cpp @@ -25,7 +25,7 @@ class InitialAuthorizationHandlerTests : public Test { void SetUp() override { GenericRequestHeader request_header; - mock_request.reset(new MockRequest{request_header, 1, "", nullptr}); + mock_request.reset(new MockRequest{request_header, 1, "", nullptr, nullptr}); handler.auth_client__ = std::unique_ptr<asapo::AuthorizationClient> {&mock_authorization_client}; SetDefaultRequestCalls(mock_request.get(),""); @@ -45,6 +45,7 @@ class InitialAuthorizationHandlerTests : public Test { TEST_F(InitialAuthorizationHandlerTests, AuthorizeOk) { ExpectAuthMocks(); + auto err = handler.ProcessRequest(mock_request.get()); ASSERT_THAT(err, Eq(nullptr)); @@ -71,7 +72,7 @@ TEST_F(InitialAuthorizationHandlerTests, RequestFromUnsupportedClient) { TEST_F(InitialAuthorizationHandlerTests, CheckStatisticEntity) { auto entity = handler.GetStatisticEntity(); - ASSERT_THAT(entity, Eq(asapo::StatisticEntity::kNetwork)); + ASSERT_THAT(entity, Eq(asapo::StatisticEntity::kNetworkIncoming)); } diff --git a/receiver/unittests/request_handler/test_request_handler_kafka_notify.cpp b/receiver/unittests/request_handler/test_request_handler_kafka_notify.cpp index fdd4c299b704c2edb2d8cc4c434b391adf30d851..bfe2471a2c651685cbdcf9cafaf9a99ba879e8d0 100644 --- a/receiver/unittests/request_handler/test_request_handler_kafka_notify.cpp +++ b/receiver/unittests/request_handler/test_request_handler_kafka_notify.cpp @@ -22,7 +22,7 @@ class KafkaNotifyHandlerTests : public Test { void SetUp() override { GenericRequestHeader request_header; - mock_request.reset(new NiceMock<MockRequest> {request_header, 1, "", nullptr}); + mock_request.reset(new NiceMock<MockRequest> {request_header, 1, "", nullptr, nullptr}); } void TearDown() override { diff --git a/receiver/unittests/request_handler/test_request_handler_monitoring.cpp b/receiver/unittests/request_handler/test_request_handler_monitoring.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2a7e4fac51110573fd01b3262581850998a7bb41 --- /dev/null +++ b/receiver/unittests/request_handler/test_request_handler_monitoring.cpp @@ -0,0 +1,120 @@ +#include <gtest/gtest.h> +#include <gmock/gmock.h> +#include <asapo/database/db_error.h> + +#include "asapo/unittests/MockIO.h" +#include "asapo/unittests/MockDatabase.h" +#include "asapo/unittests/MockLogger.h" + +#include "../../src/receiver_error.h" +#include "../../src/request.h" +#include "../../src/request_handler/request_factory.h" +#include "../../src/request_handler/request_handler.h" +#include "../../src/request_handler/request_handler_monitoring.h" + +#include "../mock_receiver_config.h" +#include "asapo/common/data_structs.h" +#include "asapo/common/networking.h" +#include "../receiver_mocking.h" +#include "../monitoring/receiver_monitoring_mocking.h" + +using asapo::MockRequest; +using asapo::MessageMeta; +using ::testing::Test; +using ::testing::Return; +using ::testing::ReturnRef; +using ::testing::_; +using ::testing::DoAll; +using ::testing::SetArgReferee; +using ::testing::Gt; +using ::testing::Eq; +using ::testing::Ne; +using ::testing::Mock; +using ::testing::NiceMock; +using ::testing::StrictMock; +using ::testing::InSequence; +using ::testing::SetArgPointee; +using ::testing::AllOf; +using ::testing::HasSubstr; + + +using ::asapo::Error; +using ::asapo::ErrorInterface; +using ::asapo::FileDescriptor; +using ::asapo::SocketDescriptor; +using ::asapo::MockIO; +using asapo::Request; +using asapo::RequestHandlerDbGetMeta; +using ::asapo::GenericRequestHeader; + +using asapo::MockDatabase; +using asapo::RequestFactory; +using asapo::SetReceiverConfig; +using asapo::ReceiverConfig; + + +namespace { + +class RequestHandlerMonitoringTests : public Test { + public: + std::shared_ptr<StrictMock<asapo::MockReceiverMonitoringClient>> mock_monitoring; + std::unique_ptr<StrictMock<asapo::MockInstancedStatistics>> mock_instanced_statistics; + std::unique_ptr<asapo::RequestHandlerMonitoring> handler; + std::unique_ptr<NiceMock<MockRequest>> mock_request; + NiceMock<MockDatabase> mock_db; + NiceMock<asapo::MockLogger> mock_logger; + ReceiverConfig config; + std::string expected_pipeline_step_id = "pipeline_step_id"; + std::string expected_producer_instance_id = "producer_instance_id"; + std::string expected_beamtime_id = "beamtime_id"; + std::string expected_data_source = "source"; + std::string expected_stream = "stream"; + std::string expected_file_name = "fname"; + + void SetUp() override { + asapo::SharedCache cache; + mock_monitoring.reset(new StrictMock<asapo::MockReceiverMonitoringClient>); + handler.reset(new asapo::RequestHandlerMonitoring(mock_monitoring)); + mock_instanced_statistics.reset(new StrictMock<asapo::MockInstancedStatistics>); + + GenericRequestHeader request_header; + mock_request.reset(new NiceMock<MockRequest> {request_header, 1, "", nullptr, nullptr}); + ON_CALL(*mock_request, GetPipelineStepId()).WillByDefault(ReturnRef(expected_pipeline_step_id)); + ON_CALL(*mock_request, GetProducerInstanceId()).WillByDefault(ReturnRef(expected_producer_instance_id)); + ON_CALL(*mock_request, GetBeamtimeId()).WillByDefault(ReturnRef(expected_beamtime_id)); + ON_CALL(*mock_request, GetDataSource()).WillByDefault(ReturnRef(expected_data_source)); + ON_CALL(*mock_request, GetStream()).WillByDefault(Return(expected_stream)); + ON_CALL(*mock_request, GetFileName()).WillByDefault(Return(expected_file_name)); + ON_CALL(*mock_request, GetStatistics()).WillByDefault(Return(mock_instanced_statistics.get())); + } + void TearDown() override { + } +}; + +TEST_F(RequestHandlerMonitoringTests, ExpectThatMonitoringFunctionIsCalled) { + + EXPECT_CALL(*mock_monitoring, SendProducerToReceiverTransferDataPoint( + expected_pipeline_step_id, expected_producer_instance_id, + expected_beamtime_id, expected_data_source, expected_stream, + 2, 3, 4, 5 + )).Times(1); + + EXPECT_CALL(*mock_instanced_statistics, GetIncomingBytes()).WillOnce( + Return(2) + ); + + EXPECT_CALL(*mock_instanced_statistics, GetElapsedMicrosecondsCount(asapo::StatisticEntity::kNetworkIncoming)).WillOnce( + Return(3) + ); + EXPECT_CALL(*mock_instanced_statistics, GetElapsedMicrosecondsCount(asapo::StatisticEntity::kDisk)).WillOnce( + Return(4) + ); + EXPECT_CALL(*mock_instanced_statistics, GetElapsedMicrosecondsCount(asapo::StatisticEntity::kDatabase)).WillOnce( + Return(5) + ); + + auto err = handler->ProcessRequest(mock_request.get()); + ASSERT_THAT(err, Eq(nullptr)); +} + +} diff --git a/receiver/unittests/request_handler/test_request_handler_receive_data.cpp b/receiver/unittests/request_handler/test_request_handler_receive_data.cpp index 9cf3f34b5e2f3f9a1b85e3188a7f83ebde228192..b0b7f922393e0b128e5c6d0e9714d8041a127731 100644 --- a/receiver/unittests/request_handler/test_request_handler_receive_data.cpp +++ b/receiver/unittests/request_handler/test_request_handler_receive_data.cpp @@ -32,14 +32,18 @@ class ReceiveDataHandlerTests : public Test { uint64_t expected_slot_id{16}; std::string expected_origin_uri = "origin_uri"; std::string expected_metadata = "meta"; + std::string expected_beamtime = "test_beamtime"; + std::string expected_source = "test_source"; + std::string expected_pipelinestepid = "test_pipe_id"; asapo::Opcode expected_op_code = asapo::kOpcodeTransferData; char expected_request_message[asapo::kMaxMessageSize] = "test_message"; + char expected_stream[asapo::kMaxMessageSize] = "test_stream"; std::unique_ptr<Request> request; NiceMock<MockIO> mock_io; MockDataCache mock_cache; RequestHandlerReceiveData handler; NiceMock<asapo::MockLogger> mock_logger; - + StrictMock<asapo::MockInstancedStatistics>* mock_instanced_statistics; void SetUp() override { generic_request_header.data_size = data_size_; @@ -47,7 +51,14 @@ class ReceiveDataHandlerTests : public Test { generic_request_header.op_code = expected_op_code; generic_request_header.custom_data[asapo::kPosIngestMode] = asapo::kDefaultIngestMode; strcpy(generic_request_header.message, expected_request_message); - request.reset(new Request{generic_request_header, socket_fd_, expected_origin_uri, nullptr, nullptr}); + strcpy(generic_request_header.stream, expected_stream); + mock_instanced_statistics = new StrictMock<asapo::MockInstancedStatistics>; + request.reset(new Request{generic_request_header, socket_fd_, expected_origin_uri, nullptr, nullptr, + std::unique_ptr<asapo::MockInstancedStatistics>{mock_instanced_statistics}}); + request->SetBeamtimeId(expected_beamtime); + request->SetPipelineStepId(expected_pipelinestepid); + request->SetDataSource(expected_source); + handler.io__ = std::unique_ptr<asapo::IO> {&mock_io}; handler.log__ = &mock_logger; } @@ -70,9 +81,9 @@ void ReceiveDataHandlerTests::ExpectReceive(uint64_t expected_size, bool ok) { DoAll( CopyStr(expected_metadata), SetArgPointee<3>(ok ? nullptr : new asapo::IOError("Test Read Error", "", asapo::IOErrorType::kReadError)), - Return(0) + Return(ok ? expected_size : 0) )); - + EXPECT_CALL(*mock_instanced_statistics, AddIncomingBytes(ok ? expected_size : 0)); } void ReceiveDataHandlerTests::ExpectReceiveData(bool ok) { ExpectReceive(data_size_, ok); @@ -80,13 +91,13 @@ void ReceiveDataHandlerTests::ExpectReceiveData(bool ok) { TEST_F(ReceiveDataHandlerTests, CheckStatisticEntity) { auto entity = handler.GetStatisticEntity(); - ASSERT_THAT(entity, Eq(asapo::StatisticEntity::kNetwork)); + ASSERT_THAT(entity, Eq(asapo::StatisticEntity::kNetworkIncoming)); } TEST_F(ReceiveDataHandlerTests, HandleDoesNotReceiveEmptyData) { generic_request_header.data_size = 0; - request.reset(new Request{generic_request_header, socket_fd_, "", nullptr, nullptr}); + request.reset(new Request{generic_request_header, socket_fd_, "", nullptr, nullptr, nullptr}); EXPECT_CALL(mock_io, Receive_t(_, _, _, _)).Times(0); @@ -99,7 +110,7 @@ TEST_F(ReceiveDataHandlerTests, HandleDoesNotReceiveEmptyData) { TEST_F(ReceiveDataHandlerTests, HandleDoesNotReceiveDataWhenMetadataOnlyWasSent) { generic_request_header.data_size = 10; generic_request_header.custom_data[asapo::kPosIngestMode] = asapo::kTransferMetaDataOnly; - request.reset(new Request{generic_request_header, socket_fd_, "", nullptr, nullptr}); + request.reset(new Request{generic_request_header, socket_fd_, "", nullptr, nullptr, nullptr}); auto err = handler.ProcessRequest(request.get()); @@ -122,25 +133,31 @@ TEST_F(ReceiveDataHandlerTests, HandleGetsMemoryFromCache) { request->cache__ = &mock_cache; asapo::CacheMeta meta; meta.id = expected_slot_id; - EXPECT_CALL(mock_cache, GetFreeSlotAndLock_t(data_size_, _, _)).WillOnce( + EXPECT_CALL(mock_cache, GetFreeSlotAndLock_t(data_size_, _, expected_beamtime, expected_source, expected_stream,_)).WillOnce( DoAll(SetArgPointee<1>(&meta), - SetArgPointee<2>(nullptr), + SetArgPointee<5>(nullptr), Return(&mock_cache) )); + EXPECT_CALL(*mock_instanced_statistics, AddIncomingBytes(0)); auto err = handler.ProcessRequest(request.get()); ASSERT_THAT(request->GetSlotId(), Eq(expected_slot_id)); + ASSERT_THAT(err, Eq(nullptr)); + } TEST_F(ReceiveDataHandlerTests, ErrorGetMemoryFromCache) { request->cache__ = &mock_cache; - EXPECT_CALL(mock_cache, GetFreeSlotAndLock_t(data_size_, _,_)).WillOnce( - DoAll(SetArgPointee<2>(asapo::ReceiverErrorTemplates::kProcessingError.Generate().release()), + EXPECT_CALL(mock_cache, GetFreeSlotAndLock_t(data_size_, _, expected_beamtime, expected_source, expected_stream,_)).WillOnce( + DoAll(SetArgPointee<5>(asapo::ReceiverErrorTemplates::kProcessingError.Generate().release()), Return(nullptr) - )); + )); + + EXPECT_CALL(*mock_instanced_statistics, AddIncomingBytes(0)); + auto err = handler.ProcessRequest(request.get()); @@ -148,6 +165,4 @@ TEST_F(ReceiveDataHandlerTests, ErrorGetMemoryFromCache) { ASSERT_THAT(err, Eq(nullptr)); } - - } diff --git a/receiver/unittests/request_handler/test_request_handler_receive_metadata.cpp b/receiver/unittests/request_handler/test_request_handler_receive_metadata.cpp index 0b15844d47183ea15cb24edda92596dafa46030d..d0f27fd8d272949ced71cc15fde8065b7239e313 100644 --- a/receiver/unittests/request_handler/test_request_handler_receive_metadata.cpp +++ b/receiver/unittests/request_handler/test_request_handler_receive_metadata.cpp @@ -40,6 +40,7 @@ class ReceiveMetaDataHandlerTests : public Test { NiceMock<MockIO> mock_io; RequestHandlerReceiveMetaData handler; NiceMock<asapo::MockLogger> mock_logger; + StrictMock<asapo::MockInstancedStatistics>* mock_instanced_statistics; void SetUp() override { generic_request_header.data_size = data_size_; @@ -47,7 +48,9 @@ class ReceiveMetaDataHandlerTests : public Test { generic_request_header.meta_size = expected_metadata_size; generic_request_header.op_code = expected_op_code; generic_request_header.custom_data[asapo::kPosIngestMode] = asapo::kDefaultIngestMode; - request.reset(new Request{generic_request_header, socket_fd_, expected_origin_uri, nullptr, nullptr}); + mock_instanced_statistics = new StrictMock<asapo::MockInstancedStatistics>; + request.reset(new Request{generic_request_header, socket_fd_, expected_origin_uri, nullptr, nullptr, + std::unique_ptr<asapo::MockInstancedStatistics>{mock_instanced_statistics}}); handler.io__ = std::unique_ptr<asapo::IO> {&mock_io}; handler.log__ = &mock_logger; } @@ -70,9 +73,9 @@ void ReceiveMetaDataHandlerTests::ExpectReceive(uint64_t expected_size, bool ok) DoAll( CopyStr(expected_metadata), SetArgPointee<3>(ok ? nullptr : new asapo::IOError("Test Read Error", "", asapo::IOErrorType::kReadError)), - Return(0) + Return(ok ? expected_size : 0) )); - + EXPECT_CALL(*mock_instanced_statistics, AddIncomingBytes(ok ? expected_size : 0)); } void ReceiveMetaDataHandlerTests::ExpectReceiveMetaData(bool ok) { @@ -81,7 +84,7 @@ void ReceiveMetaDataHandlerTests::ExpectReceiveMetaData(bool ok) { TEST_F(ReceiveMetaDataHandlerTests, CheckStatisticEntity) { auto entity = handler.GetStatisticEntity(); - ASSERT_THAT(entity, Eq(asapo::StatisticEntity::kNetwork)); + ASSERT_THAT(entity, Eq(asapo::StatisticEntity::kNetworkIncoming)); } TEST_F(ReceiveMetaDataHandlerTests, HandleReturnsErrorOnMetaDataReceive) { diff --git a/receiver/unittests/request_handler/test_request_handler_secondary_authorization.cpp b/receiver/unittests/request_handler/test_request_handler_secondary_authorization.cpp index 0e28dcbbeada20f7652a8220f30f53948ad816f4..8adea4721aced4f413577c4c8fb0de61d812b133 100644 --- a/receiver/unittests/request_handler/test_request_handler_secondary_authorization.cpp +++ b/receiver/unittests/request_handler/test_request_handler_secondary_authorization.cpp @@ -29,7 +29,9 @@ class SecondaryAuthorizationHandlerTests : public Test { std::unique_ptr<NiceMock<MockRequest>> mock_request; std::string expected_source_credentials = "source_creds"; - std::string expected_beamtime_id = "expected_beamtime"; + std::string expected_instance_id = "expected_instance_id"; + std::string expected_pipeline_step_id = "expected_pipeline_step_id"; + std::string expected_beamtime_id = "expected_beamtime_id"; std::string expected_beamline = "expected_beamline"; std::string expected_data_source = "expected_data_source"; std::string expected_beamline_path = "expected_beamline_path"; @@ -45,10 +47,12 @@ class SecondaryAuthorizationHandlerTests : public Test { auth_data.online_path = expected_beamline_path; auth_data.offline_path = expected_core_path; auth_data.beamline = expected_beamline; + auth_data.producer_instance_id = expected_instance_id; + auth_data.pipeline_step_id = expected_pipeline_step_id; auth_data.source_credentials = expected_source_credentials; GenericRequestHeader request_header; - mock_request.reset(new NiceMock<MockRequest> {request_header, 1, "", nullptr}); + mock_request.reset(new NiceMock<MockRequest> {request_header, 1, "", nullptr, nullptr}); handler.auth_client__ = std::unique_ptr<asapo::AuthorizationClient> {&mock_authorization_client}; config.authorization_interval_ms = 10000; SetReceiverConfig(config, "none"); @@ -58,6 +62,8 @@ class SecondaryAuthorizationHandlerTests : public Test { } void ExpectAuth(); void ExpectSetRequest() { + EXPECT_CALL(*mock_request, SetProducerInstanceId(expected_instance_id)); + EXPECT_CALL(*mock_request, SetPipelineStepId(expected_pipeline_step_id)); EXPECT_CALL(*mock_request, SetBeamtimeId(expected_beamtime_id)); EXPECT_CALL(*mock_request, SetBeamline(expected_beamline)); EXPECT_CALL(*mock_request, SetDataSource(expected_data_source)); diff --git a/receiver/unittests/request_handler/test_requests_dispatcher.cpp b/receiver/unittests/request_handler/test_requests_dispatcher.cpp index d5c7ead18205916bc0d1019225d22385f9ed739d..fd1bd2149d5dd0e676e868b3fd114d358a4fde94 100644 --- a/receiver/unittests/request_handler/test_requests_dispatcher.cpp +++ b/receiver/unittests/request_handler/test_requests_dispatcher.cpp @@ -11,6 +11,7 @@ #include "../../src/request_handler/requests_dispatcher.h" #include "asapo/database/db_error.h" +#include "../../src/monitoring/receiver_monitoring_client_noop.h" using namespace testing; @@ -20,7 +21,11 @@ namespace { TEST(RequestDispatcher, Constructor) { auto stat = std::unique_ptr<ReceiverStatistics> {new ReceiverStatistics}; - RequestsDispatcher dispatcher{0, "some_address", stat.get(), nullptr, nullptr}; + auto cache = asapo::SharedCache{new asapo::DataCache{0, 0}}; + + auto monitoring = asapo::SharedReceiverMonitoringClient{new asapo::ReceiverMonitoringClientNoop{}}; + + RequestsDispatcher dispatcher{0, "some_address", stat.get(), monitoring, cache, nullptr}; ASSERT_THAT(dynamic_cast<const asapo::ReceiverStatistics*>(dispatcher.statistics__), Ne(nullptr)); ASSERT_THAT(dynamic_cast<asapo::IO*>(dispatcher.io__.get()), Ne(nullptr)); ASSERT_THAT(dynamic_cast<asapo::RequestFactory*>(dispatcher.request_factory__.get()), Ne(nullptr)); @@ -30,28 +35,31 @@ TEST(RequestDispatcher, Constructor) { class MockRequest: public Request { public: MockRequest(const GenericRequestHeader& request_header, SocketDescriptor socket_fd, std::string uri = ""): - Request(request_header, socket_fd, uri, nullptr, nullptr) {}; - Error Handle(ReceiverStatistics*) override { + Request(request_header, socket_fd, uri, nullptr, nullptr, nullptr) {}; + Error Handle() override { return Error{Handle_t()}; }; MOCK_CONST_METHOD0(Handle_t, ErrorInterface * ()); + MOCK_METHOD0(GetStatistics, asapo::RequestStatistics*()); }; class MockRequestFactory: public asapo::RequestFactory { public: - MockRequestFactory(): RequestFactory(nullptr, nullptr) {}; + MockRequestFactory(): RequestFactory(nullptr, nullptr, nullptr) {}; std::unique_ptr<Request> GenerateRequest(const GenericRequestHeader& request_header, SocketDescriptor socket_fd, std::string origin_uri, + asapo::RequestStatisticsPtr statistics, Error* err) const noexcept override { ErrorInterface* error = nullptr; - auto res = GenerateRequest_t(request_header, socket_fd, origin_uri, &error); + auto res = GenerateRequest_t(request_header, socket_fd, origin_uri, statistics.get(), &error); err->reset(error); return std::unique_ptr<Request> {res}; } - MOCK_CONST_METHOD4(GenerateRequest_t, Request * (const GenericRequestHeader&, + MOCK_CONST_METHOD5(GenerateRequest_t, Request * (const GenericRequestHeader&, SocketDescriptor, std::string, + const asapo::RequestStatistics* statistics, ErrorInterface**)); }; @@ -69,7 +77,7 @@ class RequestsDispatcherTests : public Test { std::string connected_uri{"some_address"}; NiceMock<MockIO> mock_io; MockRequestFactory mock_factory; - NiceMock<MockStatistics> mock_statictics; + StrictMock<MockStatistics> mock_statistics; NiceMock<asapo::MockLogger> mock_logger; asapo::ReceiverConfig test_config; @@ -77,12 +85,17 @@ class RequestsDispatcherTests : public Test { MockRequest mock_request{GenericRequestHeader{}, 1, connected_uri}; std::unique_ptr<Request> request{&mock_request}; GenericNetworkResponse response; + + std::unique_ptr<StrictMock<asapo::MockInstancedStatistics>> mock_instanced_statistics; + + void SetUp() override { + mock_instanced_statistics.reset(new StrictMock<asapo::MockInstancedStatistics>); test_config.authorization_interval_ms = 0; SetReceiverConfig(test_config, "none"); - dispatcher = std::unique_ptr<RequestsDispatcher> {new RequestsDispatcher{0, connected_uri, &mock_statictics, nullptr, nullptr}}; + dispatcher = std::unique_ptr<RequestsDispatcher> {new RequestsDispatcher{0, connected_uri, &mock_statistics, nullptr, nullptr, nullptr}}; dispatcher->io__ = std::unique_ptr<asapo::IO> {&mock_io}; - dispatcher->statistics__ = &mock_statictics; + dispatcher->statistics__ = &mock_statistics; dispatcher->request_factory__ = std::unique_ptr<asapo::RequestFactory> {&mock_factory}; dispatcher->log__ = &mock_logger; @@ -104,9 +117,9 @@ class RequestsDispatcherTests : public Test { } void MockCreateRequest(bool error ) { - EXPECT_CALL(mock_factory, GenerateRequest_t(_, _, _, _)) + EXPECT_CALL(mock_factory, GenerateRequest_t(_, _, _, _, _)) .WillOnce( - DoAll(SetArgPointee<3>(error ? asapo::ReceiverErrorTemplates::kInvalidOpCode.Generate().release() : nullptr), + DoAll(SetArgPointee<4>(error ? asapo::ReceiverErrorTemplates::kInvalidOpCode.Generate().release() : nullptr), Return(nullptr)) ); if (error) { @@ -126,6 +139,10 @@ class RequestsDispatcherTests : public Test { } else if (error_mode == 2) { EXPECT_CALL(mock_logger, Warning(_)); } + + EXPECT_CALL(mock_request, GetStatistics()).WillRepeatedly( + Return(mock_instanced_statistics.get()) + ); } void MockSendResponse(GenericNetworkResponse* response, bool error ) { EXPECT_CALL(mock_logger, Debug(AllOf(HasSubstr("sending response"), HasSubstr(connected_uri)))); @@ -144,7 +161,6 @@ class RequestsDispatcherTests : public Test { TEST_F(RequestsDispatcherTests, ErrorReceivetNextRequest) { - EXPECT_CALL(mock_statictics, StartTimer_t(StatisticEntity::kNetwork)); MockReceiveRequest(true); Error err; @@ -155,7 +171,6 @@ TEST_F(RequestsDispatcherTests, ErrorReceivetNextRequest) { TEST_F(RequestsDispatcherTests, ClosedConnectionOnReceivetNextRequest) { - EXPECT_CALL(mock_statictics, StartTimer_t(StatisticEntity::kNetwork)); EXPECT_CALL(mock_io, Receive_t(_, _, _, _)) .WillOnce( DoAll(SetArgPointee<3>(asapo::GeneralErrorTemplates::kEndOfFile.Generate().release()), diff --git a/receiver/unittests/statistics/test_receiver_statistics.cpp b/receiver/unittests/statistics/test_receiver_statistics.cpp index 2956fb98014612bf82171a4b70cff5df6abc5441..1758379f874fcd368995417b3e7ba68e8459b649 100644 --- a/receiver/unittests/statistics/test_receiver_statistics.cpp +++ b/receiver/unittests/statistics/test_receiver_statistics.cpp @@ -7,6 +7,8 @@ #include "../../src/statistics/statistics_sender_influx_db.h" #include "../../src/statistics/statistics_sender_fluentd.h" #include "../receiver_mocking.h" +#include "../../src/receiver_config.h" +#include "../mock_receiver_config.h" using namespace testing; @@ -27,6 +29,10 @@ class ReceiverStatisticTests : public Test { void TestTimer(const StatisticEntity& entity); MockStatisticsSender mock_statistics_sender; void SetUp() override { + asapo::ReceiverConfig test_config; + test_config.monitor_performance = true; + asapo::SetReceiverConfig(test_config, "none"); + statistics.statistics_sender_list__.clear(); statistics.statistics_sender_list__.emplace_back(&mock_statistics_sender); } @@ -58,57 +64,108 @@ StatisticsToSend ReceiverStatisticTests::ExtractStat() { stat.data_volume = 0; EXPECT_CALL(mock_statistics_sender, SendStatistics_t(_)). - WillOnce(SaveArg1ToSendStatR(&stat)); + WillOnce(SaveArg1ToSendStatR(&stat)); - statistics.SendIfNeeded(); + statistics.SendIfNeeded(false); return stat; } void ReceiverStatisticTests::TestTimer(const StatisticEntity& entity) { - statistics.StartTimer(entity); + asapo::RequestStatisticsPtr instancedStatistics{new asapo::RequestStatistics}; + + instancedStatistics->StartTimer(entity); std::this_thread::sleep_for(std::chrono::milliseconds(10)); + instancedStatistics->StopTimer(); - statistics.StopTimer(); + statistics.ApplyTimeFrom(instancedStatistics.get()); auto stat = ExtractStat(); + ASSERT_THAT(stat.extra_entities.size(), Gt(static_cast<size_t>(entity))); ASSERT_THAT(stat.extra_entities[static_cast<size_t>(entity)].second, Gt(0)); ASSERT_THAT(stat.extra_entities[static_cast<size_t>(entity)].second, Le(1.0)); - } TEST_F(ReceiverStatisticTests, TimerForDatabase) { TestTimer(StatisticEntity::kDatabase); } -TEST_F(ReceiverStatisticTests, TimerForNetwork) { - TestTimer(StatisticEntity::kNetwork); +TEST_F(ReceiverStatisticTests, TimerForNetworkIncoming) { + TestTimer(StatisticEntity::kNetworkIncoming); +} + +TEST_F(ReceiverStatisticTests, TimerForNetworkOutgoing) { + TestTimer(StatisticEntity::kNetworkOutgoing); } TEST_F(ReceiverStatisticTests, TimerForDisk) { TestTimer(StatisticEntity::kDisk); } +TEST_F(ReceiverStatisticTests, TimerForMonitoring) { + TestTimer(StatisticEntity::kMonitoring); +} + +TEST_F(ReceiverStatisticTests, ByteCounter) { + asapo::RequestStatisticsPtr instancedStatistics{new asapo::RequestStatistics}; + + instancedStatistics->AddIncomingBytes(53); + instancedStatistics->AddIncomingBytes(23); + + instancedStatistics->AddOutgoingBytes(5); + instancedStatistics->AddOutgoingBytes(7); + + ASSERT_THAT(instancedStatistics->GetIncomingBytes(), Eq(76)); + ASSERT_THAT(instancedStatistics->GetOutgoingBytes(), Eq(12)); +} + TEST_F(ReceiverStatisticTests, TimerForAll) { - statistics.StartTimer(StatisticEntity::kDatabase); + asapo::RequestStatisticsPtr instancedStatistics{new asapo::RequestStatistics}; + + // kDatabase + instancedStatistics->StartTimer(StatisticEntity::kDatabase); std::this_thread::sleep_for(std::chrono::milliseconds(20)); - statistics.StopTimer(); - statistics.StartTimer(StatisticEntity::kNetwork); + instancedStatistics->StopTimer(); + + // kNetworkIncoming + instancedStatistics->StartTimer(StatisticEntity::kNetworkIncoming); std::this_thread::sleep_for(std::chrono::milliseconds(30)); - statistics.StopTimer(); + instancedStatistics->StopTimer(); - statistics.StartTimer(StatisticEntity::kDisk); + // kNetworkOutgoing + instancedStatistics->StartTimer(StatisticEntity::kNetworkOutgoing); std::this_thread::sleep_for(std::chrono::milliseconds(40)); - statistics.StopTimer(); + instancedStatistics->StopTimer(); + + // kDisk + instancedStatistics->StartTimer(StatisticEntity::kDisk); + std::this_thread::sleep_for(std::chrono::milliseconds(30)); + instancedStatistics->StopTimer(); + + // kMonitoring + instancedStatistics->StartTimer(StatisticEntity::kMonitoring); + std::this_thread::sleep_for(std::chrono::milliseconds(30)); + instancedStatistics->StopTimer(); + + statistics.ApplyTimeFrom(instancedStatistics.get()); auto stat = ExtractStat(); + ASSERT_THAT(stat.extra_entities.size(), Gt(static_cast<size_t>(StatisticEntity::kDatabase))); ASSERT_THAT(stat.extra_entities[StatisticEntity::kDatabase].second, Gt(0)); - ASSERT_THAT(stat.extra_entities[StatisticEntity::kNetwork].second, Gt(0)); + ASSERT_THAT(stat.extra_entities.size(), Gt(static_cast<size_t>(StatisticEntity::kNetworkIncoming))); + ASSERT_THAT(stat.extra_entities[StatisticEntity::kNetworkIncoming].second, Gt(0)); + ASSERT_THAT(stat.extra_entities.size(), Gt(static_cast<size_t>(StatisticEntity::kNetworkOutgoing))); + ASSERT_THAT(stat.extra_entities[StatisticEntity::kNetworkOutgoing].second, Gt(0)); + + ASSERT_THAT(stat.extra_entities.size(), Gt(static_cast<size_t>(StatisticEntity::kDisk))); ASSERT_THAT(stat.extra_entities[StatisticEntity::kDisk].second, Gt(0)); + + ASSERT_THAT(stat.extra_entities.size(), Gt(static_cast<size_t>(StatisticEntity::kMonitoring))); + ASSERT_THAT(stat.extra_entities[StatisticEntity::kMonitoring].second, Gt(0)); } } diff --git a/receiver/unittests/statistics/test_statistics.cpp b/receiver/unittests/statistics/test_statistics.cpp index 74756dcd0a0cc6fbd4c2476106db8883a7e4ecd0..4f7fe320acd45e42720994256fec519ade356ff3 100644 --- a/receiver/unittests/statistics/test_statistics.cpp +++ b/receiver/unittests/statistics/test_statistics.cpp @@ -79,6 +79,7 @@ TEST_F(StatisticTests, AddTag) { auto stat = ExtractStat(); + ASSERT_THAT(stat.tags.size(), Eq(1)); ASSERT_THAT(stat.tags[0].first, Eq("name")); ASSERT_THAT(stat.tags[0].second, Eq("value")); @@ -90,6 +91,7 @@ TEST_F(StatisticTests, AddTagTwice) { auto stat = ExtractStat(); + ASSERT_THAT(stat.tags.size(), Eq(2)); ASSERT_THAT(stat.tags[0].first, Eq("name1")); ASSERT_THAT(stat.tags[0].second, Eq("value1")); ASSERT_THAT(stat.tags[1].first, Eq("name2")); diff --git a/receiver/unittests/statistics/test_statistics_sender_fluentd.cpp b/receiver/unittests/statistics/test_statistics_sender_fluentd.cpp index 5b749f55d5990e7688253b79481ef8ddb396cb0b..bd25b3492d264451b2bf10c52985884028659acf 100644 --- a/receiver/unittests/statistics/test_statistics_sender_fluentd.cpp +++ b/receiver/unittests/statistics/test_statistics_sender_fluentd.cpp @@ -37,9 +37,10 @@ class SenderFluentdTests : public Test { statistics.n_requests = 4; statistics.extra_entities.push_back(asapo::ExtraEntity{asapo::kStatisticEntityNames[asapo::StatisticEntity::kDatabase], 0.1}); - statistics.extra_entities.push_back(asapo::ExtraEntity{asapo::kStatisticEntityNames[asapo::StatisticEntity::kNetwork], 0.3}); + statistics.extra_entities.push_back(asapo::ExtraEntity{asapo::kStatisticEntityNames[asapo::StatisticEntity::kNetworkIncoming], 0.3}); + statistics.extra_entities.push_back(asapo::ExtraEntity{asapo::kStatisticEntityNames[asapo::StatisticEntity::kNetworkOutgoing], 0.9}); statistics.extra_entities.push_back(asapo::ExtraEntity{asapo::kStatisticEntityNames[asapo::StatisticEntity::kDisk], 0.6}); - + statistics.extra_entities.push_back(asapo::ExtraEntity{asapo::kStatisticEntityNames[asapo::StatisticEntity::kMonitoring], 0.2}); statistics.elapsed_ms = 100; statistics.data_volume = 1000; @@ -62,7 +63,7 @@ class SenderFluentdTests : public Test { TEST_F(SenderFluentdTests, SendStatisticsCallsPost) { std::string expect_string = R"("@target_type_key":"stat","name1":"value1","name2":"value2","elapsed_ms":100,"data_volume":1000)" - R"(,"n_requests":4,"db_share":0.1000,"network_share":0.3000,"disk_share":0.6000)"; + R"(,"n_requests":4,"db_share":0.1000,"network_incoming_share":0.3000,"network_outgoing_share":0.9000,"disk_share":0.6000,"monitoring":0.2000)"; EXPECT_CALL(mock_logger, Info(HasSubstr(expect_string))); diff --git a/receiver/unittests/statistics/test_statistics_sender_influx_db.cpp b/receiver/unittests/statistics/test_statistics_sender_influx_db.cpp index d6c2eb77997b113e0c985b112e89050e7896d951..cca2629a48be9869ffbd3c2f9bbfccfb28c7593a 100644 --- a/receiver/unittests/statistics/test_statistics_sender_influx_db.cpp +++ b/receiver/unittests/statistics/test_statistics_sender_influx_db.cpp @@ -38,8 +38,10 @@ class SenderInfluxDbTests : public Test { statistics.n_requests = 4; statistics.extra_entities.push_back(asapo::ExtraEntity{asapo::kStatisticEntityNames[asapo::StatisticEntity::kDatabase], 0.1}); - statistics.extra_entities.push_back(asapo::ExtraEntity{asapo::kStatisticEntityNames[asapo::StatisticEntity::kNetwork], 0.3}); + statistics.extra_entities.push_back(asapo::ExtraEntity{asapo::kStatisticEntityNames[asapo::StatisticEntity::kNetworkIncoming], 0.3}); + statistics.extra_entities.push_back(asapo::ExtraEntity{asapo::kStatisticEntityNames[asapo::StatisticEntity::kNetworkOutgoing], 0.9}); statistics.extra_entities.push_back(asapo::ExtraEntity{asapo::kStatisticEntityNames[asapo::StatisticEntity::kDisk], 0.6}); + statistics.extra_entities.push_back(asapo::ExtraEntity{asapo::kStatisticEntityNames[asapo::StatisticEntity::kMonitoring], 0.2}); statistics.elapsed_ms = 100; statistics.data_volume = 1000; @@ -61,7 +63,7 @@ class SenderInfluxDbTests : public Test { TEST_F(SenderInfluxDbTests, SendStatisticsCallsPost) { std::string expect_string = "statistics,name1=value1,name2=value2 elapsed_ms=100,data_volume=1000," - "n_requests=4,db_share=0.1000,network_share=0.3000,disk_share=0.6000"; + "n_requests=4,db_share=0.1000,network_incoming_share=0.3000,network_outgoing_share=0.9000,disk_share=0.6000,monitoring=0.2000"; EXPECT_CALL(mock_http_client, Post_t("test_uri/write?db=test_name", _, expect_string, _, _)). WillOnce( DoAll(SetArgPointee<4>(new asapo::IOError("Test Read Error", "", asapo::IOErrorType::kReadError)), diff --git a/receiver/unittests/test_config.cpp b/receiver/unittests/test_config.cpp index 289113eaffcbf02e2d1bbd8b9ebdce0ba69919c9..904f4b7d51ebe9b9ddb4187c9c3b2f05eff96055 100644 --- a/receiver/unittests/test_config.cpp +++ b/receiver/unittests/test_config.cpp @@ -53,7 +53,7 @@ class ConfigTests : public Test { TEST_F(ConfigTests, ReadSettings) { PrepareConfig(); - auto err = asapo::SetReceiverConfig(test_config, "none"); + auto err = asapo::SetReceiverConfigWithError(test_config, "none"); auto config = GetReceiverConfig(); @@ -96,7 +96,7 @@ TEST_F(ConfigTests, ErrorReadSettings) { "NThreads", "DiscoveryServer", "AdvertiseURI", "NetworkMode", "MonitorPerformance", "ReceiveToDiskThresholdMB", "Metrics", "Expose","Enabled"}; for (const auto& field : fields) { - auto err = asapo::SetReceiverConfig(test_config, field); + auto err = asapo::SetReceiverConfigWithError(test_config, field); ASSERT_THAT(err, Ne(nullptr)); } } diff --git a/receiver/unittests/test_connection.cpp b/receiver/unittests/test_connection.cpp index 4f73aaa17bc3e2ba1faa7a6a72b036a0ba1b265e..48b5ff34277621e7460efa759b6b680a5e5dd7b3 100644 --- a/receiver/unittests/test_connection.cpp +++ b/receiver/unittests/test_connection.cpp @@ -7,6 +7,7 @@ #include "../src/connection.h" #include "receiver_mocking.h" #include "../src/receiver_config.h" +#include "monitoring/receiver_monitoring_mocking.h" using namespace testing; using namespace asapo; @@ -14,7 +15,7 @@ using namespace asapo; namespace { TEST(Connection, Constructor) { - Connection connection{0, "some_address", nullptr, nullptr, "some_tag"}; + Connection connection{0, "some_address", nullptr, nullptr,nullptr, "some_tag"}; ASSERT_THAT(dynamic_cast<asapo::Statistics*>(connection.statistics__.get()), Ne(nullptr)); ASSERT_THAT(dynamic_cast<asapo::IO*>(connection.io__.get()), Ne(nullptr)); ASSERT_THAT(dynamic_cast<const asapo::AbstractLogger*>(connection.log__), Ne(nullptr)); @@ -24,7 +25,7 @@ TEST(Connection, Constructor) { class MockDispatcher: public asapo::RequestsDispatcher { public: - MockDispatcher(): asapo::RequestsDispatcher(0, "", nullptr, nullptr, nullptr) {}; + MockDispatcher(): asapo::RequestsDispatcher(0, "", nullptr, nullptr, nullptr, nullptr) {}; Error ProcessRequest(const std::unique_ptr<Request>& request) const noexcept override { return Error{ProcessRequest_t(request.get())}; } @@ -50,9 +51,12 @@ class ConnectionTests : public Test { NiceMock<MockStatistics> mock_statictics; NiceMock<asapo::MockLogger> mock_logger; std::unique_ptr<Connection> connection; + std::shared_ptr<NiceMock<asapo::MockReceiverMonitoringClient>> mock_monitoring; void SetUp() override { - connection = std::unique_ptr<Connection> {new Connection{0, connected_uri, nullptr, nullptr, "some_tag"}}; + asapo::SharedCache cache; /*nullptr*/ + mock_monitoring.reset(new NiceMock<asapo::MockReceiverMonitoringClient>); + connection = std::unique_ptr<Connection> {new Connection{0, connected_uri, mock_monitoring, cache,nullptr, "some_tag"}}; connection->io__ = std::unique_ptr<asapo::IO> {&mock_io}; connection->statistics__ = std::unique_ptr<asapo::ReceiverStatistics> {&mock_statictics}; connection->log__ = &mock_logger; @@ -77,8 +81,7 @@ class ConnectionTests : public Test { )); return nullptr; } else { - auto request = new Request(GenericRequestHeader{asapo::kOpcodeUnknownOp, 0, 1, 0, ""}, 0, connected_uri, nullptr, - nullptr); + auto request = new Request(GenericRequestHeader{asapo::kOpcodeUnknownOp, 0, 1, 0, ""}, 0, connected_uri, nullptr, nullptr, nullptr); EXPECT_CALL(mock_dispatcher, GetNextRequest_t(_)) .WillOnce(DoAll( SetArgPointee<0>(nullptr), diff --git a/receiver/unittests/test_datacache.cpp b/receiver/unittests/test_datacache.cpp index f0e1e2d81f1d2f6bf30e85217f5538f5e6cb17fc..9a7f400a33a5fe23933ae47fff64ce0841ae62ad 100644 --- a/receiver/unittests/test_datacache.cpp +++ b/receiver/unittests/test_datacache.cpp @@ -31,7 +31,7 @@ class DataCacheTests : public Test { TEST_F(DataCacheTests, GetFreeSlotFailsDueToSize) { asapo::Error err; - auto addr = cache.GetFreeSlotAndLock(expected_cache_size + 1, &meta1,&err); + auto addr = cache.GetFreeSlotAndLock(expected_cache_size + 1, &meta1, "b", "so", "st", &err); ASSERT_THAT(addr, Eq(nullptr)); ASSERT_THAT(err, Ne(nullptr)); } @@ -44,7 +44,7 @@ void set_array(uint8_t* addr, uint64_t size, uint8_t val) { TEST_F(DataCacheTests, GetFreeSlotOK) { asapo::Error err; - uint8_t* addr = (uint8_t*) cache.GetFreeSlotAndLock(1, &meta1,&err); + uint8_t* addr = (uint8_t*) cache.GetFreeSlotAndLock(1, &meta1, "b", "so", "st", &err); set_array(addr, 1, 2); ASSERT_THAT(addr[0], Eq(2)); ASSERT_THAT(meta1->id, Gt(0)); @@ -52,9 +52,9 @@ TEST_F(DataCacheTests, GetFreeSlotOK) { TEST_F(DataCacheTests, GetFreeSlotStartsFromLastPointer) { asapo::Error err; - uint8_t* ini_addr = (uint8_t*) cache.GetFreeSlotAndLock(1, &meta1,&err); + uint8_t* ini_addr = (uint8_t*) cache.GetFreeSlotAndLock(1, &meta1, "b", "so", "st", &err); set_array(ini_addr, 1, 2); - uint8_t* addr = (uint8_t*) cache.GetFreeSlotAndLock(1, &meta2,&err); + uint8_t* addr = (uint8_t*) cache.GetFreeSlotAndLock(1, &meta2, "b", "so", "st", &err); set_array(addr, 1, 1); ASSERT_THAT(ini_addr[0], Eq(2)); ASSERT_THAT(ini_addr[1], Eq(1)); @@ -63,22 +63,21 @@ TEST_F(DataCacheTests, GetFreeSlotStartsFromLastPointer) { TEST_F(DataCacheTests, GetFreeSlotLocks) { asapo::Error err; - uint8_t* ini_addr = (uint8_t*) cache.GetFreeSlotAndLock(1, &meta1,&err); - uint8_t* addr = (uint8_t*) cache.GetFreeSlotAndLock(expected_cache_size, &meta2,&err); + uint8_t* ini_addr = (uint8_t*) cache.GetFreeSlotAndLock(1, &meta1, "b", "so", "st", &err); + uint8_t* addr = (uint8_t*) cache.GetFreeSlotAndLock(expected_cache_size, &meta2, "b", "so", "st", &err); ASSERT_THAT(ini_addr, Ne(nullptr)); ASSERT_THAT(addr, Eq(nullptr)); ASSERT_THAT(meta1, Ne(nullptr)); ASSERT_THAT(meta2, Eq(nullptr)); } - TEST_F(DataCacheTests, GetFreeSlotStartsFromBeginIfNotFit) { asapo::Error err; - uint8_t* ini_addr = (uint8_t*) cache.GetFreeSlotAndLock(1, &meta1,&err); + uint8_t* ini_addr = (uint8_t*) cache.GetFreeSlotAndLock(1, &meta1, "b", "so", "st", &err); auto id = meta1->id; set_array(ini_addr, 1, 2); cache.UnlockSlot(meta1); - uint8_t* addr = (uint8_t*) cache.GetFreeSlotAndLock(expected_cache_size, &meta2,&err); + uint8_t* addr = (uint8_t*) cache.GetFreeSlotAndLock(expected_cache_size, &meta2, "b", "so", "st", &err); set_array(addr, expected_cache_size, 1); ASSERT_THAT(ini_addr[0], Eq(1)); ASSERT_THAT(id, Ne(meta2->id)); @@ -86,8 +85,8 @@ TEST_F(DataCacheTests, GetFreeSlotStartsFromBeginIfNotFit) { TEST_F(DataCacheTests, GetFreeSlotCannotWriteIfAlreadyWriting) { asapo::Error err; - cache.GetFreeSlotAndLock(1, &meta1,&err); - uint8_t* addr = (uint8_t*) cache.GetFreeSlotAndLock(expected_cache_size, &meta2,&err); + cache.GetFreeSlotAndLock(1, &meta1, "b", "so", "st", &err); + uint8_t* addr = (uint8_t*) cache.GetFreeSlotAndLock(expected_cache_size, &meta2, "b", "so", "st", &err); ASSERT_THAT(addr, Eq(nullptr)); ASSERT_THAT(meta2, Eq(nullptr)); @@ -104,19 +103,27 @@ TEST_F(DataCacheTests, PrepareToReadIdNotFound) { TEST_F(DataCacheTests, PrepareToReadOk) { asapo::Error err; auto data_size = static_cast<uint64_t>(static_cast<double>(expected_cache_size) * 0.7); - uint8_t* ini_addr = (uint8_t*) cache.GetFreeSlotAndLock(data_size, &meta1,&err); + uint8_t* ini_addr = (uint8_t*) cache.GetFreeSlotAndLock(data_size, &meta1, "b1", "so1", "st1", &err); uint8_t* addr = (uint8_t*) cache.GetSlotToReadAndLock(meta1->id, data_size, &meta2); ASSERT_THAT(addr, Eq(ini_addr)); ASSERT_THAT(meta1, Eq(meta2)); ASSERT_THAT(meta2->size, Eq(data_size)); + + ASSERT_THAT(meta1->beamtime, Eq("b1")); + ASSERT_THAT(meta1->source, Eq("so1")); + ASSERT_THAT(meta1->stream, Eq("st1")); + + ASSERT_THAT(meta2->beamtime, Eq("b1")); + ASSERT_THAT(meta2->source, Eq("so1")); + ASSERT_THAT(meta2->stream, Eq("st1")); } TEST_F(DataCacheTests, PrepareToReadFailsIfTooCloseToCurrentPointer) { asapo::Error err; auto data_size = static_cast<uint64_t>(static_cast<double>(expected_cache_size) * 0.9); - cache.GetFreeSlotAndLock(data_size, &meta1,&err); + cache.GetFreeSlotAndLock(data_size, &meta1, "b", "so", "st", &err); uint8_t* addr = (uint8_t*) cache.GetSlotToReadAndLock(meta1->id, data_size, &meta2); ASSERT_THAT(addr, Eq(nullptr)); @@ -125,12 +132,12 @@ TEST_F(DataCacheTests, PrepareToReadFailsIfTooCloseToCurrentPointer) { TEST_F(DataCacheTests, GetFreeSlotRemovesOldMetadataRecords) { DataCache cache{expected_cache_size, 0}; + asapo::Error err; CacheMeta* meta3, *meta4, *meta5; CacheMeta* meta; - asapo::Error err; - cache.GetFreeSlotAndLock(10, &meta1,&err); - cache.GetFreeSlotAndLock(10, &meta2,&err); - cache.GetFreeSlotAndLock(expected_cache_size - 30, &meta3,&err); + cache.GetFreeSlotAndLock(10, &meta1, "b1", "so1", "st1", &err); + cache.GetFreeSlotAndLock(10, &meta2, "b2", "so2", "st2", &err); + cache.GetFreeSlotAndLock(expected_cache_size - 30, &meta3, "b3", "so3", "st3", &err); auto id1 = meta1->id; auto id2 = meta2->id; auto id3 = meta3->id; @@ -139,11 +146,11 @@ TEST_F(DataCacheTests, GetFreeSlotRemovesOldMetadataRecords) { cache.UnlockSlot(meta2); cache.UnlockSlot(meta3); - cache.GetFreeSlotAndLock(10, &meta4,&err); + cache.GetFreeSlotAndLock(10, &meta4, "b4", "so4", "st4", &err); auto id4 = meta4->id; cache.UnlockSlot(meta4); - cache.GetFreeSlotAndLock(30, &meta5,&err); + cache.GetFreeSlotAndLock(30, &meta5, "b5", "so5", "st5", &err); uint8_t* addr1 = (uint8_t*) cache.GetSlotToReadAndLock(id1, 10, &meta); uint8_t* addr2 = (uint8_t*) cache.GetSlotToReadAndLock(id2, 10, &meta); uint8_t* addr3 = (uint8_t*) cache.GetSlotToReadAndLock(id3, expected_cache_size - 30, &meta); @@ -154,6 +161,9 @@ TEST_F(DataCacheTests, GetFreeSlotRemovesOldMetadataRecords) { ASSERT_THAT(addr3, Eq(nullptr)); ASSERT_THAT(addr4, Ne(nullptr)); ASSERT_THAT(meta->size, Eq(10)); + ASSERT_THAT(meta->beamtime, Eq("b4")); + ASSERT_THAT(meta->source, Eq("so4")); + ASSERT_THAT(meta->stream, Eq("st4")); } TEST_F(DataCacheTests, GetFreeSlotRemovesOldWhenCrossTheBoundary) { @@ -161,19 +171,19 @@ TEST_F(DataCacheTests, GetFreeSlotRemovesOldWhenCrossTheBoundary) { DataCache cache{expected_cache_size, 0}; CacheMeta* meta1, *meta2, *meta3; CacheMeta* meta4, *meta5, *meta; - auto addr1_alloc = cache.GetFreeSlotAndLock(expected_cache_size / 3 - 1, &meta1,&err); - auto addr2_alloc = cache.GetFreeSlotAndLock(expected_cache_size / 3 - 1, &meta2,&err); - auto addr3_alloc = cache.GetFreeSlotAndLock(expected_cache_size / 3 - 1, &meta3,&err); + auto addr1_alloc = cache.GetFreeSlotAndLock(expected_cache_size / 3 - 1, &meta1, "b", "so", "st", &err); + auto addr2_alloc = cache.GetFreeSlotAndLock(expected_cache_size / 3 - 1, &meta2, "b", "so", "st", &err); + auto addr3_alloc = cache.GetFreeSlotAndLock(expected_cache_size / 3 - 1, &meta3, "b", "so", "st", &err); auto id1 = meta1->id; auto id2 = meta2->id; auto id3 = meta3->id; cache.UnlockSlot(meta1); cache.UnlockSlot(meta2); cache.UnlockSlot(meta3); - auto addr4_alloc = cache.GetFreeSlotAndLock(expected_cache_size / 2 + 5, &meta4,&err); + auto addr4_alloc = cache.GetFreeSlotAndLock(expected_cache_size / 2 + 5, &meta4, "b", "so", "st", &err); auto id4 = meta4->id; cache.UnlockSlot(meta4); - auto addr5_alloc = cache.GetFreeSlotAndLock(expected_cache_size / 2 + 5, &meta5,&err); + auto addr5_alloc = cache.GetFreeSlotAndLock(expected_cache_size / 2 + 5, &meta5, "b", "so", "st", &err); auto id5 = meta5->id; uint8_t* addr1 = (uint8_t*) cache.GetSlotToReadAndLock(id1, expected_cache_size / 3 - 1, &meta); @@ -203,18 +213,21 @@ TEST_F(DataCacheTests, GetFreeSlotRemovesOldWhenCrossTheBoundary) { TEST_F(DataCacheTests, GetSlotToReadSizeOk) { asapo::Error err; CacheMeta* meta; - cache.GetFreeSlotAndLock(expected_size, &meta1,&err); + cache.GetFreeSlotAndLock(expected_size, &meta1, "b", "so", "st", &err); uint8_t* addr1 = (uint8_t*) cache.GetSlotToReadAndLock(meta1->id, expected_size, &meta); ASSERT_THAT(addr1, Ne(nullptr)); ASSERT_THAT(meta->size, Eq(expected_size)); + ASSERT_THAT(meta->beamtime, Eq("b")); + ASSERT_THAT(meta->source, Eq("so")); + ASSERT_THAT(meta->stream, Eq("st")); } TEST_F(DataCacheTests, GetSlotToReadWrongSize) { - CacheMeta* meta; asapo::Error err; - cache.GetFreeSlotAndLock(expected_size, &meta1,&err); + CacheMeta* meta; + cache.GetFreeSlotAndLock(expected_size, &meta1, "b", "so", "st", &err); uint8_t* addr1 = (uint8_t*) cache.GetSlotToReadAndLock(meta1->id, expected_size + 1, &meta); @@ -226,11 +239,10 @@ TEST_F(DataCacheTests, GetSlotToReadWrongSize) { TEST_F(DataCacheTests, CannotGetFreeSlotIfNeedCleanOnebeingReaded) { CacheMeta* meta; asapo::Error err; - - - uint8_t* ini_addr = (uint8_t*) cache.GetFreeSlotAndLock(10, &meta1,&err); + + uint8_t* ini_addr = (uint8_t*) cache.GetFreeSlotAndLock(10, &meta1, "b", "so", "st", &err); auto res = cache.GetSlotToReadAndLock(meta1->id, 10, &meta); - uint8_t* addr = (uint8_t*) cache.GetFreeSlotAndLock(expected_cache_size, &meta2,&err); + uint8_t* addr = (uint8_t*) cache.GetFreeSlotAndLock(expected_cache_size, &meta2, "b", "so", "st", &err); ASSERT_THAT(ini_addr, Ne(nullptr)); ASSERT_THAT(res, Eq(ini_addr)); @@ -239,56 +251,55 @@ TEST_F(DataCacheTests, CannotGetFreeSlotIfNeedCleanOnebeingReaded) { TEST_F(DataCacheTests, CanGetFreeSlotIfWasUnlocked) { + asapo::Error err; CacheMeta* meta; - asapo::Error err; - cache.GetFreeSlotAndLock(10, &meta1,&err); + cache.GetFreeSlotAndLock(10, &meta1, "b", "so", "st", &err); cache.UnlockSlot(meta1); cache.GetSlotToReadAndLock(meta1->id, 10, &meta); cache.UnlockSlot(meta); - auto addr = cache.GetFreeSlotAndLock(expected_cache_size, &meta2,&err); + auto addr = cache.GetFreeSlotAndLock(expected_cache_size, &meta2, "b", "so", "st", &err); ASSERT_THAT(addr, Ne(nullptr)); } TEST_F(DataCacheTests, IncreasLockForEveryRead) { - CacheMeta* meta; asapo::Error err; - cache.GetFreeSlotAndLock(10, &meta1,&err); + CacheMeta* meta; + cache.GetFreeSlotAndLock(10, &meta1, "b", "so", "st", &err); cache.GetSlotToReadAndLock(meta1->id, 10, &meta); cache.GetSlotToReadAndLock(meta1->id, 10, &meta); cache.UnlockSlot(meta); - auto addr = cache.GetFreeSlotAndLock(expected_cache_size, &meta2,&err); + auto addr = cache.GetFreeSlotAndLock(expected_cache_size, &meta2, "b", "so", "st", &err); ASSERT_THAT(addr, Eq(nullptr)); } TEST_F(DataCacheTests, DecreasLockForEveryUnlock) { - CacheMeta* meta; asapo::Error err; - - cache.GetFreeSlotAndLock(10, &meta1,&err); + CacheMeta* meta; + cache.GetFreeSlotAndLock(10, &meta1, "b", "so", "st", &err); cache.UnlockSlot(meta1); cache.GetSlotToReadAndLock(meta1->id, 10, &meta); cache.GetSlotToReadAndLock(meta1->id, 10, &meta); cache.UnlockSlot(meta); cache.UnlockSlot(meta); - auto addr = cache.GetFreeSlotAndLock(expected_cache_size, &meta2,&err); + auto addr = cache.GetFreeSlotAndLock(expected_cache_size, &meta2, "b", "so", "st", &err); ASSERT_THAT(addr, Ne(nullptr)); } TEST_F(DataCacheTests, GetFreeSlotCreatesCorrectIds) { - CacheMeta* meta3, *meta4; asapo::Error err; - cache.GetFreeSlotAndLock(10, &meta1,&err); + CacheMeta* meta3, *meta4; + cache.GetFreeSlotAndLock(10, &meta1, "b", "so", "st", &err); std::this_thread::sleep_for(std::chrono::milliseconds(100)); - cache.GetFreeSlotAndLock(10, &meta2,&err); + cache.GetFreeSlotAndLock(10, &meta2, "b", "so", "st", &err); std::this_thread::sleep_for(std::chrono::milliseconds(10)); - cache.GetFreeSlotAndLock(10, &meta3,&err); + cache.GetFreeSlotAndLock(10, &meta3, "b", "so", "st", &err); std::this_thread::sleep_for(std::chrono::milliseconds(1)); - cache.GetFreeSlotAndLock(10, &meta4,&err); + cache.GetFreeSlotAndLock(10, &meta4, "b", "so", "st", &err); auto c1 = static_cast<uint32_t>(meta1->id); auto c2 = static_cast<uint32_t>(meta2->id); diff --git a/receiver/unittests/test_receiver.cpp b/receiver/unittests/test_receiver.cpp index 1d032201124db3a5a4644a9485d3bd57c7280fa0..23249877d13ae835ff9f41f915ddbb0dd1458a86 100644 --- a/receiver/unittests/test_receiver.cpp +++ b/receiver/unittests/test_receiver.cpp @@ -12,7 +12,7 @@ using namespace asapo; namespace { TEST(Receiver, Constructor) { - asapo::Receiver receiver(nullptr, nullptr); + asapo::Receiver receiver(nullptr, nullptr,nullptr); ASSERT_THAT(dynamic_cast<const asapo::AbstractLogger*>(receiver.log__), Ne(nullptr)); ASSERT_THAT(dynamic_cast<asapo::IO*>(receiver.io__.get()), Ne(nullptr)); } @@ -31,7 +31,7 @@ class StartListenerFixture : public testing::Test { Error err; ::testing::NiceMock<asapo::MockLogger> mock_logger; ::testing::NiceMock<asapo::MockIO> mock_io; - asapo::Receiver receiver{nullptr, nullptr}; + asapo::Receiver receiver{nullptr, nullptr,nullptr}; void SetUp() override { err = nullptr; diff --git a/receiver/unittests/test_request.cpp b/receiver/unittests/test_request.cpp index 4bd58d36a20ecf17e3e48536c1d1da9eec024340..b304dd93ff17be5114feb27601d247b1688ab848 100644 --- a/receiver/unittests/test_request.cpp +++ b/receiver/unittests/test_request.cpp @@ -31,7 +31,7 @@ class MockReqestHandler : public asapo::ReceiverRequestHandler { TEST(RequestTest, Constructor) { std::unique_ptr<Request> request; GenericRequestHeader generic_request_header; - request.reset(new Request{generic_request_header, 1, "", nullptr, nullptr}); + request.reset(new Request{generic_request_header, 1, "", nullptr, nullptr, nullptr}); ASSERT_THAT(request->WasAlreadyProcessed(), false); } @@ -51,12 +51,10 @@ class RequestTests : public Test { char expected_request_message[asapo::kMaxMessageSize] = "test_message"; std::string expected_api_version = "v0.2"; std::unique_ptr<Request> request; - NiceMock<MockIO> mock_io; - NiceMock<MockStatistics> mock_statistics; - asapo::ReceiverStatistics* stat; + StrictMock<MockIO> mock_io; + StrictMock<asapo::MockInstancedStatistics>* mock_instanced_statistics; MockDataCache mock_cache; void SetUp() override { - stat = &mock_statistics; generic_request_header.data_size = data_size_; generic_request_header.data_id = data_id_; generic_request_header.meta_size = expected_metadata_size; @@ -64,7 +62,9 @@ class RequestTests : public Test { generic_request_header.custom_data[asapo::kPosIngestMode] = asapo::kDefaultIngestMode; strcpy(generic_request_header.message, expected_request_message); strcpy(generic_request_header.api_version, expected_api_version.c_str()); - request.reset(new Request{generic_request_header, expected_socket_id, expected_origin_uri, nullptr, nullptr}); + mock_instanced_statistics = new StrictMock<asapo::MockInstancedStatistics>; + request.reset(new Request{generic_request_header, expected_socket_id, expected_origin_uri, nullptr, nullptr, + std::unique_ptr<asapo::MockInstancedStatistics> {mock_instanced_statistics}}); request->io__ = std::unique_ptr<asapo::IO> {&mock_io}; ON_CALL(mock_io, Receive_t(expected_socket_id, _, data_size_, _)).WillByDefault( DoAll(SetArgPointee<3>(nullptr), @@ -83,9 +83,9 @@ void RequestTests::MockAllocateRequestSlot() { request->cache__ = &mock_cache; asapo::CacheMeta meta; - EXPECT_CALL(mock_cache, GetFreeSlotAndLock_t(data_size_, _, _)).WillOnce( + EXPECT_CALL(mock_cache, GetFreeSlotAndLock_t(data_size_, _, _,_,_,_)).WillOnce( DoAll(SetArgPointee<1>(&meta), - SetArgPointee<2>(nullptr), + SetArgPointee<5>(nullptr), Return(&mock_cache) )); request->PrepareDataBufferAndLockIfNeeded(); @@ -104,11 +104,12 @@ TEST_F(RequestTests, HandleProcessesRequests) { request->AddHandler(&mock_request_handler); request->AddHandler(&mock_request_handler); - EXPECT_CALL(mock_statistics, StartTimer_t(asapo::StatisticEntity::kDisk)).Times(2); - EXPECT_CALL(mock_statistics, StopTimer_t()).Times(1); + EXPECT_CALL(*mock_instanced_statistics, StartTimer(asapo::StatisticEntity::kDisk)).Times(2); + + EXPECT_CALL(*mock_instanced_statistics, StopTimer()).Times(2); EXPECT_CALL(mock_cache, UnlockSlot(_)); - auto err = request->Handle(stat); + auto err = request->Handle(); ASSERT_THAT(err, Eq(asapo::IOErrorTemplates::kUnknownIOError)); } @@ -161,7 +162,7 @@ void RequestTests::ExpectFileName(std::string sended, std::string received) { strcpy(generic_request_header.message, sended.c_str()); request->io__.release(); - request.reset(new Request{generic_request_header, expected_socket_id, expected_origin_uri, nullptr, nullptr}); + request.reset(new Request{generic_request_header, expected_socket_id, expected_origin_uri, nullptr, nullptr, nullptr}); request->io__ = std::unique_ptr<asapo::IO> {&mock_io}; auto fname = request->GetFileName(); @@ -175,7 +176,7 @@ TEST_F(RequestTests, GetStream) { strcpy(generic_request_header.stream, expected_stream.c_str()); request->io__.release(); - request.reset(new Request{generic_request_header, expected_socket_id, expected_origin_uri, nullptr, nullptr}); + request.reset(new Request{generic_request_header, expected_socket_id, expected_origin_uri, nullptr, nullptr, nullptr}); request->io__ = std::unique_ptr<asapo::IO> {&mock_io}; auto stream = request->GetStream(); diff --git a/tests/automatic/authorizer/check_authorize/check_linux.sh b/tests/automatic/authorizer/check_authorize/check_linux.sh index 340c715bce4db2135a33d2015d171d6599d921c6..fde0324712c7a26ffbc5a61c698efd0d63d6ee41 100644 --- a/tests/automatic/authorizer/check_authorize/check_linux.sh +++ b/tests/automatic/authorizer/check_authorize/check_linux.sh @@ -26,54 +26,54 @@ RevokeToken=$ASAPO_REVOKE_TOKEN curl -v --silent -H "Authorization: Bearer $AdminToken" --data '{"Subject": {"beamtimeId":"12345678"},"DaysValid":123,"AccessTypes":["read"]}' 127.0.0.1:8400/asapo-authorizer/admin/issue --stderr - | tee /dev/stderr | grep "bt_12345678" curl -v --silent -H "Authorization: Bearer blabla" --data '{"Subject": {"beamtimeId":"12345678"},"DaysValid":123,"AccessTypes":["read"]}' 127.0.0.1:8400/asapo-authorizer/admin/issue --stderr - | tee /dev/stderr | grep "token does not match" -curl -v --silent --data '{"SourceCredentials":"processed%c20180508-000-COM20181%%detector%","OriginHost":"127.0.0.1:5555"}' 127.0.0.1:8400/asapo-authorizer/authorize --stderr - | tee /dev/stderr | grep c20180508-000-COM20181 -curl -v --silent --data '{"SourceCredentials":"processed%c20180508-000-COM20181%%detector%","OriginHost":"127.0.0.1:5555"}' 127.0.0.1:8400/asapo-authorizer/authorize --stderr - | tee /dev/stderr | grep p00 -curl -v --silent --data '{"SourceCredentials":"processed%c20180508-000-COM20181%%detector%","OriginHost":"127.0.0.1:5555"}' 127.0.0.1:8400/asapo-authorizer/authorize --stderr - | tee /dev/stderr | grep detector +curl -v --silent --data '{"SourceCredentials":"processed%instance%step%c20180508-000-COM20181%%detector%","OriginHost":"127.0.0.1:5555"}' 127.0.0.1:8400/asapo-authorizer/authorize --stderr - | tee /dev/stderr | grep c20180508-000-COM20181 +curl -v --silent --data '{"SourceCredentials":"processed%instance%step%c20180508-000-COM20181%%detector%","OriginHost":"127.0.0.1:5555"}' 127.0.0.1:8400/asapo-authorizer/authorize --stderr - | tee /dev/stderr | grep p00 +curl -v --silent --data '{"SourceCredentials":"processed%instance%step%c20180508-000-COM20181%%detector%","OriginHost":"127.0.0.1:5555"}' 127.0.0.1:8400/asapo-authorizer/authorize --stderr - | tee /dev/stderr | grep detector token=$C20180508_000_COM20181_TOKEN -curl -v --silent --data "{\"SourceCredentials\":\"processed%c20180508-000-COM20181%%detector%$token\",\"OriginHost\":\"bla\"}" 127.0.0.1:8400/asapo-authorizer/authorize --stderr - | tee /dev/stderr | grep detector -curl -v --silent --data "{\"SourceCredentials\":\"processed%c20180508-000-COM20181%auto%detector%$token\",\"OriginHost\":\"bla\"}" 127.0.0.1:8400/asapo-authorizer/authorize --stderr - | tee /dev/stderr | grep p00 -curl -v --silent --data '{"SourceCredentials":"processed%c20180508-000-COM20181%%detector%bla","OriginHost":"bla"}' 127.0.0.1:8400/asapo-authorizer/authorize --stderr - | tee /dev/stderr | grep 401 +curl -v --silent --data "{\"SourceCredentials\":\"processed%instance%step%c20180508-000-COM20181%%detector%$token\",\"OriginHost\":\"bla\"}" 127.0.0.1:8400/asapo-authorizer/authorize --stderr - | tee /dev/stderr | grep detector +curl -v --silent --data "{\"SourceCredentials\":\"processed%instance%step%c20180508-000-COM20181%auto%detector%$token\",\"OriginHost\":\"bla\"}" 127.0.0.1:8400/asapo-authorizer/authorize --stderr - | tee /dev/stderr | grep p00 +curl -v --silent --data '{"SourceCredentials":"processed%instance%step%c20180508-000-COM20181%%detector%bla","OriginHost":"bla"}' 127.0.0.1:8400/asapo-authorizer/authorize --stderr - | tee /dev/stderr | grep 401 token=$BT11000015_TOKEN #beamtine not online -curl -v --silent --data "{\"SourceCredentials\":\"raw%11000015%%detector%$token\",\"OriginHost\":\"bla\"}" 127.0.0.1:8400/asapo-authorizer/authorize --stderr - | tee /dev/stderr | grep 401 +curl -v --silent --data "{\"SourceCredentials\":\"raw%instance%step%11000015%%detector%$token\",\"OriginHost\":\"bla\"}" 127.0.0.1:8400/asapo-authorizer/authorize --stderr - | tee /dev/stderr | grep 401 token=$BT11000016_TOKEN -curl -v --silent --data "{\"SourceCredentials\":\"raw%11000016%%detector%${token}\",\"OriginHost\":\"bla\"}" 127.0.0.1:8400/asapo-authorizer/authorize --stderr - | tee /dev/stderr | grep 401 +curl -v --silent --data "{\"SourceCredentials\":\"raw%instance%step%11000016%%detector%${token}\",\"OriginHost\":\"bla\"}" 127.0.0.1:8400/asapo-authorizer/authorize --stderr - | tee /dev/stderr | grep 401 token=$BLP07_TOKEN -curl -v --silent --data "{\"SourceCredentials\":\"processed%auto%p07%detector%$token\",\"OriginHost\":\"bla\"}" 127.0.0.1:8400/asapo-authorizer/authorize --stderr - | tee /dev/stderr | grep 11111111 -curl -v --silent --data "{\"SourceCredentials\":\"raw%auto%p07%detector%\",\"OriginHost\":\"127.0.0.1:8400/asapo-authorizer\"}" 127.0.0.1:8400/asapo-authorizer/authorize --stderr - | tee /dev/stderr | grep writeraw -! curl -v --silent --data "{\"SourceCredentials\":\"raw%auto%p07%detector%$token\",\"OriginHost\":\"127.0.0.1:8400/asapo-authorizer\"}" 127.0.0.1:8400/asapo-authorizer/authorize --stderr - | tee /dev/stderr | grep writeraw -curl -v --silent --data "{\"SourceCredentials\":\"raw%auto%p07%detector%$token\",\"OriginHost\":\"127.0.0.1:8400/asapo-authorizer\"}" 127.0.0.1:8400/asapo-authorizer/authorize --stderr - | tee /dev/stderr | grep p07 -curl -v --silent --data "{\"SourceCredentials\":\"raw%auto%p07%detector%$token\",\"OriginHost\":\"127.0.0.1:8400/asapo-authorizer\"}" 127.0.0.1:8400/asapo-authorizer/authorize --stderr - | tee /dev/stderr | grep /asap3/petra3/gpfs/p07/2020/data/11111111 +curl -v --silent --data "{\"SourceCredentials\":\"processed%instance%step%auto%p07%detector%$token\",\"OriginHost\":\"bla\"}" 127.0.0.1:8400/asapo-authorizer/authorize --stderr - | tee /dev/stderr | grep 11111111 +curl -v --silent --data "{\"SourceCredentials\":\"raw%instance%step%auto%p07%detector%\",\"OriginHost\":\"127.0.0.1:8400/asapo-authorizer\"}" 127.0.0.1:8400/asapo-authorizer/authorize --stderr - | tee /dev/stderr | grep writeraw +! curl -v --silent --data "{\"SourceCredentials\":\"raw%instance%step%auto%p07%detector%$token\",\"OriginHost\":\"127.0.0.1:8400/asapo-authorizer\"}" 127.0.0.1:8400/asapo-authorizer/authorize --stderr - | tee /dev/stderr | grep writeraw +curl -v --silent --data "{\"SourceCredentials\":\"raw%instance%step%auto%p07%detector%$token\",\"OriginHost\":\"127.0.0.1:8400/asapo-authorizer\"}" 127.0.0.1:8400/asapo-authorizer/authorize --stderr - | tee /dev/stderr | grep p07 +curl -v --silent --data "{\"SourceCredentials\":\"raw%instance%step%auto%p07%detector%$token\",\"OriginHost\":\"127.0.0.1:8400/asapo-authorizer\"}" 127.0.0.1:8400/asapo-authorizer/authorize --stderr - | tee /dev/stderr | grep /asap3/petra3/gpfs/p07/2020/data/11111111 #wrong data in metafile -curl -v --silent --data "{\"SourceCredentials\":\"processed%auto%p08%detector%$token\",\"OriginHost\":\"bla\"}" 127.0.0.1:8400/asapo-authorizer/authorize --stderr - | tee /dev/stderr | grep "cannot set meta fields" +curl -v --silent --data "{\"SourceCredentials\":\"processed%instance%step%auto%p08%detector%$token\",\"OriginHost\":\"bla\"}" 127.0.0.1:8400/asapo-authorizer/authorize --stderr - | tee /dev/stderr | grep "cannot set meta fields" #read access -curl -v --silent --data "{\"SourceCredentials\":\"processed%auto%p07%detector%$token\",\"OriginHost\":\"bla\"}" 127.0.0.1:8400/asapo-authorizer/authorize --stderr - | tee /dev/stderr | grep read +curl -v --silent --data "{\"SourceCredentials\":\"processed%instance%step%auto%p07%detector%$token\",\"OriginHost\":\"bla\"}" 127.0.0.1:8400/asapo-authorizer/authorize --stderr - | tee /dev/stderr | grep read #write access token=$BLP07_W_TOKEN -curl -v --silent --data "{\"SourceCredentials\":\"processed%auto%p07%detector%$token\",\"OriginHost\":\"bla\"}" 127.0.0.1:8400/asapo-authorizer/authorize --stderr - | tee /dev/stderr | grep write +curl -v --silent --data "{\"SourceCredentials\":\"processed%instance%step%auto%p07%detector%$token\",\"OriginHost\":\"bla\"}" 127.0.0.1:8400/asapo-authorizer/authorize --stderr - | tee /dev/stderr | grep write #revocation token=`curl --silent -H "Authorization: Bearer $AdminToken" --data '{"Subject": {"beamtimeId":"11000015"},"DaysValid":123,"AccessTypes":["read"]}' 127.0.0.1:8400/asapo-authorizer/admin/issue | jq -r .Token` echo $token -curl -v --silent --data "{\"SourceCredentials\":\"processed%11000015%auto%detector%$token\",\"OriginHost\":\"bla\"}" 127.0.0.1:8400/asapo-authorizer/authorize --stderr - | tee /dev/stderr | grep p00 +curl -v --silent --data "{\"SourceCredentials\":\"processed%instance%step%11000015%auto%detector%$token\",\"OriginHost\":\"bla\"}" 127.0.0.1:8400/asapo-authorizer/authorize --stderr - | tee /dev/stderr | grep p00 #revoke token curl -v --silent -H "Authorization: Bearer $RevokeToken" --data '{"Token": "'"$token"'"}' 127.0.0.1:8400/asapo-authorizer/admin/revoke | grep '"Revoked":true' sleep 1 -curl -v --silent --data "{\"SourceCredentials\":\"processed%11000015%auto%detector%$token\",\"OriginHost\":\"bla\"}" 127.0.0.1:8400/asapo-authorizer/authorize --stderr - | tee /dev/stderr | grep 401 +curl -v --silent --data "{\"SourceCredentials\":\"processed%instance%step%11000015%auto%detector%$token\",\"OriginHost\":\"bla\"}" 127.0.0.1:8400/asapo-authorizer/authorize --stderr - | tee /dev/stderr | grep 401 rm -rf /tmp/asapo/asap3 /tmp/asapo/beamline \ No newline at end of file diff --git a/tests/automatic/authorizer/check_authorize/check_windows.bat b/tests/automatic/authorizer/check_authorize/check_windows.bat index 66e7cb6d48c4ddf5b575cdc3977b42216765ca97..2b8401cb5f5fa2a6e26551d15b0e78ee60d72eba 100644 --- a/tests/automatic/authorizer/check_authorize/check_windows.bat +++ b/tests/automatic/authorizer/check_authorize/check_windows.bat @@ -5,14 +5,14 @@ mkdir C:\tmp\asapo\asap3\petra3\gpfs\p00\2019\comissioning\c20180508-000-COM2018 mkdir C:\tmp\asapo\beamline\p07\current copy beamtime-metadata-11111111.json C:\tmp\asapo\beamline\p07\current\ /y -C:\Curl\curl.exe -v --silent --data "{\"SourceCredentials\":\"processed%%c20180508-000-COM20181%%%%detector%%\",\"OriginHost\":\"127.0.0.1:5555\"}" 127.0.0.1:5007/authorize --stderr - | findstr c20180508-000-COM20181 || goto :error -C:\Curl\curl.exe -v --silent --data "{\"SourceCredentials\":\"processed%%c20180508-000-COM20181%%auto%%detector%%\",\"OriginHost\":\"127.0.0.1:5555\"}" 127.0.0.1:5007/authorize --stderr - | findstr p00 || goto :error -C:\Curl\curl.exe -v --silent --data "{\"SourceCredentials\":\"processed%%c20180508-000-COM20181%%%%detector%%\",\"OriginHost\":\"127.0.0.1:5555\"}" 127.0.0.1:5007/authorize --stderr - | findstr detector || goto :error +C:\Curl\curl.exe -v --silent --data "{\"SourceCredentials\":\"processed%%instance%%step%%c20180508-000-COM20181%%%%detector%%\",\"OriginHost\":\"127.0.0.1:5555\"}" 127.0.0.1:5007/authorize --stderr - | findstr c20180508-000-COM20181 || goto :error +C:\Curl\curl.exe -v --silent --data "{\"SourceCredentials\":\"processed%%instance%%step%%c20180508-000-COM20181%%auto%%detector%%\",\"OriginHost\":\"127.0.0.1:5555\"}" 127.0.0.1:5007/authorize --stderr - | findstr p00 || goto :error +C:\Curl\curl.exe -v --silent --data "{\"SourceCredentials\":\"processed%%instance%%step%%c20180508-000-COM20181%%%%detector%%\",\"OriginHost\":\"127.0.0.1:5555\"}" 127.0.0.1:5007/authorize --stderr - | findstr detector || goto :error -C:\Curl\curl.exe -v --silent --data "{\"SourceCredentials\":\"raw%%c20180508-000-COM20181%%%%detector%%wrong\",\"OriginHost\":\"127.0.0.1:5555\"}" 127.0.0.1:5007/authorize --stderr - | findstr 401 || goto :error +C:\Curl\curl.exe -v --silent --data "{\"SourceCredentials\":\"raw%%instance%%step%%c20180508-000-COM20181%%%%detector%%wrong\",\"OriginHost\":\"127.0.0.1:5555\"}" 127.0.0.1:5007/authorize --stderr - | findstr 401 || goto :error set token=%BLP07_TOKEN% -C:\Curl\curl.exe -v --silent --data "{\"SourceCredentials\":\"raw%%auto%%p07%%detector%%%token%\",\"OriginHost\":\"127.0.0.1:5555\"}" 127.0.0.1:5007/authorize --stderr - | findstr 11111111 || goto :error +C:\Curl\curl.exe -v --silent --data "{\"SourceCredentials\":\"raw%%instance%%step%%auto%%p07%%detector%%%token%\",\"OriginHost\":\"127.0.0.1:5555\"}" 127.0.0.1:5007/authorize --stderr - | findstr 11111111 || goto :error goto :clean diff --git a/tests/automatic/common_scripts/start_services.sh b/tests/automatic/common_scripts/start_services.sh index e59a39cb8caf0cf4447f3213363142bcc1bd4b72..f321f2cdb2bbc82fa40236b828d3153fd094aecd 100755 --- a/tests/automatic/common_scripts/start_services.sh +++ b/tests/automatic/common_scripts/start_services.sh @@ -14,6 +14,8 @@ nomad run -detach authorizer.nmd nomad run -detach file_transfer.nmd nomad run -detach receiver_tcp.nmd nomad run -detach broker.nmd +nomad run -detach monitoring.nmd + while true do @@ -25,6 +27,8 @@ do echo broker started curl --silent 127.0.0.1:8400/asapo-discovery/v0.1/asapo-file-transfer?protocol=v0.1 --stderr - | grep 127.0.0.1 || continue echo file transfer started + curl --silent 127.0.0.1:8400/asapo-discovery/asapo-monitoring --stderr - | grep 127.0.0.1 || continue + echo monitoring started break done diff --git a/tests/automatic/common_scripts/stop_services.sh b/tests/automatic/common_scripts/stop_services.sh index 084630d7f250262262d4f5439172294b34985413..13481072f06b7aa6f629945980d4ffe699d183cd 100755 --- a/tests/automatic/common_scripts/stop_services.sh +++ b/tests/automatic/common_scripts/stop_services.sh @@ -5,3 +5,4 @@ nomad stop -purge broker nomad stop -purge receiver nomad stop -purge authorizer nomad stop -purge file_transfer +nomad stop -purge monitoring diff --git a/tests/automatic/consumer/consumer_api/consumer_api.c b/tests/automatic/consumer/consumer_api/consumer_api.c index 34f23dfe0df64df089cd4f8ecb3fad887d236cc2..21dbb2edbcb1beee9a2df35124ce05acf6e10cb7 100644 --- a/tests/automatic/consumer/consumer_api/consumer_api.c +++ b/tests/automatic/consumer/consumer_api/consumer_api.c @@ -229,8 +229,8 @@ int main(int argc, char* argv[]) { AsapoErrorHandle err = asapo_new_handle(); AsapoSourceCredentialsHandle cred = asapo_create_source_credentials(kProcessed, - beamtime, - "", "", token); + "auto", "auto", + beamtime, "", "", token); AsapoConsumerHandle consumer = asapo_create_consumer(endpoint, ".", 1, cred, diff --git a/tests/automatic/consumer/consumer_api/consumer_api.cpp b/tests/automatic/consumer/consumer_api/consumer_api.cpp index f388fd945e8f9f7ce6fdcf3a735018788300c359..dfef86461459c33ba13659055bedd5f77c70fe29 100644 --- a/tests/automatic/consumer/consumer_api/consumer_api.cpp +++ b/tests/automatic/consumer/consumer_api/consumer_api.cpp @@ -331,7 +331,7 @@ void TestAll(const Args& args) { ".", true, asapo::SourceCredentials{asapo::SourceType::kProcessed, - args.run_name, "", "", args.token}, + "auto", "auto", args.run_name, "", "", args.token}, &err); if (err) { std::cout << "Error CreateConsumer: " << err << std::endl; diff --git a/tests/automatic/consumer/next_multithread_broker/next_multithread_broker.cpp b/tests/automatic/consumer/next_multithread_broker/next_multithread_broker.cpp index a369f48964932c11c890137ba52c31b10380bf5d..13dd1fdc4b1560b58945e15bce75e7750ae63a57 100644 --- a/tests/automatic/consumer/next_multithread_broker/next_multithread_broker.cpp +++ b/tests/automatic/consumer/next_multithread_broker/next_multithread_broker.cpp @@ -57,7 +57,7 @@ void TestAll(const Args& args) { "dummy", true, asapo::SourceCredentials{asapo::SourceType::kProcessed, - args.run_name, "", "", args.token}, + "auto", "auto", args.run_name, "", "", args.token}, &err); if (err) { std::cout << "Error CreateConsumer: " << err << std::endl; diff --git a/tests/automatic/curl_http_client/curl_http_client_command/curl_httpclient_command.cpp b/tests/automatic/curl_http_client/curl_http_client_command/curl_httpclient_command.cpp index 875c054d1ea92a648f49fd60a2c89213e4f19b55..65634120cb0beaeed8c2dab3b39413e4020700fd 100644 --- a/tests/automatic/curl_http_client/curl_http_client_command/curl_httpclient_command.cpp +++ b/tests/automatic/curl_http_client/curl_http_client_command/curl_httpclient_command.cpp @@ -36,7 +36,7 @@ int main(int argc, char* argv[]) { auto consumer = asapo::ConsumerFactory::CreateConsumer(args.uri_authorizer, "", true, - asapo::SourceCredentials{asapo::SourceType::kProcessed, "", "", + asapo::SourceCredentials{asapo::SourceType::kProcessed, "", "", "", "", "", ""}, &err); auto consumer_impl = static_cast<asapo::ConsumerImpl*>(consumer.get()); diff --git a/tests/automatic/full_chain/CMakeLists.txt b/tests/automatic/full_chain/CMakeLists.txt index a13904442843c0b2787fde56dfcc4d01ee5f15e3..c1e1208856930c9d0e938b1a919b8b9f9f62319e 100644 --- a/tests/automatic/full_chain/CMakeLists.txt +++ b/tests/automatic/full_chain/CMakeLists.txt @@ -14,3 +14,7 @@ add_subdirectory(simple_chain_filegen_readdata_cache) add_subdirectory(simple_chain_filegen_readdata_file) add_subdirectory(simple_chain_dataset) add_subdirectory(send_recv_streams) + +if (UNIX) + add_subdirectory(simple_chain_monitoring) +endif() \ No newline at end of file diff --git a/tests/automatic/full_chain/send_recv_streams/check_linux.sh b/tests/automatic/full_chain/send_recv_streams/check_linux.sh index d1e48ef1f0f726694ac5ae067b5e5dc3f932717b..c5e1265cbe94fd5ebe2696b9fd2f4830ce59b578 100644 --- a/tests/automatic/full_chain/send_recv_streams/check_linux.sh +++ b/tests/automatic/full_chain/send_recv_streams/check_linux.sh @@ -12,13 +12,14 @@ token=$ASAPO_TEST_RW_TOKEN beamline=test set -e +set -o pipefail trap Cleanup EXIT network_type=$2 Cleanup() { - set +e + set +e echo "db.dropDatabase()" | mongo ${indatabase_name} } diff --git a/tests/automatic/full_chain/send_recv_streams/out b/tests/automatic/full_chain/send_recv_streams/out new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tests/automatic/full_chain/send_recv_streams/send_recv_streams.cpp b/tests/automatic/full_chain/send_recv_streams/send_recv_streams.cpp index a752a2ba27cd294f4f00112306e4ce075bf72d22..473254c96aa70537852ed84ee1bc3f73e4ff83a2 100644 --- a/tests/automatic/full_chain/send_recv_streams/send_recv_streams.cpp +++ b/tests/automatic/full_chain/send_recv_streams/send_recv_streams.cpp @@ -38,7 +38,7 @@ ConsumerPtr CreateConsumerAndGroup(const Args& args, Error* err) { auto consumer = asapo::ConsumerFactory::CreateConsumer(args.server, ".", true, - asapo::SourceCredentials{asapo::SourceType::kProcessed, + asapo::SourceCredentials{asapo::SourceType::kProcessed, "auto", "auto", args.beamtime_id, "", "", args.token}, err); if (*err) { @@ -61,7 +61,8 @@ ProducerPtr CreateProducer(const Args& args) { auto producer = asapo::Producer::Create(args.server, 1, asapo::RequestHandlerType::kTcp, asapo::SourceCredentials{asapo::SourceType::kProcessed, - args.beamtime_id, "", "", args.token }, 60000, &err); + "auto", "auto", + args.beamtime_id, "", "", args.token }, 60000, &err); if(err) { std::cerr << "Cannot start producer. ProducerError: " << err << std::endl; exit(EXIT_FAILURE); diff --git a/tests/automatic/full_chain/send_recv_streams_python/check_linux.sh b/tests/automatic/full_chain/send_recv_streams_python/check_linux.sh index 7e9b4f3db1fc1c8868bfef0a128df7ed97fc7029..46f17934f7ecd52ef6f533bc58159f77a3a08920 100644 --- a/tests/automatic/full_chain/send_recv_streams_python/check_linux.sh +++ b/tests/automatic/full_chain/send_recv_streams_python/check_linux.sh @@ -10,11 +10,13 @@ token=$ASAPO_TEST_RW_TOKEN beamline=test set -e +set -o pipefail trap Cleanup EXIT Cleanup() { set +e + set +o pipefail echo "db.dropDatabase()" | mongo ${indatabase_name} } diff --git a/tests/automatic/full_chain/send_recv_streams_python/send_recv_streams.py b/tests/automatic/full_chain/send_recv_streams_python/send_recv_streams.py index 5f48b974a311c3bb9cc7278465c49ac3c0712f04..655549e8205437b68f981f1aa3d5db151da63229 100644 --- a/tests/automatic/full_chain/send_recv_streams_python/send_recv_streams.py +++ b/tests/automatic/full_chain/send_recv_streams_python/send_recv_streams.py @@ -25,8 +25,8 @@ def callback(header,err): source, beamtime, token = sys.argv[1:] -consumer = asapo_consumer.create_consumer(source,".",True, beamtime,"",token,timeout) -producer = asapo_producer.create_producer(source,'processed',beamtime,'auto', "", token, 1, 600000) +consumer = asapo_consumer.create_consumer(source,".",True,beamtime,"",token,timeout,"auto","Consumer") +producer = asapo_producer.create_producer(source,'processed',beamtime,'auto', "", token, 1, 600000,"auto","Producer") producer.set_log_level("debug") group_id = consumer.generate_group_id() @@ -48,7 +48,7 @@ while True: n_recv = n_recv + 1 except asapo_consumer.AsapoStreamFinishedError as finished_stream: stream_finished = True - assert_eq(finished_stream.id_max, 11, "last id") + assert_eq(finished_stream.id_max, 10, "last id") assert_eq(finished_stream.next_stream, "next_stream", "next stream") break diff --git a/tests/automatic/full_chain/simple_chain/check_linux.sh b/tests/automatic/full_chain/simple_chain/check_linux.sh index ac9a737c668eb860c96eb2f3234b8d5e76d45a85..3da99d15daf3fb46ba308017360eb32ac126aad4 100755 --- a/tests/automatic/full_chain/simple_chain/check_linux.sh +++ b/tests/automatic/full_chain/simple_chain/check_linux.sh @@ -25,7 +25,19 @@ Cleanup() { rm -rf ${receiver_root_folder} rm -rf out echo "db.dropDatabase()" | mongo ${beamtime_id}_detector - influx -database ${monitor_database_name} -execute "drop series from statistics, RequestsRate" + + set +e + influx_out=`influx -database ${monitor_database_name} -execute "drop series from statistics, RequestsRate"` + influx_status=$? + echo "Influx output: ${influx_out}" + if [ $influx_status -ne 0 ]; then + if [[ $influx_out == *"401"* ]]; then + echo "Ignoring auth error from influxdb" + else + echo "influxdb failed to delete test database '${monitor_database_name}'" + exit $influx_status + fi + fi } token=`$asapo_tool_bin token -endpoint http://localhost:8400/asapo-authorizer -secret admin_token.key -types read $beamtime_id` diff --git a/tests/automatic/full_chain/simple_chain_dataset/check_linux.sh b/tests/automatic/full_chain/simple_chain_dataset/check_linux.sh index 15964cc6e2b423dcb190e40704591badbe4d713b..bce784a816dde961f9235bcd894c095720af22fb 100644 --- a/tests/automatic/full_chain/simple_chain_dataset/check_linux.sh +++ b/tests/automatic/full_chain/simple_chain_dataset/check_linux.sh @@ -26,7 +26,19 @@ Cleanup() { rm -rf ${receiver_root_folder} rm -rf out echo "db.dropDatabase()" | mongo ${beamtime_id}_detector - influx -database ${monitor_database_name} -execute "drop series from statistics, RequestsRate" + + set +e + influx_out=`influx -database ${monitor_database_name} -execute "drop series from statistics, RequestsRate"` + influx_status=$? + echo "Influx output: ${influx_out}" + if [ $influx_status -ne 0 ]; then + if [[ $influx_out == *"401"* ]]; then + echo "Ignoring auth error from influxdb" + else + echo "influxdb failed to delete test database '${monitor_database_name}'" + exit $influx_status + fi + fi } token=`$asapo_tool_bin token -endpoint http://localhost:8400/asapo-authorizer -secret admin_token.key -types read $beamtime_id` diff --git a/tests/automatic/full_chain/simple_chain_filegen_readdata_cache/check_linux.sh b/tests/automatic/full_chain/simple_chain_filegen_readdata_cache/check_linux.sh index 00391dff42752e43ee8ee50eaec14060486c4f7c..8bab44a7dbcffb73650feb0a9443c74d94d7e369 100644 --- a/tests/automatic/full_chain/simple_chain_filegen_readdata_cache/check_linux.sh +++ b/tests/automatic/full_chain/simple_chain_filegen_readdata_cache/check_linux.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash set -e +set -o pipefail trap Cleanup EXIT @@ -26,6 +27,7 @@ mkdir -p /tmp/asapo/test_in/processed Cleanup() { echo cleanup set +e + set +o pipefail if [[ $network_type == "fabric" ]]; then nomad stop receiver nomad run receiver_tcp.nmd @@ -40,9 +42,21 @@ Cleanup() { kill -9 $producerid rm -rf /tmp/asapo/test_in rm -rf ${receiver_folder} - influx -database ${monitor_database_name} -execute "drop series from statistics, RequestsRate" echo "db.dropDatabase()" | mongo ${beamtime_id}_detector rm out.txt + + set +e + influx_out=`influx -database ${monitor_database_name} -execute "drop series from statistics, RequestsRate"` + influx_status=$? + echo "Influx output: ${influx_out}" + if [ $influx_status -ne 0 ]; then + if [[ $influx_out == *"401"* ]]; then + echo "Ignoring auth error from influxdb" + else + echo "influxdb failed to delete test database '${monitor_database_name}'" + exit $influx_status + fi + fi } if [[ $network_type == "fabric" ]]; then diff --git a/tests/automatic/full_chain/simple_chain_filegen_readdata_file/check_linux.sh b/tests/automatic/full_chain/simple_chain_filegen_readdata_file/check_linux.sh index 36e82adc9cdb5761f3c47f6e80ff0f1f9e85a1f7..cf3c1e89bb5c790daadc870fbad3ba996f9c2e2d 100644 --- a/tests/automatic/full_chain/simple_chain_filegen_readdata_file/check_linux.sh +++ b/tests/automatic/full_chain/simple_chain_filegen_readdata_file/check_linux.sh @@ -27,9 +27,21 @@ Cleanup() { kill -9 $producerid rm -rf /tmp/asapo/test_in rm -rf ${receiver_folder} - influx -database ${monitor_database_name} -execute "drop series from statistics, RequestsRate" echo "db.dropDatabase()" | mongo ${beamtime_id}_detector rm out.txt + + set +e + influx_out=`influx -database ${monitor_database_name} -execute "drop series from statistics, RequestsRate"` + influx_status=$? + echo "Influx output: ${influx_out}" + if [ $influx_status -ne 0 ]; then + if [[ $influx_out == *"401"* ]]; then + echo "Ignoring auth error from influxdb" + else + echo "influxdb failed to delete test database '${monitor_database_name}'" + exit $influx_status + fi + fi } token=`$asapo_tool_bin token -endpoint http://localhost:8400/asapo-authorizer -secret admin_token.key -types read $beamtime_id` diff --git a/tests/automatic/full_chain/simple_chain_metadata/check_linux.sh b/tests/automatic/full_chain/simple_chain_metadata/check_linux.sh index b7594898e3a9a70412da154ae9b5aebb9609d937..e17e25cc0b6b23974713bfcfa184a6c3355035bf 100644 --- a/tests/automatic/full_chain/simple_chain_metadata/check_linux.sh +++ b/tests/automatic/full_chain/simple_chain_metadata/check_linux.sh @@ -25,7 +25,19 @@ Cleanup() { rm -rf ${receiver_root_folder} rm -rf out echo "db.dropDatabase()" | mongo ${beamtime_id}_detector - influx -database ${monitor_database_name} -execute "drop series from statistics, RequestsRate" + + set +e + influx_out=`influx -database ${monitor_database_name} -execute "drop series from statistics, RequestsRate"` + influx_status=$? + echo "Influx output: ${influx_out}" + if [ $influx_status -ne 0 ]; then + if [[ $influx_out == *"401"* ]]; then + echo "Ignoring auth error from influxdb" + else + echo "influxdb failed to delete test database '${monitor_database_name}'" + exit $influx_status + fi + fi } token=`$asapo_tool_bin token -endpoint http://localhost:8400/asapo-authorizer -secret admin_token.key -types read $beamtime_id` diff --git a/tests/automatic/full_chain/simple_chain_monitoring/CMakeLists.txt b/tests/automatic/full_chain/simple_chain_monitoring/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..93c4e277024c843786196b7b23d88534969777d7 --- /dev/null +++ b/tests/automatic/full_chain/simple_chain_monitoring/CMakeLists.txt @@ -0,0 +1,7 @@ +set(TARGET_NAME full_chain_monitoring) + +################################ +# Testing +################################ +configure_file(${CMAKE_SOURCE_DIR}/tests/automatic/settings/admin_token.key admin_token.key COPYONLY) +add_script_test("${TARGET_NAME}" "$<TARGET_FILE:dummy-data-producer> $<TARGET_FILE:getnext> $<TARGET_PROPERTY:asapo,EXENAME>" nomem) diff --git a/tests/automatic/full_chain/simple_chain_monitoring/check_linux.sh b/tests/automatic/full_chain/simple_chain_monitoring/check_linux.sh new file mode 100755 index 0000000000000000000000000000000000000000..313375b737d064a4674331bb13e3a82290ac3cfb --- /dev/null +++ b/tests/automatic/full_chain/simple_chain_monitoring/check_linux.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash + +set -e + +trap Cleanup EXIT + +producer_bin=$1 +consumer_bin=$2 +asapo_tool_bin=$3 + +beamtime_id=asapo_test + +monitor_database_name=db_test +new_monitor_database_name=asapo_monitoring + +proxy_address=127.0.0.1:8400 + +beamline=test +receiver_root_folder=/tmp/asapo/receiver/files +facility=test_facility +year=2019 +receiver_folder=${receiver_root_folder}/${facility}/gpfs/${beamline}/${year}/data/${beamtime_id} + + +Cleanup() { + echo cleanup + rm -rf ${receiver_root_folder} + rm -rf out + echo "db.dropDatabase()" | mongo ${beamtime_id}_detector + set +e + influx -database ${monitor_database_name} -execute "drop series from statistics, RequestsRate" +# influx -database ${new_monitor_database_name} -execute "drop series from /.*/" +} + +token=`$asapo_tool_bin token -endpoint http://localhost:8400/asapo-authorizer -secret admin_token.key -types read $beamtime_id` + +sleep 5 # to write to influxdb old data and the clean up +influx -database ${new_monitor_database_name} -execute "drop series from /.*/" + +echo "Start producer" +mkdir -p ${receiver_folder} +$producer_bin localhost:8400 ${beamtime_id} 100 100 4 0 100 + +echo "Start consumer in metadata only mode" +$consumer_bin ${proxy_address} ${receiver_folder} ${beamtime_id} 2 $token 2000 1 | tee out +grep "Processed 100 file(s)" out + +#check monitoring +sleep 5 # to write to influxdb +influx -execute "select sum(requestedFileCount) from brokerRequests" -database=${new_monitor_database_name} -format=json | tee /dev/stderr | jq .results[0].series[0].values[0][1] | tee /dev/stderr | grep 100 diff --git a/tests/automatic/full_chain/simple_chain_raw/check_linux.sh b/tests/automatic/full_chain/simple_chain_raw/check_linux.sh index 50214fb8142196677507e532e26f33bc11a8c643..b28ced67aefb45bd8c2ab296f2bde6b6d634db0d 100644 --- a/tests/automatic/full_chain/simple_chain_raw/check_linux.sh +++ b/tests/automatic/full_chain/simple_chain_raw/check_linux.sh @@ -19,7 +19,19 @@ Cleanup() { echo cleanup rm -rf out /tmp/asapo/asap3 /tmp/asapo/beamline echo "db.dropDatabase()" | mongo ${beamtime_id}_detector - influx -database ${monitor_database_name} -execute "drop series from statistics, RequestsRate" + + set +e + influx_out=`influx -database ${monitor_database_name} -execute "drop series from statistics, RequestsRate"` + influx_status=$? + echo "Influx output: ${influx_out}" + if [ $influx_status -ne 0 ]; then + if [[ $influx_out == *"401"* ]]; then + echo "Ignoring auth error from influxdb" + else + echo "influxdb failed to delete test database '${monitor_database_name}'" + exit $influx_status + fi + fi } echo "db.dropDatabase()" | mongo ${beamtime_id}_detector diff --git a/tests/automatic/full_chain/simple_chain_usermeta_python/check_linux.sh b/tests/automatic/full_chain/simple_chain_usermeta_python/check_linux.sh index 4054fef2804ddf41f3bf024f7ec467cfaa3daad4..fb1583d8a12df611e0aed47fd72dfa2d9add8578 100644 --- a/tests/automatic/full_chain/simple_chain_usermeta_python/check_linux.sh +++ b/tests/automatic/full_chain/simple_chain_usermeta_python/check_linux.sh @@ -24,7 +24,19 @@ Cleanup() { rm -rf ${receiver_root_folder} rm -rf out echo "db.dropDatabase()" | mongo ${beamtime_id}_detector - influx -database ${monitor_database_name} -execute "drop series from statistics, RequestsRate" + + set +e + influx_out=`influx -database ${monitor_database_name} -execute "drop series from statistics, RequestsRate"` + influx_status=$? + echo "Influx output: ${influx_out}" + if [ $influx_status -ne 0 ]; then + if [[ $influx_out == *"401"* ]]; then + echo "Ignoring auth error from influxdb" + else + echo "influxdb failed to delete test database '${monitor_database_name}'" + exit $influx_status + fi + fi } token=`$asapo_tool_bin token -endpoint http://localhost:8400/asapo-authorizer -secret admin_token.key -types read $beamtime_id` diff --git a/tests/automatic/full_chain/two_beamlines/check_linux.sh b/tests/automatic/full_chain/two_beamlines/check_linux.sh index 75be4ed22026e9719d0e328dfda1218e3ab16c87..f2fbb99e0c030d7c7a304a0920d79976614ee460 100644 --- a/tests/automatic/full_chain/two_beamlines/check_linux.sh +++ b/tests/automatic/full_chain/two_beamlines/check_linux.sh @@ -43,7 +43,19 @@ Cleanup() { rm -rf ${receiver_root_folder} echo "db.dropDatabase()" | mongo ${beamtime_id1}_${data_source} echo "db.dropDatabase()" | mongo ${beamtime_id2}_${data_source} - influx -database ${monitor_database_name} -execute "drop series from statistics, RequestsRate" + + set +e + influx_out=`influx -database ${monitor_database_name} -execute "drop series from statistics, RequestsRate"` + influx_status=$? + echo "Influx output: ${influx_out}" + if [ $influx_status -ne 0 ]; then + if [[ $influx_out == *"401"* ]]; then + echo "Ignoring auth error from influxdb" + else + echo "influxdb failed to delete test database '${monitor_database_name}'" + exit $influx_status + fi + fi } if [[ $network_type == "fabric" ]]; then diff --git a/tests/automatic/producer/beamtime_metadata/beamtime_metadata.cpp b/tests/automatic/producer/beamtime_metadata/beamtime_metadata.cpp index e0639f5f6a426fd88176d9b3aa1b6fe104371a79..d1f82fd9f06eb93abbee734fa87fbcec4a692d55 100644 --- a/tests/automatic/producer/beamtime_metadata/beamtime_metadata.cpp +++ b/tests/automatic/producer/beamtime_metadata/beamtime_metadata.cpp @@ -69,7 +69,7 @@ std::unique_ptr<asapo::Producer> CreateProducer(const Args& args) { args.mode == 0 ? asapo::RequestHandlerType::kTcp : asapo::RequestHandlerType::kFilesystem, asapo::SourceCredentials{asapo::SourceType::kProcessed, - args.beamtime_id, "", "", ""}, 60000, &err); + "auto", "auto", args.beamtime_id, "", "", ""}, 60000, &err); if (err) { std::cerr << "Cannot start producer. ProducerError: " << err << std::endl; exit(EXIT_FAILURE); diff --git a/tests/automatic/producer/c_api/producer_api.c b/tests/automatic/producer/c_api/producer_api.c index 2829064da3461e38e539065c1f391bebc88f124c..744c5601df5ebf8e9d805ef4e6d2010b7fc0006d 100644 --- a/tests/automatic/producer/c_api/producer_api.c +++ b/tests/automatic/producer/c_api/producer_api.c @@ -103,8 +103,8 @@ int main(int argc, char* argv[]) { AsapoErrorHandle err = asapo_new_handle(); AsapoSourceCredentialsHandle cred = asapo_create_source_credentials(kProcessed, - beamtime, - "", source, ""); + "auto", "auto", + beamtime, "", source, ""); AsapoProducerHandle producer = asapo_create_producer(endpoint,3,kTcp, cred,60000,&err); EXIT_IF_ERROR("create producer", err); diff --git a/tests/automatic/producer/cpp_api/producer_api.cpp b/tests/automatic/producer/cpp_api/producer_api.cpp index 699c3978d3c32851019bfae5b220d3a1eca0c2e7..dbe9cdf2411a7c675e34bc405c54207746367d90 100644 --- a/tests/automatic/producer/cpp_api/producer_api.cpp +++ b/tests/automatic/producer/cpp_api/producer_api.cpp @@ -66,7 +66,8 @@ std::unique_ptr<asapo::Producer> CreateProducer(const Args& args) { asapo::Error err; auto producer = asapo::Producer::Create(args.server, 2, asapo::RequestHandlerType::kTcp, - asapo::SourceCredentials{asapo::SourceType::kProcessed, args.beamtime, + asapo::SourceCredentials{asapo::SourceType::kProcessed, + "auto", "auto", args.beamtime, "", args.source, ""}, 60000, &err); if (err) { std::cerr << "Cannot start producer. ProducerError: " << err << std::endl; diff --git a/tests/automatic/producer_receiver/check_monitoring/check_linux.sh b/tests/automatic/producer_receiver/check_monitoring/check_linux.sh index 8c08a2f3d30873a9bda0e608f6ac2fe9c4e43462..bf4e1e7161f6e71e55aba9d6ae526116deb97faf 100644 --- a/tests/automatic/producer_receiver/check_monitoring/check_linux.sh +++ b/tests/automatic/producer_receiver/check_monitoring/check_linux.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash database_name=db_test +new_monitor_database_name=asapo_monitoring beamtime_id=asapo_test beamline=test receiver_root_folder=/tmp/asapo/receiver/files @@ -15,8 +16,9 @@ trap Cleanup EXIT Cleanup() { echo cleanup influx -database ${database_name} -execute "drop series from statistics, RequestsRate" - echo "db.dropDatabase()" | mongo ${beamtime_id}_detector - rm -rf ${receiver_root_folder} + influx -database ${new_monitor_database_name} -execute "drop series from /.*/" + echo "db.dropDatabase()" | mongo ${beamtime_id}_detector + rm -rf ${receiver_root_folder} } mkdir -p ${receiver_folder} diff --git a/tests/automatic/settings/broker_settings.json b/tests/automatic/settings/broker_settings.json index 4847d08451af7849c37e902b8a9d911014558fb8..276c5eaefa2eab50da07cd0e444196d55fece395 100644 --- a/tests/automatic/settings/broker_settings.json +++ b/tests/automatic/settings/broker_settings.json @@ -1,10 +1,12 @@ { "DatabaseServer":"127.0.0.1:27017", + "DiscoveryServer": "localhost:8400/asapo-discovery", "PerformanceDbServer": "localhost:8086", "MonitorPerformance": true, + "MonitoringServerUrl":"auto", "AuthorizationServer": "localhost:8400/asapo-authorizer", "PerformanceDbName": "db_test", "Port":5005, "LogLevel":"debug", "CheckResendInterval":0 -} \ No newline at end of file +} diff --git a/tests/automatic/settings/broker_settings.json.tpl b/tests/automatic/settings/broker_settings.json.tpl index 66c5bc9e0e34476cb19c97e829f41757eaf01922..95aa8e4afa29c3f84606b754c985a7fb13a36bd2 100644 --- a/tests/automatic/settings/broker_settings.json.tpl +++ b/tests/automatic/settings/broker_settings.json.tpl @@ -4,8 +4,9 @@ "AuthorizationServer": "localhost:8400/asapo-authorizer", "PerformanceDbServer": "localhost:8086", "MonitorPerformance": true, + "MonitoringServerUrl":"auto", "CheckResendInterval":0, "PerformanceDbName": "db_test", "Port":{{ env "NOMAD_PORT_broker" }}, "LogLevel":"debug" -} \ No newline at end of file +} diff --git a/tests/automatic/settings/file_transfer_settings.json.tpl b/tests/automatic/settings/file_transfer_settings.json.tpl index 0248e349825302f6a72d3f01fae4c230962d4f2b..b02ba44d0525ea57ed8bcd37a8f8ae6519dc1fc7 100644 --- a/tests/automatic/settings/file_transfer_settings.json.tpl +++ b/tests/automatic/settings/file_transfer_settings.json.tpl @@ -1,5 +1,8 @@ { "Port": {{ env "NOMAD_PORT_file_transfer" }}, "LogLevel":"debug", - "SecretFile":"auth_secret.key" + "SecretFile":"auth_secret.key", + "DiscoveryServer": "localhost:8400/asapo-discovery", + "MonitorPerformance": true, + "MonitoringServerUrl": "auto" } diff --git a/tests/automatic/settings/monitoring_server_settings.json.tpl b/tests/automatic/settings/monitoring_server_settings.json.tpl new file mode 100644 index 0000000000000000000000000000000000000000..98be42e62e09266518ab032bb99e130bc2d2d48f --- /dev/null +++ b/tests/automatic/settings/monitoring_server_settings.json.tpl @@ -0,0 +1,7 @@ +{ + "ThisClusterName": "asapo", + "ServerPort": {{ env "NOMAD_PORT_monitoring_server" }}, + "LogLevel": "debug", + "InfluxDbUrl": "http://localhost:8086", + "InfluxDbDatabase": "asapo_monitoring" +} diff --git a/tests/automatic/settings/receiver_fabric.json.tpl.lin.in b/tests/automatic/settings/receiver_fabric.json.tpl.lin.in index c3eb3f433ad53e400df06d1803f4eecd67c087d5..ff23cda05e003c5f20dfee4a716a61743bf8892e 100644 --- a/tests/automatic/settings/receiver_fabric.json.tpl.lin.in +++ b/tests/automatic/settings/receiver_fabric.json.tpl.lin.in @@ -1,4 +1,5 @@ { + "MonitoringServer": "auto", "PerformanceDbServer":"localhost:8086", "MonitorPerformance": true, "PerformanceDbName": "db_test", diff --git a/tests/automatic/settings/receiver_kafka.json.tpl.lin.in b/tests/automatic/settings/receiver_kafka.json.tpl.lin.in index f9d0fae47e197697f9174e37b2dfb87ce634e7ba..d7bd04f56d72552911b1f5bb46f1fa4993d4a0c3 100644 --- a/tests/automatic/settings/receiver_kafka.json.tpl.lin.in +++ b/tests/automatic/settings/receiver_kafka.json.tpl.lin.in @@ -1,4 +1,5 @@ { + "MonitoringServer": "auto", "PerformanceDbServer":"localhost:8086", "MonitorPerformance": true, "PerformanceDbName": "db_test", diff --git a/tests/automatic/settings/receiver_tcp.json.tpl.lin.in b/tests/automatic/settings/receiver_tcp.json.tpl.lin.in index ebaa3aea27f523d7c06d0d61d9c72825e054da98..386a9db3cd48193d1d335f938f0a16272670e99e 100644 --- a/tests/automatic/settings/receiver_tcp.json.tpl.lin.in +++ b/tests/automatic/settings/receiver_tcp.json.tpl.lin.in @@ -1,4 +1,5 @@ { + "MonitoringServer": "auto", "PerformanceDbServer":"localhost:8086", "MonitorPerformance": true, "PerformanceDbName": "db_test", diff --git a/tests/automatic/settings/receiver_tcp.json.tpl.win.in b/tests/automatic/settings/receiver_tcp.json.tpl.win.in index 1c08e1b8448bf8fa79092889266ca74c69d925c6..de39191ca2c7fb1ed0219d28dd5c47187d811429 100644 --- a/tests/automatic/settings/receiver_tcp.json.tpl.win.in +++ b/tests/automatic/settings/receiver_tcp.json.tpl.win.in @@ -1,4 +1,5 @@ { + "MonitoringServer": "auto", "PerformanceDbServer":"localhost:8086", "MonitorPerformance": true, "PerformanceDbName": "db_test", diff --git a/tests/automatic/support/getnext/getnext.cpp b/tests/automatic/support/getnext/getnext.cpp index a5689ca1b5da3d92dc6e0ecf2128394c1868a067..662930f121726a35faa3259d7ce2839709e072ad 100644 --- a/tests/automatic/support/getnext/getnext.cpp +++ b/tests/automatic/support/getnext/getnext.cpp @@ -43,6 +43,7 @@ struct Args { bool read_data; bool datasets; bool need_beamtime_meta = false; + std::string pipeline_name = "GetNextPipelineStep"; }; class LatchedTimer { @@ -104,6 +105,7 @@ StartThreads(const Args& params, std::vector<int>* nfiles, std::vector<int>* err params.file_path, true, asapo::SourceCredentials{asapo::SourceType::kProcessed, + "auto", params.pipeline_name, params.beamtime_id, "", params.data_source, params.token}, &err); @@ -268,11 +270,10 @@ void TryGetStream(Args* args) { int main(int argc, char* argv[]) { Args params; params.datasets = false; - if (argc != 8 && argc != 9 && argc != 10) { + if (argc != 8 && argc != 9 && argc != 10 && argc != 11) { std::cout << "Usage: " + std::string{argv[0]} - + " <server> <files_path> <run_name> <nthreads> <token> <timeout ms> <metaonly> [use datasets] [send metadata]" - << - std::endl; + + " <server> <files_path> <beamtime_id[%<data_source>[%<token>]]> <nthreads> <token> <timeout ms> <metaonly> [use datasets] [send metadata] [pipelinename]" + << std::endl; exit(EXIT_FAILURE); } params.server = std::string{argv[1]}; @@ -289,6 +290,9 @@ int main(int argc, char* argv[]) { if (argc == 10) { params.need_beamtime_meta = atoi(argv[9]) == 1; } + if (argc == 11) { + params.pipeline_name = argv[10]; + } if (params.read_data) { std::cout << "Will read metadata+payload" << std::endl;