diff --git a/.gitmodules b/.gitmodules
index df5b4ae..cba1613 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,22 +1,15 @@
-[submodule "lib/RmlUi"]
- path = lib/RmlUi
- url = https://github.com/mikke89/RmlUi/
[submodule "lib/rt64"]
path = lib/rt64
url = https://github.com/rt64/rt64
-[submodule "lib/freetype-windows-binaries"]
- path = lib/freetype-windows-binaries
- url = https://github.com/ubawurinna/freetype-windows-binaries
[submodule "lib/mm-decomp"]
path = lib/mm-decomp
url = https://github.com/zeldaret/mm
-[submodule "lib/lunasvg"]
- path = lib/lunasvg
- url = https://github.com/sammycage/lunasvg
[submodule "lib/N64ModernRuntime"]
path = lib/N64ModernRuntime
url = https://github.com/N64Recomp/N64ModernRuntime.git
[submodule "Zelda64RecompSyms"]
path = Zelda64RecompSyms
url = https://github.com/Zelda64Recomp/Zelda64RecompSyms
-
+[submodule "lib/RecompFrontend"]
+ path = lib/RecompFrontend
+ url = https://github.com/N64Recomp/RecompFrontend
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1cdda09..51e19b0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -51,15 +51,7 @@ endif()
add_subdirectory(${CMAKE_SOURCE_DIR}/lib/rt64 ${CMAKE_BINARY_DIR}/rt64)
-# set(BUILD_SHARED_LIBS_SAVED "${BUILD_SHARED_LIBS}")
set(BUILD_SHARED_LIBS OFF)
-SET(LUNASVG_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
-add_subdirectory(${CMAKE_SOURCE_DIR}/lib/lunasvg)
-# set(BUILD_SHARED_LIBS "${BUILD_SHARED_LIBS_SAVED}")
-SET(RMLUI_SVG_PLUGIN ON CACHE BOOL "" FORCE)
-SET(RMLUI_TESTS_ENABLED OFF CACHE BOOL "" FORCE)
-add_subdirectory(${CMAKE_SOURCE_DIR}/lib/RmlUi)
-target_compile_definitions(rmlui_core PRIVATE LUNASVG_BUILD_STATIC)
add_subdirectory(${CMAKE_SOURCE_DIR}/lib/N64ModernRuntime)
@@ -148,14 +140,13 @@ add_custom_command(OUTPUT
add_executable(Zelda64Recompiled)
set (SOURCES
+ ${CMAKE_SOURCE_DIR}/src/main/launcher_animation.cpp
${CMAKE_SOURCE_DIR}/src/main/main.cpp
${CMAKE_SOURCE_DIR}/src/main/support.cpp
${CMAKE_SOURCE_DIR}/src/main/register_overlays.cpp
${CMAKE_SOURCE_DIR}/src/main/register_patches.cpp
- ${CMAKE_SOURCE_DIR}/src/main/rt64_render_context.cpp
+ ${CMAKE_SOURCE_DIR}/src/main/theme.cpp
- ${CMAKE_SOURCE_DIR}/src/game/input.cpp
- ${CMAKE_SOURCE_DIR}/src/game/controls.cpp
${CMAKE_SOURCE_DIR}/src/game/config.cpp
${CMAKE_SOURCE_DIR}/src/game/scene_table.cpp
${CMAKE_SOURCE_DIR}/src/game/debug.cpp
@@ -165,68 +156,35 @@ set (SOURCES
${CMAKE_SOURCE_DIR}/src/game/recomp_data_api.cpp
${CMAKE_SOURCE_DIR}/src/game/rom_decompression.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/ui_renderer.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/ui_state.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/ui_launcher.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/ui_config.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/ui_prompt.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/ui_config_sub_menu.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/ui_color_hack.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/ui_rml_hacks.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/ui_elements.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/ui_mod_details_panel.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/ui_mod_installer.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/ui_mod_menu.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/ui_api.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/ui_api_events.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/ui_api_images.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/ui_utils.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/util/hsv.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/core/ui_context.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_button.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_clickable.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_container.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_element.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_image.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_label.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_radio.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_scroll_container.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_slider.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_span.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_style.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_text_input.cpp
- ${CMAKE_SOURCE_DIR}/src/ui/elements/ui_toggle.cpp
-
${CMAKE_SOURCE_DIR}/rsp/aspMain.cpp
${CMAKE_SOURCE_DIR}/rsp/njpgdspMain.cpp
-
- ${CMAKE_SOURCE_DIR}/lib/RmlUi/Backends/RmlUi_Platform_SDL.cpp
)
-if (APPLE)
- list(APPEND SOURCES ${CMAKE_SOURCE_DIR}/src/main/support_apple.mm)
-endif()
-
target_include_directories(Zelda64Recompiled PRIVATE
${CMAKE_SOURCE_DIR}/include
${CMAKE_SOURCE_DIR}/lib/N64ModernRuntime/N64Recomp/include
- ${CMAKE_SOURCE_DIR}/lib/concurrentqueue
- ${CMAKE_SOURCE_DIR}/lib/GamepadMotionHelpers
- ${CMAKE_SOURCE_DIR}/lib/RmlUi/Include
- ${CMAKE_SOURCE_DIR}/lib/RmlUi/Backends
+ ${CMAKE_SOURCE_DIR}/lib/N64ModernRuntime/thirdparty/sse2neon
${CMAKE_SOURCE_DIR}/lib/rt64/src/contrib
${CMAKE_SOURCE_DIR}/lib/rt64/src/contrib/hlslpp/include
${CMAKE_SOURCE_DIR}/lib/rt64/src/contrib/dxc/inc
${CMAKE_SOURCE_DIR}/lib/rt64/src
${CMAKE_SOURCE_DIR}/lib/rt64/src/rhi
${CMAKE_SOURCE_DIR}/lib/rt64/src/render
- ${CMAKE_SOURCE_DIR}/lib/freetype-windows-binaries/include
+ ${CMAKE_SOURCE_DIR}/lib/RecompFrontend/recompinput/include
+ ${CMAKE_SOURCE_DIR}/lib/RecompFrontend/recompui/include
+ ${CMAKE_SOURCE_DIR}/lib/RecompFrontend/recompui/src
${CMAKE_SOURCE_DIR}/lib/rt64/src/contrib/nativefiledialog-extended/src/include
${CMAKE_SOURCE_DIR}/lib/SlotMap
- ${CMAKE_BINARY_DIR}/shaders
${CMAKE_CURRENT_BINARY_DIR}
)
+# Generate icon_bytes.c from the app icon PNG.
+add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/icon_bytes.c ${CMAKE_CURRENT_BINARY_DIR}/icon_bytes.h
+ COMMAND file_to_c ${CMAKE_SOURCE_DIR}/icons/512.png icon_bytes ${CMAKE_CURRENT_BINARY_DIR}/icon_bytes.c ${CMAKE_CURRENT_BINARY_DIR}/icon_bytes.h
+ DEPENDS ${CMAKE_SOURCE_DIR}/icons/512.png
+)
+target_sources(Zelda64Recompiled PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/icon_bytes.c)
+
if(CMAKE_SIZEOF_VOID_P EQUAL 8 AND CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|amd64|AMD64")
target_compile_options(Zelda64Recompiled PRIVATE
-march=nehalem
@@ -309,14 +267,9 @@ endif()
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
find_package(SDL2 REQUIRED)
- add_compile_definitions("RT64_SDL_WINDOW_VULKAN")
- # Generate icon_bytes.c from the app icon PNG.
- add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/icon_bytes.c ${CMAKE_CURRENT_BINARY_DIR}/icon_bytes.h
- COMMAND file_to_c ${CMAKE_SOURCE_DIR}/icons/512.png icon_bytes ${CMAKE_CURRENT_BINARY_DIR}/icon_bytes.c ${CMAKE_CURRENT_BINARY_DIR}/icon_bytes.h
- DEPENDS ${CMAKE_SOURCE_DIR}/icons/512.png
- )
- target_sources(Zelda64Recompiled PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/icon_bytes.c)
+ add_compile_definitions("PLUME_SDL_VULKAN_ENABLED")
+ add_compile_definitions("RT64_SDL_WINDOW_VULKAN")
message(STATUS "SDL2_FOUND = ${SDL2_FOUND}")
message(STATUS "SDL2_INCLUDE_DIRS = ${SDL2_INCLUDE_DIRS}")
@@ -339,18 +292,6 @@ if (CMAKE_SYSTEM_NAME MATCHES "Linux")
target_link_libraries(Zelda64Recompiled PRIVATE "-latomic -static-libstdc++" ${CMAKE_DL_LIBS} Threads::Threads)
endif()
-target_link_libraries(Zelda64Recompiled PRIVATE
- PatchesLib
- RecompiledFuncs
- librecomp
- ultramodern
- rt64
- RmlUi::Core
- RmlUi::Debugger
- nfd
- lunasvg
-)
-
# TODO fix the rt64 CMake script so that this doesn't need to be duplicated here
# For DXC
set (DXC_COMMON_OPTS "-I${PROJECT_SOURCE_DIR}/src")
@@ -383,8 +324,21 @@ else()
endif()
endif()
-build_vertex_shader(Zelda64Recompiled "shaders/InterfaceVS.hlsl" "shaders/InterfaceVS.hlsl")
-build_pixel_shader(Zelda64Recompiled "shaders/InterfacePS.hlsl" "shaders/InterfacePS.hlsl")
+set(RECOMP_FRONTEND_N64MODERNRUNTIME_PATH ${CMAKE_SOURCE_DIR}/lib/N64ModernRuntime)
+set(RECOMP_FRONTEND_RT64_PATH ${CMAKE_SOURCE_DIR}/lib/rt64)
+
+add_subdirectory(${CMAKE_SOURCE_DIR}/lib/RecompFrontend)
+
+target_link_libraries(Zelda64Recompiled PRIVATE
+ PatchesLib
+ RecompiledFuncs
+ recompui
+ recompinput
+ librecomp
+ ultramodern
+ rt64
+ nfd
+)
# Embed all .nrm files in the "mods" directory
file(GLOB NRM_FILES "${CMAKE_SOURCE_DIR}/mods/*.nrm")
diff --git a/assets/config_menu/controls.rml b/assets/config_menu/controls.rml
deleted file mode 100644
index d947ae8..0000000
--- a/assets/config_menu/controls.rml
+++ /dev/null
@@ -1,360 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/assets/config_menu/debug.rml b/assets/config_menu/debug.rml
deleted file mode 100644
index 22cb26e..0000000
--- a/assets/config_menu/debug.rml
+++ /dev/null
@@ -1,108 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/assets/config_menu/general.rml b/assets/config_menu/general.rml
deleted file mode 100644
index 291bf8c..0000000
--- a/assets/config_menu/general.rml
+++ /dev/null
@@ -1,369 +0,0 @@
-
-
-
-
-
-
-
diff --git a/assets/config_menu/graphics.rml b/assets/config_menu/graphics.rml
deleted file mode 100644
index a11de72..0000000
--- a/assets/config_menu/graphics.rml
+++ /dev/null
@@ -1,325 +0,0 @@
-
-
-
-
-
-
-
diff --git a/assets/config_menu/mods.rml b/assets/config_menu/mods.rml
deleted file mode 100644
index debab39..0000000
--- a/assets/config_menu/mods.rml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
diff --git a/assets/config_menu/sound.rml b/assets/config_menu/sound.rml
deleted file mode 100644
index badadce..0000000
--- a/assets/config_menu/sound.rml
+++ /dev/null
@@ -1,89 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/assets/icons/Cont.svg b/assets/icons/Cont.svg
new file mode 100644
index 0000000..5959613
--- /dev/null
+++ b/assets/icons/Cont.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/icons/Keyboard.svg b/assets/icons/Keyboard.svg
new file mode 100644
index 0000000..880ceb0
--- /dev/null
+++ b/assets/icons/Keyboard.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/scss/.nvmrc b/assets/scss/.nvmrc
deleted file mode 100644
index b7586d6..0000000
--- a/assets/scss/.nvmrc
+++ /dev/null
@@ -1 +0,0 @@
-iron
diff --git a/assets/scss/.stylelintrc b/assets/scss/.stylelintrc
deleted file mode 100644
index 60ad85f..0000000
--- a/assets/scss/.stylelintrc
+++ /dev/null
@@ -1,99 +0,0 @@
-{
- "extends": [
- "stylelint-config-recommended",
- "stylelint-config-standard",
- "stylelint-config-sass-guidelines",
- "stylelint-config-property-sort-order-smacss",
- "stylelint-config-standard-scss"
- ],
- "plugins": ["stylelint-scss"],
- "overrides": [{
- "files": ["**/*.scss"],
- "customSyntax": "postcss-scss"
- }],
- "rules": {
- "no-descending-specificity": null,
- "declaration-empty-line-before": null,
- "declaration-colon-newline-after": null,
- "declaration-block-no-duplicate-properties": true,
- "declaration-block-trailing-semicolon": null,
- "declaration-no-important": true,
- "declaration-property-value-disallowed-list": {
- "/^transition/": ["/all/"]
- },
- "block-closing-brace-newline-after": null,
- "max-empty-lines": null,
- "selector-list-comma-newline-after": null,
- "at-rule-empty-line-before": null,
- "at-rule-semicolon-newline-after": null,
- "selector-pseudo-element-colon-notation": "single",
- "color-no-hex": true,
- "function-url-quotes": "always",
- "max-nesting-depth": [
- 4,
- {
- "ignoreAtRules": ["each", "media", "supports", "include"],
- "severity": "warning"
- }
- ],
- "number-leading-zero": null,
- "order/order": [
- [
- "custom-properties",
- "dollar-variables",
- {
- "type": "at-rule",
- "name": "extend"
- },
- {
- "type": "at-rule",
- "name": "include"
- },
- "declarations",
- "rules"
- ]
- ],
- "order/properties-alphabetical-order": null,
- "property-no-vendor-prefix": [
- true,
- {
- "severity": "warning"
- }
- ],
- "value-no-vendor-prefix": [
- true,
- {
- "severity": "warning"
- }
- ],
- "scss/selector-no-redundant-nesting-selector": null,
- "selector-class-pattern": null,
- "selector-max-compound-selectors": [
- 4,
- {
- "severity": "warning"
- }
- ],
- "selector-no-qualifying-type": null,
- "string-quotes": null,
- "max-line-length": null,
- "keyframes-name-pattern": null,
- "scss/double-slash-comment-empty-line-before": null,
- "scss/double-slash-comment-whitespace-inside": null,
- "scss/dollar-variable-empty-line-before": null,
- "scss/dollar-variable-pattern": "[a-z-]",
- "scss/at-import-partial-extension": null,
- "declaration-block-no-redundant-longhand-properties": null,
- "color-function-notation": null,
- "alpha-value-notation": null,
- "at-rule-no-unknown": null,
- "property-no-unknown": null,
- "scss/at-rule-no-unknown": true,
- "selector-pseudo-class-no-unknown": [true, { "ignorePseudoClasses": ["selected"] }],
- "font-family-no-missing-generic-family-keyword": null,
- "scss/no-global-function-names": null,
- "unit-no-unknown": [true, { "ignoreUnits": ["dp"] }],
- "selector-type-no-unknown": [true, { "ignore": ["custom-elements", "default-namespace"] }],
- "value-keyword-case": null
- }
-}
diff --git a/assets/scss/main.scss b/assets/scss/main.scss
deleted file mode 100644
index 9d03ad3..0000000
--- a/assets/scss/main.scss
+++ /dev/null
@@ -1,2 +0,0 @@
-@import "styles/base";
-@import "styles/global";
diff --git a/assets/scss/package-lock.json b/assets/scss/package-lock.json
deleted file mode 100644
index 78ab77a..0000000
--- a/assets/scss/package-lock.json
+++ /dev/null
@@ -1,2261 +0,0 @@
-{
- "name": "mmrecomp-ui-scss",
- "version": "1.0.0",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "name": "mmrecomp-ui-scss",
- "version": "1.0.0",
- "license": "ISC",
- "dependencies": {
- "sass": "^1.75.0"
- },
- "devDependencies": {
- "postcss-scss": "^4.0.9",
- "stylelint": "^15.11.0",
- "stylelint-config-property-sort-order-smacss": "^9.1.0",
- "stylelint-config-sass-guidelines": "^10.0.0",
- "stylelint-config-scss": "^1.0.0-security",
- "stylelint-config-standard": "^34.0.0",
- "stylelint-config-standard-scss": "^11.1.0",
- "stylelint-scss": "^5.3.1"
- }
- },
- "node_modules/@babel/code-frame": {
- "version": "7.23.5",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz",
- "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==",
- "dev": true,
- "dependencies": {
- "@babel/highlight": "^7.23.4",
- "chalk": "^2.4.2"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-validator-identifier": {
- "version": "7.22.20",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
- "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
- "dev": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/highlight": {
- "version": "7.23.4",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz",
- "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==",
- "dev": true,
- "dependencies": {
- "@babel/helper-validator-identifier": "^7.22.20",
- "chalk": "^2.4.2",
- "js-tokens": "^4.0.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@csstools/css-parser-algorithms": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.3.2.tgz",
- "integrity": "sha512-sLYGdAdEY2x7TSw9FtmdaTrh2wFtRJO5VMbBrA8tEqEod7GEggFmxTSK9XqExib3yMuYNcvcTdCZIP6ukdjAIA==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/csstools"
- },
- {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
- }
- ],
- "engines": {
- "node": "^14 || ^16 || >=18"
- },
- "peerDependencies": {
- "@csstools/css-tokenizer": "^2.2.1"
- }
- },
- "node_modules/@csstools/css-tokenizer": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.2.1.tgz",
- "integrity": "sha512-Zmsf2f/CaEPWEVgw29odOj+WEVoiJy9s9NOv5GgNY9mZ1CZ7394By6wONrONrTsnNDv6F9hR02nvFihrGVGHBg==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/csstools"
- },
- {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
- }
- ],
- "engines": {
- "node": "^14 || ^16 || >=18"
- }
- },
- "node_modules/@csstools/media-query-list-parser": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.5.tgz",
- "integrity": "sha512-IxVBdYzR8pYe89JiyXQuYk4aVVoCPhMJkz6ElRwlVysjwURTsTk/bmY/z4FfeRE+CRBMlykPwXEVUg8lThv7AQ==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/csstools"
- },
- {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
- }
- ],
- "engines": {
- "node": "^14 || ^16 || >=18"
- },
- "peerDependencies": {
- "@csstools/css-parser-algorithms": "^2.3.2",
- "@csstools/css-tokenizer": "^2.2.1"
- }
- },
- "node_modules/@csstools/selector-specificity": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-3.0.0.tgz",
- "integrity": "sha512-hBI9tfBtuPIi885ZsZ32IMEU/5nlZH/KOVYJCOh7gyMxaVLGmLedYqFN6Ui1LXkI8JlC8IsuC0rF0btcRZKd5g==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/csstools"
- },
- {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
- }
- ],
- "engines": {
- "node": "^14 || ^16 || >=18"
- },
- "peerDependencies": {
- "postcss-selector-parser": "^6.0.13"
- }
- },
- "node_modules/@nodelib/fs.scandir": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
- "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
- "dev": true,
- "dependencies": {
- "@nodelib/fs.stat": "2.0.5",
- "run-parallel": "^1.1.9"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@nodelib/fs.stat": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
- "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
- "dev": true,
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@nodelib/fs.walk": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
- "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
- "dev": true,
- "dependencies": {
- "@nodelib/fs.scandir": "2.1.5",
- "fastq": "^1.6.0"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@types/minimist": {
- "version": "1.2.5",
- "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz",
- "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==",
- "dev": true
- },
- "node_modules/@types/normalize-package-data": {
- "version": "2.4.4",
- "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz",
- "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==",
- "dev": true
- },
- "node_modules/ajv": {
- "version": "8.12.0",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz",
- "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==",
- "dev": true,
- "dependencies": {
- "fast-deep-equal": "^3.1.1",
- "json-schema-traverse": "^1.0.0",
- "require-from-string": "^2.0.2",
- "uri-js": "^4.2.2"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
- }
- },
- "node_modules/ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/ansi-styles": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
- "dev": true,
- "dependencies": {
- "color-convert": "^1.9.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/anymatch": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
- "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
- "dependencies": {
- "normalize-path": "^3.0.0",
- "picomatch": "^2.0.4"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/argparse": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
- "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
- "dev": true
- },
- "node_modules/array-union": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
- "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/arrify": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
- "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/astral-regex": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
- "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/balanced-match": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz",
- "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==",
- "dev": true
- },
- "node_modules/binary-extensions": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
- "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/brace-expansion/node_modules/balanced-match": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
- "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
- "dev": true
- },
- "node_modules/braces": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
- "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
- "dependencies": {
- "fill-range": "^7.1.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/callsites": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
- "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/camelcase": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
- "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/camelcase-keys": {
- "version": "7.0.2",
- "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-7.0.2.tgz",
- "integrity": "sha512-Rjs1H+A9R+Ig+4E/9oyB66UC5Mj9Xq3N//vcLf2WzgdTi/3gUu3Z9KoqmlrEG4VuuLK8wJHofxzdQXz/knhiYg==",
- "dev": true,
- "dependencies": {
- "camelcase": "^6.3.0",
- "map-obj": "^4.1.0",
- "quick-lru": "^5.1.1",
- "type-fest": "^1.2.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "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/chokidar": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
- "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
- "dependencies": {
- "anymatch": "~3.1.2",
- "braces": "~3.0.2",
- "glob-parent": "~5.1.2",
- "is-binary-path": "~2.1.0",
- "is-glob": "~4.0.1",
- "normalize-path": "~3.0.0",
- "readdirp": "~3.6.0"
- },
- "engines": {
- "node": ">= 8.10.0"
- },
- "funding": {
- "url": "https://paulmillr.com/funding/"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.2"
- }
- },
- "node_modules/color-convert": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
- "dev": true,
- "dependencies": {
- "color-name": "1.1.3"
- }
- },
- "node_modules/color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
- "dev": true
- },
- "node_modules/colord": {
- "version": "2.9.3",
- "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz",
- "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==",
- "dev": true
- },
- "node_modules/concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
- "dev": true
- },
- "node_modules/cosmiconfig": {
- "version": "8.3.6",
- "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz",
- "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==",
- "dev": true,
- "dependencies": {
- "import-fresh": "^3.3.0",
- "js-yaml": "^4.1.0",
- "parse-json": "^5.2.0",
- "path-type": "^4.0.0"
- },
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/sponsors/d-fischer"
- },
- "peerDependencies": {
- "typescript": ">=4.9.5"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/css-functions-list": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.1.tgz",
- "integrity": "sha512-Nj5YcaGgBtuUmn1D7oHqPW0c9iui7xsTsj5lIX8ZgevdfhmjFfKB3r8moHJtNJnctnYXJyYX5I1pp90HM4TPgQ==",
- "dev": true,
- "engines": {
- "node": ">=12 || >=16"
- }
- },
- "node_modules/css-property-sort-order-smacss": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/css-property-sort-order-smacss/-/css-property-sort-order-smacss-2.2.0.tgz",
- "integrity": "sha512-nXutswsivIEBOrPo/OZw2KQjFPLvtg68aovJf6Kqrm3L6FmTvvFPaeDrk83hh0+pRJGuP3PeKJwMS0E6DFipdQ==",
- "dev": true
- },
- "node_modules/css-tree": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz",
- "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==",
- "dev": true,
- "dependencies": {
- "mdn-data": "2.0.30",
- "source-map-js": "^1.0.1"
- },
- "engines": {
- "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
- }
- },
- "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==",
- "dev": true,
- "bin": {
- "cssesc": "bin/cssesc"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/debug": {
- "version": "4.3.4",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
- "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
- "dev": true,
- "dependencies": {
- "ms": "2.1.2"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/decamelize": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-5.0.1.tgz",
- "integrity": "sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/decamelize-keys": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz",
- "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==",
- "dev": true,
- "dependencies": {
- "decamelize": "^1.1.0",
- "map-obj": "^1.0.0"
- },
- "engines": {
- "node": ">=0.10.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/decamelize-keys/node_modules/decamelize": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
- "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/decamelize-keys/node_modules/map-obj": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
- "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/dir-glob": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
- "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
- "dev": true,
- "dependencies": {
- "path-type": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "dev": true
- },
- "node_modules/error-ex": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
- "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
- "dev": true,
- "dependencies": {
- "is-arrayish": "^0.2.1"
- }
- },
- "node_modules/escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
- "dev": true,
- "engines": {
- "node": ">=0.8.0"
- }
- },
- "node_modules/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.3.2",
- "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
- "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
- "dev": true,
- "dependencies": {
- "@nodelib/fs.stat": "^2.0.2",
- "@nodelib/fs.walk": "^1.2.3",
- "glob-parent": "^5.1.2",
- "merge2": "^1.3.0",
- "micromatch": "^4.0.4"
- },
- "engines": {
- "node": ">=8.6.0"
- }
- },
- "node_modules/fastest-levenshtein": {
- "version": "1.0.16",
- "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
- "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==",
- "dev": true,
- "engines": {
- "node": ">= 4.9.1"
- }
- },
- "node_modules/fastq": {
- "version": "1.15.0",
- "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
- "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==",
- "dev": true,
- "dependencies": {
- "reusify": "^1.0.4"
- }
- },
- "node_modules/file-entry-cache": {
- "version": "7.0.2",
- "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-7.0.2.tgz",
- "integrity": "sha512-TfW7/1iI4Cy7Y8L6iqNdZQVvdXn0f8B4QcIXmkIbtTIe/Okm/nSlHb4IwGzRVOd3WfSieCgvf5cMzEfySAIl0g==",
- "dev": true,
- "dependencies": {
- "flat-cache": "^3.2.0"
- },
- "engines": {
- "node": ">=12.0.0"
- }
- },
- "node_modules/fill-range": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
- "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
- "dependencies": {
- "to-regex-range": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/find-up": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
- "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
- "dev": true,
- "dependencies": {
- "locate-path": "^6.0.0",
- "path-exists": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/flat-cache": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz",
- "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==",
- "dev": true,
- "dependencies": {
- "flatted": "^3.2.9",
- "keyv": "^4.5.3",
- "rimraf": "^3.0.2"
- },
- "engines": {
- "node": "^10.12.0 || >=12.0.0"
- }
- },
- "node_modules/flatted": {
- "version": "3.2.9",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz",
- "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==",
- "dev": true
- },
- "node_modules/fs.realpath": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
- "dev": true
- },
- "node_modules/fsevents": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
- "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
- "hasInstallScript": true,
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
- }
- },
- "node_modules/function-bind": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
- "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
- "dev": true,
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/glob": {
- "version": "7.2.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
- "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
- "dev": true,
- "dependencies": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.1.1",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- },
- "engines": {
- "node": "*"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/glob-parent": {
- "version": "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/global-modules": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz",
- "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==",
- "dev": true,
- "dependencies": {
- "global-prefix": "^3.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/global-prefix": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz",
- "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==",
- "dev": true,
- "dependencies": {
- "ini": "^1.3.5",
- "kind-of": "^6.0.2",
- "which": "^1.3.1"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/globby": {
- "version": "11.1.0",
- "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
- "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
- "dev": true,
- "dependencies": {
- "array-union": "^2.1.0",
- "dir-glob": "^3.0.1",
- "fast-glob": "^3.2.9",
- "ignore": "^5.2.0",
- "merge2": "^1.4.1",
- "slash": "^3.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/globjoin": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz",
- "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==",
- "dev": true
- },
- "node_modules/hard-rejection": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz",
- "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/hasown": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz",
- "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==",
- "dev": true,
- "dependencies": {
- "function-bind": "^1.1.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
- "node_modules/hosted-git-info": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
- "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==",
- "dev": true,
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/html-tags": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz",
- "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/ignore": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz",
- "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==",
- "dev": true,
- "engines": {
- "node": ">= 4"
- }
- },
- "node_modules/immutable": {
- "version": "4.3.5",
- "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.5.tgz",
- "integrity": "sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw=="
- },
- "node_modules/import-fresh": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
- "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
- "dev": true,
- "dependencies": {
- "parent-module": "^1.0.0",
- "resolve-from": "^4.0.0"
- },
- "engines": {
- "node": ">=6"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/import-fresh/node_modules/resolve-from": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
- "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/import-lazy": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz",
- "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/imurmurhash": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
- "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
- "dev": true,
- "engines": {
- "node": ">=0.8.19"
- }
- },
- "node_modules/indent-string": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz",
- "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==",
- "dev": true,
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/inflight": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
- "dev": true,
- "dependencies": {
- "once": "^1.3.0",
- "wrappy": "1"
- }
- },
- "node_modules/inherits": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
- "dev": true
- },
- "node_modules/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/is-arrayish": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
- "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
- "dev": true
- },
- "node_modules/is-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-core-module": {
- "version": "2.13.1",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz",
- "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==",
- "dev": true,
- "dependencies": {
- "hasown": "^2.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/is-glob": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
- "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "dependencies": {
- "is-extglob": "^2.1.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "engines": {
- "node": ">=0.12.0"
- }
- },
- "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": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-plain-object": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
- "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/isexe": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
- "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
- "dev": true
- },
- "node_modules/js-tokens": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
- "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
- "dev": true
- },
- "node_modules/js-yaml": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
- "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
- "dev": true,
- "dependencies": {
- "argparse": "^2.0.1"
- },
- "bin": {
- "js-yaml": "bin/js-yaml.js"
- }
- },
- "node_modules/json-buffer": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
- "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
- "dev": true
- },
- "node_modules/json-parse-even-better-errors": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
- "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
- "dev": true
- },
- "node_modules/json-schema-traverse": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
- "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
- "dev": true
- },
- "node_modules/keyv": {
- "version": "4.5.4",
- "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
- "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
- "dev": true,
- "dependencies": {
- "json-buffer": "3.0.1"
- }
- },
- "node_modules/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==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/known-css-properties": {
- "version": "0.29.0",
- "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.29.0.tgz",
- "integrity": "sha512-Ne7wqW7/9Cz54PDt4I3tcV+hAyat8ypyOGzYRJQfdxnnjeWsTxt1cy8pjvvKeI5kfXuyvULyeeAvwvvtAX3ayQ==",
- "dev": true
- },
- "node_modules/lines-and-columns": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
- "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
- "dev": true
- },
- "node_modules/locate-path": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
- "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
- "dev": true,
- "dependencies": {
- "p-locate": "^5.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/lodash.truncate": {
- "version": "4.4.2",
- "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
- "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==",
- "dev": true
- },
- "node_modules/lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "dev": true,
- "dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/map-obj": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz",
- "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/mathml-tag-names": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz",
- "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==",
- "dev": true,
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
- "node_modules/mdn-data": {
- "version": "2.0.30",
- "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
- "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==",
- "dev": true
- },
- "node_modules/meow": {
- "version": "10.1.5",
- "resolved": "https://registry.npmjs.org/meow/-/meow-10.1.5.tgz",
- "integrity": "sha512-/d+PQ4GKmGvM9Bee/DPa8z3mXs/pkvJE2KEThngVNOqtmljC6K7NMPxtc2JeZYTmpWb9k/TmxjeL18ez3h7vCw==",
- "dev": true,
- "dependencies": {
- "@types/minimist": "^1.2.2",
- "camelcase-keys": "^7.0.0",
- "decamelize": "^5.0.0",
- "decamelize-keys": "^1.1.0",
- "hard-rejection": "^2.1.0",
- "minimist-options": "4.1.0",
- "normalize-package-data": "^3.0.2",
- "read-pkg-up": "^8.0.0",
- "redent": "^4.0.0",
- "trim-newlines": "^4.0.2",
- "type-fest": "^1.2.2",
- "yargs-parser": "^20.2.9"
- },
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/merge2": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
- "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
- "dev": true,
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/micromatch": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
- "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
- "dev": true,
- "dependencies": {
- "braces": "^3.0.3",
- "picomatch": "^2.3.1"
- },
- "engines": {
- "node": ">=8.6"
- }
- },
- "node_modules/min-indent": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
- "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/minimist-options": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz",
- "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==",
- "dev": true,
- "dependencies": {
- "arrify": "^1.0.1",
- "is-plain-obj": "^1.1.0",
- "kind-of": "^6.0.3"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "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/nanoid": {
- "version": "3.3.7",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
- "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "bin": {
- "nanoid": "bin/nanoid.cjs"
- },
- "engines": {
- "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
- }
- },
- "node_modules/normalize-package-data": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz",
- "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==",
- "dev": true,
- "dependencies": {
- "hosted-git-info": "^4.0.1",
- "is-core-module": "^2.5.0",
- "semver": "^7.3.4",
- "validate-npm-package-license": "^3.0.1"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "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/once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
- "dev": true,
- "dependencies": {
- "wrappy": "1"
- }
- },
- "node_modules/p-limit": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
- "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
- "dev": true,
- "dependencies": {
- "yocto-queue": "^0.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/p-locate": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
- "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
- "dev": true,
- "dependencies": {
- "p-limit": "^3.0.2"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/parent-module": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
- "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
- "dev": true,
- "dependencies": {
- "callsites": "^3.0.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/parse-json": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
- "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
- "dev": true,
- "dependencies": {
- "@babel/code-frame": "^7.0.0",
- "error-ex": "^1.3.1",
- "json-parse-even-better-errors": "^2.3.0",
- "lines-and-columns": "^1.1.6"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/path-is-absolute": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/path-type": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
- "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/picocolors": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
- "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
- "dev": true
- },
- "node_modules/picomatch": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
- "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
- "engines": {
- "node": ">=8.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/postcss": {
- "version": "8.4.32",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.32.tgz",
- "integrity": "sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/postcss"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "dependencies": {
- "nanoid": "^3.3.7",
- "picocolors": "^1.0.0",
- "source-map-js": "^1.0.2"
- },
- "engines": {
- "node": "^10 || ^12 || >=14"
- }
- },
- "node_modules/postcss-media-query-parser": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz",
- "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==",
- "dev": true
- },
- "node_modules/postcss-resolve-nested-selector": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz",
- "integrity": "sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==",
- "dev": true
- },
- "node_modules/postcss-safe-parser": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz",
- "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==",
- "dev": true,
- "engines": {
- "node": ">=12.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- "peerDependencies": {
- "postcss": "^8.3.3"
- }
- },
- "node_modules/postcss-scss": {
- "version": "4.0.9",
- "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.9.tgz",
- "integrity": "sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/postcss-scss"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "engines": {
- "node": ">=12.0"
- },
- "peerDependencies": {
- "postcss": "^8.4.29"
- }
- },
- "node_modules/postcss-selector-parser": {
- "version": "6.0.13",
- "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz",
- "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==",
- "dev": true,
- "dependencies": {
- "cssesc": "^3.0.0",
- "util-deprecate": "^1.0.2"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/postcss-sorting": {
- "version": "8.0.2",
- "resolved": "https://registry.npmjs.org/postcss-sorting/-/postcss-sorting-8.0.2.tgz",
- "integrity": "sha512-M9dkSrmU00t/jK7rF6BZSZauA5MAaBW4i5EnJXspMwt4iqTh/L9j6fgMnbElEOfyRyfLfVbIHj/R52zHzAPe1Q==",
- "dev": true,
- "peerDependencies": {
- "postcss": "^8.4.20"
- }
- },
- "node_modules/postcss-value-parser": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
- "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
- "dev": true
- },
- "node_modules/punycode": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
- "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/queue-microtask": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
- "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ]
- },
- "node_modules/quick-lru": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
- "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/read-pkg": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-6.0.0.tgz",
- "integrity": "sha512-X1Fu3dPuk/8ZLsMhEj5f4wFAF0DWoK7qhGJvgaijocXxBmSToKfbFtqbxMO7bVjNA1dmE5huAzjXj/ey86iw9Q==",
- "dev": true,
- "dependencies": {
- "@types/normalize-package-data": "^2.4.0",
- "normalize-package-data": "^3.0.2",
- "parse-json": "^5.2.0",
- "type-fest": "^1.0.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/read-pkg-up": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-8.0.0.tgz",
- "integrity": "sha512-snVCqPczksT0HS2EC+SxUndvSzn6LRCwpfSvLrIfR5BKDQQZMaI6jPRC9dYvYFDRAuFEAnkwww8kBBNE/3VvzQ==",
- "dev": true,
- "dependencies": {
- "find-up": "^5.0.0",
- "read-pkg": "^6.0.0",
- "type-fest": "^1.0.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/readdirp": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
- "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
- "dependencies": {
- "picomatch": "^2.2.1"
- },
- "engines": {
- "node": ">=8.10.0"
- }
- },
- "node_modules/redent": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/redent/-/redent-4.0.0.tgz",
- "integrity": "sha512-tYkDkVVtYkSVhuQ4zBgfvciymHaeuel+zFKXShfDnFP5SyVEP7qo70Rf1jTOTCx3vGNAbnEi/xFkcfQVMIBWag==",
- "dev": true,
- "dependencies": {
- "indent-string": "^5.0.0",
- "strip-indent": "^4.0.0"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/require-from-string": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
- "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/resolve-from": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
- "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/reusify": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
- "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
- "dev": true,
- "engines": {
- "iojs": ">=1.0.0",
- "node": ">=0.10.0"
- }
- },
- "node_modules/rimraf": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
- "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "dev": true,
- "dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/run-parallel": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
- "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "dependencies": {
- "queue-microtask": "^1.2.2"
- }
- },
- "node_modules/sass": {
- "version": "1.75.0",
- "resolved": "https://registry.npmjs.org/sass/-/sass-1.75.0.tgz",
- "integrity": "sha512-ShMYi3WkrDWxExyxSZPst4/okE9ts46xZmJDSawJQrnte7M1V9fScVB+uNXOVKRBt0PggHOwoZcn8mYX4trnBw==",
- "dependencies": {
- "chokidar": ">=3.0.0 <4.0.0",
- "immutable": "^4.0.0",
- "source-map-js": ">=0.6.2 <2.0.0"
- },
- "bin": {
- "sass": "sass.js"
- },
- "engines": {
- "node": ">=14.0.0"
- }
- },
- "node_modules/semver": {
- "version": "7.5.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
- "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
- "dev": true,
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
- "bin": {
- "semver": "bin/semver.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/signal-exit": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
- "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
- "dev": true,
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
- "node_modules/slash": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
- "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/slice-ansi": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
- "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.0.0",
- "astral-regex": "^2.0.0",
- "is-fullwidth-code-point": "^3.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/slice-ansi?sponsor=1"
- }
- },
- "node_modules/slice-ansi/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/slice-ansi/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/slice-ansi/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/source-map-js": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
- "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/spdx-correct": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",
- "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==",
- "dev": true,
- "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==",
- "dev": true
- },
- "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==",
- "dev": true,
- "dependencies": {
- "spdx-exceptions": "^2.1.0",
- "spdx-license-ids": "^3.0.0"
- }
- },
- "node_modules/spdx-license-ids": {
- "version": "3.0.16",
- "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz",
- "integrity": "sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==",
- "dev": true
- },
- "node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dev": true,
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dev": true,
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/strip-indent": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.0.0.tgz",
- "integrity": "sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==",
- "dev": true,
- "dependencies": {
- "min-indent": "^1.0.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/style-search": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz",
- "integrity": "sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==",
- "dev": true
- },
- "node_modules/stylelint": {
- "version": "15.11.0",
- "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-15.11.0.tgz",
- "integrity": "sha512-78O4c6IswZ9TzpcIiQJIN49K3qNoXTM8zEJzhaTE/xRTCZswaovSEVIa/uwbOltZrk16X4jAxjaOhzz/hTm1Kw==",
- "dev": true,
- "dependencies": {
- "@csstools/css-parser-algorithms": "^2.3.1",
- "@csstools/css-tokenizer": "^2.2.0",
- "@csstools/media-query-list-parser": "^2.1.4",
- "@csstools/selector-specificity": "^3.0.0",
- "balanced-match": "^2.0.0",
- "colord": "^2.9.3",
- "cosmiconfig": "^8.2.0",
- "css-functions-list": "^3.2.1",
- "css-tree": "^2.3.1",
- "debug": "^4.3.4",
- "fast-glob": "^3.3.1",
- "fastest-levenshtein": "^1.0.16",
- "file-entry-cache": "^7.0.0",
- "global-modules": "^2.0.0",
- "globby": "^11.1.0",
- "globjoin": "^0.1.4",
- "html-tags": "^3.3.1",
- "ignore": "^5.2.4",
- "import-lazy": "^4.0.0",
- "imurmurhash": "^0.1.4",
- "is-plain-object": "^5.0.0",
- "known-css-properties": "^0.29.0",
- "mathml-tag-names": "^2.1.3",
- "meow": "^10.1.5",
- "micromatch": "^4.0.5",
- "normalize-path": "^3.0.0",
- "picocolors": "^1.0.0",
- "postcss": "^8.4.28",
- "postcss-resolve-nested-selector": "^0.1.1",
- "postcss-safe-parser": "^6.0.0",
- "postcss-selector-parser": "^6.0.13",
- "postcss-value-parser": "^4.2.0",
- "resolve-from": "^5.0.0",
- "string-width": "^4.2.3",
- "strip-ansi": "^6.0.1",
- "style-search": "^0.1.0",
- "supports-hyperlinks": "^3.0.0",
- "svg-tags": "^1.0.0",
- "table": "^6.8.1",
- "write-file-atomic": "^5.0.1"
- },
- "bin": {
- "stylelint": "bin/stylelint.mjs"
- },
- "engines": {
- "node": "^14.13.1 || >=16.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/stylelint"
- }
- },
- "node_modules/stylelint-config-property-sort-order-smacss": {
- "version": "9.1.0",
- "resolved": "https://registry.npmjs.org/stylelint-config-property-sort-order-smacss/-/stylelint-config-property-sort-order-smacss-9.1.0.tgz",
- "integrity": "sha512-TijYeDoDgHAFjpn9NnziQrmUCGrm2AM4e1HzsdI2mCWBRkQRuewc343YqDwdFgQ5eHoMZ3JRL02i72W3vktuDA==",
- "dev": true,
- "dependencies": {
- "css-property-sort-order-smacss": "~2.2.0",
- "stylelint-order": "^6.0.2"
- },
- "peerDependencies": {
- "stylelint": "^14.0.0 || ^15.0.0"
- }
- },
- "node_modules/stylelint-config-recommended": {
- "version": "13.0.0",
- "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-13.0.0.tgz",
- "integrity": "sha512-EH+yRj6h3GAe/fRiyaoO2F9l9Tgg50AOFhaszyfov9v6ayXJ1IkSHwTxd7lB48FmOeSGDPLjatjO11fJpmarkQ==",
- "dev": true,
- "engines": {
- "node": "^14.13.1 || >=16.0.0"
- },
- "peerDependencies": {
- "stylelint": "^15.10.0"
- }
- },
- "node_modules/stylelint-config-recommended-scss": {
- "version": "13.1.0",
- "resolved": "https://registry.npmjs.org/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-13.1.0.tgz",
- "integrity": "sha512-8L5nDfd+YH6AOoBGKmhH8pLWF1dpfY816JtGMePcBqqSsLU+Ysawx44fQSlMOJ2xTfI9yTGpup5JU77c17w1Ww==",
- "dev": true,
- "dependencies": {
- "postcss-scss": "^4.0.9",
- "stylelint-config-recommended": "^13.0.0",
- "stylelint-scss": "^5.3.0"
- },
- "peerDependencies": {
- "postcss": "^8.3.3",
- "stylelint": "^15.10.0"
- },
- "peerDependenciesMeta": {
- "postcss": {
- "optional": true
- }
- }
- },
- "node_modules/stylelint-config-sass-guidelines": {
- "version": "10.0.0",
- "resolved": "https://registry.npmjs.org/stylelint-config-sass-guidelines/-/stylelint-config-sass-guidelines-10.0.0.tgz",
- "integrity": "sha512-+Rr2Dd4b72CWA4qoj1Kk+y449nP/WJsrD0nzQAWkmPPIuyVcy2GMIcfNr0Z8JJOLjRvtlkKxa49FCNXMePBikQ==",
- "dev": true,
- "dependencies": {
- "postcss-scss": "^4.0.6",
- "stylelint-scss": "^4.4.0"
- },
- "engines": {
- "node": "^14.13.1 || >=16.13.0 || >=18.0.0"
- },
- "peerDependencies": {
- "postcss": "^8.4.21",
- "stylelint": "^15.2.0"
- }
- },
- "node_modules/stylelint-config-sass-guidelines/node_modules/stylelint-scss": {
- "version": "4.7.0",
- "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-4.7.0.tgz",
- "integrity": "sha512-TSUgIeS0H3jqDZnby1UO1Qv3poi1N8wUYIJY6D1tuUq2MN3lwp/rITVo0wD+1SWTmRm0tNmGO0b7nKInnqF6Hg==",
- "dev": true,
- "dependencies": {
- "postcss-media-query-parser": "^0.2.3",
- "postcss-resolve-nested-selector": "^0.1.1",
- "postcss-selector-parser": "^6.0.11",
- "postcss-value-parser": "^4.2.0"
- },
- "peerDependencies": {
- "stylelint": "^14.5.1 || ^15.0.0"
- }
- },
- "node_modules/stylelint-config-scss": {
- "version": "1.0.0-security",
- "resolved": "https://registry.npmjs.org/stylelint-config-scss/-/stylelint-config-scss-1.0.0-security.tgz",
- "integrity": "sha512-8Pgul2mNpzTeK2KCuyV5RcDC1BgzWzU7dCLVJWuxpkKgmxrMqCvjqgyosaKbAVZy2AiaMU0zfHBt7prg7/NaxA==",
- "dev": true
- },
- "node_modules/stylelint-config-standard": {
- "version": "34.0.0",
- "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-34.0.0.tgz",
- "integrity": "sha512-u0VSZnVyW9VSryBG2LSO+OQTjN7zF9XJaAJRX/4EwkmU0R2jYwmBSN10acqZisDitS0CLiEiGjX7+Hrq8TAhfQ==",
- "dev": true,
- "dependencies": {
- "stylelint-config-recommended": "^13.0.0"
- },
- "engines": {
- "node": "^14.13.1 || >=16.0.0"
- },
- "peerDependencies": {
- "stylelint": "^15.10.0"
- }
- },
- "node_modules/stylelint-config-standard-scss": {
- "version": "11.1.0",
- "resolved": "https://registry.npmjs.org/stylelint-config-standard-scss/-/stylelint-config-standard-scss-11.1.0.tgz",
- "integrity": "sha512-5gnBgeNTgRVdchMwiFQPuBOtj9QefYtfXiddrOMJA2pI22zxt6ddI2s+e5Oh7/6QYl7QLJujGnaUR5YyGq72ow==",
- "dev": true,
- "dependencies": {
- "stylelint-config-recommended-scss": "^13.1.0",
- "stylelint-config-standard": "^34.0.0"
- },
- "peerDependencies": {
- "postcss": "^8.3.3",
- "stylelint": "^15.10.0"
- },
- "peerDependenciesMeta": {
- "postcss": {
- "optional": true
- }
- }
- },
- "node_modules/stylelint-order": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/stylelint-order/-/stylelint-order-6.0.3.tgz",
- "integrity": "sha512-1j1lOb4EU/6w49qZeT2SQVJXm0Ht+Qnq9GMfUa3pMwoyojIWfuA+JUDmoR97Bht1RLn4ei0xtLGy87M7d29B1w==",
- "dev": true,
- "dependencies": {
- "postcss": "^8.4.21",
- "postcss-sorting": "^8.0.2"
- },
- "peerDependencies": {
- "stylelint": "^14.0.0 || ^15.0.0"
- }
- },
- "node_modules/stylelint-scss": {
- "version": "5.3.1",
- "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-5.3.1.tgz",
- "integrity": "sha512-5I9ZDIm77BZrjOccma5WyW2nJEKjXDd4Ca8Kk+oBapSO4pewSlno3n+OyimcyVJJujQZkBN2D+xuMkIamSc6hA==",
- "dev": true,
- "dependencies": {
- "known-css-properties": "^0.29.0",
- "postcss-media-query-parser": "^0.2.3",
- "postcss-resolve-nested-selector": "^0.1.1",
- "postcss-selector-parser": "^6.0.13",
- "postcss-value-parser": "^4.2.0"
- },
- "peerDependencies": {
- "stylelint": "^14.5.1 || ^15.0.0"
- }
- },
- "node_modules/supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
- "dev": true,
- "dependencies": {
- "has-flag": "^3.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/supports-hyperlinks": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz",
- "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0",
- "supports-color": "^7.0.0"
- },
- "engines": {
- "node": ">=14.18"
- }
- },
- "node_modules/supports-hyperlinks/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/supports-hyperlinks/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/svg-tags": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz",
- "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==",
- "dev": true
- },
- "node_modules/table": {
- "version": "6.8.1",
- "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz",
- "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==",
- "dev": true,
- "dependencies": {
- "ajv": "^8.0.1",
- "lodash.truncate": "^4.4.2",
- "slice-ansi": "^4.0.0",
- "string-width": "^4.2.3",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=10.0.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/trim-newlines": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-4.1.1.tgz",
- "integrity": "sha512-jRKj0n0jXWo6kh62nA5TEh3+4igKDXLvzBJcPpiizP7oOolUrYIxmVBG9TOtHYFHoddUk6YvAkGeGoSVTXfQXQ==",
- "dev": true,
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/type-fest": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz",
- "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "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/util-deprecate": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
- "dev": true
- },
- "node_modules/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==",
- "dev": true,
- "dependencies": {
- "spdx-correct": "^3.0.0",
- "spdx-expression-parse": "^3.0.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/wrappy": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
- "dev": true
- },
- "node_modules/write-file-atomic": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz",
- "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==",
- "dev": true,
- "dependencies": {
- "imurmurhash": "^0.1.4",
- "signal-exit": "^4.0.1"
- },
- "engines": {
- "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
- }
- },
- "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/yargs-parser": {
- "version": "20.2.9",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
- "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
- "dev": true,
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/yocto-queue": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
- "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
- "dev": true,
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- }
- }
-}
diff --git a/assets/scss/package.json b/assets/scss/package.json
deleted file mode 100644
index 1055122..0000000
--- a/assets/scss/package.json
+++ /dev/null
@@ -1,29 +0,0 @@
-{
- "name": "mmrecomp-ui-scss",
- "version": "1.0.0",
- "description": "",
- "main": "index.js",
- "scripts": {
- "start": "npm run watch",
- "watch": "sass --no-source-map --no-charset --style=compressed main.scss ..\\recomp.rcss --watch",
- "watch:debug": "sass --no-source-map --no-charset main.scss ..\\recomp.rcss --watch",
- "build": "sass --no-source-map --no-charset --style=compressed main.scss ..\\recomp.rcss",
- "build:debug": "sass --no-source-map --no-charset main.scss ..\\recomp.rcss",
- "lint": "stylelint '.\\**\\*.scss'"
- },
- "author": "",
- "license": "ISC",
- "devDependencies": {
- "postcss-scss": "^4.0.9",
- "stylelint": "^15.11.0",
- "stylelint-config-property-sort-order-smacss": "^9.1.0",
- "stylelint-config-sass-guidelines": "^10.0.0",
- "stylelint-config-scss": "^1.0.0-security",
- "stylelint-config-standard": "^34.0.0",
- "stylelint-config-standard-scss": "^11.1.0",
- "stylelint-scss": "^5.3.1"
- },
- "dependencies": {
- "sass": "^1.75.0"
- }
-}
diff --git a/assets/scss/styles/base.scss b/assets/scss/styles/base.scss
deleted file mode 100644
index 88e158e..0000000
--- a/assets/scss/styles/base.scss
+++ /dev/null
@@ -1,11 +0,0 @@
-@use 'sass:math';
-@import "./functions/spacing";
-@import "./vars/spacing";
-@import "./vars/colors";
-@import "./vars/borders";
-@import "./vars/gradients";
-@import "./vars/transitions";
-@import "./vars/animations";
-@import "./mixins/typography";
-@import "./mixins/transitions";
-@import "./mixins/helpers";
diff --git a/assets/scss/styles/components/BottomLeft.scss b/assets/scss/styles/components/BottomLeft.scss
deleted file mode 100644
index 28821c8..0000000
--- a/assets/scss/styles/components/BottomLeft.scss
+++ /dev/null
@@ -1,14 +0,0 @@
-@use 'sass:math';
-
-.bottom-left {
- display: flex;
- position: absolute;
- bottom: space(4);
- flex-direction: row;
- align-items: flex-start;
- justify-content: flex-start;
- width: 100%;
- max-width: space($base-modal-max-width);
- height: auto;
- margin: 0 space(4);
-}
diff --git a/assets/scss/styles/components/Button.scss b/assets/scss/styles/components/Button.scss
deleted file mode 100644
index d5d1514..0000000
--- a/assets/scss/styles/components/Button.scss
+++ /dev/null
@@ -1,81 +0,0 @@
-@use 'sass:color';
-
-@mixin create-button-variation($base-col) {
- border-color: rgba($base-col, 0.8);
- background-color: rgba($base-col, 0.05);
- color: $color-text-dim;
-
- &:focus, &:hover {
- border-color: $base-col;
- background-color: rgba($base-col, 0.3);
- color: $color-text;
- }
-
- &:disabled,&[disabled] {
- color: $color-text-inactive;
- }
-
- &:active {
- background-color: rgba($base-col, 0.2);
- color: color.scale($color-text, $lightness: 20%);
- }
-}
-
-.button {
- @extend %label-md;
- @extend %nav-all;
- @include create-button-variation($color-primary);
- @include trans-colors;
-
- display: block;
- width: auto;
- height: auto;
- // leave 1dp room for border expansion
- padding: space(24 - 1);
- border-width: $border-width-thickness;
-
- border-radius: $border-radius-md;
-
- // Setting it by default for convenience
- &--primary {
- @include create-button-variation($color-primary);
- }
-
- &--large {
- @extend %label-lg;
- }
-
- &--secondary {
- @include create-button-variation($color-secondary);
- }
-
- &--tertiary {
- @include create-button-variation($color-text);
- }
-
- &--success {
- @include create-button-variation($color-success);
- }
-
- &--error {
- @include create-button-variation($color-error);
- }
-
- &--warning {
- @include create-button-variation($color-warning);
- }
-
- &:not([disabled]) {
- @extend %nav-all;
- cursor: pointer;
- }
-
- &:disabled,&[disabled] {
- opacity: 0.5;
- }
-
- &__label {
- width: auto;
- height: auto;
- }
-}
diff --git a/assets/scss/styles/components/CenteredPage.scss b/assets/scss/styles/components/CenteredPage.scss
deleted file mode 100644
index a724472..0000000
--- a/assets/scss/styles/components/CenteredPage.scss
+++ /dev/null
@@ -1,73 +0,0 @@
-@use 'sass:math';
-
-.centered-page {
- display: flex;
- // visibility: hidden;
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- padding: space($page-margin);
- background-color: $color-border-soft;
-}
-
-.centered-page__modal {
- display: flex;
- position: relative;
- flex: 1 1 100%;
- flex-direction: column;
- width: 100%;
- max-width: space($base-modal-max-width);
- height: 100%;
- margin: auto;
- border-width: $border-width-thickness;
- border-radius: $border-radius-modal;
- border-color: $color-border;
- background: $color-modal-overlay;
-
- > .tabs {
- display: flex;
- position: relative;
- flex: 1 1 100%;
- flex-direction: column;
- width: 100%;
- max-width: space($base-modal-max-width);
- height: 100%;
- margin: auto;
- }
-
- panels {
- flex: 1 1 100%;
- }
-}
-
-.centered-page__controls {
- display: flex;
- position: absolute;
- bottom: space(24);
- flex-direction: row;
- align-items: center;
- justify-content: center;
- width: 100%;
- max-width: space($base-modal-max-width);
- height: auto;
- margin: 0 auto;
-
- > label {
- @extend %label-sm;
- display: inline-block;
- align-items: center;
- justify-content: space-between;
- width: auto;
- height: space(24);
-
- &:not(:last-child) {
- margin-right: space(40);
- }
-
- > span:first-child {
- margin-right: space(4);
- }
- }
-}
diff --git a/assets/scss/styles/components/Config.scss b/assets/scss/styles/components/Config.scss
deleted file mode 100644
index 54c6e1d..0000000
--- a/assets/scss/styles/components/Config.scss
+++ /dev/null
@@ -1,101 +0,0 @@
-
-.config__icon-buttons {
- display: flex;
- position: absolute;
- top: space(8);
- right: space(0);
- flex-direction: row;
- align-items: center;
- justify-content: flex-end;
- width: auto;
-
- .icon-button {
- margin: 0 space(8);
- }
-}
-
-.config__form {
- @include border-top($color-border-soft);
- display: flex;
- flex: 1 1 100%;
- flex-direction: column;
- justify-content: space-between;
- width: 100%;
- height: 100%;
- border-bottom-right-radius: $border-radius-modal;
- border-bottom-left-radius: $border-radius-modal;
-}
-
-.config__wrapper {
- flex: 1 1 100%;
- width: auto;
- height: auto;
- padding: space(16);
- border-radius: 0dp;
- border-bottom-right-radius: $border-radius-modal;
- border-bottom-left-radius: $border-radius-modal;
- background-color: $color-bg-shadow;
- text-align: left;
-
- p {
- @extend %body;
- padding: space(16);
- line-height: space(28);
- white-space: pre-line;
-
- b {
- color: $color-primary;
- }
-
- i {
- color: $color-warning;
- font-style: normal;
- }
- }
-}
-
-.config__hz-wrapper {
- display: flex;
- flex: 1 1 100%;
- flex-direction: row;
- width: 100%;
- height: 100%;
- border-radius: 0dp;
- text-align: left;
-}
-
-.config__header, .config__footer {
- display: flex;
- align-items: center;
- justify-content: space-between;
- width: 100%;
- background-color: $color-bg-shadow;
-}
-
-.config__header {
- @include border-bottom($color-border-soft);
- padding: space(12) space(20);
-}
-
-.config__footer {
- @include border-top($color-border-soft);
- padding: space(20) space(20);
- border-bottom-right-radius: $border-radius-modal;
- border-bottom-left-radius: $border-radius-modal;
-}
-
-.config__header-left {
- display: flex;
- flex: 1 1 auto;
- flex-direction: row;
-
- > :not(:first-child) {
- margin-left: space(8);
- }
-}
-
-.config__row {
- display: flex;
- flex-direction: row;
-}
-
diff --git a/assets/scss/styles/components/ConfigDescription.scss b/assets/scss/styles/components/ConfigDescription.scss
deleted file mode 100644
index 2f4966f..0000000
--- a/assets/scss/styles/components/ConfigDescription.scss
+++ /dev/null
@@ -1,27 +0,0 @@
-.config-description {
- flex: 1 1 100%;
- width: auto;
- height: auto;
- padding: space(16);
- border-radius: 0dp;
- border-bottom-right-radius: $border-radius-modal;
- border-bottom-left-radius: $border-radius-modal;
- background-color: $color-bg-shadow;
- text-align: left;
-
- &__contents {
- @extend %body;
- padding: space(16);
- line-height: space(28);
- white-space: pre-line;
-
- b {
- color: $color-primary;
- }
-
- i {
- color: $color-warning;
- font-style: normal;
- }
- }
-}
diff --git a/assets/scss/styles/components/ConfigGroup.scss b/assets/scss/styles/components/ConfigGroup.scss
deleted file mode 100644
index 9f6444b..0000000
--- a/assets/scss/styles/components/ConfigGroup.scss
+++ /dev/null
@@ -1,29 +0,0 @@
-
-.config-group {
- position: relative;
-
- &--scrollable {
- flex: 1 1 100%;
- width: auto;
- height: auto;
- padding: 0 0 0 space(16);
-
- .config-group__wrapper {
- max-height: 100%;
- overflow-y: auto;
- }
- }
-
- &__title {
- @extend %label-md;
- color: $color-primary;
-
- &--hidden {
- display: none;
- }
- }
-
- &__wrapper {
- padding: space(16) 0;
- }
-}
diff --git a/assets/scss/styles/components/ConfigOption.scss b/assets/scss/styles/components/ConfigOption.scss
deleted file mode 100644
index 26acd85..0000000
--- a/assets/scss/styles/components/ConfigOption.scss
+++ /dev/null
@@ -1,413 +0,0 @@
-.config-option {
- display: flex;
- flex: 1;
- flex-direction: column;
- align-items: flex-start;
- justify-content: flex-start;
- margin: space(16) space(0) space(24);
-
- &--hz {
- flex-direction: row-reverse;
- align-items: center;
- margin-top: space(4);
- margin-bottom: space(4);
-
- .config-option__title {
- @extend %label-md;
- flex: 1 1 100%;
- }
-
- .config-option__list {
- flex: 1 1 auto;
- width: auto;
- }
-
- &:first-child {
- margin-top: 0;
- }
-
- &:last-child {
- margin-bottom: 0;
- }
- }
-}
-
-.config-option__title {
- @extend %label-md;
- padding: 0 space(12);
-}
-
-.config-option__radio-tabs,
-.config-option__list {
- display: flex;
- flex-direction: row;
- align-items: flex-start;
- justify-content: flex-start;
- width: 100%;
- height: auto;
- padding: 0;
-
- input:first-of-type {
- nav-left: none;
- }
-
- input:last-of-type {
- nav-right: none;
- }
-
- .config-option__tab-label {
- @extend %label-sm;
- @include trans-colors-opa;
- display: block;
- position: relative;
- height: auto;
- margin: space(4) space(12) 0;
- padding: space(8) 0;
- color: $color-text-inactive;
- tab-index: none;
-
- &:hover {
- color: $color-text;
- cursor: pointer;
- }
- }
-
- .config-option__checkbox-wrapper {
- @include trans-colors-opa;
- width: space(32);
- height: space(32);
- margin: space(4) space(12) 0;
- border-radius: $border-radius-sm;
- opacity: 0.5;
- background-color: $color-bg-overlay;
- cursor: pointer;
-
- &:hover {
- opacity: 1;
- }
-
- &[checked] {
- background-color: $color-a;
- }
- }
-
- .config-option__checkbox {
- @extend %nav-all;
- @include trans-colors-opa;
- visibility: visible;
- width: 0;
- height: 0;
- }
-
- // TODO: Remove & Replace old stylings
- input.radio {
- @extend %nav-all;
- @include trans-colors-opa;
- visibility: visible;
- width: 0;
- height: 0;
-
- &:not(:disabled) {
- &:checked + .config-option__tab-label {
- border-bottom: 1dp;
- border-color: $color-text;
- color: $color-text;
-
- &:hover {
- cursor: default;
- }
- }
-
- .rmlui-window:not([mouse-active]) &:focus + .config-option__tab-label {
- transition: none;
- animation: $focus-anim-border;
- border-color: $color-secondary;
- color: $color-secondary;
- }
-
- &:focus + .config-option__tab-label,
- &:hover + .config-option__tab-label {
- color: $color-text;
- }
- }
-
- &:disabled + .config-option__tab-label {
- opacity: 0.5;
-
- &:hover {
- cursor: default;
- }
- }
- }
-
- input.range slidertrack {
- @include trans-colors;
- height: 2dp;
- margin-top: space(8);
- background-color: $color-border;
- }
-
- input.range sliderbar {
- @include trans-colors;
- width: space(16);
- height: space(16);
- margin-top: space(1);
- margin-right: space(-8);
- margin-left: space(-8);
- transition: background-color $transition-quick;
- border-radius: 8dp;
- background-color: $color-text-dim;
-
- .rmlui-window:not([mouse-active]) &:focus {
- @include border($color-a);
- animation: $focus-anim-bg;
- }
-
- &:hover {
- background-color: $color-text;
- cursor: pointer;
- }
- }
-
- input.range sliderbar:active,
- input.range slidertrack:active + sliderbar {
- background-color: $color-secondary;
- }
-
- input.range sliderarrowdec,
- input.range sliderarrowinc {
- display: none;
- }
-}
-
-.config-option__details {
- @extend %label-xs;
- height: space(18);
- margin: space(14) space(12) 0;
- color: $color-primary;
-}
-
-.config-option-color {
- width: 100%;
- max-width: space(360);
- height: auto;
- margin-top: space(4);
- margin-left: space(12);
- padding: 0;
-
- &__preview-wrapper {
- display: flex;
- flex-direction: row;
- width: 100%;
- height: space(8 * 9);
- }
-
- &__preview-block {
- display: block;
- width: space(8 * 11);
- height: 100%;
- border-width: $border-width-thickness;
- border-radius: $border-radius-lg;
- border-color: $color-border;
- }
-
- &__hsv-wrapper {
- display: flex;
- flex: 1 1 100%;
- flex-direction: column;
- width: auto;
- height: auto;
- padding-left: space(8);
-
- .config-option-range {
- flex: 1 1 auto;
-
- label {
- min-width: space(72);
- }
-
- input {
- flex: 1 1 auto;
- }
- }
- }
-}
-
-.config-option-range {
- display: flex;
- flex-direction: row;
- align-items: flex-start;
- justify-content: flex-start;
- width: 100%;
- max-width: space(360);
- height: auto;
- margin-top: space(4);
- padding: 0;
-
- &__label {
- @extend %label-sm;
-
- display: block;
- width: space(56);
- margin: 0 12dp;
- margin-right: space(16);
- padding: 0;
- color: $color-text;
- tab-index: none;
- }
-
- &__range-input {
- flex: 1;
-
- slidertrack {
- @include trans-colors;
- height: 2dp;
- margin-top: space(8);
- background-color: $color-border;
- }
-
- sliderbar {
- @include trans-colors;
- width: space(16);
- height: space(16);
- margin-top: space(1);
- margin-right: space(-8);
- margin-left: space(-8);
- transition: background-color $transition-quick;
- border-radius: 8dp;
- background-color: $color-text-dim;
-
- .rmlui-window:not([mouse-active]) &:focus {
- @include border($color-a);
- animation: $focus-anim-bg;
- }
-
- &:hover {
- background-color: $color-text;
- cursor: pointer;
- }
- }
-
- sliderbar:active,
- slidertrack:active + sliderbar {
- background-color: $color-secondary;
- }
-
- sliderarrowdec,
- sliderarrowinc {
- display: none;
- }
- }
-
-}
-
-.config-option__range-wrapper {
- max-width: space(360);
- margin-top: space(4);
-}
-
-.config-option__range-label {
- @extend %label-sm;
-
- display: block;
- // flex: 0 0 space(32);
- width: space(56);
- margin: 0 12dp;
- margin-right: space(16);
- padding: 0;
- color: $color-text;
- tab-index: none;
-}
-
-.config-option-dropdown, .config-option-textfield {
- display: flex;
- position: relative;
- flex: 1 1 100%;
- flex-direction: row;
- align-items: center;
- justify-content: flex-start;
- width: auto;
- height: auto;
- padding: space(8) space(24) space(8) space(12);
-
- &__select {
- display: block;
- height: space(48);
- padding: space(14);
- cursor: pointer;
- }
-
- &__wrapper {
- // Cursed guess & check so that this appears to be the same height as the select
- $extra-space: 2;
-
- display: flex;
- align-items: center;
- justify-content: flex-start;
- width: 100%;
- height: auto;
- padding: space(0 + $extra-space) 0 space(10 + $extra-space);
- cursor: text;
-
- input {
- width: 100%;
- height: auto;
- vertical-align: middle;
- }
- }
-
- &__select, &__wrapper {
- @extend %body;
- @extend %nav-all;
- @include trans-colors-border;
- @include border($color-white-a50);
- position: relative;
- box-sizing: border-box;
- flex: 1 1 100%;
-
- width: auto;
- border-radius: $border-radius-md;
- background-color: $color-white-a5;
-
- &:hover, &:focus {
- @include border($color-white-a80);
- background-color: $color-white-a20;
- }
-
- selectvalue {
- display: inline;
- height: auto;
- margin: auto 0;
- }
-
- selectbox {
- @include border($color-border);
- margin-top: space(2);
- padding: space(4) 0;
- border-radius: $border-radius-md;
- background-color: $color-background-3;
-
- option {
- @extend %nav-all;
- @include trans-colors;
- padding: space(8) space(12);
- background-color: $color-transparent;
- color: $color-text-dim;
- font-weight: 400;
-
- &:hover, &:focus {
- background-color: $color-white-a20;
- }
-
- &:hover:not(:checked) {
- cursor: pointer;
- }
-
- &:checked {
- background-color: $color-white-a5;
- color: $color-white;
- }
- }
- }
- }
-}
diff --git a/assets/scss/styles/components/ControlOption.scss b/assets/scss/styles/components/ControlOption.scss
deleted file mode 100644
index 662fd63..0000000
--- a/assets/scss/styles/components/ControlOption.scss
+++ /dev/null
@@ -1,170 +0,0 @@
-@use 'sass:color';
-@use 'sass:math';
-
-.control-option {
- @include set-color($color-text-dim);
- @include trans-colors-svg;
- display: flex;
- position: relative;
- flex-direction: row;
- align-items: center;
- justify-content: space-between;
- width: 100%;
- height: auto;
- padding: space(4) space(16) space(4) space(20);
- border-radius: $border-radius-sm;
- background-color: rgba(0, 0, 0, 0);
-
- &:focus-visible:not(:disabled, [disabled]),
- &:hover:not(:disabled, [disabled]) {
- @include set-color($color-text);
- background-color: $color-bg-overlay;
- }
-
- &:disabled, &[disabled] {
- opacity: 0.5;
- }
-
- &--active {
- // while actively looking for inputs, set styles to the correct slots
- $valid-binding-slots: 0, 1;
- @each $slot in $valid-binding-slots {
- // global attr -> this active row -> binding slot
- [cur-binding-slot="#{$slot}"] & .control-option__binding[bind-slot="#{$slot}"] {
- border-color: $color-error;
-
- .control-option__binding-icon {
- opacity: 0;
- }
-
- .control-option__binding-recording {
- opacity: 1;
- }
- }
- }
- }
-
- .icon-button {
- flex: 1 1 auto;
- }
-}
-
-.control-option__label {
- @extend %label-md;
- flex: 2 1 space(300);
- height: auto;
- white-space: nowrap;
-}
-
-.control-option__bindings {
- display: flex;
- position: relative;
- flex: 2 1 space(400);
- flex-direction: row;
- align-items: center;
- justify-content: space-between;
- width: 100%;
- height: space(56);
- padding: 0 space(12) 0 space(4);
-}
-
-.control-option__binding {
- @include set-color($color-text-dim);
- @include trans-colors-border;
- display: flex;
- position: relative;
-
- flex: 1 1 100%;
- align-items: center;
- justify-content: center;
- width: 100%;
- height: space(56);
- margin: 0 space(4);
- padding: space(8);
- border-width: $border-width-thickness;
- border-radius: $border-radius-sm;
- border-color: $color-bg-overlay;
- background-color: $color-bg-overlay;
-
- &:focus, &:hover {
- @include set-color($color-text);
- border-color: $color-text;
- background-color: $color-border-soft;
- }
-
- &:active {
- @include set-color(color.scale($color-text, $lightness: 20%));
- }
-
- &:disabled, &[disabled] {
- @include set-color($color-text-dim);
- opacity: 0.5;
- }
-
- &:not([disabled]) {
- @extend %nav-all;
- cursor: pointer;
- }
-}
-
-.control-option__binding-icon {
- @include trans-colors-opa;
- opacity: 1;
-}
-
-@keyframes control-option__binding-recording-scale {
- 0% {
- transform: scale(1);
- }
-
- 50% {
- transform: scale(0.85);
- }
-
- 100% {
- transform: scale(1);
- }
-}
-
-.control-option__binding-recording {
- @include trans-colors-opa;
- display: flex;
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- align-items: center;
- justify-content: center;
- opacity: 0;
-
- .control-option__binding-circle {
- $rec-size: 24;
-
- width: space($rec-size);
- height: space($rec-size);
- animation: 1.5s sine-in-out infinite control-option__binding-recording-scale;
- border-radius: space($rec-size);
- background-color: $color-error;
- }
-
- .control-option__binding-edge {
- $edge-size: 36;
- $h-edge-size: math.div($edge-size, 2);
-
- position: absolute;
-
- top: 50%;
- left: 50%;
- width: space($edge-size);
- height: space($edge-size);
-
- transform: translate(-50%, -50%);
-
- > svg.control-option__binding-edge-svg {
- width: space($edge-size);
- height: space($edge-size);
- image-color: $color-error;
- }
- }
-}
diff --git a/assets/scss/styles/components/IconButton.scss b/assets/scss/styles/components/IconButton.scss
deleted file mode 100644
index 4e1822a..0000000
--- a/assets/scss/styles/components/IconButton.scss
+++ /dev/null
@@ -1,92 +0,0 @@
-@use 'sass:color';
-
-/*
-
-*/
-@mixin create-icon-button-variation($base-col) {
- border-color: rgba($base-col, 0.8);
- background-color: rgba($base-col, 0.05);
-
- &:focus, &:hover {
- border-color: $base-col;
- background-color: rgba($base-col, 0.3);
- }
-
- &:active {
- background-color: rgba($base-col, 0.2);
- }
-}
-
-$icon-button-size: 56 - ($border-width-thickness-num * 2);
-
-.icon-button {
- @include set-color($color-text-dim);
- @include trans-colors-border;
-
- display: flex;
- align-items: center;
- justify-content: center;
- width: space($icon-button-size);
- min-width: space($icon-button-size);
- max-width: space($icon-button-size);
- height: space($icon-button-size);
- min-height: space($icon-button-size);
- max-height: space($icon-button-size);
- border-width: $border-width-thickness;
- border-radius: space($icon-button-size * 0.5);
- border-color: $color-transparent;
- background-color: $color-transparent;
-
- &:focus, &:hover {
- @include set-color($color-text);
- background-color: $color-border;
- }
-
- &:active {
- @include set-color(color.scale($color-text, $lightness: 20%));
- background-color: $color-border-soft;
- }
-
- &:disabled,&[disabled] {
- @include set-color($color-text-dim);
- opacity: 0.5;
- }
-
- &:not([disabled]) {
- @extend %nav-all;
- cursor: pointer;
- }
-
- svg {
- width: space(32);
- height: space(32);
- }
-
- &--primary {
- @include create-icon-button-variation($color-primary);
- }
-
- &--secondary {
- @include create-icon-button-variation($color-secondary);
- }
-
- &--tertiary {
- @include create-icon-button-variation($color-text);
- }
-
- &--success {
- @include create-icon-button-variation($color-success);
- }
-
- &--error {
- @include create-icon-button-variation($color-error);
- }
-
- &--warning {
- @include create-icon-button-variation($color-warning);
- }
-}
diff --git a/assets/scss/styles/components/InputConfig.scss b/assets/scss/styles/components/InputConfig.scss
deleted file mode 100644
index c01374e..0000000
--- a/assets/scss/styles/components/InputConfig.scss
+++ /dev/null
@@ -1,349 +0,0 @@
-@use 'sass:math';
-
-// Probably will need to adjust for other langs...
-$mapping-min-width: 80 * 8;
-$visual-max-width: $base-modal-max-width - $mapping-min-width - $scrollbar-width;
-
-.input-config {
- padding: 0;
-}
-
-.input-config__horizontal-split {
- display: flex;
- position: relative;
- flex-direction: row;
- height: 100%;
-}
-
-.input-config__mappings {
- display: block;
- flex: 1 1 auto;
- min-width: space($mapping-min-width);
- height: 100%;
-}
-
-.input-config__mappings-scroll {
- display: block;
- width: 100%;
- max-height: 100%;
- overflow-y: auto;
-}
-
-.input-config__mappings-wrapper {
- padding: space(8);
-}
-
-.input-config__visual-wrapper {
- display: block;
- flex: 1 1 100%;
- width: auto;
- max-width: space($visual-max-width);
- height: auto;
- max-height: space(math.div($visual-max-width, 4) * 3);
- margin: auto 0;
-}
-
-.input-config__visual-aspect {
- position: relative;
- width: 100%;
- margin: auto 0;
- padding-bottom: 75%;
- background-color: $color-bg-shadow;
-}
-
-.input-config__visual {
- display: flex;
- position: absolute;
- top: space(16);
- right: space(16);
- bottom: space(16);
- left: space(16);
- flex-direction: column;
- border-radius: space(108);
- background-color: $color-white-a5;
-}
-
-.input-config__visual-half {
- display: flex;
- position: relative;
- flex: 1 1 100%;
- flex-direction: row;
- padding: 6%;
-
- &--bottom {
- align-items: flex-end;
- justify-content: space-between;
- }
-}
-
-.input-config__visual-quarter-left {
- display: flex;
- flex: 1 1 50%;
- align-items: flex-start;
- justify-content: flex-start;
- width: auto;
-}
-
-.input-config__visual-quarter-right {
- display: flex;
- flex: 1 1 100%;
- align-items: flex-start;
- justify-content: flex-end;
-}
-
-.input-config__visual-stick-wrapper {
- display: flex;
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- align-items: center;
- justify-content: center;
-}
-
-.input-viz {
- @include trans-colors-opa;
- display: flex;
- position: relative;
- align-items: center;
- justify-content: center;
-
- > svg:not(.input-viz__dpad-arrow) {
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- }
-
- &__mappings div {
- @extend %prompt-font-sm;
- }
-}
-
-$all-inputs: A,
- B,
- Z,
- START,
- DPAD_UP,
- DPAD_DOWN,
- DPAD_LEFT,
- DPAD_RIGHT,
- L,
- R,
- C_UP,
- C_DOWN,
- C_LEFT,
- C_RIGHT,
- X_AXIS_NEG,
- X_AXIS_POS,
- Y_AXIS_NEG,
- Y_AXIS_POS;
-
-// Show default state while no inputs are active
-[cur-input="NONE"] .input-viz[visual-input] {
- opacity: 1;
-}
-
-@each $inp in $all-inputs {
- .input-viz[visual-input~="#{$inp}"] {
- opacity: 0.25;
-
- [cur-input="#{$inp}"] & {
- opacity: 1.0;
- }
- }
-}
-
-@mixin set-sizes($sz) {
- width: space($sz);
- height: space($sz);
-
- > svg {
- width: space($sz);
- height: space($sz);
- }
-}
-
-.input-viz__button {
- @include set-color($color-text);
-
- &--sm {
- @include set-sizes(64);
- }
-
- &--md {
- @include set-sizes(76);
- }
-
- &--lg {
- @include set-sizes(84);
- }
-
- &--C {
- @include set-svgs-color($color-warning);
- }
-
- &--A {
- @include set-svgs-color($color-a);
- margin-top: auto;
- }
-
- &--B {
- @include set-svgs-color($color-success);
- }
-
- &--Start {
- @include set-svgs-color($color-error);
- }
-}
-
-.input-viz__Z {
- @include set-svgs-color($color-warning);
- @include set-sizes(136);
-}
-
-$dpad-size: 192;
-
-.input-viz.input-viz__dpad {
- @include set-svgs-color($color-text);
- @include set-sizes($dpad-size);
- position: relative;
-}
-
-$stick-size: 200;
-
-.input-config__visual-stick {
- display: flex;
- position: relative;
- align-items: center;
- justify-content: center;
- width: space($stick-size);
- height: space($stick-size);
- border-radius: space(math.div($stick-size, 2));
- background-color: $color-white-a5;
-}
-
-.input-viz__dpad-split,
-.input-viz__stick-split {
- @include inset-block(0);
- display: flex;
- width: 100%;
- height: 100%;
-
- &--vertical {
- flex-direction: column;
- align-items: center;
- justify-content: space-between;
- }
-
- &--horizontal {
- flex-direction: row;
- align-items: center;
- justify-content: space-between;
- }
-
- > div {
- display: flex;
- flex: 1 1 100%;
- flex-direction: row;
- align-items: center;
- justify-content: center;
- }
-}
-
-.input-viz__dpad-split > div {
- width: space(math.div($dpad-size, 3));
- height: space(math.div($dpad-size, 3));
-}
-
-.input-viz__stick-split > div {
- width: space(math.div($stick-size, 3));
- height: space(math.div($stick-size, 3));
-}
-
-.input-viz__dpad-arrow {
- $edge-dist: space(4);
- position: absolute;
- width: space(60);
- height: space(60);
-
- &--up {
- top: $edge-dist;
- margin: 0 auto;
- }
-
- &--down {
- bottom: $edge-dist;
- margin: 0 auto;
- transform: rotate(180deg);
- }
-
- &--left {
- left: $edge-dist;
- margin: auto 0;
- transform: rotate(-90deg);
- }
-
- &--right {
- right: $edge-dist;
- margin: auto 0;
- transform: rotate(90deg);
- }
-}
-
-.input-viz__R {
- @include set-svgs-color($color-white);
- @include set-sizes(96);
-}
-
-.input-viz__L {
- @include set-svgs-color($color-secondary);
- @include set-sizes(136);
-}
-
-.input-config__c-buttons {
- position: relative;
- width: space(76 + 76 + 56);
- height: space(76 + 56);
-
- &-lr, &-du {
- display: flex;
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- }
-
- &-lr {
- flex-direction: row;
- align-items: flex-start;
- justify-content: space-between;
- }
-
- &-du {
- flex-direction: column-reverse;
- align-items: center;
- justify-content: space-between;
- }
-
- .input-viz {
- &[visual-input="C_UP"] {
- margin-top: space(-32);
- }
- }
-}
-
-.input-config__main-buttons {
- display: flex;
- position: relative;
- flex-direction: row;
- justify-content: space-between;
- width: space(268);
- // WORKAROUND FIX: prevents RMLui assert error
- min-width: 1dp;
- height: space(128);
- margin-right: space(10);
-}
diff --git a/assets/scss/styles/components/Launcher.scss b/assets/scss/styles/components/Launcher.scss
deleted file mode 100644
index 89e4fce..0000000
--- a/assets/scss/styles/components/Launcher.scss
+++ /dev/null
@@ -1,108 +0,0 @@
-
-// TODO: Affect all elements with launcher fade-in
-// @keyframes fade-launcher-in {
-// 0% {
-// opacity: 0;
-// }
-// to {
-// opacity: 1;
-// }
-// }
-
-.launcher {
- display: block;
- position: relative;
- flex-direction: row;
- justify-content: space-between;
- width: 100%;
- height: 100%;
- background-color: $color-background-1;
-}
-
-.launcher__vertical-split {
- display: flex;
- position: absolute;
- top: 0;
- right: 50%;
- bottom: 0;
- left: 0;
- flex-direction: column;
- align-items: flex-start;
- justify-content: space-between;
-
- &--right {
- right: 0;
- left: 50%;
- align-items: flex-end;
- }
-}
-
-
-@keyframes slide-mm-bg-over {
- 0% {
- transform: translateX(space(100));
- }
-
- 100% {
- transform: translateX(space(0));
- }
-}
-
-.launcher__background-wrapper {
- display: flex;
- position: absolute;
- top: -55vw;
- right: -100%;
- bottom: -50vw;
- left: -70vw;
- align-items: center;
- justify-content: flex-start;
- transform: translateX(space(0));
- animation: 25s cubic-out 1 slide-mm-bg-over;
-}
-
-@keyframes fade-mm-in {
- 0% {
- opacity: 0;
- }
-
- 100% {
- opacity: 0.1;
- }
-}
-
-.launcher__background-mm {
- position: absolute;
- top: 0;
- bottom: 0;
- left: 0;
- width: auto;
- height: 100%;
- animation: 2.5s cubic-in-out 1 fade-mm-in;
- opacity: 0.1;
-}
-
-.launcher__title-quadrant {
- flex: 1 1 auto;
- width: auto;
- height: auto;
- padding-top: space(96);
- padding-left: space(96);
-
- &--right {
- padding-right: space(96);
- padding-left: 0;
- }
-}
-
-.launcher__content-quadrant {
- display: flex;
- position: relative;
- flex: 1 1 100%;
- flex-direction: column;
- align-items: flex-start;
- justify-content: flex-end;
- width: 100%;
- height: auto;
- padding: space(32);
-}
diff --git a/assets/scss/styles/components/MenuListItem.scss b/assets/scss/styles/components/MenuListItem.scss
deleted file mode 100644
index 657f0ef..0000000
--- a/assets/scss/styles/components/MenuListItem.scss
+++ /dev/null
@@ -1,71 +0,0 @@
-
-/*
- Example layout:
-
- - Variants:
- .menu-list-item--right (align to right side)
- - Optional:
- -
Coming Soon™
-
-*/
-
-.menu-list-item {
- @include set-color($color-text-dim);
- display: flex;
- flex-direction: row;
- align-items: center;
- width: 100%;
- height: auto;
- padding: space(16);
- border-radius: $border-radius-sm;
- background-color: rgba(0, 0, 0, 0);
- cursor: pointer;
-
- &--right {
- flex-direction: row-reverse;
- align-content: flex-end;
-
- .menu-list-item__bullet {
- margin-left: space(12);
- opacity: 1;
- }
-
- &.menu-list-item:focus:not(:disabled, [disabled]),
- &.menu-list-item:hover:not(:disabled, [disabled]) {
- decorator: $primary-rl-fade;
- }
- }
-
- &:focus:not(:disabled, [disabled]),
- &:hover:not(:disabled, [disabled]) {
- @include set-color($color-primary);
- decorator: $primary-lr-fade;
-
- .menu-list-item__bullet {
- opacity: 1;
- }
- }
-
- &:not(:disabled, [disabled]) {
- @extend %nav-all;
- }
-
- &:disabled, &[disabled] {
- opacity: 0.5;
- tab-index: none;
- cursor: default;
- }
-
-}
-
-.menu-list-item__label {
- @extend %label-lg;
-}
-
-.menu-list-item__bullet {
- margin-right: space(12);
- opacity: 0;
-}
diff --git a/assets/scss/styles/components/Prompt.scss b/assets/scss/styles/components/Prompt.scss
deleted file mode 100644
index d7b4a1d..0000000
--- a/assets/scss/styles/components/Prompt.scss
+++ /dev/null
@@ -1,70 +0,0 @@
-@use 'sass:math';
-
-$prompt-space: 24;
-
-.prompt {
- &__overlay {
- background-color: $color-bg-overlay;
- pointer-events: auto;
- }
-
- &__overlay,
- &__content-wrapper {
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- }
-
- &__content-wrapper {
- display: flex;
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- align-items: center;
- justify-content: center;
- }
-
- &__content {
- display: flex;
- position: relative;
- flex: 1 1 100%;
- flex-direction: column;
- width: 100%;
- max-width: space(700);
- height: auto;
- margin: auto;
- border-width: $border-width-thickness;
- border-radius: $border-radius-modal;
- border-color: $color-border;
- background: $color-modal-overlay;
-
- h3, p {
- margin: space($prompt-space);
- }
-
- p {
- margin-top: 0;
- }
- }
-
- &__controls {
- display: flex;
- flex-direction: row;
- justify-content: center;
- padding: space($prompt-space) space(math.div($prompt-space, 2));
- border-top-width: $border-width-thickness;
- border-top-color: $color-border-soft;
-
- .button {
- min-width: space(math.div(700, 3));
- margin: 0 space(math.div($prompt-space, 2));
- text-align: center;
- nav-up: none;
- nav-down: none;
- }
- }
-}
diff --git a/assets/scss/styles/components/SubtitleTitle.scss b/assets/scss/styles/components/SubtitleTitle.scss
deleted file mode 100644
index c04def6..0000000
--- a/assets/scss/styles/components/SubtitleTitle.scss
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- Example layout:
-
-
- - Variants:
- .subtitle-title--right (align to right side)
- - Optional:
- - Coming Soon™
-
-*/
-
-.subtitle-title {
- display: block;
- position: relative;
- flex-direction: column;
- align-content: flex-start;
- align-items: flex-start;
- width: auto;
- height: auto;
- padding: 0;
- background-color: rgba(0, 0, 0, 0);
- color: $color-text-dim;
- text-align: left;
- cursor: pointer;
-
- &--right {
- align-content: flex-end;
- }
-
- &--right, &--right > * {
- text-align: right;
- }
-
- &[selected] {
- color: $color-text;
- cursor: default;
- }
-
- &:focus:not(:disabled, [disabled]),
- &:hover:not(:disabled, [disabled], [selected]) {
- color: $color-primary;
- }
-
- &:not(:disabled, [disabled]) {
- @extend %nav-all;
- }
-
- &:disabled, &[disabled] {
- opacity: 0.5;
- cursor: default;
- tab-index: none;
- }
-
- h3 {
- margin-bottom: space(6);
- }
-
- h1 {
- margin-top: space(6);
- }
-
- &__disclaimer {
- @extend %label-sm;
-
- margin-top: space(16);
- }
-}
diff --git a/assets/scss/styles/components/Tabs.scss b/assets/scss/styles/components/Tabs.scss
deleted file mode 100644
index 53f09dc..0000000
--- a/assets/scss/styles/components/Tabs.scss
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- Example:
-
- Graphics
-
-
-*/
-
-.tabs tabs {
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: flex-start;
-}
-
-.tab {
- @extend %nav-all;
- @extend %header-3;
- display: block;
- position: relative;
- margin: 0;
- padding: space(20) space(24);
- opacity: 0.9;
- background-color: rgba(0,0,0,0);
- color: $color-text-inactive;
-
- &:selected {
- color: $color-text;
-
- .tab__indicator {
- background-color: $color-border-solid;
- }
-
- &:hover {
- cursor: default;
- }
- }
-
- .rmlui-window:not([mouse-active]) &:focus {
- transition: none;
- animation: $focus-anim-border;
-
- &:selected .tab__indicator {
- animation: $focus-anim-bg;
- }
- }
-
- &:focus, &:hover {
- opacity: 1;
- color: $color-text;
- cursor: pointer;
- }
-}
-
-.tab__indicator {
- position: absolute;
- right: 0;
- bottom: 2dp;
- left: 0;
- height: 2dp;
- background-color: rgba(0, 0, 0, 0);
-}
diff --git a/assets/scss/styles/components/Toggle.scss b/assets/scss/styles/components/Toggle.scss
deleted file mode 100644
index 065f92d..0000000
--- a/assets/scss/styles/components/Toggle.scss
+++ /dev/null
@@ -1,97 +0,0 @@
-@use "sass:math";
-
-$toggle-width: 162;
-$toggle-height: 72;
-
-$toggle-floater-width: 80;
-$toggle-floater-height: 64;
-$toggle-floater-margin: 4;
-$toggle-checked-left-offset: $toggle-width - $toggle-floater-margin - $toggle-floater-width;
-
-.toggle {
- @extend %nav-all;
- @include trans-colors-opa;
- display: flex;
- position: relative;
- flex-direction: row;
- align-items: center;
- justify-content: space-between;
- width: space($toggle-width);
- height: space($toggle-height);
- border-radius: space(math.div($toggle-height, 2));
- opacity: 0.9;
- background: $color-transparent;
- cursor: pointer;
-
- &:hover, &:focus-visible, &:focus {
- opacity: 1;
- background-color: $color-secondary-a30;
- }
-
- &:active {
- opacity: 1;
- background-color: $color-secondary-a5;
- }
-
- .toggle__border {
- @include inner-border-block($color-secondary-l);
- border-radius: space(math.div($toggle-height, 2));
- }
-
- .toggle__floater {
- position: absolute;
- top: 50%;
- left: space($toggle-floater-margin);
- width: space($toggle-floater-width);
- height: space($toggle-floater-height);
- transform: translateY(-50%);
- border-radius: space(math.div($toggle-floater-height, 2));
- background: $color-secondary-d;
- }
-
- &--checked {
- .toggle__floater {
- left: space($toggle-checked-left-offset);
- }
-
- .toggle__icon {
- &.toggle__icon--left {
- opacity: 0.9;
- color: $color-secondary-l;
- }
-
- &.toggle__icon--right {
- opacity: 1.0;
- color: $color-text;
- }
- }
- }
-}
-
-.toggle__icons {
- display: flex;
- position: absolute;
- top: 50%;
- right: space(16);
- left: space(16);
- align-items: center;
- justify-content: space-between;
- height: space(56);
- transform: translateY(-50%);
-}
-
-.toggle__icon {
- @extend %prompt-font-lg;
- @include trans-colors;
- display: flex;
- align-items: center;
- justify-content: center;
- width: space(56);
- height: space(56);
- color: $color-text;
-
- &--right {
- opacity: 1;
- color: $color-secondary-l;
- }
-}
diff --git a/assets/scss/styles/components/_components.scss b/assets/scss/styles/components/_components.scss
deleted file mode 100644
index b4a936e..0000000
--- a/assets/scss/styles/components/_components.scss
+++ /dev/null
@@ -1,16 +0,0 @@
-@import "./CenteredPage";
-@import "./ControlOption";
-@import "./Tabs";
-@import "./Config";
-@import "./ConfigGroup";
-@import "./ConfigOption";
-@import "./ConfigDescription";
-@import "./InputConfig";
-@import "./Button";
-@import "./IconButton";
-@import "./Launcher";
-@import "./MenuListItem";
-@import "./SubtitleTitle";
-@import "./Toggle";
-@import "./BottomLeft";
-@import "./Prompt";
diff --git a/assets/scss/styles/functions/_spacing.scss b/assets/scss/styles/functions/_spacing.scss
deleted file mode 100644
index 437a7ac..0000000
--- a/assets/scss/styles/functions/_spacing.scss
+++ /dev/null
@@ -1,4 +0,0 @@
-
-@function space($amt) {
- @return #{$amt}dp;
-}
diff --git a/assets/scss/styles/global.scss b/assets/scss/styles/global.scss
deleted file mode 100644
index 2e98925..0000000
--- a/assets/scss/styles/global.scss
+++ /dev/null
@@ -1,132 +0,0 @@
-@import "./base";
-@import "./globals/old";
-@import "./globals/scrollbars";
-@import "./components/components";
-@import "./pages/pages";
-
-$font-size: 20dp;
-
-body
-{
- @extend %body;
- box-sizing: border-box;
- color: $color-text;
- font-family: $font-stack;
-}
-
-.rmlui-window {
- opacity: 1;
-
- &--hidden {
- opacity: 0;
- }
-
- &:not([mouse-active]) {
- pointer-events: none;
- }
-}
-
-.nav-vert {
- @extend %nav-vert;
-}
-
-.nav-horiz {
- @extend %nav-horiz;
-}
-
-.nav-dir {
- @extend %nav-dir;
-}
-
-.nav-foc {
- @extend %nav-foc;
-}
-
-.nav-all {
- @extend %nav-all;
-}
-
-*, *:before, *:after {
- box-sizing: border-box;
-}
-
-h1 {
- @extend %header-1;
-}
-
-h2 {
- @extend %header-2;
-}
-
-h3 {
- @extend %header-3;
-}
-
-.label-lg {
- @extend %label-lg;
-}
-
-.label-md {
- @extend %label-md;
-}
-
-.label-sm {
- @extend %label-sm;
-}
-
-.prompt-font {
- @extend %prompt-font;
-}
-
-.prompt-font-sm {
- @extend %prompt-font-sm;
-}
-
-button {
- background-color: $color-primary-d;
-}
-
-@keyframes blue-pulse {
- 0% {
- color: $color-secondary;
- }
-
- 50% {
- color: $color-secondary-l;
- }
-
- 100% {
- color: $color-secondary;
- }
-}
-
-@keyframes blue-pulse-with-border {
- 0% {
- border-color: $color-secondary;
- color: $color-secondary;
- }
-
- 50% {
- border-color: $color-secondary-l;
- color: $color-secondary-l;
- }
-
- 100% {
- border-color: $color-secondary;
- color: $color-secondary;
- }
-}
-
-@keyframes blue-pulse-background {
- 0% {
- background-color: $color-secondary;
- }
-
- 50% {
- background-color: $color-secondary-l;
- }
-
- 100% {
- background-color: $color-secondary;
- }
-}
diff --git a/assets/scss/styles/globals/_old.scss b/assets/scss/styles/globals/_old.scss
deleted file mode 100644
index 20351d9..0000000
--- a/assets/scss/styles/globals/_old.scss
+++ /dev/null
@@ -1,212 +0,0 @@
-/* stylelint-disable color-no-hex */
-/* stylelint-disable selector-max-id */
-
-* {
- box-sizing:border-box;
-}
-
-hr {
- display:block;
- padding:1.5dp;
- background: $color-background-1;
-}
-
-body {
- color: #fff;
- font-family: chiaro;
- font-size: 20dp;
- font-style: normal;
- font-weight: normal
-}
-
-/* div {
- focus:none;
- tab-index:none;
-} */
-
-div#window {
- position: relative;
- box-sizing: border-box;
- width: 100%;
- height: 100%;
- border-color: $color-border;
- background-color: $color-background-2;
-}
-
-div#content {
- z-index: 2;
- width: auto;
- height: 100%;
- overflow: hidden auto;
- text-align: center
-}
-
-p {
- text-align: left;
-}
-
-input.submit {
- margin-left: 0
-}
-
-
-input.text,
-input.password {
- box-sizing: border-box;
- height: 31dp;
- padding: 11dp 10dp 0;
- text-align: left;
- cursor: text
-}
-
-textarea {
- padding: 14dp 12dp 10dp;
- text-align: left;
- cursor: text
-}
-
-input.text,
-input.password,
-select,
-textarea {
- /* color: #333; */
-
- /* font-size: 13dp */
- height: auto;
-}
-
-table input.text {
- box-sizing: border-box;
- width: 100%;
- height: auto;
-
- /* height: 18dp; */
- margin: 0;
- border-width: $border-width-thickness;
- border-color: #000;
- background-color: #fff;
- font-size: 15dp;
-
- /* padding: 0 5dp; */
- line-height: 1;
- decorator: none;
-
- /* vertical-align: center; */
-}
-
-select {
- // display: inline-block;
- // /* width: 175dp; */
- // /* height: 37dp; */
- // /* height: auto; */
- // text-align: left;
- // box-sizing:border-box;
- // /* padding: 4dp; */
- // vertical-align: center;
- // padding: 4dp;
- // border-radius: 5dp;
- // background-color: rgb(120, 120, 120);
- // width: 100%;
-}
-// select {
-// @extend %body;
-// display: flex;
-// align-items: center;
-// justify-content: flex-start;
-// box-sizing: border-box;
-// padding: space(16);
-// flex: 1 1 100%;
-// // width: auto;
-// height: space(1000);
-// border-radius: $border-radius-lg;
-// background-color: $color-white-a20;
-// }
-
-// select selectvalue {
-// height: auto;
-// /* padding: 4dp; */
-// /* margin-right: 30dp; */
-// /* height: 25dp; */
-// /* padding: 4dp; */
-// /* decorator: image(selectvalue) */
-// }
-
-// select:hover selectvalue {
-// /* margin-right: 30dp; */
-// /* height: 25dp; */
-// /* padding: 4dp; */
-// background-color: rgb(150, 150, 150);
-// /* decorator: image(selectvalue) */
-// }
-
-// select selectarrow {
-// /* width: 30dp; */
-// /* height: 37dp; */
-// /* decorator: image(selectarrow) */
-// /* background-color: black; */
-// /* appearance: none; */
-// }
-
-// select:hover selectarrow {
-// /* decorator: image(selectarrow-hover) */
-// }
-
-// select:active selectarrow,
-// select selectarrow:checked {
-// /* decorator: image(selectarrow-active) */
-// }
-
-// select selectbox {
-// /* margin-left: 1dp; */
-// /* margin-top: -7dp; */
-// /* margin-bottom: -10dp; */
-// /* width: 162dp; */
-// /* padding: 1dp 4dp 4dp 4dp */
-// }
-
-// select selectbox,
-// tbody {
-// background-color: rgb(120,120,120);
-// /* decorator: tiled-box(selectbox-tl, selectbox-t, selectbox-tr, selectbox-l, selectbox-c, auto, selectbox-bl, selectbox-b, selectbox-br) */
-// }
-
-// select selectbox option {
-// width: auto;
-// background-color: rgb(120, 120, 120)
-// }
-
-// select selectbox option:nth-child(even),
-// tr:nth-child(even) {
-// background-color: rgb(100, 100, 100)
-// }
-
-// select selectbox option:checked {
-// font-weight:bold;
-// color:rgb(255,255,255);
-// }
-
-// select selectbox option:hover {
-// background: rgb(150,150,150)
-// }
-
-input.radio {
- flex: 0;
- width:0dp;
- nav-up:auto;
- nav-right:auto;
- nav-down:auto;
- nav-left:auto;
- tab-index:auto;
- focus:auto;
-}
-
-input.checkbox {
- width: space(20);
- height: space(20);
- nav-up:auto;
- nav-right:auto;
- nav-down:auto;
- nav-left:auto;
- tab-index:auto;
- focus:auto;
-}
diff --git a/assets/scss/styles/globals/_scrollbars.scss b/assets/scss/styles/globals/_scrollbars.scss
deleted file mode 100644
index 375c164..0000000
--- a/assets/scss/styles/globals/_scrollbars.scss
+++ /dev/null
@@ -1,52 +0,0 @@
-@use 'sass:math';
-
-$scrollbar-width: 12;
-
-@mixin _set-scroll-size($size-key) {
- #{$size-key}: space($scrollbar-width);
-
- slidertrack {
- #{$size-key}: space($scrollbar-width);
- }
-
- sliderbar {
- #{$size-key}: space($scrollbar-width);
- }
-}
-
-scrollbarvertical,scrollbarhorizontal {
- margin: 0;
- border: 0;
-
- slidertrack {
- background: $color-primary-l;
- opacity: 0.05;
- }
-
- sliderbar {
- border-radius: space(math.div($scrollbar-width, 2) - 1);
- background: $color-primary-l;
- opacity: 0.1;
-
- &:hover:not(:active) {
- opacity: 0.2;
- }
-
- &:active {
- opacity: 0.3;
- }
- }
-
- sliderarrowdec, sliderarrowinc {
- width: 0;
- height: 0;
- }
-}
-
-scrollbarvertical {
- @include _set-scroll-size(width);
-}
-
-scrollbarhorizontal {
- @include _set-scroll-size(height);
-}
diff --git a/assets/scss/styles/mixins/_helpers.scss b/assets/scss/styles/mixins/_helpers.scss
deleted file mode 100644
index 9759630..0000000
--- a/assets/scss/styles/mixins/_helpers.scss
+++ /dev/null
@@ -1,39 +0,0 @@
-
-%nav-vert {
- nav-up: auto;
- nav-down: auto;
-}
-
-%nav-horiz {
- nav-right: auto;
- nav-left: auto;
-}
-
-%nav-dir {
- @extend %nav-vert;
- @extend %nav-horiz;
-}
-
-%nav-foc {
- focus: auto;
- tab-index: auto;
-}
-
-%nav-all {
- @extend %nav-dir;
- @extend %nav-foc;
-}
-
-@mixin set-svgs-color($col) {
- svg {
- image-color: $col;
- }
-}
-
-/*
-@include set-color(COLOR);
-*/
-@mixin set-color($col) {
- @include set-svgs-color($col);
- color: $col;
-}
diff --git a/assets/scss/styles/mixins/_transitions.scss b/assets/scss/styles/mixins/_transitions.scss
deleted file mode 100644
index 06c8677..0000000
--- a/assets/scss/styles/mixins/_transitions.scss
+++ /dev/null
@@ -1,36 +0,0 @@
-
-/*
-@include trans-colors;
-*/
-@mixin trans-colors {
- transition: color $transition-quick, background-color $transition-quick;
-}
-
-/*
-@include trans-colors-opa;
-*/
-@mixin trans-colors-opa {
- transition: color $transition-quick, background-color $transition-quick, opacity $transition-quick;
-}
-
-/*
-@include trans-colors-svg;
-*/
-@mixin trans-colors-svg {
- transition: color $transition-quick, background-color $transition-quick, opacity $transition-quick;
-
- svg {
- transition: image-color $transition-quick, background-color $transition-quick;
- }
-}
-
-/*
-@include trans-colors-border;
-*/
-@mixin trans-colors-border {
- transition: color $transition-quick, background-color $transition-quick, opacity $transition-quick, border-color $transition-quick;
-
- svg {
- transition: image-color $transition-quick, background-color $transition-quick;
- }
-}
diff --git a/assets/scss/styles/mixins/_typography.scss b/assets/scss/styles/mixins/_typography.scss
deleted file mode 100644
index a638b1a..0000000
--- a/assets/scss/styles/mixins/_typography.scss
+++ /dev/null
@@ -1,83 +0,0 @@
-
-$font-stack: chiaro;
-
-@mixin set-font-sizing($sz, $spacing) {
- // font-family: $font-stack;
- $sz-add: $sz + 4;
- font-size: space($sz-add);
- letter-spacing: space($sz-add * $spacing);
- line-height: space($sz-add);
-}
-
-%header-1 {
- @include set-font-sizing(64, 0.07);
- font-style: normal;
- font-weight: 700;
-}
-
-%header-2 {
- @include set-font-sizing(48, 0.07);
- font-style: normal;
- font-weight: 700;
-}
-
-%header-3 {
- @include set-font-sizing(32, 0.07);
- font-style: normal;
- font-weight: 700;
-}
-
-%label-lg {
- @include set-font-sizing(32, 0.11);
- font-style: normal;
- font-weight: 700;
-}
-
-%label-md {
- @include set-font-sizing(24, 0.11);
- font-style: normal;
- font-weight: 700;
-}
-
-%label-sm {
- @include set-font-sizing(16, 0.14);
- font-style: normal;
- font-weight: 700;
- text-transform: uppercase;
-}
-
-%label-xs {
- @include set-font-sizing(14, 0.14);
- font-style: normal;
- font-weight: 400;
-}
-
-%body {
- @include set-font-sizing(16, 0.0);
- font-style: normal;
- font-weight: 400;
-}
-
-%prompt-font-lg {
- font-family: promptfont;
- font-size: space(56);
- font-style: normal;
- font-weight: 400;
- line-height: space(56);
-}
-
-%prompt-font {
- font-family: promptfont;
- font-size: space(40);
- font-style: normal;
- font-weight: 400;
- line-height: space(40);
-}
-
-%prompt-font-sm {
- font-family: promptfont;
- font-size: space(32);
- font-style: normal;
- font-weight: 400;
- line-height: space(32);
-}
diff --git a/assets/scss/styles/pages/_pages.scss b/assets/scss/styles/pages/_pages.scss
deleted file mode 100644
index 16e2e18..0000000
--- a/assets/scss/styles/pages/_pages.scss
+++ /dev/null
@@ -1 +0,0 @@
-@import "./config/config";
diff --git a/assets/scss/styles/pages/config/_config.scss b/assets/scss/styles/pages/config/_config.scss
deleted file mode 100644
index c4e69bc..0000000
--- a/assets/scss/styles/pages/config/_config.scss
+++ /dev/null
@@ -1 +0,0 @@
-@import "./debug";
diff --git a/assets/scss/styles/pages/config/debug.scss b/assets/scss/styles/pages/config/debug.scss
deleted file mode 100644
index 997bfc0..0000000
--- a/assets/scss/styles/pages/config/debug.scss
+++ /dev/null
@@ -1,178 +0,0 @@
-
-.config-debug {
- display: block;
- position: relative;
- width: 100%;
- max-height: 100%;
- padding: space(8);
-}
-
-.config-debug__scroll {
- display: block;
- position: relative;
- width: 100%;
- max-height: 100%;
- overflow-y: auto;
-}
-
-.config-debug-option {
- @include set-color($color-text-dim);
- @include trans-colors-svg;
- @include border-bottom($color-border-soft);
- display: block;
- position: relative;
- flex-direction: column;
- width: 100%;
- height: auto;
- padding: space(12) space(4);
- background-color: rgba(0, 0, 0, 0);
-
- &:focus:not(:disabled, [disabled]),
- &:focus-visible:not(:disabled, [disabled]),
- &:hover:not(:disabled, [disabled]) {
- @include set-color($color-text);
- background-color: $color-bg-overlay;
- }
-
- &:disabled, &[disabled] {
- opacity: 0.5;
- }
-
- .icon-button {
- margin-left: space(8);
- }
-}
-
-.config-debug__option-split {
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: space-between;
-}
-
-.config-debug-option__label {
- @extend %label-md;
- display: flex;
- flex-direction: row;
- align-items: center;
- justify-content: flex-start;
- padding: space(4) space(16) space(12);
- width: auto;
- height: auto;
- white-space: nowrap;
-}
-
-.config-debug__option-controls {
- display: block;
- position: relative;
- flex: 1 1 auto;
- height: auto;
- width: auto;
- max-width: space(800);
- padding: 0 space(12);
-}
-
-.config-debug__option-trigger {
- flex: 1 1 auto;
-}
-
-.config-debug__select-wrapper {
- display: flex;
- position: relative;
- flex-direction: row;
- align-items: center;
- justify-content: flex-start;
- flex: 1 1 100%;
- width: auto;
- max-width: space(800);
- height: auto;
- padding: space(4);
-
- .config-debug__select-label {
- @extend %label-sm;
- padding-right: space(16);
- flex: auto;
- width: space(196);
-
- > div {
- display: inline;
- width: auto;
- height: auto;
- }
- }
-
- input {
- @extend %body;
- @extend %nav-all;
- display: block;
- position: relative;
- box-sizing: border-box;
- padding: 0;
- flex: 1 1 100%;
- width: auto;
- height: space(20);
- margin: auto 0;
- }
-
- select {
- @extend %body;
- @extend %nav-all;
- @include trans-colors-border;
- @include border($color-white-a50);
- display: block;
- position: relative;
- box-sizing: border-box;
- padding: 0;
- flex: 1 1 100%;
- width: auto;
- height: space(48);
- border-radius: $border-radius-md;
- background-color: $color-white-a5;
- cursor: pointer;
-
- align-items: center;
- justify-content: flex-start;
- padding: space(14);
-
- &:hover, &:focus {
- @include border($color-white-a80);
- background-color: $color-white-a20;
- }
-
- selectvalue {
- display: inline;
- margin: auto 0;
- height: auto;
- }
-
- selectbox {
- @include border($color-white-a80);
- background-color: $color-background-3;
- padding: space(4) 0;
- margin-top: space(2);
- border-radius: $border-radius-md;
-
- option {
- @extend %nav-all;
- @include trans-colors;
- padding: space(8) space(12);
- background-color: $color-transparent;
- color: $color-text-dim;
- font-weight: 400;
-
- &:hover, &:focus {
- background-color: $color-white-a20;
- }
-
- &:hover:not(:checked) {
- cursor: pointer;
- }
-
- &:checked {
- color: $color-white;
- background-color: $color-white-a5;
- }
- }
- }
- }
-}
diff --git a/assets/scss/styles/vars/_animations.scss b/assets/scss/styles/vars/_animations.scss
deleted file mode 100644
index 9315f4d..0000000
--- a/assets/scss/styles/vars/_animations.scss
+++ /dev/null
@@ -1,4 +0,0 @@
-
-$focus-anim: blue-pulse-with-border 0.75s infinite;
-$focus-anim-border: blue-pulse 0.75s infinite;
-$focus-anim-bg: blue-pulse-background 0.75s infinite;
diff --git a/assets/scss/styles/vars/_borders.scss b/assets/scss/styles/vars/_borders.scss
deleted file mode 100644
index 5088285..0000000
--- a/assets/scss/styles/vars/_borders.scss
+++ /dev/null
@@ -1,42 +0,0 @@
-
-$border-radius-sm: 8dp;
-$border-radius-md: 12dp;
-// modals/pages
-$border-radius-lg: 16dp;
-
-$border-radius-modal: $border-radius-lg;
-
-$border-width-thickness-num: 1.1;
-// $border-width-thickness-num: 1.5;
-$border-width-thickness: space($border-width-thickness-num);
-
-@mixin border($col: $color-border) {
- border-width: $border-width-thickness;
- border-color: $col;
-}
-
-@mixin border-top($col: $color-border) {
- border-top-width: $border-width-thickness;
- border-top-color: $col;
-}
-
-@mixin border-bottom($col: $color-border) {
- border-bottom-width: $border-width-thickness;
- border-bottom-color: $col;
-}
-
-@mixin inset-block($inset-amt) {
- position: absolute;
- top: $inset-amt;
- right: $inset-amt;
- bottom: $inset-amt;
- left: $inset-amt;
-}
-
-// add this to a child of the container that needs a border.
-// parent must have `position: relative`
-@mixin inner-border-block($col: $color-border) {
- @include inset-block($border-width-thickness);
- @include border($col);
- display: block;
-}
diff --git a/assets/scss/styles/vars/_colors.scss b/assets/scss/styles/vars/_colors.scss
deleted file mode 100644
index 0b5cfd7..0000000
--- a/assets/scss/styles/vars/_colors.scss
+++ /dev/null
@@ -1,71 +0,0 @@
-/* stylelint-disable color-no-hex, color-hex-length */
-
-$color-background-1: #08070D;
-$color-background-2: #121018;
-$color-background-3: #191622;
-$color-bg-overlay: rgba(190, 184, 219, 0.1000);
-$color-modal-overlay: rgba(8, 7, 13, 0.9000);
-$color-bg-shadow: rgba(0, 0, 0, 0.3500);
-$color-bg-shadow-2: rgba(8, 7, 13, 0.7200);
-$color-text: #F2F2F2;
-$color-text-dim: #CCCCCC;
-$color-text-inactive: rgba(255, 255, 255, 0.6000);
-$color-primary: #B97DF2;
-$color-primary-l: #DABAF7;
-$color-primary-d: #7A2AC6;
-$color-primary-a5: rgba(185, 125, 242, 0.0500);
-$color-primary-a20: rgba(185, 125, 242, 0.2000);
-$color-primary-a30: rgba(185, 125, 242, 0.3000);
-$color-primary-a50: rgba(185, 125, 242, 0.5000);
-$color-primary-a80: rgba(185, 125, 242, 0.8000);
-$color-secondary: #17D6E8;
-$color-secondary-l: #A2EFF6;
-$color-secondary-d: #25A1AD;
-$color-secondary-a5: rgba(23, 214, 232, 0.0500);
-$color-secondary-a20: rgba(23, 214, 232, 0.2000);
-$color-secondary-a30: rgba(23, 214, 232, 0.3000);
-$color-secondary-a50: rgba(23, 214, 232, 0.5000);
-$color-secondary-a80: rgba(23, 214, 232, 0.8000);
-$color-warning: #E9CD35;
-$color-warning-l: #F9E57C;
-$color-warning-d: #C5AA16;
-$color-warning-a5: rgba(233, 205, 53, 0.0500);
-$color-warning-a20: rgba(233, 205, 53, 0.2000);
-$color-warning-a30: rgba(233, 205, 53, 0.3000);
-$color-warning-a50: rgba(233, 205, 53, 0.5000);
-$color-warning-a80: rgba(233, 205, 53, 0.8000);
-$color-error: #F86039;
-$color-error-l: #FE8667;
-$color-error-d: #B23919;
-$color-error-a5: rgba(248, 96, 57, 0.0500);
-$color-error-a20: rgba(248, 96, 57, 0.2000);
-$color-error-a30: rgba(248, 96, 57, 0.3000);
-$color-error-a50: rgba(248, 96, 57, 0.5000);
-$color-error-a80: rgba(248, 96, 57, 0.8000);
-$color-success: #45D043;
-$color-success-l: #AAEAA9;
-$color-success-d: #2CA72A;
-$color-success-a5: rgba(69, 208, 67, 0.0500);
-$color-success-a20: rgba(69, 208, 67, 0.2000);
-$color-success-a30: rgba(69, 208, 67, 0.3000);
-$color-success-a50: rgba(69, 208, 67, 0.5000);
-$color-success-a80: rgba(69, 208, 67, 0.8000);
-$color-border: rgba(255, 255, 255, 0.2000);
-$color-border-soft: rgba(255, 255, 255, 0.1000);
-$color-border-hard: rgba(255, 255, 255, 0.3000);
-$color-border-solid: rgba(255, 255, 255, 0.6000);
-$color-transparent: rgba(0, 0, 0, 0.0000);
-$color-a: #3333FF;
-$color-a-l: #B2B2FF;
-$color-a-d: #2020AC;
-$color-a-a5: rgba(51, 51, 255, 0.0500);
-$color-a-a20: rgba(51, 51, 255, 0.2000);
-$color-a-a30: rgba(51, 51, 255, 0.3000);
-$color-a-a50: rgba(51, 51, 255, 0.5000);
-$color-a-a80: rgba(51, 51, 255, 0.8000);
-$color-white: #FFFFFF;
-$color-white-a5: rgba(255, 255, 255, 0.0500);
-$color-white-a20: rgba(255, 255, 255, 0.2000);
-$color-white-a30: rgba(255, 255, 255, 0.3000);
-$color-white-a50: rgba(255, 255, 255, 0.5000);
-$color-white-a80: rgba(255, 255, 255, 0.8000);
diff --git a/assets/scss/styles/vars/_gradients.scss b/assets/scss/styles/vars/_gradients.scss
deleted file mode 100644
index 1cdebd5..0000000
--- a/assets/scss/styles/vars/_gradients.scss
+++ /dev/null
@@ -1,7 +0,0 @@
-
-// Not supported yet, need to use decorator: gradient atm
-// $primary-lr-fade: linear-gradient(90deg, rgba($color-primary-l, 0.08) 0%, rgba($color-primary-l, 0.00) 100%);
-// $primary-rl-fade: linear-gradient(90deg, rgba($color-primary-l, 0.00) 0%, rgba($color-primary-l, 0.08) 100%);
-
-$primary-lr-fade: horizontal-gradient(#{$color-primary-d}14 #{$color-primary-l}00);
-$primary-rl-fade: horizontal-gradient(#{$color-primary-d}00 #{$color-primary-l}14);
diff --git a/assets/scss/styles/vars/_spacing.scss b/assets/scss/styles/vars/_spacing.scss
deleted file mode 100644
index b61c8e1..0000000
--- a/assets/scss/styles/vars/_spacing.scss
+++ /dev/null
@@ -1,7 +0,0 @@
-@use 'sass:math';
-
-// $page-margin: 32;
-$page-margin: 64;
-$base-height: 1080;
-$base-modal-height: $base-height - ($page-margin * 2);
-$base-modal-max-width: math.div($base-modal-height * 16, 9);
diff --git a/assets/scss/styles/vars/_transitions.scss b/assets/scss/styles/vars/_transitions.scss
deleted file mode 100644
index 0586d88..0000000
--- a/assets/scss/styles/vars/_transitions.scss
+++ /dev/null
@@ -1,3 +0,0 @@
-// see: lib/RmlUi/Source/Core/PropertyParserAnimation.cpp
-$transition-quick: 0.05s linear-in-out;
-// $transition-quick: 0.033s linear-in-out;
diff --git a/include/recomp_input.h b/include/recomp_input.h
deleted file mode 100644
index 8599628..0000000
--- a/include/recomp_input.h
+++ /dev/null
@@ -1,202 +0,0 @@
-#ifndef __RECOMP_INPUT_H__
-#define __RECOMP_INPUT_H__
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "ultramodern/input.hpp"
-
-#include "json/json.hpp"
-
-namespace recomp {
- // x-macros to build input enums and arrays.
- // First parameter is the enum name, second parameter is the bit field for the input (or 0 if there is no associated one), third is the readable name.
- // TODO refactor this to allow projects to rename these, or get rid of the readable name and leave that up to individual projects to map.
- #define DEFINE_N64_BUTTON_INPUTS() \
- DEFINE_INPUT(A, 0x8000, "Action") \
- DEFINE_INPUT(B, 0x4000, "Attack/Cancel") \
- DEFINE_INPUT(Z, 0x2000, "Target") \
- DEFINE_INPUT(START, 0x1000, "Start") \
- DEFINE_INPUT(L, 0x0020, "Toggle map") \
- DEFINE_INPUT(R, 0x0010, "Shield") \
- DEFINE_INPUT(C_UP, 0x0008, "Look/Fairy") \
- DEFINE_INPUT(C_LEFT, 0x0002, "Item 1") \
- DEFINE_INPUT(C_DOWN, 0x0004, "Item 2") \
- DEFINE_INPUT(C_RIGHT, 0x0001, "Item 3") \
- DEFINE_INPUT(DPAD_UP, 0x0800, "Special Item 1") \
- DEFINE_INPUT(DPAD_RIGHT, 0x0100, "Special Item 2") \
- DEFINE_INPUT(DPAD_DOWN, 0x0400, "Special Item 3") \
- DEFINE_INPUT(DPAD_LEFT, 0x0200, "Special Item 4")
-
- #define DEFINE_N64_AXIS_INPUTS() \
- DEFINE_INPUT(Y_AXIS_POS, 0, "Up") \
- DEFINE_INPUT(Y_AXIS_NEG, 0, "Down") \
- DEFINE_INPUT(X_AXIS_NEG, 0, "Left") \
- DEFINE_INPUT(X_AXIS_POS, 0, "Right") \
-
- #define DEFINE_RECOMP_UI_INPUTS() \
- DEFINE_INPUT(TOGGLE_MENU, 0, "Toggle Menu") \
- DEFINE_INPUT(ACCEPT_MENU, 0, "Accept (Menu)") \
- DEFINE_INPUT(APPLY_MENU, 0, "Apply (Menu)")
-
- #define DEFINE_ALL_INPUTS() \
- DEFINE_N64_BUTTON_INPUTS() \
- DEFINE_N64_AXIS_INPUTS() \
- DEFINE_RECOMP_UI_INPUTS()
-
- // Enum containing every recomp input.
- #define DEFINE_INPUT(name, value, readable) name,
- enum class GameInput {
- DEFINE_ALL_INPUTS()
-
- COUNT,
- N64_BUTTON_START = A,
- N64_BUTTON_COUNT = C_RIGHT - N64_BUTTON_START + 1,
- N64_AXIS_START = X_AXIS_NEG,
- N64_AXIS_COUNT = Y_AXIS_POS - N64_AXIS_START + 1,
- };
- #undef DEFINE_INPUT
-
- struct InputField {
- uint32_t input_type;
- int32_t input_id;
- std::string to_string() const;
- auto operator<=>(const InputField& rhs) const = default;
- };
-
- void poll_inputs();
- float get_input_analog(const InputField& field);
- float get_input_analog(const std::span fields);
- bool get_input_digital(const InputField& field);
- bool get_input_digital(const std::span fields);
- void get_gyro_deltas(float* x, float* y);
- void get_mouse_deltas(float* x, float* y);
- void get_right_analog(float* x, float* y);
-
- enum class InputDevice {
- Controller,
- Keyboard,
- COUNT
- };
-
- void start_scanning_input(InputDevice device);
- void stop_scanning_input();
- void finish_scanning_input(InputField scanned_field);
- void cancel_scanning_input();
- void config_menu_set_cont_or_kb(bool cont_interacted);
- InputField get_scanned_input();
- int get_scanned_input_index();
-
- struct DefaultN64Mappings {
- std::vector a;
- std::vector b;
- std::vector l;
- std::vector r;
- std::vector z;
- std::vector start;
-
- std::vector c_left;
- std::vector c_right;
- std::vector c_up;
- std::vector c_down;
-
- std::vector dpad_left;
- std::vector dpad_right;
- std::vector dpad_up;
- std::vector dpad_down;
-
- std::vector analog_left;
- std::vector analog_right;
- std::vector analog_up;
- std::vector analog_down;
-
- std::vector toggle_menu;
- std::vector accept_menu;
- std::vector apply_menu;
- };
-
- inline const std::vector& get_default_mapping_for_input(const DefaultN64Mappings& defaults, const GameInput input) {
- static const std::vector empty_input_field{};
- switch (input) {
- case GameInput::A: return defaults.a;
- case GameInput::B: return defaults.b;
- case GameInput::L: return defaults.l;
- case GameInput::R: return defaults.r;
- case GameInput::Z: return defaults.z;
- case GameInput::START: return defaults.start;
- case GameInput::C_LEFT: return defaults.c_left;
- case GameInput::C_RIGHT: return defaults.c_right;
- case GameInput::C_UP: return defaults.c_up;
- case GameInput::C_DOWN: return defaults.c_down;
- case GameInput::DPAD_LEFT: return defaults.dpad_left;
- case GameInput::DPAD_RIGHT: return defaults.dpad_right;
- case GameInput::DPAD_UP: return defaults.dpad_up;
- case GameInput::DPAD_DOWN: return defaults.dpad_down;
- case GameInput::X_AXIS_NEG: return defaults.analog_left;
- case GameInput::X_AXIS_POS: return defaults.analog_right;
- case GameInput::Y_AXIS_POS: return defaults.analog_up;
- case GameInput::Y_AXIS_NEG: return defaults.analog_down;
- case GameInput::TOGGLE_MENU: return defaults.toggle_menu;
- case GameInput::ACCEPT_MENU: return defaults.accept_menu;
- case GameInput::APPLY_MENU: return defaults.apply_menu;
- default: return empty_input_field;
- }
- }
-
- extern const DefaultN64Mappings default_n64_keyboard_mappings;
- extern const DefaultN64Mappings default_n64_controller_mappings;
-
- constexpr size_t bindings_per_input = 2;
-
- size_t get_num_inputs();
- const std::string& get_input_name(GameInput input);
- const std::string& get_input_enum_name(GameInput input);
- GameInput get_input_from_enum_name(const std::string_view name);
- InputField& get_input_binding(GameInput input, size_t binding_index, InputDevice device);
- void set_input_binding(GameInput input, size_t binding_index, InputDevice device, InputField value);
-
- bool get_n64_input(int controller_num, uint16_t* buttons_out, float* x_out, float* y_out);
- void set_rumble(int controller_num, bool);
- void update_rumble();
- void handle_events();
-
- ultramodern::input::connected_device_info_t get_connected_device_info(int controller_num);
-
- // Rumble strength ranges from 0 to 100.
- int get_rumble_strength();
- void set_rumble_strength(int strength);
-
- // Gyro and mouse sensitivities range from 0 to 100.
- int get_gyro_sensitivity();
- int get_mouse_sensitivity();
- int get_joystick_deadzone();
- void set_gyro_sensitivity(int strength);
- void set_mouse_sensitivity(int strength);
- void set_joystick_deadzone(int strength);
- void apply_joystick_deadzone(float x_in, float y_in, float* x_out, float* y_out);
- void set_right_analog_suppressed(bool suppressed);
-
- enum class BackgroundInputMode {
- On,
- Off,
- OptionCount
- };
-
- NLOHMANN_JSON_SERIALIZE_ENUM(recomp::BackgroundInputMode, {
- {recomp::BackgroundInputMode::On, "On"},
- {recomp::BackgroundInputMode::Off, "Off"}
- });
-
- BackgroundInputMode get_background_input_mode();
- void set_background_input_mode(BackgroundInputMode mode);
-
- bool game_input_disabled();
- bool all_input_disabled();
-}
-
-#endif
diff --git a/include/recomp_ui.h b/include/recomp_ui.h
deleted file mode 100644
index f609a52..0000000
--- a/include/recomp_ui.h
+++ /dev/null
@@ -1,146 +0,0 @@
-#ifndef __RECOMP_UI__
-#define __RECOMP_UI__
-
-#include
-#include
-#include
-#include
-
-// TODO move this file into src/ui
-
-#include "SDL.h"
-#include "RmlUi/Core.h"
-
-#include "../src/ui/util/hsv.h"
-#include "../src/ui/util/bem.h"
-
-#include "../src/ui/core/ui_context.h"
-
-namespace Rml {
- class ElementDocument;
- class EventListenerInstancer;
- class Context;
- class Event;
-}
-
-namespace recompui {
- class UiEventListenerInstancer;
-
- // TODO remove this once the UI has been ported over to the new system.
- class MenuController {
- public:
- virtual ~MenuController() {}
- virtual void load_document() = 0;
- virtual void register_events(UiEventListenerInstancer& listener) = 0;
- virtual void make_bindings(Rml::Context* context) = 0;
- };
-
- std::unique_ptr create_launcher_menu();
- std::unique_ptr create_config_menu();
-
- using event_handler_t = void(const std::string& param, Rml::Event&);
-
- void queue_event(const SDL_Event& event);
- bool try_deque_event(SDL_Event& out);
-
- std::unique_ptr make_event_listener_instancer();
- void register_event(UiEventListenerInstancer& listener, const std::string& name, event_handler_t* handler);
-
- void show_context(ContextId context, std::string_view param);
- void hide_context(ContextId context);
- void hide_all_contexts();
- bool is_context_shown(ContextId context);
- bool is_context_capturing_input();
- bool is_context_capturing_mouse();
- bool is_any_context_shown();
- ContextId try_close_current_context();
-
- ContextId get_launcher_context_id();
- ContextId get_config_context_id();
- ContextId get_config_sub_menu_context_id();
-
- enum class ConfigTab {
- General,
- Controls,
- Graphics,
- Sound,
- Mods,
- Debug,
- };
-
- void set_config_tab(ConfigTab tab);
- int config_tab_to_index(ConfigTab tab);
- Rml::ElementTabSet* get_config_tabset();
- Rml::Element* get_mod_tab();
- void set_config_tabset_mod_nav();
- void focus_mod_configure_button();
-
- enum class ButtonVariant {
- Primary,
- Secondary,
- Tertiary,
- Success,
- Error,
- Warning,
- NumVariants,
- };
-
- void init_styling(const std::filesystem::path& rcss_file);
- void init_prompt_context();
- void open_choice_prompt(
- const std::string& header_text,
- const std::string& content_text,
- const std::string& confirm_label_text,
- const std::string& cancel_label_text,
- std::function confirm_action,
- std::function cancel_action,
- ButtonVariant confirm_variant = ButtonVariant::Success,
- ButtonVariant cancel_variant = ButtonVariant::Error,
- bool focus_on_cancel = true,
- const std::string& return_element_id = ""
- );
- void open_info_prompt(
- const std::string& header_text,
- const std::string& content_text,
- const std::string& okay_label_text,
- std::function okay_action,
- ButtonVariant okay_variant = ButtonVariant::Error,
- const std::string& return_element_id = ""
- );
- void open_notification(
- const std::string& header_text,
- const std::string& content_text,
- const std::string& return_element_id = ""
- );
- void close_prompt();
- bool is_prompt_open();
- void update_mod_list(bool scan_mods = true);
- void process_game_started();
-
- void apply_color_hack();
- void get_window_size(int& width, int& height);
- void set_cursor_visible(bool visible);
- void update_supported_options();
- void toggle_fullscreen();
-
- bool get_cont_active(void);
- void set_cont_active(bool active);
- void activate_mouse();
-
- void message_box(const char* msg);
-
- void set_render_hooks();
-
- Rml::ElementPtr create_custom_element(Rml::Element* parent, std::string tag);
- Rml::ElementDocument* load_document(const std::filesystem::path& path);
- Rml::ElementDocument* create_empty_document();
- Rml::Element* get_child_by_tag(Rml::Element* parent, const std::string& tag);
-
- void queue_image_from_bytes_rgba32(const std::string &src, const std::vector &bytes, uint32_t width, uint32_t height);
- void queue_image_from_bytes_file(const std::string &src, const std::vector &bytes);
- void release_image(const std::string &src);
-
- void drop_files(const std::list &file_list);
-}
-
-#endif
diff --git a/include/zelda_config.h b/include/zelda_config.h
index 59b41f0..d15da18 100644
--- a/include/zelda_config.h
+++ b/include/zelda_config.h
@@ -2,92 +2,71 @@
#define __ZELDA_CONFIG_H__
#include
-#include
-#include "ultramodern/config.hpp"
-#include "recomp_input.h"
+#include
namespace zelda64 {
- constexpr std::u8string_view program_id = u8"Zelda64Recompiled";
- constexpr std::string_view program_name = "Zelda 64: Recompiled";
+ inline const std::u8string program_id = u8"Zelda64Recompiled";
+ inline const std::string program_name = "Zelda 64: Recompiled";
+
+ namespace configkeys {
+ namespace general {
+ inline const std::string debug_mode = "debug_mode";
+ inline const std::string targeting_mode = "targeting_mode";
+ inline const std::string autosave_mode = "autosave_mode";
+ inline const std::string camera_invert_mode = "camera_invert_mode";
+ inline const std::string analog_cam_mode = "analog_cam_mode";
+ inline const std::string analog_camera_invert_mode = "analog_camera_invert_mode";
+ }
+
+ namespace sound {
+ inline const std::string bgm_volume = "bgm_volume";
+ inline const std::string low_health_beeps = "low_health_beeps";
+ }
+
+ namespace graphics {
+ }
+ }
// TODO: Move loading configs to the runtime once we have a way to allow per-project customization.
- void load_config();
- void save_config();
-
- void reset_input_bindings();
- void reset_cont_input_bindings();
- void reset_kb_input_bindings();
- void reset_single_input_binding(recomp::InputDevice device, recomp::GameInput input);
-
- std::filesystem::path get_app_folder_path();
+ void init_config();
bool get_debug_mode_enabled();
- void set_debug_mode_enabled(bool enabled);
-
+
enum class AutosaveMode {
- On,
Off,
- OptionCount
+ On,
};
- NLOHMANN_JSON_SERIALIZE_ENUM(zelda64::AutosaveMode, {
- {zelda64::AutosaveMode::On, "On"},
- {zelda64::AutosaveMode::Off, "Off"}
- });
+ AutosaveMode get_autosave_mode();
enum class TargetingMode {
Switch,
- Hold,
- OptionCount
+ Hold
};
-
- NLOHMANN_JSON_SERIALIZE_ENUM(zelda64::TargetingMode, {
- {zelda64::TargetingMode::Switch, "Switch"},
- {zelda64::TargetingMode::Hold, "Hold"}
- });
-
+
TargetingMode get_targeting_mode();
- void set_targeting_mode(TargetingMode mode);
enum class CameraInvertMode {
InvertNone,
InvertX,
InvertY,
- InvertBoth,
- OptionCount
+ InvertBoth
};
-
- NLOHMANN_JSON_SERIALIZE_ENUM(zelda64::CameraInvertMode, {
- {zelda64::CameraInvertMode::InvertNone, "InvertNone"},
- {zelda64::CameraInvertMode::InvertX, "InvertX"},
- {zelda64::CameraInvertMode::InvertY, "InvertY"},
- {zelda64::CameraInvertMode::InvertBoth, "InvertBoth"}
- });
-
+
CameraInvertMode get_camera_invert_mode();
- void set_camera_invert_mode(CameraInvertMode mode);
-
CameraInvertMode get_analog_camera_invert_mode();
- void set_analog_camera_invert_mode(CameraInvertMode mode);
enum class AnalogCamMode {
- On,
Off,
- OptionCount
+ On,
};
-
- NLOHMANN_JSON_SERIALIZE_ENUM(zelda64::AnalogCamMode, {
- {zelda64::AnalogCamMode::On, "On"},
- {zelda64::AnalogCamMode::Off, "Off"}
- });
-
- AutosaveMode get_autosave_mode();
- void set_autosave_mode(AutosaveMode mode);
-
+
AnalogCamMode get_analog_cam_mode();
- void set_analog_cam_mode(AnalogCamMode mode);
- void open_quit_game_prompt();
+ enum class LowHealthBeepsMode {
+ Off,
+ On,
+ };
};
#endif
diff --git a/include/zelda_debug.h b/include/zelda_debug.h
index 4c0743e..26552f4 100644
--- a/include/zelda_debug.h
+++ b/include/zelda_debug.h
@@ -5,6 +5,11 @@
#include
namespace zelda64 {
+ namespace debug {
+ inline const std::string tab_id = "debug";
+ inline const std::string tab_name = "Debug";
+ }
+
struct SceneWarps {
int index;
std::string name;
diff --git a/include/zelda_launcher.h b/include/zelda_launcher.h
new file mode 100644
index 0000000..f88f7ee
--- /dev/null
+++ b/include/zelda_launcher.h
@@ -0,0 +1,11 @@
+#ifndef __ZELDA_LAUNCHER_H__
+#define __ZELDA_LAUNCHER_H__
+
+#include "recompui/recompui.h"
+
+namespace zelda64 {
+ void launcher_animation_setup(recompui::LauncherMenu *menu);
+ void launcher_animation_update(recompui::LauncherMenu *menu);
+}
+
+#endif
diff --git a/include/zelda_render.h b/include/zelda_render.h
deleted file mode 100644
index 15397f9..0000000
--- a/include/zelda_render.h
+++ /dev/null
@@ -1,61 +0,0 @@
-#ifndef __ZELDA_RENDER_H__
-#define __ZELDA_RENDER_H__
-
-#include
-#include
-
-#include "common/rt64_user_configuration.h"
-#include "ultramodern/renderer_context.hpp"
-#include "librecomp/mods.hpp"
-
-namespace RT64 {
- struct Application;
-}
-
-namespace zelda64 {
- namespace renderer {
- inline const std::string special_option_texture_pack_enabled = "_recomp_texture_pack_enabled";
-
- class RT64Context final : public ultramodern::renderer::RendererContext {
- public:
- ~RT64Context() override;
- RT64Context(uint8_t *rdram, ultramodern::renderer::WindowHandle window_handle, bool developer_mode);
-
- bool valid() override { return static_cast(app); }
-
- bool update_config(const ultramodern::renderer::GraphicsConfig &old_config, const ultramodern::renderer::GraphicsConfig &new_config) override;
-
- void enable_instant_present() override;
- void send_dl(const OSTask *task) override;
- void update_screen() override;
- void shutdown() override;
- uint32_t get_display_framerate() const override;
- float get_resolution_scale() const override;
-
- private:
- std::unique_ptr app;
- std::unordered_set enabled_texture_packs;
- std::unordered_set secondary_disabled_texture_packs;
-
- void check_texture_pack_actions();
- };
-
- std::unique_ptr create_render_context(uint8_t *rdram, ultramodern::renderer::WindowHandle window_handle, bool developer_mode);
-
- RT64::UserConfiguration::Antialiasing RT64MaxMSAA();
- bool RT64SamplePositionsSupported();
- bool RT64HighPrecisionFBEnabled();
-
- void trigger_texture_pack_update();
- void enable_texture_pack(const recomp::mods::ModContext& context, const recomp::mods::ModHandle& mod);
- void disable_texture_pack(const recomp::mods::ModHandle& mod);
- void secondary_enable_texture_pack(const std::string& mod_id);
- void secondary_disable_texture_pack(const std::string& mod_id);
-
- // Texture pack enable option. Must be an enum with two options.
- // The first option is treated as disabled and the second option is treated as enabled.
- bool is_texture_pack_enable_config_option(const recomp::mods::ConfigOption& option, bool show_errors);
- }
-}
-
-#endif
diff --git a/include/zelda_sound.h b/include/zelda_sound.h
index 33bec01..07f0aaf 100644
--- a/include/zelda_sound.h
+++ b/include/zelda_sound.h
@@ -3,11 +3,7 @@
namespace zelda64 {
void reset_sound_settings();
- void set_main_volume(int volume);
- int get_main_volume();
- void set_bgm_volume(int volume);
int get_bgm_volume();
- void set_low_health_beeps_enabled(bool enabled);
bool get_low_health_beeps_enabled();
}
diff --git a/lib/FindFreetype.cmake b/lib/FindFreetype.cmake
deleted file mode 100644
index 1e50bcd..0000000
--- a/lib/FindFreetype.cmake
+++ /dev/null
@@ -1,9 +0,0 @@
-set(FREETYPE_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/lib/freetype-windows-binaries/include)
-set(FREETYPE_LIBRARIES "${CMAKE_SOURCE_DIR}/lib/freetype-windows-binaries/release static/vs2015-2022/win64/freetype.lib")
-add_library(Freetype::Freetype STATIC IMPORTED)
-set_target_properties(Freetype::Freetype PROPERTIES
- IMPORTED_LOCATION ${FREETYPE_LIBRARIES}
-)
-target_include_directories(Freetype::Freetype INTERFACE
- ${FREETYPE_INCLUDE_DIRS}
-)
diff --git a/lib/GamepadMotionHelpers/.gitignore b/lib/GamepadMotionHelpers/.gitignore
deleted file mode 100644
index 259148f..0000000
--- a/lib/GamepadMotionHelpers/.gitignore
+++ /dev/null
@@ -1,32 +0,0 @@
-# Prerequisites
-*.d
-
-# Compiled Object files
-*.slo
-*.lo
-*.o
-*.obj
-
-# Precompiled Headers
-*.gch
-*.pch
-
-# Compiled Dynamic libraries
-*.so
-*.dylib
-*.dll
-
-# Fortran module files
-*.mod
-*.smod
-
-# Compiled Static libraries
-*.lai
-*.la
-*.a
-*.lib
-
-# Executables
-*.exe
-*.out
-*.app
diff --git a/lib/GamepadMotionHelpers/CMakeLists.txt b/lib/GamepadMotionHelpers/CMakeLists.txt
deleted file mode 100644
index 27f7748..0000000
--- a/lib/GamepadMotionHelpers/CMakeLists.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-cmake_minimum_required(VERSION 3.8)
-
-project(GamepadMotionHelpers LANGUAGES CXX)
-
-add_library(${PROJECT_NAME} INTERFACE)
-add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
-target_include_directories(${PROJECT_NAME}
- INTERFACE
- $
- $)
-
\ No newline at end of file
diff --git a/lib/GamepadMotionHelpers/GamepadMotion.hpp b/lib/GamepadMotionHelpers/GamepadMotion.hpp
deleted file mode 100644
index 02497ac..0000000
--- a/lib/GamepadMotionHelpers/GamepadMotion.hpp
+++ /dev/null
@@ -1,1312 +0,0 @@
-// Copyright (c) 2020-2023 Julian "Jibb" Smart
-// Released under the MIT license. See https://github.com/JibbSmart/GamepadMotionHelpers/blob/main/LICENSE for more info
-// Version 9
-
-#pragma once
-
-#define _USE_MATH_DEFINES
-#include
-#include // std::min, std::max and std::clamp
-
-// You don't need to look at these. These will just be used internally by the GamepadMotion class declared below.
-// You can ignore anything in namespace GamepadMotionHelpers.
-class GamepadMotionSettings;
-class GamepadMotion;
-
-namespace GamepadMotionHelpers
-{
- struct GyroCalibration
- {
- float X;
- float Y;
- float Z;
- float AccelMagnitude;
- int NumSamples;
- };
-
- struct Quat
- {
- float w;
- float x;
- float y;
- float z;
-
- Quat();
- Quat(float inW, float inX, float inY, float inZ);
- void Set(float inW, float inX, float inY, float inZ);
- Quat& operator*=(const Quat& rhs);
- friend Quat operator*(Quat lhs, const Quat& rhs);
- void Normalize();
- Quat Normalized() const;
- void Invert();
- Quat Inverse() const;
- };
-
- struct Vec
- {
- float x;
- float y;
- float z;
-
- Vec();
- Vec(float inValue);
- Vec(float inX, float inY, float inZ);
- void Set(float inX, float inY, float inZ);
- float Length() const;
- float LengthSquared() const;
- void Normalize();
- Vec Normalized() const;
- float Dot(const Vec& other) const;
- Vec Cross(const Vec& other) const;
- Vec Min(const Vec& other) const;
- Vec Max(const Vec& other) const;
- Vec Abs() const;
- Vec Lerp(const Vec& other, float factor) const;
- Vec Lerp(const Vec& other, const Vec& factor) const;
- Vec& operator+=(const Vec& rhs);
- friend Vec operator+(Vec lhs, const Vec& rhs);
- Vec& operator-=(const Vec& rhs);
- friend Vec operator-(Vec lhs, const Vec& rhs);
- Vec& operator*=(const float rhs);
- friend Vec operator*(Vec lhs, const float rhs);
- Vec& operator/=(const float rhs);
- friend Vec operator/(Vec lhs, const float rhs);
- Vec& operator*=(const Quat& rhs);
- friend Vec operator*(Vec lhs, const Quat& rhs);
- Vec operator-() const;
- };
-
- struct SensorMinMaxWindow
- {
- Vec MinGyro;
- Vec MaxGyro;
- Vec MeanGyro;
- Vec MinAccel;
- Vec MaxAccel;
- Vec MeanAccel;
- Vec StartAccel;
- int NumSamples = 0;
- float TimeSampled = 0.f;
-
- SensorMinMaxWindow();
- void Reset(float remainder);
- void AddSample(const Vec& inGyro, const Vec& inAccel, float deltaTime);
- Vec GetMidGyro();
- };
-
- struct AutoCalibration
- {
- SensorMinMaxWindow MinMaxWindow;
- Vec SmoothedAngularVelocityGyro;
- Vec SmoothedAngularVelocityAccel;
- Vec SmoothedPreviousAccel;
- Vec PreviousAccel;
-
- AutoCalibration();
- void Reset();
- bool AddSampleStillness(const Vec& inGyro, const Vec& inAccel, float deltaTime, bool doSensorFusion);
- void NoSampleStillness();
- bool AddSampleSensorFusion(const Vec& inGyro, const Vec& inAccel, float deltaTime);
- void NoSampleSensorFusion();
- void SetCalibrationData(GyroCalibration* calibrationData);
- void SetSettings(GamepadMotionSettings* settings);
-
- float Confidence = 0.f;
- bool IsSteady() { return bIsSteady; }
-
- private:
- Vec MinDeltaGyro = Vec(1.f);
- Vec MinDeltaAccel = Vec(0.25f);
- float RecalibrateThreshold = 1.f;
- float SensorFusionSkippedTime = 0.f;
- float TimeSteadySensorFusion = 0.f;
- float TimeSteadyStillness = 0.f;
- bool bIsSteady = false;
-
- GyroCalibration* CalibrationData;
- GamepadMotionSettings* Settings;
- };
-
- struct Motion
- {
- Quat Quaternion;
- Vec Accel;
- Vec Grav;
-
- Vec SmoothAccel = Vec();
- float Shakiness = 0.f;
- const float ShortSteadinessHalfTime = 0.25f;
- const float LongSteadinessHalfTime = 1.f;
-
- Motion();
- void Reset();
- void Update(float inGyroX, float inGyroY, float inGyroZ, float inAccelX, float inAccelY, float inAccelZ, float gravityLength, float deltaTime);
- void SetSettings(GamepadMotionSettings* settings);
-
- private:
- GamepadMotionSettings* Settings;
- };
-
- enum CalibrationMode
- {
- Manual = 0,
- Stillness = 1,
- SensorFusion = 2,
- };
-
- // https://stackoverflow.com/a/1448478/1130520
- inline CalibrationMode operator|(CalibrationMode a, CalibrationMode b)
- {
- return static_cast(static_cast(a) | static_cast(b));
- }
-
- inline CalibrationMode operator&(CalibrationMode a, CalibrationMode b)
- {
- return static_cast(static_cast(a) & static_cast(b));
- }
-
- inline CalibrationMode operator~(CalibrationMode a)
- {
- return static_cast(~static_cast(a));
- }
-
- // https://stackoverflow.com/a/23152590/1130520
- inline CalibrationMode& operator|=(CalibrationMode& a, CalibrationMode b)
- {
- return (CalibrationMode&)((int&)(a) |= static_cast(b));
- }
-
- inline CalibrationMode& operator&=(CalibrationMode& a, CalibrationMode b)
- {
- return (CalibrationMode&)((int&)(a) &= static_cast(b));
- }
-}
-
-// Note that I'm using a Y-up coordinate system. This is to follow the convention set by the motion sensors in
-// PlayStation controllers, which was what I was using when writing in this. But for the record, Z-up is
-// better for most games (XY ground-plane in 3D games simplifies using 2D vectors in navigation, for example).
-
-// Gyro units should be degrees per second. Accelerometer should be g-force (approx. 9.8 m/s^2 = 1 g). If you're using
-// radians per second, meters per second squared, etc, conversion should be simple.
-
-class GamepadMotionSettings
-{
-public:
- int MinStillnessSamples = 10;
- float MinStillnessCollectionTime = 0.5f;
- float MinStillnessCorrectionTime = 2.f;
- float MaxStillnessError = 2.f;
- float StillnessSampleDeteriorationRate = 0.2f;
- float StillnessErrorClimbRate = 0.1f;
- float StillnessErrorDropOnRecalibrate = 0.1f;
- float StillnessCalibrationEaseInTime = 3.f;
- float StillnessCalibrationHalfTime = 0.1f;
- float StillnessConfidenceRate = 1.f;
-
- float StillnessGyroDelta = -1.f;
- float StillnessAccelDelta = -1.f;
-
- float SensorFusionCalibrationSmoothingStrength = 2.f;
- float SensorFusionAngularAccelerationThreshold = 20.f;
- float SensorFusionCalibrationEaseInTime = 3.f;
- float SensorFusionCalibrationHalfTime = 0.1f;
- float SensorFusionConfidenceRate = 1.f;
-
- float GravityCorrectionShakinessMaxThreshold = 0.4f;
- float GravityCorrectionShakinessMinThreshold = 0.01f;
-
- float GravityCorrectionStillSpeed = 1.f;
- float GravityCorrectionShakySpeed = 0.1f;
-
- float GravityCorrectionGyroFactor = 0.1f;
- float GravityCorrectionGyroMinThreshold = 0.05f;
- float GravityCorrectionGyroMaxThreshold = 0.25f;
-
- float GravityCorrectionMinimumSpeed = 0.01f;
-};
-
-class GamepadMotion
-{
-public:
- GamepadMotion();
-
- void Reset();
-
- void ProcessMotion(float gyroX, float gyroY, float gyroZ,
- float accelX, float accelY, float accelZ, float deltaTime);
-
- // reading the current state
- void GetCalibratedGyro(float& x, float& y, float& z);
- void GetGravity(float& x, float& y, float& z);
- void GetProcessedAcceleration(float& x, float& y, float& z);
- void GetOrientation(float& w, float& x, float& y, float& z);
- void GetPlayerSpaceGyro(float& x, float& y, const float yawRelaxFactor = 1.41f);
- static void CalculatePlayerSpaceGyro(float& x, float& y, const float gyroX, const float gyroY, const float gyroZ, const float gravX, const float gravY, const float gravZ, const float yawRelaxFactor = 1.41f);
- void GetWorldSpaceGyro(float& x, float& y, const float sideReductionThreshold = 0.125f);
- static void CalculateWorldSpaceGyro(float& x, float& y, const float gyroX, const float gyroY, const float gyroZ, const float gravX, const float gravY, const float gravZ, const float sideReductionThreshold = 0.125f);
-
- // gyro calibration functions
- void StartContinuousCalibration();
- void PauseContinuousCalibration();
- void ResetContinuousCalibration();
- void GetCalibrationOffset(float& xOffset, float& yOffset, float& zOffset);
- void SetCalibrationOffset(float xOffset, float yOffset, float zOffset, int weight);
- float GetAutoCalibrationConfidence();
- void SetAutoCalibrationConfidence(float newConfidence);
- bool GetAutoCalibrationIsSteady();
-
- GamepadMotionHelpers::CalibrationMode GetCalibrationMode();
- void SetCalibrationMode(GamepadMotionHelpers::CalibrationMode calibrationMode);
-
- void ResetMotion();
-
- GamepadMotionSettings Settings;
-
-private:
- GamepadMotionHelpers::Vec Gyro;
- GamepadMotionHelpers::Vec RawAccel;
- GamepadMotionHelpers::Motion Motion;
- GamepadMotionHelpers::GyroCalibration GyroCalibration;
- GamepadMotionHelpers::AutoCalibration AutoCalibration;
- GamepadMotionHelpers::CalibrationMode CurrentCalibrationMode;
-
- bool IsCalibrating;
- void PushSensorSamples(float gyroX, float gyroY, float gyroZ, float accelMagnitude);
- void GetCalibratedSensor(float& gyroOffsetX, float& gyroOffsetY, float& gyroOffsetZ, float& accelMagnitude);
-};
-
-///////////// Everything below here are just implementation details /////////////
-
-namespace GamepadMotionHelpers
-{
- inline Quat::Quat()
- {
- w = 1.0f;
- x = 0.0f;
- y = 0.0f;
- z = 0.0f;
- }
-
- inline Quat::Quat(float inW, float inX, float inY, float inZ)
- {
- w = inW;
- x = inX;
- y = inY;
- z = inZ;
- }
-
- inline static Quat AngleAxis(float inAngle, float inX, float inY, float inZ)
- {
- const float sinHalfAngle = sinf(inAngle * 0.5f);
- Vec inAxis = Vec(inX, inY, inZ);
- inAxis.Normalize();
- inAxis *= sinHalfAngle;
- Quat result = Quat(cosf(inAngle * 0.5f), inAxis.x, inAxis.y, inAxis.z);
- return result;
- }
-
- inline void Quat::Set(float inW, float inX, float inY, float inZ)
- {
- w = inW;
- x = inX;
- y = inY;
- z = inZ;
- }
-
- inline Quat& Quat::operator*=(const Quat& rhs)
- {
- Set(w * rhs.w - x * rhs.x - y * rhs.y - z * rhs.z,
- w * rhs.x + x * rhs.w + y * rhs.z - z * rhs.y,
- w * rhs.y - x * rhs.z + y * rhs.w + z * rhs.x,
- w * rhs.z + x * rhs.y - y * rhs.x + z * rhs.w);
- return *this;
- }
-
- inline Quat operator*(Quat lhs, const Quat& rhs)
- {
- lhs *= rhs;
- return lhs;
- }
-
- inline void Quat::Normalize()
- {
- const float length = sqrtf(w * w + x * x + y * y + z * z);
- const float fixFactor = 1.0f / length;
-
- w *= fixFactor;
- x *= fixFactor;
- y *= fixFactor;
- z *= fixFactor;
-
- return;
- }
-
- inline Quat Quat::Normalized() const
- {
- Quat result = *this;
- result.Normalize();
- return result;
- }
-
- inline void Quat::Invert()
- {
- x = -x;
- y = -y;
- z = -z;
- return;
- }
-
- inline Quat Quat::Inverse() const
- {
- Quat result = *this;
- result.Invert();
- return result;
- }
-
- inline Vec::Vec()
- {
- x = 0.0f;
- y = 0.0f;
- z = 0.0f;
- }
-
- inline Vec::Vec(float inValue)
- {
- x = inValue;
- y = inValue;
- z = inValue;
- }
-
- inline Vec::Vec(float inX, float inY, float inZ)
- {
- x = inX;
- y = inY;
- z = inZ;
- }
-
- inline void Vec::Set(float inX, float inY, float inZ)
- {
- x = inX;
- y = inY;
- z = inZ;
- }
-
- inline float Vec::Length() const
- {
- return sqrtf(x * x + y * y + z * z);
- }
-
- inline float Vec::LengthSquared() const
- {
- return x * x + y * y + z * z;
- }
-
- inline void Vec::Normalize()
- {
- const float length = Length();
- if (length == 0.0)
- {
- return;
- }
- const float fixFactor = 1.0f / length;
-
- x *= fixFactor;
- y *= fixFactor;
- z *= fixFactor;
- return;
- }
-
- inline Vec Vec::Normalized() const
- {
- Vec result = *this;
- result.Normalize();
- return result;
- }
-
- inline Vec& Vec::operator+=(const Vec& rhs)
- {
- Set(x + rhs.x, y + rhs.y, z + rhs.z);
- return *this;
- }
-
- inline Vec operator+(Vec lhs, const Vec& rhs)
- {
- lhs += rhs;
- return lhs;
- }
-
- inline Vec& Vec::operator-=(const Vec& rhs)
- {
- Set(x - rhs.x, y - rhs.y, z - rhs.z);
- return *this;
- }
-
- inline Vec operator-(Vec lhs, const Vec& rhs)
- {
- lhs -= rhs;
- return lhs;
- }
-
- inline Vec& Vec::operator*=(const float rhs)
- {
- Set(x * rhs, y * rhs, z * rhs);
- return *this;
- }
-
- inline Vec operator*(Vec lhs, const float rhs)
- {
- lhs *= rhs;
- return lhs;
- }
-
- inline Vec& Vec::operator/=(const float rhs)
- {
- Set(x / rhs, y / rhs, z / rhs);
- return *this;
- }
-
- inline Vec operator/(Vec lhs, const float rhs)
- {
- lhs /= rhs;
- return lhs;
- }
-
- inline Vec& Vec::operator*=(const Quat& rhs)
- {
- Quat temp = rhs * Quat(0.0f, x, y, z) * rhs.Inverse();
- Set(temp.x, temp.y, temp.z);
- return *this;
- }
-
- inline Vec operator*(Vec lhs, const Quat& rhs)
- {
- lhs *= rhs;
- return lhs;
- }
-
- inline Vec Vec::operator-() const
- {
- Vec result = Vec(-x, -y, -z);
- return result;
- }
-
- inline float Vec::Dot(const Vec& other) const
- {
- return x * other.x + y * other.y + z * other.z;
- }
-
- inline Vec Vec::Cross(const Vec& other) const
- {
- return Vec(y * other.z - z * other.y,
- z * other.x - x * other.z,
- x * other.y - y * other.x);
- }
-
- inline Vec Vec::Min(const Vec& other) const
- {
- return Vec(x < other.x ? x : other.x,
- y < other.y ? y : other.y,
- z < other.z ? z : other.z);
- }
-
- inline Vec Vec::Max(const Vec& other) const
- {
- return Vec(x > other.x ? x : other.x,
- y > other.y ? y : other.y,
- z > other.z ? z : other.z);
- }
-
- inline Vec Vec::Abs() const
- {
- return Vec(x > 0 ? x : -x,
- y > 0 ? y : -y,
- z > 0 ? z : -z);
- }
-
- inline Vec Vec::Lerp(const Vec& other, float factor) const
- {
- return *this + (other - *this) * factor;
- }
-
- inline Vec Vec::Lerp(const Vec& other, const Vec& factor) const
- {
- return Vec(this->x + (other.x - this->x) * factor.x,
- this->y + (other.y - this->y) * factor.y,
- this->z + (other.z - this->z) * factor.z);
- }
-
- inline Motion::Motion()
- {
- Reset();
- }
-
- inline void Motion::Reset()
- {
- Quaternion.Set(1.f, 0.f, 0.f, 0.f);
- Accel.Set(0.f, 0.f, 0.f);
- Grav.Set(0.f, 0.f, 0.f);
- SmoothAccel.Set(0.f, 0.f, 0.f);
- Shakiness = 0.f;
- }
-
- ///
- /// The gyro inputs should be calibrated degrees per second but have no other processing. Acceleration is in G units (1 = approx. 9.8m/s^2)
- ///
- inline void Motion::Update(float inGyroX, float inGyroY, float inGyroZ, float inAccelX, float inAccelY, float inAccelZ, float gravityLength, float deltaTime)
- {
- if (!Settings)
- {
- return;
- }
-
- // get settings
- const float gravityCorrectionShakinessMinThreshold = Settings->GravityCorrectionShakinessMinThreshold;
- const float gravityCorrectionShakinessMaxThreshold = Settings->GravityCorrectionShakinessMaxThreshold;
- const float gravityCorrectionStillSpeed = Settings->GravityCorrectionStillSpeed;
- const float gravityCorrectionShakySpeed = Settings->GravityCorrectionShakySpeed;
- const float gravityCorrectionGyroFactor = Settings->GravityCorrectionGyroFactor;
- const float gravityCorrectionGyroMinThreshold = Settings->GravityCorrectionGyroMinThreshold;
- const float gravityCorrectionGyroMaxThreshold = Settings->GravityCorrectionGyroMaxThreshold;
- const float gravityCorrectionMinimumSpeed = Settings->GravityCorrectionMinimumSpeed;
-
- const Vec axis = Vec(inGyroX, inGyroY, inGyroZ);
- const Vec accel = Vec(inAccelX, inAccelY, inAccelZ);
- const float angleSpeed = axis.Length() * (float)M_PI / 180.0f;
- const float angle = angleSpeed * deltaTime;
-
- // rotate
- Quat rotation = AngleAxis(angle, axis.x, axis.y, axis.z);
- Quaternion *= rotation; // do it this way because it's a local rotation, not global
-
- //printf("Quat: %.4f %.4f %.4f %.4f\n",
- // Quaternion.w, Quaternion.x, Quaternion.y, Quaternion.z);
- float accelMagnitude = accel.Length();
- if (accelMagnitude > 0.0f)
- {
- const Vec accelNorm = accel / accelMagnitude;
- // account for rotation when tracking smoothed acceleration
- SmoothAccel *= rotation.Inverse();
- //printf("Absolute Accel: %.4f %.4f %.4f\n",
- // absoluteAccel.x, absoluteAccel.y, absoluteAccel.z);
- const float smoothFactor = ShortSteadinessHalfTime <= 0.f ? 0.f : exp2f(-deltaTime / ShortSteadinessHalfTime);
- Shakiness *= smoothFactor;
- Shakiness = std::max(Shakiness, (accel - SmoothAccel).Length());
- SmoothAccel = accel.Lerp(SmoothAccel, smoothFactor);
-
- //printf("Shakiness: %.4f\n", Shakiness);
-
- // update grav by rotation
- Grav *= rotation.Inverse();
- // we want to close the gap between grav and raw acceleration. What's the difference
- const Vec gravToAccel = (accelNorm * -gravityLength) - Grav;
- const Vec gravToAccelDir = gravToAccel.Normalized();
- // adjustment rate
- float gravCorrectionSpeed;
- if (gravityCorrectionShakinessMinThreshold < gravityCorrectionShakinessMaxThreshold)
- {
- gravCorrectionSpeed = gravityCorrectionStillSpeed + (gravityCorrectionShakySpeed - gravityCorrectionStillSpeed) * std::clamp((Shakiness - gravityCorrectionShakinessMinThreshold) / (gravityCorrectionShakinessMaxThreshold - gravityCorrectionShakinessMinThreshold), 0.f, 1.f);
- }
- else
- {
- gravCorrectionSpeed = Shakiness < gravityCorrectionShakinessMaxThreshold ? gravityCorrectionStillSpeed : gravityCorrectionShakySpeed;
- }
- // we also limit it to be no faster than a given proportion of the gyro rate, or the minimum gravity correction speed
- const float gyroGravCorrectionLimit = std::max(angleSpeed * gravityCorrectionGyroFactor, gravityCorrectionMinimumSpeed);
- if (gravCorrectionSpeed > gyroGravCorrectionLimit)
- {
- float closeEnoughFactor;
- if (gravityCorrectionGyroMinThreshold < gravityCorrectionGyroMaxThreshold)
- {
- closeEnoughFactor = std::clamp((gravToAccel.Length() - gravityCorrectionGyroMinThreshold) / (gravityCorrectionGyroMaxThreshold - gravityCorrectionGyroMinThreshold), 0.f, 1.f);
- }
- else
- {
- closeEnoughFactor = gravToAccel.Length() < gravityCorrectionGyroMaxThreshold ? 0.f : 1.f;
- }
- gravCorrectionSpeed = gyroGravCorrectionLimit + (gravCorrectionSpeed - gyroGravCorrectionLimit) * closeEnoughFactor;
- }
- const Vec gravToAccelDelta = gravToAccelDir * gravCorrectionSpeed * deltaTime;
- if (gravToAccelDelta.LengthSquared() < gravToAccel.LengthSquared())
- {
- Grav += gravToAccelDelta;
- }
- else
- {
- Grav = accelNorm * -gravityLength;
- }
-
- const Vec gravityDirection = Grav.Normalized() * Quaternion.Inverse(); // absolute gravity direction
- const float errorAngle = acosf(std::clamp(Vec(0.0f, -1.0f, 0.0f).Dot(gravityDirection), -1.f, 1.f));
- const Vec flattened = Vec(0.0f, -1.0f, 0.0f).Cross(gravityDirection);
- Quat correctionQuat = AngleAxis(errorAngle, flattened.x, flattened.y, flattened.z);
- Quaternion = Quaternion * correctionQuat;
-
- Accel = accel + Grav;
- }
- else
- {
- Grav *= rotation.Inverse();
- Accel = Grav;
- }
- Quaternion.Normalize();
- }
-
- inline void Motion::SetSettings(GamepadMotionSettings* settings)
- {
- Settings = settings;
- }
-
- inline SensorMinMaxWindow::SensorMinMaxWindow()
- {
- Reset(0.f);
- }
-
- inline void SensorMinMaxWindow::Reset(float remainder)
- {
- NumSamples = 0;
- TimeSampled = remainder;
- }
-
- inline void SensorMinMaxWindow::AddSample(const Vec& inGyro, const Vec& inAccel, float deltaTime)
- {
- if (NumSamples == 0)
- {
- MaxGyro = inGyro;
- MinGyro = inGyro;
- MeanGyro = inGyro;
- MaxAccel = inAccel;
- MinAccel = inAccel;
- MeanAccel = inAccel;
- StartAccel = inAccel;
- NumSamples = 1;
- TimeSampled += deltaTime;
- return;
- }
-
- MaxGyro = MaxGyro.Max(inGyro);
- MinGyro = MinGyro.Min(inGyro);
- MaxAccel = MaxAccel.Max(inAccel);
- MinAccel = MinAccel.Min(inAccel);
-
- NumSamples++;
- TimeSampled += deltaTime;
-
- Vec delta = inGyro - MeanGyro;
- MeanGyro += delta * (1.f / NumSamples);
- delta = inAccel - MeanAccel;
- MeanAccel += delta * (1.f / NumSamples);
- }
-
- inline Vec SensorMinMaxWindow::GetMidGyro()
- {
- return MeanGyro;
- }
-
- inline AutoCalibration::AutoCalibration()
- {
- CalibrationData = nullptr;
- Reset();
- }
-
- inline void AutoCalibration::Reset()
- {
- MinMaxWindow.Reset(0.f);
- Confidence = 0.f;
- bIsSteady = false;
- MinDeltaGyro = Vec(1.f);
- MinDeltaAccel = Vec(0.25f);
- RecalibrateThreshold = 1.f;
- SensorFusionSkippedTime = 0.f;
- TimeSteadySensorFusion = 0.f;
- TimeSteadyStillness = 0.f;
- }
-
- inline bool AutoCalibration::AddSampleStillness(const Vec& inGyro, const Vec& inAccel, float deltaTime, bool doSensorFusion)
- {
- if (inGyro.x == 0.f && inGyro.y == 0.f && inGyro.z == 0.f &&
- inAccel.x == 0.f && inAccel.y == 0.f && inAccel.z == 0.f)
- {
- // zeroes are almost certainly not valid inputs
- return false;
- }
-
- if (!Settings)
- {
- return false;
- }
-
- if (!CalibrationData)
- {
- return false;
- }
-
- // get settings
- const int minStillnessSamples = Settings->MinStillnessSamples;
- const float minStillnessCollectionTime = Settings->MinStillnessCollectionTime;
- const float minStillnessCorrectionTime = Settings->MinStillnessCorrectionTime;
- const float maxStillnessError = Settings->MaxStillnessError;
- const float stillnessSampleDeteriorationRate = Settings->StillnessSampleDeteriorationRate;
- const float stillnessErrorClimbRate = Settings->StillnessErrorClimbRate;
- const float stillnessErrorDropOnRecalibrate = Settings->StillnessErrorDropOnRecalibrate;
- const float stillnessCalibrationEaseInTime = Settings->StillnessCalibrationEaseInTime;
- const float stillnessCalibrationHalfTime = Settings->StillnessCalibrationHalfTime * Confidence;
- const float stillnessConfidenceRate = Settings->StillnessConfidenceRate;
- const float stillnessGyroDelta = Settings->StillnessGyroDelta;
- const float stillnessAccelDelta = Settings->StillnessAccelDelta;
-
- MinMaxWindow.AddSample(inGyro, inAccel, deltaTime);
- // get deltas
- const Vec gyroDelta = MinMaxWindow.MaxGyro - MinMaxWindow.MinGyro;
- const Vec accelDelta = MinMaxWindow.MaxAccel - MinMaxWindow.MinAccel;
-
- bool calibrated = false;
- bool isSteady = false;
- const Vec climbThisTick = Vec(stillnessSampleDeteriorationRate * deltaTime);
- if (stillnessGyroDelta < 0.f)
- {
- if (Confidence < 1.f)
- {
- MinDeltaGyro += climbThisTick;
- }
- }
- else
- {
- MinDeltaGyro = Vec(stillnessGyroDelta);
- }
- if (stillnessAccelDelta < 0.f)
- {
- if (Confidence < 1.f)
- {
- MinDeltaAccel += climbThisTick;
- }
- }
- else
- {
- MinDeltaAccel = Vec(stillnessAccelDelta);
- }
-
- //printf("Deltas: %.4f %.4f %.4f; %.4f %.4f %.4f\n",
- // gyroDelta.x, gyroDelta.y, gyroDelta.z,
- // accelDelta.x, accelDelta.y, accelDelta.z);
-
- if (MinMaxWindow.NumSamples >= minStillnessSamples && MinMaxWindow.TimeSampled >= minStillnessCollectionTime)
- {
- MinDeltaGyro = MinDeltaGyro.Min(gyroDelta);
- MinDeltaAccel = MinDeltaAccel.Min(accelDelta);
- }
- else
- {
- RecalibrateThreshold = std::min(RecalibrateThreshold + stillnessErrorClimbRate * deltaTime, maxStillnessError);
- return false;
- }
-
- // check that all inputs are below appropriate thresholds to be considered "still"
- if (gyroDelta.x <= MinDeltaGyro.x * RecalibrateThreshold &&
- gyroDelta.y <= MinDeltaGyro.y * RecalibrateThreshold &&
- gyroDelta.z <= MinDeltaGyro.z * RecalibrateThreshold &&
- accelDelta.x <= MinDeltaAccel.x * RecalibrateThreshold &&
- accelDelta.y <= MinDeltaAccel.y * RecalibrateThreshold &&
- accelDelta.z <= MinDeltaAccel.z * RecalibrateThreshold)
- {
- if (MinMaxWindow.NumSamples >= minStillnessSamples && MinMaxWindow.TimeSampled >= minStillnessCorrectionTime)
- {
- /*if (TimeSteadyStillness == 0.f)
- {
- printf("Still!\n");
- }/**/
-
- TimeSteadyStillness = std::min(TimeSteadyStillness + deltaTime, stillnessCalibrationEaseInTime);
- const float calibrationEaseIn = stillnessCalibrationEaseInTime <= 0.f ? 1.f : TimeSteadyStillness / stillnessCalibrationEaseInTime;
-
- const Vec calibratedGyro = MinMaxWindow.GetMidGyro();
-
- const Vec oldGyroBias = Vec(CalibrationData->X, CalibrationData->Y, CalibrationData->Z) / std::max((float)CalibrationData->NumSamples, 1.f);
- const float stillnessLerpFactor = stillnessCalibrationHalfTime <= 0.f ? 0.f : exp2f(-calibrationEaseIn * deltaTime / stillnessCalibrationHalfTime);
- Vec newGyroBias = calibratedGyro.Lerp(oldGyroBias, stillnessLerpFactor);
- Confidence = std::min(Confidence + deltaTime * stillnessConfidenceRate, 1.f);
- isSteady = true;
-
- if (doSensorFusion)
- {
- const Vec previousNormal = MinMaxWindow.StartAccel.Normalized();
- const Vec thisNormal = inAccel.Normalized();
- Vec angularVelocity = thisNormal.Cross(previousNormal);
- const float crossLength = angularVelocity.Length();
- if (crossLength > 0.f)
- {
- const float thisDotPrev = std::clamp(thisNormal.Dot(previousNormal), -1.f, 1.f);
- const float angleChange = acosf(thisDotPrev) * 180.0f / (float)M_PI;
- const float anglePerSecond = angleChange / MinMaxWindow.TimeSampled;
- angularVelocity *= anglePerSecond / crossLength;
- }
-
- Vec axisCalibrationStrength = thisNormal.Abs();
- Vec sensorFusionBias = (calibratedGyro - angularVelocity).Lerp(oldGyroBias, stillnessLerpFactor);
- if (axisCalibrationStrength.x <= 0.7f)
- {
- newGyroBias.x = sensorFusionBias.x;
- }
- if (axisCalibrationStrength.y <= 0.7f)
- {
- newGyroBias.y = sensorFusionBias.y;
- }
- if (axisCalibrationStrength.z <= 0.7f)
- {
- newGyroBias.z = sensorFusionBias.z;
- }
- }
-
- CalibrationData->X = newGyroBias.x;
- CalibrationData->Y = newGyroBias.y;
- CalibrationData->Z = newGyroBias.z;
-
- CalibrationData->AccelMagnitude = MinMaxWindow.MeanAccel.Length();
- CalibrationData->NumSamples = 1;
-
- calibrated = true;
- }
- else
- {
- RecalibrateThreshold = std::min(RecalibrateThreshold + stillnessErrorClimbRate * deltaTime, maxStillnessError);
- }
- }
- else if (TimeSteadyStillness > 0.f)
- {
- //printf("Moved!\n");
- RecalibrateThreshold -= stillnessErrorDropOnRecalibrate;
- if (RecalibrateThreshold < 1.f) RecalibrateThreshold = 1.f;
-
- TimeSteadyStillness = 0.f;
- MinMaxWindow.Reset(0.f);
- }
- else
- {
- RecalibrateThreshold = std::min(RecalibrateThreshold + stillnessErrorClimbRate * deltaTime, maxStillnessError);
- MinMaxWindow.Reset(0.f);
- }
-
- bIsSteady = isSteady;
- return calibrated;
- }
-
- inline void AutoCalibration::NoSampleStillness()
- {
- MinMaxWindow.Reset(0.f);
- }
-
- inline bool AutoCalibration::AddSampleSensorFusion(const Vec& inGyro, const Vec& inAccel, float deltaTime)
- {
- if (deltaTime <= 0.f)
- {
- return false;
- }
-
- if (inGyro.x == 0.f && inGyro.y == 0.f && inGyro.z == 0.f &&
- inAccel.x == 0.f && inAccel.y == 0.f && inAccel.z == 0.f)
- {
- // all zeroes are almost certainly not valid inputs
- TimeSteadySensorFusion = 0.f;
- SensorFusionSkippedTime = 0.f;
- PreviousAccel = inAccel;
- SmoothedPreviousAccel = inAccel;
- SmoothedAngularVelocityGyro = GamepadMotionHelpers::Vec();
- SmoothedAngularVelocityAccel = GamepadMotionHelpers::Vec();
- return false;
- }
-
- if (PreviousAccel.x == 0.f && PreviousAccel.y == 0.f && PreviousAccel.z == 0.f)
- {
- TimeSteadySensorFusion = 0.f;
- SensorFusionSkippedTime = 0.f;
- PreviousAccel = inAccel;
- SmoothedPreviousAccel = inAccel;
- SmoothedAngularVelocityGyro = GamepadMotionHelpers::Vec();
- SmoothedAngularVelocityAccel = GamepadMotionHelpers::Vec();
- return false;
- }
-
- // in case the controller state hasn't updated between samples
- if (inAccel.x == PreviousAccel.x && inAccel.y == PreviousAccel.y && inAccel.z == PreviousAccel.z)
- {
- SensorFusionSkippedTime += deltaTime;
- return false;
- }
-
- if (!Settings)
- {
- return false;
- }
-
- // get settings
- const float sensorFusionCalibrationSmoothingStrength = Settings->SensorFusionCalibrationSmoothingStrength;
- const float sensorFusionAngularAccelerationThreshold = Settings->SensorFusionAngularAccelerationThreshold;
- const float sensorFusionCalibrationEaseInTime = Settings->SensorFusionCalibrationEaseInTime;
- const float sensorFusionCalibrationHalfTime = Settings->SensorFusionCalibrationHalfTime * Confidence;
- const float sensorFusionConfidenceRate = Settings->SensorFusionConfidenceRate;
-
- deltaTime += SensorFusionSkippedTime;
- SensorFusionSkippedTime = 0.f;
- bool calibrated = false;
- bool isSteady = false;
-
- // framerate independent lerp smoothing: https://www.gamasutra.com/blogs/ScottLembcke/20180404/316046/Improved_Lerp_Smoothing.php
- const float smoothingLerpFactor = exp2f(-sensorFusionCalibrationSmoothingStrength * deltaTime);
- // velocity from smoothed accel matches better if we also smooth gyro
- const Vec previousGyro = SmoothedAngularVelocityGyro;
- SmoothedAngularVelocityGyro = inGyro.Lerp(SmoothedAngularVelocityGyro, smoothingLerpFactor); // smooth what remains
- const float gyroAccelerationMag = (SmoothedAngularVelocityGyro - previousGyro).Length() / deltaTime;
- // get angle between old and new accel
- const Vec previousNormal = SmoothedPreviousAccel.Normalized();
- const Vec thisAccel = inAccel.Lerp(SmoothedPreviousAccel, smoothingLerpFactor);
- const Vec thisNormal = thisAccel.Normalized();
- Vec angularVelocity = thisNormal.Cross(previousNormal);
- const float crossLength = angularVelocity.Length();
- if (crossLength > 0.f)
- {
- const float thisDotPrev = std::clamp(thisNormal.Dot(previousNormal), -1.f, 1.f);
- const float angleChange = acosf(thisDotPrev) * 180.0f / (float)M_PI;
- const float anglePerSecond = angleChange / deltaTime;
- angularVelocity *= anglePerSecond / crossLength;
- }
- SmoothedAngularVelocityAccel = angularVelocity;
-
- // apply corrections
- if (gyroAccelerationMag > sensorFusionAngularAccelerationThreshold || CalibrationData == nullptr)
- {
- /*if (TimeSteadySensorFusion > 0.f)
- {
- printf("Shaken!\n");
- }/**/
- TimeSteadySensorFusion = 0.f;
- //printf("No calibration due to acceleration of %.4f\n", gyroAccelerationMag);
- }
- else
- {
- /*if (TimeSteadySensorFusion == 0.f)
- {
- printf("Steady!\n");
- }/**/
-
- TimeSteadySensorFusion = std::min(TimeSteadySensorFusion + deltaTime, sensorFusionCalibrationEaseInTime);
- const float calibrationEaseIn = sensorFusionCalibrationEaseInTime <= 0.f ? 1.f : TimeSteadySensorFusion / sensorFusionCalibrationEaseInTime;
- const Vec oldGyroBias = Vec(CalibrationData->X, CalibrationData->Y, CalibrationData->Z) / std::max((float)CalibrationData->NumSamples, 1.f);
- // recalibrate over time proportional to the difference between the calculated bias and the current assumed bias
- const float sensorFusionLerpFactor = sensorFusionCalibrationHalfTime <= 0.f ? 0.f : exp2f(-calibrationEaseIn * deltaTime / sensorFusionCalibrationHalfTime);
- Vec newGyroBias = (SmoothedAngularVelocityGyro - SmoothedAngularVelocityAccel).Lerp(oldGyroBias, sensorFusionLerpFactor);
- Confidence = std::min(Confidence + deltaTime * sensorFusionConfidenceRate, 1.f);
- isSteady = true;
- // don't change bias in axes that can't be affected by the gravity direction
- Vec axisCalibrationStrength = thisNormal.Abs();
- if (axisCalibrationStrength.x > 0.7f)
- {
- axisCalibrationStrength.x = 1.f;
- }
- if (axisCalibrationStrength.y > 0.7f)
- {
- axisCalibrationStrength.y = 1.f;
- }
- if (axisCalibrationStrength.z > 0.7f)
- {
- axisCalibrationStrength.z = 1.f;
- }
- newGyroBias = newGyroBias.Lerp(oldGyroBias, axisCalibrationStrength.Min(Vec(1.f)));
-
- CalibrationData->X = newGyroBias.x;
- CalibrationData->Y = newGyroBias.y;
- CalibrationData->Z = newGyroBias.z;
-
- CalibrationData->AccelMagnitude = thisAccel.Length();
-
- CalibrationData->NumSamples = 1;
-
- calibrated = true;
-
- //printf("Recalibrating at a strength of %.4f\n", calibrationEaseIn);
- }
-
- SmoothedPreviousAccel = thisAccel;
- PreviousAccel = inAccel;
-
- //printf("Gyro: %.4f, %.4f, %.4f | Accel: %.4f, %.4f, %.4f\n",
- // SmoothedAngularVelocityGyro.x, SmoothedAngularVelocityGyro.y, SmoothedAngularVelocityGyro.z,
- // SmoothedAngularVelocityAccel.x, SmoothedAngularVelocityAccel.y, SmoothedAngularVelocityAccel.z);
-
- bIsSteady = isSteady;
-
- return calibrated;
- }
-
- inline void AutoCalibration::NoSampleSensorFusion()
- {
- TimeSteadySensorFusion = 0.f;
- SensorFusionSkippedTime = 0.f;
- PreviousAccel = GamepadMotionHelpers::Vec();
- SmoothedPreviousAccel = GamepadMotionHelpers::Vec();
- SmoothedAngularVelocityGyro = GamepadMotionHelpers::Vec();
- SmoothedAngularVelocityAccel = GamepadMotionHelpers::Vec();
- }
-
- inline void AutoCalibration::SetCalibrationData(GyroCalibration* calibrationData)
- {
- CalibrationData = calibrationData;
- }
-
- inline void AutoCalibration::SetSettings(GamepadMotionSettings* settings)
- {
- Settings = settings;
- }
-
-} // namespace GamepadMotionHelpers
-
-inline GamepadMotion::GamepadMotion()
-{
- IsCalibrating = false;
- CurrentCalibrationMode = GamepadMotionHelpers::CalibrationMode::Manual;
- Reset();
- AutoCalibration.SetCalibrationData(&GyroCalibration);
- AutoCalibration.SetSettings(&Settings);
- Motion.SetSettings(&Settings);
-}
-
-inline void GamepadMotion::Reset()
-{
- GyroCalibration = {};
- Gyro = {};
- RawAccel = {};
- Settings = GamepadMotionSettings();
- Motion.Reset();
-}
-
-inline void GamepadMotion::ProcessMotion(float gyroX, float gyroY, float gyroZ,
- float accelX, float accelY, float accelZ, float deltaTime)
-{
- if (gyroX == 0.f && gyroY == 0.f && gyroZ == 0.f &&
- accelX == 0.f && accelY == 0.f && accelZ == 0.f)
- {
- // all zeroes are almost certainly not valid inputs
- return;
- }
-
- float accelMagnitude = sqrtf(accelX * accelX + accelY * accelY + accelZ * accelZ);
-
- if (IsCalibrating)
- {
- // manual calibration
- PushSensorSamples(gyroX, gyroY, gyroZ, accelMagnitude);
- AutoCalibration.NoSampleSensorFusion();
- AutoCalibration.NoSampleStillness();
- }
- else if (CurrentCalibrationMode & GamepadMotionHelpers::CalibrationMode::Stillness)
- {
- AutoCalibration.AddSampleStillness(GamepadMotionHelpers::Vec(gyroX, gyroY, gyroZ), GamepadMotionHelpers::Vec(accelX, accelY, accelZ), deltaTime, CurrentCalibrationMode & GamepadMotionHelpers::CalibrationMode::SensorFusion);
- AutoCalibration.NoSampleSensorFusion();
- }
- else
- {
- AutoCalibration.NoSampleStillness();
- if (CurrentCalibrationMode & GamepadMotionHelpers::CalibrationMode::SensorFusion)
- {
- AutoCalibration.AddSampleSensorFusion(GamepadMotionHelpers::Vec(gyroX, gyroY, gyroZ), GamepadMotionHelpers::Vec(accelX, accelY, accelZ), deltaTime);
- }
- else
- {
- AutoCalibration.NoSampleSensorFusion();
- }
- }
-
- float gyroOffsetX, gyroOffsetY, gyroOffsetZ;
- GetCalibratedSensor(gyroOffsetX, gyroOffsetY, gyroOffsetZ, accelMagnitude);
-
- gyroX -= gyroOffsetX;
- gyroY -= gyroOffsetY;
- gyroZ -= gyroOffsetZ;
-
- Motion.Update(gyroX, gyroY, gyroZ, accelX, accelY, accelZ, accelMagnitude, deltaTime);
-
- Gyro.x = gyroX;
- Gyro.y = gyroY;
- Gyro.z = gyroZ;
- RawAccel.x = accelX;
- RawAccel.y = accelY;
- RawAccel.z = accelZ;
-}
-
-// reading the current state
-inline void GamepadMotion::GetCalibratedGyro(float& x, float& y, float& z)
-{
- x = Gyro.x;
- y = Gyro.y;
- z = Gyro.z;
-}
-
-inline void GamepadMotion::GetGravity(float& x, float& y, float& z)
-{
- x = Motion.Grav.x;
- y = Motion.Grav.y;
- z = Motion.Grav.z;
-}
-
-inline void GamepadMotion::GetProcessedAcceleration(float& x, float& y, float& z)
-{
- x = Motion.Accel.x;
- y = Motion.Accel.y;
- z = Motion.Accel.z;
-}
-
-inline void GamepadMotion::GetOrientation(float& w, float& x, float& y, float& z)
-{
- w = Motion.Quaternion.w;
- x = Motion.Quaternion.x;
- y = Motion.Quaternion.y;
- z = Motion.Quaternion.z;
-}
-
-inline void GamepadMotion::GetPlayerSpaceGyro(float& x, float& y, const float yawRelaxFactor)
-{
- CalculatePlayerSpaceGyro(x, y, Gyro.x, Gyro.y, Gyro.z, Motion.Grav.x, Motion.Grav.y, Motion.Grav.z, yawRelaxFactor);
-}
-
-inline void GamepadMotion::CalculatePlayerSpaceGyro(float& x, float& y, const float gyroX, const float gyroY, const float gyroZ, const float gravX, const float gravY, const float gravZ, const float yawRelaxFactor)
-{
- // take gravity into account without taking on any error from gravity. Explained in depth at http://gyrowiki.jibbsmart.com/blog:player-space-gyro-and-alternatives-explained#toc7
- const float worldYaw = -(gravY * gyroY + gravZ * gyroZ);
- const float worldYawSign = worldYaw < 0.f ? -1.f : 1.f;
- y = worldYawSign * std::min(std::abs(worldYaw) * yawRelaxFactor, sqrtf(gyroY * gyroY + gyroZ * gyroZ));
- x = gyroX;
-}
-
-inline void GamepadMotion::GetWorldSpaceGyro(float& x, float& y, const float sideReductionThreshold)
-{
- CalculateWorldSpaceGyro(x, y, Gyro.x, Gyro.y, Gyro.z, Motion.Grav.x, Motion.Grav.y, Motion.Grav.z, sideReductionThreshold);
-}
-
-inline void GamepadMotion::CalculateWorldSpaceGyro(float& x, float& y, const float gyroX, const float gyroY, const float gyroZ, const float gravX, const float gravY, const float gravZ, const float sideReductionThreshold)
-{
- // use the gravity direction as the yaw axis, and derive an appropriate pitch axis. Explained in depth at http://gyrowiki.jibbsmart.com/blog:player-space-gyro-and-alternatives-explained#toc6
- const float worldYaw = -gravX * gyroX - gravY * gyroY - gravZ * gyroZ;
- // project local pitch axis (X) onto gravity plane
- const float gravDotPitchAxis = gravX;
- GamepadMotionHelpers::Vec pitchAxis(1.f - gravX * gravDotPitchAxis,
- -gravY * gravDotPitchAxis,
- -gravZ * gravDotPitchAxis);
- // normalize
- const float pitchAxisLengthSquared = pitchAxis.LengthSquared();
- if (pitchAxisLengthSquared > 0.f)
- {
- const float pitchAxisLength = sqrtf(pitchAxisLengthSquared);
- const float lengthReciprocal = 1.f / pitchAxisLength;
- pitchAxis *= lengthReciprocal;
-
- const float flatness = std::abs(gravY);
- const float upness = std::abs(gravZ);
- const float sideReduction = sideReductionThreshold <= 0.f ? 1.f : std::clamp((std::max(flatness, upness) - sideReductionThreshold) / sideReductionThreshold, 0.f, 1.f);
-
- x = sideReduction * pitchAxis.Dot(GamepadMotionHelpers::Vec(gyroX, gyroY, gyroZ));
- }
- else
- {
- x = 0.f;
- }
-
- y = worldYaw;
-}
-
-// gyro calibration functions
-inline void GamepadMotion::StartContinuousCalibration()
-{
- IsCalibrating = true;
-}
-
-inline void GamepadMotion::PauseContinuousCalibration()
-{
- IsCalibrating = false;
-}
-
-inline void GamepadMotion::ResetContinuousCalibration()
-{
- GyroCalibration = {};
- AutoCalibration.Reset();
-}
-
-inline void GamepadMotion::GetCalibrationOffset(float& xOffset, float& yOffset, float& zOffset)
-{
- float accelMagnitude;
- GetCalibratedSensor(xOffset, yOffset, zOffset, accelMagnitude);
-}
-
-inline void GamepadMotion::SetCalibrationOffset(float xOffset, float yOffset, float zOffset, int weight)
-{
- if (GyroCalibration.NumSamples > 1)
- {
- GyroCalibration.AccelMagnitude *= ((float)weight) / GyroCalibration.NumSamples;
- }
- else
- {
- GyroCalibration.AccelMagnitude = (float)weight;
- }
-
- GyroCalibration.NumSamples = weight;
- GyroCalibration.X = xOffset * weight;
- GyroCalibration.Y = yOffset * weight;
- GyroCalibration.Z = zOffset * weight;
-}
-
-inline float GamepadMotion::GetAutoCalibrationConfidence()
-{
- return AutoCalibration.Confidence;
-}
-
-inline void GamepadMotion::SetAutoCalibrationConfidence(float newConfidence)
-{
- AutoCalibration.Confidence = newConfidence;
-}
-
-inline bool GamepadMotion::GetAutoCalibrationIsSteady()
-{
- return AutoCalibration.IsSteady();
-}
-
-inline GamepadMotionHelpers::CalibrationMode GamepadMotion::GetCalibrationMode()
-{
- return CurrentCalibrationMode;
-}
-
-inline void GamepadMotion::SetCalibrationMode(GamepadMotionHelpers::CalibrationMode calibrationMode)
-{
- CurrentCalibrationMode = calibrationMode;
-}
-
-inline void GamepadMotion::ResetMotion()
-{
- Motion.Reset();
-}
-
-// Private Methods
-
-inline void GamepadMotion::PushSensorSamples(float gyroX, float gyroY, float gyroZ, float accelMagnitude)
-{
- // accumulate
- GyroCalibration.NumSamples++;
- GyroCalibration.X += gyroX;
- GyroCalibration.Y += gyroY;
- GyroCalibration.Z += gyroZ;
- GyroCalibration.AccelMagnitude += accelMagnitude;
-}
-
-inline void GamepadMotion::GetCalibratedSensor(float& gyroOffsetX, float& gyroOffsetY, float& gyroOffsetZ, float& accelMagnitude)
-{
- if (GyroCalibration.NumSamples <= 0)
- {
- gyroOffsetX = 0.f;
- gyroOffsetY = 0.f;
- gyroOffsetZ = 0.f;
- accelMagnitude = 1.f;
- return;
- }
-
- const float inverseSamples = 1.f / GyroCalibration.NumSamples;
- gyroOffsetX = GyroCalibration.X * inverseSamples;
- gyroOffsetY = GyroCalibration.Y * inverseSamples;
- gyroOffsetZ = GyroCalibration.Z * inverseSamples;
- accelMagnitude = GyroCalibration.AccelMagnitude * inverseSamples;
-}
diff --git a/lib/GamepadMotionHelpers/LICENSE b/lib/GamepadMotionHelpers/LICENSE
deleted file mode 100644
index a46396a..0000000
--- a/lib/GamepadMotionHelpers/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2020-2023 Julian "Jibb" Smart
-
-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/lib/GamepadMotionHelpers/README.md b/lib/GamepadMotionHelpers/README.md
deleted file mode 100644
index c5c1bc9..0000000
--- a/lib/GamepadMotionHelpers/README.md
+++ /dev/null
@@ -1,76 +0,0 @@
-# GamepadMotionHelpers
-GamepadMotionHelpers is a lightweight header-only library for sensor fusion, gyro calibration, etc. BYO input library (eg [SDL2](https://github.com/libsdl-org/SDL)).
-
-## Units
-Convert your gyro units into **degrees per second** and accelerometer units to **g-force** (1 g = 9.8 m/s^2). You don't have to use these units in your application, but convert to these units when writing to GamepadMotionHelpers and convert back when reading from it. Your input reader might prefer radians per second and metres per second squared, but the datasheets for every IMU I've seen talk about degrees per second and g-force.
-
-## Coordinate Space
-This library uses a Y-up coordinate system. While Z-up is (only slightly) preferable for many games, PlayStation controllers use Y-up, and have set the standard for input libraries like [SDL2](https://github.com/libsdl-org/SDL) and [JSL](https://github.com/JibbSmart/JoyShockLibrary). These libraries convert inputs from other controller types to the same space used by PlayStation's DualShock 4 and DualSense, so that's what's used here.
-
-## Basic Use
-Include the GamepadMotion.hpp file in your C++ project. That's it! Everything you need is in that file, and its only dependency is ``````.
-
-For each controller with gyro (and optionally accelerometer), create a ```GamepadMotion``` object. At regular intervals, whether when a new report comes in from the controller or when polling the controller's state, you should call ```ProcessMotion(...)```. This is when you tell your GamepadMotion object the latest gyro (in degrees per second) and accelerometer (in g-force) inputs. You'll also give it the time since the last update for this controller (in seconds).
-
-ProcessMotion takes these inputs, updates some internal values, and then you can use any of the following to read its current state:
-- ```GetCalibratedGyro(float& x, float& y, float& z)``` - Get the controller's angular velocity in degrees per second. This is just the raw gyro you gave it minus the gyro's bias as determined by your calibration settings (more on that below).
-- ```GetGravity(float& x, float& y, float& z)``` - Get the gravity direction in the controller's local space. When the controller is still on a flat surface it'll be approximately (0, -1, 0). The controller can't detect the gravity direction when it's in freefall or being shaken around, but it can make a pretty good guess if its gyro is correctly calibrated and then make further corrections when the controller is still again.
-- ```GetProcessedAcceleration(float& x, float& y, float& z)``` - Get the controller's current acceleration in g-force with gravity removed. Raw accelerometer input includes gravity -- it is only (0, 0, 0) when the controller is in freefall. However, using the gravity direction as calculated for GetGravity, it can remove that component and detect how you're shaking the controller about. This function gives you that acceleration vector with the gravity removed.
-- ```GetOrientation(float& w, float& x, float& y, float& z)``` - Get the controller's orientation. Gyro and accelerometer input are combined to give a good estimate of the controller's orientation.
-
-Additional helper functions are available for taking gravity into account and returning a "world space" or "player space" rotation in two axes. Bear in mind that the **X** and **Y** set by these functions is still around the controller's axes. This means **Y** is the *horizontal* part of the rotation, and **X** is the vertical part. To convert to a mouse-like input, you'll treat the **Y** as the horizontal or yaw input and **X** as the vertical or pitch input. This might be unintuitive, but since it's also true of the "local space" angular velocities obtained from GetCalibratedGyro, this makes it simple to let the user choose between *local space*, *world space*, and *player space* in your game or application by just swapping GetCalibratedGyro for these functions depending on that selection:
-- ```GetWorldSpaceGyro(float& x, float& y, const float sideReductionThreshold = 0.125f)``` - Get the controller's angular velocity in *world space* as described on GyroWiki in the [player space article here](http://gyrowiki.jibbsmart.com/blog:player-space-gyro-and-alternatives-explained#toc6). Yaw input will be derived from motion around the gravity axis, and pitch input from an appropriate pitch axis calculated from the controller's orientation with respect to the gravity axis. Any errors in the calculated gravity axis (though likely very small) will be taken on by the calculated world space gyro rotation, making it slightly less robust than using calibrated gyro directly ("local space" gyro) or using *player space* gyro below. More info in the linked article.
-- ```GetPlayerSpaceGyro(float& x, float& y, const float yawRelaxFactor = 1.41f)``` - Get the controller's angular velocity in *player space* as described on GyroWiki in the [player space article here](http://gyrowiki.jibbsmart.com/blog:player-space-gyro-and-alternatives-explained#toc7). Yaw input will be derived from motion approximately around the gravity axis, without any impact from errors in the gravity calculation. Pitch is just local pitch. It is robust, accommodates players who are used to both local space and world space gyro, while taking on most of the advantages of each. It is proven in popular games and is an ideal default for players using a standalone controller. For handheld (where the screen is part of the controller, such as mobile, Switch, or Steam Deck) local space (using the calibrated gyro input directly) may be preferable. More info in the linked article.
-
-If you want to plug in the gyro and gravity values yourself (perhaps you're using an externally calculated gravity), you can use ```CalculateWorldSpaceGyro``` and ```CalculatePlayerSpaceGyro``` instead. Make sure you use this GamepadMotionHelpers' coordinate space, units, and gravity is normalized, since those are all assumed for these functions.
-
-## Sensor Fusion
-Combining multiple types of sensor like this to get a better picture of the controller's state is called "sensor fusion". Moment-to-moment changes in orientation are detected using the gyro, but that only gives local angular velocity and needs to be correctly calibrated. Errors can accumulate over time. The gravity vector as detected by the accelerometer is used to make corrections to the relevant components of the controller's orientation.
-
-But this cannot be used to correct the controller's orientation around the gravity vector (the **yaw** axis). If you're using the controller's absolute orientation for some reason, this "yaw drift" may need to be accounted for somehow. Some devices also have a magnetometer (compass) to counter yaw drift, but since popular game controllers don't have a magnetometer, I haven't tried it myself. In future, if I get such a device, I'd like to add the option for GamepadMotionHelpers to accept magnetometer input and account for it when calculating values for the above functions.
-
-## Gyro Calibration
-Modern gyroscopes often need calibration. This is like how a [weighing scale](https://en.wikipedia.org/wiki/Weighing_scale) can need calibration to tell it what 'zero' is. Like a weighing scale, a correctly calibrated gyroscope will give an accurate reading. If you're using the gyro input as a mouse, which is the simplest application of a controller's gyro, you can find essential reading on [GyroWiki here](http://gyrowiki.jibbsmart.com/blog:good-gyro-controls-part-1:the-gyro-is-a-mouse).
-
-Calibration just means having the controller sit still and remembering the average reported angular velocity in each axis. This is the gyro's "bias". In GamepadMotionHelpers, I call our best guess at the controller's bias the "calibration offset". GamepadMotionHelpers has some options to help with calibrating:
-
-At any time, you can begin manually calibrating a controller by calling ```StartContinuousCalibration()```. This will start recording the average angular velocity and apply it immediately to any subsequent **GetGalibratedGyro(...)** call. At any time you can ```PauseContinuousCalibration()``` to no longer add current values to the average angular velocity being recorded. You can ```ResetContinousCalibration()``` to remove the recorded average before starting over with **StartContinuousCalibration** again.
-
-You can read the stored calibration values using ```GetCalibrationOffset(float& xOffset, float& yOffset, float& zOffset)```. You can manually set the calibration offset yourself with ```SetCalibrationOffset(float xOffset, float yOffset, float zOffset, int weight)```. This will override all stored values. The **weight** argument at the end determines how strongly these values should be considered over time if Continuous Calibration is still active (new values are still being added to the average). Each new sample has a weight of 1, so if you **SetCalibrationOffset** with a weight of 10, it'll have the weight of 10 samples when calculating the average. If you're not continuing to add samples (Continuous Calibration is not active), the weight will be meaningless. Setting this manually is unusual, so don't worry about it too much if that sounds complicated.
-
-Most games don't ask the user to calibrate the gyro themselves. They have built-in automatic calibration, which I like to call "auto-calibration". There's no such thing as a "good enough" auto-calibration solution -- at least not with only gyro and accelerometer. Every game that has an auto-calibration solution would be made better for more serious players with the option to manually calibrate their gyro, so I urge you to provide players the option to do the same in your game. Having said that, auto-calibration is a useful option for casual players, and you may choose to have it enabled in your game by default.
-
-So GamepadMotionHelpers provides some auto-calibration options. You can call ```SetCalibrationMode(CalibrationMode)``` on each GamepadMotion instance with the following options:
-- ```CalibrationMode::Manual``` - No auto-calibration. This is the default.
-- ```CalibrationMode::Stillness``` - Automatically try to detect when the controller is being held still and update the calibration offset accordingly.
-- ```CalibrationMode::SensorFusion``` - Calculate an angular velocity from changes in the gravity direction as detected by the accelerometer. If these are steady enough, use them to make corrections to the calibration offset. This will only apply to relevant axes.
-
-Many players are already aware of the shortcomings of trying to automatically detect stillness to automatically calibrate the gyro. Whether on Switch, PlayStation, or using PlayStation controllers on PC, players have tried to track a slow or distant target only to have the aimer suddenly stop moving! The game or the platform has **misinterpreted their slow and steady input as the controller being held still**, and they've incorrectly recalibrated accordingly. Players *hate it* when this happens.
-
-**This is why it's important to let players manually calibrate their gyro** if they want to.
-
-Auto-calibration is used so widely in console games that it's speculated that game developers may not have the option to disable it on these platforms. If this is the case, GamepadMotionHelpers offers a big advantage over those platforms: you can disable it and enable it at any time.
-
-You, the game developer, can have your game tell if the player is tracking a distant or slow-moving target. You can tell if the player's aimer is moving towards a visible target or roughly following the movement of one. When it is, maybe disabling the auto-calibration (```SetCalibrationMode(CalibrationMode::Manual)```) could be the difference between good and bad auto-calibration. I don't know if the GamepadMotionHelpers auto-calibration functions are better or worse than their Switch and PlayStation counterparts generally, but by letting you take the game's context into account, you may be able to offer players a way better experience without them having to manually calibrate.
-
-But still give them the option to calibrate manually, please :)
-
-The **SensorFusion** calibration mode has shortcomings of its own. It's much harder to accidentally trick the game into incorrectly calibrating, but the angular velocity calculated from the accelerometer moment-to-moment is generally much less precise. Leaving the controller still, you'll notice the calibrated gyro moving slightly up and down over time. So while the **Stillness** mode is characterised by good behaviour occasionally punctuated by frustrating errors, the **SensorFusion** mode will tend to be more consistently not-quite-right without being terrible.
-
-Secondly, this library currently only combines accelerometer and gyro, so the **SensorFusion** auto-calibration cannot correct the gyro in all axes at the same time. The **SensorFusion**-only mode will be more useful in future when magnetometer input is supported, which can account for the axes that the accelerometer can't.
-
-Both auto-calibration modes can be combined by passing ```CalibrationMode::Stillness | CalibrationMode::SensorFusion``` to **SetCalibrationMode**. In this case, it'll use **Stillness** auto-calibration, but it'll adjust the calibration offset based on any angular velocity implied by changes in the accelerometer input. This tends to give better results than just using **Stillness** or **SensorFusion** on their own.
-
-If you aren't sure what to choose, I'd suggest using the combined ```CalibrationMode::Stillness | CalibrationMode::SensorFusion``` when auto calibration is enabled, but also allowing the player to manually calibrate.
-
-**TODO** This is a clunky way to let the user set up what is obviously the best solution. Maybe I should just call it "hybrid" or something and be done with it?
-
-Auto-calibration can also be used to communicate manual calibration to the player. ```GetAutoCalibrationIsSteady()``` will tell you whether GamepadMotionHelpers thinks the controller is currently being held steady (if auto-calibration is enabled). ```GetAutoCalibrationConfidence()``` will tell you how confident GamepadMotionHelpers is that it has a good calibration value from auto-calibration, from 0-1. Higher confidence means that new calibration changes will be applied more gradually. You can use these functions to detect when a controller needs to be calibrated, prompt the player to put their controller down, detect when they have put their controller down, and show progress for calibration (default 1 second once it starts). You can also override the confidence yourself (```SetAutoCalibrationConfidence()```), and resetting calibration will reset confidence to 0. How quickly confidence grows as well as other calibration settings can be customised in **GamepadMotionSettings**.
-
-## In the Wild
-GamepadMotionHelpers is currently used in:
-- [JoyShockMapper](https://github.com/Electronicks/JoyShockMapper)
-- [JoyShockLibrary](https://github.com/JibbSmart/JoyShockLibrary)
-- JoyShockOverlay
-
-If you know of any other games or applications using GamepadMotionHelpers, please let me know!
\ No newline at end of file
diff --git a/lib/N64ModernRuntime b/lib/N64ModernRuntime
index df7e820..589bbf0 160000
--- a/lib/N64ModernRuntime
+++ b/lib/N64ModernRuntime
@@ -1 +1 @@
-Subproject commit df7e820d8c55e4fcb4616c210cbb2c01b25cd48c
+Subproject commit 589bbf018a3e6d3646ddf7de1e7919f1b7e99bb1
diff --git a/lib/RecompFrontend b/lib/RecompFrontend
new file mode 160000
index 0000000..b1a1477
--- /dev/null
+++ b/lib/RecompFrontend
@@ -0,0 +1 @@
+Subproject commit b1a1477c6556aeb7ed45defbfb5924f721efebc1
diff --git a/lib/RmlUi b/lib/RmlUi
deleted file mode 160000
index 7a06f27..0000000
--- a/lib/RmlUi
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 7a06f27db04fe5d13a5dacc19b2b4544673a4eca
diff --git a/lib/concurrentqueue/blockingconcurrentqueue.h b/lib/concurrentqueue/blockingconcurrentqueue.h
deleted file mode 100644
index 205a4db..0000000
--- a/lib/concurrentqueue/blockingconcurrentqueue.h
+++ /dev/null
@@ -1,582 +0,0 @@
-// Provides an efficient blocking version of moodycamel::ConcurrentQueue.
-// ©2015-2020 Cameron Desrochers. Distributed under the terms of the simplified
-// BSD license, available at the top of concurrentqueue.h.
-// Also dual-licensed under the Boost Software License (see LICENSE.md)
-// Uses Jeff Preshing's semaphore implementation (under the terms of its
-// separate zlib license, see lightweightsemaphore.h).
-
-#pragma once
-
-#include "concurrentqueue.h"
-#include "lightweightsemaphore.h"
-
-#include
-#include
-#include
-#include
-#include
-
-namespace moodycamel
-{
-// This is a blocking version of the queue. It has an almost identical interface to
-// the normal non-blocking version, with the addition of various wait_dequeue() methods
-// and the removal of producer-specific dequeue methods.
-template
-class BlockingConcurrentQueue
-{
-private:
- typedef ::moodycamel::ConcurrentQueue ConcurrentQueue;
- typedef ::moodycamel::LightweightSemaphore LightweightSemaphore;
-
-public:
- typedef typename ConcurrentQueue::producer_token_t producer_token_t;
- typedef typename ConcurrentQueue::consumer_token_t consumer_token_t;
-
- typedef typename ConcurrentQueue::index_t index_t;
- typedef typename ConcurrentQueue::size_t size_t;
- typedef typename std::make_signed::type ssize_t;
-
- static const size_t BLOCK_SIZE = ConcurrentQueue::BLOCK_SIZE;
- static const size_t EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD = ConcurrentQueue::EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD;
- static const size_t EXPLICIT_INITIAL_INDEX_SIZE = ConcurrentQueue::EXPLICIT_INITIAL_INDEX_SIZE;
- static const size_t IMPLICIT_INITIAL_INDEX_SIZE = ConcurrentQueue::IMPLICIT_INITIAL_INDEX_SIZE;
- static const size_t INITIAL_IMPLICIT_PRODUCER_HASH_SIZE = ConcurrentQueue::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE;
- static const std::uint32_t EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE = ConcurrentQueue::EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE;
- static const size_t MAX_SUBQUEUE_SIZE = ConcurrentQueue::MAX_SUBQUEUE_SIZE;
-
-public:
- // Creates a queue with at least `capacity` element slots; note that the
- // actual number of elements that can be inserted without additional memory
- // allocation depends on the number of producers and the block size (e.g. if
- // the block size is equal to `capacity`, only a single block will be allocated
- // up-front, which means only a single producer will be able to enqueue elements
- // without an extra allocation -- blocks aren't shared between producers).
- // This method is not thread safe -- it is up to the user to ensure that the
- // queue is fully constructed before it starts being used by other threads (this
- // includes making the memory effects of construction visible, possibly with a
- // memory barrier).
- explicit BlockingConcurrentQueue(size_t capacity = 6 * BLOCK_SIZE)
- : inner(capacity), sema(create(0, (int)Traits::MAX_SEMA_SPINS), &BlockingConcurrentQueue::template destroy)
- {
- assert(reinterpret_cast((BlockingConcurrentQueue*)1) == &((BlockingConcurrentQueue*)1)->inner && "BlockingConcurrentQueue must have ConcurrentQueue as its first member");
- if (!sema) {
- MOODYCAMEL_THROW(std::bad_alloc());
- }
- }
-
- BlockingConcurrentQueue(size_t minCapacity, size_t maxExplicitProducers, size_t maxImplicitProducers)
- : inner(minCapacity, maxExplicitProducers, maxImplicitProducers), sema(create(0, (int)Traits::MAX_SEMA_SPINS), &BlockingConcurrentQueue::template destroy)
- {
- assert(reinterpret_cast((BlockingConcurrentQueue*)1) == &((BlockingConcurrentQueue*)1)->inner && "BlockingConcurrentQueue must have ConcurrentQueue as its first member");
- if (!sema) {
- MOODYCAMEL_THROW(std::bad_alloc());
- }
- }
-
- // Disable copying and copy assignment
- BlockingConcurrentQueue(BlockingConcurrentQueue const&) MOODYCAMEL_DELETE_FUNCTION;
- BlockingConcurrentQueue& operator=(BlockingConcurrentQueue const&) MOODYCAMEL_DELETE_FUNCTION;
-
- // Moving is supported, but note that it is *not* a thread-safe operation.
- // Nobody can use the queue while it's being moved, and the memory effects
- // of that move must be propagated to other threads before they can use it.
- // Note: When a queue is moved, its tokens are still valid but can only be
- // used with the destination queue (i.e. semantically they are moved along
- // with the queue itself).
- BlockingConcurrentQueue(BlockingConcurrentQueue&& other) MOODYCAMEL_NOEXCEPT
- : inner(std::move(other.inner)), sema(std::move(other.sema))
- { }
-
- inline BlockingConcurrentQueue& operator=(BlockingConcurrentQueue&& other) MOODYCAMEL_NOEXCEPT
- {
- return swap_internal(other);
- }
-
- // Swaps this queue's state with the other's. Not thread-safe.
- // Swapping two queues does not invalidate their tokens, however
- // the tokens that were created for one queue must be used with
- // only the swapped queue (i.e. the tokens are tied to the
- // queue's movable state, not the object itself).
- inline void swap(BlockingConcurrentQueue& other) MOODYCAMEL_NOEXCEPT
- {
- swap_internal(other);
- }
-
-private:
- BlockingConcurrentQueue& swap_internal(BlockingConcurrentQueue& other)
- {
- if (this == &other) {
- return *this;
- }
-
- inner.swap(other.inner);
- sema.swap(other.sema);
- return *this;
- }
-
-public:
- // Enqueues a single item (by copying it).
- // Allocates memory if required. Only fails if memory allocation fails (or implicit
- // production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0,
- // or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
- // Thread-safe.
- inline bool enqueue(T const& item)
- {
- if ((details::likely)(inner.enqueue(item))) {
- sema->signal();
- return true;
- }
- return false;
- }
-
- // Enqueues a single item (by moving it, if possible).
- // Allocates memory if required. Only fails if memory allocation fails (or implicit
- // production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0,
- // or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
- // Thread-safe.
- inline bool enqueue(T&& item)
- {
- if ((details::likely)(inner.enqueue(std::move(item)))) {
- sema->signal();
- return true;
- }
- return false;
- }
-
- // Enqueues a single item (by copying it) using an explicit producer token.
- // Allocates memory if required. Only fails if memory allocation fails (or
- // Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
- // Thread-safe.
- inline bool enqueue(producer_token_t const& token, T const& item)
- {
- if ((details::likely)(inner.enqueue(token, item))) {
- sema->signal();
- return true;
- }
- return false;
- }
-
- // Enqueues a single item (by moving it, if possible) using an explicit producer token.
- // Allocates memory if required. Only fails if memory allocation fails (or
- // Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
- // Thread-safe.
- inline bool enqueue(producer_token_t const& token, T&& item)
- {
- if ((details::likely)(inner.enqueue(token, std::move(item)))) {
- sema->signal();
- return true;
- }
- return false;
- }
-
- // Enqueues several items.
- // Allocates memory if required. Only fails if memory allocation fails (or
- // implicit production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE
- // is 0, or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
- // Note: Use std::make_move_iterator if the elements should be moved instead of copied.
- // Thread-safe.
- template
- inline bool enqueue_bulk(It itemFirst, size_t count)
- {
- if ((details::likely)(inner.enqueue_bulk(std::forward(itemFirst), count))) {
- sema->signal((LightweightSemaphore::ssize_t)(ssize_t)count);
- return true;
- }
- return false;
- }
-
- // Enqueues several items using an explicit producer token.
- // Allocates memory if required. Only fails if memory allocation fails
- // (or Traits::MAX_SUBQUEUE_SIZE has been defined and would be surpassed).
- // Note: Use std::make_move_iterator if the elements should be moved
- // instead of copied.
- // Thread-safe.
- template
- inline bool enqueue_bulk(producer_token_t const& token, It itemFirst, size_t count)
- {
- if ((details::likely)(inner.enqueue_bulk(token, std::forward(itemFirst), count))) {
- sema->signal((LightweightSemaphore::ssize_t)(ssize_t)count);
- return true;
- }
- return false;
- }
-
- // Enqueues a single item (by copying it).
- // Does not allocate memory. Fails if not enough room to enqueue (or implicit
- // production is disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE
- // is 0).
- // Thread-safe.
- inline bool try_enqueue(T const& item)
- {
- if (inner.try_enqueue(item)) {
- sema->signal();
- return true;
- }
- return false;
- }
-
- // Enqueues a single item (by moving it, if possible).
- // Does not allocate memory (except for one-time implicit producer).
- // Fails if not enough room to enqueue (or implicit production is
- // disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0).
- // Thread-safe.
- inline bool try_enqueue(T&& item)
- {
- if (inner.try_enqueue(std::move(item))) {
- sema->signal();
- return true;
- }
- return false;
- }
-
- // Enqueues a single item (by copying it) using an explicit producer token.
- // Does not allocate memory. Fails if not enough room to enqueue.
- // Thread-safe.
- inline bool try_enqueue(producer_token_t const& token, T const& item)
- {
- if (inner.try_enqueue(token, item)) {
- sema->signal();
- return true;
- }
- return false;
- }
-
- // Enqueues a single item (by moving it, if possible) using an explicit producer token.
- // Does not allocate memory. Fails if not enough room to enqueue.
- // Thread-safe.
- inline bool try_enqueue(producer_token_t const& token, T&& item)
- {
- if (inner.try_enqueue(token, std::move(item))) {
- sema->signal();
- return true;
- }
- return false;
- }
-
- // Enqueues several items.
- // Does not allocate memory (except for one-time implicit producer).
- // Fails if not enough room to enqueue (or implicit production is
- // disabled because Traits::INITIAL_IMPLICIT_PRODUCER_HASH_SIZE is 0).
- // Note: Use std::make_move_iterator if the elements should be moved
- // instead of copied.
- // Thread-safe.
- template
- inline bool try_enqueue_bulk(It itemFirst, size_t count)
- {
- if (inner.try_enqueue_bulk(std::forward(itemFirst), count)) {
- sema->signal((LightweightSemaphore::ssize_t)(ssize_t)count);
- return true;
- }
- return false;
- }
-
- // Enqueues several items using an explicit producer token.
- // Does not allocate memory. Fails if not enough room to enqueue.
- // Note: Use std::make_move_iterator if the elements should be moved
- // instead of copied.
- // Thread-safe.
- template
- inline bool try_enqueue_bulk(producer_token_t const& token, It itemFirst, size_t count)
- {
- if (inner.try_enqueue_bulk(token, std::forward(itemFirst), count)) {
- sema->signal((LightweightSemaphore::ssize_t)(ssize_t)count);
- return true;
- }
- return false;
- }
-
-
- // Attempts to dequeue from the queue.
- // Returns false if all producer streams appeared empty at the time they
- // were checked (so, the queue is likely but not guaranteed to be empty).
- // Never allocates. Thread-safe.
- template
- inline bool try_dequeue(U& item)
- {
- if (sema->tryWait()) {
- while (!inner.try_dequeue(item)) {
- continue;
- }
- return true;
- }
- return false;
- }
-
- // Attempts to dequeue from the queue using an explicit consumer token.
- // Returns false if all producer streams appeared empty at the time they
- // were checked (so, the queue is likely but not guaranteed to be empty).
- // Never allocates. Thread-safe.
- template
- inline bool try_dequeue(consumer_token_t& token, U& item)
- {
- if (sema->tryWait()) {
- while (!inner.try_dequeue(token, item)) {
- continue;
- }
- return true;
- }
- return false;
- }
-
- // Attempts to dequeue several elements from the queue.
- // Returns the number of items actually dequeued.
- // Returns 0 if all producer streams appeared empty at the time they
- // were checked (so, the queue is likely but not guaranteed to be empty).
- // Never allocates. Thread-safe.
- template
- inline size_t try_dequeue_bulk(It itemFirst, size_t max)
- {
- size_t count = 0;
- max = (size_t)sema->tryWaitMany((LightweightSemaphore::ssize_t)(ssize_t)max);
- while (count != max) {
- count += inner.template try_dequeue_bulk(itemFirst, max - count);
- }
- return count;
- }
-
- // Attempts to dequeue several elements from the queue using an explicit consumer token.
- // Returns the number of items actually dequeued.
- // Returns 0 if all producer streams appeared empty at the time they
- // were checked (so, the queue is likely but not guaranteed to be empty).
- // Never allocates. Thread-safe.
- template
- inline size_t try_dequeue_bulk(consumer_token_t& token, It itemFirst, size_t max)
- {
- size_t count = 0;
- max = (size_t)sema->tryWaitMany((LightweightSemaphore::ssize_t)(ssize_t)max);
- while (count != max) {
- count += inner.template try_dequeue_bulk(token, itemFirst, max - count);
- }
- return count;
- }
-
-
-
- // Blocks the current thread until there's something to dequeue, then
- // dequeues it.
- // Never allocates. Thread-safe.
- template
- inline void wait_dequeue(U& item)
- {
- while (!sema->wait()) {
- continue;
- }
- while (!inner.try_dequeue(item)) {
- continue;
- }
- }
-
- // Blocks the current thread until either there's something to dequeue
- // or the timeout (specified in microseconds) expires. Returns false
- // without setting `item` if the timeout expires, otherwise assigns
- // to `item` and returns true.
- // Using a negative timeout indicates an indefinite timeout,
- // and is thus functionally equivalent to calling wait_dequeue.
- // Never allocates. Thread-safe.
- template
- inline bool wait_dequeue_timed(U& item, std::int64_t timeout_usecs)
- {
- if (!sema->wait(timeout_usecs)) {
- return false;
- }
- while (!inner.try_dequeue(item)) {
- continue;
- }
- return true;
- }
-
- // Blocks the current thread until either there's something to dequeue
- // or the timeout expires. Returns false without setting `item` if the
- // timeout expires, otherwise assigns to `item` and returns true.
- // Never allocates. Thread-safe.
- template
- inline bool wait_dequeue_timed(U& item, std::chrono::duration const& timeout)
- {
- return wait_dequeue_timed(item, std::chrono::duration_cast(timeout).count());
- }
-
- // Blocks the current thread until there's something to dequeue, then
- // dequeues it using an explicit consumer token.
- // Never allocates. Thread-safe.
- template
- inline void wait_dequeue(consumer_token_t& token, U& item)
- {
- while (!sema->wait()) {
- continue;
- }
- while (!inner.try_dequeue(token, item)) {
- continue;
- }
- }
-
- // Blocks the current thread until either there's something to dequeue
- // or the timeout (specified in microseconds) expires. Returns false
- // without setting `item` if the timeout expires, otherwise assigns
- // to `item` and returns true.
- // Using a negative timeout indicates an indefinite timeout,
- // and is thus functionally equivalent to calling wait_dequeue.
- // Never allocates. Thread-safe.
- template
- inline bool wait_dequeue_timed(consumer_token_t& token, U& item, std::int64_t timeout_usecs)
- {
- if (!sema->wait(timeout_usecs)) {
- return false;
- }
- while (!inner.try_dequeue(token, item)) {
- continue;
- }
- return true;
- }
-
- // Blocks the current thread until either there's something to dequeue
- // or the timeout expires. Returns false without setting `item` if the
- // timeout expires, otherwise assigns to `item` and returns true.
- // Never allocates. Thread-safe.
- template
- inline bool wait_dequeue_timed(consumer_token_t& token, U& item, std::chrono::duration const& timeout)
- {
- return wait_dequeue_timed(token, item, std::chrono::duration_cast(timeout).count());
- }
-
- // Attempts to dequeue several elements from the queue.
- // Returns the number of items actually dequeued, which will
- // always be at least one (this method blocks until the queue
- // is non-empty) and at most max.
- // Never allocates. Thread-safe.
- template
- inline size_t wait_dequeue_bulk(It itemFirst, size_t max)
- {
- size_t count = 0;
- max = (size_t)sema->waitMany((LightweightSemaphore::ssize_t)(ssize_t)max);
- while (count != max) {
- count += inner.template try_dequeue_bulk(itemFirst, max - count);
- }
- return count;
- }
-
- // Attempts to dequeue several elements from the queue.
- // Returns the number of items actually dequeued, which can
- // be 0 if the timeout expires while waiting for elements,
- // and at most max.
- // Using a negative timeout indicates an indefinite timeout,
- // and is thus functionally equivalent to calling wait_dequeue_bulk.
- // Never allocates. Thread-safe.
- template
- inline size_t wait_dequeue_bulk_timed(It itemFirst, size_t max, std::int64_t timeout_usecs)
- {
- size_t count = 0;
- max = (size_t)sema->waitMany((LightweightSemaphore::ssize_t)(ssize_t)max, timeout_usecs);
- while (count != max) {
- count += inner.template try_dequeue_bulk(itemFirst, max - count);
- }
- return count;
- }
-
- // Attempts to dequeue several elements from the queue.
- // Returns the number of items actually dequeued, which can
- // be 0 if the timeout expires while waiting for elements,
- // and at most max.
- // Never allocates. Thread-safe.
- template
- inline size_t wait_dequeue_bulk_timed(It itemFirst, size_t max, std::chrono::duration const& timeout)
- {
- return wait_dequeue_bulk_timed(itemFirst, max, std::chrono::duration_cast(timeout).count());
- }
-
- // Attempts to dequeue several elements from the queue using an explicit consumer token.
- // Returns the number of items actually dequeued, which will
- // always be at least one (this method blocks until the queue
- // is non-empty) and at most max.
- // Never allocates. Thread-safe.
- template
- inline size_t wait_dequeue_bulk(consumer_token_t& token, It itemFirst, size_t max)
- {
- size_t count = 0;
- max = (size_t)sema->waitMany((LightweightSemaphore::ssize_t)(ssize_t)max);
- while (count != max) {
- count += inner.template try_dequeue_bulk(token, itemFirst, max - count);
- }
- return count;
- }
-
- // Attempts to dequeue several elements from the queue using an explicit consumer token.
- // Returns the number of items actually dequeued, which can
- // be 0 if the timeout expires while waiting for elements,
- // and at most max.
- // Using a negative timeout indicates an indefinite timeout,
- // and is thus functionally equivalent to calling wait_dequeue_bulk.
- // Never allocates. Thread-safe.
- template
- inline size_t wait_dequeue_bulk_timed(consumer_token_t& token, It itemFirst, size_t max, std::int64_t timeout_usecs)
- {
- size_t count = 0;
- max = (size_t)sema->waitMany((LightweightSemaphore::ssize_t)(ssize_t)max, timeout_usecs);
- while (count != max) {
- count += inner.template try_dequeue_bulk(token, itemFirst, max - count);
- }
- return count;
- }
-
- // Attempts to dequeue several elements from the queue using an explicit consumer token.
- // Returns the number of items actually dequeued, which can
- // be 0 if the timeout expires while waiting for elements,
- // and at most max.
- // Never allocates. Thread-safe.
- template
- inline size_t wait_dequeue_bulk_timed(consumer_token_t& token, It itemFirst, size_t max, std::chrono::duration const& timeout)
- {
- return wait_dequeue_bulk_timed(token, itemFirst, max, std::chrono::duration_cast(timeout).count());
- }
-
-
- // Returns an estimate of the total number of elements currently in the queue. This
- // estimate is only accurate if the queue has completely stabilized before it is called
- // (i.e. all enqueue and dequeue operations have completed and their memory effects are
- // visible on the calling thread, and no further operations start while this method is
- // being called).
- // Thread-safe.
- inline size_t size_approx() const
- {
- return (size_t)sema->availableApprox();
- }
-
-
- // Returns true if the underlying atomic variables used by
- // the queue are lock-free (they should be on most platforms).
- // Thread-safe.
- static constexpr bool is_lock_free()
- {
- return ConcurrentQueue::is_lock_free();
- }
-
-
-private:
- template
- static inline U* create(A1&& a1, A2&& a2)
- {
- void* p = (Traits::malloc)(sizeof(U));
- return p != nullptr ? new (p) U(std::forward(a1), std::forward(a2)) : nullptr;
- }
-
- template
- static inline void destroy(U* p)
- {
- if (p != nullptr) {
- p->~U();
- }
- (Traits::free)(p);
- }
-
-private:
- ConcurrentQueue inner;
- std::unique_ptr sema;
-};
-
-
-template
-inline void swap(BlockingConcurrentQueue& a, BlockingConcurrentQueue& b) MOODYCAMEL_NOEXCEPT
-{
- a.swap(b);
-}
-
-} // end namespace moodycamel
diff --git a/lib/concurrentqueue/concurrentqueue.h b/lib/concurrentqueue/concurrentqueue.h
deleted file mode 100644
index bcb06a1..0000000
--- a/lib/concurrentqueue/concurrentqueue.h
+++ /dev/null
@@ -1,3747 +0,0 @@
-// Provides a C++11 implementation of a multi-producer, multi-consumer lock-free queue.
-// An overview, including benchmark results, is provided here:
-// http://moodycamel.com/blog/2014/a-fast-general-purpose-lock-free-queue-for-c++
-// The full design is also described in excruciating detail at:
-// http://moodycamel.com/blog/2014/detailed-design-of-a-lock-free-queue
-
-// Simplified BSD license:
-// Copyright (c) 2013-2020, Cameron Desrochers.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without modification,
-// are permitted provided that the following conditions are met:
-//
-// - Redistributions of source code must retain the above copyright notice, this list of
-// conditions and the following disclaimer.
-// - Redistributions in binary form must reproduce the above copyright notice, this list of
-// conditions and the following disclaimer in the documentation and/or other materials
-// provided with the distribution.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
-// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
-// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
-// TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Also dual-licensed under the Boost Software License (see LICENSE.md)
-
-#pragma once
-
-#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
-// Disable -Wconversion warnings (spuriously triggered when Traits::size_t and
-// Traits::index_t are set to < 32 bits, causing integer promotion, causing warnings
-// upon assigning any computed values)
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wconversion"
-
-#ifdef MCDBGQ_USE_RELACY
-#pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
-#endif
-#endif
-
-#if defined(_MSC_VER) && (!defined(_HAS_CXX17) || !_HAS_CXX17)
-// VS2019 with /W4 warns about constant conditional expressions but unless /std=c++17 or higher
-// does not support `if constexpr`, so we have no choice but to simply disable the warning
-#pragma warning(push)
-#pragma warning(disable: 4127) // conditional expression is constant
-#endif
-
-#if defined(__APPLE__)
-#include "TargetConditionals.h"
-#endif
-
-#ifdef MCDBGQ_USE_RELACY
-#include "relacy/relacy_std.hpp"
-#include "relacy_shims.h"
-// We only use malloc/free anyway, and the delete macro messes up `= delete` method declarations.
-// We'll override the default trait malloc ourselves without a macro.
-#undef new
-#undef delete
-#undef malloc
-#undef free
-#else
-#include // Requires C++11. Sorry VS2010.
-#include
-#endif
-#include // for max_align_t
-#include
-#include
-#include
-#include
-#include
-#include
-#include // for CHAR_BIT
-#include
-#include // partly for __WINPTHREADS_VERSION if on MinGW-w64 w/ POSIX threading
-#include // used for thread exit synchronization
-
-// Platform-specific definitions of a numeric thread ID type and an invalid value
-namespace moodycamel { namespace details {
- template struct thread_id_converter {
- typedef thread_id_t thread_id_numeric_size_t;
- typedef thread_id_t thread_id_hash_t;
- static thread_id_hash_t prehash(thread_id_t const& x) { return x; }
- };
-} }
-#if defined(MCDBGQ_USE_RELACY)
-namespace moodycamel { namespace details {
- typedef std::uint32_t thread_id_t;
- static const thread_id_t invalid_thread_id = 0xFFFFFFFFU;
- static const thread_id_t invalid_thread_id2 = 0xFFFFFFFEU;
- static inline thread_id_t thread_id() { return rl::thread_index(); }
-} }
-#elif defined(_WIN32) || defined(__WINDOWS__) || defined(__WIN32__)
-// No sense pulling in windows.h in a header, we'll manually declare the function
-// we use and rely on backwards-compatibility for this not to break
-extern "C" __declspec(dllimport) unsigned long __stdcall GetCurrentThreadId(void);
-namespace moodycamel { namespace details {
- static_assert(sizeof(unsigned long) == sizeof(std::uint32_t), "Expected size of unsigned long to be 32 bits on Windows");
- typedef std::uint32_t thread_id_t;
- static const thread_id_t invalid_thread_id = 0; // See http://blogs.msdn.com/b/oldnewthing/archive/2004/02/23/78395.aspx
- static const thread_id_t invalid_thread_id2 = 0xFFFFFFFFU; // Not technically guaranteed to be invalid, but is never used in practice. Note that all Win32 thread IDs are presently multiples of 4.
- static inline thread_id_t thread_id() { return static_cast(::GetCurrentThreadId()); }
-} }
-#elif defined(__arm__) || defined(_M_ARM) || defined(__aarch64__) || (defined(__APPLE__) && TARGET_OS_IPHONE) || defined(MOODYCAMEL_NO_THREAD_LOCAL)
-namespace moodycamel { namespace details {
- static_assert(sizeof(std::thread::id) == 4 || sizeof(std::thread::id) == 8, "std::thread::id is expected to be either 4 or 8 bytes");
-
- typedef std::thread::id thread_id_t;
- static const thread_id_t invalid_thread_id; // Default ctor creates invalid ID
-
- // Note we don't define a invalid_thread_id2 since std::thread::id doesn't have one; it's
- // only used if MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED is defined anyway, which it won't
- // be.
- static inline thread_id_t thread_id() { return std::this_thread::get_id(); }
-
- template struct thread_id_size { };
- template<> struct thread_id_size<4> { typedef std::uint32_t numeric_t; };
- template<> struct thread_id_size<8> { typedef std::uint64_t numeric_t; };
-
- template<> struct thread_id_converter {
- typedef thread_id_size::numeric_t thread_id_numeric_size_t;
-#ifndef __APPLE__
- typedef std::size_t thread_id_hash_t;
-#else
- typedef thread_id_numeric_size_t thread_id_hash_t;
-#endif
-
- static thread_id_hash_t prehash(thread_id_t const& x)
- {
-#ifndef __APPLE__
- return std::hash()(x);
-#else
- return *reinterpret_cast(&x);
-#endif
- }
- };
-} }
-#else
-// Use a nice trick from this answer: http://stackoverflow.com/a/8438730/21475
-// In order to get a numeric thread ID in a platform-independent way, we use a thread-local
-// static variable's address as a thread identifier :-)
-#if defined(__GNUC__) || defined(__INTEL_COMPILER)
-#define MOODYCAMEL_THREADLOCAL __thread
-#elif defined(_MSC_VER)
-#define MOODYCAMEL_THREADLOCAL __declspec(thread)
-#else
-// Assume C++11 compliant compiler
-#define MOODYCAMEL_THREADLOCAL thread_local
-#endif
-namespace moodycamel { namespace details {
- typedef std::uintptr_t thread_id_t;
- static const thread_id_t invalid_thread_id = 0; // Address can't be nullptr
- static const thread_id_t invalid_thread_id2 = 1; // Member accesses off a null pointer are also generally invalid. Plus it's not aligned.
- inline thread_id_t thread_id() { static MOODYCAMEL_THREADLOCAL int x; return reinterpret_cast(&x); }
-} }
-#endif
-
-// Constexpr if
-#ifndef MOODYCAMEL_CONSTEXPR_IF
-#if (defined(_MSC_VER) && defined(_HAS_CXX17) && _HAS_CXX17) || __cplusplus > 201402L
-#define MOODYCAMEL_CONSTEXPR_IF if constexpr
-#define MOODYCAMEL_MAYBE_UNUSED [[maybe_unused]]
-#else
-#define MOODYCAMEL_CONSTEXPR_IF if
-#define MOODYCAMEL_MAYBE_UNUSED
-#endif
-#endif
-
-// Exceptions
-#ifndef MOODYCAMEL_EXCEPTIONS_ENABLED
-#if (defined(_MSC_VER) && defined(_CPPUNWIND)) || (defined(__GNUC__) && defined(__EXCEPTIONS)) || (!defined(_MSC_VER) && !defined(__GNUC__))
-#define MOODYCAMEL_EXCEPTIONS_ENABLED
-#endif
-#endif
-#ifdef MOODYCAMEL_EXCEPTIONS_ENABLED
-#define MOODYCAMEL_TRY try
-#define MOODYCAMEL_CATCH(...) catch(__VA_ARGS__)
-#define MOODYCAMEL_RETHROW throw
-#define MOODYCAMEL_THROW(expr) throw (expr)
-#else
-#define MOODYCAMEL_TRY MOODYCAMEL_CONSTEXPR_IF (true)
-#define MOODYCAMEL_CATCH(...) else MOODYCAMEL_CONSTEXPR_IF (false)
-#define MOODYCAMEL_RETHROW
-#define MOODYCAMEL_THROW(expr)
-#endif
-
-#ifndef MOODYCAMEL_NOEXCEPT
-#if !defined(MOODYCAMEL_EXCEPTIONS_ENABLED)
-#define MOODYCAMEL_NOEXCEPT
-#define MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr) true
-#define MOODYCAMEL_NOEXCEPT_ASSIGN(type, valueType, expr) true
-#elif defined(_MSC_VER) && defined(_NOEXCEPT) && _MSC_VER < 1800
-// VS2012's std::is_nothrow_[move_]constructible is broken and returns true when it shouldn't :-(
-// We have to assume *all* non-trivial constructors may throw on VS2012!
-#define MOODYCAMEL_NOEXCEPT _NOEXCEPT
-#define MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr) (std::is_rvalue_reference::value && std::is_move_constructible::value ? std::is_trivially_move_constructible::value : std::is_trivially_copy_constructible::value)
-#define MOODYCAMEL_NOEXCEPT_ASSIGN(type, valueType, expr) ((std::is_rvalue_reference::value && std::is_move_assignable::value ? std::is_trivially_move_assignable::value || std::is_nothrow_move_assignable::value : std::is_trivially_copy_assignable::value || std::is_nothrow_copy_assignable::value) && MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr))
-#elif defined(_MSC_VER) && defined(_NOEXCEPT) && _MSC_VER < 1900
-#define MOODYCAMEL_NOEXCEPT _NOEXCEPT
-#define MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr) (std::is_rvalue_reference::value && std::is_move_constructible::value ? std::is_trivially_move_constructible::value || std::is_nothrow_move_constructible::value : std::is_trivially_copy_constructible::value || std::is_nothrow_copy_constructible::value)
-#define MOODYCAMEL_NOEXCEPT_ASSIGN(type, valueType, expr) ((std::is_rvalue_reference::value && std::is_move_assignable::value ? std::is_trivially_move_assignable::value || std::is_nothrow_move_assignable::value : std::is_trivially_copy_assignable::value || std::is_nothrow_copy_assignable::value) && MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr))
-#else
-#define MOODYCAMEL_NOEXCEPT noexcept
-#define MOODYCAMEL_NOEXCEPT_CTOR(type, valueType, expr) noexcept(expr)
-#define MOODYCAMEL_NOEXCEPT_ASSIGN(type, valueType, expr) noexcept(expr)
-#endif
-#endif
-
-#ifndef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED
-#ifdef MCDBGQ_USE_RELACY
-#define MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED
-#else
-// VS2013 doesn't support `thread_local`, and MinGW-w64 w/ POSIX threading has a crippling bug: http://sourceforge.net/p/mingw-w64/bugs/445
-// g++ <=4.7 doesn't support thread_local either.
-// Finally, iOS/ARM doesn't have support for it either, and g++/ARM allows it to compile but it's unconfirmed to actually work
-#if (!defined(_MSC_VER) || _MSC_VER >= 1900) && (!defined(__MINGW32__) && !defined(__MINGW64__) || !defined(__WINPTHREADS_VERSION)) && (!defined(__GNUC__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)) && (!defined(__APPLE__) || !TARGET_OS_IPHONE) && !defined(__arm__) && !defined(_M_ARM) && !defined(__aarch64__)
-// Assume `thread_local` is fully supported in all other C++11 compilers/platforms
-#define MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED // tentatively enabled for now; years ago several users report having problems with it on
-#endif
-#endif
-#endif
-
-// VS2012 doesn't support deleted functions.
-// In this case, we declare the function normally but don't define it. A link error will be generated if the function is called.
-#ifndef MOODYCAMEL_DELETE_FUNCTION
-#if defined(_MSC_VER) && _MSC_VER < 1800
-#define MOODYCAMEL_DELETE_FUNCTION
-#else
-#define MOODYCAMEL_DELETE_FUNCTION = delete
-#endif
-#endif
-
-namespace moodycamel { namespace details {
-#ifndef MOODYCAMEL_ALIGNAS
-// VS2013 doesn't support alignas or alignof, and align() requires a constant literal
-#if defined(_MSC_VER) && _MSC_VER <= 1800
-#define MOODYCAMEL_ALIGNAS(alignment) __declspec(align(alignment))
-#define MOODYCAMEL_ALIGNOF(obj) __alignof(obj)
-#define MOODYCAMEL_ALIGNED_TYPE_LIKE(T, obj) typename details::Vs2013Aligned::value, T>::type
- template struct Vs2013Aligned { }; // default, unsupported alignment
- template struct Vs2013Aligned<1, T> { typedef __declspec(align(1)) T type; };
- template struct Vs2013Aligned<2, T> { typedef __declspec(align(2)) T type; };
- template struct Vs2013Aligned<4, T> { typedef __declspec(align(4)) T type; };
- template struct Vs2013Aligned<8, T> { typedef __declspec(align(8)) T type; };
- template struct Vs2013Aligned<16, T> { typedef __declspec(align(16)) T type; };
- template struct Vs2013Aligned<32, T> { typedef __declspec(align(32)) T type; };
- template struct Vs2013Aligned<64, T> { typedef __declspec(align(64)) T type; };
- template struct Vs2013Aligned<128, T> { typedef __declspec(align(128)) T type; };
- template struct Vs2013Aligned<256, T> { typedef __declspec(align(256)) T type; };
-#else
- template struct identity { typedef T type; };
-#define MOODYCAMEL_ALIGNAS(alignment) alignas(alignment)
-#define MOODYCAMEL_ALIGNOF(obj) alignof(obj)
-#define MOODYCAMEL_ALIGNED_TYPE_LIKE(T, obj) alignas(alignof(obj)) typename details::identity::type
-#endif
-#endif
-} }
-
-
-// TSAN can false report races in lock-free code. To enable TSAN to be used from projects that use this one,
-// we can apply per-function compile-time suppression.
-// See https://clang.llvm.org/docs/ThreadSanitizer.html#has-feature-thread-sanitizer
-#define MOODYCAMEL_NO_TSAN
-#if defined(__has_feature)
- #if __has_feature(thread_sanitizer)
- #undef MOODYCAMEL_NO_TSAN
- #define MOODYCAMEL_NO_TSAN __attribute__((no_sanitize("thread")))
- #endif // TSAN
-#endif // TSAN
-
-// Compiler-specific likely/unlikely hints
-namespace moodycamel { namespace details {
-#if defined(__GNUC__)
- static inline bool (likely)(bool x) { return __builtin_expect((x), true); }
- static inline bool (unlikely)(bool x) { return __builtin_expect((x), false); }
-#else
- static inline bool (likely)(bool x) { return x; }
- static inline bool (unlikely)(bool x) { return x; }
-#endif
-} }
-
-#ifdef MOODYCAMEL_QUEUE_INTERNAL_DEBUG
-#include "internal/concurrentqueue_internal_debug.h"
-#endif
-
-namespace moodycamel {
-namespace details {
- template
- struct const_numeric_max {
- static_assert(std::is_integral::value, "const_numeric_max can only be used with integers");
- static const T value = std::numeric_limits::is_signed
- ? (static_cast(1) << (sizeof(T) * CHAR_BIT - 1)) - static_cast(1)
- : static_cast(-1);
- };
-
-#if defined(__GLIBCXX__)
- typedef ::max_align_t std_max_align_t; // libstdc++ forgot to add it to std:: for a while
-#else
- typedef std::max_align_t std_max_align_t; // Others (e.g. MSVC) insist it can *only* be accessed via std::
-#endif
-
- // Some platforms have incorrectly set max_align_t to a type with <8 bytes alignment even while supporting
- // 8-byte aligned scalar values (*cough* 32-bit iOS). Work around this with our own union. See issue #64.
- typedef union {
- std_max_align_t x;
- long long y;
- void* z;
- } max_align_t;
-}
-
-// Default traits for the ConcurrentQueue. To change some of the
-// traits without re-implementing all of them, inherit from this
-// struct and shadow the declarations you wish to be different;
-// since the traits are used as a template type parameter, the
-// shadowed declarations will be used where defined, and the defaults
-// otherwise.
-struct ConcurrentQueueDefaultTraits
-{
- // General-purpose size type. std::size_t is strongly recommended.
- typedef std::size_t size_t;
-
- // The type used for the enqueue and dequeue indices. Must be at least as
- // large as size_t. Should be significantly larger than the number of elements
- // you expect to hold at once, especially if you have a high turnover rate;
- // for example, on 32-bit x86, if you expect to have over a hundred million
- // elements or pump several million elements through your queue in a very
- // short space of time, using a 32-bit type *may* trigger a race condition.
- // A 64-bit int type is recommended in that case, and in practice will
- // prevent a race condition no matter the usage of the queue. Note that
- // whether the queue is lock-free with a 64-int type depends on the whether
- // std::atomic is lock-free, which is platform-specific.
- typedef std::size_t index_t;
-
- // Internally, all elements are enqueued and dequeued from multi-element
- // blocks; this is the smallest controllable unit. If you expect few elements
- // but many producers, a smaller block size should be favoured. For few producers
- // and/or many elements, a larger block size is preferred. A sane default
- // is provided. Must be a power of 2.
- static const size_t BLOCK_SIZE = 32;
-
- // For explicit producers (i.e. when using a producer token), the block is
- // checked for being empty by iterating through a list of flags, one per element.
- // For large block sizes, this is too inefficient, and switching to an atomic
- // counter-based approach is faster. The switch is made for block sizes strictly
- // larger than this threshold.
- static const size_t EXPLICIT_BLOCK_EMPTY_COUNTER_THRESHOLD = 32;
-
- // How many full blocks can be expected for a single explicit producer? This should
- // reflect that number's maximum for optimal performance. Must be a power of 2.
- static const size_t EXPLICIT_INITIAL_INDEX_SIZE = 32;
-
- // How many full blocks can be expected for a single implicit producer? This should
- // reflect that number's maximum for optimal performance. Must be a power of 2.
- static const size_t IMPLICIT_INITIAL_INDEX_SIZE = 32;
-
- // The initial size of the hash table mapping thread IDs to implicit producers.
- // Note that the hash is resized every time it becomes half full.
- // Must be a power of two, and either 0 or at least 1. If 0, implicit production
- // (using the enqueue methods without an explicit producer token) is disabled.
- static const size_t INITIAL_IMPLICIT_PRODUCER_HASH_SIZE = 32;
-
- // Controls the number of items that an explicit consumer (i.e. one with a token)
- // must consume before it causes all consumers to rotate and move on to the next
- // internal queue.
- static const std::uint32_t EXPLICIT_CONSUMER_CONSUMPTION_QUOTA_BEFORE_ROTATE = 256;
-
- // The maximum number of elements (inclusive) that can be enqueued to a sub-queue.
- // Enqueue operations that would cause this limit to be surpassed will fail. Note
- // that this limit is enforced at the block level (for performance reasons), i.e.
- // it's rounded up to the nearest block size.
- static const size_t MAX_SUBQUEUE_SIZE = details::const_numeric_max::value;
-
- // The number of times to spin before sleeping when waiting on a semaphore.
- // Recommended values are on the order of 1000-10000 unless the number of
- // consumer threads exceeds the number of idle cores (in which case try 0-100).
- // Only affects instances of the BlockingConcurrentQueue.
- static const int MAX_SEMA_SPINS = 100;
-
- // Whether to recycle dynamically-allocated blocks into an internal free list or
- // not. If false, only pre-allocated blocks (controlled by the constructor
- // arguments) will be recycled, and all others will be `free`d back to the heap.
- // Note that blocks consumed by explicit producers are only freed on destruction
- // of the queue (not following destruction of the token) regardless of this trait.
- static const bool RECYCLE_ALLOCATED_BLOCKS = false;
-
-
-#ifndef MCDBGQ_USE_RELACY
- // Memory allocation can be customized if needed.
- // malloc should return nullptr on failure, and handle alignment like std::malloc.
-#if defined(malloc) || defined(free)
- // Gah, this is 2015, stop defining macros that break standard code already!
- // Work around malloc/free being special macros:
- static inline void* WORKAROUND_malloc(size_t size) { return malloc(size); }
- static inline void WORKAROUND_free(void* ptr) { return free(ptr); }
- static inline void* (malloc)(size_t size) { return WORKAROUND_malloc(size); }
- static inline void (free)(void* ptr) { return WORKAROUND_free(ptr); }
-#else
- static inline void* malloc(size_t size) { return std::malloc(size); }
- static inline void free(void* ptr) { return std::free(ptr); }
-#endif
-#else
- // Debug versions when running under the Relacy race detector (ignore
- // these in user code)
- static inline void* malloc(size_t size) { return rl::rl_malloc(size, $); }
- static inline void free(void* ptr) { return rl::rl_free(ptr, $); }
-#endif
-};
-
-
-// When producing or consuming many elements, the most efficient way is to:
-// 1) Use one of the bulk-operation methods of the queue with a token
-// 2) Failing that, use the bulk-operation methods without a token
-// 3) Failing that, create a token and use that with the single-item methods
-// 4) Failing that, use the single-parameter methods of the queue
-// Having said that, don't create tokens willy-nilly -- ideally there should be
-// a maximum of one token per thread (of each kind).
-struct ProducerToken;
-struct ConsumerToken;
-
-template class ConcurrentQueue;
-template class BlockingConcurrentQueue;
-class ConcurrentQueueTests;
-
-
-namespace details
-{
- struct ConcurrentQueueProducerTypelessBase
- {
- ConcurrentQueueProducerTypelessBase* next;
- std::atomic inactive;
- ProducerToken* token;
-
- ConcurrentQueueProducerTypelessBase()
- : next(nullptr), inactive(false), token(nullptr)
- {
- }
- };
-
- template struct _hash_32_or_64 {
- static inline std::uint32_t hash(std::uint32_t h)
- {
- // MurmurHash3 finalizer -- see https://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp
- // Since the thread ID is already unique, all we really want to do is propagate that
- // uniqueness evenly across all the bits, so that we can use a subset of the bits while
- // reducing collisions significantly
- h ^= h >> 16;
- h *= 0x85ebca6b;
- h ^= h >> 13;
- h *= 0xc2b2ae35;
- return h ^ (h >> 16);
- }
- };
- template<> struct _hash_32_or_64<1> {
- static inline std::uint64_t hash(std::uint64_t h)
- {
- h ^= h >> 33;
- h *= 0xff51afd7ed558ccd;
- h ^= h >> 33;
- h *= 0xc4ceb9fe1a85ec53;
- return h ^ (h >> 33);
- }
- };
- template struct hash_32_or_64 : public _hash_32_or_64<(size > 4)> { };
-
- static inline size_t hash_thread_id(thread_id_t id)
- {
- static_assert(sizeof(thread_id_t) <= 8, "Expected a platform where thread IDs are at most 64-bit values");
- return static_cast(hash_32_or_64::thread_id_hash_t)>::hash(
- thread_id_converter::prehash(id)));
- }
-
- template
- static inline bool circular_less_than(T a, T b)
- {
- static_assert(std::is_integral::value && !std::numeric_limits::is_signed, "circular_less_than is intended to be used only with unsigned integer types");
- return static_cast(a - b) > static_cast(static_cast(1) << (static_cast(sizeof(T) * CHAR_BIT - 1)));
- // Note: extra parens around rhs of operator<< is MSVC bug: https://developercommunity2.visualstudio.com/t/C4554-triggers-when-both-lhs-and-rhs-is/10034931
- // silencing the bug requires #pragma warning(disable: 4554) around the calling code and has no effect when done here.
- }
-
- template
- static inline char* align_for(char* ptr)
- {
- const std::size_t alignment = std::alignment_of::value;
- return ptr + (alignment - (reinterpret_cast(ptr) % alignment)) % alignment;
- }
-
- template
- static inline T ceil_to_pow_2(T x)
- {
- static_assert(std::is_integral::value && !std::numeric_limits::is_signed, "ceil_to_pow_2 is intended to be used only with unsigned integer types");
-
- // Adapted from http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
- --x;
- x |= x >> 1;
- x |= x >> 2;
- x |= x >> 4;
- for (std::size_t i = 1; i < sizeof(T); i <<= 1) {
- x |= x >> (i << 3);
- }
- ++x;
- return x;
- }
-
- template
- static inline void swap_relaxed(std::atomic& left, std::atomic& right)
- {
- T temp = std::move(left.load(std::memory_order_relaxed));
- left.store(std::move(right.load(std::memory_order_relaxed)), std::memory_order_relaxed);
- right.store(std::move(temp), std::memory_order_relaxed);
- }
-
- template
- static inline T const& nomove(T const& x)
- {
- return x;
- }
-
- template
- struct nomove_if
- {
- template
- static inline T const& eval(T const& x)
- {
- return x;
- }
- };
-
- template<>
- struct nomove_if
- {
- template
- static inline auto eval(U&& x)
- -> decltype(std::forward(x))
- {
- return std::forward(x);
- }
- };
-
- template
- static inline auto deref_noexcept(It& it) MOODYCAMEL_NOEXCEPT -> decltype(*it)
- {
- return *it;
- }
-
-#if defined(__clang__) || !defined(__GNUC__) || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
- template struct is_trivially_destructible : std::is_trivially_destructible { };
-#else
- template struct is_trivially_destructible : std::has_trivial_destructor { };
-#endif
-
-#ifdef MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED
-#ifdef MCDBGQ_USE_RELACY
- typedef RelacyThreadExitListener ThreadExitListener;
- typedef RelacyThreadExitNotifier ThreadExitNotifier;
-#else
- class ThreadExitNotifier;
-
- struct ThreadExitListener
- {
- typedef void (*callback_t)(void*);
- callback_t callback;
- void* userData;
-
- ThreadExitListener* next; // reserved for use by the ThreadExitNotifier
- ThreadExitNotifier* chain; // reserved for use by the ThreadExitNotifier
- };
-
- class ThreadExitNotifier
- {
- public:
- static void subscribe(ThreadExitListener* listener)
- {
- auto& tlsInst = instance();
- std::lock_guard guard(mutex());
- listener->next = tlsInst.tail;
- listener->chain = &tlsInst;
- tlsInst.tail = listener;
- }
-
- static void unsubscribe(ThreadExitListener* listener)
- {
- std::lock_guard guard(mutex());
- if (!listener->chain) {
- return; // race with ~ThreadExitNotifier
- }
- auto& tlsInst = *listener->chain;
- listener->chain = nullptr;
- ThreadExitListener** prev = &tlsInst.tail;
- for (auto ptr = tlsInst.tail; ptr != nullptr; ptr = ptr->next) {
- if (ptr == listener) {
- *prev = ptr->next;
- break;
- }
- prev = &ptr->next;
- }
- }
-
- private:
- ThreadExitNotifier() : tail(nullptr) { }
- ThreadExitNotifier(ThreadExitNotifier const&) MOODYCAMEL_DELETE_FUNCTION;
- ThreadExitNotifier& operator=(ThreadExitNotifier const&) MOODYCAMEL_DELETE_FUNCTION;
-
- ~ThreadExitNotifier()
- {
- // This thread is about to exit, let everyone know!
- assert(this == &instance() && "If this assert fails, you likely have a buggy compiler! Change the preprocessor conditions such that MOODYCAMEL_CPP11_THREAD_LOCAL_SUPPORTED is no longer defined.");
- std::lock_guard guard(mutex());
- for (auto ptr = tail; ptr != nullptr; ptr = ptr->next) {
- ptr->chain = nullptr;
- ptr->callback(ptr->userData);
- }
- }
-
- // Thread-local
- static inline ThreadExitNotifier& instance()
- {
- static thread_local ThreadExitNotifier notifier;
- return notifier;
- }
-
- static inline std::mutex& mutex()
- {
- // Must be static because the ThreadExitNotifier could be destroyed while unsubscribe is called
- static std::mutex mutex;
- return mutex;
- }
-
- private:
- ThreadExitListener* tail;
- };
-#endif
-#endif
-
- template struct static_is_lock_free_num { enum { value = 0 }; };
- template<> struct static_is_lock_free_num { enum { value = ATOMIC_CHAR_LOCK_FREE }; };
- template<> struct static_is_lock_free_num { enum { value = ATOMIC_SHORT_LOCK_FREE }; };
- template<> struct static_is_lock_free_num { enum { value = ATOMIC_INT_LOCK_FREE }; };
- template<> struct static_is_lock_free_num { enum { value = ATOMIC_LONG_LOCK_FREE }; };
- template<> struct static_is_lock_free_num { enum { value = ATOMIC_LLONG_LOCK_FREE }; };
- template struct static_is_lock_free : static_is_lock_free_num::type> { };
- template<> struct static_is_lock_free { enum { value = ATOMIC_BOOL_LOCK_FREE }; };
- template struct static_is_lock_free { enum { value = ATOMIC_POINTER_LOCK_FREE }; };
-}
-
-
-struct ProducerToken
-{
- template
- explicit ProducerToken(ConcurrentQueue& queue);
-
- template
- explicit ProducerToken(BlockingConcurrentQueue& queue);
-
- ProducerToken(ProducerToken&& other) MOODYCAMEL_NOEXCEPT
- : producer(other.producer)
- {
- other.producer = nullptr;
- if (producer != nullptr) {
- producer->token = this;
- }
- }
-
- inline ProducerToken& operator=(ProducerToken&& other) MOODYCAMEL_NOEXCEPT
- {
- swap(other);
- return *this;
- }
-
- void swap(ProducerToken& other) MOODYCAMEL_NOEXCEPT
- {
- std::swap(producer, other.producer);
- if (producer != nullptr) {
- producer->token = this;
- }
- if (other.producer != nullptr) {
- other.producer->token = &other;
- }
- }
-
- // A token is always valid unless:
- // 1) Memory allocation failed during construction
- // 2) It was moved via the move constructor
- // (Note: assignment does a swap, leaving both potentially valid)
- // 3) The associated queue was destroyed
- // Note that if valid() returns true, that only indicates
- // that the token is valid for use with a specific queue,
- // but not which one; that's up to the user to track.
- inline bool valid() const { return producer != nullptr; }
-
- ~ProducerToken()
- {
- if (producer != nullptr) {
- producer->token = nullptr;
- producer->inactive.store(true, std::memory_order_release);
- }
- }
-
- // Disable copying and assignment
- ProducerToken(ProducerToken const&) MOODYCAMEL_DELETE_FUNCTION;
- ProducerToken& operator=(ProducerToken const&) MOODYCAMEL_DELETE_FUNCTION;
-
-private:
- template friend class ConcurrentQueue;
- friend class ConcurrentQueueTests;
-
-protected:
- details::ConcurrentQueueProducerTypelessBase* producer;
-};
-
-
-struct ConsumerToken
-{
- template
- explicit ConsumerToken(ConcurrentQueue