mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-06-10 06:53:33 -07:00
general: snapshot
This commit is contained in:
+11
-1
@@ -6,6 +6,8 @@
|
||||
|
||||
### App
|
||||
|
||||
- General
|
||||
- Added a light theme !
|
||||
- Performance
|
||||
- Improved app's reactivity
|
||||
- Added some chunk splitting for a faster initial load
|
||||
@@ -13,10 +15,18 @@
|
||||
- Chart
|
||||
- Fixed legend hovering on mobile not resetting on touch end
|
||||
- Updated legend padding so that the scrollbar, if visible, is less in the way
|
||||
- Added yearly time scale setters (from year 2009 to today)
|
||||
- Added "3 months" and yearly time scale setters (from year 2009 to today)
|
||||
- Hide scrollbar of timescale setters
|
||||
- Changed scroll buttons visibility by screen type (touchscreen or not) instead of screen size
|
||||
- Added scroll buttons to the legend
|
||||
- Tweaked scroll buttons background and gradient color from black to stone gray
|
||||
- Improved Share/QR Code screen
|
||||
- Settings
|
||||
- Finally made a proper component where you can chose the app's theme, between a moving or static background and its text opacity
|
||||
- Misc
|
||||
- Support mini window size, could be useful for embedded views
|
||||
- Hopefully made scrollbars a little more subtle on WIndows and Linux, can't test
|
||||
- Generale style updates
|
||||
|
||||
## v. 0.1.1 | 849240 - 2024/06/24
|
||||
|
||||
|
||||
+5
-2
@@ -1,5 +1,5 @@
|
||||
<!doctype html>
|
||||
<html lang="en" class="overflow-hidden bg-black text-white">
|
||||
<html lang="en" class="overflow-hidden">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Satonomics</title>
|
||||
@@ -362,7 +362,10 @@
|
||||
media="(prefers-color-scheme: dark) and (device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
|
||||
/>
|
||||
</head>
|
||||
<body style="font-size: 15px; line-height: 22px">
|
||||
<body
|
||||
class="text-high-contrast bg-white dark:bg-black"
|
||||
style="font-size: 15px; line-height: 22px"
|
||||
>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
|
||||
<div id="root"></div>
|
||||
|
||||
+6
-6
@@ -23,14 +23,14 @@
|
||||
"@solid-primitives/resize-observer": "^2.0.25",
|
||||
"lean-qr": "^2.3.4",
|
||||
"lightweight-charts": "^4.1.6",
|
||||
"solid-js": "^1.8.17"
|
||||
"solid-js": "^1.8.18"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ianvs/prettier-plugin-sort-imports": "^4.2.1",
|
||||
"@iconify-json/tabler": "^1.1.114",
|
||||
"@ianvs/prettier-plugin-sort-imports": "^4.3.0",
|
||||
"@iconify-json/tabler": "^1.1.115",
|
||||
"@tailwindcss/container-queries": "^0.1.1",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"postcss": "^8.4.38",
|
||||
"postcss": "^8.4.39",
|
||||
"prettier": "^3.3.2",
|
||||
"prettier-plugin-tailwindcss": "^0.6.5",
|
||||
"pwa-asset-generator": "^6.3.1",
|
||||
@@ -39,10 +39,10 @@
|
||||
"typescript": "^5.5.2",
|
||||
"unplugin-auto-import": "^0.17.6",
|
||||
"unplugin-icons": "^0.19.0",
|
||||
"vite": "^5.3.1",
|
||||
"vite": "^5.3.2",
|
||||
"vite-plugin-pwa": "^0.20.0",
|
||||
"vite-plugin-solid": "^2.10.2",
|
||||
"workbox-window": "^7.1.0",
|
||||
"wrangler": "^3.61.0"
|
||||
"wrangler": "^3.62.0"
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+152
-147
@@ -10,16 +10,16 @@ dependencies:
|
||||
version: 1.0.14
|
||||
'@solid-primitives/event-listener':
|
||||
specifier: ^2.3.3
|
||||
version: 2.3.3(solid-js@1.8.17)
|
||||
version: 2.3.3(solid-js@1.8.18)
|
||||
'@solid-primitives/intersection-observer':
|
||||
specifier: ^2.1.6
|
||||
version: 2.1.6(solid-js@1.8.17)
|
||||
version: 2.1.6(solid-js@1.8.18)
|
||||
'@solid-primitives/memo':
|
||||
specifier: ^1.3.8
|
||||
version: 1.3.8(solid-js@1.8.17)
|
||||
version: 1.3.8(solid-js@1.8.18)
|
||||
'@solid-primitives/resize-observer':
|
||||
specifier: ^2.0.25
|
||||
version: 2.0.25(solid-js@1.8.17)
|
||||
version: 2.0.25(solid-js@1.8.18)
|
||||
lean-qr:
|
||||
specifier: ^2.3.4
|
||||
version: 2.3.4
|
||||
@@ -27,31 +27,31 @@ dependencies:
|
||||
specifier: ^4.1.6
|
||||
version: 4.1.6
|
||||
solid-js:
|
||||
specifier: ^1.8.17
|
||||
version: 1.8.17
|
||||
specifier: ^1.8.18
|
||||
version: 1.8.18
|
||||
|
||||
devDependencies:
|
||||
'@ianvs/prettier-plugin-sort-imports':
|
||||
specifier: ^4.2.1
|
||||
version: 4.2.1(prettier@3.3.2)
|
||||
specifier: ^4.3.0
|
||||
version: 4.3.0(prettier@3.3.2)
|
||||
'@iconify-json/tabler':
|
||||
specifier: ^1.1.114
|
||||
version: 1.1.114
|
||||
specifier: ^1.1.115
|
||||
version: 1.1.115
|
||||
'@tailwindcss/container-queries':
|
||||
specifier: ^0.1.1
|
||||
version: 0.1.1(tailwindcss@3.4.4)
|
||||
autoprefixer:
|
||||
specifier: ^10.4.19
|
||||
version: 10.4.19(postcss@8.4.38)
|
||||
version: 10.4.19(postcss@8.4.39)
|
||||
postcss:
|
||||
specifier: ^8.4.38
|
||||
version: 8.4.38
|
||||
specifier: ^8.4.39
|
||||
version: 8.4.39
|
||||
prettier:
|
||||
specifier: ^3.3.2
|
||||
version: 3.3.2
|
||||
prettier-plugin-tailwindcss:
|
||||
specifier: ^0.6.5
|
||||
version: 0.6.5(@ianvs/prettier-plugin-sort-imports@4.2.1)(prettier@3.3.2)
|
||||
version: 0.6.5(@ianvs/prettier-plugin-sort-imports@4.3.0)(prettier@3.3.2)
|
||||
pwa-asset-generator:
|
||||
specifier: ^6.3.1
|
||||
version: 6.3.1
|
||||
@@ -71,20 +71,20 @@ devDependencies:
|
||||
specifier: ^0.19.0
|
||||
version: 0.19.0
|
||||
vite:
|
||||
specifier: ^5.3.1
|
||||
version: 5.3.1
|
||||
specifier: ^5.3.2
|
||||
version: 5.3.2
|
||||
vite-plugin-pwa:
|
||||
specifier: ^0.20.0
|
||||
version: 0.20.0(vite@5.3.1)(workbox-build@7.1.1)(workbox-window@7.1.0)
|
||||
version: 0.20.0(vite@5.3.2)(workbox-build@7.1.1)(workbox-window@7.1.0)
|
||||
vite-plugin-solid:
|
||||
specifier: ^2.10.2
|
||||
version: 2.10.2(solid-js@1.8.17)(vite@5.3.1)
|
||||
version: 2.10.2(solid-js@1.8.18)(vite@5.3.2)
|
||||
workbox-window:
|
||||
specifier: ^7.1.0
|
||||
version: 7.1.0
|
||||
wrangler:
|
||||
specifier: ^3.61.0
|
||||
version: 3.61.0
|
||||
specifier: ^3.62.0
|
||||
version: 3.62.0
|
||||
|
||||
packages:
|
||||
|
||||
@@ -114,8 +114,8 @@ packages:
|
||||
'@jsdevtools/ez-spawn': 3.0.4
|
||||
dev: true
|
||||
|
||||
/@antfu/utils@0.7.8:
|
||||
resolution: {integrity: sha512-rWQkqXRESdjXtc+7NRfK9lASQjpXJu1ayp7qi1d23zZorY+wBHVLHHoVcMsEnkqEBWTFqbztO7/QdJFzyEcLTg==}
|
||||
/@antfu/utils@0.7.10:
|
||||
resolution: {integrity: sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==}
|
||||
dev: true
|
||||
|
||||
/@apideck/better-ajv-errors@0.3.6(ajv@8.16.0):
|
||||
@@ -1383,15 +1383,15 @@ packages:
|
||||
to-fast-properties: 2.0.0
|
||||
dev: true
|
||||
|
||||
/@cloudflare/kv-asset-handler@0.3.3:
|
||||
resolution: {integrity: sha512-wpE+WiWW2kUNwNE0xyl4CtTAs+STjGtouHGiZPGRaisGB7eXXdbvfZdOrQJQVKgTxZiNAgVgmc7fj0sUmd8zyA==}
|
||||
/@cloudflare/kv-asset-handler@0.3.4:
|
||||
resolution: {integrity: sha512-YLPHc8yASwjNkmcDMQMY35yiWjoKAKnhUbPRszBRS0YgH+IXtsMp61j+yTcnCE3oO2DgP0U3iejLC8FTtKDC8Q==}
|
||||
engines: {node: '>=16.13'}
|
||||
dependencies:
|
||||
mime: 3.0.0
|
||||
dev: true
|
||||
|
||||
/@cloudflare/workerd-darwin-64@1.20240610.1:
|
||||
resolution: {integrity: sha512-YanZ1iXgMGaUWlleB5cswSE6qbzyjQ8O7ENWZcPAcZZ6BfuL7q3CWi0t9iM1cv2qx92rRztsRTyjcfq099++XQ==}
|
||||
/@cloudflare/workerd-darwin-64@1.20240620.1:
|
||||
resolution: {integrity: sha512-YWeS2aE8jAzDefuus/3GmZcFGu3Ef94uCAoxsQuaEXNsiGM9NeAhPpKC1BJAlcv168U/Q1J+6hckcGtipf6ZcQ==}
|
||||
engines: {node: '>=16'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
@@ -1399,8 +1399,8 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@cloudflare/workerd-darwin-arm64@1.20240610.1:
|
||||
resolution: {integrity: sha512-bRe/y/LKjIgp3L2EHjc+CvoCzfHhf4aFTtOBkv2zW+VToNJ4KlXridndf7LvR9urfsFRRo9r4TXCssuKaU+ypQ==}
|
||||
/@cloudflare/workerd-darwin-arm64@1.20240620.1:
|
||||
resolution: {integrity: sha512-3rdND+EHpmCrwYX6hvxIBSBJ0f40tRNxond1Vfw7GiR1MJVi3gragiBx75UDFHCxfRw3J0GZ1qVlkRce2/Xbsg==}
|
||||
engines: {node: '>=16'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
@@ -1408,8 +1408,8 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@cloudflare/workerd-linux-64@1.20240610.1:
|
||||
resolution: {integrity: sha512-2zDcadR7+Gs9SjcMXmwsMji2Xs+yASGNA2cEHDuFc4NMUup+eL1mkzxc/QzvFjyBck98e92rBjMZt2dVscpGKg==}
|
||||
/@cloudflare/workerd-linux-64@1.20240620.1:
|
||||
resolution: {integrity: sha512-tURcTrXGeSbYqeM5ISVcofY20StKbVIcdxjJvNYNZ+qmSV9Fvn+zr7rRE+q64pEloVZfhsEPAlUCnFso5VV4XQ==}
|
||||
engines: {node: '>=16'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
@@ -1417,8 +1417,8 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@cloudflare/workerd-linux-arm64@1.20240610.1:
|
||||
resolution: {integrity: sha512-7y41rPi5xmIYJN8CY+t3RHnjLL0xx/WYmaTd/j552k1qSr02eTE2o/TGyWZmGUC+lWnwdPQJla0mXbvdqgRdQg==}
|
||||
/@cloudflare/workerd-linux-arm64@1.20240620.1:
|
||||
resolution: {integrity: sha512-TThvkwNxaZFKhHZnNjOGqIYCOk05DDWgO+wYMuXg15ymN/KZPnCicRAkuyqiM+R1Fgc4kwe/pehjP8pbmcf6sg==}
|
||||
engines: {node: '>=16'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
@@ -1426,8 +1426,8 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@cloudflare/workerd-windows-64@1.20240610.1:
|
||||
resolution: {integrity: sha512-B0LyT3DB6rXHWNptnntYHPaoJIy0rXnGfeDBM3nEVV8JIsQrx8MEFn2F2jYioH1FkUVavsaqKO/zUosY3tZXVA==}
|
||||
/@cloudflare/workerd-windows-64@1.20240620.1:
|
||||
resolution: {integrity: sha512-Y/BA9Yj0r7Al1HK3nDHcfISgFllw6NR3XMMPChev57vrVT9C9D4erBL3sUBfofHU+2U9L+ShLsl6obBpe3vvUw==}
|
||||
engines: {node: '>=16'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
@@ -1870,8 +1870,8 @@ packages:
|
||||
engines: {node: '>=14'}
|
||||
dev: true
|
||||
|
||||
/@ianvs/prettier-plugin-sort-imports@4.2.1(prettier@3.3.2):
|
||||
resolution: {integrity: sha512-NKN1LVFWUDGDGr3vt+6Ey3qPeN/163uR1pOPAlkWpgvAqgxQ6kSdUf1F0it8aHUtKRUzEGcK38Wxd07O61d7+Q==}
|
||||
/@ianvs/prettier-plugin-sort-imports@4.3.0(prettier@3.3.2):
|
||||
resolution: {integrity: sha512-OOMtUcO4J3LoL63dOKAe7bn+lSRRPeit2DqNHpx+wvBp3Grejo2PMaK4Mp1mwy8pnat64ccSgk/lBZbsAdLErw==}
|
||||
peerDependencies:
|
||||
'@vue/compiler-sfc': 2.7.x || 3.x
|
||||
prettier: 2 || 3
|
||||
@@ -1890,8 +1890,8 @@ packages:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@iconify-json/tabler@1.1.114:
|
||||
resolution: {integrity: sha512-AaTTGEyiPQ7VAYyXGQ9jUI8+8iL6xanucYsACz6f3U6JLph6jDyicXXUh+dYM6HxW6TGehwVqRO2NSIQpACszw==}
|
||||
/@iconify-json/tabler@1.1.115:
|
||||
resolution: {integrity: sha512-nyD8OmtQhBl6FLptfVJe04fjoLIUT3sxe4sEChrXhVDuYQlb1DUPEQQkbwjAIzP4w9JcNYwdUpVbIWn60AjECw==}
|
||||
dependencies:
|
||||
'@iconify/types': 2.0.0
|
||||
dev: true
|
||||
@@ -1904,7 +1904,7 @@ packages:
|
||||
resolution: {integrity: sha512-Y+iGko8uv/Fz5bQLLJyNSZGOdMW0G7cnlEX1CiNcKsRXX9cq/y/vwxrIAtLCZhKHr3m0VJmsjVPsvnM4uX8YLg==}
|
||||
dependencies:
|
||||
'@antfu/install-pkg': 0.1.1
|
||||
'@antfu/utils': 0.7.8
|
||||
'@antfu/utils': 0.7.10
|
||||
'@iconify/types': 2.0.0
|
||||
debug: 4.3.5
|
||||
kolorist: 1.8.0
|
||||
@@ -2233,78 +2233,78 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@solid-primitives/event-listener@2.3.3(solid-js@1.8.17):
|
||||
/@solid-primitives/event-listener@2.3.3(solid-js@1.8.18):
|
||||
resolution: {integrity: sha512-DAJbl+F0wrFW2xmcV8dKMBhk9QLVLuBSW+TR4JmIfTaObxd13PuL7nqaXnaYKDWOYa6otB00qcCUIGbuIhSUgQ==}
|
||||
peerDependencies:
|
||||
solid-js: ^1.6.12
|
||||
dependencies:
|
||||
'@solid-primitives/utils': 6.2.3(solid-js@1.8.17)
|
||||
solid-js: 1.8.17
|
||||
'@solid-primitives/utils': 6.2.3(solid-js@1.8.18)
|
||||
solid-js: 1.8.18
|
||||
dev: false
|
||||
|
||||
/@solid-primitives/intersection-observer@2.1.6(solid-js@1.8.17):
|
||||
/@solid-primitives/intersection-observer@2.1.6(solid-js@1.8.18):
|
||||
resolution: {integrity: sha512-SeiCmN/R46Z+o9+5HhIQzSor0DqVPyo4ROLQMvCI8AsGZl/5nHlWzHTTbWPeukVUXTgb04wfC3DUo9IzF/XloA==}
|
||||
peerDependencies:
|
||||
solid-js: ^1.6.12
|
||||
dependencies:
|
||||
'@solid-primitives/utils': 6.2.3(solid-js@1.8.17)
|
||||
solid-js: 1.8.17
|
||||
'@solid-primitives/utils': 6.2.3(solid-js@1.8.18)
|
||||
solid-js: 1.8.18
|
||||
dev: false
|
||||
|
||||
/@solid-primitives/memo@1.3.8(solid-js@1.8.17):
|
||||
/@solid-primitives/memo@1.3.8(solid-js@1.8.18):
|
||||
resolution: {integrity: sha512-U75pfLFSxFmM2xbx1+2XPPyWbaXrnUFF10spbFuOUgJ7azrC+4y+FnrVi4RKqHw9gftd8aKQuTiyMQq468YLQw==}
|
||||
peerDependencies:
|
||||
solid-js: ^1.6.12
|
||||
dependencies:
|
||||
'@solid-primitives/scheduled': 1.4.3(solid-js@1.8.17)
|
||||
'@solid-primitives/utils': 6.2.3(solid-js@1.8.17)
|
||||
solid-js: 1.8.17
|
||||
'@solid-primitives/scheduled': 1.4.3(solid-js@1.8.18)
|
||||
'@solid-primitives/utils': 6.2.3(solid-js@1.8.18)
|
||||
solid-js: 1.8.18
|
||||
dev: false
|
||||
|
||||
/@solid-primitives/resize-observer@2.0.25(solid-js@1.8.17):
|
||||
/@solid-primitives/resize-observer@2.0.25(solid-js@1.8.18):
|
||||
resolution: {integrity: sha512-jVDXkt2MiriYRaz4DYs62185d+6jQ+1DCsR+v7f6XMsIJJuf963qdBRFjtZtKXBaxdPNMyuPeDgf5XQe3EoDJg==}
|
||||
peerDependencies:
|
||||
solid-js: ^1.6.12
|
||||
dependencies:
|
||||
'@solid-primitives/event-listener': 2.3.3(solid-js@1.8.17)
|
||||
'@solid-primitives/rootless': 1.4.5(solid-js@1.8.17)
|
||||
'@solid-primitives/static-store': 0.0.8(solid-js@1.8.17)
|
||||
'@solid-primitives/utils': 6.2.3(solid-js@1.8.17)
|
||||
solid-js: 1.8.17
|
||||
'@solid-primitives/event-listener': 2.3.3(solid-js@1.8.18)
|
||||
'@solid-primitives/rootless': 1.4.5(solid-js@1.8.18)
|
||||
'@solid-primitives/static-store': 0.0.8(solid-js@1.8.18)
|
||||
'@solid-primitives/utils': 6.2.3(solid-js@1.8.18)
|
||||
solid-js: 1.8.18
|
||||
dev: false
|
||||
|
||||
/@solid-primitives/rootless@1.4.5(solid-js@1.8.17):
|
||||
/@solid-primitives/rootless@1.4.5(solid-js@1.8.18):
|
||||
resolution: {integrity: sha512-GFJE9GC3ojx0aUKqAUZmQPyU8fOVMtnVNrkdk2yS4kd17WqVSpXpoTmo9CnOwA+PG7FTzdIkogvfLQSLs4lrww==}
|
||||
peerDependencies:
|
||||
solid-js: ^1.6.12
|
||||
dependencies:
|
||||
'@solid-primitives/utils': 6.2.3(solid-js@1.8.17)
|
||||
solid-js: 1.8.17
|
||||
'@solid-primitives/utils': 6.2.3(solid-js@1.8.18)
|
||||
solid-js: 1.8.18
|
||||
dev: false
|
||||
|
||||
/@solid-primitives/scheduled@1.4.3(solid-js@1.8.17):
|
||||
/@solid-primitives/scheduled@1.4.3(solid-js@1.8.18):
|
||||
resolution: {integrity: sha512-HfWN5w7b7FEc6VPLBKnnE302h90jsLMuR28Fcf7neRGGf8jBj6wm6/UFQ00VlKexHFMR6KQ2u4VBh5a1ZcqM8g==}
|
||||
peerDependencies:
|
||||
solid-js: ^1.6.12
|
||||
dependencies:
|
||||
solid-js: 1.8.17
|
||||
solid-js: 1.8.18
|
||||
dev: false
|
||||
|
||||
/@solid-primitives/static-store@0.0.8(solid-js@1.8.17):
|
||||
/@solid-primitives/static-store@0.0.8(solid-js@1.8.18):
|
||||
resolution: {integrity: sha512-ZecE4BqY0oBk0YG00nzaAWO5Mjcny8Fc06CdbXadH9T9lzq/9GefqcSe/5AtdXqjvY/DtJ5C6CkcjPZO0o/eqg==}
|
||||
peerDependencies:
|
||||
solid-js: ^1.6.12
|
||||
dependencies:
|
||||
'@solid-primitives/utils': 6.2.3(solid-js@1.8.17)
|
||||
solid-js: 1.8.17
|
||||
'@solid-primitives/utils': 6.2.3(solid-js@1.8.18)
|
||||
solid-js: 1.8.18
|
||||
dev: false
|
||||
|
||||
/@solid-primitives/utils@6.2.3(solid-js@1.8.17):
|
||||
/@solid-primitives/utils@6.2.3(solid-js@1.8.18):
|
||||
resolution: {integrity: sha512-CqAwKb2T5Vi72+rhebSsqNZ9o67buYRdEJrIFzRXz3U59QqezuuxPsyzTSVCacwS5Pf109VRsgCJQoxKRoECZQ==}
|
||||
peerDependencies:
|
||||
solid-js: ^1.6.12
|
||||
dependencies:
|
||||
solid-js: 1.8.17
|
||||
solid-js: 1.8.18
|
||||
dev: false
|
||||
|
||||
/@surma/rollup-plugin-off-main-thread@2.2.3:
|
||||
@@ -2368,11 +2368,11 @@ packages:
|
||||
/@types/node-forge@1.3.11:
|
||||
resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==}
|
||||
dependencies:
|
||||
'@types/node': 20.14.8
|
||||
'@types/node': 20.14.9
|
||||
dev: true
|
||||
|
||||
/@types/node@20.14.8:
|
||||
resolution: {integrity: sha512-DO+2/jZinXfROG7j7WKFn/3C6nFwxy2lLpgLjEXJz+0XKphZlTLJ14mo8Vfg8X5BWN6XjyESXq+LcYdT7tR3bA==}
|
||||
/@types/node@20.14.9:
|
||||
resolution: {integrity: sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==}
|
||||
dependencies:
|
||||
undici-types: 5.26.5
|
||||
dev: true
|
||||
@@ -2393,7 +2393,7 @@ packages:
|
||||
resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==}
|
||||
requiresBuild: true
|
||||
dependencies:
|
||||
'@types/node': 20.14.8
|
||||
'@types/node': 20.14.9
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
@@ -2520,7 +2520,7 @@ packages:
|
||||
engines: {node: '>= 4.0.0'}
|
||||
dev: true
|
||||
|
||||
/autoprefixer@10.4.19(postcss@8.4.38):
|
||||
/autoprefixer@10.4.19(postcss@8.4.39):
|
||||
resolution: {integrity: sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==}
|
||||
engines: {node: ^10 || ^12 || >=14}
|
||||
hasBin: true
|
||||
@@ -2528,11 +2528,11 @@ packages:
|
||||
postcss: ^8.1.0
|
||||
dependencies:
|
||||
browserslist: 4.23.1
|
||||
caniuse-lite: 1.0.30001636
|
||||
caniuse-lite: 1.0.30001638
|
||||
fraction.js: 4.3.7
|
||||
normalize-range: 0.1.2
|
||||
picocolors: 1.0.1
|
||||
postcss: 8.4.38
|
||||
postcss: 8.4.39
|
||||
postcss-value-parser: 4.2.0
|
||||
dev: true
|
||||
|
||||
@@ -2543,8 +2543,8 @@ packages:
|
||||
possible-typed-array-names: 1.0.0
|
||||
dev: true
|
||||
|
||||
/babel-plugin-jsx-dom-expressions@0.37.21(@babel/core@7.24.7):
|
||||
resolution: {integrity: sha512-WbQo1NQ241oki8bYasVzkMXOTSIri5GO/K47rYJb2ZBh8GaPUEWiWbMV3KwXz+96eU2i54N6ThzjQG/f5n8Azw==}
|
||||
/babel-plugin-jsx-dom-expressions@0.37.23(@babel/core@7.24.7):
|
||||
resolution: {integrity: sha512-Y/r8LyLi/njnwPTaDuPEReWk30FJ1KplloYvcFUhHmiH1F7yVVj5mWojD7mbO/IruKyvOs9OIPUoeMi3Z++J4w==}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.20.12
|
||||
dependencies:
|
||||
@@ -2592,13 +2592,13 @@ packages:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/babel-preset-solid@1.8.17(@babel/core@7.24.7):
|
||||
resolution: {integrity: sha512-s/FfTZOeds0hYxYqce90Jb+0ycN2lrzC7VP1k1JIn3wBqcaexDKdYi6xjB+hMNkL+Q6HobKbwsriqPloasR9LA==}
|
||||
/babel-preset-solid@1.8.18(@babel/core@7.24.7):
|
||||
resolution: {integrity: sha512-ky0FA4cCS9dk+xYBBItHoxtbRnaDIOGpmHLFqKPaR81hpMbJBOiLOZia2hT0JBwx4zn/D2OjMRvRr6kqtRMoUw==}
|
||||
peerDependencies:
|
||||
'@babel/core': ^7.0.0
|
||||
dependencies:
|
||||
'@babel/core': 7.24.7
|
||||
babel-plugin-jsx-dom-expressions: 0.37.21(@babel/core@7.24.7)
|
||||
babel-plugin-jsx-dom-expressions: 0.37.23(@babel/core@7.24.7)
|
||||
dev: true
|
||||
|
||||
/balanced-match@1.0.2:
|
||||
@@ -2655,8 +2655,8 @@ packages:
|
||||
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
caniuse-lite: 1.0.30001636
|
||||
electron-to-chromium: 1.4.810
|
||||
caniuse-lite: 1.0.30001638
|
||||
electron-to-chromium: 1.4.815
|
||||
node-releases: 2.0.14
|
||||
update-browserslist-db: 1.0.16(browserslist@4.23.1)
|
||||
dev: true
|
||||
@@ -2715,8 +2715,8 @@ packages:
|
||||
engines: {node: '>=6'}
|
||||
dev: true
|
||||
|
||||
/caniuse-lite@1.0.30001636:
|
||||
resolution: {integrity: sha512-bMg2vmr8XBsbL6Lr0UHXy/21m84FTxDLWn2FSqMd5PrlbMxwJlQnC2YWYxVgp66PZE+BBNF2jYQUBKCo1FDeZg==}
|
||||
/caniuse-lite@1.0.30001638:
|
||||
resolution: {integrity: sha512-5SuJUJ7cZnhPpeLHaH0c/HPAnAHZvS6ElWyHK9GSIbVOQABLzowiI2pjmpvZ1WEbkyz46iFd4UXlOHR5SqgfMQ==}
|
||||
dev: true
|
||||
|
||||
/capnp-ts@0.7.0:
|
||||
@@ -2793,7 +2793,7 @@ packages:
|
||||
engines: {node: '>=12.13.0'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
'@types/node': 20.14.8
|
||||
'@types/node': 20.14.9
|
||||
escape-string-regexp: 4.0.0
|
||||
is-wsl: 2.2.0
|
||||
lighthouse-logger: 1.4.2
|
||||
@@ -2976,6 +2976,10 @@ packages:
|
||||
is-data-view: 1.0.1
|
||||
dev: true
|
||||
|
||||
/date-fns@3.6.0:
|
||||
resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==}
|
||||
dev: true
|
||||
|
||||
/debug@2.6.9:
|
||||
resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==}
|
||||
peerDependencies:
|
||||
@@ -3118,8 +3122,8 @@ packages:
|
||||
jake: 10.9.1
|
||||
dev: true
|
||||
|
||||
/electron-to-chromium@1.4.810:
|
||||
resolution: {integrity: sha512-Kaxhu4T7SJGpRQx99tq216gCq2nMxJo+uuT6uzz9l8TVN2stL7M06MIIXAtr9jsrLs2Glflgf2vMQRepxawOdQ==}
|
||||
/electron-to-chromium@1.4.815:
|
||||
resolution: {integrity: sha512-OvpTT2ItpOXJL7IGcYakRjHCt8L5GrrN/wHCQsRB4PQa1X9fe+X9oen245mIId7s14xvArCGSTIq644yPUKKLg==}
|
||||
dev: true
|
||||
|
||||
/emoji-regex@8.0.0:
|
||||
@@ -3596,7 +3600,7 @@ packages:
|
||||
dependencies:
|
||||
foreground-child: 3.2.1
|
||||
jackspeak: 3.4.0
|
||||
minimatch: 9.0.4
|
||||
minimatch: 9.0.5
|
||||
minipass: 7.1.2
|
||||
package-json-from-dist: 1.0.0
|
||||
path-scurry: 1.11.1
|
||||
@@ -4158,8 +4162,8 @@ packages:
|
||||
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
|
||||
dev: true
|
||||
|
||||
/lru-cache@10.2.2:
|
||||
resolution: {integrity: sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==}
|
||||
/lru-cache@10.3.0:
|
||||
resolution: {integrity: sha512-CQl19J/g+Hbjbv4Y3mFNNXFEL/5t/KCg8POCuUqd4rMKjGG+j1ybER83hxV58zL+dFI1PTkt3GNFSHRt+d8qEQ==}
|
||||
engines: {node: 14 || >=16.14}
|
||||
dev: true
|
||||
|
||||
@@ -4272,8 +4276,8 @@ packages:
|
||||
engines: {node: '>=4'}
|
||||
dev: true
|
||||
|
||||
/miniflare@3.20240610.1:
|
||||
resolution: {integrity: sha512-ZkfSpBmX3nJW00yYhvF2kGvjb6f77TOimRR6+2GQvsArbwo6e0iYqLGM9aB/cnJzgFjLMvOv1qj4756iynSxJQ==}
|
||||
/miniflare@3.20240620.0:
|
||||
resolution: {integrity: sha512-NBMzqUE2mMlh/hIdt6U5MP+aFhEjKDq3l8CAajXAQa1WkndJdciWvzB2mfLETwoVFhMl/lphaVzyEN2AgwJpbQ==}
|
||||
engines: {node: '>=16.13'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
@@ -4285,7 +4289,7 @@ packages:
|
||||
glob-to-regexp: 0.4.1
|
||||
stoppable: 1.1.0
|
||||
undici: 5.28.4
|
||||
workerd: 1.20240610.1
|
||||
workerd: 1.20240620.1
|
||||
ws: 8.17.1
|
||||
youch: 3.3.3
|
||||
zod: 3.23.8
|
||||
@@ -4315,8 +4319,8 @@ packages:
|
||||
brace-expansion: 2.0.1
|
||||
dev: true
|
||||
|
||||
/minimatch@9.0.4:
|
||||
resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==}
|
||||
/minimatch@9.0.5:
|
||||
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
dependencies:
|
||||
brace-expansion: 2.0.1
|
||||
@@ -4586,7 +4590,7 @@ packages:
|
||||
resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
|
||||
engines: {node: '>=16 || 14 >=14.18'}
|
||||
dependencies:
|
||||
lru-cache: 10.2.2
|
||||
lru-cache: 10.3.0
|
||||
minipass: 7.1.2
|
||||
dev: true
|
||||
|
||||
@@ -4641,29 +4645,29 @@ packages:
|
||||
engines: {node: '>= 0.4'}
|
||||
dev: true
|
||||
|
||||
/postcss-import@15.1.0(postcss@8.4.38):
|
||||
/postcss-import@15.1.0(postcss@8.4.39):
|
||||
resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
peerDependencies:
|
||||
postcss: ^8.0.0
|
||||
dependencies:
|
||||
postcss: 8.4.38
|
||||
postcss: 8.4.39
|
||||
postcss-value-parser: 4.2.0
|
||||
read-cache: 1.0.0
|
||||
resolve: 1.22.8
|
||||
dev: true
|
||||
|
||||
/postcss-js@4.0.1(postcss@8.4.38):
|
||||
/postcss-js@4.0.1(postcss@8.4.39):
|
||||
resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==}
|
||||
engines: {node: ^12 || ^14 || >= 16}
|
||||
peerDependencies:
|
||||
postcss: ^8.4.21
|
||||
dependencies:
|
||||
camelcase-css: 2.0.1
|
||||
postcss: 8.4.38
|
||||
postcss: 8.4.39
|
||||
dev: true
|
||||
|
||||
/postcss-load-config@4.0.2(postcss@8.4.38):
|
||||
/postcss-load-config@4.0.2(postcss@8.4.39):
|
||||
resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==}
|
||||
engines: {node: '>= 14'}
|
||||
peerDependencies:
|
||||
@@ -4676,17 +4680,17 @@ packages:
|
||||
optional: true
|
||||
dependencies:
|
||||
lilconfig: 3.1.2
|
||||
postcss: 8.4.38
|
||||
postcss: 8.4.39
|
||||
yaml: 2.4.5
|
||||
dev: true
|
||||
|
||||
/postcss-nested@6.0.1(postcss@8.4.38):
|
||||
/postcss-nested@6.0.1(postcss@8.4.39):
|
||||
resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==}
|
||||
engines: {node: '>=12.0'}
|
||||
peerDependencies:
|
||||
postcss: ^8.2.14
|
||||
dependencies:
|
||||
postcss: 8.4.38
|
||||
postcss: 8.4.39
|
||||
postcss-selector-parser: 6.1.0
|
||||
dev: true
|
||||
|
||||
@@ -4702,8 +4706,8 @@ packages:
|
||||
resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
|
||||
dev: true
|
||||
|
||||
/postcss@8.4.38:
|
||||
resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==}
|
||||
/postcss@8.4.39:
|
||||
resolution: {integrity: sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==}
|
||||
engines: {node: ^10 || ^12 || >=14}
|
||||
dependencies:
|
||||
nanoid: 3.3.7
|
||||
@@ -4711,7 +4715,7 @@ packages:
|
||||
source-map-js: 1.2.0
|
||||
dev: true
|
||||
|
||||
/prettier-plugin-tailwindcss@0.6.5(@ianvs/prettier-plugin-sort-imports@4.2.1)(prettier@3.3.2):
|
||||
/prettier-plugin-tailwindcss@0.6.5(@ianvs/prettier-plugin-sort-imports@4.3.0)(prettier@3.3.2):
|
||||
resolution: {integrity: sha512-axfeOArc/RiGHjOIy9HytehlC0ZLeMaqY09mm8YCkMzznKiDkwFzOpBvtuhuv3xG5qB73+Mj7OCe2j/L1ryfuQ==}
|
||||
engines: {node: '>=14.21.3'}
|
||||
peerDependencies:
|
||||
@@ -4763,7 +4767,7 @@ packages:
|
||||
prettier-plugin-svelte:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@ianvs/prettier-plugin-sort-imports': 4.2.1(prettier@3.3.2)
|
||||
'@ianvs/prettier-plugin-sort-imports': 4.3.0(prettier@3.3.2)
|
||||
prettier: 3.3.2
|
||||
dev: true
|
||||
|
||||
@@ -5228,14 +5232,14 @@ packages:
|
||||
resolution: {integrity: sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==}
|
||||
dev: true
|
||||
|
||||
/solid-js@1.8.17:
|
||||
resolution: {integrity: sha512-E0FkUgv9sG/gEBWkHr/2XkBluHb1fkrHywUgA6o6XolPDCJ4g1HaLmQufcBBhiF36ee40q+HpG/vCZu7fLpI3Q==}
|
||||
/solid-js@1.8.18:
|
||||
resolution: {integrity: sha512-cpkxDPvO/AuKBugVv6xKFd1C9VC0XZMu4VtF56IlHoux8HgyW44uqNSWbozMnVcpIzHIhS3vVXPAVZYM26jpWw==}
|
||||
dependencies:
|
||||
csstype: 3.1.3
|
||||
seroval: 1.0.7
|
||||
seroval-plugins: 1.0.7(seroval@1.0.7)
|
||||
|
||||
/solid-refresh@0.6.3(solid-js@1.8.17):
|
||||
/solid-refresh@0.6.3(solid-js@1.8.18):
|
||||
resolution: {integrity: sha512-F3aPsX6hVw9ttm5LYlth8Q15x6MlI/J3Dn+o3EQyRTtTxidepSTwAYdozt01/YA+7ObcciagGEyXIopGZzQtbA==}
|
||||
peerDependencies:
|
||||
solid-js: ^1.3
|
||||
@@ -5243,7 +5247,7 @@ packages:
|
||||
'@babel/generator': 7.24.7
|
||||
'@babel/helper-module-imports': 7.24.7
|
||||
'@babel/types': 7.24.7
|
||||
solid-js: 1.8.17
|
||||
solid-js: 1.8.18
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
@@ -5488,11 +5492,11 @@ packages:
|
||||
normalize-path: 3.0.0
|
||||
object-hash: 3.0.0
|
||||
picocolors: 1.0.1
|
||||
postcss: 8.4.38
|
||||
postcss-import: 15.1.0(postcss@8.4.38)
|
||||
postcss-js: 4.0.1(postcss@8.4.38)
|
||||
postcss-load-config: 4.0.2(postcss@8.4.38)
|
||||
postcss-nested: 6.0.1(postcss@8.4.38)
|
||||
postcss: 8.4.39
|
||||
postcss-import: 15.1.0(postcss@8.4.39)
|
||||
postcss-js: 4.0.1(postcss@8.4.39)
|
||||
postcss-load-config: 4.0.2(postcss@8.4.39)
|
||||
postcss-nested: 6.0.1(postcss@8.4.39)
|
||||
postcss-selector-parser: 6.1.0
|
||||
resolve: 1.22.8
|
||||
sucrase: 3.35.0
|
||||
@@ -5753,7 +5757,7 @@ packages:
|
||||
pkg-types: 1.1.1
|
||||
scule: 1.3.0
|
||||
strip-literal: 2.1.0
|
||||
unplugin: 1.10.1
|
||||
unplugin: 1.10.2
|
||||
transitivePeerDependencies:
|
||||
- rollup
|
||||
dev: true
|
||||
@@ -5782,14 +5786,14 @@ packages:
|
||||
'@vueuse/core':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@antfu/utils': 0.7.8
|
||||
'@antfu/utils': 0.7.10
|
||||
'@rollup/pluginutils': 5.1.0(rollup@2.79.1)
|
||||
fast-glob: 3.3.2
|
||||
local-pkg: 0.5.0
|
||||
magic-string: 0.30.10
|
||||
minimatch: 9.0.4
|
||||
minimatch: 9.0.5
|
||||
unimport: 3.7.2(rollup@2.79.1)
|
||||
unplugin: 1.10.1
|
||||
unplugin: 1.10.2
|
||||
transitivePeerDependencies:
|
||||
- rollup
|
||||
dev: true
|
||||
@@ -5815,18 +5819,18 @@ packages:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@antfu/install-pkg': 0.3.3
|
||||
'@antfu/utils': 0.7.8
|
||||
'@antfu/utils': 0.7.10
|
||||
'@iconify/utils': 2.1.25
|
||||
debug: 4.3.5
|
||||
kolorist: 1.8.0
|
||||
local-pkg: 0.5.0
|
||||
unplugin: 1.10.1
|
||||
unplugin: 1.10.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/unplugin@1.10.1:
|
||||
resolution: {integrity: sha512-d6Mhq8RJeGA8UfKCu54Um4lFA0eSaRa3XxdAJg8tIdxbu1ubW0hBCZUL7yI2uGyYCRndvbK8FLHzqy2XKfeMsg==}
|
||||
/unplugin@1.10.2:
|
||||
resolution: {integrity: sha512-KuPqnjU4HBcrSwmQatfdc5hU4xzaQrhoKqCKylwmLnbBvqj5udXL8cHrkOuYDoI4ESCwJIiAIKMujroIUKLgow==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
dependencies:
|
||||
acorn: 8.12.0
|
||||
@@ -5872,7 +5876,7 @@ packages:
|
||||
spdx-expression-parse: 3.0.1
|
||||
dev: true
|
||||
|
||||
/vite-plugin-pwa@0.20.0(vite@5.3.1)(workbox-build@7.1.1)(workbox-window@7.1.0):
|
||||
/vite-plugin-pwa@0.20.0(vite@5.3.2)(workbox-build@7.1.1)(workbox-window@7.1.0):
|
||||
resolution: {integrity: sha512-/kDZyqF8KqoXRpMUQtR5Atri/7BWayW8Gp7Kz/4bfstsV6zSFTxjREbXZYL7zSuRL40HGA+o2hvUAFRmC+bL7g==}
|
||||
engines: {node: '>=16.0.0'}
|
||||
peerDependencies:
|
||||
@@ -5887,14 +5891,14 @@ packages:
|
||||
debug: 4.3.5
|
||||
fast-glob: 3.3.2
|
||||
pretty-bytes: 6.1.1
|
||||
vite: 5.3.1
|
||||
vite: 5.3.2
|
||||
workbox-build: 7.1.1
|
||||
workbox-window: 7.1.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/vite-plugin-solid@2.10.2(solid-js@1.8.17)(vite@5.3.1):
|
||||
/vite-plugin-solid@2.10.2(solid-js@1.8.18)(vite@5.3.2):
|
||||
resolution: {integrity: sha512-AOEtwMe2baBSXMXdo+BUwECC8IFHcKS6WQV/1NEd+Q7vHPap5fmIhLcAzr+DUJ04/KHx/1UBU0l1/GWP+rMAPQ==}
|
||||
peerDependencies:
|
||||
'@testing-library/jest-dom': ^5.16.6 || ^5.17.0 || ^6.*
|
||||
@@ -5906,18 +5910,18 @@ packages:
|
||||
dependencies:
|
||||
'@babel/core': 7.24.7
|
||||
'@types/babel__core': 7.20.5
|
||||
babel-preset-solid: 1.8.17(@babel/core@7.24.7)
|
||||
babel-preset-solid: 1.8.18(@babel/core@7.24.7)
|
||||
merge-anything: 5.1.7
|
||||
solid-js: 1.8.17
|
||||
solid-refresh: 0.6.3(solid-js@1.8.17)
|
||||
vite: 5.3.1
|
||||
vitefu: 0.2.5(vite@5.3.1)
|
||||
solid-js: 1.8.18
|
||||
solid-refresh: 0.6.3(solid-js@1.8.18)
|
||||
vite: 5.3.2
|
||||
vitefu: 0.2.5(vite@5.3.2)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/vite@5.3.1:
|
||||
resolution: {integrity: sha512-XBmSKRLXLxiaPYamLv3/hnP/KXDai1NDexN0FpkTaZXTfycHvkRHoenpgl/fvuK/kPbB6xAgoyiryAhQNxYmAQ==}
|
||||
/vite@5.3.2:
|
||||
resolution: {integrity: sha512-6lA7OBHBlXUxiJxbO5aAY2fsHHzDr1q7DvXYnyZycRs2Dz+dXBWuhpWHvmljTRTpQC2uvGmUFFkSHF2vGo90MA==}
|
||||
engines: {node: ^18.0.0 || >=20.0.0}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
@@ -5945,13 +5949,13 @@ packages:
|
||||
optional: true
|
||||
dependencies:
|
||||
esbuild: 0.21.5
|
||||
postcss: 8.4.38
|
||||
postcss: 8.4.39
|
||||
rollup: 4.18.0
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.3
|
||||
dev: true
|
||||
|
||||
/vitefu@0.2.5(vite@5.3.1):
|
||||
/vitefu@0.2.5(vite@5.3.2):
|
||||
resolution: {integrity: sha512-SgHtMLoqaeeGnd2evZ849ZbACbnwQCIwRH57t18FxcXoZop0uQu0uzlIhJBlF/eWVzuce0sHeqPcDo+evVcg8Q==}
|
||||
peerDependencies:
|
||||
vite: ^3.0.0 || ^4.0.0 || ^5.0.0
|
||||
@@ -5959,7 +5963,7 @@ packages:
|
||||
vite:
|
||||
optional: true
|
||||
dependencies:
|
||||
vite: 5.3.1
|
||||
vite: 5.3.2
|
||||
dev: true
|
||||
|
||||
/webidl-conversions@3.0.1:
|
||||
@@ -6169,36 +6173,37 @@ packages:
|
||||
workbox-core: 7.1.0
|
||||
dev: true
|
||||
|
||||
/workerd@1.20240610.1:
|
||||
resolution: {integrity: sha512-Rtut5GrsODQMh6YU43b9WZ980Wd05Ov1/ds88pT/SoetmXFBvkBzdRfiHiATv+azmGX8KveE0i/Eqzk/yI01ug==}
|
||||
/workerd@1.20240620.1:
|
||||
resolution: {integrity: sha512-Qoq+RrFNk4pvEO+kpJVn8uJ5TRE9YJx5jX5pC5LjdKlw1XeD8EdXt5k0TbByvWunZ4qgYIcF9lnVxhcDFo203g==}
|
||||
engines: {node: '>=16'}
|
||||
hasBin: true
|
||||
requiresBuild: true
|
||||
optionalDependencies:
|
||||
'@cloudflare/workerd-darwin-64': 1.20240610.1
|
||||
'@cloudflare/workerd-darwin-arm64': 1.20240610.1
|
||||
'@cloudflare/workerd-linux-64': 1.20240610.1
|
||||
'@cloudflare/workerd-linux-arm64': 1.20240610.1
|
||||
'@cloudflare/workerd-windows-64': 1.20240610.1
|
||||
'@cloudflare/workerd-darwin-64': 1.20240620.1
|
||||
'@cloudflare/workerd-darwin-arm64': 1.20240620.1
|
||||
'@cloudflare/workerd-linux-64': 1.20240620.1
|
||||
'@cloudflare/workerd-linux-arm64': 1.20240620.1
|
||||
'@cloudflare/workerd-windows-64': 1.20240620.1
|
||||
dev: true
|
||||
|
||||
/wrangler@3.61.0:
|
||||
resolution: {integrity: sha512-feVAp0986x9xL3Dc1zin0ZVXKaqzp7eZur7iPLnpEwjG1Xy4dkVEZ5a1LET94Iyejt1P+EX5lgGcz63H7EfzUw==}
|
||||
/wrangler@3.62.0:
|
||||
resolution: {integrity: sha512-TM1Bd8+GzxFw/JzwsC3i/Oss4LTWvIEWXXo1vZhx+7PHcsxdbnQGBBwPurHNJDSu2Pw22+2pCZiUGKexmgJksw==}
|
||||
engines: {node: '>=16.17.0'}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
'@cloudflare/workers-types': ^4.20240605.0
|
||||
'@cloudflare/workers-types': ^4.20240620.0
|
||||
peerDependenciesMeta:
|
||||
'@cloudflare/workers-types':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@cloudflare/kv-asset-handler': 0.3.3
|
||||
'@cloudflare/kv-asset-handler': 0.3.4
|
||||
'@esbuild-plugins/node-globals-polyfill': 0.2.3(esbuild@0.17.19)
|
||||
'@esbuild-plugins/node-modules-polyfill': 0.2.2(esbuild@0.17.19)
|
||||
blake3-wasm: 2.1.5
|
||||
chokidar: 3.6.0
|
||||
date-fns: 3.6.0
|
||||
esbuild: 0.17.19
|
||||
miniflare: 3.20240610.1
|
||||
miniflare: 3.20240620.0
|
||||
nanoid: 3.3.7
|
||||
path-to-regexp: 6.2.2
|
||||
resolve: 1.22.8
|
||||
|
||||
@@ -40,50 +40,47 @@ const texts = [
|
||||
"absolute scarcity",
|
||||
];
|
||||
|
||||
export const LOCAL_STORAGE_MARQUEE_KEY = "bg-marquee";
|
||||
|
||||
export function Background({
|
||||
marquee: on,
|
||||
mode,
|
||||
opacity,
|
||||
focused,
|
||||
}: {
|
||||
marquee: Accessor<boolean>;
|
||||
mode: SL<"Scroll" | "Static">;
|
||||
opacity: SL<{ text: string; value: number }>;
|
||||
focused: Accessor<boolean>;
|
||||
}) {
|
||||
createEffect(() => {
|
||||
if (on()) {
|
||||
localStorage.removeItem(LOCAL_STORAGE_MARQUEE_KEY);
|
||||
} else {
|
||||
localStorage.setItem(LOCAL_STORAGE_MARQUEE_KEY, "false");
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
<div class="absolute h-full w-full overflow-hidden opacity-[0.0333] will-change-auto">
|
||||
<div
|
||||
class="absolute h-full w-full overflow-hidden will-change-auto"
|
||||
style={{
|
||||
opacity: opacity.selected().value,
|
||||
}}
|
||||
>
|
||||
<div class="-m-[2rem] -space-y-1 overflow-hidden md:-m-[1rem]">
|
||||
<Line on={on} focused={focused} />
|
||||
<Line on={on} focused={focused} />
|
||||
<Line on={on} focused={focused} />
|
||||
<Line on={on} focused={focused} />
|
||||
<Line on={on} focused={focused} />
|
||||
<Line on={on} focused={focused} />
|
||||
<Line on={on} focused={focused} />
|
||||
<Line on={on} focused={focused} />
|
||||
<Line on={on} focused={focused} />
|
||||
<Line on={on} focused={focused} />
|
||||
<Line on={on} focused={focused} />
|
||||
<Line on={on} focused={focused} />
|
||||
<Line on={on} focused={focused} />
|
||||
<Line on={on} focused={focused} />
|
||||
<Line on={on} focused={focused} />
|
||||
<Line on={on} focused={focused} />
|
||||
<Line on={on} focused={focused} />
|
||||
<Line on={on} focused={focused} />
|
||||
<Line on={on} focused={focused} />
|
||||
<Line on={on} focused={focused} />
|
||||
<Line on={on} focused={focused} />
|
||||
<Line on={on} focused={focused} />
|
||||
<Line on={on} focused={focused} />
|
||||
<Line mode={mode} focused={focused} />
|
||||
<Line mode={mode} focused={focused} />
|
||||
<Line mode={mode} focused={focused} />
|
||||
<Line mode={mode} focused={focused} />
|
||||
<Line mode={mode} focused={focused} />
|
||||
<Line mode={mode} focused={focused} />
|
||||
<Line mode={mode} focused={focused} />
|
||||
<Line mode={mode} focused={focused} />
|
||||
<Line mode={mode} focused={focused} />
|
||||
<Line mode={mode} focused={focused} />
|
||||
<Line mode={mode} focused={focused} />
|
||||
<Line mode={mode} focused={focused} />
|
||||
<Line mode={mode} focused={focused} />
|
||||
<Line mode={mode} focused={focused} />
|
||||
<Line mode={mode} focused={focused} />
|
||||
<Line mode={mode} focused={focused} />
|
||||
<Line mode={mode} focused={focused} />
|
||||
<Line mode={mode} focused={focused} />
|
||||
<Line mode={mode} focused={focused} />
|
||||
<Line mode={mode} focused={focused} />
|
||||
<Line mode={mode} focused={focused} />
|
||||
<Line mode={mode} focused={focused} />
|
||||
<Line mode={mode} focused={focused} />
|
||||
</div>
|
||||
</div>
|
||||
<div class="absolute h-full w-full opacity-10 mix-blend-multiply">
|
||||
@@ -97,10 +94,10 @@ export function Background({
|
||||
}
|
||||
|
||||
function Line({
|
||||
on,
|
||||
mode,
|
||||
focused,
|
||||
}: {
|
||||
on: Accessor<boolean>;
|
||||
mode: SL<"Scroll" | "Static">;
|
||||
focused: Accessor<boolean>;
|
||||
}) {
|
||||
const shuffled = shuffle([...texts]);
|
||||
@@ -109,17 +106,17 @@ function Line({
|
||||
|
||||
return (
|
||||
<div class="select-none whitespace-nowrap">
|
||||
<TextWrapper on={on} focused={focused} joined={joined} />
|
||||
<TextWrapper mode={mode} focused={focused} joined={joined} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function TextWrapper({
|
||||
joined,
|
||||
on,
|
||||
mode,
|
||||
focused,
|
||||
}: {
|
||||
on: Accessor<boolean>;
|
||||
mode: SL<"Scroll" | "Static">;
|
||||
focused: Accessor<boolean>;
|
||||
joined: string;
|
||||
}) {
|
||||
@@ -128,7 +125,7 @@ function TextWrapper({
|
||||
const wasOnceOn = createRWS(false);
|
||||
|
||||
createEffect(() => {
|
||||
if (!wasOnceOn() && on()) {
|
||||
if (!wasOnceOn() && mode.selected() === "Scroll") {
|
||||
wasOnceOn.set(true);
|
||||
}
|
||||
});
|
||||
@@ -140,7 +137,10 @@ function TextWrapper({
|
||||
...(wasOnceOn()
|
||||
? {
|
||||
animation: `marquee ${seconds}s linear infinite`,
|
||||
"animation-play-state": focused() && on() ? "running" : "paused",
|
||||
"animation-play-state":
|
||||
focused() && mode.selected() === "Scroll"
|
||||
? "running"
|
||||
: "paused",
|
||||
}
|
||||
: {}),
|
||||
}}
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
import { createResizeObserver } from "@solid-primitives/resize-observer";
|
||||
|
||||
import { classPropToString } from "/src/solid/classes";
|
||||
import { createRWS } from "/src/solid/rws";
|
||||
|
||||
export function Box({
|
||||
flex = true,
|
||||
@@ -9,45 +6,14 @@ export function Box({
|
||||
padded = true,
|
||||
children,
|
||||
dark,
|
||||
overflowY,
|
||||
classes,
|
||||
}: {
|
||||
flex?: boolean;
|
||||
absolute?: "top" | "bottom";
|
||||
padded?: boolean;
|
||||
dark?: boolean;
|
||||
overflowY?: boolean;
|
||||
classes?: string;
|
||||
} & ParentProps) {
|
||||
const maybeScrollable = createRWS<HTMLDivElement | undefined>(undefined);
|
||||
const scrollable = createRWS(false);
|
||||
const showLeftArrow = createRWS(false);
|
||||
const showRightArrow = createRWS(false);
|
||||
|
||||
onMount(() => {
|
||||
createResizeObserver(maybeScrollable, (_, el) => {
|
||||
if (el !== maybeScrollable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
scrollable.set(() => el.scrollWidth > el.clientWidth);
|
||||
|
||||
checkArrows();
|
||||
});
|
||||
});
|
||||
|
||||
function checkArrows() {
|
||||
const offset = 20;
|
||||
|
||||
const target = maybeScrollable()!;
|
||||
|
||||
const left = target.scrollLeft;
|
||||
const right = target.scrollWidth - target.scrollLeft - target.clientWidth;
|
||||
|
||||
showLeftArrow.set(() => left > offset);
|
||||
showRightArrow.set(() => right > offset);
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
class={classPropToString([
|
||||
@@ -57,7 +23,7 @@ export function Box({
|
||||
"absolute inset-x-0",
|
||||
absolute === "top"
|
||||
? "top-0"
|
||||
: "pointer-events-none bottom-0 bg-gradient-to-b from-transparent to-black",
|
||||
: "pointer-events-none bottom-0 bg-gradient-to-b from-transparent to-orange-100 dark:to-black",
|
||||
]
|
||||
: "relative",
|
||||
classes,
|
||||
@@ -65,87 +31,15 @@ export function Box({
|
||||
>
|
||||
<div
|
||||
class={classPropToString([
|
||||
"pointer-events-auto relative overflow-hidden rounded-xl border border-orange-200/10 shadow-md",
|
||||
"border-lighter pointer-events-auto relative overflow-hidden rounded-xl border shadow-md",
|
||||
dark
|
||||
? "bg-orange-100/5 backdrop-blur-sm"
|
||||
: "bg-orange-200/10 backdrop-blur-md",
|
||||
? "bg-white/40 backdrop-blur-sm dark:bg-orange-100/5"
|
||||
: "bg-white/60 backdrop-blur-md dark:bg-orange-200/10",
|
||||
])}
|
||||
>
|
||||
<For
|
||||
each={[
|
||||
{
|
||||
showArrow: showLeftArrow,
|
||||
side: "left-0",
|
||||
order: "",
|
||||
buttonPadding: "pl-3 pr-2",
|
||||
iconPadding: "pr-0.5",
|
||||
scrollMultiplier: -1,
|
||||
chevronIcon: IconTablerChevronLeft,
|
||||
gradientDirection: "bg-gradient-to-r",
|
||||
},
|
||||
{
|
||||
showArrow: showRightArrow,
|
||||
side: "right-0",
|
||||
order: "order-2",
|
||||
buttonPadding: "pl-2 pr-3",
|
||||
iconPadding: "pl-0.5",
|
||||
scrollMultiplier: 1,
|
||||
chevronIcon: IconTablerChevronRight,
|
||||
gradientDirection: "bg-gradient-to-l",
|
||||
},
|
||||
]}
|
||||
>
|
||||
{(obj) => (
|
||||
<Show when={scrollable() && obj.showArrow()}>
|
||||
<div
|
||||
class={[
|
||||
obj.side,
|
||||
"pointer-events-none absolute bottom-0 top-0 z-20 flex transition-opacity duration-200 ease-in-out",
|
||||
].join(" ")}
|
||||
>
|
||||
<div
|
||||
class={[
|
||||
obj.order,
|
||||
obj.buttonPadding,
|
||||
"pointer-events-auto hidden h-full items-center bg-black/90 md:flex",
|
||||
].join(" ")}
|
||||
>
|
||||
<button
|
||||
onClick={() => {
|
||||
maybeScrollable()?.scrollBy({
|
||||
left: Math.floor(
|
||||
maybeScrollable()!.clientWidth *
|
||||
obj.scrollMultiplier *
|
||||
0.8,
|
||||
),
|
||||
behavior: "smooth",
|
||||
});
|
||||
}}
|
||||
class="rounded-full border border-orange-200/20 bg-black p-0.5 transition hover:scale-110 active:scale-100"
|
||||
>
|
||||
<Dynamic
|
||||
component={obj.chevronIcon}
|
||||
class={[`size-5 ${obj.iconPadding}`]}
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class={[
|
||||
obj.gradientDirection,
|
||||
"h-full w-10 from-black/90 to-transparent",
|
||||
].join(" ")}
|
||||
/>
|
||||
</div>
|
||||
</Show>
|
||||
)}
|
||||
</For>
|
||||
|
||||
<div
|
||||
ref={maybeScrollable.set}
|
||||
onScroll={checkArrows}
|
||||
class={classPropToString([
|
||||
flex && "flex w-full space-x-2",
|
||||
overflowY && "overflow-y-auto",
|
||||
padded && "p-1.5",
|
||||
])}
|
||||
>
|
||||
|
||||
@@ -17,7 +17,7 @@ export function Actions({
|
||||
);
|
||||
|
||||
return (
|
||||
<div class="flex space-x-1">
|
||||
<div class="flex space-x-1 p-1.5">
|
||||
<Show when={fullscreen}>
|
||||
{(fullscreen) => (
|
||||
<Button
|
||||
|
||||
@@ -12,6 +12,8 @@ export function ButtonShare({ qrcode }: { qrcode: RWS<string> }) {
|
||||
generate(document.location.href).toDataURL({
|
||||
on: [0xff, 0xff, 0xff, 0xff],
|
||||
off: [0x00, 0x00, 0x00, 0x00],
|
||||
padX: 0,
|
||||
padY: 0,
|
||||
}),
|
||||
);
|
||||
}}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { cleanChart } from "/src/scripts/lightweightCharts/chart/clean";
|
||||
import { renderChart } from "/src/scripts/lightweightCharts/chart/render";
|
||||
|
||||
export function Chart({
|
||||
charts,
|
||||
parentDiv,
|
||||
presets,
|
||||
datasets,
|
||||
legendSetter,
|
||||
activeResources,
|
||||
}: {
|
||||
charts: RWS<IChartApi[]>;
|
||||
parentDiv: RWS<HTMLDivElement | undefined>;
|
||||
presets: Presets;
|
||||
datasets: Datasets;
|
||||
legendSetter: Setter<PresetLegend>;
|
||||
@@ -15,19 +16,37 @@ export function Chart({
|
||||
onMount(() => {
|
||||
createEffect(() => {
|
||||
const preset = presets.selected();
|
||||
const div = parentDiv();
|
||||
|
||||
untrack(() =>
|
||||
renderChart({
|
||||
datasets,
|
||||
preset,
|
||||
legendSetter,
|
||||
activeResources,
|
||||
}),
|
||||
);
|
||||
if (!div) return;
|
||||
|
||||
untrack(() => {
|
||||
try {
|
||||
console.log(`preset: ${preset.id}`);
|
||||
preset.applyPreset({
|
||||
charts,
|
||||
parentDiv: div,
|
||||
datasets,
|
||||
preset,
|
||||
activeResources,
|
||||
legendSetter,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("chart: render: failed", error);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
onCleanup(cleanChart);
|
||||
onCleanup(() =>
|
||||
charts.set((charts) => {
|
||||
charts.forEach((chart) => {
|
||||
chart.remove();
|
||||
});
|
||||
|
||||
return [];
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
return <div id="chart" class="h-full w-full cursor-crosshair" />;
|
||||
return <></>;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { createRWS } from "/src/solid/rws";
|
||||
|
||||
const transparency = "66";
|
||||
import { Scrollable } from "../../scrollable";
|
||||
|
||||
const transparency = "44";
|
||||
|
||||
export function Legend({
|
||||
legend: legendList,
|
||||
@@ -12,7 +14,7 @@ export function Legend({
|
||||
let toggle = false;
|
||||
|
||||
return (
|
||||
<div class="-my-1.5 -ml-1.5 flex flex-1 items-center gap-1 overflow-y-auto p-1.5">
|
||||
<Scrollable classes="flex flex-1 items-center gap-1 p-1.5">
|
||||
<For each={legendList()}>
|
||||
{(legend) => {
|
||||
const initialColors = {} as any;
|
||||
@@ -44,7 +46,9 @@ export function Legend({
|
||||
<Show when={!legend.disabled()}>
|
||||
<button
|
||||
onMouseEnter={() => {
|
||||
hovering.set(legend);
|
||||
if (legend.visible()) {
|
||||
hovering.set(legend);
|
||||
}
|
||||
}}
|
||||
onMouseLeave={() => hovering.set(undefined)}
|
||||
onTouchEnd={() => hovering.set(undefined)}
|
||||
@@ -66,8 +70,14 @@ export function Legend({
|
||||
}
|
||||
|
||||
previousClickValueOf = currentClickValueOf;
|
||||
|
||||
if (legend.visible()) {
|
||||
hovering.set(legend);
|
||||
} else {
|
||||
hovering.set(undefined);
|
||||
}
|
||||
}}
|
||||
class="flex flex-none items-center space-x-1.5 rounded-full py-1.5 pl-2 pr-2.5 hover:bg-orange-200/20 active:scale-[0.975]"
|
||||
class="flex flex-none items-center space-x-1.5 rounded-full py-1.5 pl-2 pr-2.5 hover:bg-orange-800/20 active:scale-[0.975] dark:hover:bg-orange-200/20"
|
||||
>
|
||||
<span
|
||||
class="flex size-4 flex-col overflow-hidden rounded-full"
|
||||
@@ -93,7 +103,7 @@ export function Legend({
|
||||
</For>
|
||||
</span>
|
||||
<span
|
||||
class="text-white decoration-white decoration-wavy decoration-[1.5px]"
|
||||
class="text-high-contrast decoration-high-contrast decoration-wavy decoration-[1.5px]"
|
||||
style={{
|
||||
"text-decoration-line": !legend.visible()
|
||||
? "line-through"
|
||||
@@ -107,10 +117,7 @@ export function Legend({
|
||||
{(url) => (
|
||||
<a
|
||||
title="Dataset"
|
||||
class="-my-0.5 !-mr-1 inline-flex size-6 flex-col overflow-hidden rounded-full border border-orange-200/5 bg-orange-200 bg-opacity-5 p-1 pl-0.5 hover:bg-opacity-30"
|
||||
style={{
|
||||
opacity: legend.visible() ? 1 : 0.5,
|
||||
}}
|
||||
class="border-superlight -my-0.5 !-mr-1 inline-flex size-6 flex-col overflow-hidden rounded-full border bg-white bg-opacity-5 p-1 pl-0.5 hover:bg-opacity-50 dark:bg-orange-200 dark:bg-opacity-5 dark:hover:bg-opacity-25"
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
// event.preventDefault();
|
||||
@@ -131,6 +138,6 @@ export function Legend({
|
||||
);
|
||||
}}
|
||||
</For>
|
||||
</div>
|
||||
</Scrollable>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,63 +1,134 @@
|
||||
import { chartState } from "/src/scripts/lightweightCharts/chart/state";
|
||||
import { GENESIS_DAY } from "/src/scripts/lightweightCharts/chart/whitespace";
|
||||
import { ONE_DAY_IN_MS } from "/src/scripts/utils/time";
|
||||
import { classPropToString } from "/src/solid/classes";
|
||||
|
||||
import { Box } from "../../box";
|
||||
import { Scrollable } from "../../scrollable";
|
||||
|
||||
export function TimeScale() {
|
||||
export function TimeScale({ charts }: { charts: RWS<IChartApi[]> }) {
|
||||
const today = new Date();
|
||||
|
||||
const disabled = createMemo(() => charts().length === 0);
|
||||
|
||||
return (
|
||||
<Box dark padded overflowY classes="short:hidden">
|
||||
<Button onClick={() => setTimeScale({})}>All Time</Button>
|
||||
<Button onClick={() => setTimeScale({ days: 7 })}>1 Week</Button>
|
||||
<Button onClick={() => setTimeScale({ days: 30 })}>1 Month</Button>
|
||||
<Button onClick={() => setTimeScale({ days: 30 * 6 })}>6 Months</Button>
|
||||
<Button
|
||||
onClick={() =>
|
||||
setTimeScale({
|
||||
days: Math.ceil(
|
||||
(today.valueOf() -
|
||||
new Date(`${today.getUTCFullYear()}-01-01`).valueOf()) /
|
||||
ONE_DAY_IN_MS,
|
||||
),
|
||||
})
|
||||
}
|
||||
>
|
||||
Year To Date
|
||||
</Button>
|
||||
<Button onClick={() => setTimeScale({ days: 365 })}>1 Year</Button>
|
||||
<Button onClick={() => setTimeScale({ days: 2 * 365 })}>2 Years</Button>
|
||||
<Button onClick={() => setTimeScale({ days: 4 * 365 })}>4 Years</Button>
|
||||
<Button onClick={() => setTimeScale({ days: 8 * 365 })}>8 Years</Button>
|
||||
<For
|
||||
each={new Array(
|
||||
new Date().getFullYear() - new Date("2009-01-01").getFullYear(),
|
||||
)
|
||||
.fill(0)
|
||||
.map((_, index) => index + 2009)
|
||||
.reverse()}
|
||||
>
|
||||
{(year) => (
|
||||
<Button onClick={() => setTimeScale({ year })}>{year}</Button>
|
||||
)}
|
||||
</For>
|
||||
<Box dark padded={false} classes="short:hidden">
|
||||
<Scrollable classes="p-1.5 space-x-2">
|
||||
<Button disabled={disabled} onClick={() => setTimeScale({ charts })}>
|
||||
All Time
|
||||
</Button>
|
||||
<Button
|
||||
disabled={disabled}
|
||||
onClick={() => setTimeScale({ charts, days: 7 })}
|
||||
>
|
||||
1 Week
|
||||
</Button>
|
||||
<Button
|
||||
disabled={disabled}
|
||||
onClick={() => setTimeScale({ charts, days: 30 })}
|
||||
>
|
||||
1 Month
|
||||
</Button>
|
||||
<Button
|
||||
disabled={disabled}
|
||||
onClick={() => setTimeScale({ charts, days: 3 * 30 })}
|
||||
>
|
||||
3 Months
|
||||
</Button>
|
||||
<Button
|
||||
disabled={disabled}
|
||||
onClick={() => setTimeScale({ charts, days: 6 * 30 })}
|
||||
>
|
||||
6 Months
|
||||
</Button>
|
||||
<Button
|
||||
disabled={disabled}
|
||||
onClick={() =>
|
||||
setTimeScale({
|
||||
charts,
|
||||
days: Math.ceil(
|
||||
(today.valueOf() -
|
||||
new Date(`${today.getUTCFullYear()}-01-01`).valueOf()) /
|
||||
ONE_DAY_IN_MS,
|
||||
),
|
||||
})
|
||||
}
|
||||
>
|
||||
Year To Date
|
||||
</Button>
|
||||
<Button
|
||||
disabled={disabled}
|
||||
onClick={() => setTimeScale({ charts, days: 365 })}
|
||||
>
|
||||
1 Year
|
||||
</Button>
|
||||
<Button
|
||||
disabled={disabled}
|
||||
onClick={() => setTimeScale({ charts, days: 2 * 365 })}
|
||||
>
|
||||
2 Years
|
||||
</Button>
|
||||
<Button
|
||||
disabled={disabled}
|
||||
onClick={() => setTimeScale({ charts, days: 4 * 365 })}
|
||||
>
|
||||
4 Years
|
||||
</Button>
|
||||
<Button
|
||||
disabled={disabled}
|
||||
onClick={() => setTimeScale({ charts, days: 8 * 365 })}
|
||||
>
|
||||
8 Years
|
||||
</Button>
|
||||
<For
|
||||
each={new Array(
|
||||
new Date().getFullYear() - new Date("2009-01-01").getFullYear(),
|
||||
)
|
||||
.fill(0)
|
||||
.map((_, index) => index + 2009)
|
||||
.reverse()}
|
||||
>
|
||||
{(year) => (
|
||||
<Button
|
||||
disabled={disabled}
|
||||
onClick={() => setTimeScale({ charts, year })}
|
||||
>
|
||||
{year}
|
||||
</Button>
|
||||
)}
|
||||
</For>
|
||||
</Scrollable>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
function Button(props: ParentProps & { onClick: VoidFunction }) {
|
||||
function Button({
|
||||
onClick,
|
||||
disabled,
|
||||
children,
|
||||
}: ParentProps & { onClick: VoidFunction; disabled: Accessor<boolean> }) {
|
||||
return (
|
||||
<button
|
||||
class="min-w-20 flex-shrink-0 flex-grow whitespace-nowrap rounded-lg px-2 py-1.5 hover:bg-white/20 active:scale-95"
|
||||
onClick={props.onClick}
|
||||
class={classPropToString([
|
||||
disabled() ? "opacity-50" : "hover:bg-orange-50/20 active:scale-95",
|
||||
"min-w-20 flex-shrink-0 flex-grow whitespace-nowrap rounded-lg px-2 py-1.5",
|
||||
])}
|
||||
onClick={onClick}
|
||||
disabled={disabled()}
|
||||
>
|
||||
{props.children}
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
function setTimeScale({ days, year }: { days?: number; year?: number }) {
|
||||
function setTimeScale({
|
||||
charts,
|
||||
days,
|
||||
year,
|
||||
}: {
|
||||
charts: RWS<IChartApi[]>;
|
||||
days?: number;
|
||||
year?: number;
|
||||
}) {
|
||||
let from = new Date();
|
||||
let to = new Date();
|
||||
|
||||
@@ -70,12 +141,10 @@ function setTimeScale({ days, year }: { days?: number; year?: number }) {
|
||||
from = new Date(GENESIS_DAY);
|
||||
}
|
||||
|
||||
setRange({
|
||||
from: (from.getTime() / 1000) as Time,
|
||||
to: (to.getTime() / 1000) as Time,
|
||||
});
|
||||
}
|
||||
|
||||
function setRange(range: TimeRange) {
|
||||
chartState.chart?.timeScale().setVisibleRange(range);
|
||||
charts()[0]
|
||||
.timeScale()
|
||||
.setVisibleRange({
|
||||
from: (from.getTime() / 1000) as Time,
|
||||
to: (to.getTime() / 1000) as Time,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
export function Title({ presets }: { presets: Presets }) {
|
||||
return (
|
||||
<div class="flex flex-1 items-center overflow-y-auto pb-1.5 text-orange-100/50">
|
||||
<div class="flex flex-1 items-center overflow-y-auto p-1.5">
|
||||
<div class="flex-1 -space-y-1 whitespace-nowrap px-1 md:mt-0.5 md:-space-y-1.5">
|
||||
<h3 class="text-xs">{`/ ${[...presets.selected().path.map(({ name }) => name), presets.selected().name].join(" / ")}`}</h3>
|
||||
<h1 class="text-lg font-bold text-white md:text-xl">
|
||||
{presets.selected().title}
|
||||
</h1>
|
||||
<h3 class="text-xs opacity-50">{`/ ${[...presets.selected().path.map(({ name }) => name), presets.selected().name].join(" / ")}`}</h3>
|
||||
<h1 class="text-lg font-bold md:text-xl">{presets.selected().title}</h1>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -27,6 +27,10 @@ export function ChartFrame({
|
||||
}) {
|
||||
const legend = createRWS<PresetLegend>([]);
|
||||
|
||||
const charts = createRWS<IChartApi[]>([]);
|
||||
|
||||
const div = createRWS<HTMLDivElement | undefined>(undefined);
|
||||
|
||||
const Chart = lazy(() =>
|
||||
import("./components/chart").then((d) => ({ default: d.Chart })),
|
||||
);
|
||||
@@ -35,29 +39,31 @@ export function ChartFrame({
|
||||
<div
|
||||
class={classPropToString([
|
||||
standalone &&
|
||||
"rounded-2xl border border-orange-200/15 bg-gradient-to-b from-orange-100/5 to-black/10 to-80%",
|
||||
"border-lighter rounded-2xl border bg-gradient-to-b from-white/15 to-white/30 to-80% shadow-md dark:from-orange-100/5 dark:to-black/10",
|
||||
"flex size-full min-h-0 flex-1 flex-col overflow-hidden",
|
||||
])}
|
||||
style={{
|
||||
display: (hide ? hide() : false) ? "none" : undefined,
|
||||
}}
|
||||
>
|
||||
<Box flex={false} dark classes="short:hidden">
|
||||
<Box flex={false} dark padded={false} classes="short:hidden">
|
||||
<Title presets={presets} />
|
||||
|
||||
<div class="-mx-2 border-t border-orange-200/15" />
|
||||
<div class="border-lighter border-t" />
|
||||
|
||||
<div class="flex pt-1.5">
|
||||
<div class="flex">
|
||||
<Legend legend={legend} />
|
||||
|
||||
<div class="-my-1.5 border-l border-orange-200/15 pr-1.5" />
|
||||
<div class="border-lighter border-l" />
|
||||
|
||||
<Actions presets={presets} qrcode={qrcode} fullscreen={fullscreen} />
|
||||
</div>
|
||||
</Box>
|
||||
|
||||
<div class="-mt-2 min-h-0 flex-1">
|
||||
<div ref={div.set} class="-mr-2 -mt-2 flex min-h-0 flex-1 flex-col">
|
||||
<Chart
|
||||
parentDiv={div}
|
||||
charts={charts}
|
||||
activeResources={activeResources}
|
||||
datasets={datasets}
|
||||
legendSetter={legend.set}
|
||||
@@ -65,7 +71,7 @@ export function ChartFrame({
|
||||
/>
|
||||
</div>
|
||||
|
||||
<TimeScale />
|
||||
<TimeScale charts={charts} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ export function FavoritesFrame({
|
||||
favorites.
|
||||
</Header>
|
||||
|
||||
<div class="-mx-4 border-t border-orange-200/10" />
|
||||
<div class="border-lighter -mx-4 border-t" />
|
||||
|
||||
<div
|
||||
class="space-y-0.5 py-1"
|
||||
|
||||
+2
-2
@@ -26,10 +26,10 @@ export function Folder({
|
||||
name={name}
|
||||
icon={icon}
|
||||
onClick={onClick}
|
||||
classes={() => (open() ? "text-orange-100/75" : "")}
|
||||
classes={() => (open() ? "opacity-60" : "")}
|
||||
tail={() => (
|
||||
<Show when={!open()}>
|
||||
<span class="rounded-full bg-white bg-opacity-[0.075] px-2 py-0.5 text-xs text-neutral-400">
|
||||
<span class="rounded-full bg-orange-50/10 px-2 py-0.5 text-xs text-neutral-400">
|
||||
{children}
|
||||
</span>
|
||||
</Show>
|
||||
+3
-3
@@ -8,7 +8,7 @@ import { Header } from "../header";
|
||||
import { Number } from "../number";
|
||||
import { Tree } from "./components/tree";
|
||||
|
||||
export function TreeFrame({
|
||||
export function FoldersFrame({
|
||||
presets,
|
||||
selectedFrame,
|
||||
}: {
|
||||
@@ -25,7 +25,7 @@ export function TreeFrame({
|
||||
<div
|
||||
class="relative flex size-full flex-1 flex-col"
|
||||
style={{
|
||||
display: selectedFrame() !== "Tree" ? "none" : undefined,
|
||||
display: selectedFrame() !== "Folders" ? "none" : undefined,
|
||||
}}
|
||||
>
|
||||
<div class="flex-1 overflow-y-auto">
|
||||
@@ -35,7 +35,7 @@ export function TreeFrame({
|
||||
tree like structure.
|
||||
</Header>
|
||||
|
||||
<div class="-mx-4 border-t border-orange-200/10" />
|
||||
<div class="border-lighter -mx-4 border-t" />
|
||||
|
||||
<Tree
|
||||
tree={presets.tree}
|
||||
@@ -2,7 +2,7 @@ export function Header({ title, children }: { title: string } & ParentProps) {
|
||||
return (
|
||||
<div>
|
||||
<h3 class="text-lg font-bold md:text-xl">{title}</h3>
|
||||
<p class="text-orange-100/75">{children}</p>
|
||||
<p class="text-orange-950/60 dark:text-orange-100/75">{children}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -36,8 +36,8 @@ export function HistoryFrame({
|
||||
presets.history()[index() - 1].date.toJSON().split("T")[0]
|
||||
}
|
||||
>
|
||||
<div class="sticky top-[-0.5rem] z-10 -mx-4 py-2">
|
||||
<div class="border-y border-orange-200/10 bg-[rgb(25,15,15)] p-2">
|
||||
<div class="sticky top-[calc(-0.5rem-1px)] z-10 -mx-4 py-2">
|
||||
<div class="border-lighter border-y bg-[#F4EAE3] p-2 dark:bg-[rgb(25,15,15)]">
|
||||
<p class="ml-2">
|
||||
<Switch fallback={date.toLocaleDateString()}>
|
||||
<Match
|
||||
|
||||
@@ -45,9 +45,7 @@ export function Line({
|
||||
title={name}
|
||||
>
|
||||
<For each={new Array(depth)}>
|
||||
{() => (
|
||||
<span class="ml-1 h-8 w-3 flex-none border-l border-orange-200/10" />
|
||||
)}
|
||||
{() => <span class="border-lighter ml-1 h-8 w-3 flex-none border-l" />}
|
||||
</For>
|
||||
<Show when={icon}>
|
||||
{(icon) => (
|
||||
@@ -68,10 +66,7 @@ export function Line({
|
||||
])}
|
||||
>
|
||||
<Show when={header}>
|
||||
<span
|
||||
class="truncate text-xs text-white text-opacity-50"
|
||||
innerHTML={header}
|
||||
/>
|
||||
<span class="truncate text-xs opacity-50" innerHTML={header} />
|
||||
</Show>
|
||||
<span class="space-x-1 truncate">
|
||||
<span innerHTML={name} />
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
import { createResizeObserver } from "@solid-primitives/resize-observer";
|
||||
|
||||
import { touchScreen } from "/src/env";
|
||||
import { classPropToString } from "/src/solid/classes";
|
||||
import { createRWS } from "/src/solid/rws";
|
||||
|
||||
export function Scrollable({
|
||||
children,
|
||||
classes,
|
||||
}: {
|
||||
classes?: string;
|
||||
} & ParentProps) {
|
||||
const maybeScrollable = createRWS<HTMLDivElement | undefined>(undefined);
|
||||
const scrollable = createRWS(false);
|
||||
const showLeftArrow = createRWS(false);
|
||||
const showRightArrow = createRWS(false);
|
||||
|
||||
onMount(() => {
|
||||
createResizeObserver(maybeScrollable, (_, el) => {
|
||||
if (el !== maybeScrollable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
scrollable.set(() => el.scrollWidth > el.clientWidth);
|
||||
|
||||
checkArrows();
|
||||
});
|
||||
});
|
||||
|
||||
function checkArrows() {
|
||||
const target = maybeScrollable()!;
|
||||
|
||||
const left = target.scrollLeft;
|
||||
const right =
|
||||
target.scrollWidth - Math.ceil(target.scrollLeft + target.clientWidth);
|
||||
|
||||
showLeftArrow.set(() => left > 0);
|
||||
showRightArrow.set(() => right > 0);
|
||||
}
|
||||
|
||||
return (
|
||||
<div class="relative min-w-0 flex-1">
|
||||
<For
|
||||
each={[
|
||||
{
|
||||
showArrow: showLeftArrow,
|
||||
side: "left-0",
|
||||
order: "",
|
||||
buttonPadding: "pl-2",
|
||||
iconPadding: "pr-0.5",
|
||||
scrollMultiplier: -1,
|
||||
chevronIcon: IconTablerChevronLeft,
|
||||
gradientDirection: "bg-gradient-to-r",
|
||||
},
|
||||
{
|
||||
showArrow: showRightArrow,
|
||||
side: "right-0",
|
||||
order: "order-2",
|
||||
buttonPadding: "pr-2",
|
||||
iconPadding: "pl-0.5",
|
||||
scrollMultiplier: 1,
|
||||
chevronIcon: IconTablerChevronRight,
|
||||
gradientDirection: "bg-gradient-to-l",
|
||||
},
|
||||
]}
|
||||
>
|
||||
{(obj) => (
|
||||
<Show when={scrollable() && obj.showArrow()}>
|
||||
<div
|
||||
class={[
|
||||
obj.side,
|
||||
"pointer-events-none absolute bottom-0 top-0 flex transition-opacity duration-200 ease-in-out",
|
||||
].join(" ")}
|
||||
>
|
||||
<Show when={!touchScreen}>
|
||||
<div
|
||||
class={[
|
||||
obj.order,
|
||||
obj.buttonPadding,
|
||||
"pointer-events-auto flex h-full items-center bg-stone-100/75 dark:bg-stone-900/75",
|
||||
].join(" ")}
|
||||
>
|
||||
<button
|
||||
onClick={() => {
|
||||
maybeScrollable()?.scrollBy({
|
||||
left: Math.floor(
|
||||
maybeScrollable()!.clientWidth *
|
||||
obj.scrollMultiplier *
|
||||
0.75,
|
||||
),
|
||||
behavior: "smooth",
|
||||
});
|
||||
}}
|
||||
class="border-light rounded-full border bg-stone-100 p-0.5 shadow transition hover:scale-110 active:scale-100 dark:bg-stone-900"
|
||||
>
|
||||
<Dynamic
|
||||
component={obj.chevronIcon}
|
||||
class={[`size-5 ${obj.iconPadding}`]}
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</Show>
|
||||
<div
|
||||
class={[
|
||||
obj.gradientDirection,
|
||||
"h-full w-8 from-stone-100/75 to-transparent dark:from-stone-900/75",
|
||||
].join(" ")}
|
||||
/>
|
||||
</div>
|
||||
</Show>
|
||||
)}
|
||||
</For>
|
||||
|
||||
<div
|
||||
ref={maybeScrollable.set}
|
||||
onScroll={checkArrows}
|
||||
class={classPropToString([
|
||||
"no-scrollbar flex w-full overflow-x-auto",
|
||||
classes,
|
||||
])}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -135,7 +135,7 @@ export function SearchFrame({
|
||||
</p>
|
||||
|
||||
<Show when={search()}>
|
||||
<div class="-mx-4 border-t border-orange-200/10" />
|
||||
<div class="border-lighter -mx-4 border-t" />
|
||||
|
||||
<div
|
||||
class="py-1"
|
||||
@@ -176,7 +176,7 @@ export function SearchFrame({
|
||||
value={search()}
|
||||
onInput={(event) => search.set(event.target.value)}
|
||||
/>
|
||||
<span class="-mx-1 flex size-5 flex-none items-center justify-center rounded-md border border-white text-xs font-bold">
|
||||
<span class="-mx-1 flex size-5 flex-none items-center justify-center rounded-md border border-current text-xs font-bold">
|
||||
<IconTablerSlash />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -1,15 +1,30 @@
|
||||
import { version } from "/src/../package.json";
|
||||
import { classPropToString } from "/src/solid/classes";
|
||||
|
||||
import { Header } from "./header";
|
||||
|
||||
export function SettingsFrame({
|
||||
marquee,
|
||||
selectedFrame,
|
||||
appTheme,
|
||||
backgroundMode,
|
||||
backgroundOpacity,
|
||||
}: {
|
||||
marquee: RWS<boolean>;
|
||||
selectedFrame: Accessor<FrameName>;
|
||||
appTheme: SL<"System" | "Dark" | "Light">;
|
||||
backgroundMode: SL<"Scroll" | "Static">;
|
||||
backgroundOpacity: SL<{ text: string; value: number }>;
|
||||
}) {
|
||||
const value = marquee();
|
||||
createEffect(() => {
|
||||
if (
|
||||
appTheme.selected() === "Dark" ||
|
||||
(appTheme.selected() === "System" &&
|
||||
window.matchMedia("(prefers-color-scheme: dark)").matches)
|
||||
) {
|
||||
document.documentElement.classList.add("dark");
|
||||
} else {
|
||||
document.documentElement.classList.remove("dark");
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -19,28 +34,102 @@ export function SettingsFrame({
|
||||
}}
|
||||
>
|
||||
<div class="space-y-4 p-4">
|
||||
<Header title="Settings">And other stuff.</Header>
|
||||
<Header title="Settings">
|
||||
And other stuff <strong class="italic">NOT</strong> transmitted by
|
||||
relays.
|
||||
</Header>
|
||||
|
||||
<div class="-mx-4 border-t border-orange-200/10" />
|
||||
<div class="border-lighter -mx-4 border-t" />
|
||||
|
||||
<div class="space-y-2">
|
||||
<p>Background</p>
|
||||
<div>Opacity</div>
|
||||
<div>
|
||||
<label class="switch">
|
||||
Scroll
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={value}
|
||||
onChange={(event) => marquee.set(event.target.checked || false)}
|
||||
/>
|
||||
<span class="slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
<hr class="border-t border-orange-200/20" />
|
||||
<p>Version: {version}</p>
|
||||
<div class="space-y-4">
|
||||
<p class="text-base font-medium">General</p>
|
||||
|
||||
<RadioGroup
|
||||
title="Theme"
|
||||
ariaTitle="App's theme"
|
||||
description="Options for the app's theme"
|
||||
sl={appTheme}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="border-lighter -mx-4 border-t" />
|
||||
|
||||
<div class="space-y-4">
|
||||
<p class="text-base font-medium">Background</p>
|
||||
|
||||
<RadioGroup
|
||||
title="Mode"
|
||||
ariaTitle="Background mode"
|
||||
description="Options for how the background in displayed"
|
||||
sl={backgroundMode}
|
||||
/>
|
||||
|
||||
<RadioGroup
|
||||
title="Opacity"
|
||||
ariaTitle="Background mode"
|
||||
description="Options for the opacity of the text in the background"
|
||||
sl={backgroundOpacity}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<hr class="border-lighter -mx-4 border-t" />
|
||||
<p class="text-center">
|
||||
<span class="opacity-50">Version:</span> {version}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function RadioGroup<
|
||||
T extends
|
||||
| string
|
||||
| {
|
||||
text: string;
|
||||
value: number;
|
||||
},
|
||||
>({
|
||||
title,
|
||||
sl,
|
||||
ariaTitle,
|
||||
description,
|
||||
}: {
|
||||
title: string;
|
||||
ariaTitle: string;
|
||||
description: string;
|
||||
sl: SL<T>;
|
||||
}) {
|
||||
return (
|
||||
<fieldset aria-label={`Choose an option for: ${ariaTitle}`}>
|
||||
<p class="pb-0.5">{title}</p>
|
||||
|
||||
<p class="pb-1 text-sm opacity-50">{description}</p>
|
||||
|
||||
<div class="border-superlight -mx-2 mt-2 flex gap-1.5 rounded-lg border bg-stone-400/30 p-1.5 backdrop-blur-[2px] dark:bg-stone-950/75">
|
||||
<For each={sl.list()}>
|
||||
{(value) => (
|
||||
<label
|
||||
class={classPropToString([
|
||||
value === sl.selected()
|
||||
? "border-lighter bg-orange-50/75 shadow dark:bg-orange-200/10"
|
||||
: "border-transparent",
|
||||
"flex cursor-pointer select-none items-center justify-center rounded-md border px-3 py-1.5 font-medium hover:bg-orange-50 focus:outline-none active:scale-95 active:bg-orange-50 dark:hover:bg-orange-200/20 dark:active:bg-orange-200/10 sm:flex-1",
|
||||
])}
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
name={`${title}-option`}
|
||||
value={typeof value === "object" ? value.value : value}
|
||||
class="sr-only"
|
||||
onClick={() => {
|
||||
sl.select(value);
|
||||
}}
|
||||
/>
|
||||
<span>{typeof value === "object" ? value.text : value}</span>
|
||||
</label>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
</fieldset>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,25 +1,34 @@
|
||||
import { touchScreen } from "/src/env";
|
||||
|
||||
export function Qrcode({ qrcode }: { qrcode: RWS<string> }) {
|
||||
return (
|
||||
<Show when={qrcode()}>
|
||||
<div
|
||||
class="absolute inset-0 z-50 flex size-full justify-center bg-black"
|
||||
class="absolute inset-0 z-50 flex size-full items-center justify-center bg-black/50 backdrop-blur-md"
|
||||
onClick={() => {
|
||||
qrcode.set("");
|
||||
}}
|
||||
>
|
||||
<div class="flex size-full max-w-md flex-col items-center justify-center bg-black px-8 py-16 text-lg">
|
||||
<p class="pb-16 text-2xl font-bold">Share</p>
|
||||
<div class="flex size-full max-h-[80dvh] max-w-md flex-col justify-center space-y-8 px-8 pb-8 text-base">
|
||||
<p class="pb-4 text-center text-3xl font-bold">Share</p>
|
||||
|
||||
<div class="flex min-h-0 w-full flex-1 flex-col">
|
||||
<p>You can scan the following QR Code with a phone:</p>
|
||||
<p>
|
||||
To share this page, you can either send the following QR Code with a
|
||||
phone:
|
||||
</p>
|
||||
<div class="flex min-h-0 w-full flex-1 flex-col items-center justify-center">
|
||||
<img
|
||||
class="aspect-square min-h-0 flex-1 grow object-contain"
|
||||
onClick={(event) => {
|
||||
event?.stopPropagation();
|
||||
}}
|
||||
src={qrcode()}
|
||||
style={{ "image-rendering": "pixelated" }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p>Or if you prefer you can send this link instead:</p>
|
||||
<p>Or if you prefer you can share this link instead:</p>
|
||||
<a
|
||||
onClick={(event) => {
|
||||
event.stopPropagation();
|
||||
@@ -29,6 +38,11 @@ export function Qrcode({ qrcode }: { qrcode: RWS<string> }) {
|
||||
{location.href}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
{touchScreen ? "Touch" : "Click"} anywhere but on the QR Code to
|
||||
exit.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</Show>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
export function AnchorLogo() {
|
||||
return (
|
||||
<a
|
||||
class="inline-flex justify-center rounded-lg bg-gradient-to-br from-orange-500 to-orange-800 p-4 text-white"
|
||||
class="inline-flex justify-center rounded-lg bg-gradient-to-br from-orange-300 to-orange-600 p-4 text-orange-50 shadow dark:from-orange-500 dark:to-orange-800 dark:text-orange-50"
|
||||
href="https://app.satonomics.xyz"
|
||||
title="Reload"
|
||||
>
|
||||
|
||||
+2
-2
@@ -1,13 +1,13 @@
|
||||
import { Button } from "./button";
|
||||
|
||||
export function ButtonTree({
|
||||
export function ButtonFolders({
|
||||
selected,
|
||||
setSelected,
|
||||
}: {
|
||||
selected: Accessor<FrameName>;
|
||||
setSelected: Setter<FrameName>;
|
||||
}) {
|
||||
const frameName: FrameName = "Tree";
|
||||
const frameName: FrameName = "Folders";
|
||||
|
||||
return (
|
||||
<Button
|
||||
@@ -20,10 +20,10 @@ export function Clickable({
|
||||
class={classPropToString([
|
||||
!href
|
||||
? selected?.()
|
||||
? "bg-orange-200/10"
|
||||
: "text-orange-100/50"
|
||||
: "text-orange-300/70",
|
||||
"select-none rounded-lg p-3.5 hover:bg-orange-200/10 hover:text-orange-400 hover:opacity-100 active:scale-90",
|
||||
? "bg-orange-800/10 dark:bg-orange-200/10"
|
||||
: "text-orange-900/50 dark:text-orange-100/50"
|
||||
: "text-opacity-70 dark:text-opacity-70",
|
||||
"select-none rounded-lg p-3.5 hover:bg-orange-800/10 hover:text-orange-600 hover:opacity-100 active:scale-90 dark:hover:bg-orange-200/10 dark:hover:text-orange-400",
|
||||
])}
|
||||
title={title}
|
||||
onClick={onClick}
|
||||
|
||||
@@ -5,10 +5,10 @@ import { AnchorLogo } from "./components/anchorLogo";
|
||||
import { AnchorNostr } from "./components/anchorNostr";
|
||||
import { ButtonChart } from "./components/buttonChart";
|
||||
import { ButtonFavorites } from "./components/buttonFavorites";
|
||||
import { ButtonFolders } from "./components/buttonFolders";
|
||||
import { ButtonHistory } from "./components/buttonHistory";
|
||||
import { ButtonSearch } from "./components/buttonSearch";
|
||||
import { ButtonSettings } from "./components/buttonSettings";
|
||||
import { ButtonTree } from "./components/buttonTree";
|
||||
|
||||
export function StripDesktop({
|
||||
selected,
|
||||
@@ -21,7 +21,7 @@ export function StripDesktop({
|
||||
<>
|
||||
<AnchorLogo />
|
||||
|
||||
<ButtonTree selected={selected} setSelected={setSelected} />
|
||||
<ButtonFolders selected={selected} setSelected={setSelected} />
|
||||
<ButtonFavorites selected={selected} setSelected={setSelected} />
|
||||
<ButtonSearch selected={selected} setSelected={setSelected} />
|
||||
<ButtonHistory selected={selected} setSelected={setSelected} />
|
||||
@@ -49,7 +49,7 @@ export function StripMobile({
|
||||
return (
|
||||
<>
|
||||
<ButtonChart selected={selected} setSelected={setSelected} />
|
||||
<ButtonTree selected={selected} setSelected={setSelected} />
|
||||
<ButtonFolders selected={selected} setSelected={setSelected} />
|
||||
<ButtonFavorites selected={selected} setSelected={setSelected} />
|
||||
<ButtonSearch selected={selected} setSelected={setSelected} />
|
||||
<ButtonHistory selected={selected} setSelected={setSelected} />
|
||||
|
||||
+66
-19
@@ -5,7 +5,7 @@ import { createDatasets } from "../scripts/datasets";
|
||||
import { chartState } from "../scripts/lightweightCharts/chart/state";
|
||||
import { setTimeScale } from "../scripts/lightweightCharts/chart/time";
|
||||
import { createPresets } from "../scripts/presets";
|
||||
import { priceToUSLocale } from "../scripts/utils/locale";
|
||||
import { createSL } from "../scripts/utils/selectableList/static";
|
||||
import { sleep } from "../scripts/utils/sleep";
|
||||
import {
|
||||
readBooleanFromStorage,
|
||||
@@ -14,12 +14,12 @@ import {
|
||||
import { readBooleanURLParam, writeURLParam } from "../scripts/utils/urlParams";
|
||||
import { webSockets } from "../scripts/ws";
|
||||
import { classPropToString } from "../solid/classes";
|
||||
import { Background, LOCAL_STORAGE_MARQUEE_KEY } from "./components/background";
|
||||
import { Background } from "./components/background";
|
||||
import { ChartFrame } from "./components/frames/chart";
|
||||
import { FavoritesFrame } from "./components/frames/favorites";
|
||||
import { FoldersFrame } from "./components/frames/folders";
|
||||
import { HistoryFrame } from "./components/frames/history";
|
||||
import { SettingsFrame } from "./components/frames/settings";
|
||||
import { TreeFrame } from "./components/frames/tree";
|
||||
import { Qrcode } from "./components/qrcode";
|
||||
import { StripDesktop, StripMobile } from "./components/strip";
|
||||
import { Update } from "./components/update";
|
||||
@@ -31,9 +31,52 @@ export const INPUT_PRESET_SEARCH_ID = "input-search-preset";
|
||||
|
||||
export function App() {
|
||||
const tabFocused = createRWS(true);
|
||||
|
||||
const qrcode = createRWS("");
|
||||
|
||||
const appTheme = createSL(["System", "Dark", "Light"] as const, {
|
||||
saveable: {
|
||||
key: "app-theme",
|
||||
mode: "localStorage",
|
||||
},
|
||||
defaultIndex: 0,
|
||||
});
|
||||
|
||||
const backgroundMode = createSL(["Scroll", "Static"] as const, {
|
||||
saveable: {
|
||||
key: "bg-mode",
|
||||
mode: "localStorage",
|
||||
},
|
||||
defaultIndex: 0,
|
||||
});
|
||||
|
||||
const backgroundOpacity = createSL(
|
||||
[
|
||||
{
|
||||
text: "Strong",
|
||||
value: 0.0444,
|
||||
},
|
||||
{
|
||||
text: "Normal",
|
||||
value: 0.0333,
|
||||
},
|
||||
{
|
||||
text: "Light",
|
||||
value: 0.0222,
|
||||
},
|
||||
{
|
||||
text: "Subtle",
|
||||
value: 0.0111,
|
||||
},
|
||||
] as const,
|
||||
{
|
||||
saveable: {
|
||||
key: "bg-text-opacity",
|
||||
mode: "localStorage",
|
||||
},
|
||||
defaultIndex: 2,
|
||||
},
|
||||
);
|
||||
|
||||
const fullscreen = createRWS(
|
||||
readBooleanURLParam(LOCAL_STORAGE_FULLSCREEN) ||
|
||||
readBooleanFromStorage(LOCAL_STORAGE_FULLSCREEN) ||
|
||||
@@ -48,7 +91,7 @@ export function App() {
|
||||
window.addEventListener("resize", windowResizeCallback);
|
||||
onCleanup(() => window.removeEventListener("resize", windowResizeCallback));
|
||||
|
||||
const windowSizeIsAtLeastMedium = createMemo(() => windowWidth() >= 720);
|
||||
const windowSizeIsAtLeastMedium = createMemo(() => windowWidth() >= 768);
|
||||
|
||||
const minBarWidth = 384;
|
||||
const barWidth = createRWS(
|
||||
@@ -73,14 +116,12 @@ export function App() {
|
||||
|
||||
const selectedFrame = createMemo(() =>
|
||||
windowSizeIsAtLeastMedium() && _selectedFrame() === "Chart"
|
||||
? "Tree"
|
||||
? "Folders"
|
||||
: _selectedFrame(),
|
||||
);
|
||||
|
||||
const presets = createPresets();
|
||||
|
||||
const marquee = createRWS(!localStorage.getItem(LOCAL_STORAGE_MARQUEE_KEY));
|
||||
|
||||
const resizingBarStart = createRWS<number | undefined>(undefined);
|
||||
const resizingBarWidth = createRWS<number>(0);
|
||||
|
||||
@@ -114,7 +155,7 @@ export function App() {
|
||||
|
||||
console.log("close:", close);
|
||||
|
||||
document.title = `${priceToUSLocale(latest.close, false)} | Satonomics`;
|
||||
document.title = `${latest.close.toLocaleString("en-us")} | Satonomics`;
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -163,7 +204,11 @@ export function App() {
|
||||
|
||||
return (
|
||||
<>
|
||||
<Background marquee={marquee} focused={tabFocused} />
|
||||
<Background
|
||||
focused={tabFocused}
|
||||
mode={backgroundMode}
|
||||
opacity={backgroundOpacity}
|
||||
/>
|
||||
|
||||
<div
|
||||
class="relative h-dvh selection:bg-orange-800"
|
||||
@@ -195,15 +240,15 @@ export function App() {
|
||||
<Qrcode qrcode={qrcode} />
|
||||
<Update />
|
||||
|
||||
<div class="md:short:p-0 flex size-full flex-col md:flex-row md:p-3">
|
||||
<div class="flex size-full flex-col md:flex-row md:p-3 md:short:p-0">
|
||||
<Show when={!windowSizeIsAtLeastMedium() || !fullscreen()}>
|
||||
<div
|
||||
class={classPropToString([
|
||||
standalone && "border-t",
|
||||
"md:short:hidden flex h-full flex-col overflow-hidden border-white/10 bg-gradient-to-b from-orange-500/10 to-orange-950/10 md:flex-row md:rounded-2xl md:border",
|
||||
standalone && "border-t md:border-t-0",
|
||||
"border-lighter flex h-full flex-col overflow-hidden bg-gradient-to-b from-orange-300/15 to-orange-400/15 dark:from-orange-500/10 dark:to-orange-950/10 md:flex-row md:rounded-2xl md:border md:shadow-md md:short:hidden",
|
||||
])}
|
||||
>
|
||||
<div class="hidden flex-col gap-2 border-r border-white/10 bg-black/30 p-3 backdrop-blur-sm md:flex">
|
||||
<div class="border-lighter hidden flex-col gap-2 border-r bg-orange-300/30 p-3 backdrop-blur-sm dark:bg-black/30 md:flex">
|
||||
<StripDesktop
|
||||
selected={selectedFrame}
|
||||
setSelected={_selectedFrame.set}
|
||||
@@ -232,7 +277,7 @@ export function App() {
|
||||
/>
|
||||
</Show>
|
||||
|
||||
<TreeFrame presets={presets} selectedFrame={selectedFrame} />
|
||||
<FoldersFrame presets={presets} selectedFrame={selectedFrame} />
|
||||
<FavoritesFrame
|
||||
presets={presets}
|
||||
selectedFrame={selectedFrame}
|
||||
@@ -240,15 +285,17 @@ export function App() {
|
||||
<SearchFrame presets={presets} selectedFrame={selectedFrame} />
|
||||
<HistoryFrame presets={presets} selectedFrame={selectedFrame} />
|
||||
<SettingsFrame
|
||||
marquee={marquee}
|
||||
selectedFrame={selectedFrame}
|
||||
appTheme={appTheme}
|
||||
backgroundMode={backgroundMode}
|
||||
backgroundOpacity={backgroundOpacity}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class={classPropToString([
|
||||
standalone && "pb-6",
|
||||
"short:hidden flex justify-between gap-3 border-t border-white/10 bg-black/30 p-2 backdrop-blur-sm md:hidden",
|
||||
"border-lighter flex justify-between gap-3 border-t bg-black/30 p-2 backdrop-blur-sm sm:justify-around md:hidden short:hidden",
|
||||
])}
|
||||
>
|
||||
<StripMobile
|
||||
@@ -261,7 +308,7 @@ export function App() {
|
||||
|
||||
<Show when={!fullscreen()}>
|
||||
<div
|
||||
class="short:hidden mx-[3px] my-8 hidden w-[6px] cursor-col-resize items-center justify-center rounded-full bg-orange-100 opacity-0 hover:opacity-50 md:block"
|
||||
class="mx-[3px] my-8 hidden w-[6px] cursor-col-resize items-center justify-center rounded-full bg-orange-900 opacity-0 hover:opacity-50 dark:bg-orange-100 md:block short:hidden"
|
||||
onMouseDown={(event) => {
|
||||
resizeInitialRange.set(chartState.range);
|
||||
|
||||
@@ -279,8 +326,8 @@ export function App() {
|
||||
}
|
||||
}}
|
||||
onDblClick={() => {
|
||||
resizeInitialRange.set(chartState.range);
|
||||
barWidth.set(0);
|
||||
|
||||
setTimeScale(resizeInitialRange());
|
||||
}}
|
||||
/>
|
||||
|
||||
Vendored
+1
-1
@@ -1,6 +1,6 @@
|
||||
type FrameName =
|
||||
| "Chart"
|
||||
| "Tree"
|
||||
| "Folders"
|
||||
| "Favorites"
|
||||
| "Search"
|
||||
| "History"
|
||||
|
||||
Vendored
+3
@@ -34,6 +34,9 @@ interface ResourceDataset<
|
||||
drop: VoidFunction;
|
||||
}
|
||||
|
||||
type AnyDataset<Scale extends ResourceScale> = Dataset<Scale> &
|
||||
Partial<ResourceDataset<Scale>>;
|
||||
|
||||
interface FetchedResult<
|
||||
Scale extends ResourceScale,
|
||||
Type extends number | OHLC,
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
import { chartState } from "./state";
|
||||
|
||||
export function cleanChart() {
|
||||
console.log("chart: clean");
|
||||
|
||||
try {
|
||||
chartState.chart?.remove();
|
||||
} catch {}
|
||||
|
||||
chartState.chart = null;
|
||||
}
|
||||
@@ -5,14 +5,14 @@ import {
|
||||
} from "lightweight-charts";
|
||||
|
||||
import { colors } from "../../utils/colors";
|
||||
import { priceToUSLocale } from "../../utils/locale";
|
||||
import { cleanChart } from "./clean";
|
||||
import { valueToString } from "../../utils/locale";
|
||||
import { HorzScaleBehaviorHeight } from "./horzScaleBehavior";
|
||||
import { chartState } from "./state";
|
||||
|
||||
export function createChart(scale: ResourceScale) {
|
||||
cleanChart();
|
||||
|
||||
export function createChart(
|
||||
scale: ResourceScale,
|
||||
element: HTMLElement,
|
||||
priceScaleOptions?: DeepPartialPriceScaleOptions,
|
||||
) {
|
||||
console.log(`chart: create (scale: ${scale})`);
|
||||
|
||||
const { white } = colors;
|
||||
@@ -29,19 +29,19 @@ export function createChart(scale: ResourceScale) {
|
||||
vertLines: { visible: false },
|
||||
horzLines: { visible: false },
|
||||
},
|
||||
leftPriceScale: {
|
||||
// borderColor: white,
|
||||
},
|
||||
rightPriceScale: {
|
||||
// borderColor: white,
|
||||
borderColor: "#332F24",
|
||||
},
|
||||
timeScale: {
|
||||
borderColor: "#332F24",
|
||||
minBarSpacing: scale === "date" ? 0.05 : 0.005,
|
||||
shiftVisibleRangeOnNewBar: false,
|
||||
allowShiftVisibleRangeOnWhitespaceReplacement: false,
|
||||
},
|
||||
handleScale: {
|
||||
axisDoubleClickReset: false,
|
||||
axisDoubleClickReset: {
|
||||
time: false,
|
||||
},
|
||||
},
|
||||
crosshair: {
|
||||
mode: CrosshairMode.Normal,
|
||||
@@ -55,17 +55,31 @@ export function createChart(scale: ResourceScale) {
|
||||
},
|
||||
},
|
||||
localization: {
|
||||
priceFormatter: priceToUSLocale,
|
||||
priceFormatter: valueToString,
|
||||
locale: "en-us",
|
||||
},
|
||||
};
|
||||
|
||||
let chart: IChartApi;
|
||||
|
||||
if (scale === "date") {
|
||||
chartState.chart = createClassicChart("chart", options);
|
||||
chart = createClassicChart(element, options);
|
||||
} else {
|
||||
const horzScaleBehavior = new HorzScaleBehaviorHeight();
|
||||
|
||||
// @ts-ignore
|
||||
chartState.chart = createCustomChart("chart", horzScaleBehavior, options);
|
||||
chart = createCustomChart(element, horzScaleBehavior, options);
|
||||
}
|
||||
|
||||
chart.priceScale("right").applyOptions({
|
||||
...priceScaleOptions,
|
||||
scaleMargins: {
|
||||
top: 0.05,
|
||||
bottom: 0.05,
|
||||
...priceScaleOptions?.scaleMargins,
|
||||
},
|
||||
minimumWidth: 78,
|
||||
});
|
||||
|
||||
return chart;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { colors } from "/src/scripts/utils/colors";
|
||||
import { priceToUSLocale } from "/src/scripts/utils/locale";
|
||||
import { ONE_DAY_IN_MS } from "/src/scripts/utils/time";
|
||||
|
||||
import { chartState } from "./state";
|
||||
@@ -101,12 +100,11 @@ export const setMinMaxMarkers = ({
|
||||
candle &&
|
||||
markers.push({
|
||||
...markerOptions,
|
||||
// date: candle.date,
|
||||
number: candle.number,
|
||||
time: candle.time,
|
||||
color: lowerOpacity ? colors.darkWhite : colors.white,
|
||||
size: 0,
|
||||
text: priceToUSLocale(value),
|
||||
text: value.toLocaleString("en-us"),
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
import { createRWS } from "/src/solid/rws";
|
||||
|
||||
import { colors } from "../../utils/colors";
|
||||
import { getNumberOfDaysBetweenTwoDates } from "../../utils/date";
|
||||
import { debounce } from "../../utils/debounce";
|
||||
import { webSockets } from "../../ws";
|
||||
import { createCandlesticksSeries } from "../series/creators/candlesticks";
|
||||
import { createSeriesLegend } from "../series/creators/legend";
|
||||
import { createLineSeries } from "../series/creators/line";
|
||||
import { setMinMaxMarkers } from "./markers";
|
||||
import { chartState } from "./state";
|
||||
import { initTimeScale } from "./time";
|
||||
|
||||
export const PRICE_SCALE_MOMENTUM_ID = "momentum";
|
||||
@@ -18,76 +12,32 @@ export const applyPriceSeries = <
|
||||
T extends SingleValueData,
|
||||
>({
|
||||
chart,
|
||||
datasets,
|
||||
preset,
|
||||
dataset: _dataset,
|
||||
dataset,
|
||||
seriesType,
|
||||
valuesSkipped,
|
||||
options,
|
||||
activeResources,
|
||||
}: {
|
||||
chart: IChartApi;
|
||||
datasets: Datasets;
|
||||
preset: Preset;
|
||||
valuesSkipped: Accessor<number>;
|
||||
seriesType: Accessor<"Candlestick" | "Line">;
|
||||
activeResources: Accessor<Set<ResourceDataset<any, any>>>;
|
||||
dataset?: Dataset<Scale, T>;
|
||||
dataset: Dataset<Scale, T>;
|
||||
options?: PriceSeriesOptions;
|
||||
}) => {
|
||||
const id = options?.id || "price";
|
||||
const title = options?.title || "Price";
|
||||
|
||||
const dataset = _dataset || datasets[preset.scale].price;
|
||||
|
||||
const url = "url" in dataset ? (dataset as any).url : undefined;
|
||||
|
||||
const priceScaleOptions: DeepPartial<PriceScaleOptions> = {
|
||||
...(options?.halved
|
||||
? {
|
||||
scaleMargins: {
|
||||
top: 0.05,
|
||||
bottom: 0.55,
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
...(options?.id || options?.title
|
||||
? {}
|
||||
: {
|
||||
mode: 1,
|
||||
}),
|
||||
const priceScaleOptions: DeepPartialPriceScaleOptions = {
|
||||
mode: 1,
|
||||
...options?.priceScaleOptions,
|
||||
};
|
||||
|
||||
const seriesType = createRWS(
|
||||
checkIfUpClose(chart, chartState.range) || "Candlestick",
|
||||
);
|
||||
|
||||
const debouncedCallback = debounce((range: TimeRange | null) => {
|
||||
try {
|
||||
seriesType.set((previous) => checkIfUpClose(chart, range) || previous);
|
||||
} catch {}
|
||||
}, 50);
|
||||
|
||||
chart?.timeScale().subscribeVisibleTimeRangeChange(debouncedCallback);
|
||||
|
||||
onCleanup(
|
||||
() =>
|
||||
chart === chartState.chart &&
|
||||
chartState.chart
|
||||
?.timeScale()
|
||||
.unsubscribeVisibleTimeRangeChange(debouncedCallback),
|
||||
);
|
||||
|
||||
const lowerOpacity = options?.lowerOpacity || options?.halved || false;
|
||||
|
||||
if (options?.halved) {
|
||||
options.seriesOptions = {
|
||||
...options.seriesOptions,
|
||||
priceScaleId: "left",
|
||||
};
|
||||
}
|
||||
|
||||
const [ohlcSeries, ohlcColors] = createCandlesticksSeries(chart, {
|
||||
...options,
|
||||
lowerOpacity,
|
||||
});
|
||||
const [ohlcSeries, ohlcColors] = createCandlesticksSeries(chart, options);
|
||||
|
||||
const ohlcLegend = createSeriesLegend({
|
||||
id,
|
||||
@@ -103,7 +53,7 @@ export const applyPriceSeries = <
|
||||
|
||||
// ---
|
||||
|
||||
const lineColor = lowerOpacity ? colors.darkWhite : colors.white;
|
||||
const lineColor = colors.white;
|
||||
|
||||
const lineSeries = createLineSeries(chart, {
|
||||
color: lineColor,
|
||||
@@ -139,11 +89,10 @@ export const applyPriceSeries = <
|
||||
|
||||
createEffect(() => {
|
||||
const values = dataset.values();
|
||||
// const values = computeDrawnSeriesValues(dataset.values(), valuesSkipped());
|
||||
|
||||
if (values) {
|
||||
lineSeries.setData(values);
|
||||
ohlcSeries.setData(values);
|
||||
}
|
||||
lineSeries.setData(values);
|
||||
ohlcSeries.setData(values);
|
||||
});
|
||||
|
||||
createEffect(() => {
|
||||
@@ -159,20 +108,3 @@ export const applyPriceSeries = <
|
||||
|
||||
return { ohlcLegend, lineLegend };
|
||||
};
|
||||
|
||||
function checkIfUpClose(chart: IChartApi, range?: TimeRange | null) {
|
||||
if (!range) return undefined;
|
||||
|
||||
const from = new Date(range.from);
|
||||
const to = new Date(range.to);
|
||||
|
||||
const width = chart.timeScale().width();
|
||||
|
||||
const difference = getNumberOfDaysBetweenTwoDates(from, to);
|
||||
|
||||
return width / difference >= 2.05
|
||||
? "Candlestick"
|
||||
: width / difference <= 1.95
|
||||
? "Line"
|
||||
: undefined;
|
||||
}
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
import { createChart } from "./create";
|
||||
import { chartState } from "./state";
|
||||
import { setWhitespace } from "./whitespace";
|
||||
|
||||
export function renderChart({
|
||||
datasets,
|
||||
legendSetter,
|
||||
preset,
|
||||
activeResources,
|
||||
}: {
|
||||
datasets: Datasets;
|
||||
legendSetter: Setter<PresetLegend>;
|
||||
preset: Preset;
|
||||
activeResources: Accessor<Set<ResourceDataset<any, any>>>;
|
||||
}) {
|
||||
const scale = preset.scale;
|
||||
|
||||
createChart(scale);
|
||||
|
||||
const chart = chartState.chart;
|
||||
|
||||
if (!chart) return;
|
||||
|
||||
try {
|
||||
setWhitespace(chart, scale);
|
||||
|
||||
console.log(`preset: ${preset.id}`);
|
||||
|
||||
const legend = preset.applyPreset({
|
||||
chart,
|
||||
datasets,
|
||||
preset,
|
||||
activeResources,
|
||||
});
|
||||
|
||||
legendSetter(legend);
|
||||
} catch (error) {
|
||||
console.error("chart: render: failed", error);
|
||||
}
|
||||
}
|
||||
+1
-2
@@ -1,8 +1,7 @@
|
||||
interface PriceSeriesOptions {
|
||||
halved?: boolean;
|
||||
placement?: "top" | "bottom";
|
||||
title?: string;
|
||||
id?: string;
|
||||
lowerOpacity?: boolean;
|
||||
inverseColors?: boolean;
|
||||
seriesOptions?: DeepPartial<SeriesOptionsCommon>;
|
||||
priceScaleOptions?: DeepPartial<PriceScaleOptions>;
|
||||
|
||||
@@ -2,25 +2,13 @@ import { colors } from "/src/scripts/utils/colors";
|
||||
|
||||
export const createCandlesticksSeries = (
|
||||
chart: IChartApi,
|
||||
options: PriceSeriesOptions,
|
||||
options: PriceSeriesOptions = {},
|
||||
): [ISeriesApi<"Candlestick">, string[]] => {
|
||||
const { inverseColors, lowerOpacity } = options;
|
||||
const { inverseColors } = options;
|
||||
|
||||
const upColor = lowerOpacity
|
||||
? inverseColors
|
||||
? colors.darkLoss
|
||||
: colors.darkProfit
|
||||
: inverseColors
|
||||
? colors.loss
|
||||
: colors.profit;
|
||||
const upColor = inverseColors ? colors.loss : colors.profit;
|
||||
|
||||
const downColor = lowerOpacity
|
||||
? inverseColors
|
||||
? colors.darkProfit
|
||||
: colors.darkLoss
|
||||
: inverseColors
|
||||
? colors.profit
|
||||
: colors.loss;
|
||||
const downColor = inverseColors ? colors.profit : colors.loss;
|
||||
|
||||
const candlestickSeries = chart.addCandlestickSeries({
|
||||
baseLineVisible: false,
|
||||
@@ -34,7 +22,6 @@ export const createCandlesticksSeries = (
|
||||
borderColor: "",
|
||||
borderDownColor: "",
|
||||
borderUpColor: "",
|
||||
// lastValueVisible: false,
|
||||
...options.seriesOptions,
|
||||
});
|
||||
|
||||
|
||||
@@ -8,9 +8,6 @@ import {
|
||||
} from "/src/scripts/utils/urlParams";
|
||||
import { createRWS } from "/src/solid/rws";
|
||||
|
||||
import { chartState } from "../../chart/state";
|
||||
import { setTimeScale } from "../../chart/time";
|
||||
|
||||
export function createSeriesLegend({
|
||||
id,
|
||||
presetId,
|
||||
@@ -44,15 +41,20 @@ export function createSeriesLegend({
|
||||
|
||||
const disabled = createMemo(_disabled || (() => false));
|
||||
|
||||
const drawn = createMemo(() => visible() && !disabled());
|
||||
|
||||
createEffect(() => {
|
||||
const v = visible();
|
||||
const d = disabled();
|
||||
|
||||
series.applyOptions({
|
||||
visible: !d && v,
|
||||
visible: drawn(),
|
||||
});
|
||||
});
|
||||
|
||||
setTimeScale(chartState.range);
|
||||
createEffect(() => {
|
||||
if (disabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const v = visible();
|
||||
|
||||
if (v !== defaultVisible) {
|
||||
writeURLParam(id, v);
|
||||
@@ -70,6 +72,7 @@ export function createSeriesLegend({
|
||||
color,
|
||||
visible,
|
||||
disabled,
|
||||
drawn,
|
||||
url,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
export const resetRightPriceScale = (
|
||||
chart: IChartApi,
|
||||
options?: FullPriceScaleOptions,
|
||||
) => {
|
||||
const finalOptions = {
|
||||
...options,
|
||||
scaleMargins: {
|
||||
...(options?.halved
|
||||
? {
|
||||
top: 0.5,
|
||||
bottom: 0.05,
|
||||
}
|
||||
: {
|
||||
top: 0.1,
|
||||
bottom: 0.1,
|
||||
}),
|
||||
...options?.scaleMargins,
|
||||
},
|
||||
};
|
||||
|
||||
chart.priceScale("right").applyOptions(finalOptions);
|
||||
|
||||
return finalOptions;
|
||||
};
|
||||
|
||||
export const resetLeftPriceScale = (
|
||||
chart: IChartApi,
|
||||
options?: FullPriceScaleOptions,
|
||||
) =>
|
||||
chart.priceScale("left").applyOptions({
|
||||
visible: false,
|
||||
...options,
|
||||
scaleMargins: {
|
||||
...(options?.halved
|
||||
? {
|
||||
top: 0.475,
|
||||
bottom: 0.025,
|
||||
}
|
||||
: {
|
||||
top: 0.25,
|
||||
bottom: 0.25,
|
||||
}),
|
||||
...options?.scaleMargins,
|
||||
},
|
||||
});
|
||||
@@ -1,3 +0,0 @@
|
||||
interface FullPriceScaleOptions extends DeepPartial<PriceScaleOptions> {
|
||||
halved?: boolean;
|
||||
}
|
||||
@@ -4,8 +4,8 @@ import {
|
||||
} from "../../datasets/consts/address";
|
||||
import { liquidities } from "../../datasets/consts/liquidities";
|
||||
import { colors } from "../../utils/colors";
|
||||
import { applySeriesList, SeriesType } from "../apply";
|
||||
import { createCohortPresetList } from "../templates/cohort";
|
||||
import { applyMultipleSeries, SeriesType } from "../templates/multiple";
|
||||
|
||||
export function createPresets({
|
||||
scale,
|
||||
@@ -22,12 +22,9 @@ export function createPresets({
|
||||
description: "",
|
||||
icon: IconTablerWallet,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: `Total Non Empty Address`,
|
||||
color: colors.bitcoin,
|
||||
@@ -45,12 +42,9 @@ export function createPresets({
|
||||
description: "",
|
||||
icon: IconTablerSparkles,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: `New Addresses`,
|
||||
color: colors.white,
|
||||
@@ -67,12 +61,9 @@ export function createPresets({
|
||||
description: "",
|
||||
icon: IconTablerArchive,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: `Total Addresses Created`,
|
||||
color: colors.bitcoin,
|
||||
@@ -90,12 +81,9 @@ export function createPresets({
|
||||
description: "",
|
||||
icon: IconTablerTrash,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: `Total Empty Addresses`,
|
||||
color: colors.darkWhite,
|
||||
@@ -191,12 +179,9 @@ export function createAddressCountPreset<Scale extends ResourceScale>({
|
||||
title: `${name} Address Count`,
|
||||
icon: IconTablerAddressBook,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Address Count",
|
||||
color,
|
||||
|
||||
@@ -0,0 +1,357 @@
|
||||
import { createRWS } from "/src/solid/rws";
|
||||
|
||||
import { createChart } from "../lightweightCharts/chart/create";
|
||||
import { applyPriceSeries } from "../lightweightCharts/chart/price";
|
||||
import { chartState } from "../lightweightCharts/chart/state";
|
||||
import { setWhitespace } from "../lightweightCharts/chart/whitespace";
|
||||
import { createAreaSeries } from "../lightweightCharts/series/creators/area";
|
||||
import {
|
||||
createBaseLineSeries,
|
||||
DEFAULT_BASELINE_COLORS,
|
||||
} from "../lightweightCharts/series/creators/baseLine";
|
||||
import { createHistogramSeries } from "../lightweightCharts/series/creators/histogram";
|
||||
import { createSeriesLegend } from "../lightweightCharts/series/creators/legend";
|
||||
import { createLineSeries } from "../lightweightCharts/series/creators/line";
|
||||
import { debounce } from "../utils/debounce";
|
||||
import { stringToId } from "../utils/id";
|
||||
|
||||
export enum SeriesType {
|
||||
Normal,
|
||||
Based,
|
||||
Area,
|
||||
Histogram,
|
||||
}
|
||||
|
||||
type SeriesConfig<Scale extends ResourceScale> =
|
||||
| {
|
||||
dataset: AnyDataset<Scale>;
|
||||
color?: string;
|
||||
colors?: undefined;
|
||||
seriesType: SeriesType.Based;
|
||||
title: string;
|
||||
options?: BaselineSeriesOptions;
|
||||
defaultVisible?: boolean;
|
||||
}
|
||||
| {
|
||||
dataset: AnyDataset<Scale>;
|
||||
color?: string;
|
||||
colors?: string[];
|
||||
seriesType: SeriesType.Histogram;
|
||||
title: string;
|
||||
options?: DeepPartialHistogramOptions;
|
||||
defaultVisible?: boolean;
|
||||
}
|
||||
| {
|
||||
dataset: AnyDataset<Scale>;
|
||||
color: string;
|
||||
colors?: undefined;
|
||||
seriesType?: SeriesType.Normal | SeriesType.Area;
|
||||
title: string;
|
||||
options?: DeepPartialLineOptions;
|
||||
defaultVisible?: boolean;
|
||||
};
|
||||
|
||||
export function applySeriesList<Scale extends ResourceScale>({
|
||||
parentDiv,
|
||||
charts: reactiveChartList,
|
||||
top,
|
||||
bottom,
|
||||
preset,
|
||||
priceScaleOptions,
|
||||
datasets,
|
||||
priceDataset,
|
||||
priceOptions,
|
||||
activeResources,
|
||||
legendSetter,
|
||||
}: {
|
||||
charts: RWS<IChartApi[]>;
|
||||
parentDiv: HTMLDivElement;
|
||||
preset: Preset;
|
||||
legendSetter: Setter<PresetLegend>;
|
||||
priceDataset?: AnyDataset<Scale>;
|
||||
priceOptions?: PriceSeriesOptions;
|
||||
priceScaleOptions?: DeepPartialPriceScaleOptions;
|
||||
top?: SeriesConfig<Scale>[];
|
||||
bottom?: SeriesConfig<Scale>[];
|
||||
datasets: Datasets;
|
||||
activeResources: Accessor<Set<ResourceDataset<any, any>>>;
|
||||
}) {
|
||||
reactiveChartList.set((charts) => {
|
||||
charts.forEach((chart) => {
|
||||
chart.remove();
|
||||
});
|
||||
|
||||
return [];
|
||||
});
|
||||
|
||||
parentDiv.replaceChildren();
|
||||
|
||||
const scale = preset.scale;
|
||||
|
||||
const legendList: PresetLegend = [];
|
||||
|
||||
const priceSeriesType = createRWS<"Candlestick" | "Line">("Candlestick");
|
||||
|
||||
const valuesSkipped = createRWS(0);
|
||||
|
||||
const charts = [top || [], bottom]
|
||||
.flatMap((list) => (list ? [list] : []))
|
||||
.flatMap((seriesConfigList, index, array) => {
|
||||
if (index !== 0 && seriesConfigList.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const isAnyArea = seriesConfigList.find(
|
||||
(config) => config.seriesType === SeriesType.Area,
|
||||
);
|
||||
|
||||
const div = document.createElement("div");
|
||||
|
||||
div.className = "w-full cursor-crosshair min-h-0 border-orange-200/10";
|
||||
|
||||
parentDiv.appendChild(div);
|
||||
|
||||
const chart = createChart(scale, div, {
|
||||
...priceScaleOptions,
|
||||
...(isAnyArea
|
||||
? {
|
||||
scaleMargins: {
|
||||
bottom: 0,
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
});
|
||||
|
||||
chartState.chart = chart;
|
||||
|
||||
if (!chart) {
|
||||
console.log("chart: undefined");
|
||||
return [];
|
||||
}
|
||||
|
||||
setWhitespace(chart, scale);
|
||||
|
||||
const seriesList: ISeriesApi<any>[] = [];
|
||||
|
||||
const _legendList: PresetLegend = [];
|
||||
|
||||
if (index === 0) {
|
||||
const price = applyPriceSeries({
|
||||
chart,
|
||||
preset,
|
||||
seriesType: priceSeriesType,
|
||||
valuesSkipped,
|
||||
dataset:
|
||||
priceDataset ||
|
||||
(datasets[preset.scale as Scale].price as unknown as NonNullable<
|
||||
typeof priceDataset
|
||||
>),
|
||||
activeResources,
|
||||
options: priceOptions,
|
||||
});
|
||||
|
||||
_legendList.push(price.lineLegend, price.ohlcLegend);
|
||||
|
||||
seriesList.push(price.lineLegend.series, price.ohlcLegend.series);
|
||||
}
|
||||
|
||||
seriesList.push(
|
||||
...seriesConfigList
|
||||
.reverse()
|
||||
.map(
|
||||
({
|
||||
dataset,
|
||||
color,
|
||||
colors,
|
||||
seriesType: type,
|
||||
title,
|
||||
options,
|
||||
defaultVisible,
|
||||
}) => {
|
||||
let series: ISeriesApi<
|
||||
"Baseline" | "Line" | "Area" | "Histogram"
|
||||
>;
|
||||
|
||||
if (type === SeriesType.Based) {
|
||||
series = createBaseLineSeries(chart, {
|
||||
color,
|
||||
...options,
|
||||
});
|
||||
} else if (type === SeriesType.Area) {
|
||||
series = createAreaSeries(chart, {
|
||||
color,
|
||||
autoscaleInfoProvider: (
|
||||
getInfo: () => AutoscaleInfo | null,
|
||||
) => {
|
||||
const info = getInfo();
|
||||
if (info) {
|
||||
info.priceRange.minValue = 0;
|
||||
}
|
||||
return info;
|
||||
},
|
||||
...options,
|
||||
});
|
||||
} else if (type === SeriesType.Histogram) {
|
||||
series = createHistogramSeries(chart, {
|
||||
color,
|
||||
...options,
|
||||
});
|
||||
} else {
|
||||
series = createLineSeries(chart, {
|
||||
color,
|
||||
...options,
|
||||
});
|
||||
}
|
||||
|
||||
_legendList.push(
|
||||
createSeriesLegend({
|
||||
id: stringToId(title),
|
||||
presetId: preset.id,
|
||||
title,
|
||||
series,
|
||||
color: () => colors || color || DEFAULT_BASELINE_COLORS,
|
||||
defaultVisible,
|
||||
url: dataset.url,
|
||||
}),
|
||||
);
|
||||
|
||||
createEffect(() => {
|
||||
series.setData(
|
||||
dataset?.values() || [],
|
||||
// computeDrawnSeriesValues(dataset?.values(), valuesSkipped()),
|
||||
);
|
||||
});
|
||||
|
||||
return series;
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
_legendList.forEach((legend) => {
|
||||
legendList.splice(0, 0, legend);
|
||||
});
|
||||
|
||||
return [{ div, chart, seriesList, legendList: _legendList }];
|
||||
});
|
||||
|
||||
createEffect(() => {
|
||||
const visibleCharts: typeof charts = [];
|
||||
|
||||
charts.forEach((chart) => {
|
||||
if (chart.legendList.some((legend) => legend.drawn())) {
|
||||
chart.div.style.border = "";
|
||||
visibleCharts.push(chart);
|
||||
} else {
|
||||
chart.div.style.height = "0px";
|
||||
chart.div.style.border = "none";
|
||||
}
|
||||
});
|
||||
|
||||
visibleCharts.forEach(({ div, chart }, index) => {
|
||||
const last = index === visibleCharts.length - 1;
|
||||
|
||||
div.style.height = last ? "100%" : "calc(100% - 62px)";
|
||||
div.style.borderBottomWidth = last ? "none" : "1px";
|
||||
|
||||
chart.timeScale().applyOptions({
|
||||
visible: last,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// const seriesType = createRWS(
|
||||
// checkIfUpClose(chart, chartState.range) || "Candlestick",
|
||||
// );
|
||||
|
||||
function updateVisibleRangeRatio(
|
||||
chart: IChartApi,
|
||||
range: LogicalRange | null,
|
||||
) {
|
||||
if (!range) return;
|
||||
|
||||
try {
|
||||
const width = chart.timeScale().width();
|
||||
|
||||
const ratio = (range.to - range.from) / width;
|
||||
|
||||
if (ratio <= 0.5) {
|
||||
priceSeriesType.set("Candlestick");
|
||||
} else {
|
||||
priceSeriesType.set("Line");
|
||||
|
||||
valuesSkipped.set(Math.floor(ratio / 5));
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
|
||||
const debouncedUpdateVisibleRangeRatio = debounce(
|
||||
updateVisibleRangeRatio,
|
||||
50,
|
||||
);
|
||||
|
||||
charts.forEach(({ chart }, index) => {
|
||||
chart.timeScale().subscribeVisibleLogicalRangeChange((timeRange) => {
|
||||
// Last chart otherwise length of timescale is Infinity
|
||||
if (index === charts.length - 1) {
|
||||
debouncedUpdateVisibleRangeRatio(chart, timeRange);
|
||||
}
|
||||
|
||||
charts.forEach(({ chart: _chart }, _index) => {
|
||||
if (timeRange && index !== _index) {
|
||||
_chart.timeScale().setVisibleLogicalRange(timeRange);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
chart.subscribeCrosshairMove(({ time, sourceEvent }) => {
|
||||
// Don't override crosshair position from scroll event
|
||||
if (time && !sourceEvent) return;
|
||||
|
||||
charts.forEach(({ chart: _chart, seriesList }, _index) => {
|
||||
const first = seriesList.at(0);
|
||||
|
||||
if (first && index !== _index) {
|
||||
if (time) {
|
||||
_chart.setCrosshairPosition(NaN, time, first);
|
||||
} else {
|
||||
// No time when mouse goes outside the chart
|
||||
_chart.clearCrosshairPosition();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
legendSetter(legendList);
|
||||
|
||||
reactiveChartList.set(() => charts.map(({ chart }) => chart));
|
||||
}
|
||||
|
||||
export function computeDrawnSeriesValues<T>(
|
||||
values: DatasetValue<T>[] | undefined,
|
||||
valuesSkipped: number,
|
||||
) {
|
||||
values = values || [];
|
||||
|
||||
if (valuesSkipped === 0) {
|
||||
return values;
|
||||
} else {
|
||||
const valuesSkippedPlus1 = valuesSkipped + 1;
|
||||
|
||||
// console.log(_valuesSkippedPlus1);
|
||||
|
||||
let length = Math.floor(values.length / valuesSkippedPlus1);
|
||||
|
||||
// console.log(length);
|
||||
|
||||
const filteredValues = new Array(length);
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
filteredValues[i] = values[i * valuesSkippedPlus1];
|
||||
}
|
||||
|
||||
// console.log(filteredValues.length);
|
||||
|
||||
return filteredValues;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { colors } from "../../utils/colors";
|
||||
import { applyMultipleSeries, SeriesType } from "../templates/multiple";
|
||||
import { applySeriesList, SeriesType } from "../apply";
|
||||
|
||||
export function createPresets() {
|
||||
const scale: ResourceScale = "date";
|
||||
@@ -14,12 +14,9 @@ export function createPresets() {
|
||||
title: "Block Height",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Height",
|
||||
color: colors.bitcoin,
|
||||
@@ -40,19 +37,15 @@ export function createPresets() {
|
||||
title: "Daily Sum Of Blocks Mined",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Target",
|
||||
color: colors.white,
|
||||
dataset: params.datasets.date.blocks_mined_1d_target,
|
||||
options: {
|
||||
lineStyle: 3,
|
||||
// lineStyle: LineStyle.LargeDashed,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -82,19 +75,15 @@ export function createPresets() {
|
||||
title: "Weekly Sum Of Blocks Mined",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Target",
|
||||
color: colors.white,
|
||||
dataset: params.datasets.date.blocks_mined_1w_target,
|
||||
options: {
|
||||
lineStyle: 3,
|
||||
// lineStyle: LineStyle.LargeDashed,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -113,18 +102,14 @@ export function createPresets() {
|
||||
title: "Monthly Sum Of Blocks Mined",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Target",
|
||||
color: colors.white,
|
||||
dataset: params.datasets.date.blocks_mined_1m_target,
|
||||
options: {
|
||||
// lineStyle: LineStyle.LargeDashed,
|
||||
lineStyle: 3,
|
||||
},
|
||||
},
|
||||
@@ -144,19 +129,15 @@ export function createPresets() {
|
||||
title: "Yearly Sum Of Blocks Mined",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Target",
|
||||
color: colors.white,
|
||||
dataset: params.datasets.date.blocks_mined_1y_target,
|
||||
options: {
|
||||
lineStyle: 3,
|
||||
// lineStyle: LineStyle.LargeDashed,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -175,12 +156,9 @@ export function createPresets() {
|
||||
title: "Total Blocks Mined",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Mined",
|
||||
color: colors.bitcoin,
|
||||
@@ -200,12 +178,9 @@ export function createPresets() {
|
||||
title: "Cumulative Block Size",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Size (MB)",
|
||||
color: colors.darkWhite,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { colors } from "../../utils/colors";
|
||||
import { applyMultipleSeries, SeriesType } from "../templates/multiple";
|
||||
import { applySeriesList, SeriesType } from "../apply";
|
||||
|
||||
export function createPresets<Scale extends ResourceScale>({
|
||||
scale,
|
||||
@@ -19,9 +19,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "All Cointime Prices",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
list: [
|
||||
top: [
|
||||
{
|
||||
title: "Vaulted Price",
|
||||
color: colors.vaultedness,
|
||||
@@ -61,9 +61,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Active Price",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
list: [
|
||||
top: [
|
||||
{
|
||||
title: "Active Price",
|
||||
color: colors.liveliness,
|
||||
@@ -85,9 +85,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Vaulted Price",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
list: [
|
||||
top: [
|
||||
{
|
||||
title: "Vaulted Price",
|
||||
color: colors.vaultedness,
|
||||
@@ -109,9 +109,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "True Market Mean",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
list: [
|
||||
top: [
|
||||
{
|
||||
title: "True Market Mean",
|
||||
color: colors.trueMarketMeanPrice,
|
||||
@@ -133,9 +133,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Cointime Price",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
list: [
|
||||
top: [
|
||||
{
|
||||
title: "Cointime",
|
||||
color: colors.cointimePrice,
|
||||
@@ -159,16 +159,14 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Cointime Capitalizations",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
mode: 1,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Market Cap",
|
||||
|
||||
color: colors.white,
|
||||
dataset: params.datasets[scale].market_cap,
|
||||
},
|
||||
@@ -198,13 +196,12 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Thermo Cap",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
mode: 1,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Thermo Cap",
|
||||
color: colors.thermoCap,
|
||||
@@ -221,13 +218,12 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Investor Cap",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
mode: 1,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Investor Cap",
|
||||
color: colors.investorCap,
|
||||
@@ -244,12 +240,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Thermo Cap To Investor Cap Ratio (%)",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Ratio",
|
||||
color: colors.bitcoin,
|
||||
@@ -272,12 +265,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "All Coinblocks",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Coinblocks Created",
|
||||
color: colors.coinblocksCreated,
|
||||
@@ -304,12 +294,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Coinblocks Created",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Coinblocks Created",
|
||||
color: colors.coinblocksCreated,
|
||||
@@ -326,12 +313,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Coinblocks Destroyed",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Coinblocks Destroyed",
|
||||
color: colors.coinblocksDestroyed,
|
||||
@@ -348,12 +332,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Coinblocks Stored",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Coinblocks Stored",
|
||||
color: colors.coinblocksStored,
|
||||
@@ -375,12 +356,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "All Cumulative Coinblocks",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Cumulative Coinblocks Created",
|
||||
color: colors.coinblocksCreated,
|
||||
@@ -410,12 +388,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Cumulative Coinblocks Created",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Cumulative Coinblocks Created",
|
||||
color: colors.coinblocksCreated,
|
||||
@@ -433,12 +408,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Cumulative Coinblocks Destroyed",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Cumulative Coinblocks Destroyed",
|
||||
color: colors.coinblocksDestroyed,
|
||||
@@ -456,12 +428,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Cumulative Coinblocks Stored",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Cumulative Coinblocks Stored",
|
||||
color: colors.coinblocksStored,
|
||||
@@ -484,12 +453,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Liveliness (Activity)",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Liveliness",
|
||||
color: colors.liveliness,
|
||||
@@ -506,12 +472,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Vaultedness",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Vaultedness",
|
||||
color: colors.vaultedness,
|
||||
@@ -528,12 +491,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Liveliness V. Vaultedness",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Liveliness",
|
||||
color: colors.liveliness,
|
||||
@@ -555,12 +515,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Activity To Vaultedness Ratio",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Activity To Vaultedness Ratio",
|
||||
color: colors.activityToVaultednessRatio,
|
||||
@@ -578,12 +535,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Concurrent Liveliness - Supply Adjusted Coindays Destroyed",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Concurrent Liveliness 14d Median",
|
||||
color: `${colors.liveliness}66`,
|
||||
@@ -606,12 +560,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Liveliness Incremental Change",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Liveliness Incremental Change",
|
||||
color: colors.darkLiveliness,
|
||||
@@ -641,12 +592,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Vaulted Supply",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Vaulted Supply",
|
||||
color: colors.vaultedness,
|
||||
@@ -663,12 +611,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Active Supply",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Active Supply",
|
||||
color: colors.liveliness,
|
||||
@@ -685,12 +630,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Vaulted V. Active",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Circulating Supply",
|
||||
color: colors.coinblocksCreated,
|
||||
@@ -747,12 +689,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Vaulted Supply Net Change",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Vaulted Supply Net Change",
|
||||
color: colors.vaultedness,
|
||||
@@ -769,12 +708,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Active Supply Net Change",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Active Supply Net Change",
|
||||
color: colors.liveliness,
|
||||
@@ -791,12 +727,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Active VS. Vaulted 90 Day Supply Net Change",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Active Supply Net Change",
|
||||
color: `${colors.liveliness}80`,
|
||||
@@ -919,12 +852,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Cointime Supply In Profit",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Circulating Supply",
|
||||
color: colors.coinblocksCreated,
|
||||
@@ -951,12 +881,9 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Cointime Supply In Loss",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Circulating Supply",
|
||||
color: colors.coinblocksCreated,
|
||||
@@ -985,13 +912,12 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Cointime-Adjusted Yearly Inflation Rate (%)",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
mode: 1,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Cointime Adjusted",
|
||||
color: colors.coinblocksCreated,
|
||||
@@ -1015,13 +941,12 @@ export function createPresets<Scale extends ResourceScale>({
|
||||
title: "Cointime-Adjusted Transactions Velocity",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
mode: 1,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Cointime Adjusted",
|
||||
color: colors.coinblocksCreated,
|
||||
|
||||
@@ -6,8 +6,8 @@ import {
|
||||
yearCohorts,
|
||||
} from "../../datasets/consts/age";
|
||||
import { colors } from "../../utils/colors";
|
||||
import { applySeriesList } from "../apply";
|
||||
import { createCohortPresetFolder } from "../templates/cohort";
|
||||
import { applyMultipleSeries } from "../templates/multiple";
|
||||
|
||||
export function createPresets({ scale }: { scale: ResourceScale }) {
|
||||
return {
|
||||
@@ -20,12 +20,9 @@ export function createPresets({ scale }: { scale: ResourceScale }) {
|
||||
description: "",
|
||||
icon: IconTablerRipple,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: `24h`,
|
||||
color: colors.up_to_1d,
|
||||
|
||||
@@ -48,22 +48,21 @@ export function createPresets(): Presets {
|
||||
],
|
||||
} satisfies PartialPresetFolder,
|
||||
{
|
||||
name: "By Height (Coming soon)",
|
||||
name: "By Height",
|
||||
tree: [
|
||||
// createMarketPresets({ scale: "height", datasets }),
|
||||
// createMinersPresets("height"),
|
||||
// createTransactionsPresets("height"),
|
||||
// ...createCohortPresetList({
|
||||
// datasets,
|
||||
// scale: "height",
|
||||
// color: colors.bitcoin,
|
||||
// name: "",
|
||||
// datasetKey: "",
|
||||
// title: "",
|
||||
// }),
|
||||
// createHodlersPresets({ scale: "height", datasets }),
|
||||
// createAddressesPresets({ scale: "height", datasets }),
|
||||
// createCoinblocksPresets({ scale: "height", datasets }),
|
||||
createMarketPresets({ scale: "height" }),
|
||||
createMinersPresets("height"),
|
||||
createTransactionsPresets("height"),
|
||||
...createCohortPresetList({
|
||||
scale: "height",
|
||||
color: colors.bitcoin,
|
||||
name: "",
|
||||
datasetKey: "",
|
||||
title: "",
|
||||
}),
|
||||
createHodlersPresets({ scale: "height" }),
|
||||
createAddressesPresets({ scale: "height" }),
|
||||
createCoinblocksPresets({ scale: "height" }),
|
||||
],
|
||||
} satisfies PartialPresetFolder,
|
||||
],
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { averages } from "/src/scripts/datasets/date";
|
||||
import { colors } from "/src/scripts/utils/colors";
|
||||
|
||||
import { applyMultipleSeries } from "../../templates/multiple";
|
||||
import { applySeriesList } from "../../apply";
|
||||
|
||||
export function createPresets(): PartialPresetFolder {
|
||||
const scale: ResourceScale = "date";
|
||||
@@ -15,9 +15,9 @@ export function createPresets(): PartialPresetFolder {
|
||||
name: "All",
|
||||
title: "All Averages",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
list: averages.map((average) => ({
|
||||
top: averages.map((average) => ({
|
||||
title: average.key.toUpperCase(),
|
||||
color: colors[`_${average.key}`],
|
||||
dataset: params.datasets.date[`price_${average.key}_sma`],
|
||||
@@ -60,9 +60,9 @@ function createPresetFolder({
|
||||
icon: IconTablerMathAvg,
|
||||
title: `${name} Moving Average`,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
list: [
|
||||
top: [
|
||||
{
|
||||
title: `SMA`,
|
||||
color,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { colors } from "../../utils/colors";
|
||||
import { applyMultipleSeries } from "../templates/multiple";
|
||||
import { applySeriesList } from "../apply";
|
||||
import { createPresets as createAveragesPresets } from "./averages";
|
||||
import { createPresets as createIndicatorsPresets } from "./indicators";
|
||||
import { createPresets as createReturnsPresets } from "./returns";
|
||||
@@ -14,7 +14,7 @@ export function createPresets({ scale }: { scale: ResourceScale }) {
|
||||
name: "Price",
|
||||
title: "Market Price",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({ ...params });
|
||||
return applySeriesList(params);
|
||||
},
|
||||
description: "",
|
||||
},
|
||||
@@ -24,7 +24,7 @@ export function createPresets({ scale }: { scale: ResourceScale }) {
|
||||
name: "Performance",
|
||||
title: "Market Performance",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceOptions: {
|
||||
id: "performance",
|
||||
@@ -43,12 +43,9 @@ export function createPresets({ scale }: { scale: ResourceScale }) {
|
||||
name: "Capitalization",
|
||||
title: "Market Capitalization",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Market Cap.",
|
||||
dataset: params.datasets[scale].market_cap,
|
||||
|
||||
@@ -3,7 +3,7 @@ import {
|
||||
totalReturns,
|
||||
} from "/src/scripts/datasets/consts/returns";
|
||||
|
||||
import { applyMultipleSeries, SeriesType } from "../../templates/multiple";
|
||||
import { applySeriesList, SeriesType } from "../../apply";
|
||||
|
||||
export function createPresets() {
|
||||
return {
|
||||
@@ -57,12 +57,9 @@ function createPreset({
|
||||
icon: IconTablerReceiptTax,
|
||||
title: `${title} Return`,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: `Return (%)`,
|
||||
seriesType: SeriesType.Based,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { colors } from "../../utils/colors";
|
||||
import { applyMultipleSeries, SeriesType } from "../templates/multiple";
|
||||
import { applySeriesList, SeriesType } from "../apply";
|
||||
|
||||
export function createPresets(scale: ResourceScale) {
|
||||
return {
|
||||
@@ -20,12 +20,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Last Coinbase (In Bitcoin)",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Last",
|
||||
color: colors.bitcoin,
|
||||
@@ -42,12 +39,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Last Coinbase (In Dollars)",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Last",
|
||||
color: colors.dollars,
|
||||
@@ -71,12 +65,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Daily Sum Of Bitcoin Coinbases",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Coinbases (Bitcoin)",
|
||||
color: colors.bitcoin,
|
||||
@@ -93,12 +84,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Daily Sum Of Dollar Coinbases",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Coinbases (Dollars)",
|
||||
color: colors.dollars,
|
||||
@@ -122,12 +110,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Yearly Sum Of Bitcoin Coinbases",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Coinbases (Bitcoin)",
|
||||
color: colors.bitcoin,
|
||||
@@ -144,12 +129,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Yearly Sum Of Dollar Coinbases",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Coinbases (Dollars)",
|
||||
color: colors.dollars,
|
||||
@@ -174,12 +156,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Cumulative Bitcoin Coinbases",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Coinbases (Bitcoin)",
|
||||
color: colors.bitcoin,
|
||||
@@ -197,12 +176,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Cumulative Dollar Coinbases",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Coinbases (Dollars)",
|
||||
color: colors.dollars,
|
||||
@@ -236,12 +212,10 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Last Subsidy (In Bitcoin)",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
|
||||
bottom: [
|
||||
{
|
||||
title: "Last",
|
||||
color: colors.bitcoin,
|
||||
@@ -258,12 +232,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Last Subsidy (In Dollars)",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Last",
|
||||
color: colors.dollars,
|
||||
@@ -287,12 +258,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Daily Sum Of Bitcoin Subsidies",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Subsidies (Bitcoin)",
|
||||
color: colors.bitcoin,
|
||||
@@ -309,12 +277,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Daily Sum Of Dollar Subsidies",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Subsidies (Dollars)",
|
||||
color: colors.dollars,
|
||||
@@ -338,12 +303,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Yearly Sum Of Bitcoin Subsidies",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Subsidies (Bitcoin)",
|
||||
color: colors.bitcoin,
|
||||
@@ -360,12 +322,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Yearly Sum Of Dollar Subsidies",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Subsidies (Dollars)",
|
||||
color: colors.dollars,
|
||||
@@ -390,12 +349,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Cumulative Bitcoin Subsidies",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Subsidies (Bitcoin)",
|
||||
color: colors.bitcoin,
|
||||
@@ -413,12 +369,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Cumulative Dollar Subsidies",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Subsidies (Dollars)",
|
||||
color: colors.dollars,
|
||||
@@ -452,12 +405,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Last Fees (In Bitcoin)",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Last",
|
||||
color: colors.bitcoin,
|
||||
@@ -474,12 +424,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Last Fees (In Dollars)",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Last",
|
||||
color: colors.dollars,
|
||||
@@ -503,12 +450,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Daily Sum Of Bitcoin Fees",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Fees (Bitcoin)",
|
||||
color: colors.bitcoin,
|
||||
@@ -525,12 +469,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Daily Sum Of Dollar Fees",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Fees (Dollars)",
|
||||
color: colors.dollars,
|
||||
@@ -553,12 +494,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Yearly Sum Of Bitcoin Fees",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Fees (Bitcoin)",
|
||||
color: colors.bitcoin,
|
||||
@@ -575,12 +513,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Yearly Sum Of Dollar Fees",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Fees (Dollars)",
|
||||
color: colors.dollars,
|
||||
@@ -604,12 +539,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Cumulative Bitcoin Fees",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Fees (Bitcoin)",
|
||||
color: colors.bitcoin,
|
||||
@@ -626,12 +558,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Cumulative Dollar Fees",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Fees (Dollars)",
|
||||
color: colors.dollars,
|
||||
@@ -657,12 +586,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Subsidy V. Fees",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Subsidy (%)",
|
||||
color: colors.bitcoin,
|
||||
@@ -687,13 +613,12 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Puell Multiple",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
mode: 1,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Multiple",
|
||||
color: colors.bitcoin,
|
||||
@@ -711,13 +636,12 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Hash Rate (EH/s)",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
mode: 1,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "1M SMA",
|
||||
color: colors.momentumYellow,
|
||||
@@ -745,13 +669,12 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Hash Ribbon (EH/s)",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
mode: 1,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "1M SMA",
|
||||
color: colors.profit,
|
||||
@@ -774,12 +697,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Hash Price",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Price ($/PH/s)",
|
||||
color: colors.dollars,
|
||||
@@ -799,13 +719,12 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Difficulty",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
mode: 1,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Difficulty",
|
||||
color: colors.bitcoin,
|
||||
@@ -825,15 +744,11 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Difficulty Adjustment",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Adjustment (%)",
|
||||
// color: colors.bitcoin,
|
||||
seriesType: SeriesType.Based,
|
||||
dataset: params.datasets[scale].difficulty_adjustment,
|
||||
},
|
||||
@@ -851,13 +766,12 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Annualized Issuance",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
mode: 1,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Issuance",
|
||||
color: colors.bitcoin,
|
||||
@@ -875,13 +789,12 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Yearly Inflation Rate",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
mode: 1,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Rate (%)",
|
||||
color: colors.bitcoin,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { percentiles } from "../../datasets/consts/percentiles";
|
||||
import { colors } from "../../utils/colors";
|
||||
import { applyMultipleSeries, SeriesType } from "./multiple";
|
||||
import { applySeriesList, SeriesType } from "../apply";
|
||||
|
||||
export function createCohortPresetFolder<Scale extends ResourceScale>({
|
||||
scale,
|
||||
@@ -54,12 +54,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Unspent Transaction Outputs Count`,
|
||||
icon: () => IconTablerTicket,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Count",
|
||||
color,
|
||||
@@ -83,9 +80,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
description: "",
|
||||
icon: () => IconTablerTag,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
list: [
|
||||
top: [
|
||||
{
|
||||
title: "Realized Price",
|
||||
color,
|
||||
@@ -102,12 +99,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Realized Capitalization`,
|
||||
icon: () => IconTablerPigMoney,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: `${name} Realized Cap.`,
|
||||
color,
|
||||
@@ -136,12 +130,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Realized Capitalization 1 Month Net Change`,
|
||||
icon: () => IconTablerStatusChange,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: `Net Change`,
|
||||
seriesType: SeriesType.Based,
|
||||
@@ -161,12 +152,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Realized Profit`,
|
||||
icon: () => IconTablerCash,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Realized Profit",
|
||||
dataset:
|
||||
@@ -185,12 +173,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Realized Loss`,
|
||||
icon: () => IconTablerCoffin,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Realized Loss",
|
||||
dataset:
|
||||
@@ -209,12 +194,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Realized Profit And Loss`,
|
||||
icon: () => IconTablerArrowsVertical,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Profit",
|
||||
color: colors.profit,
|
||||
@@ -242,12 +224,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Net Realized Profit And Loss`,
|
||||
icon: () => IconTablerScale,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Net PNL",
|
||||
seriesType: SeriesType.Based,
|
||||
@@ -267,12 +246,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Net Realized Profit And Loss Relative To Market Capitalization`,
|
||||
icon: () => IconTablerDivide,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Net",
|
||||
seriesType: SeriesType.Based,
|
||||
@@ -292,12 +268,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Cumulative Realized Profit`,
|
||||
icon: () => IconTablerSum,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Cumulative Realized Profit",
|
||||
color: colors.profit,
|
||||
@@ -318,12 +291,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Cumulative Realized Loss`,
|
||||
icon: () => IconTablerSum,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Cumulative Realized Loss",
|
||||
color: colors.loss,
|
||||
@@ -344,12 +314,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Cumulative Net Realized Profit And Loss`,
|
||||
icon: () => IconTablerSum,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Cumulative Net Realized PNL",
|
||||
seriesType: SeriesType.Based,
|
||||
@@ -369,12 +336,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Cumulative Net Realized Profit And Loss 30 Day Change`,
|
||||
icon: () => IconTablerTimeDuration30,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Cumulative Net Realized PNL 30d Change",
|
||||
dataset:
|
||||
@@ -399,12 +363,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Unrealized Profit`,
|
||||
icon: () => IconTablerMoodDollar,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Profit",
|
||||
dataset:
|
||||
@@ -424,12 +385,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Unrealized Loss`,
|
||||
icon: () => IconTablerMoodSadDizzy,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Loss",
|
||||
dataset:
|
||||
@@ -448,12 +406,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Unrealized Profit And Loss`,
|
||||
icon: () => IconTablerArrowsVertical,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Profit",
|
||||
color: colors.profit,
|
||||
@@ -481,12 +436,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Net Unrealized Profit And Loss`,
|
||||
icon: () => IconTablerScale,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Net Unrealized PNL",
|
||||
dataset:
|
||||
@@ -506,12 +458,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Net Unrealized Profit And Loss Relative To Total Market Capitalization`,
|
||||
icon: () => IconTablerDivide,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Relative Net Unrealized PNL",
|
||||
dataset:
|
||||
@@ -540,12 +489,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
icon: () => IconTablerArrowsCross,
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "In Profit",
|
||||
color: colors.profit,
|
||||
@@ -587,12 +533,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
icon: () => IconTablerSum,
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Supply",
|
||||
color,
|
||||
@@ -609,12 +552,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Supply In Profit`,
|
||||
icon: () => IconTablerTrendingUp,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Supply",
|
||||
color: colors.profit,
|
||||
@@ -635,12 +575,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Supply In Loss`,
|
||||
icon: () => IconTablerTrendingDown,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Supply",
|
||||
color: colors.loss,
|
||||
@@ -667,12 +604,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
icon: () => IconTablerArrowsCross,
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "In Profit",
|
||||
color: colors.profit,
|
||||
@@ -718,12 +652,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Total supply Relative To Circulating Supply`,
|
||||
icon: () => IconTablerSum,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Supply",
|
||||
color,
|
||||
@@ -744,12 +675,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Supply In Profit Relative To Circulating Supply`,
|
||||
icon: () => IconTablerTrendingUp,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Supply",
|
||||
color: colors.profit,
|
||||
@@ -770,12 +698,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Supply In Loss Relative To Circulating Supply`,
|
||||
icon: () => IconTablerTrendingDown,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Supply",
|
||||
seriesType: SeriesType.Area,
|
||||
@@ -801,14 +726,11 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Supply In Profit And Loss Relative To Own Supply`,
|
||||
icon: () => IconTablerArrowsCross,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "In profit",
|
||||
title: "In Profit",
|
||||
dataset:
|
||||
params.datasets[scale][
|
||||
`${datasetPrefix}supply_in_profit_to_own_supply_ratio`
|
||||
@@ -816,7 +738,7 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
color: colors.profit,
|
||||
},
|
||||
{
|
||||
title: "In loss",
|
||||
title: "In Loss",
|
||||
color: colors.loss,
|
||||
dataset:
|
||||
params.datasets[scale][
|
||||
@@ -851,12 +773,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Supply In Profit Relative To Own Supply`,
|
||||
icon: () => IconTablerTrendingUp,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Supply",
|
||||
color: colors.profit,
|
||||
@@ -877,12 +796,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Supply In Loss Relative To Own Supply`,
|
||||
icon: () => IconTablerTrendingDown,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Supply",
|
||||
seriesType: SeriesType.Area,
|
||||
@@ -917,9 +833,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} Average Price Paid - Realized Price`,
|
||||
icon: () => IconTablerMathAvg,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
list: [
|
||||
top: [
|
||||
{
|
||||
title: "Average",
|
||||
color,
|
||||
@@ -937,9 +853,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} deciles`,
|
||||
icon: () => IconTablerSquareHalf,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
list: percentiles
|
||||
top: percentiles
|
||||
.filter(({ value }) => Number(value) % 10 === 0)
|
||||
.map(({ name, key }) => ({
|
||||
dataset: params.datasets[scale][`${datasetPrefix}${key}`],
|
||||
@@ -957,9 +873,9 @@ export function createCohortPresetList<Scale extends ResourceScale>({
|
||||
title: `${title} ${percentile.title}`,
|
||||
icon: () => IconTablerSquareHalf,
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
list: [
|
||||
top: [
|
||||
{
|
||||
title: percentile.name,
|
||||
color,
|
||||
|
||||
@@ -1,183 +0,0 @@
|
||||
import { applyPriceSeries } from "../../lightweightCharts/chart/price";
|
||||
import { chartState } from "../../lightweightCharts/chart/state";
|
||||
import { setTimeScale } from "../../lightweightCharts/chart/time";
|
||||
import { createAreaSeries } from "../../lightweightCharts/series/creators/area";
|
||||
import {
|
||||
createBaseLineSeries,
|
||||
DEFAULT_BASELINE_COLORS,
|
||||
} from "../../lightweightCharts/series/creators/baseLine";
|
||||
import { createHistogramSeries } from "../../lightweightCharts/series/creators/histogram";
|
||||
import { createSeriesLegend } from "../../lightweightCharts/series/creators/legend";
|
||||
import { createLineSeries } from "../../lightweightCharts/series/creators/line";
|
||||
import { resetRightPriceScale } from "../../lightweightCharts/series/options/priceScale";
|
||||
import { stringToId } from "../../utils/id";
|
||||
|
||||
export enum SeriesType {
|
||||
Normal,
|
||||
Based,
|
||||
Area,
|
||||
Histogram,
|
||||
}
|
||||
|
||||
export function applyMultipleSeries<
|
||||
Scale extends ResourceScale,
|
||||
DS extends Dataset<Scale> & Partial<ResourceDataset<Scale>>,
|
||||
>({
|
||||
chart,
|
||||
list = [],
|
||||
preset,
|
||||
priceScaleOptions,
|
||||
datasets,
|
||||
priceDataset,
|
||||
priceOptions,
|
||||
activeResources,
|
||||
}: {
|
||||
chart: IChartApi;
|
||||
preset: Preset;
|
||||
priceDataset?: DS;
|
||||
priceOptions?: PriceSeriesOptions;
|
||||
priceScaleOptions?: FullPriceScaleOptions;
|
||||
list?: (
|
||||
| {
|
||||
dataset: DS;
|
||||
color?: string;
|
||||
colors?: undefined;
|
||||
seriesType: SeriesType.Based;
|
||||
title: string;
|
||||
options?: BaselineSeriesOptions;
|
||||
defaultVisible?: boolean;
|
||||
}
|
||||
| {
|
||||
dataset: DS;
|
||||
color?: string;
|
||||
colors?: string[];
|
||||
seriesType: SeriesType.Histogram;
|
||||
title: string;
|
||||
options?: DeepPartialHistogramOptions;
|
||||
defaultVisible?: boolean;
|
||||
}
|
||||
| {
|
||||
dataset: DS;
|
||||
color: string;
|
||||
colors?: undefined;
|
||||
seriesType?: SeriesType.Normal | SeriesType.Area;
|
||||
title: string;
|
||||
options?: DeepPartialLineOptions;
|
||||
defaultVisible?: boolean;
|
||||
}
|
||||
)[];
|
||||
datasets: Datasets;
|
||||
activeResources: Accessor<Set<ResourceDataset<any, any>>>;
|
||||
}): PresetLegend {
|
||||
const { halved } = priceScaleOptions || {};
|
||||
|
||||
const price = applyPriceSeries({
|
||||
chart,
|
||||
datasets,
|
||||
preset,
|
||||
dataset: priceDataset,
|
||||
activeResources,
|
||||
options: {
|
||||
...priceOptions,
|
||||
halved,
|
||||
},
|
||||
});
|
||||
|
||||
const legendList: PresetLegend = [price.lineLegend, price.ohlcLegend];
|
||||
|
||||
const isAnyArea = list.find(
|
||||
(config) => config.seriesType === SeriesType.Area,
|
||||
);
|
||||
|
||||
const rightPriceScaleOptions = resetRightPriceScale(chart, {
|
||||
...priceScaleOptions,
|
||||
...(isAnyArea
|
||||
? {
|
||||
scaleMargins: {
|
||||
bottom: 0,
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
});
|
||||
|
||||
[...list]
|
||||
.reverse()
|
||||
.forEach(
|
||||
({
|
||||
dataset,
|
||||
color,
|
||||
colors,
|
||||
seriesType: type,
|
||||
title,
|
||||
options,
|
||||
defaultVisible,
|
||||
}) => {
|
||||
let series: ISeriesApi<"Baseline" | "Line" | "Area" | "Histogram">;
|
||||
|
||||
if (type === SeriesType.Based) {
|
||||
series = createBaseLineSeries(chart, {
|
||||
color,
|
||||
...options,
|
||||
});
|
||||
} else if (type === SeriesType.Area) {
|
||||
series = createAreaSeries(chart, {
|
||||
color,
|
||||
autoscaleInfoProvider: (getInfo: () => AutoscaleInfo | null) => {
|
||||
const info = getInfo();
|
||||
if (info) {
|
||||
info.priceRange.minValue = 0;
|
||||
}
|
||||
return info;
|
||||
},
|
||||
...options,
|
||||
});
|
||||
} else if (type === SeriesType.Histogram) {
|
||||
series = createHistogramSeries(chart, {
|
||||
color,
|
||||
...options,
|
||||
});
|
||||
} else {
|
||||
series = createLineSeries(chart, {
|
||||
color,
|
||||
...options,
|
||||
});
|
||||
}
|
||||
|
||||
legendList.splice(
|
||||
0,
|
||||
0,
|
||||
createSeriesLegend({
|
||||
id: stringToId(title),
|
||||
presetId: preset.id,
|
||||
title,
|
||||
series,
|
||||
color: () => colors || color || DEFAULT_BASELINE_COLORS,
|
||||
defaultVisible,
|
||||
url: dataset.url,
|
||||
}),
|
||||
);
|
||||
|
||||
createEffect(() => {
|
||||
series.setData(dataset?.values() || []);
|
||||
|
||||
setTimeScale(chartState.range);
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
createEffect(() => {
|
||||
const options = {
|
||||
scaleMargins: {
|
||||
top:
|
||||
price.lineLegend.visible() || price.ohlcLegend.visible()
|
||||
? rightPriceScaleOptions.scaleMargins.top
|
||||
: rightPriceScaleOptions.scaleMargins.bottom,
|
||||
bottom: rightPriceScaleOptions.scaleMargins.bottom,
|
||||
},
|
||||
};
|
||||
|
||||
chart.priceScale("right").applyOptions(options);
|
||||
});
|
||||
|
||||
return legendList;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { colors } from "../../utils/colors";
|
||||
import { applyMultipleSeries } from "../templates/multiple";
|
||||
import { applySeriesList } from "../apply";
|
||||
|
||||
export function createPresets(scale: ResourceScale) {
|
||||
return {
|
||||
@@ -12,12 +12,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Transaction Count",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "1M SMA",
|
||||
color: colors.momentumYellow,
|
||||
@@ -48,12 +45,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Transaction Volume",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "1M SMA",
|
||||
color: colors.momentumYellow,
|
||||
@@ -80,13 +74,12 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Transaction Volume In Dollars",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
mode: 1,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "1M SMA",
|
||||
color: colors.lightDollars,
|
||||
@@ -124,12 +117,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Annualized Transaction Volume",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Volume",
|
||||
color: colors.bitcoin,
|
||||
@@ -147,12 +137,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Annualized Transaction Volume In Dollars",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Volume",
|
||||
color: colors.dollars,
|
||||
@@ -173,12 +160,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Transactions Velocity",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "Transactions Velocity",
|
||||
color: colors.bitcoin,
|
||||
@@ -195,12 +179,9 @@ export function createPresets(scale: ResourceScale) {
|
||||
title: "Transactions Per Second",
|
||||
description: "",
|
||||
applyPreset(params) {
|
||||
return applyMultipleSeries({
|
||||
return applySeriesList({
|
||||
...params,
|
||||
priceScaleOptions: {
|
||||
halved: true,
|
||||
},
|
||||
list: [
|
||||
bottom: [
|
||||
{
|
||||
title: "1M SMA",
|
||||
color: colors.lightBitcoin,
|
||||
|
||||
Vendored
+4
-4
@@ -20,13 +20,13 @@ type FilePath = {
|
||||
}[];
|
||||
|
||||
type ApplyPreset = (params: {
|
||||
chart: IChartApi;
|
||||
charts: RWS<IChartApi[]>;
|
||||
parentDiv: HTMLDivElement;
|
||||
datasets: Datasets;
|
||||
preset: Preset;
|
||||
activeResources: Accessor<Set<ResourceDataset<any, any>>>;
|
||||
}) => ApplyPresetReturn;
|
||||
|
||||
type ApplyPresetReturn = PresetLegend;
|
||||
legendSetter: Setter<PresetLegend>;
|
||||
}) => void;
|
||||
|
||||
interface PartialPresetFolder {
|
||||
name: string;
|
||||
|
||||
@@ -1,31 +1,52 @@
|
||||
export const priceToUSLocale = (price: number, compact = true) => {
|
||||
const absolutePrice = Math.abs(price);
|
||||
const lessThan100 = absolutePrice < 100;
|
||||
const lessThan1000 = absolutePrice < 1_000;
|
||||
const biggerThanMillion = absolutePrice >= 1_000_000;
|
||||
const suffices = ["M", "B", "T", "Q"];
|
||||
|
||||
return numberToUSLocale(
|
||||
price,
|
||||
lessThan1000 ? (lessThan100 ? 2 : 1) : biggerThanMillion ? 3 : 0,
|
||||
biggerThanMillion && compact
|
||||
? {
|
||||
notation: "compact",
|
||||
compactDisplay: "short",
|
||||
}
|
||||
: undefined,
|
||||
);
|
||||
};
|
||||
export function valueToString(value: number) {
|
||||
const absoluteValue = Math.abs(value);
|
||||
|
||||
export const percentageToUSLocale = (percentage: number) =>
|
||||
numberToUSLocale(percentage, 1);
|
||||
// value = absoluteValue;
|
||||
|
||||
const numberToUSLocale = (
|
||||
if (isNaN(value)) {
|
||||
return "";
|
||||
// } else if (value === 0) {
|
||||
// return "0";
|
||||
} else if (absoluteValue < 10) {
|
||||
return numberToUSLocale(value, 3);
|
||||
} else if (absoluteValue < 100) {
|
||||
return numberToUSLocale(value, 2);
|
||||
} else if (absoluteValue < 1_000) {
|
||||
return numberToUSLocale(value, 1);
|
||||
} else if (absoluteValue < 100_000) {
|
||||
return numberToUSLocale(value, 0);
|
||||
} else if (absoluteValue < 1_000_000) {
|
||||
return `${numberToUSLocale(value / 1_000, 1)}K`;
|
||||
} else if (absoluteValue >= 1_000_000_000_000_000_000) {
|
||||
return "Inf.";
|
||||
}
|
||||
|
||||
const log = Math.floor(Math.log10(absoluteValue) - 6);
|
||||
|
||||
const letterIndex = Math.floor(log / 3);
|
||||
const letter = suffices[letterIndex];
|
||||
|
||||
const modulused = log % 3;
|
||||
|
||||
if (modulused === 0) {
|
||||
return `${numberToUSLocale(value / (1_000_000 * 1_000 ** letterIndex), 3)}${letter}`;
|
||||
} else if (modulused === 1) {
|
||||
return `${numberToUSLocale(value / (1_000_000 * 1_000 ** letterIndex), 2)}${letter}`;
|
||||
} else {
|
||||
return `${numberToUSLocale(value / (1_000_000 * 1_000 ** letterIndex), 1)}${letter}`;
|
||||
}
|
||||
}
|
||||
|
||||
function numberToUSLocale(
|
||||
value: number,
|
||||
digits: number,
|
||||
digits?: number,
|
||||
options?: Intl.NumberFormatOptions | undefined,
|
||||
) =>
|
||||
value.toLocaleString("en-us", {
|
||||
) {
|
||||
return value.toLocaleString("en-us", {
|
||||
...options,
|
||||
minimumFractionDigits: digits,
|
||||
maximumFractionDigits: digits,
|
||||
});
|
||||
}
|
||||
|
||||
+12
-12
@@ -1,7 +1,7 @@
|
||||
import { createRWS } from "/src/solid/rws";
|
||||
|
||||
export const createSelectableList = <T, L extends T[] = T[]>(
|
||||
list: L,
|
||||
export const createDynamicList = <T, L extends T[] = T[]>(
|
||||
l: L,
|
||||
parameters?: {
|
||||
selected?: L[number];
|
||||
selectedIndex?: number | null;
|
||||
@@ -10,10 +10,10 @@ export const createSelectableList = <T, L extends T[] = T[]>(
|
||||
const selected = createRWS<L[number] | null>(null);
|
||||
const selectedIndex = createRWS<number | null>(null);
|
||||
|
||||
const selectableList: SelectableList<L[number], L> = {
|
||||
const list: DynamicList<L[number], L> = {
|
||||
selected,
|
||||
selectedIndex,
|
||||
list: createRWS(list, {
|
||||
list: createRWS(l, {
|
||||
equals: false,
|
||||
}),
|
||||
select(s) {
|
||||
@@ -83,10 +83,10 @@ export const createSelectableList = <T, L extends T[] = T[]>(
|
||||
toJSON<TJSON, LJSON extends TJSON[] = TJSON[]>(
|
||||
transform: (value: T) => TJSON,
|
||||
filter?: (value: T) => boolean,
|
||||
): JSONSelectableList<TJSON, LJSON> {
|
||||
): JSONDynamicList<TJSON, LJSON> {
|
||||
return {
|
||||
version: 1,
|
||||
selectedIndex: getIndexOfSelectedInSelectableList(this),
|
||||
selectedIndex: getIndexOfSelectedInDynamicList(this),
|
||||
list: (filter ? this.list().filter(filter) : this.list()).map((value) =>
|
||||
transform(value),
|
||||
) as LJSON,
|
||||
@@ -95,18 +95,18 @@ export const createSelectableList = <T, L extends T[] = T[]>(
|
||||
};
|
||||
|
||||
if (parameters?.selected !== undefined) {
|
||||
selectableList.select(parameters.selected);
|
||||
list.select(parameters.selected);
|
||||
} else if (parameters?.selectedIndex !== undefined) {
|
||||
selectableList.selectIndex(parameters.selectedIndex);
|
||||
list.selectIndex(parameters.selectedIndex);
|
||||
}
|
||||
|
||||
return selectableList;
|
||||
return list;
|
||||
};
|
||||
|
||||
export const createSL = createSelectableList;
|
||||
export const createDSL = createDynamicList;
|
||||
|
||||
export const getIndexOfSelectedInSelectableList = <T, L extends T[] = T[]>(
|
||||
sl: SelectableList<L[number], L>,
|
||||
export const getIndexOfSelectedInDynamicList = <T, L extends T[] = T[]>(
|
||||
sl: DynamicList<L[number], L>,
|
||||
) => {
|
||||
const selected = sl.selected();
|
||||
|
||||
+3
-3
@@ -2,7 +2,7 @@
|
||||
// JSON
|
||||
// ---
|
||||
|
||||
interface JSONSelectableList<T, L extends T[] = T[]> {
|
||||
interface JSONDynamicList<T, L extends T[] = T[]> {
|
||||
readonly version: 1;
|
||||
selectedIndex: number | null;
|
||||
readonly list: L;
|
||||
@@ -12,7 +12,7 @@ interface JSONSelectableList<T, L extends T[] = T[]> {
|
||||
// Object
|
||||
// ---
|
||||
|
||||
interface SelectableList<T, L extends T[] = T[]> {
|
||||
interface DynamicList<T, L extends T[] = T[]> {
|
||||
readonly selected: Accessor<T | null>;
|
||||
readonly selectedIndex: Accessor<number | null>;
|
||||
readonly list: RWS<L>;
|
||||
@@ -29,5 +29,5 @@ interface SelectableList<T, L extends T[] = T[]> {
|
||||
readonly toJSON: <TJSON, LJSON extends TJSON[] = TJSON[]>(
|
||||
transform: (value: T) => LJSON[number],
|
||||
filter?: (value: T) => boolean,
|
||||
) => JSONSelectableList<TJSON, LJSON>;
|
||||
) => JSONDynamicList<TJSON, LJSON>;
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
import { createRWS } from "/src/solid/rws";
|
||||
|
||||
import { run } from "../../run";
|
||||
|
||||
export const createStaticList = <T, L extends T[] = T[]>(
|
||||
l: L,
|
||||
parameters: {
|
||||
selected?: L[number];
|
||||
selectedIndex?: number;
|
||||
saveable?: {
|
||||
mode: "localStorage" | "URLParams" | "both";
|
||||
key: string;
|
||||
};
|
||||
defaultValue?: L[number];
|
||||
defaultIndex?: number;
|
||||
},
|
||||
) => {
|
||||
if (
|
||||
!l.length ||
|
||||
(parameters.saveable === undefined &&
|
||||
parameters.selected === undefined &&
|
||||
parameters.selectedIndex === undefined)
|
||||
) {
|
||||
throw Error("not possible");
|
||||
}
|
||||
|
||||
const selected = createRWS<L[number]>(
|
||||
run(() => {
|
||||
let savedIndex: number | undefined;
|
||||
|
||||
if (parameters.saveable) {
|
||||
if (parameters.saveable.mode !== "localStorage") {
|
||||
throw Error("unsupported");
|
||||
}
|
||||
|
||||
const savedRaw = localStorage.getItem(parameters.saveable.key);
|
||||
|
||||
if (savedRaw) {
|
||||
savedIndex = Number(savedRaw);
|
||||
}
|
||||
}
|
||||
|
||||
if (parameters.selected) {
|
||||
const found = l.find((v) => v === parameters.selected);
|
||||
|
||||
if (!found) {
|
||||
throw Error("unreachable");
|
||||
}
|
||||
|
||||
return found;
|
||||
} else {
|
||||
return (
|
||||
l.at(savedIndex ?? parameters.selectedIndex!) ??
|
||||
parameters.defaultValue ??
|
||||
l[parameters.defaultIndex || 0]
|
||||
);
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
const selectedIndex = createRWS<number>(
|
||||
run(() => {
|
||||
if (
|
||||
parameters.selectedIndex !== null &&
|
||||
parameters.selectedIndex !== undefined
|
||||
) {
|
||||
const found = l.at(parameters.selectedIndex);
|
||||
|
||||
if (!found) {
|
||||
throw Error("unreachable");
|
||||
}
|
||||
|
||||
return parameters.selectedIndex;
|
||||
} else {
|
||||
return l.indexOf(selected());
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
createEffect(() => {
|
||||
if (parameters.saveable) {
|
||||
localStorage.setItem(parameters.saveable.key, String(selectedIndex()));
|
||||
}
|
||||
});
|
||||
|
||||
const list: StaticList<L[number], L> = {
|
||||
selected,
|
||||
selectedIndex,
|
||||
list: createRWS(l, {
|
||||
equals: false,
|
||||
}),
|
||||
select(s) {
|
||||
if (this.selected() !== s) {
|
||||
batch(() => {
|
||||
selected.set(() => s);
|
||||
this.selectIndex(this.list().indexOf(s));
|
||||
});
|
||||
}
|
||||
},
|
||||
selectIndex(i) {
|
||||
if (i && (i < 0 || i >= this.list().length)) {
|
||||
throw new Error(
|
||||
`SelectableList: selectIndex: ${i} is incorrect ! (has ${
|
||||
this.list().length
|
||||
} elements)`,
|
||||
);
|
||||
}
|
||||
|
||||
if (i !== this.selectedIndex()) {
|
||||
selectedIndex.set(i);
|
||||
|
||||
const value = this.list().at(i);
|
||||
|
||||
if (value === undefined) {
|
||||
throw Error("unreachable");
|
||||
}
|
||||
|
||||
this.select(value);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
if (parameters?.selected !== undefined) {
|
||||
list.select(parameters.selected);
|
||||
} else if (parameters?.selectedIndex !== undefined) {
|
||||
list.selectIndex(parameters.selectedIndex);
|
||||
}
|
||||
|
||||
return list;
|
||||
};
|
||||
|
||||
export const createSL = createStaticList;
|
||||
|
||||
export const getIndexOfSelectedInStaticList = <T, L extends T[] = T[]>(
|
||||
sl: StaticList<L[number], L>,
|
||||
) => {
|
||||
const selected = sl.selected();
|
||||
|
||||
return selected ? sl.list().indexOf(selected) : null;
|
||||
};
|
||||
@@ -0,0 +1,9 @@
|
||||
interface StaticList<T, L extends T[] = T[]> {
|
||||
readonly selected: Accessor<T>;
|
||||
readonly selectedIndex: Accessor<number>;
|
||||
readonly list: RWS<L>;
|
||||
readonly select: <S extends L[number] = L[number]>(s: S) => void;
|
||||
readonly selectIndex: (index: number) => void;
|
||||
}
|
||||
|
||||
type SL<T, L extends T[] = T[]> = StaticList<T, L>;
|
||||
+32
-2
@@ -28,9 +28,39 @@ html {
|
||||
}
|
||||
|
||||
a {
|
||||
@apply text-orange-300 hover:underline;
|
||||
@apply text-orange-700 hover:underline dark:text-orange-300;
|
||||
}
|
||||
|
||||
mark {
|
||||
@apply bg-transparent p-0 text-orange-400;
|
||||
@apply bg-transparent p-0 text-orange-600 dark:text-orange-400;
|
||||
}
|
||||
|
||||
/* Hide scrollbar for Chrome, Safari and Opera */
|
||||
.no-scrollbar::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Hide scrollbar for IE, Edge and Firefox */
|
||||
.no-scrollbar {
|
||||
-ms-overflow-style: none; /* IE and Edge */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
}
|
||||
|
||||
.border-light {
|
||||
@apply border-orange-800/25 dark:border-orange-200/25;
|
||||
}
|
||||
|
||||
.border-lighter {
|
||||
@apply border-orange-800/[0.125] dark:border-orange-200/[0.125];
|
||||
}
|
||||
|
||||
.border-superlight {
|
||||
@apply border-orange-800/5 dark:border-orange-200/[0.0625];
|
||||
}
|
||||
|
||||
.text-high-contrast {
|
||||
@apply text-orange-950 dark:text-orange-50;
|
||||
}
|
||||
.decoration-high-contrast {
|
||||
@apply decoration-orange-950 dark:decoration-orange-50;
|
||||
}
|
||||
|
||||
+2
@@ -63,3 +63,5 @@ type DeepPartialBaselineOptions = DeepPartial<
|
||||
>;
|
||||
|
||||
type DeepPartialChartOptions = DeepPartial<ChartOptions>;
|
||||
|
||||
type DeepPartialPriceScaleOptions = DeepPartial<PriceScaleOptions>;
|
||||
@@ -14,7 +14,6 @@ export default {
|
||||
sans: ["Lexend", ...defaultTheme.fontFamily.sans],
|
||||
},
|
||||
screens: {
|
||||
md: "720px",
|
||||
"2xl": "1600px",
|
||||
short: { raw: "(max-height: 350px)" },
|
||||
},
|
||||
|
||||
@@ -70,7 +70,7 @@ impl CointimeDataset {
|
||||
active_supply: BiMap::new_bin(1, &f("active_supply")),
|
||||
active_supply_3m_net_change: BiMap::new_bin(1, &f("active_supply_3m_net_change")),
|
||||
active_supply_net_change: BiMap::new_bin(1, &f("active_supply_net_change")),
|
||||
activity_to_vaultedness_ratio: BiMap::new_bin(1, &f("activity_to_vaultedness_ratio")),
|
||||
activity_to_vaultedness_ratio: BiMap::new_bin(2, &f("activity_to_vaultedness_ratio")),
|
||||
coinblocks_created: BiMap::new_bin(1, &f("coinblocks_created")),
|
||||
coinblocks_destroyed: BiMap::new_bin(1, &f("coinblocks_destroyed")),
|
||||
coinblocks_stored: BiMap::new_bin(1, &f("coinblocks_stored")),
|
||||
@@ -106,7 +106,7 @@ impl CointimeDataset {
|
||||
producerness: BiMap::new_bin(1, &f("producerness")),
|
||||
thermo_cap: BiMap::new_bin(1, &f("thermo_cap")),
|
||||
thermo_cap_to_investor_cap_ratio: BiMap::new_bin(
|
||||
1,
|
||||
2,
|
||||
&f("thermo_cap_to_investor_cap_ratio"),
|
||||
),
|
||||
total_cointime_value_created: BiMap::new_bin(1, &f("total_cointime_value_created")),
|
||||
@@ -215,7 +215,7 @@ impl CointimeDataset {
|
||||
&|liveliness| 1.0 - liveliness,
|
||||
);
|
||||
|
||||
self.activity_to_vaultedness_ratio.multi_insert_divide(
|
||||
self.activity_to_vaultedness_ratio.multi_insert_percentage(
|
||||
heights,
|
||||
dates,
|
||||
&mut self.liveliness,
|
||||
@@ -332,12 +332,8 @@ impl CointimeDataset {
|
||||
self.investor_cap
|
||||
.multi_insert_subtract(heights, dates, realized_cap, &mut self.thermo_cap);
|
||||
|
||||
self.thermo_cap_to_investor_cap_ratio.multi_insert_divide(
|
||||
heights,
|
||||
dates,
|
||||
&mut self.thermo_cap,
|
||||
&mut self.investor_cap,
|
||||
);
|
||||
self.thermo_cap_to_investor_cap_ratio
|
||||
.multi_insert_percentage(heights, dates, &mut self.thermo_cap, &mut self.investor_cap);
|
||||
|
||||
// TODO:
|
||||
// const activeSupplyChangeFromIssuance90dChange = createNetChangeLazyDataset(
|
||||
|
||||
@@ -38,7 +38,7 @@ impl RealizedSubDataset {
|
||||
negative_realized_loss: BiMap::new_bin(2, &f("negative_realized_loss")),
|
||||
net_realized_profit_and_loss: BiMap::new_bin(1, &f("net_realized_profit_and_loss")),
|
||||
net_realized_profit_and_loss_to_market_cap_ratio: BiMap::new_bin(
|
||||
1,
|
||||
2,
|
||||
&f("net_realized_profit_and_loss_to_market_cap_ratio"),
|
||||
),
|
||||
cumulative_realized_profit: BiMap::new_bin(1, &f("cumulative_realized_profit")),
|
||||
@@ -107,7 +107,7 @@ impl RealizedSubDataset {
|
||||
);
|
||||
|
||||
self.net_realized_profit_and_loss_to_market_cap_ratio
|
||||
.multi_insert_divide(
|
||||
.multi_insert_percentage(
|
||||
heights,
|
||||
dates,
|
||||
&mut self.net_realized_profit_and_loss,
|
||||
|
||||
@@ -40,7 +40,7 @@ impl UnrealizedSubDataset {
|
||||
negative_unrealized_loss: BiMap::new_bin(1, &f("negative_unrealized_loss")),
|
||||
net_unrealized_profit_and_loss: BiMap::new_bin(1, &f("net_unrealized_profit_and_loss")),
|
||||
net_unrealized_profit_and_loss_to_market_cap_ratio: BiMap::new_bin(
|
||||
1,
|
||||
2,
|
||||
&f("net_unrealized_profit_and_loss_to_market_cap_ratio"),
|
||||
),
|
||||
supply_in_profit_to_own_supply_ratio: BiMap::new_bin(
|
||||
@@ -136,7 +136,7 @@ impl UnrealizedSubDataset {
|
||||
);
|
||||
|
||||
self.net_unrealized_profit_and_loss_to_market_cap_ratio
|
||||
.multi_insert_divide(
|
||||
.multi_insert_percentage(
|
||||
heights,
|
||||
dates,
|
||||
&mut self.net_unrealized_profit_and_loss,
|
||||
|
||||
@@ -273,20 +273,30 @@ where
|
||||
std::any::type_name::<T>()
|
||||
}
|
||||
|
||||
// fn reset(&mut self) -> color_eyre::Result<()> {
|
||||
// fs::remove_dir(&self.path_all)?;
|
||||
|
||||
// self.initial_last_height = None;
|
||||
// self.initial_first_unsafe_height = None;
|
||||
|
||||
// self.imported.clear();
|
||||
// self.to_insert.clear();
|
||||
|
||||
// Ok(())
|
||||
// }
|
||||
|
||||
fn pre_export(&mut self) {
|
||||
self.to_insert.iter_mut().for_each(|(chunk_start, map)| {
|
||||
let to_insert = &mut self.to_insert;
|
||||
|
||||
to_insert.iter_mut().for_each(|(chunk_start, map)| {
|
||||
if let Some((key, _)) = map.first_key_value() {
|
||||
if *key > 0 && !self.imported.contains_key(chunk_start) {
|
||||
// Had to copy paste many lines from functions as calling a function from self isn't allowed because of the &mut
|
||||
|
||||
let dir_content = Self::_read_dir(&self.path_all, &self.serialization);
|
||||
|
||||
let path = dir_content.get(chunk_start).unwrap_or_else(|| {
|
||||
dbg!(&self.path_all, chunk_start, &dir_content);
|
||||
panic!();
|
||||
});
|
||||
|
||||
let serialized = self
|
||||
.serialization
|
||||
.import::<SerializedHeightMap<T>>(path.to_str().unwrap())
|
||||
.unwrap();
|
||||
|
||||
self.imported.insert(*chunk_start, serialized);
|
||||
}
|
||||
}
|
||||
|
||||
let serialized = self
|
||||
.imported
|
||||
.entry(*chunk_start)
|
||||
@@ -301,7 +311,10 @@ where
|
||||
|(chunk_height, value)| match serialized.map.len().cmp(&chunk_height) {
|
||||
Ordering::Greater => serialized.map[chunk_height] = value,
|
||||
Ordering::Equal => serialized.map.push(value),
|
||||
Ordering::Less => panic!(),
|
||||
Ordering::Less => {
|
||||
dbg!(&self.path_all, &serialized.map, chunk_height, value);
|
||||
panic!()
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user