From 9613fce9193b580f1e2e9bff87c2ab9458ca7321 Mon Sep 17 00:00:00 2001 From: nym21 Date: Tue, 20 Jan 2026 15:04:00 +0100 Subject: [PATCH] global: snapshot --- .cargo/config.toml | 13 + .gitignore | 3 +- Cargo.lock | 42 +- Cargo.toml | 4 +- crates/brk_cli/README.md | 4 +- crates/brk_client/src/lib.rs | 3928 ++++------------- crates/brk_computer/Cargo.toml | 2 +- crates/brk_computer/src/constants.rs | 20 +- .../state/cost_basis/price_to_amount.rs | 9 +- .../src/internal/single/transform/mod.rs | 4 +- .../internal/single/transform/return_i16.rs | 12 - .../internal/single/transform/return_i8.rs | 12 + crates/brk_indexer/src/stores.rs | 8 +- crates/brk_playground/Cargo.toml | 8 + crates/brk_playground/src/lib.rs | 28 +- crates/brk_query/src/impl/metrics.rs | 2 + crates/brk_query/src/impl/metrics_legacy.rs | 1 + crates/brk_query/src/resolved.rs | 3 +- crates/brk_store/src/any.rs | 1 + crates/brk_store/src/lib.rs | 11 + crates/brk_store/src/meta.rs | 8 + crates/brk_types/src/dateindex.rs | 22 +- crates/brk_types/src/decadeindex.rs | 16 +- crates/brk_types/src/etag.rs | 8 +- crates/brk_types/src/halvingepoch.rs | 14 +- crates/brk_types/src/lib.rs | 2 + crates/brk_types/src/metricoutput.rs | 14 +- crates/brk_types/src/monthindex.rs | 2 +- crates/brk_types/src/outputtype.rs | 14 +- crates/brk_types/src/quarterindex.rs | 14 +- crates/brk_types/src/semesterindex.rs | 14 +- crates/brk_types/src/stored_bool.rs | 4 +- crates/brk_types/src/stored_i8.rs | 123 + crates/brk_types/src/txversion.rs | 8 +- crates/brk_types/src/yearindex.rs | 16 +- modules/brk-client/index.js | 380 +- packages/brk_client/brk_client/__init__.py | 184 +- website/.gitignore | 2 + website/scripts/chart/index.js | 200 +- website/scripts/chart/legend.js | 51 +- website/scripts/chart/markers.js | 38 +- website/scripts/chart/state.js | 105 +- website/scripts/main.js | 4 +- .../panes/{explorer.js => _explorer.js} | 0 .../panes/{simulation.js => _simulation.js} | 0 website/scripts/panes/chart/index.js | 48 +- website/scripts/signals.js | 207 +- website/scripts/utils/colors.js | 145 +- website/scripts/utils/dom.js | 41 +- website/scripts/utils/serde.js | 4 +- website/scripts/utils/storage.js | 22 - website/scripts/utils/url.js | 8 +- website/service-worker.js | 59 +- 53 files changed, 1811 insertions(+), 4081 deletions(-) delete mode 100644 crates/brk_computer/src/internal/single/transform/return_i16.rs create mode 100644 crates/brk_computer/src/internal/single/transform/return_i8.rs create mode 100644 crates/brk_types/src/stored_i8.rs rename website/scripts/panes/{explorer.js => _explorer.js} (100%) rename website/scripts/panes/{simulation.js => _simulation.js} (100%) diff --git a/.cargo/config.toml b/.cargo/config.toml index ddff4407b..d627f84c7 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,2 +1,15 @@ [build] rustflags = ["-C", "target-cpu=native"] + +# pco (pcodec) decompression is significantly faster with these SIMD instructions +[target.x86_64-unknown-linux-gnu] +rustflags = ["-C", "target-cpu=native", "-C", "target-feature=+bmi1,+bmi2,+avx2"] + +[target.x86_64-apple-darwin] +rustflags = ["-C", "target-cpu=native", "-C", "target-feature=+bmi1,+bmi2,+avx2"] + +[target.x86_64-pc-windows-msvc] +rustflags = ["-C", "target-cpu=native", "-C", "target-feature=+bmi1,+bmi2,+avx2"] + +[target.x86_64-pc-windows-gnu] +rustflags = ["-C", "target-cpu=native", "-C", "target-feature=+bmi1,+bmi2,+avx2"] diff --git a/.gitignore b/.gitignore index 416b4b09c..76cffb2ea 100644 --- a/.gitignore +++ b/.gitignore @@ -20,7 +20,8 @@ _* /*.html /research /filter_* -/heatmaps +/heatmaps* +/oracle* # Logs *.log* diff --git a/Cargo.lock b/Cargo.lock index 24ad0f751..ab41ff931 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -54,7 +54,7 @@ dependencies = [ "serde", "serde_json", "serde_qs", - "thiserror 2.0.17", + "thiserror 2.0.18", "tower-layer", "tower-service", "tracing", @@ -483,7 +483,7 @@ dependencies = [ "jiff", "minreq", "serde_json", - "thiserror 2.0.17", + "thiserror 2.0.18", "tokio", "vecdb", ] @@ -1158,9 +1158,9 @@ dependencies = [ [[package]] name = "dtype_dispatch" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3a5ccdfd6c5e7e2fea9c5cf256f2a08216047fab19c621c3da64e9ae4a1462d" +checksum = "63cb69518c750a905135325cb009ffb24e1dff48cfc7bee026cd8e7e90d14f26" [[package]] name = "dwrote" @@ -2255,9 +2255,9 @@ dependencies = [ [[package]] name = "pco" -version = "0.4.9" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42382de9fb564e2d10cb4d5ca97cc06d928f0f9667bbef456b57e60827b6548b" +checksum = "4acf50a078a796b341d327c18a0d3b2d2ca7dd630f04958558608169e2686e87" dependencies = [ "better_io", "dtype_dispatch", @@ -2483,8 +2483,6 @@ dependencies = [ [[package]] name = "rawdb" version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "133cd3a1d92510fe902efcdf70a7f45aa83e1cd47173d8cc013fef82af0b8f8e" dependencies = [ "libc", "log", @@ -2492,7 +2490,7 @@ dependencies = [ "parking_lot", "rayon", "smallvec", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] @@ -2532,7 +2530,7 @@ checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ "getrandom 0.2.17", "libredox", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] @@ -2845,7 +2843,7 @@ dependencies = [ "futures", "percent-encoding", "serde", - "thiserror 2.0.17", + "thiserror 2.0.18", ] [[package]] @@ -3011,11 +3009,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.17" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" dependencies = [ - "thiserror-impl 2.0.17", + "thiserror-impl 2.0.18", ] [[package]] @@ -3031,9 +3029,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.17" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", @@ -3234,7 +3232,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "786d480bce6247ab75f005b14ae1624ad978d3029d9113f0a22fa1ac773faeaf" dependencies = [ "crossbeam-channel", - "thiserror 2.0.17", + "thiserror 2.0.18", "time", "tracing-subscriber", ] @@ -3366,8 +3364,6 @@ checksum = "8f54a172d0620933a27a4360d3db3e2ae0dd6cceae9730751a036bbf182c4b23" [[package]] name = "vecdb" version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a9b98950cd49f718ec32f3b91282b9d0c033ea15430436ddb0cc286c77aa5bb" dependencies = [ "ctrlc", "log", @@ -3378,7 +3374,7 @@ dependencies = [ "schemars", "serde", "serde_json", - "thiserror 2.0.17", + "thiserror 2.0.18", "vecdb_derive", "zerocopy", "zstd", @@ -3387,8 +3383,6 @@ dependencies = [ [[package]] name = "vecdb_derive" version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "043380b6bd5d519b63def192ff310f7a599feaca7f5b12cc86e5d9dd7eabf750" dependencies = [ "quote", "syn", @@ -3881,9 +3875,9 @@ dependencies = [ [[package]] name = "zmij" -version = "1.0.14" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd8f3f50b848df28f887acb68e41201b5aea6bc8a8dacc00fb40635ff9a72fea" +checksum = "dfcd145825aace48cff44a8844de64bf75feec3080e0aa5cdbde72961ae51a65" [[package]] name = "zstd" diff --git a/Cargo.toml b/Cargo.toml index 0e55e02c0..5234a4234 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -81,8 +81,8 @@ tokio = { version = "1.49.0", features = ["rt-multi-thread"] } tracing = { version = "0.1", default-features = false, features = ["std"] } tower-http = { version = "0.6.8", features = ["catch-panic", "compression-br", "compression-gzip", "compression-zstd", "cors", "normalize-path", "timeout", "trace"] } tower-layer = "0.3" -vecdb = { version = "0.5.11", features = ["derive", "serde_json", "pco", "schemars"] } -# vecdb = { path = "../anydb/crates/vecdb", features = ["derive", "serde_json", "pco", "schemars"] } +# vecdb = { version = "0.5.11", features = ["derive", "serde_json", "pco", "schemars"] } +vecdb = { path = "../anydb/crates/vecdb", features = ["derive", "serde_json", "pco", "schemars"] } [workspace.metadata.release] shared-version = true diff --git a/crates/brk_cli/README.md b/crates/brk_cli/README.md index 0c20a71f7..a9fd9f453 100644 --- a/crates/brk_cli/README.md +++ b/crates/brk_cli/README.md @@ -18,9 +18,11 @@ Command-line interface for running a Bitcoin Research Kit instance. ```bash rustup update -RUSTFLAGS="-C target-cpu=native" cargo install --locked brk_cli --version "$(cargo search brk_cli | head -1 | awk -F'"' '{print $2}')" +RUSTFLAGS="-C target-cpu=native -C target-feature=+bmi1,+bmi2,+avx2" cargo install --locked brk_cli --version "$(cargo search brk_cli | head -1 | awk -F'"' '{print $2}')" ``` +The SIMD flags (`bmi1`, `bmi2`, `avx2`) significantly improve pcodec decompression performance. + Portable build (without native CPU optimizations): ```bash diff --git a/crates/brk_client/src/lib.rs b/crates/brk_client/src/lib.rs index bb68e33da..b8600309e 100644 --- a/crates/brk_client/src/lib.rs +++ b/crates/brk_client/src/lib.rs @@ -7,11 +7,12 @@ #![allow(clippy::useless_format)] #![allow(clippy::unnecessary_to_owned)] +use std::sync::Arc; +use std::ops::{Bound, RangeBounds}; +use serde::de::DeserializeOwned; pub use brk_cohort::*; pub use brk_types::*; -use serde::de::DeserializeOwned; -use std::ops::{Bound, RangeBounds}; -use std::sync::Arc; + /// Error type for BRK client operations. #[derive(Debug)] @@ -76,9 +77,7 @@ impl BrkClientBase { let response = minreq::get(&url) .with_timeout(self.timeout_secs) .send() - .map_err(|e| BrkError { - message: e.to_string(), - })?; + .map_err(|e| BrkError { message: e.to_string() })?; if response.status_code >= 400 { return Err(BrkError { @@ -91,9 +90,9 @@ impl BrkClientBase { /// Make a GET request and deserialize JSON response. pub fn get_json(&self, path: &str) -> Result { - self.get(path)?.json().map_err(|e| BrkError { - message: e.to_string(), - }) + self.get(path)? + .json() + .map_err(|e| BrkError { message: e.to_string() }) } /// Make a GET request and return raw text response. @@ -101,34 +100,25 @@ impl BrkClientBase { self.get(path)? .as_str() .map(|s| s.to_string()) - .map_err(|e| BrkError { - message: e.to_string(), - }) + .map_err(|e| BrkError { message: e.to_string() }) } } /// Build metric name with suffix. #[inline] fn _m(acc: &str, s: &str) -> String { - if s.is_empty() { - acc.to_string() - } else if acc.is_empty() { - s.to_string() - } else { - format!("{acc}_{s}") - } + if s.is_empty() { acc.to_string() } + else if acc.is_empty() { s.to_string() } + else { format!("{acc}_{s}") } } /// Build metric name with prefix. #[inline] fn _p(prefix: &str, acc: &str) -> String { - if acc.is_empty() { - prefix.to_string() - } else { - format!("{prefix}_{acc}") - } + if acc.is_empty() { prefix.to_string() } else { format!("{prefix}_{acc}") } } + /// Non-generic trait for metric patterns (usable in collections). pub trait AnyMetricPattern { /// Get the metric name. @@ -144,6 +134,7 @@ pub trait MetricPattern: AnyMetricPattern { fn get(&self, index: Index) -> Option>; } + /// Shared endpoint configuration. #[derive(Clone)] struct EndpointConfig { @@ -156,13 +147,7 @@ struct EndpointConfig { impl EndpointConfig { fn new(client: Arc, name: Arc, index: Index) -> Self { - Self { - client, - name, - index, - start: None, - end: None, - } + Self { client, name, index, start: None, end: None } } fn path(&self) -> String { @@ -171,21 +156,11 @@ impl EndpointConfig { fn build_path(&self, format: Option<&str>) -> String { let mut params = Vec::new(); - if let Some(s) = self.start { - params.push(format!("start={}", s)); - } - if let Some(e) = self.end { - params.push(format!("end={}", e)); - } - if let Some(fmt) = format { - params.push(format!("format={}", fmt)); - } + if let Some(s) = self.start { params.push(format!("start={}", s)); } + if let Some(e) = self.end { params.push(format!("end={}", e)); } + if let Some(fmt) = format { params.push(format!("format={}", fmt)); } let p = self.path(); - if params.is_empty() { - p - } else { - format!("{}?{}", p, params.join("&")) - } + if params.is_empty() { p } else { format!("{}?{}", p, params.join("&")) } } fn get_json(&self, format: Option<&str>) -> Result { @@ -231,20 +206,14 @@ pub struct MetricEndpointBuilder { impl MetricEndpointBuilder { pub fn new(client: Arc, name: Arc, index: Index) -> Self { - Self { - config: EndpointConfig::new(client, name, index), - _marker: std::marker::PhantomData, - } + Self { config: EndpointConfig::new(client, name, index), _marker: std::marker::PhantomData } } /// Select a specific index position. pub fn get(mut self, index: usize) -> SingleItemBuilder { self.config.start = Some(index as i64); self.config.end = Some(index as i64 + 1); - SingleItemBuilder { - config: self.config, - _marker: std::marker::PhantomData, - } + SingleItemBuilder { config: self.config, _marker: std::marker::PhantomData } } /// Select a range using Rust range syntax. @@ -266,10 +235,7 @@ impl MetricEndpointBuilder { Bound::Excluded(&n) => Some(n as i64), Bound::Unbounded => None, }; - RangeBuilder { - config: self.config, - _marker: std::marker::PhantomData, - } + RangeBuilder { config: self.config, _marker: std::marker::PhantomData } } /// Take the first n items. @@ -284,19 +250,13 @@ impl MetricEndpointBuilder { } else { self.config.start = Some(-(n as i64)); } - RangeBuilder { - config: self.config, - _marker: std::marker::PhantomData, - } + RangeBuilder { config: self.config, _marker: std::marker::PhantomData } } /// Skip the first n items. Chain with `take(n)` to get a range. pub fn skip(mut self, n: usize) -> SkippedBuilder { self.config.start = Some(n as i64); - SkippedBuilder { - config: self.config, - _marker: std::marker::PhantomData, - } + SkippedBuilder { config: self.config, _marker: std::marker::PhantomData } } /// Fetch all data as parsed JSON. @@ -344,10 +304,7 @@ impl SkippedBuilder { pub fn take(mut self, n: usize) -> RangeBuilder { let start = self.config.start.unwrap_or(0); self.config.end = Some(start + n as i64); - RangeBuilder { - config: self.config, - _marker: std::marker::PhantomData, - } + RangeBuilder { config: self.config, _marker: std::marker::PhantomData } } /// Fetch from the skipped position to the end. @@ -379,47 +336,12 @@ impl RangeBuilder { } } + // Static index arrays -const _I1: &[Index] = &[ - Index::DateIndex, - Index::DecadeIndex, - Index::DifficultyEpoch, - Index::Height, - Index::MonthIndex, - Index::QuarterIndex, - Index::SemesterIndex, - Index::WeekIndex, - Index::YearIndex, -]; -const _I2: &[Index] = &[ - Index::DateIndex, - Index::DecadeIndex, - Index::DifficultyEpoch, - Index::MonthIndex, - Index::QuarterIndex, - Index::SemesterIndex, - Index::WeekIndex, - Index::YearIndex, -]; -const _I3: &[Index] = &[ - Index::DateIndex, - Index::DecadeIndex, - Index::Height, - Index::MonthIndex, - Index::QuarterIndex, - Index::SemesterIndex, - Index::WeekIndex, - Index::YearIndex, -]; -const _I4: &[Index] = &[ - Index::DateIndex, - Index::DecadeIndex, - Index::MonthIndex, - Index::QuarterIndex, - Index::SemesterIndex, - Index::WeekIndex, - Index::YearIndex, -]; +const _I1: &[Index] = &[Index::DateIndex, Index::DecadeIndex, Index::DifficultyEpoch, Index::Height, Index::MonthIndex, Index::QuarterIndex, Index::SemesterIndex, Index::WeekIndex, Index::YearIndex]; +const _I2: &[Index] = &[Index::DateIndex, Index::DecadeIndex, Index::DifficultyEpoch, Index::MonthIndex, Index::QuarterIndex, Index::SemesterIndex, Index::WeekIndex, Index::YearIndex]; +const _I3: &[Index] = &[Index::DateIndex, Index::DecadeIndex, Index::Height, Index::MonthIndex, Index::QuarterIndex, Index::SemesterIndex, Index::WeekIndex, Index::YearIndex]; +const _I4: &[Index] = &[Index::DateIndex, Index::DecadeIndex, Index::MonthIndex, Index::QuarterIndex, Index::SemesterIndex, Index::WeekIndex, Index::YearIndex]; const _I5: &[Index] = &[Index::DateIndex, Index::Height]; const _I6: &[Index] = &[Index::DateIndex]; const _I7: &[Index] = &[Index::DecadeIndex]; @@ -451,1653 +373,502 @@ const _I32: &[Index] = &[Index::EmptyAddressIndex]; const _I33: &[Index] = &[Index::PairOutputIndex]; #[inline] -fn _ep( - c: &Arc, - n: &Arc, - i: Index, -) -> MetricEndpointBuilder { +fn _ep(c: &Arc, n: &Arc, i: Index) -> MetricEndpointBuilder { MetricEndpointBuilder::new(c.clone(), n.clone(), i) } // Index accessor structs -pub struct MetricPattern1By { - client: Arc, - name: Arc, - _marker: std::marker::PhantomData, -} +pub struct MetricPattern1By { client: Arc, name: Arc, _marker: std::marker::PhantomData } impl MetricPattern1By { - pub fn dateindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::DateIndex) - } - pub fn decadeindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::DecadeIndex) - } - pub fn difficultyepoch(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::DifficultyEpoch) - } - pub fn height(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::Height) - } - pub fn monthindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::MonthIndex) - } - pub fn quarterindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::QuarterIndex) - } - pub fn semesterindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::SemesterIndex) - } - pub fn weekindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::WeekIndex) - } - pub fn yearindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::YearIndex) - } + pub fn dateindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::DateIndex) } + pub fn decadeindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::DecadeIndex) } + pub fn difficultyepoch(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::DifficultyEpoch) } + pub fn height(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::Height) } + pub fn monthindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::MonthIndex) } + pub fn quarterindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::QuarterIndex) } + pub fn semesterindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::SemesterIndex) } + pub fn weekindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::WeekIndex) } + pub fn yearindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::YearIndex) } } -pub struct MetricPattern1 { - name: Arc, - pub by: MetricPattern1By, -} +pub struct MetricPattern1 { name: Arc, pub by: MetricPattern1By } impl MetricPattern1 { - pub fn new(client: Arc, name: String) -> Self { - let name: Arc = name.into(); - Self { - name: name.clone(), - by: MetricPattern1By { - client, - name, - _marker: std::marker::PhantomData, - }, - } - } - pub fn name(&self) -> &str { - &self.name - } + pub fn new(client: Arc, name: String) -> Self { let name: Arc = name.into(); Self { name: name.clone(), by: MetricPattern1By { client, name, _marker: std::marker::PhantomData } } } + pub fn name(&self) -> &str { &self.name } } -impl AnyMetricPattern for MetricPattern1 { - fn name(&self) -> &str { - &self.name - } - fn indexes(&self) -> &'static [Index] { - _I1 - } -} -impl MetricPattern for MetricPattern1 { - fn get(&self, index: Index) -> Option> { - _I1.contains(&index) - .then(|| _ep(&self.by.client, &self.by.name, index)) - } -} +impl AnyMetricPattern for MetricPattern1 { fn name(&self) -> &str { &self.name } fn indexes(&self) -> &'static [Index] { _I1 } } +impl MetricPattern for MetricPattern1 { fn get(&self, index: Index) -> Option> { _I1.contains(&index).then(|| _ep(&self.by.client, &self.by.name, index)) } } -pub struct MetricPattern2By { - client: Arc, - name: Arc, - _marker: std::marker::PhantomData, -} +pub struct MetricPattern2By { client: Arc, name: Arc, _marker: std::marker::PhantomData } impl MetricPattern2By { - pub fn dateindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::DateIndex) - } - pub fn decadeindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::DecadeIndex) - } - pub fn difficultyepoch(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::DifficultyEpoch) - } - pub fn monthindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::MonthIndex) - } - pub fn quarterindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::QuarterIndex) - } - pub fn semesterindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::SemesterIndex) - } - pub fn weekindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::WeekIndex) - } - pub fn yearindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::YearIndex) - } + pub fn dateindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::DateIndex) } + pub fn decadeindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::DecadeIndex) } + pub fn difficultyepoch(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::DifficultyEpoch) } + pub fn monthindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::MonthIndex) } + pub fn quarterindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::QuarterIndex) } + pub fn semesterindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::SemesterIndex) } + pub fn weekindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::WeekIndex) } + pub fn yearindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::YearIndex) } } -pub struct MetricPattern2 { - name: Arc, - pub by: MetricPattern2By, -} +pub struct MetricPattern2 { name: Arc, pub by: MetricPattern2By } impl MetricPattern2 { - pub fn new(client: Arc, name: String) -> Self { - let name: Arc = name.into(); - Self { - name: name.clone(), - by: MetricPattern2By { - client, - name, - _marker: std::marker::PhantomData, - }, - } - } - pub fn name(&self) -> &str { - &self.name - } + pub fn new(client: Arc, name: String) -> Self { let name: Arc = name.into(); Self { name: name.clone(), by: MetricPattern2By { client, name, _marker: std::marker::PhantomData } } } + pub fn name(&self) -> &str { &self.name } } -impl AnyMetricPattern for MetricPattern2 { - fn name(&self) -> &str { - &self.name - } - fn indexes(&self) -> &'static [Index] { - _I2 - } -} -impl MetricPattern for MetricPattern2 { - fn get(&self, index: Index) -> Option> { - _I2.contains(&index) - .then(|| _ep(&self.by.client, &self.by.name, index)) - } -} +impl AnyMetricPattern for MetricPattern2 { fn name(&self) -> &str { &self.name } fn indexes(&self) -> &'static [Index] { _I2 } } +impl MetricPattern for MetricPattern2 { fn get(&self, index: Index) -> Option> { _I2.contains(&index).then(|| _ep(&self.by.client, &self.by.name, index)) } } -pub struct MetricPattern3By { - client: Arc, - name: Arc, - _marker: std::marker::PhantomData, -} +pub struct MetricPattern3By { client: Arc, name: Arc, _marker: std::marker::PhantomData } impl MetricPattern3By { - pub fn dateindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::DateIndex) - } - pub fn decadeindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::DecadeIndex) - } - pub fn height(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::Height) - } - pub fn monthindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::MonthIndex) - } - pub fn quarterindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::QuarterIndex) - } - pub fn semesterindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::SemesterIndex) - } - pub fn weekindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::WeekIndex) - } - pub fn yearindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::YearIndex) - } + pub fn dateindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::DateIndex) } + pub fn decadeindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::DecadeIndex) } + pub fn height(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::Height) } + pub fn monthindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::MonthIndex) } + pub fn quarterindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::QuarterIndex) } + pub fn semesterindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::SemesterIndex) } + pub fn weekindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::WeekIndex) } + pub fn yearindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::YearIndex) } } -pub struct MetricPattern3 { - name: Arc, - pub by: MetricPattern3By, -} +pub struct MetricPattern3 { name: Arc, pub by: MetricPattern3By } impl MetricPattern3 { - pub fn new(client: Arc, name: String) -> Self { - let name: Arc = name.into(); - Self { - name: name.clone(), - by: MetricPattern3By { - client, - name, - _marker: std::marker::PhantomData, - }, - } - } - pub fn name(&self) -> &str { - &self.name - } + pub fn new(client: Arc, name: String) -> Self { let name: Arc = name.into(); Self { name: name.clone(), by: MetricPattern3By { client, name, _marker: std::marker::PhantomData } } } + pub fn name(&self) -> &str { &self.name } } -impl AnyMetricPattern for MetricPattern3 { - fn name(&self) -> &str { - &self.name - } - fn indexes(&self) -> &'static [Index] { - _I3 - } -} -impl MetricPattern for MetricPattern3 { - fn get(&self, index: Index) -> Option> { - _I3.contains(&index) - .then(|| _ep(&self.by.client, &self.by.name, index)) - } -} +impl AnyMetricPattern for MetricPattern3 { fn name(&self) -> &str { &self.name } fn indexes(&self) -> &'static [Index] { _I3 } } +impl MetricPattern for MetricPattern3 { fn get(&self, index: Index) -> Option> { _I3.contains(&index).then(|| _ep(&self.by.client, &self.by.name, index)) } } -pub struct MetricPattern4By { - client: Arc, - name: Arc, - _marker: std::marker::PhantomData, -} +pub struct MetricPattern4By { client: Arc, name: Arc, _marker: std::marker::PhantomData } impl MetricPattern4By { - pub fn dateindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::DateIndex) - } - pub fn decadeindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::DecadeIndex) - } - pub fn monthindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::MonthIndex) - } - pub fn quarterindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::QuarterIndex) - } - pub fn semesterindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::SemesterIndex) - } - pub fn weekindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::WeekIndex) - } - pub fn yearindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::YearIndex) - } + pub fn dateindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::DateIndex) } + pub fn decadeindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::DecadeIndex) } + pub fn monthindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::MonthIndex) } + pub fn quarterindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::QuarterIndex) } + pub fn semesterindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::SemesterIndex) } + pub fn weekindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::WeekIndex) } + pub fn yearindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::YearIndex) } } -pub struct MetricPattern4 { - name: Arc, - pub by: MetricPattern4By, -} +pub struct MetricPattern4 { name: Arc, pub by: MetricPattern4By } impl MetricPattern4 { - pub fn new(client: Arc, name: String) -> Self { - let name: Arc = name.into(); - Self { - name: name.clone(), - by: MetricPattern4By { - client, - name, - _marker: std::marker::PhantomData, - }, - } - } - pub fn name(&self) -> &str { - &self.name - } + pub fn new(client: Arc, name: String) -> Self { let name: Arc = name.into(); Self { name: name.clone(), by: MetricPattern4By { client, name, _marker: std::marker::PhantomData } } } + pub fn name(&self) -> &str { &self.name } } -impl AnyMetricPattern for MetricPattern4 { - fn name(&self) -> &str { - &self.name - } - fn indexes(&self) -> &'static [Index] { - _I4 - } -} -impl MetricPattern for MetricPattern4 { - fn get(&self, index: Index) -> Option> { - _I4.contains(&index) - .then(|| _ep(&self.by.client, &self.by.name, index)) - } -} +impl AnyMetricPattern for MetricPattern4 { fn name(&self) -> &str { &self.name } fn indexes(&self) -> &'static [Index] { _I4 } } +impl MetricPattern for MetricPattern4 { fn get(&self, index: Index) -> Option> { _I4.contains(&index).then(|| _ep(&self.by.client, &self.by.name, index)) } } -pub struct MetricPattern5By { - client: Arc, - name: Arc, - _marker: std::marker::PhantomData, -} +pub struct MetricPattern5By { client: Arc, name: Arc, _marker: std::marker::PhantomData } impl MetricPattern5By { - pub fn dateindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::DateIndex) - } - pub fn height(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::Height) - } + pub fn dateindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::DateIndex) } + pub fn height(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::Height) } } -pub struct MetricPattern5 { - name: Arc, - pub by: MetricPattern5By, -} +pub struct MetricPattern5 { name: Arc, pub by: MetricPattern5By } impl MetricPattern5 { - pub fn new(client: Arc, name: String) -> Self { - let name: Arc = name.into(); - Self { - name: name.clone(), - by: MetricPattern5By { - client, - name, - _marker: std::marker::PhantomData, - }, - } - } - pub fn name(&self) -> &str { - &self.name - } + pub fn new(client: Arc, name: String) -> Self { let name: Arc = name.into(); Self { name: name.clone(), by: MetricPattern5By { client, name, _marker: std::marker::PhantomData } } } + pub fn name(&self) -> &str { &self.name } } -impl AnyMetricPattern for MetricPattern5 { - fn name(&self) -> &str { - &self.name - } - fn indexes(&self) -> &'static [Index] { - _I5 - } -} -impl MetricPattern for MetricPattern5 { - fn get(&self, index: Index) -> Option> { - _I5.contains(&index) - .then(|| _ep(&self.by.client, &self.by.name, index)) - } -} +impl AnyMetricPattern for MetricPattern5 { fn name(&self) -> &str { &self.name } fn indexes(&self) -> &'static [Index] { _I5 } } +impl MetricPattern for MetricPattern5 { fn get(&self, index: Index) -> Option> { _I5.contains(&index).then(|| _ep(&self.by.client, &self.by.name, index)) } } -pub struct MetricPattern6By { - client: Arc, - name: Arc, - _marker: std::marker::PhantomData, -} +pub struct MetricPattern6By { client: Arc, name: Arc, _marker: std::marker::PhantomData } impl MetricPattern6By { - pub fn dateindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::DateIndex) - } + pub fn dateindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::DateIndex) } } -pub struct MetricPattern6 { - name: Arc, - pub by: MetricPattern6By, -} +pub struct MetricPattern6 { name: Arc, pub by: MetricPattern6By } impl MetricPattern6 { - pub fn new(client: Arc, name: String) -> Self { - let name: Arc = name.into(); - Self { - name: name.clone(), - by: MetricPattern6By { - client, - name, - _marker: std::marker::PhantomData, - }, - } - } - pub fn name(&self) -> &str { - &self.name - } + pub fn new(client: Arc, name: String) -> Self { let name: Arc = name.into(); Self { name: name.clone(), by: MetricPattern6By { client, name, _marker: std::marker::PhantomData } } } + pub fn name(&self) -> &str { &self.name } } -impl AnyMetricPattern for MetricPattern6 { - fn name(&self) -> &str { - &self.name - } - fn indexes(&self) -> &'static [Index] { - _I6 - } -} -impl MetricPattern for MetricPattern6 { - fn get(&self, index: Index) -> Option> { - _I6.contains(&index) - .then(|| _ep(&self.by.client, &self.by.name, index)) - } -} +impl AnyMetricPattern for MetricPattern6 { fn name(&self) -> &str { &self.name } fn indexes(&self) -> &'static [Index] { _I6 } } +impl MetricPattern for MetricPattern6 { fn get(&self, index: Index) -> Option> { _I6.contains(&index).then(|| _ep(&self.by.client, &self.by.name, index)) } } -pub struct MetricPattern7By { - client: Arc, - name: Arc, - _marker: std::marker::PhantomData, -} +pub struct MetricPattern7By { client: Arc, name: Arc, _marker: std::marker::PhantomData } impl MetricPattern7By { - pub fn decadeindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::DecadeIndex) - } + pub fn decadeindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::DecadeIndex) } } -pub struct MetricPattern7 { - name: Arc, - pub by: MetricPattern7By, -} +pub struct MetricPattern7 { name: Arc, pub by: MetricPattern7By } impl MetricPattern7 { - pub fn new(client: Arc, name: String) -> Self { - let name: Arc = name.into(); - Self { - name: name.clone(), - by: MetricPattern7By { - client, - name, - _marker: std::marker::PhantomData, - }, - } - } - pub fn name(&self) -> &str { - &self.name - } + pub fn new(client: Arc, name: String) -> Self { let name: Arc = name.into(); Self { name: name.clone(), by: MetricPattern7By { client, name, _marker: std::marker::PhantomData } } } + pub fn name(&self) -> &str { &self.name } } -impl AnyMetricPattern for MetricPattern7 { - fn name(&self) -> &str { - &self.name - } - fn indexes(&self) -> &'static [Index] { - _I7 - } -} -impl MetricPattern for MetricPattern7 { - fn get(&self, index: Index) -> Option> { - _I7.contains(&index) - .then(|| _ep(&self.by.client, &self.by.name, index)) - } -} +impl AnyMetricPattern for MetricPattern7 { fn name(&self) -> &str { &self.name } fn indexes(&self) -> &'static [Index] { _I7 } } +impl MetricPattern for MetricPattern7 { fn get(&self, index: Index) -> Option> { _I7.contains(&index).then(|| _ep(&self.by.client, &self.by.name, index)) } } -pub struct MetricPattern8By { - client: Arc, - name: Arc, - _marker: std::marker::PhantomData, -} +pub struct MetricPattern8By { client: Arc, name: Arc, _marker: std::marker::PhantomData } impl MetricPattern8By { - pub fn difficultyepoch(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::DifficultyEpoch) - } + pub fn difficultyepoch(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::DifficultyEpoch) } } -pub struct MetricPattern8 { - name: Arc, - pub by: MetricPattern8By, -} +pub struct MetricPattern8 { name: Arc, pub by: MetricPattern8By } impl MetricPattern8 { - pub fn new(client: Arc, name: String) -> Self { - let name: Arc = name.into(); - Self { - name: name.clone(), - by: MetricPattern8By { - client, - name, - _marker: std::marker::PhantomData, - }, - } - } - pub fn name(&self) -> &str { - &self.name - } + pub fn new(client: Arc, name: String) -> Self { let name: Arc = name.into(); Self { name: name.clone(), by: MetricPattern8By { client, name, _marker: std::marker::PhantomData } } } + pub fn name(&self) -> &str { &self.name } } -impl AnyMetricPattern for MetricPattern8 { - fn name(&self) -> &str { - &self.name - } - fn indexes(&self) -> &'static [Index] { - _I8 - } -} -impl MetricPattern for MetricPattern8 { - fn get(&self, index: Index) -> Option> { - _I8.contains(&index) - .then(|| _ep(&self.by.client, &self.by.name, index)) - } -} +impl AnyMetricPattern for MetricPattern8 { fn name(&self) -> &str { &self.name } fn indexes(&self) -> &'static [Index] { _I8 } } +impl MetricPattern for MetricPattern8 { fn get(&self, index: Index) -> Option> { _I8.contains(&index).then(|| _ep(&self.by.client, &self.by.name, index)) } } -pub struct MetricPattern9By { - client: Arc, - name: Arc, - _marker: std::marker::PhantomData, -} +pub struct MetricPattern9By { client: Arc, name: Arc, _marker: std::marker::PhantomData } impl MetricPattern9By { - pub fn emptyoutputindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::EmptyOutputIndex) - } + pub fn emptyoutputindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::EmptyOutputIndex) } } -pub struct MetricPattern9 { - name: Arc, - pub by: MetricPattern9By, -} +pub struct MetricPattern9 { name: Arc, pub by: MetricPattern9By } impl MetricPattern9 { - pub fn new(client: Arc, name: String) -> Self { - let name: Arc = name.into(); - Self { - name: name.clone(), - by: MetricPattern9By { - client, - name, - _marker: std::marker::PhantomData, - }, - } - } - pub fn name(&self) -> &str { - &self.name - } + pub fn new(client: Arc, name: String) -> Self { let name: Arc = name.into(); Self { name: name.clone(), by: MetricPattern9By { client, name, _marker: std::marker::PhantomData } } } + pub fn name(&self) -> &str { &self.name } } -impl AnyMetricPattern for MetricPattern9 { - fn name(&self) -> &str { - &self.name - } - fn indexes(&self) -> &'static [Index] { - _I9 - } -} -impl MetricPattern for MetricPattern9 { - fn get(&self, index: Index) -> Option> { - _I9.contains(&index) - .then(|| _ep(&self.by.client, &self.by.name, index)) - } -} +impl AnyMetricPattern for MetricPattern9 { fn name(&self) -> &str { &self.name } fn indexes(&self) -> &'static [Index] { _I9 } } +impl MetricPattern for MetricPattern9 { fn get(&self, index: Index) -> Option> { _I9.contains(&index).then(|| _ep(&self.by.client, &self.by.name, index)) } } -pub struct MetricPattern10By { - client: Arc, - name: Arc, - _marker: std::marker::PhantomData, -} +pub struct MetricPattern10By { client: Arc, name: Arc, _marker: std::marker::PhantomData } impl MetricPattern10By { - pub fn halvingepoch(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::HalvingEpoch) - } + pub fn halvingepoch(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::HalvingEpoch) } } -pub struct MetricPattern10 { - name: Arc, - pub by: MetricPattern10By, -} +pub struct MetricPattern10 { name: Arc, pub by: MetricPattern10By } impl MetricPattern10 { - pub fn new(client: Arc, name: String) -> Self { - let name: Arc = name.into(); - Self { - name: name.clone(), - by: MetricPattern10By { - client, - name, - _marker: std::marker::PhantomData, - }, - } - } - pub fn name(&self) -> &str { - &self.name - } + pub fn new(client: Arc, name: String) -> Self { let name: Arc = name.into(); Self { name: name.clone(), by: MetricPattern10By { client, name, _marker: std::marker::PhantomData } } } + pub fn name(&self) -> &str { &self.name } } -impl AnyMetricPattern for MetricPattern10 { - fn name(&self) -> &str { - &self.name - } - fn indexes(&self) -> &'static [Index] { - _I10 - } -} -impl MetricPattern for MetricPattern10 { - fn get(&self, index: Index) -> Option> { - _I10.contains(&index) - .then(|| _ep(&self.by.client, &self.by.name, index)) - } -} +impl AnyMetricPattern for MetricPattern10 { fn name(&self) -> &str { &self.name } fn indexes(&self) -> &'static [Index] { _I10 } } +impl MetricPattern for MetricPattern10 { fn get(&self, index: Index) -> Option> { _I10.contains(&index).then(|| _ep(&self.by.client, &self.by.name, index)) } } -pub struct MetricPattern11By { - client: Arc, - name: Arc, - _marker: std::marker::PhantomData, -} +pub struct MetricPattern11By { client: Arc, name: Arc, _marker: std::marker::PhantomData } impl MetricPattern11By { - pub fn height(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::Height) - } + pub fn height(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::Height) } } -pub struct MetricPattern11 { - name: Arc, - pub by: MetricPattern11By, -} +pub struct MetricPattern11 { name: Arc, pub by: MetricPattern11By } impl MetricPattern11 { - pub fn new(client: Arc, name: String) -> Self { - let name: Arc = name.into(); - Self { - name: name.clone(), - by: MetricPattern11By { - client, - name, - _marker: std::marker::PhantomData, - }, - } - } - pub fn name(&self) -> &str { - &self.name - } + pub fn new(client: Arc, name: String) -> Self { let name: Arc = name.into(); Self { name: name.clone(), by: MetricPattern11By { client, name, _marker: std::marker::PhantomData } } } + pub fn name(&self) -> &str { &self.name } } -impl AnyMetricPattern for MetricPattern11 { - fn name(&self) -> &str { - &self.name - } - fn indexes(&self) -> &'static [Index] { - _I11 - } -} -impl MetricPattern for MetricPattern11 { - fn get(&self, index: Index) -> Option> { - _I11.contains(&index) - .then(|| _ep(&self.by.client, &self.by.name, index)) - } -} +impl AnyMetricPattern for MetricPattern11 { fn name(&self) -> &str { &self.name } fn indexes(&self) -> &'static [Index] { _I11 } } +impl MetricPattern for MetricPattern11 { fn get(&self, index: Index) -> Option> { _I11.contains(&index).then(|| _ep(&self.by.client, &self.by.name, index)) } } -pub struct MetricPattern12By { - client: Arc, - name: Arc, - _marker: std::marker::PhantomData, -} +pub struct MetricPattern12By { client: Arc, name: Arc, _marker: std::marker::PhantomData } impl MetricPattern12By { - pub fn txinindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::TxInIndex) - } + pub fn txinindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::TxInIndex) } } -pub struct MetricPattern12 { - name: Arc, - pub by: MetricPattern12By, -} +pub struct MetricPattern12 { name: Arc, pub by: MetricPattern12By } impl MetricPattern12 { - pub fn new(client: Arc, name: String) -> Self { - let name: Arc = name.into(); - Self { - name: name.clone(), - by: MetricPattern12By { - client, - name, - _marker: std::marker::PhantomData, - }, - } - } - pub fn name(&self) -> &str { - &self.name - } + pub fn new(client: Arc, name: String) -> Self { let name: Arc = name.into(); Self { name: name.clone(), by: MetricPattern12By { client, name, _marker: std::marker::PhantomData } } } + pub fn name(&self) -> &str { &self.name } } -impl AnyMetricPattern for MetricPattern12 { - fn name(&self) -> &str { - &self.name - } - fn indexes(&self) -> &'static [Index] { - _I12 - } -} -impl MetricPattern for MetricPattern12 { - fn get(&self, index: Index) -> Option> { - _I12.contains(&index) - .then(|| _ep(&self.by.client, &self.by.name, index)) - } -} +impl AnyMetricPattern for MetricPattern12 { fn name(&self) -> &str { &self.name } fn indexes(&self) -> &'static [Index] { _I12 } } +impl MetricPattern for MetricPattern12 { fn get(&self, index: Index) -> Option> { _I12.contains(&index).then(|| _ep(&self.by.client, &self.by.name, index)) } } -pub struct MetricPattern13By { - client: Arc, - name: Arc, - _marker: std::marker::PhantomData, -} +pub struct MetricPattern13By { client: Arc, name: Arc, _marker: std::marker::PhantomData } impl MetricPattern13By { - pub fn monthindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::MonthIndex) - } + pub fn monthindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::MonthIndex) } } -pub struct MetricPattern13 { - name: Arc, - pub by: MetricPattern13By, -} +pub struct MetricPattern13 { name: Arc, pub by: MetricPattern13By } impl MetricPattern13 { - pub fn new(client: Arc, name: String) -> Self { - let name: Arc = name.into(); - Self { - name: name.clone(), - by: MetricPattern13By { - client, - name, - _marker: std::marker::PhantomData, - }, - } - } - pub fn name(&self) -> &str { - &self.name - } + pub fn new(client: Arc, name: String) -> Self { let name: Arc = name.into(); Self { name: name.clone(), by: MetricPattern13By { client, name, _marker: std::marker::PhantomData } } } + pub fn name(&self) -> &str { &self.name } } -impl AnyMetricPattern for MetricPattern13 { - fn name(&self) -> &str { - &self.name - } - fn indexes(&self) -> &'static [Index] { - _I13 - } -} -impl MetricPattern for MetricPattern13 { - fn get(&self, index: Index) -> Option> { - _I13.contains(&index) - .then(|| _ep(&self.by.client, &self.by.name, index)) - } -} +impl AnyMetricPattern for MetricPattern13 { fn name(&self) -> &str { &self.name } fn indexes(&self) -> &'static [Index] { _I13 } } +impl MetricPattern for MetricPattern13 { fn get(&self, index: Index) -> Option> { _I13.contains(&index).then(|| _ep(&self.by.client, &self.by.name, index)) } } -pub struct MetricPattern14By { - client: Arc, - name: Arc, - _marker: std::marker::PhantomData, -} +pub struct MetricPattern14By { client: Arc, name: Arc, _marker: std::marker::PhantomData } impl MetricPattern14By { - pub fn opreturnindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::OpReturnIndex) - } + pub fn opreturnindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::OpReturnIndex) } } -pub struct MetricPattern14 { - name: Arc, - pub by: MetricPattern14By, -} +pub struct MetricPattern14 { name: Arc, pub by: MetricPattern14By } impl MetricPattern14 { - pub fn new(client: Arc, name: String) -> Self { - let name: Arc = name.into(); - Self { - name: name.clone(), - by: MetricPattern14By { - client, - name, - _marker: std::marker::PhantomData, - }, - } - } - pub fn name(&self) -> &str { - &self.name - } + pub fn new(client: Arc, name: String) -> Self { let name: Arc = name.into(); Self { name: name.clone(), by: MetricPattern14By { client, name, _marker: std::marker::PhantomData } } } + pub fn name(&self) -> &str { &self.name } } -impl AnyMetricPattern for MetricPattern14 { - fn name(&self) -> &str { - &self.name - } - fn indexes(&self) -> &'static [Index] { - _I14 - } -} -impl MetricPattern for MetricPattern14 { - fn get(&self, index: Index) -> Option> { - _I14.contains(&index) - .then(|| _ep(&self.by.client, &self.by.name, index)) - } -} +impl AnyMetricPattern for MetricPattern14 { fn name(&self) -> &str { &self.name } fn indexes(&self) -> &'static [Index] { _I14 } } +impl MetricPattern for MetricPattern14 { fn get(&self, index: Index) -> Option> { _I14.contains(&index).then(|| _ep(&self.by.client, &self.by.name, index)) } } -pub struct MetricPattern15By { - client: Arc, - name: Arc, - _marker: std::marker::PhantomData, -} +pub struct MetricPattern15By { client: Arc, name: Arc, _marker: std::marker::PhantomData } impl MetricPattern15By { - pub fn txoutindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::TxOutIndex) - } + pub fn txoutindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::TxOutIndex) } } -pub struct MetricPattern15 { - name: Arc, - pub by: MetricPattern15By, -} +pub struct MetricPattern15 { name: Arc, pub by: MetricPattern15By } impl MetricPattern15 { - pub fn new(client: Arc, name: String) -> Self { - let name: Arc = name.into(); - Self { - name: name.clone(), - by: MetricPattern15By { - client, - name, - _marker: std::marker::PhantomData, - }, - } - } - pub fn name(&self) -> &str { - &self.name - } + pub fn new(client: Arc, name: String) -> Self { let name: Arc = name.into(); Self { name: name.clone(), by: MetricPattern15By { client, name, _marker: std::marker::PhantomData } } } + pub fn name(&self) -> &str { &self.name } } -impl AnyMetricPattern for MetricPattern15 { - fn name(&self) -> &str { - &self.name - } - fn indexes(&self) -> &'static [Index] { - _I15 - } -} -impl MetricPattern for MetricPattern15 { - fn get(&self, index: Index) -> Option> { - _I15.contains(&index) - .then(|| _ep(&self.by.client, &self.by.name, index)) - } -} +impl AnyMetricPattern for MetricPattern15 { fn name(&self) -> &str { &self.name } fn indexes(&self) -> &'static [Index] { _I15 } } +impl MetricPattern for MetricPattern15 { fn get(&self, index: Index) -> Option> { _I15.contains(&index).then(|| _ep(&self.by.client, &self.by.name, index)) } } -pub struct MetricPattern16By { - client: Arc, - name: Arc, - _marker: std::marker::PhantomData, -} +pub struct MetricPattern16By { client: Arc, name: Arc, _marker: std::marker::PhantomData } impl MetricPattern16By { - pub fn p2aaddressindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::P2AAddressIndex) - } + pub fn p2aaddressindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::P2AAddressIndex) } } -pub struct MetricPattern16 { - name: Arc, - pub by: MetricPattern16By, -} +pub struct MetricPattern16 { name: Arc, pub by: MetricPattern16By } impl MetricPattern16 { - pub fn new(client: Arc, name: String) -> Self { - let name: Arc = name.into(); - Self { - name: name.clone(), - by: MetricPattern16By { - client, - name, - _marker: std::marker::PhantomData, - }, - } - } - pub fn name(&self) -> &str { - &self.name - } + pub fn new(client: Arc, name: String) -> Self { let name: Arc = name.into(); Self { name: name.clone(), by: MetricPattern16By { client, name, _marker: std::marker::PhantomData } } } + pub fn name(&self) -> &str { &self.name } } -impl AnyMetricPattern for MetricPattern16 { - fn name(&self) -> &str { - &self.name - } - fn indexes(&self) -> &'static [Index] { - _I16 - } -} -impl MetricPattern for MetricPattern16 { - fn get(&self, index: Index) -> Option> { - _I16.contains(&index) - .then(|| _ep(&self.by.client, &self.by.name, index)) - } -} +impl AnyMetricPattern for MetricPattern16 { fn name(&self) -> &str { &self.name } fn indexes(&self) -> &'static [Index] { _I16 } } +impl MetricPattern for MetricPattern16 { fn get(&self, index: Index) -> Option> { _I16.contains(&index).then(|| _ep(&self.by.client, &self.by.name, index)) } } -pub struct MetricPattern17By { - client: Arc, - name: Arc, - _marker: std::marker::PhantomData, -} +pub struct MetricPattern17By { client: Arc, name: Arc, _marker: std::marker::PhantomData } impl MetricPattern17By { - pub fn p2msoutputindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::P2MSOutputIndex) - } + pub fn p2msoutputindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::P2MSOutputIndex) } } -pub struct MetricPattern17 { - name: Arc, - pub by: MetricPattern17By, -} +pub struct MetricPattern17 { name: Arc, pub by: MetricPattern17By } impl MetricPattern17 { - pub fn new(client: Arc, name: String) -> Self { - let name: Arc = name.into(); - Self { - name: name.clone(), - by: MetricPattern17By { - client, - name, - _marker: std::marker::PhantomData, - }, - } - } - pub fn name(&self) -> &str { - &self.name - } + pub fn new(client: Arc, name: String) -> Self { let name: Arc = name.into(); Self { name: name.clone(), by: MetricPattern17By { client, name, _marker: std::marker::PhantomData } } } + pub fn name(&self) -> &str { &self.name } } -impl AnyMetricPattern for MetricPattern17 { - fn name(&self) -> &str { - &self.name - } - fn indexes(&self) -> &'static [Index] { - _I17 - } -} -impl MetricPattern for MetricPattern17 { - fn get(&self, index: Index) -> Option> { - _I17.contains(&index) - .then(|| _ep(&self.by.client, &self.by.name, index)) - } -} +impl AnyMetricPattern for MetricPattern17 { fn name(&self) -> &str { &self.name } fn indexes(&self) -> &'static [Index] { _I17 } } +impl MetricPattern for MetricPattern17 { fn get(&self, index: Index) -> Option> { _I17.contains(&index).then(|| _ep(&self.by.client, &self.by.name, index)) } } -pub struct MetricPattern18By { - client: Arc, - name: Arc, - _marker: std::marker::PhantomData, -} +pub struct MetricPattern18By { client: Arc, name: Arc, _marker: std::marker::PhantomData } impl MetricPattern18By { - pub fn p2pk33addressindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::P2PK33AddressIndex) - } + pub fn p2pk33addressindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::P2PK33AddressIndex) } } -pub struct MetricPattern18 { - name: Arc, - pub by: MetricPattern18By, -} +pub struct MetricPattern18 { name: Arc, pub by: MetricPattern18By } impl MetricPattern18 { - pub fn new(client: Arc, name: String) -> Self { - let name: Arc = name.into(); - Self { - name: name.clone(), - by: MetricPattern18By { - client, - name, - _marker: std::marker::PhantomData, - }, - } - } - pub fn name(&self) -> &str { - &self.name - } + pub fn new(client: Arc, name: String) -> Self { let name: Arc = name.into(); Self { name: name.clone(), by: MetricPattern18By { client, name, _marker: std::marker::PhantomData } } } + pub fn name(&self) -> &str { &self.name } } -impl AnyMetricPattern for MetricPattern18 { - fn name(&self) -> &str { - &self.name - } - fn indexes(&self) -> &'static [Index] { - _I18 - } -} -impl MetricPattern for MetricPattern18 { - fn get(&self, index: Index) -> Option> { - _I18.contains(&index) - .then(|| _ep(&self.by.client, &self.by.name, index)) - } -} +impl AnyMetricPattern for MetricPattern18 { fn name(&self) -> &str { &self.name } fn indexes(&self) -> &'static [Index] { _I18 } } +impl MetricPattern for MetricPattern18 { fn get(&self, index: Index) -> Option> { _I18.contains(&index).then(|| _ep(&self.by.client, &self.by.name, index)) } } -pub struct MetricPattern19By { - client: Arc, - name: Arc, - _marker: std::marker::PhantomData, -} +pub struct MetricPattern19By { client: Arc, name: Arc, _marker: std::marker::PhantomData } impl MetricPattern19By { - pub fn p2pk65addressindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::P2PK65AddressIndex) - } + pub fn p2pk65addressindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::P2PK65AddressIndex) } } -pub struct MetricPattern19 { - name: Arc, - pub by: MetricPattern19By, -} +pub struct MetricPattern19 { name: Arc, pub by: MetricPattern19By } impl MetricPattern19 { - pub fn new(client: Arc, name: String) -> Self { - let name: Arc = name.into(); - Self { - name: name.clone(), - by: MetricPattern19By { - client, - name, - _marker: std::marker::PhantomData, - }, - } - } - pub fn name(&self) -> &str { - &self.name - } + pub fn new(client: Arc, name: String) -> Self { let name: Arc = name.into(); Self { name: name.clone(), by: MetricPattern19By { client, name, _marker: std::marker::PhantomData } } } + pub fn name(&self) -> &str { &self.name } } -impl AnyMetricPattern for MetricPattern19 { - fn name(&self) -> &str { - &self.name - } - fn indexes(&self) -> &'static [Index] { - _I19 - } -} -impl MetricPattern for MetricPattern19 { - fn get(&self, index: Index) -> Option> { - _I19.contains(&index) - .then(|| _ep(&self.by.client, &self.by.name, index)) - } -} +impl AnyMetricPattern for MetricPattern19 { fn name(&self) -> &str { &self.name } fn indexes(&self) -> &'static [Index] { _I19 } } +impl MetricPattern for MetricPattern19 { fn get(&self, index: Index) -> Option> { _I19.contains(&index).then(|| _ep(&self.by.client, &self.by.name, index)) } } -pub struct MetricPattern20By { - client: Arc, - name: Arc, - _marker: std::marker::PhantomData, -} +pub struct MetricPattern20By { client: Arc, name: Arc, _marker: std::marker::PhantomData } impl MetricPattern20By { - pub fn p2pkhaddressindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::P2PKHAddressIndex) - } + pub fn p2pkhaddressindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::P2PKHAddressIndex) } } -pub struct MetricPattern20 { - name: Arc, - pub by: MetricPattern20By, -} +pub struct MetricPattern20 { name: Arc, pub by: MetricPattern20By } impl MetricPattern20 { - pub fn new(client: Arc, name: String) -> Self { - let name: Arc = name.into(); - Self { - name: name.clone(), - by: MetricPattern20By { - client, - name, - _marker: std::marker::PhantomData, - }, - } - } - pub fn name(&self) -> &str { - &self.name - } + pub fn new(client: Arc, name: String) -> Self { let name: Arc = name.into(); Self { name: name.clone(), by: MetricPattern20By { client, name, _marker: std::marker::PhantomData } } } + pub fn name(&self) -> &str { &self.name } } -impl AnyMetricPattern for MetricPattern20 { - fn name(&self) -> &str { - &self.name - } - fn indexes(&self) -> &'static [Index] { - _I20 - } -} -impl MetricPattern for MetricPattern20 { - fn get(&self, index: Index) -> Option> { - _I20.contains(&index) - .then(|| _ep(&self.by.client, &self.by.name, index)) - } -} +impl AnyMetricPattern for MetricPattern20 { fn name(&self) -> &str { &self.name } fn indexes(&self) -> &'static [Index] { _I20 } } +impl MetricPattern for MetricPattern20 { fn get(&self, index: Index) -> Option> { _I20.contains(&index).then(|| _ep(&self.by.client, &self.by.name, index)) } } -pub struct MetricPattern21By { - client: Arc, - name: Arc, - _marker: std::marker::PhantomData, -} +pub struct MetricPattern21By { client: Arc, name: Arc, _marker: std::marker::PhantomData } impl MetricPattern21By { - pub fn p2shaddressindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::P2SHAddressIndex) - } + pub fn p2shaddressindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::P2SHAddressIndex) } } -pub struct MetricPattern21 { - name: Arc, - pub by: MetricPattern21By, -} +pub struct MetricPattern21 { name: Arc, pub by: MetricPattern21By } impl MetricPattern21 { - pub fn new(client: Arc, name: String) -> Self { - let name: Arc = name.into(); - Self { - name: name.clone(), - by: MetricPattern21By { - client, - name, - _marker: std::marker::PhantomData, - }, - } - } - pub fn name(&self) -> &str { - &self.name - } + pub fn new(client: Arc, name: String) -> Self { let name: Arc = name.into(); Self { name: name.clone(), by: MetricPattern21By { client, name, _marker: std::marker::PhantomData } } } + pub fn name(&self) -> &str { &self.name } } -impl AnyMetricPattern for MetricPattern21 { - fn name(&self) -> &str { - &self.name - } - fn indexes(&self) -> &'static [Index] { - _I21 - } -} -impl MetricPattern for MetricPattern21 { - fn get(&self, index: Index) -> Option> { - _I21.contains(&index) - .then(|| _ep(&self.by.client, &self.by.name, index)) - } -} +impl AnyMetricPattern for MetricPattern21 { fn name(&self) -> &str { &self.name } fn indexes(&self) -> &'static [Index] { _I21 } } +impl MetricPattern for MetricPattern21 { fn get(&self, index: Index) -> Option> { _I21.contains(&index).then(|| _ep(&self.by.client, &self.by.name, index)) } } -pub struct MetricPattern22By { - client: Arc, - name: Arc, - _marker: std::marker::PhantomData, -} +pub struct MetricPattern22By { client: Arc, name: Arc, _marker: std::marker::PhantomData } impl MetricPattern22By { - pub fn p2traddressindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::P2TRAddressIndex) - } + pub fn p2traddressindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::P2TRAddressIndex) } } -pub struct MetricPattern22 { - name: Arc, - pub by: MetricPattern22By, -} +pub struct MetricPattern22 { name: Arc, pub by: MetricPattern22By } impl MetricPattern22 { - pub fn new(client: Arc, name: String) -> Self { - let name: Arc = name.into(); - Self { - name: name.clone(), - by: MetricPattern22By { - client, - name, - _marker: std::marker::PhantomData, - }, - } - } - pub fn name(&self) -> &str { - &self.name - } + pub fn new(client: Arc, name: String) -> Self { let name: Arc = name.into(); Self { name: name.clone(), by: MetricPattern22By { client, name, _marker: std::marker::PhantomData } } } + pub fn name(&self) -> &str { &self.name } } -impl AnyMetricPattern for MetricPattern22 { - fn name(&self) -> &str { - &self.name - } - fn indexes(&self) -> &'static [Index] { - _I22 - } -} -impl MetricPattern for MetricPattern22 { - fn get(&self, index: Index) -> Option> { - _I22.contains(&index) - .then(|| _ep(&self.by.client, &self.by.name, index)) - } -} +impl AnyMetricPattern for MetricPattern22 { fn name(&self) -> &str { &self.name } fn indexes(&self) -> &'static [Index] { _I22 } } +impl MetricPattern for MetricPattern22 { fn get(&self, index: Index) -> Option> { _I22.contains(&index).then(|| _ep(&self.by.client, &self.by.name, index)) } } -pub struct MetricPattern23By { - client: Arc, - name: Arc, - _marker: std::marker::PhantomData, -} +pub struct MetricPattern23By { client: Arc, name: Arc, _marker: std::marker::PhantomData } impl MetricPattern23By { - pub fn p2wpkhaddressindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::P2WPKHAddressIndex) - } + pub fn p2wpkhaddressindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::P2WPKHAddressIndex) } } -pub struct MetricPattern23 { - name: Arc, - pub by: MetricPattern23By, -} +pub struct MetricPattern23 { name: Arc, pub by: MetricPattern23By } impl MetricPattern23 { - pub fn new(client: Arc, name: String) -> Self { - let name: Arc = name.into(); - Self { - name: name.clone(), - by: MetricPattern23By { - client, - name, - _marker: std::marker::PhantomData, - }, - } - } - pub fn name(&self) -> &str { - &self.name - } + pub fn new(client: Arc, name: String) -> Self { let name: Arc = name.into(); Self { name: name.clone(), by: MetricPattern23By { client, name, _marker: std::marker::PhantomData } } } + pub fn name(&self) -> &str { &self.name } } -impl AnyMetricPattern for MetricPattern23 { - fn name(&self) -> &str { - &self.name - } - fn indexes(&self) -> &'static [Index] { - _I23 - } -} -impl MetricPattern for MetricPattern23 { - fn get(&self, index: Index) -> Option> { - _I23.contains(&index) - .then(|| _ep(&self.by.client, &self.by.name, index)) - } -} +impl AnyMetricPattern for MetricPattern23 { fn name(&self) -> &str { &self.name } fn indexes(&self) -> &'static [Index] { _I23 } } +impl MetricPattern for MetricPattern23 { fn get(&self, index: Index) -> Option> { _I23.contains(&index).then(|| _ep(&self.by.client, &self.by.name, index)) } } -pub struct MetricPattern24By { - client: Arc, - name: Arc, - _marker: std::marker::PhantomData, -} +pub struct MetricPattern24By { client: Arc, name: Arc, _marker: std::marker::PhantomData } impl MetricPattern24By { - pub fn p2wshaddressindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::P2WSHAddressIndex) - } + pub fn p2wshaddressindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::P2WSHAddressIndex) } } -pub struct MetricPattern24 { - name: Arc, - pub by: MetricPattern24By, -} +pub struct MetricPattern24 { name: Arc, pub by: MetricPattern24By } impl MetricPattern24 { - pub fn new(client: Arc, name: String) -> Self { - let name: Arc = name.into(); - Self { - name: name.clone(), - by: MetricPattern24By { - client, - name, - _marker: std::marker::PhantomData, - }, - } - } - pub fn name(&self) -> &str { - &self.name - } + pub fn new(client: Arc, name: String) -> Self { let name: Arc = name.into(); Self { name: name.clone(), by: MetricPattern24By { client, name, _marker: std::marker::PhantomData } } } + pub fn name(&self) -> &str { &self.name } } -impl AnyMetricPattern for MetricPattern24 { - fn name(&self) -> &str { - &self.name - } - fn indexes(&self) -> &'static [Index] { - _I24 - } -} -impl MetricPattern for MetricPattern24 { - fn get(&self, index: Index) -> Option> { - _I24.contains(&index) - .then(|| _ep(&self.by.client, &self.by.name, index)) - } -} +impl AnyMetricPattern for MetricPattern24 { fn name(&self) -> &str { &self.name } fn indexes(&self) -> &'static [Index] { _I24 } } +impl MetricPattern for MetricPattern24 { fn get(&self, index: Index) -> Option> { _I24.contains(&index).then(|| _ep(&self.by.client, &self.by.name, index)) } } -pub struct MetricPattern25By { - client: Arc, - name: Arc, - _marker: std::marker::PhantomData, -} +pub struct MetricPattern25By { client: Arc, name: Arc, _marker: std::marker::PhantomData } impl MetricPattern25By { - pub fn quarterindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::QuarterIndex) - } + pub fn quarterindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::QuarterIndex) } } -pub struct MetricPattern25 { - name: Arc, - pub by: MetricPattern25By, -} +pub struct MetricPattern25 { name: Arc, pub by: MetricPattern25By } impl MetricPattern25 { - pub fn new(client: Arc, name: String) -> Self { - let name: Arc = name.into(); - Self { - name: name.clone(), - by: MetricPattern25By { - client, - name, - _marker: std::marker::PhantomData, - }, - } - } - pub fn name(&self) -> &str { - &self.name - } + pub fn new(client: Arc, name: String) -> Self { let name: Arc = name.into(); Self { name: name.clone(), by: MetricPattern25By { client, name, _marker: std::marker::PhantomData } } } + pub fn name(&self) -> &str { &self.name } } -impl AnyMetricPattern for MetricPattern25 { - fn name(&self) -> &str { - &self.name - } - fn indexes(&self) -> &'static [Index] { - _I25 - } -} -impl MetricPattern for MetricPattern25 { - fn get(&self, index: Index) -> Option> { - _I25.contains(&index) - .then(|| _ep(&self.by.client, &self.by.name, index)) - } -} +impl AnyMetricPattern for MetricPattern25 { fn name(&self) -> &str { &self.name } fn indexes(&self) -> &'static [Index] { _I25 } } +impl MetricPattern for MetricPattern25 { fn get(&self, index: Index) -> Option> { _I25.contains(&index).then(|| _ep(&self.by.client, &self.by.name, index)) } } -pub struct MetricPattern26By { - client: Arc, - name: Arc, - _marker: std::marker::PhantomData, -} +pub struct MetricPattern26By { client: Arc, name: Arc, _marker: std::marker::PhantomData } impl MetricPattern26By { - pub fn semesterindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::SemesterIndex) - } + pub fn semesterindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::SemesterIndex) } } -pub struct MetricPattern26 { - name: Arc, - pub by: MetricPattern26By, -} +pub struct MetricPattern26 { name: Arc, pub by: MetricPattern26By } impl MetricPattern26 { - pub fn new(client: Arc, name: String) -> Self { - let name: Arc = name.into(); - Self { - name: name.clone(), - by: MetricPattern26By { - client, - name, - _marker: std::marker::PhantomData, - }, - } - } - pub fn name(&self) -> &str { - &self.name - } + pub fn new(client: Arc, name: String) -> Self { let name: Arc = name.into(); Self { name: name.clone(), by: MetricPattern26By { client, name, _marker: std::marker::PhantomData } } } + pub fn name(&self) -> &str { &self.name } } -impl AnyMetricPattern for MetricPattern26 { - fn name(&self) -> &str { - &self.name - } - fn indexes(&self) -> &'static [Index] { - _I26 - } -} -impl MetricPattern for MetricPattern26 { - fn get(&self, index: Index) -> Option> { - _I26.contains(&index) - .then(|| _ep(&self.by.client, &self.by.name, index)) - } -} +impl AnyMetricPattern for MetricPattern26 { fn name(&self) -> &str { &self.name } fn indexes(&self) -> &'static [Index] { _I26 } } +impl MetricPattern for MetricPattern26 { fn get(&self, index: Index) -> Option> { _I26.contains(&index).then(|| _ep(&self.by.client, &self.by.name, index)) } } -pub struct MetricPattern27By { - client: Arc, - name: Arc, - _marker: std::marker::PhantomData, -} +pub struct MetricPattern27By { client: Arc, name: Arc, _marker: std::marker::PhantomData } impl MetricPattern27By { - pub fn txindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::TxIndex) - } + pub fn txindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::TxIndex) } } -pub struct MetricPattern27 { - name: Arc, - pub by: MetricPattern27By, -} +pub struct MetricPattern27 { name: Arc, pub by: MetricPattern27By } impl MetricPattern27 { - pub fn new(client: Arc, name: String) -> Self { - let name: Arc = name.into(); - Self { - name: name.clone(), - by: MetricPattern27By { - client, - name, - _marker: std::marker::PhantomData, - }, - } - } - pub fn name(&self) -> &str { - &self.name - } + pub fn new(client: Arc, name: String) -> Self { let name: Arc = name.into(); Self { name: name.clone(), by: MetricPattern27By { client, name, _marker: std::marker::PhantomData } } } + pub fn name(&self) -> &str { &self.name } } -impl AnyMetricPattern for MetricPattern27 { - fn name(&self) -> &str { - &self.name - } - fn indexes(&self) -> &'static [Index] { - _I27 - } -} -impl MetricPattern for MetricPattern27 { - fn get(&self, index: Index) -> Option> { - _I27.contains(&index) - .then(|| _ep(&self.by.client, &self.by.name, index)) - } -} +impl AnyMetricPattern for MetricPattern27 { fn name(&self) -> &str { &self.name } fn indexes(&self) -> &'static [Index] { _I27 } } +impl MetricPattern for MetricPattern27 { fn get(&self, index: Index) -> Option> { _I27.contains(&index).then(|| _ep(&self.by.client, &self.by.name, index)) } } -pub struct MetricPattern28By { - client: Arc, - name: Arc, - _marker: std::marker::PhantomData, -} +pub struct MetricPattern28By { client: Arc, name: Arc, _marker: std::marker::PhantomData } impl MetricPattern28By { - pub fn unknownoutputindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::UnknownOutputIndex) - } + pub fn unknownoutputindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::UnknownOutputIndex) } } -pub struct MetricPattern28 { - name: Arc, - pub by: MetricPattern28By, -} +pub struct MetricPattern28 { name: Arc, pub by: MetricPattern28By } impl MetricPattern28 { - pub fn new(client: Arc, name: String) -> Self { - let name: Arc = name.into(); - Self { - name: name.clone(), - by: MetricPattern28By { - client, - name, - _marker: std::marker::PhantomData, - }, - } - } - pub fn name(&self) -> &str { - &self.name - } + pub fn new(client: Arc, name: String) -> Self { let name: Arc = name.into(); Self { name: name.clone(), by: MetricPattern28By { client, name, _marker: std::marker::PhantomData } } } + pub fn name(&self) -> &str { &self.name } } -impl AnyMetricPattern for MetricPattern28 { - fn name(&self) -> &str { - &self.name - } - fn indexes(&self) -> &'static [Index] { - _I28 - } -} -impl MetricPattern for MetricPattern28 { - fn get(&self, index: Index) -> Option> { - _I28.contains(&index) - .then(|| _ep(&self.by.client, &self.by.name, index)) - } -} +impl AnyMetricPattern for MetricPattern28 { fn name(&self) -> &str { &self.name } fn indexes(&self) -> &'static [Index] { _I28 } } +impl MetricPattern for MetricPattern28 { fn get(&self, index: Index) -> Option> { _I28.contains(&index).then(|| _ep(&self.by.client, &self.by.name, index)) } } -pub struct MetricPattern29By { - client: Arc, - name: Arc, - _marker: std::marker::PhantomData, -} +pub struct MetricPattern29By { client: Arc, name: Arc, _marker: std::marker::PhantomData } impl MetricPattern29By { - pub fn weekindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::WeekIndex) - } + pub fn weekindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::WeekIndex) } } -pub struct MetricPattern29 { - name: Arc, - pub by: MetricPattern29By, -} +pub struct MetricPattern29 { name: Arc, pub by: MetricPattern29By } impl MetricPattern29 { - pub fn new(client: Arc, name: String) -> Self { - let name: Arc = name.into(); - Self { - name: name.clone(), - by: MetricPattern29By { - client, - name, - _marker: std::marker::PhantomData, - }, - } - } - pub fn name(&self) -> &str { - &self.name - } + pub fn new(client: Arc, name: String) -> Self { let name: Arc = name.into(); Self { name: name.clone(), by: MetricPattern29By { client, name, _marker: std::marker::PhantomData } } } + pub fn name(&self) -> &str { &self.name } } -impl AnyMetricPattern for MetricPattern29 { - fn name(&self) -> &str { - &self.name - } - fn indexes(&self) -> &'static [Index] { - _I29 - } -} -impl MetricPattern for MetricPattern29 { - fn get(&self, index: Index) -> Option> { - _I29.contains(&index) - .then(|| _ep(&self.by.client, &self.by.name, index)) - } -} +impl AnyMetricPattern for MetricPattern29 { fn name(&self) -> &str { &self.name } fn indexes(&self) -> &'static [Index] { _I29 } } +impl MetricPattern for MetricPattern29 { fn get(&self, index: Index) -> Option> { _I29.contains(&index).then(|| _ep(&self.by.client, &self.by.name, index)) } } -pub struct MetricPattern30By { - client: Arc, - name: Arc, - _marker: std::marker::PhantomData, -} +pub struct MetricPattern30By { client: Arc, name: Arc, _marker: std::marker::PhantomData } impl MetricPattern30By { - pub fn yearindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::YearIndex) - } + pub fn yearindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::YearIndex) } } -pub struct MetricPattern30 { - name: Arc, - pub by: MetricPattern30By, -} +pub struct MetricPattern30 { name: Arc, pub by: MetricPattern30By } impl MetricPattern30 { - pub fn new(client: Arc, name: String) -> Self { - let name: Arc = name.into(); - Self { - name: name.clone(), - by: MetricPattern30By { - client, - name, - _marker: std::marker::PhantomData, - }, - } - } - pub fn name(&self) -> &str { - &self.name - } + pub fn new(client: Arc, name: String) -> Self { let name: Arc = name.into(); Self { name: name.clone(), by: MetricPattern30By { client, name, _marker: std::marker::PhantomData } } } + pub fn name(&self) -> &str { &self.name } } -impl AnyMetricPattern for MetricPattern30 { - fn name(&self) -> &str { - &self.name - } - fn indexes(&self) -> &'static [Index] { - _I30 - } -} -impl MetricPattern for MetricPattern30 { - fn get(&self, index: Index) -> Option> { - _I30.contains(&index) - .then(|| _ep(&self.by.client, &self.by.name, index)) - } -} +impl AnyMetricPattern for MetricPattern30 { fn name(&self) -> &str { &self.name } fn indexes(&self) -> &'static [Index] { _I30 } } +impl MetricPattern for MetricPattern30 { fn get(&self, index: Index) -> Option> { _I30.contains(&index).then(|| _ep(&self.by.client, &self.by.name, index)) } } -pub struct MetricPattern31By { - client: Arc, - name: Arc, - _marker: std::marker::PhantomData, -} +pub struct MetricPattern31By { client: Arc, name: Arc, _marker: std::marker::PhantomData } impl MetricPattern31By { - pub fn loadedaddressindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::LoadedAddressIndex) - } + pub fn loadedaddressindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::LoadedAddressIndex) } } -pub struct MetricPattern31 { - name: Arc, - pub by: MetricPattern31By, -} +pub struct MetricPattern31 { name: Arc, pub by: MetricPattern31By } impl MetricPattern31 { - pub fn new(client: Arc, name: String) -> Self { - let name: Arc = name.into(); - Self { - name: name.clone(), - by: MetricPattern31By { - client, - name, - _marker: std::marker::PhantomData, - }, - } - } - pub fn name(&self) -> &str { - &self.name - } + pub fn new(client: Arc, name: String) -> Self { let name: Arc = name.into(); Self { name: name.clone(), by: MetricPattern31By { client, name, _marker: std::marker::PhantomData } } } + pub fn name(&self) -> &str { &self.name } } -impl AnyMetricPattern for MetricPattern31 { - fn name(&self) -> &str { - &self.name - } - fn indexes(&self) -> &'static [Index] { - _I31 - } -} -impl MetricPattern for MetricPattern31 { - fn get(&self, index: Index) -> Option> { - _I31.contains(&index) - .then(|| _ep(&self.by.client, &self.by.name, index)) - } -} +impl AnyMetricPattern for MetricPattern31 { fn name(&self) -> &str { &self.name } fn indexes(&self) -> &'static [Index] { _I31 } } +impl MetricPattern for MetricPattern31 { fn get(&self, index: Index) -> Option> { _I31.contains(&index).then(|| _ep(&self.by.client, &self.by.name, index)) } } -pub struct MetricPattern32By { - client: Arc, - name: Arc, - _marker: std::marker::PhantomData, -} +pub struct MetricPattern32By { client: Arc, name: Arc, _marker: std::marker::PhantomData } impl MetricPattern32By { - pub fn emptyaddressindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::EmptyAddressIndex) - } + pub fn emptyaddressindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::EmptyAddressIndex) } } -pub struct MetricPattern32 { - name: Arc, - pub by: MetricPattern32By, -} +pub struct MetricPattern32 { name: Arc, pub by: MetricPattern32By } impl MetricPattern32 { - pub fn new(client: Arc, name: String) -> Self { - let name: Arc = name.into(); - Self { - name: name.clone(), - by: MetricPattern32By { - client, - name, - _marker: std::marker::PhantomData, - }, - } - } - pub fn name(&self) -> &str { - &self.name - } + pub fn new(client: Arc, name: String) -> Self { let name: Arc = name.into(); Self { name: name.clone(), by: MetricPattern32By { client, name, _marker: std::marker::PhantomData } } } + pub fn name(&self) -> &str { &self.name } } -impl AnyMetricPattern for MetricPattern32 { - fn name(&self) -> &str { - &self.name - } - fn indexes(&self) -> &'static [Index] { - _I32 - } -} -impl MetricPattern for MetricPattern32 { - fn get(&self, index: Index) -> Option> { - _I32.contains(&index) - .then(|| _ep(&self.by.client, &self.by.name, index)) - } -} +impl AnyMetricPattern for MetricPattern32 { fn name(&self) -> &str { &self.name } fn indexes(&self) -> &'static [Index] { _I32 } } +impl MetricPattern for MetricPattern32 { fn get(&self, index: Index) -> Option> { _I32.contains(&index).then(|| _ep(&self.by.client, &self.by.name, index)) } } -pub struct MetricPattern33By { - client: Arc, - name: Arc, - _marker: std::marker::PhantomData, -} +pub struct MetricPattern33By { client: Arc, name: Arc, _marker: std::marker::PhantomData } impl MetricPattern33By { - pub fn pairoutputindex(&self) -> MetricEndpointBuilder { - _ep(&self.client, &self.name, Index::PairOutputIndex) - } + pub fn pairoutputindex(&self) -> MetricEndpointBuilder { _ep(&self.client, &self.name, Index::PairOutputIndex) } } -pub struct MetricPattern33 { - name: Arc, - pub by: MetricPattern33By, -} +pub struct MetricPattern33 { name: Arc, pub by: MetricPattern33By } impl MetricPattern33 { - pub fn new(client: Arc, name: String) -> Self { - let name: Arc = name.into(); - Self { - name: name.clone(), - by: MetricPattern33By { - client, - name, - _marker: std::marker::PhantomData, - }, - } - } - pub fn name(&self) -> &str { - &self.name - } + pub fn new(client: Arc, name: String) -> Self { let name: Arc = name.into(); Self { name: name.clone(), by: MetricPattern33By { client, name, _marker: std::marker::PhantomData } } } + pub fn name(&self) -> &str { &self.name } } -impl AnyMetricPattern for MetricPattern33 { - fn name(&self) -> &str { - &self.name - } - fn indexes(&self) -> &'static [Index] { - _I33 - } -} -impl MetricPattern for MetricPattern33 { - fn get(&self, index: Index) -> Option> { - _I33.contains(&index) - .then(|| _ep(&self.by.client, &self.by.name, index)) - } -} +impl AnyMetricPattern for MetricPattern33 { fn name(&self) -> &str { &self.name } fn indexes(&self) -> &'static [Index] { _I33 } } +impl MetricPattern for MetricPattern33 { fn get(&self, index: Index) -> Option> { _I33.contains(&index).then(|| _ep(&self.by.client, &self.by.name, index)) } } // Reusable pattern structs @@ -2142,88 +913,31 @@ impl RealizedPattern3 { pub fn new(client: Arc, acc: String) -> Self { Self { adjusted_sopr: MetricPattern6::new(client.clone(), _m(&acc, "adjusted_sopr")), - adjusted_sopr_30d_ema: MetricPattern6::new( - client.clone(), - _m(&acc, "adjusted_sopr_30d_ema"), - ), - adjusted_sopr_7d_ema: MetricPattern6::new( - client.clone(), - _m(&acc, "adjusted_sopr_7d_ema"), - ), - adjusted_value_created: MetricPattern1::new( - client.clone(), - _m(&acc, "adjusted_value_created"), - ), - adjusted_value_destroyed: MetricPattern1::new( - client.clone(), - _m(&acc, "adjusted_value_destroyed"), - ), + adjusted_sopr_30d_ema: MetricPattern6::new(client.clone(), _m(&acc, "adjusted_sopr_30d_ema")), + adjusted_sopr_7d_ema: MetricPattern6::new(client.clone(), _m(&acc, "adjusted_sopr_7d_ema")), + adjusted_value_created: MetricPattern1::new(client.clone(), _m(&acc, "adjusted_value_created")), + adjusted_value_destroyed: MetricPattern1::new(client.clone(), _m(&acc, "adjusted_value_destroyed")), mvrv: MetricPattern4::new(client.clone(), _m(&acc, "mvrv")), neg_realized_loss: BitcoinPattern2::new(client.clone(), _m(&acc, "neg_realized_loss")), net_realized_pnl: BlockCountPattern::new(client.clone(), _m(&acc, "net_realized_pnl")), - net_realized_pnl_cumulative_30d_delta: MetricPattern4::new( - client.clone(), - _m(&acc, "net_realized_pnl_cumulative_30d_delta"), - ), - net_realized_pnl_cumulative_30d_delta_rel_to_market_cap: MetricPattern4::new( - client.clone(), - _m( - &acc, - "net_realized_pnl_cumulative_30d_delta_rel_to_market_cap", - ), - ), - net_realized_pnl_cumulative_30d_delta_rel_to_realized_cap: MetricPattern4::new( - client.clone(), - _m( - &acc, - "net_realized_pnl_cumulative_30d_delta_rel_to_realized_cap", - ), - ), - net_realized_pnl_rel_to_realized_cap: BlockCountPattern::new( - client.clone(), - _m(&acc, "net_realized_pnl_rel_to_realized_cap"), - ), + net_realized_pnl_cumulative_30d_delta: MetricPattern4::new(client.clone(), _m(&acc, "net_realized_pnl_cumulative_30d_delta")), + net_realized_pnl_cumulative_30d_delta_rel_to_market_cap: MetricPattern4::new(client.clone(), _m(&acc, "net_realized_pnl_cumulative_30d_delta_rel_to_market_cap")), + net_realized_pnl_cumulative_30d_delta_rel_to_realized_cap: MetricPattern4::new(client.clone(), _m(&acc, "net_realized_pnl_cumulative_30d_delta_rel_to_realized_cap")), + net_realized_pnl_rel_to_realized_cap: BlockCountPattern::new(client.clone(), _m(&acc, "net_realized_pnl_rel_to_realized_cap")), realized_cap: MetricPattern1::new(client.clone(), _m(&acc, "realized_cap")), - realized_cap_30d_delta: MetricPattern4::new( - client.clone(), - _m(&acc, "realized_cap_30d_delta"), - ), - realized_cap_rel_to_own_market_cap: MetricPattern1::new( - client.clone(), - _m(&acc, "realized_cap_rel_to_own_market_cap"), - ), + realized_cap_30d_delta: MetricPattern4::new(client.clone(), _m(&acc, "realized_cap_30d_delta")), + realized_cap_rel_to_own_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "realized_cap_rel_to_own_market_cap")), realized_loss: BlockCountPattern::new(client.clone(), _m(&acc, "realized_loss")), - realized_loss_rel_to_realized_cap: BlockCountPattern::new( - client.clone(), - _m(&acc, "realized_loss_rel_to_realized_cap"), - ), + realized_loss_rel_to_realized_cap: BlockCountPattern::new(client.clone(), _m(&acc, "realized_loss_rel_to_realized_cap")), realized_price: MetricPattern1::new(client.clone(), _m(&acc, "realized_price")), - realized_price_extra: ActivePriceRatioPattern::new( - client.clone(), - _m(&acc, "realized_price_ratio"), - ), + realized_price_extra: ActivePriceRatioPattern::new(client.clone(), _m(&acc, "realized_price_ratio")), realized_profit: BlockCountPattern::new(client.clone(), _m(&acc, "realized_profit")), - realized_profit_rel_to_realized_cap: BlockCountPattern::new( - client.clone(), - _m(&acc, "realized_profit_rel_to_realized_cap"), - ), - realized_profit_to_loss_ratio: MetricPattern6::new( - client.clone(), - _m(&acc, "realized_profit_to_loss_ratio"), - ), + realized_profit_rel_to_realized_cap: BlockCountPattern::new(client.clone(), _m(&acc, "realized_profit_rel_to_realized_cap")), + realized_profit_to_loss_ratio: MetricPattern6::new(client.clone(), _m(&acc, "realized_profit_to_loss_ratio")), realized_value: MetricPattern1::new(client.clone(), _m(&acc, "realized_value")), - sell_side_risk_ratio: MetricPattern6::new( - client.clone(), - _m(&acc, "sell_side_risk_ratio"), - ), - sell_side_risk_ratio_30d_ema: MetricPattern6::new( - client.clone(), - _m(&acc, "sell_side_risk_ratio_30d_ema"), - ), - sell_side_risk_ratio_7d_ema: MetricPattern6::new( - client.clone(), - _m(&acc, "sell_side_risk_ratio_7d_ema"), - ), + sell_side_risk_ratio: MetricPattern6::new(client.clone(), _m(&acc, "sell_side_risk_ratio")), + sell_side_risk_ratio_30d_ema: MetricPattern6::new(client.clone(), _m(&acc, "sell_side_risk_ratio_30d_ema")), + sell_side_risk_ratio_7d_ema: MetricPattern6::new(client.clone(), _m(&acc, "sell_side_risk_ratio_7d_ema")), sopr: MetricPattern6::new(client.clone(), _m(&acc, "sopr")), sopr_30d_ema: MetricPattern6::new(client.clone(), _m(&acc, "sopr_30d_ema")), sopr_7d_ema: MetricPattern6::new(client.clone(), _m(&acc, "sopr_7d_ema")), @@ -2273,80 +987,29 @@ impl RealizedPattern4 { pub fn new(client: Arc, acc: String) -> Self { Self { adjusted_sopr: MetricPattern6::new(client.clone(), _m(&acc, "adjusted_sopr")), - adjusted_sopr_30d_ema: MetricPattern6::new( - client.clone(), - _m(&acc, "adjusted_sopr_30d_ema"), - ), - adjusted_sopr_7d_ema: MetricPattern6::new( - client.clone(), - _m(&acc, "adjusted_sopr_7d_ema"), - ), - adjusted_value_created: MetricPattern1::new( - client.clone(), - _m(&acc, "adjusted_value_created"), - ), - adjusted_value_destroyed: MetricPattern1::new( - client.clone(), - _m(&acc, "adjusted_value_destroyed"), - ), + adjusted_sopr_30d_ema: MetricPattern6::new(client.clone(), _m(&acc, "adjusted_sopr_30d_ema")), + adjusted_sopr_7d_ema: MetricPattern6::new(client.clone(), _m(&acc, "adjusted_sopr_7d_ema")), + adjusted_value_created: MetricPattern1::new(client.clone(), _m(&acc, "adjusted_value_created")), + adjusted_value_destroyed: MetricPattern1::new(client.clone(), _m(&acc, "adjusted_value_destroyed")), mvrv: MetricPattern4::new(client.clone(), _m(&acc, "mvrv")), neg_realized_loss: BitcoinPattern2::new(client.clone(), _m(&acc, "neg_realized_loss")), net_realized_pnl: BlockCountPattern::new(client.clone(), _m(&acc, "net_realized_pnl")), - net_realized_pnl_cumulative_30d_delta: MetricPattern4::new( - client.clone(), - _m(&acc, "net_realized_pnl_cumulative_30d_delta"), - ), - net_realized_pnl_cumulative_30d_delta_rel_to_market_cap: MetricPattern4::new( - client.clone(), - _m( - &acc, - "net_realized_pnl_cumulative_30d_delta_rel_to_market_cap", - ), - ), - net_realized_pnl_cumulative_30d_delta_rel_to_realized_cap: MetricPattern4::new( - client.clone(), - _m( - &acc, - "net_realized_pnl_cumulative_30d_delta_rel_to_realized_cap", - ), - ), - net_realized_pnl_rel_to_realized_cap: BlockCountPattern::new( - client.clone(), - _m(&acc, "net_realized_pnl_rel_to_realized_cap"), - ), + net_realized_pnl_cumulative_30d_delta: MetricPattern4::new(client.clone(), _m(&acc, "net_realized_pnl_cumulative_30d_delta")), + net_realized_pnl_cumulative_30d_delta_rel_to_market_cap: MetricPattern4::new(client.clone(), _m(&acc, "net_realized_pnl_cumulative_30d_delta_rel_to_market_cap")), + net_realized_pnl_cumulative_30d_delta_rel_to_realized_cap: MetricPattern4::new(client.clone(), _m(&acc, "net_realized_pnl_cumulative_30d_delta_rel_to_realized_cap")), + net_realized_pnl_rel_to_realized_cap: BlockCountPattern::new(client.clone(), _m(&acc, "net_realized_pnl_rel_to_realized_cap")), realized_cap: MetricPattern1::new(client.clone(), _m(&acc, "realized_cap")), - realized_cap_30d_delta: MetricPattern4::new( - client.clone(), - _m(&acc, "realized_cap_30d_delta"), - ), + realized_cap_30d_delta: MetricPattern4::new(client.clone(), _m(&acc, "realized_cap_30d_delta")), realized_loss: BlockCountPattern::new(client.clone(), _m(&acc, "realized_loss")), - realized_loss_rel_to_realized_cap: BlockCountPattern::new( - client.clone(), - _m(&acc, "realized_loss_rel_to_realized_cap"), - ), + realized_loss_rel_to_realized_cap: BlockCountPattern::new(client.clone(), _m(&acc, "realized_loss_rel_to_realized_cap")), realized_price: MetricPattern1::new(client.clone(), _m(&acc, "realized_price")), - realized_price_extra: RealizedPriceExtraPattern::new( - client.clone(), - _m(&acc, "realized_price_ratio"), - ), + realized_price_extra: RealizedPriceExtraPattern::new(client.clone(), _m(&acc, "realized_price_ratio")), realized_profit: BlockCountPattern::new(client.clone(), _m(&acc, "realized_profit")), - realized_profit_rel_to_realized_cap: BlockCountPattern::new( - client.clone(), - _m(&acc, "realized_profit_rel_to_realized_cap"), - ), + realized_profit_rel_to_realized_cap: BlockCountPattern::new(client.clone(), _m(&acc, "realized_profit_rel_to_realized_cap")), realized_value: MetricPattern1::new(client.clone(), _m(&acc, "realized_value")), - sell_side_risk_ratio: MetricPattern6::new( - client.clone(), - _m(&acc, "sell_side_risk_ratio"), - ), - sell_side_risk_ratio_30d_ema: MetricPattern6::new( - client.clone(), - _m(&acc, "sell_side_risk_ratio_30d_ema"), - ), - sell_side_risk_ratio_7d_ema: MetricPattern6::new( - client.clone(), - _m(&acc, "sell_side_risk_ratio_7d_ema"), - ), + sell_side_risk_ratio: MetricPattern6::new(client.clone(), _m(&acc, "sell_side_risk_ratio")), + sell_side_risk_ratio_30d_ema: MetricPattern6::new(client.clone(), _m(&acc, "sell_side_risk_ratio_30d_ema")), + sell_side_risk_ratio_7d_ema: MetricPattern6::new(client.clone(), _m(&acc, "sell_side_risk_ratio_7d_ema")), sopr: MetricPattern6::new(client.clone(), _m(&acc, "sopr")), sopr_30d_ema: MetricPattern6::new(client.clone(), _m(&acc, "sopr_30d_ema")), sopr_7d_ema: MetricPattern6::new(client.clone(), _m(&acc, "sopr_7d_ema")), @@ -2463,69 +1126,24 @@ impl RealizedPattern2 { mvrv: MetricPattern4::new(client.clone(), _m(&acc, "mvrv")), neg_realized_loss: BitcoinPattern2::new(client.clone(), _m(&acc, "neg_realized_loss")), net_realized_pnl: BlockCountPattern::new(client.clone(), _m(&acc, "net_realized_pnl")), - net_realized_pnl_cumulative_30d_delta: MetricPattern4::new( - client.clone(), - _m(&acc, "net_realized_pnl_cumulative_30d_delta"), - ), - net_realized_pnl_cumulative_30d_delta_rel_to_market_cap: MetricPattern4::new( - client.clone(), - _m( - &acc, - "net_realized_pnl_cumulative_30d_delta_rel_to_market_cap", - ), - ), - net_realized_pnl_cumulative_30d_delta_rel_to_realized_cap: MetricPattern4::new( - client.clone(), - _m( - &acc, - "net_realized_pnl_cumulative_30d_delta_rel_to_realized_cap", - ), - ), - net_realized_pnl_rel_to_realized_cap: BlockCountPattern::new( - client.clone(), - _m(&acc, "net_realized_pnl_rel_to_realized_cap"), - ), + net_realized_pnl_cumulative_30d_delta: MetricPattern4::new(client.clone(), _m(&acc, "net_realized_pnl_cumulative_30d_delta")), + net_realized_pnl_cumulative_30d_delta_rel_to_market_cap: MetricPattern4::new(client.clone(), _m(&acc, "net_realized_pnl_cumulative_30d_delta_rel_to_market_cap")), + net_realized_pnl_cumulative_30d_delta_rel_to_realized_cap: MetricPattern4::new(client.clone(), _m(&acc, "net_realized_pnl_cumulative_30d_delta_rel_to_realized_cap")), + net_realized_pnl_rel_to_realized_cap: BlockCountPattern::new(client.clone(), _m(&acc, "net_realized_pnl_rel_to_realized_cap")), realized_cap: MetricPattern1::new(client.clone(), _m(&acc, "realized_cap")), - realized_cap_30d_delta: MetricPattern4::new( - client.clone(), - _m(&acc, "realized_cap_30d_delta"), - ), - realized_cap_rel_to_own_market_cap: MetricPattern1::new( - client.clone(), - _m(&acc, "realized_cap_rel_to_own_market_cap"), - ), + realized_cap_30d_delta: MetricPattern4::new(client.clone(), _m(&acc, "realized_cap_30d_delta")), + realized_cap_rel_to_own_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "realized_cap_rel_to_own_market_cap")), realized_loss: BlockCountPattern::new(client.clone(), _m(&acc, "realized_loss")), - realized_loss_rel_to_realized_cap: BlockCountPattern::new( - client.clone(), - _m(&acc, "realized_loss_rel_to_realized_cap"), - ), + realized_loss_rel_to_realized_cap: BlockCountPattern::new(client.clone(), _m(&acc, "realized_loss_rel_to_realized_cap")), realized_price: MetricPattern1::new(client.clone(), _m(&acc, "realized_price")), - realized_price_extra: ActivePriceRatioPattern::new( - client.clone(), - _m(&acc, "realized_price_ratio"), - ), + realized_price_extra: ActivePriceRatioPattern::new(client.clone(), _m(&acc, "realized_price_ratio")), realized_profit: BlockCountPattern::new(client.clone(), _m(&acc, "realized_profit")), - realized_profit_rel_to_realized_cap: BlockCountPattern::new( - client.clone(), - _m(&acc, "realized_profit_rel_to_realized_cap"), - ), - realized_profit_to_loss_ratio: MetricPattern6::new( - client.clone(), - _m(&acc, "realized_profit_to_loss_ratio"), - ), + realized_profit_rel_to_realized_cap: BlockCountPattern::new(client.clone(), _m(&acc, "realized_profit_rel_to_realized_cap")), + realized_profit_to_loss_ratio: MetricPattern6::new(client.clone(), _m(&acc, "realized_profit_to_loss_ratio")), realized_value: MetricPattern1::new(client.clone(), _m(&acc, "realized_value")), - sell_side_risk_ratio: MetricPattern6::new( - client.clone(), - _m(&acc, "sell_side_risk_ratio"), - ), - sell_side_risk_ratio_30d_ema: MetricPattern6::new( - client.clone(), - _m(&acc, "sell_side_risk_ratio_30d_ema"), - ), - sell_side_risk_ratio_7d_ema: MetricPattern6::new( - client.clone(), - _m(&acc, "sell_side_risk_ratio_7d_ema"), - ), + sell_side_risk_ratio: MetricPattern6::new(client.clone(), _m(&acc, "sell_side_risk_ratio")), + sell_side_risk_ratio_30d_ema: MetricPattern6::new(client.clone(), _m(&acc, "sell_side_risk_ratio_30d_ema")), + sell_side_risk_ratio_7d_ema: MetricPattern6::new(client.clone(), _m(&acc, "sell_side_risk_ratio_7d_ema")), sopr: MetricPattern6::new(client.clone(), _m(&acc, "sopr")), sopr_30d_ema: MetricPattern6::new(client.clone(), _m(&acc, "sopr_30d_ema")), sopr_7d_ema: MetricPattern6::new(client.clone(), _m(&acc, "sopr_7d_ema")), @@ -2572,61 +1190,22 @@ impl RealizedPattern { mvrv: MetricPattern4::new(client.clone(), _m(&acc, "mvrv")), neg_realized_loss: BitcoinPattern2::new(client.clone(), _m(&acc, "neg_realized_loss")), net_realized_pnl: BlockCountPattern::new(client.clone(), _m(&acc, "net_realized_pnl")), - net_realized_pnl_cumulative_30d_delta: MetricPattern4::new( - client.clone(), - _m(&acc, "net_realized_pnl_cumulative_30d_delta"), - ), - net_realized_pnl_cumulative_30d_delta_rel_to_market_cap: MetricPattern4::new( - client.clone(), - _m( - &acc, - "net_realized_pnl_cumulative_30d_delta_rel_to_market_cap", - ), - ), - net_realized_pnl_cumulative_30d_delta_rel_to_realized_cap: MetricPattern4::new( - client.clone(), - _m( - &acc, - "net_realized_pnl_cumulative_30d_delta_rel_to_realized_cap", - ), - ), - net_realized_pnl_rel_to_realized_cap: BlockCountPattern::new( - client.clone(), - _m(&acc, "net_realized_pnl_rel_to_realized_cap"), - ), + net_realized_pnl_cumulative_30d_delta: MetricPattern4::new(client.clone(), _m(&acc, "net_realized_pnl_cumulative_30d_delta")), + net_realized_pnl_cumulative_30d_delta_rel_to_market_cap: MetricPattern4::new(client.clone(), _m(&acc, "net_realized_pnl_cumulative_30d_delta_rel_to_market_cap")), + net_realized_pnl_cumulative_30d_delta_rel_to_realized_cap: MetricPattern4::new(client.clone(), _m(&acc, "net_realized_pnl_cumulative_30d_delta_rel_to_realized_cap")), + net_realized_pnl_rel_to_realized_cap: BlockCountPattern::new(client.clone(), _m(&acc, "net_realized_pnl_rel_to_realized_cap")), realized_cap: MetricPattern1::new(client.clone(), _m(&acc, "realized_cap")), - realized_cap_30d_delta: MetricPattern4::new( - client.clone(), - _m(&acc, "realized_cap_30d_delta"), - ), + realized_cap_30d_delta: MetricPattern4::new(client.clone(), _m(&acc, "realized_cap_30d_delta")), realized_loss: BlockCountPattern::new(client.clone(), _m(&acc, "realized_loss")), - realized_loss_rel_to_realized_cap: BlockCountPattern::new( - client.clone(), - _m(&acc, "realized_loss_rel_to_realized_cap"), - ), + realized_loss_rel_to_realized_cap: BlockCountPattern::new(client.clone(), _m(&acc, "realized_loss_rel_to_realized_cap")), realized_price: MetricPattern1::new(client.clone(), _m(&acc, "realized_price")), - realized_price_extra: RealizedPriceExtraPattern::new( - client.clone(), - _m(&acc, "realized_price_ratio"), - ), + realized_price_extra: RealizedPriceExtraPattern::new(client.clone(), _m(&acc, "realized_price_ratio")), realized_profit: BlockCountPattern::new(client.clone(), _m(&acc, "realized_profit")), - realized_profit_rel_to_realized_cap: BlockCountPattern::new( - client.clone(), - _m(&acc, "realized_profit_rel_to_realized_cap"), - ), + realized_profit_rel_to_realized_cap: BlockCountPattern::new(client.clone(), _m(&acc, "realized_profit_rel_to_realized_cap")), realized_value: MetricPattern1::new(client.clone(), _m(&acc, "realized_value")), - sell_side_risk_ratio: MetricPattern6::new( - client.clone(), - _m(&acc, "sell_side_risk_ratio"), - ), - sell_side_risk_ratio_30d_ema: MetricPattern6::new( - client.clone(), - _m(&acc, "sell_side_risk_ratio_30d_ema"), - ), - sell_side_risk_ratio_7d_ema: MetricPattern6::new( - client.clone(), - _m(&acc, "sell_side_risk_ratio_7d_ema"), - ), + sell_side_risk_ratio: MetricPattern6::new(client.clone(), _m(&acc, "sell_side_risk_ratio")), + sell_side_risk_ratio_30d_ema: MetricPattern6::new(client.clone(), _m(&acc, "sell_side_risk_ratio_30d_ema")), + sell_side_risk_ratio_7d_ema: MetricPattern6::new(client.clone(), _m(&acc, "sell_side_risk_ratio_7d_ema")), sopr: MetricPattern6::new(client.clone(), _m(&acc, "sopr")), sopr_30d_ema: MetricPattern6::new(client.clone(), _m(&acc, "sopr_30d_ema")), sopr_7d_ema: MetricPattern6::new(client.clone(), _m(&acc, "sopr_7d_ema")), @@ -2815,75 +1394,24 @@ impl RelativePattern5 { /// Create a new pattern node with accumulated metric name. pub fn new(client: Arc, acc: String) -> Self { Self { - neg_unrealized_loss_rel_to_market_cap: MetricPattern1::new( - client.clone(), - _m(&acc, "neg_unrealized_loss_rel_to_market_cap"), - ), - neg_unrealized_loss_rel_to_own_market_cap: MetricPattern1::new( - client.clone(), - _m(&acc, "neg_unrealized_loss_rel_to_own_market_cap"), - ), - neg_unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1::new( - client.clone(), - _m(&acc, "neg_unrealized_loss_rel_to_own_total_unrealized_pnl"), - ), - net_unrealized_pnl_rel_to_market_cap: MetricPattern1::new( - client.clone(), - _m(&acc, "net_unrealized_pnl_rel_to_market_cap"), - ), - net_unrealized_pnl_rel_to_own_market_cap: MetricPattern1::new( - client.clone(), - _m(&acc, "net_unrealized_pnl_rel_to_own_market_cap"), - ), - net_unrealized_pnl_rel_to_own_total_unrealized_pnl: MetricPattern1::new( - client.clone(), - _m(&acc, "net_unrealized_pnl_rel_to_own_total_unrealized_pnl"), - ), + neg_unrealized_loss_rel_to_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "neg_unrealized_loss_rel_to_market_cap")), + neg_unrealized_loss_rel_to_own_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "neg_unrealized_loss_rel_to_own_market_cap")), + neg_unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1::new(client.clone(), _m(&acc, "neg_unrealized_loss_rel_to_own_total_unrealized_pnl")), + net_unrealized_pnl_rel_to_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "net_unrealized_pnl_rel_to_market_cap")), + net_unrealized_pnl_rel_to_own_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "net_unrealized_pnl_rel_to_own_market_cap")), + net_unrealized_pnl_rel_to_own_total_unrealized_pnl: MetricPattern1::new(client.clone(), _m(&acc, "net_unrealized_pnl_rel_to_own_total_unrealized_pnl")), nupl: MetricPattern1::new(client.clone(), _m(&acc, "nupl")), - supply_in_loss_rel_to_circulating_supply: MetricPattern1::new( - client.clone(), - _m(&acc, "supply_in_loss_rel_to_circulating_supply"), - ), - supply_in_loss_rel_to_own_supply: MetricPattern1::new( - client.clone(), - _m(&acc, "supply_in_loss_rel_to_own_supply"), - ), - supply_in_profit_rel_to_circulating_supply: MetricPattern1::new( - client.clone(), - _m(&acc, "supply_in_profit_rel_to_circulating_supply"), - ), - supply_in_profit_rel_to_own_supply: MetricPattern1::new( - client.clone(), - _m(&acc, "supply_in_profit_rel_to_own_supply"), - ), - supply_rel_to_circulating_supply: MetricPattern4::new( - client.clone(), - _m(&acc, "supply_rel_to_circulating_supply"), - ), - unrealized_loss_rel_to_market_cap: MetricPattern1::new( - client.clone(), - _m(&acc, "unrealized_loss_rel_to_market_cap"), - ), - unrealized_loss_rel_to_own_market_cap: MetricPattern1::new( - client.clone(), - _m(&acc, "unrealized_loss_rel_to_own_market_cap"), - ), - unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1::new( - client.clone(), - _m(&acc, "unrealized_loss_rel_to_own_total_unrealized_pnl"), - ), - unrealized_profit_rel_to_market_cap: MetricPattern1::new( - client.clone(), - _m(&acc, "unrealized_profit_rel_to_market_cap"), - ), - unrealized_profit_rel_to_own_market_cap: MetricPattern1::new( - client.clone(), - _m(&acc, "unrealized_profit_rel_to_own_market_cap"), - ), - unrealized_profit_rel_to_own_total_unrealized_pnl: MetricPattern1::new( - client.clone(), - _m(&acc, "unrealized_profit_rel_to_own_total_unrealized_pnl"), - ), + supply_in_loss_rel_to_circulating_supply: MetricPattern1::new(client.clone(), _m(&acc, "supply_in_loss_rel_to_circulating_supply")), + supply_in_loss_rel_to_own_supply: MetricPattern1::new(client.clone(), _m(&acc, "supply_in_loss_rel_to_own_supply")), + supply_in_profit_rel_to_circulating_supply: MetricPattern1::new(client.clone(), _m(&acc, "supply_in_profit_rel_to_circulating_supply")), + supply_in_profit_rel_to_own_supply: MetricPattern1::new(client.clone(), _m(&acc, "supply_in_profit_rel_to_own_supply")), + supply_rel_to_circulating_supply: MetricPattern4::new(client.clone(), _m(&acc, "supply_rel_to_circulating_supply")), + unrealized_loss_rel_to_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_loss_rel_to_market_cap")), + unrealized_loss_rel_to_own_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_loss_rel_to_own_market_cap")), + unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_loss_rel_to_own_total_unrealized_pnl")), + unrealized_profit_rel_to_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_profit_rel_to_market_cap")), + unrealized_profit_rel_to_own_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_profit_rel_to_own_market_cap")), + unrealized_profit_rel_to_own_total_unrealized_pnl: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_profit_rel_to_own_total_unrealized_pnl")), } } } @@ -3091,17 +1619,17 @@ impl ClassAveragePricePattern { /// Create a new pattern node with accumulated metric name. pub fn new(client: Arc, acc: String) -> Self { Self { - _2015: MetricPattern4::new(client.clone(), _m(&acc, "2015_average_price")), - _2016: MetricPattern4::new(client.clone(), _m(&acc, "2016_average_price")), - _2017: MetricPattern4::new(client.clone(), _m(&acc, "2017_average_price")), - _2018: MetricPattern4::new(client.clone(), _m(&acc, "2018_average_price")), - _2019: MetricPattern4::new(client.clone(), _m(&acc, "2019_average_price")), - _2020: MetricPattern4::new(client.clone(), _m(&acc, "2020_average_price")), - _2021: MetricPattern4::new(client.clone(), _m(&acc, "2021_average_price")), - _2022: MetricPattern4::new(client.clone(), _m(&acc, "2022_average_price")), - _2023: MetricPattern4::new(client.clone(), _m(&acc, "2023_average_price")), - _2024: MetricPattern4::new(client.clone(), _m(&acc, "2024_average_price")), - _2025: MetricPattern4::new(client.clone(), _m(&acc, "2025_average_price")), + _2015: MetricPattern4::new(client.clone(), _m(&acc, "2015_returns")), + _2016: MetricPattern4::new(client.clone(), _m(&acc, "2016_returns")), + _2017: MetricPattern4::new(client.clone(), _m(&acc, "2017_returns")), + _2018: MetricPattern4::new(client.clone(), _m(&acc, "2018_returns")), + _2019: MetricPattern4::new(client.clone(), _m(&acc, "2019_returns")), + _2020: MetricPattern4::new(client.clone(), _m(&acc, "2020_returns")), + _2021: MetricPattern4::new(client.clone(), _m(&acc, "2021_returns")), + _2022: MetricPattern4::new(client.clone(), _m(&acc, "2022_returns")), + _2023: MetricPattern4::new(client.clone(), _m(&acc, "2023_returns")), + _2024: MetricPattern4::new(client.clone(), _m(&acc, "2024_returns")), + _2025: MetricPattern4::new(client.clone(), _m(&acc, "2025_returns")), } } } @@ -3158,46 +1686,16 @@ impl RelativePattern2 { /// Create a new pattern node with accumulated metric name. pub fn new(client: Arc, acc: String) -> Self { Self { - neg_unrealized_loss_rel_to_own_market_cap: MetricPattern1::new( - client.clone(), - _m(&acc, "neg_unrealized_loss_rel_to_own_market_cap"), - ), - neg_unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1::new( - client.clone(), - _m(&acc, "neg_unrealized_loss_rel_to_own_total_unrealized_pnl"), - ), - net_unrealized_pnl_rel_to_own_market_cap: MetricPattern1::new( - client.clone(), - _m(&acc, "net_unrealized_pnl_rel_to_own_market_cap"), - ), - net_unrealized_pnl_rel_to_own_total_unrealized_pnl: MetricPattern1::new( - client.clone(), - _m(&acc, "net_unrealized_pnl_rel_to_own_total_unrealized_pnl"), - ), - supply_in_loss_rel_to_own_supply: MetricPattern1::new( - client.clone(), - _m(&acc, "supply_in_loss_rel_to_own_supply"), - ), - supply_in_profit_rel_to_own_supply: MetricPattern1::new( - client.clone(), - _m(&acc, "supply_in_profit_rel_to_own_supply"), - ), - unrealized_loss_rel_to_own_market_cap: MetricPattern1::new( - client.clone(), - _m(&acc, "unrealized_loss_rel_to_own_market_cap"), - ), - unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1::new( - client.clone(), - _m(&acc, "unrealized_loss_rel_to_own_total_unrealized_pnl"), - ), - unrealized_profit_rel_to_own_market_cap: MetricPattern1::new( - client.clone(), - _m(&acc, "unrealized_profit_rel_to_own_market_cap"), - ), - unrealized_profit_rel_to_own_total_unrealized_pnl: MetricPattern1::new( - client.clone(), - _m(&acc, "unrealized_profit_rel_to_own_total_unrealized_pnl"), - ), + neg_unrealized_loss_rel_to_own_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "neg_unrealized_loss_rel_to_own_market_cap")), + neg_unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1::new(client.clone(), _m(&acc, "neg_unrealized_loss_rel_to_own_total_unrealized_pnl")), + net_unrealized_pnl_rel_to_own_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "net_unrealized_pnl_rel_to_own_market_cap")), + net_unrealized_pnl_rel_to_own_total_unrealized_pnl: MetricPattern1::new(client.clone(), _m(&acc, "net_unrealized_pnl_rel_to_own_total_unrealized_pnl")), + supply_in_loss_rel_to_own_supply: MetricPattern1::new(client.clone(), _m(&acc, "supply_in_loss_rel_to_own_supply")), + supply_in_profit_rel_to_own_supply: MetricPattern1::new(client.clone(), _m(&acc, "supply_in_profit_rel_to_own_supply")), + unrealized_loss_rel_to_own_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_loss_rel_to_own_market_cap")), + unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_loss_rel_to_own_total_unrealized_pnl")), + unrealized_profit_rel_to_own_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_profit_rel_to_own_market_cap")), + unrealized_profit_rel_to_own_total_unrealized_pnl: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_profit_rel_to_own_total_unrealized_pnl")), } } } @@ -3220,43 +1718,16 @@ impl RelativePattern { /// Create a new pattern node with accumulated metric name. pub fn new(client: Arc, acc: String) -> Self { Self { - neg_unrealized_loss_rel_to_market_cap: MetricPattern1::new( - client.clone(), - _m(&acc, "neg_unrealized_loss_rel_to_market_cap"), - ), - net_unrealized_pnl_rel_to_market_cap: MetricPattern1::new( - client.clone(), - _m(&acc, "net_unrealized_pnl_rel_to_market_cap"), - ), + neg_unrealized_loss_rel_to_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "neg_unrealized_loss_rel_to_market_cap")), + net_unrealized_pnl_rel_to_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "net_unrealized_pnl_rel_to_market_cap")), nupl: MetricPattern1::new(client.clone(), _m(&acc, "nupl")), - supply_in_loss_rel_to_circulating_supply: MetricPattern1::new( - client.clone(), - _m(&acc, "supply_in_loss_rel_to_circulating_supply"), - ), - supply_in_loss_rel_to_own_supply: MetricPattern1::new( - client.clone(), - _m(&acc, "supply_in_loss_rel_to_own_supply"), - ), - supply_in_profit_rel_to_circulating_supply: MetricPattern1::new( - client.clone(), - _m(&acc, "supply_in_profit_rel_to_circulating_supply"), - ), - supply_in_profit_rel_to_own_supply: MetricPattern1::new( - client.clone(), - _m(&acc, "supply_in_profit_rel_to_own_supply"), - ), - supply_rel_to_circulating_supply: MetricPattern4::new( - client.clone(), - _m(&acc, "supply_rel_to_circulating_supply"), - ), - unrealized_loss_rel_to_market_cap: MetricPattern1::new( - client.clone(), - _m(&acc, "unrealized_loss_rel_to_market_cap"), - ), - unrealized_profit_rel_to_market_cap: MetricPattern1::new( - client.clone(), - _m(&acc, "unrealized_profit_rel_to_market_cap"), - ), + supply_in_loss_rel_to_circulating_supply: MetricPattern1::new(client.clone(), _m(&acc, "supply_in_loss_rel_to_circulating_supply")), + supply_in_loss_rel_to_own_supply: MetricPattern1::new(client.clone(), _m(&acc, "supply_in_loss_rel_to_own_supply")), + supply_in_profit_rel_to_circulating_supply: MetricPattern1::new(client.clone(), _m(&acc, "supply_in_profit_rel_to_circulating_supply")), + supply_in_profit_rel_to_own_supply: MetricPattern1::new(client.clone(), _m(&acc, "supply_in_profit_rel_to_own_supply")), + supply_rel_to_circulating_supply: MetricPattern4::new(client.clone(), _m(&acc, "supply_rel_to_circulating_supply")), + unrealized_loss_rel_to_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_loss_rel_to_market_cap")), + unrealized_profit_rel_to_market_cap: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_profit_rel_to_market_cap")), } } } @@ -3323,36 +1794,6 @@ impl AddrCountPattern { } } -/// Pattern struct for repeated tree structure. -pub struct FeeRatePattern { - pub average: MetricPattern1, - pub max: MetricPattern1, - pub median: MetricPattern11, - pub min: MetricPattern1, - pub pct10: MetricPattern11, - pub pct25: MetricPattern11, - pub pct75: MetricPattern11, - pub pct90: MetricPattern11, - pub txindex: MetricPattern27, -} - -impl FeeRatePattern { - /// Create a new pattern node with accumulated metric name. - pub fn new(client: Arc, acc: String) -> Self { - Self { - average: MetricPattern1::new(client.clone(), _m(&acc, "average")), - max: MetricPattern1::new(client.clone(), _m(&acc, "max")), - median: MetricPattern11::new(client.clone(), _m(&acc, "median")), - min: MetricPattern1::new(client.clone(), _m(&acc, "min")), - pct10: MetricPattern11::new(client.clone(), _m(&acc, "pct10")), - pct25: MetricPattern11::new(client.clone(), _m(&acc, "pct25")), - pct75: MetricPattern11::new(client.clone(), _m(&acc, "pct75")), - pct90: MetricPattern11::new(client.clone(), _m(&acc, "pct90")), - txindex: MetricPattern27::new(client.clone(), acc.clone()), - } - } -} - /// Pattern struct for repeated tree structure. pub struct FullnessPattern { pub average: MetricPattern2, @@ -3383,6 +1824,36 @@ impl FullnessPattern { } } +/// Pattern struct for repeated tree structure. +pub struct FeeRatePattern { + pub average: MetricPattern1, + pub max: MetricPattern1, + pub median: MetricPattern11, + pub min: MetricPattern1, + pub pct10: MetricPattern11, + pub pct25: MetricPattern11, + pub pct75: MetricPattern11, + pub pct90: MetricPattern11, + pub txindex: MetricPattern27, +} + +impl FeeRatePattern { + /// Create a new pattern node with accumulated metric name. + pub fn new(client: Arc, acc: String) -> Self { + Self { + average: MetricPattern1::new(client.clone(), _m(&acc, "average")), + max: MetricPattern1::new(client.clone(), _m(&acc, "max")), + median: MetricPattern11::new(client.clone(), _m(&acc, "median")), + min: MetricPattern1::new(client.clone(), _m(&acc, "min")), + pct10: MetricPattern11::new(client.clone(), _m(&acc, "pct10")), + pct25: MetricPattern11::new(client.clone(), _m(&acc, "pct25")), + pct75: MetricPattern11::new(client.clone(), _m(&acc, "pct75")), + pct90: MetricPattern11::new(client.clone(), _m(&acc, "pct90")), + txindex: MetricPattern27::new(client.clone(), acc.clone()), + } + } +} + /// Pattern struct for repeated tree structure. pub struct _0satsPattern { pub activity: ActivityPattern2, @@ -3439,32 +1910,6 @@ impl PhaseDailyCentsPattern { } } -/// Pattern struct for repeated tree structure. -pub struct PeriodCagrPattern { - pub _10y: MetricPattern4, - pub _2y: MetricPattern4, - pub _3y: MetricPattern4, - pub _4y: MetricPattern4, - pub _5y: MetricPattern4, - pub _6y: MetricPattern4, - pub _8y: MetricPattern4, -} - -impl PeriodCagrPattern { - /// Create a new pattern node with accumulated metric name. - pub fn new(client: Arc, acc: String) -> Self { - Self { - _10y: MetricPattern4::new(client.clone(), _p("10y", &acc)), - _2y: MetricPattern4::new(client.clone(), _p("2y", &acc)), - _3y: MetricPattern4::new(client.clone(), _p("3y", &acc)), - _4y: MetricPattern4::new(client.clone(), _p("4y", &acc)), - _5y: MetricPattern4::new(client.clone(), _p("5y", &acc)), - _6y: MetricPattern4::new(client.clone(), _p("6y", &acc)), - _8y: MetricPattern4::new(client.clone(), _p("8y", &acc)), - } - } -} - /// Pattern struct for repeated tree structure. pub struct _10yTo12yPattern { pub activity: ActivityPattern2, @@ -3584,26 +2029,43 @@ impl UnrealizedPattern { /// Create a new pattern node with accumulated metric name. pub fn new(client: Arc, acc: String) -> Self { Self { - neg_unrealized_loss: MetricPattern1::new( - client.clone(), - _m(&acc, "neg_unrealized_loss"), - ), + neg_unrealized_loss: MetricPattern1::new(client.clone(), _m(&acc, "neg_unrealized_loss")), net_unrealized_pnl: MetricPattern1::new(client.clone(), _m(&acc, "net_unrealized_pnl")), supply_in_loss: ActiveSupplyPattern::new(client.clone(), _m(&acc, "supply_in_loss")), - supply_in_profit: ActiveSupplyPattern::new( - client.clone(), - _m(&acc, "supply_in_profit"), - ), - total_unrealized_pnl: MetricPattern1::new( - client.clone(), - _m(&acc, "total_unrealized_pnl"), - ), + supply_in_profit: ActiveSupplyPattern::new(client.clone(), _m(&acc, "supply_in_profit")), + total_unrealized_pnl: MetricPattern1::new(client.clone(), _m(&acc, "total_unrealized_pnl")), unrealized_loss: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_loss")), unrealized_profit: MetricPattern1::new(client.clone(), _m(&acc, "unrealized_profit")), } } } +/// Pattern struct for repeated tree structure. +pub struct PeriodCagrPattern { + pub _10y: MetricPattern4, + pub _2y: MetricPattern4, + pub _3y: MetricPattern4, + pub _4y: MetricPattern4, + pub _5y: MetricPattern4, + pub _6y: MetricPattern4, + pub _8y: MetricPattern4, +} + +impl PeriodCagrPattern { + /// Create a new pattern node with accumulated metric name. + pub fn new(client: Arc, acc: String) -> Self { + Self { + _10y: MetricPattern4::new(client.clone(), _p("10y", &acc)), + _2y: MetricPattern4::new(client.clone(), _p("2y", &acc)), + _3y: MetricPattern4::new(client.clone(), _p("3y", &acc)), + _4y: MetricPattern4::new(client.clone(), _p("4y", &acc)), + _5y: MetricPattern4::new(client.clone(), _p("5y", &acc)), + _6y: MetricPattern4::new(client.clone(), _p("6y", &acc)), + _8y: MetricPattern4::new(client.clone(), _p("8y", &acc)), + } + } +} + /// Pattern struct for repeated tree structure. pub struct ActivityPattern2 { pub coinblocks_destroyed: BlockCountPattern, @@ -3617,18 +2079,9 @@ impl ActivityPattern2 { /// Create a new pattern node with accumulated metric name. pub fn new(client: Arc, acc: String) -> Self { Self { - coinblocks_destroyed: BlockCountPattern::new( - client.clone(), - _m(&acc, "coinblocks_destroyed"), - ), - coindays_destroyed: BlockCountPattern::new( - client.clone(), - _m(&acc, "coindays_destroyed"), - ), - satblocks_destroyed: MetricPattern11::new( - client.clone(), - _m(&acc, "satblocks_destroyed"), - ), + coinblocks_destroyed: BlockCountPattern::new(client.clone(), _m(&acc, "coinblocks_destroyed")), + coindays_destroyed: BlockCountPattern::new(client.clone(), _m(&acc, "coindays_destroyed")), + satblocks_destroyed: MetricPattern11::new(client.clone(), _m(&acc, "satblocks_destroyed")), satdays_destroyed: MetricPattern11::new(client.clone(), _m(&acc, "satdays_destroyed")), sent: UnclaimedRewardsPattern::new(client.clone(), _m(&acc, "sent")), } @@ -3656,19 +2109,19 @@ impl SplitPattern2 { } /// Pattern struct for repeated tree structure. -pub struct CoinbasePattern { - pub bitcoin: BitcoinPattern, - pub dollars: DollarsPattern, - pub sats: DollarsPattern, +pub struct CostBasisPattern2 { + pub max: MetricPattern1, + pub min: MetricPattern1, + pub percentiles: PercentilesPattern, } -impl CoinbasePattern { +impl CostBasisPattern2 { /// Create a new pattern node with accumulated metric name. pub fn new(client: Arc, acc: String) -> Self { Self { - bitcoin: BitcoinPattern::new(client.clone(), _m(&acc, "btc")), - dollars: DollarsPattern::new(client.clone(), _m(&acc, "usd")), - sats: DollarsPattern::new(client.clone(), acc.clone()), + max: MetricPattern1::new(client.clone(), _m(&acc, "max_cost_basis")), + min: MetricPattern1::new(client.clone(), _m(&acc, "min_cost_basis")), + percentiles: PercentilesPattern::new(client.clone(), _m(&acc, "cost_basis")), } } } @@ -3691,6 +2144,24 @@ impl CoinbasePattern2 { } } +/// Pattern struct for repeated tree structure. +pub struct ActiveSupplyPattern { + pub bitcoin: MetricPattern1, + pub dollars: MetricPattern1, + pub sats: MetricPattern1, +} + +impl ActiveSupplyPattern { + /// Create a new pattern node with accumulated metric name. + pub fn new(client: Arc, acc: String) -> Self { + Self { + bitcoin: MetricPattern1::new(client.clone(), _m(&acc, "btc")), + dollars: MetricPattern1::new(client.clone(), _m(&acc, "usd")), + sats: MetricPattern1::new(client.clone(), acc.clone()), + } + } +} + /// Pattern struct for repeated tree structure. pub struct SegwitAdoptionPattern { pub base: MetricPattern11, @@ -3709,24 +2180,6 @@ impl SegwitAdoptionPattern { } } -/// Pattern struct for repeated tree structure. -pub struct CostBasisPattern2 { - pub max: MetricPattern1, - pub min: MetricPattern1, - pub percentiles: PercentilesPattern, -} - -impl CostBasisPattern2 { - /// Create a new pattern node with accumulated metric name. - pub fn new(client: Arc, acc: String) -> Self { - Self { - max: MetricPattern1::new(client.clone(), _m(&acc, "max_cost_basis")), - min: MetricPattern1::new(client.clone(), _m(&acc, "min_cost_basis")), - percentiles: PercentilesPattern::new(client.clone(), _m(&acc, "cost_basis")), - } - } -} - /// Pattern struct for repeated tree structure. pub struct UnclaimedRewardsPattern { pub bitcoin: BitcoinPattern2, @@ -3764,19 +2217,19 @@ impl _2015Pattern { } /// Pattern struct for repeated tree structure. -pub struct ActiveSupplyPattern { - pub bitcoin: MetricPattern1, - pub dollars: MetricPattern1, - pub sats: MetricPattern1, +pub struct CoinbasePattern { + pub bitcoin: BitcoinPattern, + pub dollars: DollarsPattern, + pub sats: DollarsPattern, } -impl ActiveSupplyPattern { +impl CoinbasePattern { /// Create a new pattern node with accumulated metric name. pub fn new(client: Arc, acc: String) -> Self { Self { - bitcoin: MetricPattern1::new(client.clone(), _m(&acc, "btc")), - dollars: MetricPattern1::new(client.clone(), _m(&acc, "usd")), - sats: MetricPattern1::new(client.clone(), acc.clone()), + bitcoin: BitcoinPattern::new(client.clone(), _m(&acc, "btc")), + dollars: DollarsPattern::new(client.clone(), _m(&acc, "usd")), + sats: DollarsPattern::new(client.clone(), acc.clone()), } } } @@ -3797,22 +2250,6 @@ impl _1dReturns1mSdPattern { } } -/// Pattern struct for repeated tree structure. -pub struct SupplyPattern2 { - pub halved: ActiveSupplyPattern, - pub total: ActiveSupplyPattern, -} - -impl SupplyPattern2 { - /// Create a new pattern node with accumulated metric name. - pub fn new(client: Arc, acc: String) -> Self { - Self { - halved: ActiveSupplyPattern::new(client.clone(), _m(&acc, "halved")), - total: ActiveSupplyPattern::new(client.clone(), acc.clone()), - } - } -} - /// Pattern struct for repeated tree structure. pub struct CostBasisPattern { pub max: MetricPattern1, @@ -3839,14 +2276,24 @@ impl RelativePattern4 { /// Create a new pattern node with accumulated metric name. pub fn new(client: Arc, acc: String) -> Self { Self { - supply_in_loss_rel_to_own_supply: MetricPattern1::new( - client.clone(), - _m(&acc, "loss_rel_to_own_supply"), - ), - supply_in_profit_rel_to_own_supply: MetricPattern1::new( - client.clone(), - _m(&acc, "profit_rel_to_own_supply"), - ), + supply_in_loss_rel_to_own_supply: MetricPattern1::new(client.clone(), _m(&acc, "loss_rel_to_own_supply")), + supply_in_profit_rel_to_own_supply: MetricPattern1::new(client.clone(), _m(&acc, "profit_rel_to_own_supply")), + } + } +} + +/// Pattern struct for repeated tree structure. +pub struct SupplyPattern2 { + pub halved: ActiveSupplyPattern, + pub total: ActiveSupplyPattern, +} + +impl SupplyPattern2 { + /// Create a new pattern node with accumulated metric name. + pub fn new(client: Arc, acc: String) -> Self { + Self { + halved: ActiveSupplyPattern::new(client.clone(), _m(&acc, "halved")), + total: ActiveSupplyPattern::new(client.clone(), acc.clone()), } } } @@ -3867,22 +2314,6 @@ impl BitcoinPattern2 { } } -/// Pattern struct for repeated tree structure. -pub struct SatsPattern { - pub ohlc: MetricPattern1, - pub split: SplitPattern2, -} - -impl SatsPattern { - /// Create a new pattern node with accumulated metric name. - pub fn new(client: Arc, acc: String) -> Self { - Self { - ohlc: MetricPattern1::new(client.clone(), _m(&acc, "ohlc_sats")), - split: SplitPattern2::new(client.clone(), _m(&acc, "sats")), - } - } -} - /// Pattern struct for repeated tree structure. pub struct BlockCountPattern { pub cumulative: MetricPattern1, @@ -3899,6 +2330,22 @@ impl BlockCountPattern { } } +/// Pattern struct for repeated tree structure. +pub struct SatsPattern { + pub ohlc: MetricPattern1, + pub split: SplitPattern2, +} + +impl SatsPattern { + /// Create a new pattern node with accumulated metric name. + pub fn new(client: Arc, acc: String) -> Self { + Self { + ohlc: MetricPattern1::new(client.clone(), _m(&acc, "ohlc_sats")), + split: SplitPattern2::new(client.clone(), _m(&acc, "sats")), + } + } +} + /// Pattern struct for repeated tree structure. pub struct RealizedPriceExtraPattern { pub ratio: MetricPattern4, @@ -3955,10 +2402,7 @@ impl MetricsTree { blocks: MetricsTree_Blocks::new(client.clone(), format!("{base_path}_blocks")), cointime: MetricsTree_Cointime::new(client.clone(), format!("{base_path}_cointime")), constants: MetricsTree_Constants::new(client.clone(), format!("{base_path}_constants")), - distribution: MetricsTree_Distribution::new( - client.clone(), - format!("{base_path}_distribution"), - ), + distribution: MetricsTree_Distribution::new(client.clone(), format!("{base_path}_distribution")), indexes: MetricsTree_Indexes::new(client.clone(), format!("{base_path}_indexes")), inputs: MetricsTree_Inputs::new(client.clone(), format!("{base_path}_inputs")), market: MetricsTree_Market::new(client.clone(), format!("{base_path}_market")), @@ -3968,10 +2412,7 @@ impl MetricsTree { price: MetricsTree_Price::new(client.clone(), format!("{base_path}_price")), scripts: MetricsTree_Scripts::new(client.clone(), format!("{base_path}_scripts")), supply: MetricsTree_Supply::new(client.clone(), format!("{base_path}_supply")), - transactions: MetricsTree_Transactions::new( - client.clone(), - format!("{base_path}_transactions"), - ), + transactions: MetricsTree_Transactions::new(client.clone(), format!("{base_path}_transactions")), } } } @@ -3999,38 +2440,14 @@ pub struct MetricsTree_Addresses { impl MetricsTree_Addresses { pub fn new(client: Arc, base_path: String) -> Self { Self { - first_p2aaddressindex: MetricPattern11::new( - client.clone(), - "first_p2aaddressindex".to_string(), - ), - first_p2pk33addressindex: MetricPattern11::new( - client.clone(), - "first_p2pk33addressindex".to_string(), - ), - first_p2pk65addressindex: MetricPattern11::new( - client.clone(), - "first_p2pk65addressindex".to_string(), - ), - first_p2pkhaddressindex: MetricPattern11::new( - client.clone(), - "first_p2pkhaddressindex".to_string(), - ), - first_p2shaddressindex: MetricPattern11::new( - client.clone(), - "first_p2shaddressindex".to_string(), - ), - first_p2traddressindex: MetricPattern11::new( - client.clone(), - "first_p2traddressindex".to_string(), - ), - first_p2wpkhaddressindex: MetricPattern11::new( - client.clone(), - "first_p2wpkhaddressindex".to_string(), - ), - first_p2wshaddressindex: MetricPattern11::new( - client.clone(), - "first_p2wshaddressindex".to_string(), - ), + first_p2aaddressindex: MetricPattern11::new(client.clone(), "first_p2aaddressindex".to_string()), + first_p2pk33addressindex: MetricPattern11::new(client.clone(), "first_p2pk33addressindex".to_string()), + first_p2pk65addressindex: MetricPattern11::new(client.clone(), "first_p2pk65addressindex".to_string()), + first_p2pkhaddressindex: MetricPattern11::new(client.clone(), "first_p2pkhaddressindex".to_string()), + first_p2shaddressindex: MetricPattern11::new(client.clone(), "first_p2shaddressindex".to_string()), + first_p2traddressindex: MetricPattern11::new(client.clone(), "first_p2traddressindex".to_string()), + first_p2wpkhaddressindex: MetricPattern11::new(client.clone(), "first_p2wpkhaddressindex".to_string()), + first_p2wshaddressindex: MetricPattern11::new(client.clone(), "first_p2wshaddressindex".to_string()), p2abytes: MetricPattern16::new(client.clone(), "p2abytes".to_string()), p2pk33bytes: MetricPattern18::new(client.clone(), "p2pk33bytes".to_string()), p2pk65bytes: MetricPattern19::new(client.clone(), "p2pk65bytes".to_string()), @@ -4065,21 +2482,12 @@ impl MetricsTree_Blocks { Self { blockhash: MetricPattern11::new(client.clone(), "blockhash".to_string()), count: MetricsTree_Blocks_Count::new(client.clone(), format!("{base_path}_count")), - difficulty: MetricsTree_Blocks_Difficulty::new( - client.clone(), - format!("{base_path}_difficulty"), - ), + difficulty: MetricsTree_Blocks_Difficulty::new(client.clone(), format!("{base_path}_difficulty")), fullness: FullnessPattern::new(client.clone(), "block_fullness".to_string()), - halving: MetricsTree_Blocks_Halving::new( - client.clone(), - format!("{base_path}_halving"), - ), + halving: MetricsTree_Blocks_Halving::new(client.clone(), format!("{base_path}_halving")), interval: FullnessPattern::new(client.clone(), "block_interval".to_string()), mining: MetricsTree_Blocks_Mining::new(client.clone(), format!("{base_path}_mining")), - rewards: MetricsTree_Blocks_Rewards::new( - client.clone(), - format!("{base_path}_rewards"), - ), + rewards: MetricsTree_Blocks_Rewards::new(client.clone(), format!("{base_path}_rewards")), size: MetricsTree_Blocks_Size::new(client.clone(), format!("{base_path}_size")), time: MetricsTree_Blocks_Time::new(client.clone(), format!("{base_path}_time")), total_size: MetricPattern11::new(client.clone(), "total_size".to_string()), @@ -4115,10 +2523,7 @@ impl MetricsTree_Blocks_Count { _24h_block_count: MetricPattern1::new(client.clone(), "24h_block_count".to_string()), _24h_start: MetricPattern11::new(client.clone(), "24h_start".to_string()), block_count: BlockCountPattern::new(client.clone(), "block_count".to_string()), - block_count_target: MetricPattern4::new( - client.clone(), - "block_count_target".to_string(), - ), + block_count_target: MetricPattern4::new(client.clone(), "block_count_target".to_string()), } } } @@ -4138,14 +2543,8 @@ impl MetricsTree_Blocks_Difficulty { Self { adjustment: MetricPattern1::new(client.clone(), "difficulty_adjustment".to_string()), as_hash: MetricPattern1::new(client.clone(), "difficulty_as_hash".to_string()), - blocks_before_next_adjustment: MetricPattern1::new( - client.clone(), - "blocks_before_next_difficulty_adjustment".to_string(), - ), - days_before_next_adjustment: MetricPattern1::new( - client.clone(), - "days_before_next_difficulty_adjustment".to_string(), - ), + blocks_before_next_adjustment: MetricPattern1::new(client.clone(), "blocks_before_next_difficulty_adjustment".to_string()), + days_before_next_adjustment: MetricPattern1::new(client.clone(), "days_before_next_difficulty_adjustment".to_string()), epoch: MetricPattern4::new(client.clone(), "difficultyepoch".to_string()), raw: MetricPattern1::new(client.clone(), "difficulty".to_string()), } @@ -4162,14 +2561,8 @@ pub struct MetricsTree_Blocks_Halving { impl MetricsTree_Blocks_Halving { pub fn new(client: Arc, base_path: String) -> Self { Self { - blocks_before_next_halving: MetricPattern1::new( - client.clone(), - "blocks_before_next_halving".to_string(), - ), - days_before_next_halving: MetricPattern1::new( - client.clone(), - "days_before_next_halving".to_string(), - ), + blocks_before_next_halving: MetricPattern1::new(client.clone(), "blocks_before_next_halving".to_string()), + days_before_next_halving: MetricPattern1::new(client.clone(), "days_before_next_halving".to_string()), epoch: MetricPattern4::new(client.clone(), "halvingepoch".to_string()), } } @@ -4198,38 +2591,20 @@ impl MetricsTree_Blocks_Mining { pub fn new(client: Arc, base_path: String) -> Self { Self { hash_price_phs: MetricPattern1::new(client.clone(), "hash_price_phs".to_string()), - hash_price_phs_min: MetricPattern1::new( - client.clone(), - "hash_price_phs_min".to_string(), - ), - hash_price_rebound: MetricPattern1::new( - client.clone(), - "hash_price_rebound".to_string(), - ), + hash_price_phs_min: MetricPattern1::new(client.clone(), "hash_price_phs_min".to_string()), + hash_price_rebound: MetricPattern1::new(client.clone(), "hash_price_rebound".to_string()), hash_price_ths: MetricPattern1::new(client.clone(), "hash_price_ths".to_string()), - hash_price_ths_min: MetricPattern1::new( - client.clone(), - "hash_price_ths_min".to_string(), - ), + hash_price_ths_min: MetricPattern1::new(client.clone(), "hash_price_ths_min".to_string()), hash_rate: MetricPattern1::new(client.clone(), "hash_rate".to_string()), hash_rate_1m_sma: MetricPattern4::new(client.clone(), "hash_rate_1m_sma".to_string()), hash_rate_1w_sma: MetricPattern4::new(client.clone(), "hash_rate_1w_sma".to_string()), hash_rate_1y_sma: MetricPattern4::new(client.clone(), "hash_rate_1y_sma".to_string()), hash_rate_2m_sma: MetricPattern4::new(client.clone(), "hash_rate_2m_sma".to_string()), hash_value_phs: MetricPattern1::new(client.clone(), "hash_value_phs".to_string()), - hash_value_phs_min: MetricPattern1::new( - client.clone(), - "hash_value_phs_min".to_string(), - ), - hash_value_rebound: MetricPattern1::new( - client.clone(), - "hash_value_rebound".to_string(), - ), + hash_value_phs_min: MetricPattern1::new(client.clone(), "hash_value_phs_min".to_string()), + hash_value_rebound: MetricPattern1::new(client.clone(), "hash_value_rebound".to_string()), hash_value_ths: MetricPattern1::new(client.clone(), "hash_value_ths".to_string()), - hash_value_ths_min: MetricPattern1::new( - client.clone(), - "hash_value_ths_min".to_string(), - ), + hash_value_ths_min: MetricPattern1::new(client.clone(), "hash_value_ths_min".to_string()), } } } @@ -4248,22 +2623,13 @@ pub struct MetricsTree_Blocks_Rewards { impl MetricsTree_Blocks_Rewards { pub fn new(client: Arc, base_path: String) -> Self { Self { - _24h_coinbase_sum: MetricsTree_Blocks_Rewards_24hCoinbaseSum::new( - client.clone(), - format!("{base_path}_24h_coinbase_sum"), - ), + _24h_coinbase_sum: MetricsTree_Blocks_Rewards_24hCoinbaseSum::new(client.clone(), format!("{base_path}_24h_coinbase_sum")), coinbase: CoinbasePattern::new(client.clone(), "coinbase".to_string()), fee_dominance: MetricPattern6::new(client.clone(), "fee_dominance".to_string()), subsidy: CoinbasePattern::new(client.clone(), "subsidy".to_string()), subsidy_dominance: MetricPattern6::new(client.clone(), "subsidy_dominance".to_string()), - subsidy_usd_1y_sma: MetricPattern4::new( - client.clone(), - "subsidy_usd_1y_sma".to_string(), - ), - unclaimed_rewards: UnclaimedRewardsPattern::new( - client.clone(), - "unclaimed_rewards".to_string(), - ), + subsidy_usd_1y_sma: MetricPattern4::new(client.clone(), "subsidy_usd_1y_sma".to_string()), + unclaimed_rewards: UnclaimedRewardsPattern::new(client.clone(), "unclaimed_rewards".to_string()), } } } @@ -4328,10 +2694,7 @@ impl MetricsTree_Blocks_Time { Self { date: MetricPattern11::new(client.clone(), "date".to_string()), timestamp: MetricPattern1::new(client.clone(), "timestamp".to_string()), - timestamp_monotonic: MetricPattern11::new( - client.clone(), - "timestamp_monotonic".to_string(), - ), + timestamp_monotonic: MetricPattern11::new(client.clone(), "timestamp_monotonic".to_string()), } } } @@ -4349,19 +2712,10 @@ pub struct MetricsTree_Cointime { impl MetricsTree_Cointime { pub fn new(client: Arc, base_path: String) -> Self { Self { - activity: MetricsTree_Cointime_Activity::new( - client.clone(), - format!("{base_path}_activity"), - ), - adjusted: MetricsTree_Cointime_Adjusted::new( - client.clone(), - format!("{base_path}_adjusted"), - ), + activity: MetricsTree_Cointime_Activity::new(client.clone(), format!("{base_path}_activity")), + adjusted: MetricsTree_Cointime_Adjusted::new(client.clone(), format!("{base_path}_adjusted")), cap: MetricsTree_Cointime_Cap::new(client.clone(), format!("{base_path}_cap")), - pricing: MetricsTree_Cointime_Pricing::new( - client.clone(), - format!("{base_path}_pricing"), - ), + pricing: MetricsTree_Cointime_Pricing::new(client.clone(), format!("{base_path}_pricing")), supply: MetricsTree_Cointime_Supply::new(client.clone(), format!("{base_path}_supply")), value: MetricsTree_Cointime_Value::new(client.clone(), format!("{base_path}_value")), } @@ -4380,18 +2734,9 @@ pub struct MetricsTree_Cointime_Activity { impl MetricsTree_Cointime_Activity { pub fn new(client: Arc, base_path: String) -> Self { Self { - activity_to_vaultedness_ratio: MetricPattern1::new( - client.clone(), - "activity_to_vaultedness_ratio".to_string(), - ), - coinblocks_created: BlockCountPattern::new( - client.clone(), - "coinblocks_created".to_string(), - ), - coinblocks_stored: BlockCountPattern::new( - client.clone(), - "coinblocks_stored".to_string(), - ), + activity_to_vaultedness_ratio: MetricPattern1::new(client.clone(), "activity_to_vaultedness_ratio".to_string()), + coinblocks_created: BlockCountPattern::new(client.clone(), "coinblocks_created".to_string()), + coinblocks_stored: BlockCountPattern::new(client.clone(), "coinblocks_stored".to_string()), liveliness: MetricPattern1::new(client.clone(), "liveliness".to_string()), vaultedness: MetricPattern1::new(client.clone(), "vaultedness".to_string()), } @@ -4408,18 +2753,9 @@ pub struct MetricsTree_Cointime_Adjusted { impl MetricsTree_Cointime_Adjusted { pub fn new(client: Arc, base_path: String) -> Self { Self { - cointime_adj_inflation_rate: MetricPattern4::new( - client.clone(), - "cointime_adj_inflation_rate".to_string(), - ), - cointime_adj_tx_btc_velocity: MetricPattern4::new( - client.clone(), - "cointime_adj_tx_btc_velocity".to_string(), - ), - cointime_adj_tx_usd_velocity: MetricPattern4::new( - client.clone(), - "cointime_adj_tx_usd_velocity".to_string(), - ), + cointime_adj_inflation_rate: MetricPattern4::new(client.clone(), "cointime_adj_inflation_rate".to_string()), + cointime_adj_tx_btc_velocity: MetricPattern4::new(client.clone(), "cointime_adj_tx_btc_velocity".to_string()), + cointime_adj_tx_usd_velocity: MetricPattern4::new(client.clone(), "cointime_adj_tx_usd_velocity".to_string()), } } } @@ -4461,25 +2797,13 @@ impl MetricsTree_Cointime_Pricing { pub fn new(client: Arc, base_path: String) -> Self { Self { active_price: MetricPattern1::new(client.clone(), "active_price".to_string()), - active_price_ratio: ActivePriceRatioPattern::new( - client.clone(), - "active_price_ratio".to_string(), - ), + active_price_ratio: ActivePriceRatioPattern::new(client.clone(), "active_price_ratio".to_string()), cointime_price: MetricPattern1::new(client.clone(), "cointime_price".to_string()), - cointime_price_ratio: ActivePriceRatioPattern::new( - client.clone(), - "cointime_price_ratio".to_string(), - ), + cointime_price_ratio: ActivePriceRatioPattern::new(client.clone(), "cointime_price_ratio".to_string()), true_market_mean: MetricPattern1::new(client.clone(), "true_market_mean".to_string()), - true_market_mean_ratio: ActivePriceRatioPattern::new( - client.clone(), - "true_market_mean_ratio".to_string(), - ), + true_market_mean_ratio: ActivePriceRatioPattern::new(client.clone(), "true_market_mean_ratio".to_string()), vaulted_price: MetricPattern1::new(client.clone(), "vaulted_price".to_string()), - vaulted_price_ratio: ActivePriceRatioPattern::new( - client.clone(), - "vaulted_price_ratio".to_string(), - ), + vaulted_price_ratio: ActivePriceRatioPattern::new(client.clone(), "vaulted_price_ratio".to_string()), } } } @@ -4509,18 +2833,9 @@ pub struct MetricsTree_Cointime_Value { impl MetricsTree_Cointime_Value { pub fn new(client: Arc, base_path: String) -> Self { Self { - cointime_value_created: BlockCountPattern::new( - client.clone(), - "cointime_value_created".to_string(), - ), - cointime_value_destroyed: BlockCountPattern::new( - client.clone(), - "cointime_value_destroyed".to_string(), - ), - cointime_value_stored: BlockCountPattern::new( - client.clone(), - "cointime_value_stored".to_string(), - ), + cointime_value_created: BlockCountPattern::new(client.clone(), "cointime_value_created".to_string()), + cointime_value_destroyed: BlockCountPattern::new(client.clone(), "cointime_value_destroyed".to_string()), + cointime_value_stored: BlockCountPattern::new(client.clone(), "cointime_value_stored".to_string()), } } } @@ -4541,10 +2856,10 @@ pub struct MetricsTree_Constants { pub constant_61_8: MetricPattern1, pub constant_70: MetricPattern1, pub constant_80: MetricPattern1, - pub constant_minus_1: MetricPattern1, - pub constant_minus_2: MetricPattern1, - pub constant_minus_3: MetricPattern1, - pub constant_minus_4: MetricPattern1, + pub constant_minus_1: MetricPattern1, + pub constant_minus_2: MetricPattern1, + pub constant_minus_3: MetricPattern1, + pub constant_minus_4: MetricPattern1, } impl MetricsTree_Constants { @@ -4589,32 +2904,14 @@ impl MetricsTree_Distribution { pub fn new(client: Arc, base_path: String) -> Self { Self { addr_count: AddrCountPattern::new(client.clone(), "addr_count".to_string()), - address_cohorts: MetricsTree_Distribution_AddressCohorts::new( - client.clone(), - format!("{base_path}_address_cohorts"), - ), - addresses_data: MetricsTree_Distribution_AddressesData::new( - client.clone(), - format!("{base_path}_addresses_data"), - ), - any_address_indexes: MetricsTree_Distribution_AnyAddressIndexes::new( - client.clone(), - format!("{base_path}_any_address_indexes"), - ), + address_cohorts: MetricsTree_Distribution_AddressCohorts::new(client.clone(), format!("{base_path}_address_cohorts")), + addresses_data: MetricsTree_Distribution_AddressesData::new(client.clone(), format!("{base_path}_addresses_data")), + any_address_indexes: MetricsTree_Distribution_AnyAddressIndexes::new(client.clone(), format!("{base_path}_any_address_indexes")), chain_state: MetricPattern11::new(client.clone(), "chain".to_string()), empty_addr_count: AddrCountPattern::new(client.clone(), "empty_addr_count".to_string()), - emptyaddressindex: MetricPattern32::new( - client.clone(), - "emptyaddressindex".to_string(), - ), - loadedaddressindex: MetricPattern31::new( - client.clone(), - "loadedaddressindex".to_string(), - ), - utxo_cohorts: MetricsTree_Distribution_UtxoCohorts::new( - client.clone(), - format!("{base_path}_utxo_cohorts"), - ), + emptyaddressindex: MetricPattern32::new(client.clone(), "emptyaddressindex".to_string()), + loadedaddressindex: MetricPattern31::new(client.clone(), "loadedaddressindex".to_string()), + utxo_cohorts: MetricsTree_Distribution_UtxoCohorts::new(client.clone(), format!("{base_path}_utxo_cohorts")), } } } @@ -4629,18 +2926,9 @@ pub struct MetricsTree_Distribution_AddressCohorts { impl MetricsTree_Distribution_AddressCohorts { pub fn new(client: Arc, base_path: String) -> Self { Self { - amount_range: MetricsTree_Distribution_AddressCohorts_AmountRange::new( - client.clone(), - format!("{base_path}_amount_range"), - ), - ge_amount: MetricsTree_Distribution_AddressCohorts_GeAmount::new( - client.clone(), - format!("{base_path}_ge_amount"), - ), - lt_amount: MetricsTree_Distribution_AddressCohorts_LtAmount::new( - client.clone(), - format!("{base_path}_lt_amount"), - ), + amount_range: MetricsTree_Distribution_AddressCohorts_AmountRange::new(client.clone(), format!("{base_path}_amount_range")), + ge_amount: MetricsTree_Distribution_AddressCohorts_GeAmount::new(client.clone(), format!("{base_path}_ge_amount")), + lt_amount: MetricsTree_Distribution_AddressCohorts_LtAmount::new(client.clone(), format!("{base_path}_lt_amount")), } } } @@ -4668,62 +2956,20 @@ impl MetricsTree_Distribution_AddressCohorts_AmountRange { pub fn new(client: Arc, base_path: String) -> Self { Self { _0sats: _0satsPattern::new(client.clone(), "addrs_with_0sats".to_string()), - _100btc_to_1k_btc: _0satsPattern::new( - client.clone(), - "addrs_above_100btc_under_1k_btc".to_string(), - ), - _100k_btc_or_more: _0satsPattern::new( - client.clone(), - "addrs_above_100k_btc".to_string(), - ), - _100k_sats_to_1m_sats: _0satsPattern::new( - client.clone(), - "addrs_above_100k_sats_under_1m_sats".to_string(), - ), - _100sats_to_1k_sats: _0satsPattern::new( - client.clone(), - "addrs_above_100sats_under_1k_sats".to_string(), - ), - _10btc_to_100btc: _0satsPattern::new( - client.clone(), - "addrs_above_10btc_under_100btc".to_string(), - ), - _10k_btc_to_100k_btc: _0satsPattern::new( - client.clone(), - "addrs_above_10k_btc_under_100k_btc".to_string(), - ), - _10k_sats_to_100k_sats: _0satsPattern::new( - client.clone(), - "addrs_above_10k_sats_under_100k_sats".to_string(), - ), - _10m_sats_to_1btc: _0satsPattern::new( - client.clone(), - "addrs_above_10m_sats_under_1btc".to_string(), - ), - _10sats_to_100sats: _0satsPattern::new( - client.clone(), - "addrs_above_10sats_under_100sats".to_string(), - ), - _1btc_to_10btc: _0satsPattern::new( - client.clone(), - "addrs_above_1btc_under_10btc".to_string(), - ), - _1k_btc_to_10k_btc: _0satsPattern::new( - client.clone(), - "addrs_above_1k_btc_under_10k_btc".to_string(), - ), - _1k_sats_to_10k_sats: _0satsPattern::new( - client.clone(), - "addrs_above_1k_sats_under_10k_sats".to_string(), - ), - _1m_sats_to_10m_sats: _0satsPattern::new( - client.clone(), - "addrs_above_1m_sats_under_10m_sats".to_string(), - ), - _1sat_to_10sats: _0satsPattern::new( - client.clone(), - "addrs_above_1sat_under_10sats".to_string(), - ), + _100btc_to_1k_btc: _0satsPattern::new(client.clone(), "addrs_above_100btc_under_1k_btc".to_string()), + _100k_btc_or_more: _0satsPattern::new(client.clone(), "addrs_above_100k_btc".to_string()), + _100k_sats_to_1m_sats: _0satsPattern::new(client.clone(), "addrs_above_100k_sats_under_1m_sats".to_string()), + _100sats_to_1k_sats: _0satsPattern::new(client.clone(), "addrs_above_100sats_under_1k_sats".to_string()), + _10btc_to_100btc: _0satsPattern::new(client.clone(), "addrs_above_10btc_under_100btc".to_string()), + _10k_btc_to_100k_btc: _0satsPattern::new(client.clone(), "addrs_above_10k_btc_under_100k_btc".to_string()), + _10k_sats_to_100k_sats: _0satsPattern::new(client.clone(), "addrs_above_10k_sats_under_100k_sats".to_string()), + _10m_sats_to_1btc: _0satsPattern::new(client.clone(), "addrs_above_10m_sats_under_1btc".to_string()), + _10sats_to_100sats: _0satsPattern::new(client.clone(), "addrs_above_10sats_under_100sats".to_string()), + _1btc_to_10btc: _0satsPattern::new(client.clone(), "addrs_above_1btc_under_10btc".to_string()), + _1k_btc_to_10k_btc: _0satsPattern::new(client.clone(), "addrs_above_1k_btc_under_10k_btc".to_string()), + _1k_sats_to_10k_sats: _0satsPattern::new(client.clone(), "addrs_above_1k_sats_under_10k_sats".to_string()), + _1m_sats_to_10m_sats: _0satsPattern::new(client.clone(), "addrs_above_1m_sats_under_10m_sats".to_string()), + _1sat_to_10sats: _0satsPattern::new(client.clone(), "addrs_above_1sat_under_10sats".to_string()), } } } @@ -4862,50 +3108,17 @@ pub struct MetricsTree_Distribution_UtxoCohorts { impl MetricsTree_Distribution_UtxoCohorts { pub fn new(client: Arc, base_path: String) -> Self { Self { - age_range: MetricsTree_Distribution_UtxoCohorts_AgeRange::new( - client.clone(), - format!("{base_path}_age_range"), - ), - all: MetricsTree_Distribution_UtxoCohorts_All::new( - client.clone(), - format!("{base_path}_all"), - ), - amount_range: MetricsTree_Distribution_UtxoCohorts_AmountRange::new( - client.clone(), - format!("{base_path}_amount_range"), - ), - epoch: MetricsTree_Distribution_UtxoCohorts_Epoch::new( - client.clone(), - format!("{base_path}_epoch"), - ), - ge_amount: MetricsTree_Distribution_UtxoCohorts_GeAmount::new( - client.clone(), - format!("{base_path}_ge_amount"), - ), - lt_amount: MetricsTree_Distribution_UtxoCohorts_LtAmount::new( - client.clone(), - format!("{base_path}_lt_amount"), - ), - max_age: MetricsTree_Distribution_UtxoCohorts_MaxAge::new( - client.clone(), - format!("{base_path}_max_age"), - ), - min_age: MetricsTree_Distribution_UtxoCohorts_MinAge::new( - client.clone(), - format!("{base_path}_min_age"), - ), - term: MetricsTree_Distribution_UtxoCohorts_Term::new( - client.clone(), - format!("{base_path}_term"), - ), - type_: MetricsTree_Distribution_UtxoCohorts_Type::new( - client.clone(), - format!("{base_path}_type_"), - ), - year: MetricsTree_Distribution_UtxoCohorts_Year::new( - client.clone(), - format!("{base_path}_year"), - ), + age_range: MetricsTree_Distribution_UtxoCohorts_AgeRange::new(client.clone(), format!("{base_path}_age_range")), + all: MetricsTree_Distribution_UtxoCohorts_All::new(client.clone(), format!("{base_path}_all")), + amount_range: MetricsTree_Distribution_UtxoCohorts_AmountRange::new(client.clone(), format!("{base_path}_amount_range")), + epoch: MetricsTree_Distribution_UtxoCohorts_Epoch::new(client.clone(), format!("{base_path}_epoch")), + ge_amount: MetricsTree_Distribution_UtxoCohorts_GeAmount::new(client.clone(), format!("{base_path}_ge_amount")), + lt_amount: MetricsTree_Distribution_UtxoCohorts_LtAmount::new(client.clone(), format!("{base_path}_lt_amount")), + max_age: MetricsTree_Distribution_UtxoCohorts_MaxAge::new(client.clone(), format!("{base_path}_max_age")), + min_age: MetricsTree_Distribution_UtxoCohorts_MinAge::new(client.clone(), format!("{base_path}_min_age")), + term: MetricsTree_Distribution_UtxoCohorts_Term::new(client.clone(), format!("{base_path}_term")), + type_: MetricsTree_Distribution_UtxoCohorts_Type::new(client.clone(), format!("{base_path}_type_")), + year: MetricsTree_Distribution_UtxoCohorts_Year::new(client.clone(), format!("{base_path}_year")), } } } @@ -4938,82 +3151,25 @@ pub struct MetricsTree_Distribution_UtxoCohorts_AgeRange { impl MetricsTree_Distribution_UtxoCohorts_AgeRange { pub fn new(client: Arc, base_path: String) -> Self { Self { - _10y_to_12y: _10yTo12yPattern::new( - client.clone(), - "utxos_at_least_10y_up_to_12y_old".to_string(), - ), - _12y_to_15y: _10yTo12yPattern::new( - client.clone(), - "utxos_at_least_12y_up_to_15y_old".to_string(), - ), - _1d_to_1w: _10yTo12yPattern::new( - client.clone(), - "utxos_at_least_1d_up_to_1w_old".to_string(), - ), - _1h_to_1d: _10yTo12yPattern::new( - client.clone(), - "utxos_at_least_1h_up_to_1d_old".to_string(), - ), - _1m_to_2m: _10yTo12yPattern::new( - client.clone(), - "utxos_at_least_1m_up_to_2m_old".to_string(), - ), - _1w_to_1m: _10yTo12yPattern::new( - client.clone(), - "utxos_at_least_1w_up_to_1m_old".to_string(), - ), - _1y_to_2y: _10yTo12yPattern::new( - client.clone(), - "utxos_at_least_1y_up_to_2y_old".to_string(), - ), - _2m_to_3m: _10yTo12yPattern::new( - client.clone(), - "utxos_at_least_2m_up_to_3m_old".to_string(), - ), - _2y_to_3y: _10yTo12yPattern::new( - client.clone(), - "utxos_at_least_2y_up_to_3y_old".to_string(), - ), - _3m_to_4m: _10yTo12yPattern::new( - client.clone(), - "utxos_at_least_3m_up_to_4m_old".to_string(), - ), - _3y_to_4y: _10yTo12yPattern::new( - client.clone(), - "utxos_at_least_3y_up_to_4y_old".to_string(), - ), - _4m_to_5m: _10yTo12yPattern::new( - client.clone(), - "utxos_at_least_4m_up_to_5m_old".to_string(), - ), - _4y_to_5y: _10yTo12yPattern::new( - client.clone(), - "utxos_at_least_4y_up_to_5y_old".to_string(), - ), - _5m_to_6m: _10yTo12yPattern::new( - client.clone(), - "utxos_at_least_5m_up_to_6m_old".to_string(), - ), - _5y_to_6y: _10yTo12yPattern::new( - client.clone(), - "utxos_at_least_5y_up_to_6y_old".to_string(), - ), - _6m_to_1y: _10yTo12yPattern::new( - client.clone(), - "utxos_at_least_6m_up_to_1y_old".to_string(), - ), - _6y_to_7y: _10yTo12yPattern::new( - client.clone(), - "utxos_at_least_6y_up_to_7y_old".to_string(), - ), - _7y_to_8y: _10yTo12yPattern::new( - client.clone(), - "utxos_at_least_7y_up_to_8y_old".to_string(), - ), - _8y_to_10y: _10yTo12yPattern::new( - client.clone(), - "utxos_at_least_8y_up_to_10y_old".to_string(), - ), + _10y_to_12y: _10yTo12yPattern::new(client.clone(), "utxos_at_least_10y_up_to_12y_old".to_string()), + _12y_to_15y: _10yTo12yPattern::new(client.clone(), "utxos_at_least_12y_up_to_15y_old".to_string()), + _1d_to_1w: _10yTo12yPattern::new(client.clone(), "utxos_at_least_1d_up_to_1w_old".to_string()), + _1h_to_1d: _10yTo12yPattern::new(client.clone(), "utxos_at_least_1h_up_to_1d_old".to_string()), + _1m_to_2m: _10yTo12yPattern::new(client.clone(), "utxos_at_least_1m_up_to_2m_old".to_string()), + _1w_to_1m: _10yTo12yPattern::new(client.clone(), "utxos_at_least_1w_up_to_1m_old".to_string()), + _1y_to_2y: _10yTo12yPattern::new(client.clone(), "utxos_at_least_1y_up_to_2y_old".to_string()), + _2m_to_3m: _10yTo12yPattern::new(client.clone(), "utxos_at_least_2m_up_to_3m_old".to_string()), + _2y_to_3y: _10yTo12yPattern::new(client.clone(), "utxos_at_least_2y_up_to_3y_old".to_string()), + _3m_to_4m: _10yTo12yPattern::new(client.clone(), "utxos_at_least_3m_up_to_4m_old".to_string()), + _3y_to_4y: _10yTo12yPattern::new(client.clone(), "utxos_at_least_3y_up_to_4y_old".to_string()), + _4m_to_5m: _10yTo12yPattern::new(client.clone(), "utxos_at_least_4m_up_to_5m_old".to_string()), + _4y_to_5y: _10yTo12yPattern::new(client.clone(), "utxos_at_least_4y_up_to_5y_old".to_string()), + _5m_to_6m: _10yTo12yPattern::new(client.clone(), "utxos_at_least_5m_up_to_6m_old".to_string()), + _5y_to_6y: _10yTo12yPattern::new(client.clone(), "utxos_at_least_5y_up_to_6y_old".to_string()), + _6m_to_1y: _10yTo12yPattern::new(client.clone(), "utxos_at_least_6m_up_to_1y_old".to_string()), + _6y_to_7y: _10yTo12yPattern::new(client.clone(), "utxos_at_least_6y_up_to_7y_old".to_string()), + _7y_to_8y: _10yTo12yPattern::new(client.clone(), "utxos_at_least_7y_up_to_8y_old".to_string()), + _8y_to_10y: _10yTo12yPattern::new(client.clone(), "utxos_at_least_8y_up_to_10y_old".to_string()), from_15y: _10yTo12yPattern::new(client.clone(), "utxos_at_least_15y_old".to_string()), up_to_1h: _10yTo12yPattern::new(client.clone(), "utxos_up_to_1h_old".to_string()), } @@ -5035,16 +3191,10 @@ impl MetricsTree_Distribution_UtxoCohorts_All { pub fn new(client: Arc, base_path: String) -> Self { Self { activity: ActivityPattern2::new(client.clone(), "".to_string()), - cost_basis: MetricsTree_Distribution_UtxoCohorts_All_CostBasis::new( - client.clone(), - format!("{base_path}_cost_basis"), - ), + cost_basis: MetricsTree_Distribution_UtxoCohorts_All_CostBasis::new(client.clone(), format!("{base_path}_cost_basis")), outputs: OutputsPattern::new(client.clone(), "utxo_count".to_string()), realized: RealizedPattern3::new(client.clone(), "".to_string()), - relative: MetricsTree_Distribution_UtxoCohorts_All_Relative::new( - client.clone(), - format!("{base_path}_relative"), - ), + relative: MetricsTree_Distribution_UtxoCohorts_All_Relative::new(client.clone(), format!("{base_path}_relative")), supply: SupplyPattern2::new(client.clone(), "supply".to_string()), unrealized: UnrealizedPattern::new(client.clone(), "".to_string()), } @@ -5081,30 +3231,12 @@ pub struct MetricsTree_Distribution_UtxoCohorts_All_Relative { impl MetricsTree_Distribution_UtxoCohorts_All_Relative { pub fn new(client: Arc, base_path: String) -> Self { Self { - neg_unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1::new( - client.clone(), - "neg_unrealized_loss_rel_to_own_total_unrealized_pnl".to_string(), - ), - net_unrealized_pnl_rel_to_own_total_unrealized_pnl: MetricPattern1::new( - client.clone(), - "net_unrealized_pnl_rel_to_own_total_unrealized_pnl".to_string(), - ), - supply_in_loss_rel_to_own_supply: MetricPattern1::new( - client.clone(), - "supply_in_loss_rel_to_own_supply".to_string(), - ), - supply_in_profit_rel_to_own_supply: MetricPattern1::new( - client.clone(), - "supply_in_profit_rel_to_own_supply".to_string(), - ), - unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1::new( - client.clone(), - "unrealized_loss_rel_to_own_total_unrealized_pnl".to_string(), - ), - unrealized_profit_rel_to_own_total_unrealized_pnl: MetricPattern1::new( - client.clone(), - "unrealized_profit_rel_to_own_total_unrealized_pnl".to_string(), - ), + neg_unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1::new(client.clone(), "neg_unrealized_loss_rel_to_own_total_unrealized_pnl".to_string()), + net_unrealized_pnl_rel_to_own_total_unrealized_pnl: MetricPattern1::new(client.clone(), "net_unrealized_pnl_rel_to_own_total_unrealized_pnl".to_string()), + supply_in_loss_rel_to_own_supply: MetricPattern1::new(client.clone(), "supply_in_loss_rel_to_own_supply".to_string()), + supply_in_profit_rel_to_own_supply: MetricPattern1::new(client.clone(), "supply_in_profit_rel_to_own_supply".to_string()), + unrealized_loss_rel_to_own_total_unrealized_pnl: MetricPattern1::new(client.clone(), "unrealized_loss_rel_to_own_total_unrealized_pnl".to_string()), + unrealized_profit_rel_to_own_total_unrealized_pnl: MetricPattern1::new(client.clone(), "unrealized_profit_rel_to_own_total_unrealized_pnl".to_string()), } } } @@ -5132,62 +3264,20 @@ impl MetricsTree_Distribution_UtxoCohorts_AmountRange { pub fn new(client: Arc, base_path: String) -> Self { Self { _0sats: _0satsPattern2::new(client.clone(), "utxos_with_0sats".to_string()), - _100btc_to_1k_btc: _0satsPattern2::new( - client.clone(), - "utxos_above_100btc_under_1k_btc".to_string(), - ), - _100k_btc_or_more: _0satsPattern2::new( - client.clone(), - "utxos_above_100k_btc".to_string(), - ), - _100k_sats_to_1m_sats: _0satsPattern2::new( - client.clone(), - "utxos_above_100k_sats_under_1m_sats".to_string(), - ), - _100sats_to_1k_sats: _0satsPattern2::new( - client.clone(), - "utxos_above_100sats_under_1k_sats".to_string(), - ), - _10btc_to_100btc: _0satsPattern2::new( - client.clone(), - "utxos_above_10btc_under_100btc".to_string(), - ), - _10k_btc_to_100k_btc: _0satsPattern2::new( - client.clone(), - "utxos_above_10k_btc_under_100k_btc".to_string(), - ), - _10k_sats_to_100k_sats: _0satsPattern2::new( - client.clone(), - "utxos_above_10k_sats_under_100k_sats".to_string(), - ), - _10m_sats_to_1btc: _0satsPattern2::new( - client.clone(), - "utxos_above_10m_sats_under_1btc".to_string(), - ), - _10sats_to_100sats: _0satsPattern2::new( - client.clone(), - "utxos_above_10sats_under_100sats".to_string(), - ), - _1btc_to_10btc: _0satsPattern2::new( - client.clone(), - "utxos_above_1btc_under_10btc".to_string(), - ), - _1k_btc_to_10k_btc: _0satsPattern2::new( - client.clone(), - "utxos_above_1k_btc_under_10k_btc".to_string(), - ), - _1k_sats_to_10k_sats: _0satsPattern2::new( - client.clone(), - "utxos_above_1k_sats_under_10k_sats".to_string(), - ), - _1m_sats_to_10m_sats: _0satsPattern2::new( - client.clone(), - "utxos_above_1m_sats_under_10m_sats".to_string(), - ), - _1sat_to_10sats: _0satsPattern2::new( - client.clone(), - "utxos_above_1sat_under_10sats".to_string(), - ), + _100btc_to_1k_btc: _0satsPattern2::new(client.clone(), "utxos_above_100btc_under_1k_btc".to_string()), + _100k_btc_or_more: _0satsPattern2::new(client.clone(), "utxos_above_100k_btc".to_string()), + _100k_sats_to_1m_sats: _0satsPattern2::new(client.clone(), "utxos_above_100k_sats_under_1m_sats".to_string()), + _100sats_to_1k_sats: _0satsPattern2::new(client.clone(), "utxos_above_100sats_under_1k_sats".to_string()), + _10btc_to_100btc: _0satsPattern2::new(client.clone(), "utxos_above_10btc_under_100btc".to_string()), + _10k_btc_to_100k_btc: _0satsPattern2::new(client.clone(), "utxos_above_10k_btc_under_100k_btc".to_string()), + _10k_sats_to_100k_sats: _0satsPattern2::new(client.clone(), "utxos_above_10k_sats_under_100k_sats".to_string()), + _10m_sats_to_1btc: _0satsPattern2::new(client.clone(), "utxos_above_10m_sats_under_1btc".to_string()), + _10sats_to_100sats: _0satsPattern2::new(client.clone(), "utxos_above_10sats_under_100sats".to_string()), + _1btc_to_10btc: _0satsPattern2::new(client.clone(), "utxos_above_1btc_under_10btc".to_string()), + _1k_btc_to_10k_btc: _0satsPattern2::new(client.clone(), "utxos_above_1k_btc_under_10k_btc".to_string()), + _1k_sats_to_10k_sats: _0satsPattern2::new(client.clone(), "utxos_above_1k_sats_under_10k_sats".to_string()), + _1m_sats_to_10m_sats: _0satsPattern2::new(client.clone(), "utxos_above_1m_sats_under_10m_sats".to_string()), + _1sat_to_10sats: _0satsPattern2::new(client.clone(), "utxos_above_1sat_under_10sats".to_string()), } } } @@ -5390,14 +3480,8 @@ pub struct MetricsTree_Distribution_UtxoCohorts_Term { impl MetricsTree_Distribution_UtxoCohorts_Term { pub fn new(client: Arc, base_path: String) -> Self { Self { - long: MetricsTree_Distribution_UtxoCohorts_Term_Long::new( - client.clone(), - format!("{base_path}_long"), - ), - short: MetricsTree_Distribution_UtxoCohorts_Term_Short::new( - client.clone(), - format!("{base_path}_short"), - ), + long: MetricsTree_Distribution_UtxoCohorts_Term_Long::new(client.clone(), format!("{base_path}_long")), + short: MetricsTree_Distribution_UtxoCohorts_Term_Short::new(client.clone(), format!("{base_path}_short")), } } } @@ -5553,59 +3637,20 @@ pub struct MetricsTree_Indexes { impl MetricsTree_Indexes { pub fn new(client: Arc, base_path: String) -> Self { Self { - address: MetricsTree_Indexes_Address::new( - client.clone(), - format!("{base_path}_address"), - ), - dateindex: MetricsTree_Indexes_Dateindex::new( - client.clone(), - format!("{base_path}_dateindex"), - ), - decadeindex: MetricsTree_Indexes_Decadeindex::new( - client.clone(), - format!("{base_path}_decadeindex"), - ), - difficultyepoch: MetricsTree_Indexes_Difficultyepoch::new( - client.clone(), - format!("{base_path}_difficultyepoch"), - ), - halvingepoch: MetricsTree_Indexes_Halvingepoch::new( - client.clone(), - format!("{base_path}_halvingepoch"), - ), + address: MetricsTree_Indexes_Address::new(client.clone(), format!("{base_path}_address")), + dateindex: MetricsTree_Indexes_Dateindex::new(client.clone(), format!("{base_path}_dateindex")), + decadeindex: MetricsTree_Indexes_Decadeindex::new(client.clone(), format!("{base_path}_decadeindex")), + difficultyepoch: MetricsTree_Indexes_Difficultyepoch::new(client.clone(), format!("{base_path}_difficultyepoch")), + halvingepoch: MetricsTree_Indexes_Halvingepoch::new(client.clone(), format!("{base_path}_halvingepoch")), height: MetricsTree_Indexes_Height::new(client.clone(), format!("{base_path}_height")), - monthindex: MetricsTree_Indexes_Monthindex::new( - client.clone(), - format!("{base_path}_monthindex"), - ), - quarterindex: MetricsTree_Indexes_Quarterindex::new( - client.clone(), - format!("{base_path}_quarterindex"), - ), - semesterindex: MetricsTree_Indexes_Semesterindex::new( - client.clone(), - format!("{base_path}_semesterindex"), - ), - txindex: MetricsTree_Indexes_Txindex::new( - client.clone(), - format!("{base_path}_txindex"), - ), - txinindex: MetricsTree_Indexes_Txinindex::new( - client.clone(), - format!("{base_path}_txinindex"), - ), - txoutindex: MetricsTree_Indexes_Txoutindex::new( - client.clone(), - format!("{base_path}_txoutindex"), - ), - weekindex: MetricsTree_Indexes_Weekindex::new( - client.clone(), - format!("{base_path}_weekindex"), - ), - yearindex: MetricsTree_Indexes_Yearindex::new( - client.clone(), - format!("{base_path}_yearindex"), - ), + monthindex: MetricsTree_Indexes_Monthindex::new(client.clone(), format!("{base_path}_monthindex")), + quarterindex: MetricsTree_Indexes_Quarterindex::new(client.clone(), format!("{base_path}_quarterindex")), + semesterindex: MetricsTree_Indexes_Semesterindex::new(client.clone(), format!("{base_path}_semesterindex")), + txindex: MetricsTree_Indexes_Txindex::new(client.clone(), format!("{base_path}_txindex")), + txinindex: MetricsTree_Indexes_Txinindex::new(client.clone(), format!("{base_path}_txinindex")), + txoutindex: MetricsTree_Indexes_Txoutindex::new(client.clone(), format!("{base_path}_txoutindex")), + weekindex: MetricsTree_Indexes_Weekindex::new(client.clone(), format!("{base_path}_weekindex")), + yearindex: MetricsTree_Indexes_Yearindex::new(client.clone(), format!("{base_path}_yearindex")), } } } @@ -5629,51 +3674,18 @@ pub struct MetricsTree_Indexes_Address { impl MetricsTree_Indexes_Address { pub fn new(client: Arc, base_path: String) -> Self { Self { - empty: MetricsTree_Indexes_Address_Empty::new( - client.clone(), - format!("{base_path}_empty"), - ), - opreturn: MetricsTree_Indexes_Address_Opreturn::new( - client.clone(), - format!("{base_path}_opreturn"), - ), + empty: MetricsTree_Indexes_Address_Empty::new(client.clone(), format!("{base_path}_empty")), + opreturn: MetricsTree_Indexes_Address_Opreturn::new(client.clone(), format!("{base_path}_opreturn")), p2a: MetricsTree_Indexes_Address_P2a::new(client.clone(), format!("{base_path}_p2a")), - p2ms: MetricsTree_Indexes_Address_P2ms::new( - client.clone(), - format!("{base_path}_p2ms"), - ), - p2pk33: MetricsTree_Indexes_Address_P2pk33::new( - client.clone(), - format!("{base_path}_p2pk33"), - ), - p2pk65: MetricsTree_Indexes_Address_P2pk65::new( - client.clone(), - format!("{base_path}_p2pk65"), - ), - p2pkh: MetricsTree_Indexes_Address_P2pkh::new( - client.clone(), - format!("{base_path}_p2pkh"), - ), - p2sh: MetricsTree_Indexes_Address_P2sh::new( - client.clone(), - format!("{base_path}_p2sh"), - ), - p2tr: MetricsTree_Indexes_Address_P2tr::new( - client.clone(), - format!("{base_path}_p2tr"), - ), - p2wpkh: MetricsTree_Indexes_Address_P2wpkh::new( - client.clone(), - format!("{base_path}_p2wpkh"), - ), - p2wsh: MetricsTree_Indexes_Address_P2wsh::new( - client.clone(), - format!("{base_path}_p2wsh"), - ), - unknown: MetricsTree_Indexes_Address_Unknown::new( - client.clone(), - format!("{base_path}_unknown"), - ), + p2ms: MetricsTree_Indexes_Address_P2ms::new(client.clone(), format!("{base_path}_p2ms")), + p2pk33: MetricsTree_Indexes_Address_P2pk33::new(client.clone(), format!("{base_path}_p2pk33")), + p2pk65: MetricsTree_Indexes_Address_P2pk65::new(client.clone(), format!("{base_path}_p2pk65")), + p2pkh: MetricsTree_Indexes_Address_P2pkh::new(client.clone(), format!("{base_path}_p2pkh")), + p2sh: MetricsTree_Indexes_Address_P2sh::new(client.clone(), format!("{base_path}_p2sh")), + p2tr: MetricsTree_Indexes_Address_P2tr::new(client.clone(), format!("{base_path}_p2tr")), + p2wpkh: MetricsTree_Indexes_Address_P2wpkh::new(client.clone(), format!("{base_path}_p2wpkh")), + p2wsh: MetricsTree_Indexes_Address_P2wsh::new(client.clone(), format!("{base_path}_p2wsh")), + unknown: MetricsTree_Indexes_Address_Unknown::new(client.clone(), format!("{base_path}_unknown")), } } } @@ -6132,24 +4144,12 @@ impl MetricsTree_Market { Self { ath: MetricsTree_Market_Ath::new(client.clone(), format!("{base_path}_ath")), dca: MetricsTree_Market_Dca::new(client.clone(), format!("{base_path}_dca")), - indicators: MetricsTree_Market_Indicators::new( - client.clone(), - format!("{base_path}_indicators"), - ), + indicators: MetricsTree_Market_Indicators::new(client.clone(), format!("{base_path}_indicators")), lookback: LookbackPattern::new(client.clone(), "price".to_string()), - moving_average: MetricsTree_Market_MovingAverage::new( - client.clone(), - format!("{base_path}_moving_average"), - ), + moving_average: MetricsTree_Market_MovingAverage::new(client.clone(), format!("{base_path}_moving_average")), range: MetricsTree_Market_Range::new(client.clone(), format!("{base_path}_range")), - returns: MetricsTree_Market_Returns::new( - client.clone(), - format!("{base_path}_returns"), - ), - volatility: MetricsTree_Market_Volatility::new( - client.clone(), - format!("{base_path}_volatility"), - ), + returns: MetricsTree_Market_Returns::new(client.clone(), format!("{base_path}_returns")), + volatility: MetricsTree_Market_Volatility::new(client.clone(), format!("{base_path}_volatility")), } } } @@ -6167,32 +4167,20 @@ pub struct MetricsTree_Market_Ath { impl MetricsTree_Market_Ath { pub fn new(client: Arc, base_path: String) -> Self { Self { - days_since_price_ath: MetricPattern4::new( - client.clone(), - "days_since_price_ath".to_string(), - ), - max_days_between_price_aths: MetricPattern4::new( - client.clone(), - "max_days_between_price_aths".to_string(), - ), - max_years_between_price_aths: MetricPattern4::new( - client.clone(), - "max_years_between_price_aths".to_string(), - ), + days_since_price_ath: MetricPattern4::new(client.clone(), "days_since_price_ath".to_string()), + max_days_between_price_aths: MetricPattern4::new(client.clone(), "max_days_between_price_aths".to_string()), + max_years_between_price_aths: MetricPattern4::new(client.clone(), "max_years_between_price_aths".to_string()), price_ath: MetricPattern1::new(client.clone(), "price_ath".to_string()), price_drawdown: MetricPattern3::new(client.clone(), "price_drawdown".to_string()), - years_since_price_ath: MetricPattern4::new( - client.clone(), - "years_since_price_ath".to_string(), - ), + years_since_price_ath: MetricPattern4::new(client.clone(), "years_since_price_ath".to_string()), } } } /// Metrics tree node. pub struct MetricsTree_Market_Dca { - pub class_average_price: ClassAveragePricePattern, - pub class_returns: MetricsTree_Market_Dca_ClassReturns, + pub class_average_price: MetricsTree_Market_Dca_ClassAveragePrice, + pub class_returns: ClassAveragePricePattern, pub class_stack: MetricsTree_Market_Dca_ClassStack, pub period_average_price: PeriodAveragePricePattern, pub period_cagr: PeriodCagrPattern, @@ -6204,65 +4192,47 @@ pub struct MetricsTree_Market_Dca { impl MetricsTree_Market_Dca { pub fn new(client: Arc, base_path: String) -> Self { Self { - class_average_price: ClassAveragePricePattern::new( - client.clone(), - "dca_class".to_string(), - ), - class_returns: MetricsTree_Market_Dca_ClassReturns::new( - client.clone(), - format!("{base_path}_class_returns"), - ), - class_stack: MetricsTree_Market_Dca_ClassStack::new( - client.clone(), - format!("{base_path}_class_stack"), - ), - period_average_price: PeriodAveragePricePattern::new( - client.clone(), - "dca_average_price".to_string(), - ), + class_average_price: MetricsTree_Market_Dca_ClassAveragePrice::new(client.clone(), format!("{base_path}_class_average_price")), + class_returns: ClassAveragePricePattern::new(client.clone(), "dca_class".to_string()), + class_stack: MetricsTree_Market_Dca_ClassStack::new(client.clone(), format!("{base_path}_class_stack")), + period_average_price: PeriodAveragePricePattern::new(client.clone(), "dca_average_price".to_string()), period_cagr: PeriodCagrPattern::new(client.clone(), "dca_cagr".to_string()), - period_lump_sum_stack: PeriodLumpSumStackPattern::new( - client.clone(), - "lump_sum_stack".to_string(), - ), - period_returns: PeriodAveragePricePattern::new( - client.clone(), - "dca_returns".to_string(), - ), + period_lump_sum_stack: PeriodLumpSumStackPattern::new(client.clone(), "lump_sum_stack".to_string()), + period_returns: PeriodAveragePricePattern::new(client.clone(), "dca_returns".to_string()), period_stack: PeriodLumpSumStackPattern::new(client.clone(), "dca_stack".to_string()), } } } /// Metrics tree node. -pub struct MetricsTree_Market_Dca_ClassReturns { - pub _2015: MetricPattern4, - pub _2016: MetricPattern4, - pub _2017: MetricPattern4, - pub _2018: MetricPattern4, - pub _2019: MetricPattern4, - pub _2020: MetricPattern4, - pub _2021: MetricPattern4, - pub _2022: MetricPattern4, - pub _2023: MetricPattern4, - pub _2024: MetricPattern4, - pub _2025: MetricPattern4, +pub struct MetricsTree_Market_Dca_ClassAveragePrice { + pub _2015: MetricPattern4, + pub _2016: MetricPattern4, + pub _2017: MetricPattern4, + pub _2018: MetricPattern4, + pub _2019: MetricPattern4, + pub _2020: MetricPattern4, + pub _2021: MetricPattern4, + pub _2022: MetricPattern4, + pub _2023: MetricPattern4, + pub _2024: MetricPattern4, + pub _2025: MetricPattern4, } -impl MetricsTree_Market_Dca_ClassReturns { +impl MetricsTree_Market_Dca_ClassAveragePrice { pub fn new(client: Arc, base_path: String) -> Self { Self { - _2015: MetricPattern4::new(client.clone(), "dca_class_2015_returns".to_string()), - _2016: MetricPattern4::new(client.clone(), "dca_class_2016_returns".to_string()), - _2017: MetricPattern4::new(client.clone(), "dca_class_2017_returns".to_string()), - _2018: MetricPattern4::new(client.clone(), "dca_class_2018_returns".to_string()), - _2019: MetricPattern4::new(client.clone(), "dca_class_2019_returns".to_string()), - _2020: MetricPattern4::new(client.clone(), "dca_class_2020_returns".to_string()), - _2021: MetricPattern4::new(client.clone(), "dca_class_2021_returns".to_string()), - _2022: MetricPattern4::new(client.clone(), "dca_class_2022_returns".to_string()), - _2023: MetricPattern4::new(client.clone(), "dca_class_2023_returns".to_string()), - _2024: MetricPattern4::new(client.clone(), "dca_class_2024_returns".to_string()), - _2025: MetricPattern4::new(client.clone(), "dca_class_2025_returns".to_string()), + _2015: MetricPattern4::new(client.clone(), "dca_class_2015_average_price".to_string()), + _2016: MetricPattern4::new(client.clone(), "dca_class_2016_average_price".to_string()), + _2017: MetricPattern4::new(client.clone(), "dca_class_2017_average_price".to_string()), + _2018: MetricPattern4::new(client.clone(), "dca_class_2018_average_price".to_string()), + _2019: MetricPattern4::new(client.clone(), "dca_class_2019_average_price".to_string()), + _2020: MetricPattern4::new(client.clone(), "dca_class_2020_average_price".to_string()), + _2021: MetricPattern4::new(client.clone(), "dca_class_2021_average_price".to_string()), + _2022: MetricPattern4::new(client.clone(), "dca_class_2022_average_price".to_string()), + _2023: MetricPattern4::new(client.clone(), "dca_class_2023_average_price".to_string()), + _2024: MetricPattern4::new(client.clone(), "dca_class_2024_average_price".to_string()), + _2025: MetricPattern4::new(client.clone(), "dca_class_2025_average_price".to_string()), } } } @@ -6336,14 +4306,8 @@ impl MetricsTree_Market_Indicators { rsi_14d: MetricPattern6::new(client.clone(), "rsi_14d".to_string()), rsi_14d_max: MetricPattern6::new(client.clone(), "rsi_14d_max".to_string()), rsi_14d_min: MetricPattern6::new(client.clone(), "rsi_14d_min".to_string()), - rsi_average_gain_14d: MetricPattern6::new( - client.clone(), - "rsi_average_gain_14d".to_string(), - ), - rsi_average_loss_14d: MetricPattern6::new( - client.clone(), - "rsi_average_loss_14d".to_string(), - ), + rsi_average_gain_14d: MetricPattern6::new(client.clone(), "rsi_average_gain_14d".to_string()), + rsi_average_loss_14d: MetricPattern6::new(client.clone(), "rsi_average_loss_14d".to_string()), rsi_gains: MetricPattern6::new(client.clone(), "rsi_gains".to_string()), rsi_losses: MetricPattern6::new(client.clone(), "rsi_losses".to_string()), stoch_d: MetricPattern6::new(client.clone(), "stoch_d".to_string()), @@ -6411,14 +4375,8 @@ impl MetricsTree_Market_MovingAverage { price_1y_sma: Price111dSmaPattern::new(client.clone(), "price_1y_sma".to_string()), price_200d_ema: Price111dSmaPattern::new(client.clone(), "price_200d_ema".to_string()), price_200d_sma: Price111dSmaPattern::new(client.clone(), "price_200d_sma".to_string()), - price_200d_sma_x0_8: MetricPattern4::new( - client.clone(), - "price_200d_sma_x0_8".to_string(), - ), - price_200d_sma_x2_4: MetricPattern4::new( - client.clone(), - "price_200d_sma_x2_4".to_string(), - ), + price_200d_sma_x0_8: MetricPattern4::new(client.clone(), "price_200d_sma_x0_8".to_string()), + price_200d_sma_x2_4: MetricPattern4::new(client.clone(), "price_200d_sma_x2_4".to_string()), price_200w_ema: Price111dSmaPattern::new(client.clone(), "price_200w_ema".to_string()), price_200w_sma: Price111dSmaPattern::new(client.clone(), "price_200w_sma".to_string()), price_21d_ema: Price111dSmaPattern::new(client.clone(), "price_21d_ema".to_string()), @@ -6466,17 +4424,11 @@ impl MetricsTree_Market_Range { price_1w_min: MetricPattern4::new(client.clone(), "price_1w_min".to_string()), price_1y_max: MetricPattern4::new(client.clone(), "price_1y_max".to_string()), price_1y_min: MetricPattern4::new(client.clone(), "price_1y_min".to_string()), - price_2w_choppiness_index: MetricPattern4::new( - client.clone(), - "price_2w_choppiness_index".to_string(), - ), + price_2w_choppiness_index: MetricPattern4::new(client.clone(), "price_2w_choppiness_index".to_string()), price_2w_max: MetricPattern4::new(client.clone(), "price_2w_max".to_string()), price_2w_min: MetricPattern4::new(client.clone(), "price_2w_min".to_string()), price_true_range: MetricPattern6::new(client.clone(), "price_true_range".to_string()), - price_true_range_2w_sum: MetricPattern6::new( - client.clone(), - "price_true_range_2w_sum".to_string(), - ), + price_true_range_2w_sum: MetricPattern6::new(client.clone(), "price_true_range_2w_sum".to_string()), } } } @@ -6497,36 +4449,15 @@ pub struct MetricsTree_Market_Returns { impl MetricsTree_Market_Returns { pub fn new(client: Arc, base_path: String) -> Self { Self { - _1d_returns_1m_sd: _1dReturns1mSdPattern::new( - client.clone(), - "1d_returns_1m_sd".to_string(), - ), - _1d_returns_1w_sd: _1dReturns1mSdPattern::new( - client.clone(), - "1d_returns_1w_sd".to_string(), - ), - _1d_returns_1y_sd: _1dReturns1mSdPattern::new( - client.clone(), - "1d_returns_1y_sd".to_string(), - ), + _1d_returns_1m_sd: _1dReturns1mSdPattern::new(client.clone(), "1d_returns_1m_sd".to_string()), + _1d_returns_1w_sd: _1dReturns1mSdPattern::new(client.clone(), "1d_returns_1w_sd".to_string()), + _1d_returns_1y_sd: _1dReturns1mSdPattern::new(client.clone(), "1d_returns_1y_sd".to_string()), cagr: PeriodCagrPattern::new(client.clone(), "cagr".to_string()), - downside_1m_sd: _1dReturns1mSdPattern::new( - client.clone(), - "downside_1m_sd".to_string(), - ), - downside_1w_sd: _1dReturns1mSdPattern::new( - client.clone(), - "downside_1w_sd".to_string(), - ), - downside_1y_sd: _1dReturns1mSdPattern::new( - client.clone(), - "downside_1y_sd".to_string(), - ), + downside_1m_sd: _1dReturns1mSdPattern::new(client.clone(), "downside_1m_sd".to_string()), + downside_1w_sd: _1dReturns1mSdPattern::new(client.clone(), "downside_1w_sd".to_string()), + downside_1y_sd: _1dReturns1mSdPattern::new(client.clone(), "downside_1y_sd".to_string()), downside_returns: MetricPattern6::new(client.clone(), "downside_returns".to_string()), - price_returns: MetricsTree_Market_Returns_PriceReturns::new( - client.clone(), - format!("{base_path}_price_returns"), - ), + price_returns: MetricsTree_Market_Returns_PriceReturns::new(client.clone(), format!("{base_path}_price_returns")), } } } @@ -6584,18 +4515,9 @@ pub struct MetricsTree_Market_Volatility { impl MetricsTree_Market_Volatility { pub fn new(client: Arc, base_path: String) -> Self { Self { - price_1m_volatility: MetricPattern4::new( - client.clone(), - "price_1m_volatility".to_string(), - ), - price_1w_volatility: MetricPattern4::new( - client.clone(), - "price_1w_volatility".to_string(), - ), - price_1y_volatility: MetricPattern4::new( - client.clone(), - "price_1y_volatility".to_string(), - ), + price_1m_volatility: MetricPattern4::new(client.clone(), "price_1m_volatility".to_string()), + price_1w_volatility: MetricPattern4::new(client.clone(), "price_1w_volatility".to_string()), + price_1y_volatility: MetricPattern4::new(client.clone(), "price_1y_volatility".to_string()), sharpe_1m: MetricPattern6::new(client.clone(), "sharpe_1m".to_string()), sharpe_1w: MetricPattern6::new(client.clone(), "sharpe_1w".to_string()), sharpe_1y: MetricPattern6::new(client.clone(), "sharpe_1y".to_string()), @@ -6850,10 +4772,7 @@ impl MetricsTree_Pools_Vecs { binancepool: AaopoolPattern::new(client.clone(), "binancepool".to_string()), bitalo: AaopoolPattern::new(client.clone(), "bitalo".to_string()), bitclub: AaopoolPattern::new(client.clone(), "bitclub".to_string()), - bitcoinaffiliatenetwork: AaopoolPattern::new( - client.clone(), - "bitcoinaffiliatenetwork".to_string(), - ), + bitcoinaffiliatenetwork: AaopoolPattern::new(client.clone(), "bitcoinaffiliatenetwork".to_string()), bitcoincom: AaopoolPattern::new(client.clone(), "bitcoincom".to_string()), bitcoinindia: AaopoolPattern::new(client.clone(), "bitcoinindia".to_string()), bitcoinrussia: AaopoolPattern::new(client.clone(), "bitcoinrussia".to_string()), @@ -6899,19 +4818,13 @@ impl MetricsTree_Pools_Vecs { ekanembtc: AaopoolPattern::new(client.clone(), "ekanembtc".to_string()), eligius: AaopoolPattern::new(client.clone(), "eligius".to_string()), emcdpool: AaopoolPattern::new(client.clone(), "emcdpool".to_string()), - entrustcharitypool: AaopoolPattern::new( - client.clone(), - "entrustcharitypool".to_string(), - ), + entrustcharitypool: AaopoolPattern::new(client.clone(), "entrustcharitypool".to_string()), eobot: AaopoolPattern::new(client.clone(), "eobot".to_string()), exxbw: AaopoolPattern::new(client.clone(), "exxbw".to_string()), f2pool: AaopoolPattern::new(client.clone(), "f2pool".to_string()), fiftyeightcoin: AaopoolPattern::new(client.clone(), "fiftyeightcoin".to_string()), foundryusa: AaopoolPattern::new(client.clone(), "foundryusa".to_string()), - futurebitapollosolo: AaopoolPattern::new( - client.clone(), - "futurebitapollosolo".to_string(), - ), + futurebitapollosolo: AaopoolPattern::new(client.clone(), "futurebitapollosolo".to_string()), gbminers: AaopoolPattern::new(client.clone(), "gbminers".to_string()), ghashio: AaopoolPattern::new(client.clone(), "ghashio".to_string()), givemecoins: AaopoolPattern::new(client.clone(), "givemecoins".to_string()), @@ -6992,10 +4905,7 @@ impl MetricsTree_Pools_Vecs { tiger: AaopoolPattern::new(client.clone(), "tiger".to_string()), tigerpoolnet: AaopoolPattern::new(client.clone(), "tigerpoolnet".to_string()), titan: AaopoolPattern::new(client.clone(), "titan".to_string()), - transactioncoinmining: AaopoolPattern::new( - client.clone(), - "transactioncoinmining".to_string(), - ), + transactioncoinmining: AaopoolPattern::new(client.clone(), "transactioncoinmining".to_string()), trickysbtcpool: AaopoolPattern::new(client.clone(), "trickysbtcpool".to_string()), triplemining: AaopoolPattern::new(client.clone(), "triplemining".to_string()), twentyoneinc: AaopoolPattern::new(client.clone(), "twentyoneinc".to_string()), @@ -7114,87 +5024,30 @@ pub struct MetricsTree_Price_Oracle { impl MetricsTree_Price_Oracle { pub fn new(client: Arc, base_path: String) -> Self { Self { - height_to_first_pairoutputindex: MetricPattern11::new( - client.clone(), - "height_to_first_pairoutputindex".to_string(), - ), + height_to_first_pairoutputindex: MetricPattern11::new(client.clone(), "height_to_first_pairoutputindex".to_string()), ohlc_cents: MetricPattern6::new(client.clone(), "oracle_ohlc_cents".to_string()), ohlc_dollars: MetricPattern6::new(client.clone(), "oracle_ohlc".to_string()), output0_value: MetricPattern33::new(client.clone(), "pair_output0_value".to_string()), output1_value: MetricPattern33::new(client.clone(), "pair_output1_value".to_string()), - pairoutputindex_to_txindex: MetricPattern33::new( - client.clone(), - "pairoutputindex_to_txindex".to_string(), - ), - phase_daily_cents: PhaseDailyCentsPattern::new( - client.clone(), - "phase_daily".to_string(), - ), - phase_daily_dollars: PhaseDailyCentsPattern::new( - client.clone(), - "phase_daily_dollars".to_string(), - ), + pairoutputindex_to_txindex: MetricPattern33::new(client.clone(), "pairoutputindex_to_txindex".to_string()), + phase_daily_cents: PhaseDailyCentsPattern::new(client.clone(), "phase_daily".to_string()), + phase_daily_dollars: PhaseDailyCentsPattern::new(client.clone(), "phase_daily_dollars".to_string()), phase_histogram: MetricPattern11::new(client.clone(), "phase_histogram".to_string()), - phase_price_cents: MetricPattern11::new( - client.clone(), - "phase_price_cents".to_string(), - ), - phase_v2_daily_cents: PhaseDailyCentsPattern::new( - client.clone(), - "phase_v2_daily".to_string(), - ), - phase_v2_daily_dollars: PhaseDailyCentsPattern::new( - client.clone(), - "phase_v2_daily_dollars".to_string(), - ), - phase_v2_histogram: MetricPattern11::new( - client.clone(), - "phase_v2_histogram".to_string(), - ), - phase_v2_peak_daily_cents: PhaseDailyCentsPattern::new( - client.clone(), - "phase_v2_peak_daily".to_string(), - ), - phase_v2_peak_daily_dollars: PhaseDailyCentsPattern::new( - client.clone(), - "phase_v2_peak_daily_dollars".to_string(), - ), - phase_v2_peak_price_cents: MetricPattern11::new( - client.clone(), - "phase_v2_peak_price_cents".to_string(), - ), - phase_v2_price_cents: MetricPattern11::new( - client.clone(), - "phase_v2_price_cents".to_string(), - ), - phase_v3_daily_cents: PhaseDailyCentsPattern::new( - client.clone(), - "phase_v3_daily".to_string(), - ), - phase_v3_daily_dollars: PhaseDailyCentsPattern::new( - client.clone(), - "phase_v3_daily_dollars".to_string(), - ), - phase_v3_histogram: MetricPattern11::new( - client.clone(), - "phase_v3_histogram".to_string(), - ), - phase_v3_peak_daily_cents: PhaseDailyCentsPattern::new( - client.clone(), - "phase_v3_peak_daily".to_string(), - ), - phase_v3_peak_daily_dollars: PhaseDailyCentsPattern::new( - client.clone(), - "phase_v3_peak_daily_dollars".to_string(), - ), - phase_v3_peak_price_cents: MetricPattern11::new( - client.clone(), - "phase_v3_peak_price_cents".to_string(), - ), - phase_v3_price_cents: MetricPattern11::new( - client.clone(), - "phase_v3_price_cents".to_string(), - ), + phase_price_cents: MetricPattern11::new(client.clone(), "phase_price_cents".to_string()), + phase_v2_daily_cents: PhaseDailyCentsPattern::new(client.clone(), "phase_v2_daily".to_string()), + phase_v2_daily_dollars: PhaseDailyCentsPattern::new(client.clone(), "phase_v2_daily_dollars".to_string()), + phase_v2_histogram: MetricPattern11::new(client.clone(), "phase_v2_histogram".to_string()), + phase_v2_peak_daily_cents: PhaseDailyCentsPattern::new(client.clone(), "phase_v2_peak_daily".to_string()), + phase_v2_peak_daily_dollars: PhaseDailyCentsPattern::new(client.clone(), "phase_v2_peak_daily_dollars".to_string()), + phase_v2_peak_price_cents: MetricPattern11::new(client.clone(), "phase_v2_peak_price_cents".to_string()), + phase_v2_price_cents: MetricPattern11::new(client.clone(), "phase_v2_price_cents".to_string()), + phase_v3_daily_cents: PhaseDailyCentsPattern::new(client.clone(), "phase_v3_daily".to_string()), + phase_v3_daily_dollars: PhaseDailyCentsPattern::new(client.clone(), "phase_v3_daily_dollars".to_string()), + phase_v3_histogram: MetricPattern11::new(client.clone(), "phase_v3_histogram".to_string()), + phase_v3_peak_daily_cents: PhaseDailyCentsPattern::new(client.clone(), "phase_v3_peak_daily".to_string()), + phase_v3_peak_daily_dollars: PhaseDailyCentsPattern::new(client.clone(), "phase_v3_peak_daily_dollars".to_string()), + phase_v3_peak_price_cents: MetricPattern11::new(client.clone(), "phase_v3_peak_price_cents".to_string()), + phase_v3_price_cents: MetricPattern11::new(client.clone(), "phase_v3_price_cents".to_string()), price_cents: MetricPattern11::new(client.clone(), "oracle_price_cents".to_string()), tx_count: MetricPattern6::new(client.clone(), "oracle_tx_count".to_string()), } @@ -7235,22 +5088,10 @@ impl MetricsTree_Scripts { Self { count: MetricsTree_Scripts_Count::new(client.clone(), format!("{base_path}_count")), empty_to_txindex: MetricPattern9::new(client.clone(), "txindex".to_string()), - first_emptyoutputindex: MetricPattern11::new( - client.clone(), - "first_emptyoutputindex".to_string(), - ), - first_opreturnindex: MetricPattern11::new( - client.clone(), - "first_opreturnindex".to_string(), - ), - first_p2msoutputindex: MetricPattern11::new( - client.clone(), - "first_p2msoutputindex".to_string(), - ), - first_unknownoutputindex: MetricPattern11::new( - client.clone(), - "first_unknownoutputindex".to_string(), - ), + first_emptyoutputindex: MetricPattern11::new(client.clone(), "first_emptyoutputindex".to_string()), + first_opreturnindex: MetricPattern11::new(client.clone(), "first_opreturnindex".to_string()), + first_p2msoutputindex: MetricPattern11::new(client.clone(), "first_p2msoutputindex".to_string()), + first_unknownoutputindex: MetricPattern11::new(client.clone(), "first_unknownoutputindex".to_string()), opreturn_to_txindex: MetricPattern14::new(client.clone(), "txindex".to_string()), p2ms_to_txindex: MetricPattern17::new(client.clone(), "txindex".to_string()), unknown_to_txindex: MetricPattern28::new(client.clone(), "txindex".to_string()), @@ -7293,14 +5134,8 @@ impl MetricsTree_Scripts_Count { p2wpkh: DollarsPattern::new(client.clone(), "p2wpkh_count".to_string()), p2wsh: DollarsPattern::new(client.clone(), "p2wsh_count".to_string()), segwit: DollarsPattern::new(client.clone(), "segwit_count".to_string()), - segwit_adoption: SegwitAdoptionPattern::new( - client.clone(), - "segwit_adoption".to_string(), - ), - taproot_adoption: SegwitAdoptionPattern::new( - client.clone(), - "taproot_adoption".to_string(), - ), + segwit_adoption: SegwitAdoptionPattern::new(client.clone(), "segwit_adoption".to_string()), + taproot_adoption: SegwitAdoptionPattern::new(client.clone(), "taproot_adoption".to_string()), unknownoutput: DollarsPattern::new(client.clone(), "unknownoutput_count".to_string()), } } @@ -7332,16 +5167,10 @@ impl MetricsTree_Supply { pub fn new(client: Arc, base_path: String) -> Self { Self { burned: MetricsTree_Supply_Burned::new(client.clone(), format!("{base_path}_burned")), - circulating: MetricsTree_Supply_Circulating::new( - client.clone(), - format!("{base_path}_circulating"), - ), + circulating: MetricsTree_Supply_Circulating::new(client.clone(), format!("{base_path}_circulating")), inflation: MetricPattern4::new(client.clone(), "inflation_rate".to_string()), market_cap: MetricPattern1::new(client.clone(), "market_cap".to_string()), - velocity: MetricsTree_Supply_Velocity::new( - client.clone(), - format!("{base_path}_velocity"), - ), + velocity: MetricsTree_Supply_Velocity::new(client.clone(), format!("{base_path}_velocity")), } } } @@ -7356,10 +5185,7 @@ impl MetricsTree_Supply_Burned { pub fn new(client: Arc, base_path: String) -> Self { Self { opreturn: UnclaimedRewardsPattern::new(client.clone(), "opreturn_supply".to_string()), - unspendable: UnclaimedRewardsPattern::new( - client.clone(), - "unspendable_supply".to_string(), - ), + unspendable: UnclaimedRewardsPattern::new(client.clone(), "unspendable_supply".to_string()), } } } @@ -7419,32 +5245,20 @@ impl MetricsTree_Transactions { pub fn new(client: Arc, base_path: String) -> Self { Self { base_size: MetricPattern27::new(client.clone(), "base_size".to_string()), - count: MetricsTree_Transactions_Count::new( - client.clone(), - format!("{base_path}_count"), - ), + count: MetricsTree_Transactions_Count::new(client.clone(), format!("{base_path}_count")), fees: MetricsTree_Transactions_Fees::new(client.clone(), format!("{base_path}_fees")), first_txindex: MetricPattern11::new(client.clone(), "first_txindex".to_string()), first_txinindex: MetricPattern27::new(client.clone(), "first_txinindex".to_string()), first_txoutindex: MetricPattern27::new(client.clone(), "first_txoutindex".to_string()), height: MetricPattern27::new(client.clone(), "height".to_string()), - is_explicitly_rbf: MetricPattern27::new( - client.clone(), - "is_explicitly_rbf".to_string(), - ), + is_explicitly_rbf: MetricPattern27::new(client.clone(), "is_explicitly_rbf".to_string()), rawlocktime: MetricPattern27::new(client.clone(), "rawlocktime".to_string()), size: MetricsTree_Transactions_Size::new(client.clone(), format!("{base_path}_size")), total_size: MetricPattern27::new(client.clone(), "total_size".to_string()), txid: MetricPattern27::new(client.clone(), "txid".to_string()), txversion: MetricPattern27::new(client.clone(), "txversion".to_string()), - versions: MetricsTree_Transactions_Versions::new( - client.clone(), - format!("{base_path}_versions"), - ), - volume: MetricsTree_Transactions_Volume::new( - client.clone(), - format!("{base_path}_volume"), - ), + versions: MetricsTree_Transactions_Versions::new(client.clone(), format!("{base_path}_versions")), + volume: MetricsTree_Transactions_Volume::new(client.clone(), format!("{base_path}_volume")), } } } @@ -7495,10 +5309,7 @@ impl MetricsTree_Transactions_Fees_Fee { pub fn new(client: Arc, base_path: String) -> Self { Self { bitcoin: CountPattern2::new(client.clone(), "fee_btc".to_string()), - dollars: MetricsTree_Transactions_Fees_Fee_Dollars::new( - client.clone(), - format!("{base_path}_dollars"), - ), + dollars: MetricsTree_Transactions_Fees_Fee_Dollars::new(client.clone(), format!("{base_path}_dollars")), sats: CountPattern2::new(client.clone(), "fee".to_string()), txindex: MetricPattern27::new(client.clone(), "fee".to_string()), } @@ -7525,10 +5336,7 @@ impl MetricsTree_Transactions_Fees_Fee_Dollars { Self { average: MetricPattern1::new(client.clone(), "fee_usd_average".to_string()), cumulative: MetricPattern2::new(client.clone(), "fee_usd_cumulative".to_string()), - height_cumulative: MetricPattern11::new( - client.clone(), - "fee_usd_cumulative".to_string(), - ), + height_cumulative: MetricPattern11::new(client.clone(), "fee_usd_cumulative".to_string()), max: MetricPattern1::new(client.clone(), "fee_usd_max".to_string()), median: MetricPattern11::new(client.clone(), "fee_usd_median".to_string()), min: MetricPattern1::new(client.clone(), "fee_usd_min".to_string()), @@ -7634,12 +5442,12 @@ impl BrkClient { /// .last(10) /// .json::()?; /// ``` - pub fn metric( - &self, - metric: impl Into, - index: Index, - ) -> MetricEndpointBuilder { - MetricEndpointBuilder::new(self.base.clone(), Arc::from(metric.into().as_str()), index) + pub fn metric(&self, metric: impl Into, index: Index) -> MetricEndpointBuilder { + MetricEndpointBuilder::new( + self.base.clone(), + Arc::from(metric.into().as_str()), + index, + ) } /// Compact OpenAPI specification @@ -7669,24 +5477,11 @@ impl BrkClient { /// *[Mempool.space docs](https://mempool.space/docs/api/rest#get-address-transactions)* /// /// Endpoint: `GET /api/address/{address}/txs` - pub fn get_address_txs( - &self, - address: Address, - after_txid: Option<&str>, - limit: Option, - ) -> Result> { + pub fn get_address_txs(&self, address: Address, after_txid: Option<&str>, limit: Option) -> Result> { let mut query = Vec::new(); - if let Some(v) = after_txid { - query.push(format!("after_txid={}", v)); - } - if let Some(v) = limit { - query.push(format!("limit={}", v)); - } - let query_str = if query.is_empty() { - String::new() - } else { - format!("?{}", query.join("&")) - }; + if let Some(v) = after_txid { query.push(format!("after_txid={}", v)); } + if let Some(v) = limit { query.push(format!("limit={}", v)); } + let query_str = if query.is_empty() { String::new() } else { format!("?{}", query.join("&")) }; let path = format!("/api/address/{address}/txs{}", query_str); self.base.get_json(&path) } @@ -7698,24 +5493,11 @@ impl BrkClient { /// *[Mempool.space docs](https://mempool.space/docs/api/rest#get-address-transactions-chain)* /// /// Endpoint: `GET /api/address/{address}/txs/chain` - pub fn get_address_confirmed_txs( - &self, - address: Address, - after_txid: Option<&str>, - limit: Option, - ) -> Result> { + pub fn get_address_confirmed_txs(&self, address: Address, after_txid: Option<&str>, limit: Option) -> Result> { let mut query = Vec::new(); - if let Some(v) = after_txid { - query.push(format!("after_txid={}", v)); - } - if let Some(v) = limit { - query.push(format!("limit={}", v)); - } - let query_str = if query.is_empty() { - String::new() - } else { - format!("?{}", query.join("&")) - }; + if let Some(v) = after_txid { query.push(format!("after_txid={}", v)); } + if let Some(v) = limit { query.push(format!("limit={}", v)); } + let query_str = if query.is_empty() { String::new() } else { format!("?{}", query.join("&")) }; let path = format!("/api/address/{address}/txs/chain{}", query_str); self.base.get_json(&path) } @@ -7728,8 +5510,7 @@ impl BrkClient { /// /// Endpoint: `GET /api/address/{address}/txs/mempool` pub fn get_address_mempool_txs(&self, address: Address) -> Result> { - self.base - .get_json(&format!("/api/address/{address}/txs/mempool")) + self.base.get_json(&format!("/api/address/{address}/txs/mempool")) } /// Address UTXOs @@ -7795,8 +5576,7 @@ impl BrkClient { /// /// Endpoint: `GET /api/block/{hash}/txid/{index}` pub fn get_block_txid(&self, hash: BlockHash, index: TxIndex) -> Result { - self.base - .get_json(&format!("/api/block/{hash}/txid/{index}")) + self.base.get_json(&format!("/api/block/{hash}/txid/{index}")) } /// Block transaction IDs @@ -7818,8 +5598,7 @@ impl BrkClient { /// /// Endpoint: `GET /api/block/{hash}/txs/{start_index}` pub fn get_block_txs(&self, hash: BlockHash, start_index: TxIndex) -> Result> { - self.base - .get_json(&format!("/api/block/{hash}/txs/{start_index}")) + self.base.get_json(&format!("/api/block/{hash}/txs/{start_index}")) } /// Recent blocks @@ -7880,38 +5659,14 @@ impl BrkClient { /// Fetch data for a specific metric at the given index. Use query parameters to filter by date range and format (json/csv). /// /// Endpoint: `GET /api/metric/{metric}/{index}` - pub fn get_metric( - &self, - metric: Metric, - index: Index, - start: Option, - end: Option, - limit: Option<&str>, - format: Option, - ) -> Result> { + pub fn get_metric(&self, metric: Metric, index: Index, start: Option, end: Option, limit: Option<&str>, format: Option) -> Result> { let mut query = Vec::new(); - if let Some(v) = start { - query.push(format!("start={}", v)); - } - if let Some(v) = end { - query.push(format!("end={}", v)); - } - if let Some(v) = limit { - query.push(format!("limit={}", v)); - } - if let Some(v) = format { - query.push(format!("format={}", v)); - } - let query_str = if query.is_empty() { - String::new() - } else { - format!("?{}", query.join("&")) - }; - let path = format!( - "/api/metric/{metric}/{}{}", - index.serialize_long(), - query_str - ); + if let Some(v) = start { query.push(format!("start={}", v)); } + if let Some(v) = end { query.push(format!("end={}", v)); } + if let Some(v) = limit { query.push(format!("limit={}", v)); } + if let Some(v) = format { query.push(format!("format={}", v)); } + let query_str = if query.is_empty() { String::new() } else { format!("?{}", query.join("&")) }; + let path = format!("/api/metric/{metric}/{}{}", index.serialize_long(), query_str); if format == Some(Format::CSV) { self.base.get_text(&path).map(FormatResponse::Csv) } else { @@ -7933,35 +5688,15 @@ impl BrkClient { /// Fetch multiple metrics in a single request. Supports filtering by index and date range. Returns an array of MetricData objects. For a single metric, use `get_metric` instead. /// /// Endpoint: `GET /api/metrics/bulk` - pub fn get_metrics( - &self, - metrics: Metrics, - index: Index, - start: Option, - end: Option, - limit: Option<&str>, - format: Option, - ) -> Result>> { + pub fn get_metrics(&self, metrics: Metrics, index: Index, start: Option, end: Option, limit: Option<&str>, format: Option) -> Result>> { let mut query = Vec::new(); query.push(format!("metrics={}", metrics)); query.push(format!("index={}", index)); - if let Some(v) = start { - query.push(format!("start={}", v)); - } - if let Some(v) = end { - query.push(format!("end={}", v)); - } - if let Some(v) = limit { - query.push(format!("limit={}", v)); - } - if let Some(v) = format { - query.push(format!("format={}", v)); - } - let query_str = if query.is_empty() { - String::new() - } else { - format!("?{}", query.join("&")) - }; + if let Some(v) = start { query.push(format!("start={}", v)); } + if let Some(v) = end { query.push(format!("end={}", v)); } + if let Some(v) = limit { query.push(format!("limit={}", v)); } + if let Some(v) = format { query.push(format!("format={}", v)); } + let query_str = if query.is_empty() { String::new() } else { format!("?{}", query.join("&")) }; let path = format!("/api/metrics/bulk{}", query_str); if format == Some(Format::CSV) { self.base.get_text(&path).map(FormatResponse::Csv) @@ -7995,14 +5730,8 @@ impl BrkClient { /// Endpoint: `GET /api/metrics/list` pub fn list_metrics(&self, page: Option) -> Result { let mut query = Vec::new(); - if let Some(v) = page { - query.push(format!("page={}", v)); - } - let query_str = if query.is_empty() { - String::new() - } else { - format!("?{}", query.join("&")) - }; + if let Some(v) = page { query.push(format!("page={}", v)); } + let query_str = if query.is_empty() { String::new() } else { format!("?{}", query.join("&")) }; let path = format!("/api/metrics/list{}", query_str); self.base.get_json(&path) } @@ -8014,14 +5743,8 @@ impl BrkClient { /// Endpoint: `GET /api/metrics/search/{metric}` pub fn search_metrics(&self, metric: Metric, limit: Option) -> Result> { let mut query = Vec::new(); - if let Some(v) = limit { - query.push(format!("limit={}", v)); - } - let query_str = if query.is_empty() { - String::new() - } else { - format!("?{}", query.join("&")) - }; + if let Some(v) = limit { query.push(format!("limit={}", v)); } + let query_str = if query.is_empty() { String::new() } else { format!("?{}", query.join("&")) }; let path = format!("/api/metrics/search/{metric}{}", query_str); self.base.get_json(&path) } @@ -8074,8 +5797,7 @@ impl BrkClient { /// /// Endpoint: `GET /api/tx/{txid}/outspend/{vout}` pub fn get_tx_outspend(&self, txid: Txid, vout: Vout) -> Result { - self.base - .get_json(&format!("/api/tx/{txid}/outspend/{vout}")) + self.base.get_json(&format!("/api/tx/{txid}/outspend/{vout}")) } /// All output spend statuses @@ -8108,8 +5830,7 @@ impl BrkClient { /// /// Endpoint: `GET /api/v1/difficulty-adjustment` pub fn get_difficulty_adjustment(&self) -> Result { - self.base - .get_json(&format!("/api/v1/difficulty-adjustment")) + self.base.get_json(&format!("/api/v1/difficulty-adjustment")) } /// Projected mempool blocks @@ -8142,8 +5863,7 @@ impl BrkClient { /// /// Endpoint: `GET /api/v1/mining/blocks/fee-rates/{time_period}` pub fn get_block_fee_rates(&self, time_period: TimePeriod) -> Result { - self.base - .get_json(&format!("/api/v1/mining/blocks/fee-rates/{time_period}")) + self.base.get_json(&format!("/api/v1/mining/blocks/fee-rates/{time_period}")) } /// Block fees @@ -8154,8 +5874,7 @@ impl BrkClient { /// /// Endpoint: `GET /api/v1/mining/blocks/fees/{time_period}` pub fn get_block_fees(&self, time_period: TimePeriod) -> Result> { - self.base - .get_json(&format!("/api/v1/mining/blocks/fees/{time_period}")) + self.base.get_json(&format!("/api/v1/mining/blocks/fees/{time_period}")) } /// Block rewards @@ -8166,8 +5885,7 @@ impl BrkClient { /// /// Endpoint: `GET /api/v1/mining/blocks/rewards/{time_period}` pub fn get_block_rewards(&self, time_period: TimePeriod) -> Result> { - self.base - .get_json(&format!("/api/v1/mining/blocks/rewards/{time_period}")) + self.base.get_json(&format!("/api/v1/mining/blocks/rewards/{time_period}")) } /// Block sizes and weights @@ -8178,9 +5896,7 @@ impl BrkClient { /// /// Endpoint: `GET /api/v1/mining/blocks/sizes-weights/{time_period}` pub fn get_block_sizes_weights(&self, time_period: TimePeriod) -> Result { - self.base.get_json(&format!( - "/api/v1/mining/blocks/sizes-weights/{time_period}" - )) + self.base.get_json(&format!("/api/v1/mining/blocks/sizes-weights/{time_period}")) } /// Block by timestamp @@ -8191,8 +5907,7 @@ impl BrkClient { /// /// Endpoint: `GET /api/v1/mining/blocks/timestamp/{timestamp}` pub fn get_block_by_timestamp(&self, timestamp: Timestamp) -> Result { - self.base - .get_json(&format!("/api/v1/mining/blocks/timestamp/{timestamp}")) + self.base.get_json(&format!("/api/v1/mining/blocks/timestamp/{timestamp}")) } /// Difficulty adjustments (all time) @@ -8203,8 +5918,7 @@ impl BrkClient { /// /// Endpoint: `GET /api/v1/mining/difficulty-adjustments` pub fn get_difficulty_adjustments(&self) -> Result> { - self.base - .get_json(&format!("/api/v1/mining/difficulty-adjustments")) + self.base.get_json(&format!("/api/v1/mining/difficulty-adjustments")) } /// Difficulty adjustments @@ -8214,13 +5928,8 @@ impl BrkClient { /// *[Mempool.space docs](https://mempool.space/docs/api/rest#get-difficulty-adjustments)* /// /// Endpoint: `GET /api/v1/mining/difficulty-adjustments/{time_period}` - pub fn get_difficulty_adjustments_by_period( - &self, - time_period: TimePeriod, - ) -> Result> { - self.base.get_json(&format!( - "/api/v1/mining/difficulty-adjustments/{time_period}" - )) + pub fn get_difficulty_adjustments_by_period(&self, time_period: TimePeriod) -> Result> { + self.base.get_json(&format!("/api/v1/mining/difficulty-adjustments/{time_period}")) } /// Network hashrate (all time) @@ -8242,8 +5951,7 @@ impl BrkClient { /// /// Endpoint: `GET /api/v1/mining/hashrate/{time_period}` pub fn get_hashrate_by_period(&self, time_period: TimePeriod) -> Result { - self.base - .get_json(&format!("/api/v1/mining/hashrate/{time_period}")) + self.base.get_json(&format!("/api/v1/mining/hashrate/{time_period}")) } /// Mining pool details @@ -8276,8 +5984,7 @@ impl BrkClient { /// /// Endpoint: `GET /api/v1/mining/pools/{time_period}` pub fn get_pool_stats(&self, time_period: TimePeriod) -> Result { - self.base - .get_json(&format!("/api/v1/mining/pools/{time_period}")) + self.base.get_json(&format!("/api/v1/mining/pools/{time_period}")) } /// Mining reward statistics @@ -8288,8 +5995,7 @@ impl BrkClient { /// /// Endpoint: `GET /api/v1/mining/reward-stats/{block_count}` pub fn get_reward_stats(&self, block_count: i64) -> Result { - self.base - .get_json(&format!("/api/v1/mining/reward-stats/{block_count}")) + self.base.get_json(&format!("/api/v1/mining/reward-stats/{block_count}")) } /// Validate address @@ -8300,8 +6006,7 @@ impl BrkClient { /// /// Endpoint: `GET /api/v1/validate-address/{address}` pub fn validate_address(&self, address: &str) -> Result { - self.base - .get_json(&format!("/api/v1/validate-address/{address}")) + self.base.get_json(&format!("/api/v1/validate-address/{address}")) } /// Health check @@ -8330,4 +6035,5 @@ impl BrkClient { pub fn get_version(&self) -> Result { self.base.get_json(&format!("/version")) } + } diff --git a/crates/brk_computer/Cargo.toml b/crates/brk_computer/Cargo.toml index 72192a890..7ad8d856f 100644 --- a/crates/brk_computer/Cargo.toml +++ b/crates/brk_computer/Cargo.toml @@ -22,7 +22,7 @@ brk_traversable = { workspace = true } brk_types = { workspace = true } derive_more = { workspace = true } tracing = { workspace = true } -pco = "0.4.9" +pco = "1.0.0" rayon = { workspace = true } rustc-hash = { workspace = true } schemars = { workspace = true } diff --git a/crates/brk_computer/src/constants.rs b/crates/brk_computer/src/constants.rs index 24277a20f..fe9af32e2 100644 --- a/crates/brk_computer/src/constants.rs +++ b/crates/brk_computer/src/constants.rs @@ -1,9 +1,9 @@ use brk_traversable::Traversable; -use brk_types::{StoredF32, StoredI16, StoredU16, Version}; +use brk_types::{StoredF32, StoredI8, StoredU16, Version}; use super::{ indexes, - internal::{ConstantVecs, ReturnF32Tenths, ReturnI16, ReturnU16}, + internal::{ConstantVecs, ReturnF32Tenths, ReturnI8, ReturnU16}, }; pub const DB_NAME: &str = "constants"; @@ -24,10 +24,10 @@ pub struct Vecs { pub constant_80: ConstantVecs, pub constant_100: ConstantVecs, pub constant_600: ConstantVecs, - pub constant_minus_1: ConstantVecs, - pub constant_minus_2: ConstantVecs, - pub constant_minus_3: ConstantVecs, - pub constant_minus_4: ConstantVecs, + pub constant_minus_1: ConstantVecs, + pub constant_minus_2: ConstantVecs, + pub constant_minus_3: ConstantVecs, + pub constant_minus_4: ConstantVecs, } impl Vecs { @@ -49,10 +49,10 @@ impl Vecs { constant_80: ConstantVecs::new::>("constant_80", v, indexes), constant_100: ConstantVecs::new::>("constant_100", v, indexes), constant_600: ConstantVecs::new::>("constant_600", v, indexes), - constant_minus_1: ConstantVecs::new::>("constant_minus_1", v, indexes), - constant_minus_2: ConstantVecs::new::>("constant_minus_2", v, indexes), - constant_minus_3: ConstantVecs::new::>("constant_minus_3", v, indexes), - constant_minus_4: ConstantVecs::new::>("constant_minus_4", v, indexes), + constant_minus_1: ConstantVecs::new::>("constant_minus_1", v, indexes), + constant_minus_2: ConstantVecs::new::>("constant_minus_2", v, indexes), + constant_minus_3: ConstantVecs::new::>("constant_minus_3", v, indexes), + constant_minus_4: ConstantVecs::new::>("constant_minus_4", v, indexes), } } } diff --git a/crates/brk_computer/src/distribution/state/cost_basis/price_to_amount.rs b/crates/brk_computer/src/distribution/state/cost_basis/price_to_amount.rs index a5417d9a0..c9fea735d 100644 --- a/crates/brk_computer/src/distribution/state/cost_basis/price_to_amount.rs +++ b/crates/brk_computer/src/distribution/state/cost_basis/price_to_amount.rs @@ -8,7 +8,7 @@ use std::{ use brk_error::{Error, Result}; use brk_types::{CentsCompact, Dollars, Height, Sats, SupplyState}; use derive_more::{Deref, DerefMut}; -use pco::standalone::{simple_decompress, simpler_compress}; +use pco::{standalone::{simple_compress, simple_decompress}, ChunkConfig}; use rustc_hash::FxHashMap; use serde::{Deserialize, Serialize}; use vecdb::Bytes; @@ -234,15 +234,14 @@ impl PriceToAmount { #[derive(Clone, Default, Debug, Deref, DerefMut, Serialize, Deserialize)] struct State(BTreeMap); -const COMPRESSION_LEVEL: usize = 4; - impl State { fn serialize(&self) -> vecdb::Result> { let keys: Vec = self.keys().map(|k| i32::from(*k)).collect(); let values: Vec = self.values().map(|v| u64::from(*v)).collect(); - let compressed_keys = simpler_compress(&keys, COMPRESSION_LEVEL)?; - let compressed_values = simpler_compress(&values, COMPRESSION_LEVEL)?; + let config = ChunkConfig::default(); + let compressed_keys = simple_compress(&keys, &config)?; + let compressed_values = simple_compress(&values, &config)?; let mut buffer = Vec::new(); buffer.extend(keys.len().to_bytes()); diff --git a/crates/brk_computer/src/internal/single/transform/mod.rs b/crates/brk_computer/src/internal/single/transform/mod.rs index 5b63f73e0..851aaf3c8 100644 --- a/crates/brk_computer/src/internal/single/transform/mod.rs +++ b/crates/brk_computer/src/internal/single/transform/mod.rs @@ -21,7 +21,7 @@ mod ratio32; mod ratio32_neg; mod ratio_f32; mod return_f32_tenths; -mod return_i16; +mod return_i8; mod return_u16; mod rsi_formula; mod sat_halve; @@ -61,7 +61,7 @@ pub use ratio32::*; pub use ratio32_neg::*; pub use ratio_f32::*; pub use return_f32_tenths::*; -pub use return_i16::*; +pub use return_i8::*; pub use return_u16::*; pub use rsi_formula::*; pub use sat_halve::*; diff --git a/crates/brk_computer/src/internal/single/transform/return_i16.rs b/crates/brk_computer/src/internal/single/transform/return_i16.rs deleted file mode 100644 index 8122dfa7d..000000000 --- a/crates/brk_computer/src/internal/single/transform/return_i16.rs +++ /dev/null @@ -1,12 +0,0 @@ -use brk_types::StoredI16; -use vecdb::UnaryTransform; - -/// Returns a constant i16 value, ignoring the input. -pub struct ReturnI16; - -impl UnaryTransform for ReturnI16 { - #[inline(always)] - fn apply(_: S) -> StoredI16 { - StoredI16::new(V) - } -} diff --git a/crates/brk_computer/src/internal/single/transform/return_i8.rs b/crates/brk_computer/src/internal/single/transform/return_i8.rs new file mode 100644 index 000000000..caddb7b21 --- /dev/null +++ b/crates/brk_computer/src/internal/single/transform/return_i8.rs @@ -0,0 +1,12 @@ +use brk_types::StoredI8; +use vecdb::UnaryTransform; + +/// Returns a constant i8 value, ignoring the input. +pub struct ReturnI8; + +impl UnaryTransform for ReturnI8 { + #[inline(always)] + fn apply(_: S) -> StoredI8 { + StoredI8::new(V) + } +} diff --git a/crates/brk_indexer/src/stores.rs b/crates/brk_indexer/src/stores.rs index d317ba11f..fb7b6fcb6 100644 --- a/crates/brk_indexer/src/stores.rs +++ b/crates/brk_indexer/src/stores.rs @@ -383,11 +383,9 @@ impl Stores { pub fn reset(&mut self) -> Result<()> { info!("Resetting stores..."); - // Clear all keyspaces - self.iter_any().try_for_each(|store| -> Result<()> { - store.keyspace().clear()?; - Ok(()) - })?; + // Clear all stores (both in-memory buffers and on-disk keyspaces) + self.par_iter_any_mut() + .try_for_each(|store| store.reset())?; // Persist the cleared state self.db.persist(PersistMode::SyncAll)?; diff --git a/crates/brk_playground/Cargo.toml b/crates/brk_playground/Cargo.toml index dd2371431..110aa3a10 100644 --- a/crates/brk_playground/Cargo.toml +++ b/crates/brk_playground/Cargo.toml @@ -19,3 +19,11 @@ memmap2 = "0.9" plotters = "0.3" tracing = { workspace = true } vecdb = { workspace = true } + +[[example]] +name = "heatmap" +path = "examples/heatmap.rs" + +[[example]] +name = "oracle" +path = "examples/oracle.rs" diff --git a/crates/brk_playground/src/lib.rs b/crates/brk_playground/src/lib.rs index 71504580c..4335be26b 100644 --- a/crates/brk_playground/src/lib.rs +++ b/crates/brk_playground/src/lib.rs @@ -1,4 +1,26 @@ -//! Experimental playground for brk development. +//! Playground library for Bitcoin on-chain analysis //! -//! This crate is for experiments and prototypes. -//! Most contents are git-ignored. +//! This crate provides tools for: +//! - Phase histogram analysis of UTXO patterns +//! - Filter-based output selection for price signal extraction +//! - On-chain OHLC price oracle derivation + +pub mod anchors; +pub mod conditions; +pub mod constants; +pub mod filters; +pub mod histogram; +pub mod oracle; +pub mod render; +pub mod signal; + +pub use anchors::{get_anchor_ohlc, get_anchor_range, Ohlc}; +pub use conditions::{out_bits, tx_bits, MappedOutputConditions}; +pub use constants::{HeatmapFilter, NUM_BINS, ROUND_USD_AMOUNTS}; +pub use filters::FILTERS; +pub use oracle::{ + derive_daily_ohlc, derive_daily_ohlc_with_confidence, derive_height_price, + derive_ohlc_from_height_prices, derive_price_from_histogram, OracleConfig, OracleResult, +}; +pub use signal::{compute_expected_bins_per_day, usd_to_bin}; +pub use histogram::load_or_compute_output_conditions; diff --git a/crates/brk_query/src/impl/metrics.rs b/crates/brk_query/src/impl/metrics.rs index b40d8db2d..f2813d1ac 100644 --- a/crates/brk_query/src/impl/metrics.rs +++ b/crates/brk_query/src/impl/metrics.rs @@ -160,6 +160,7 @@ impl Query { total, start, end, + height: *self.height(), }) } @@ -173,6 +174,7 @@ impl Query { total, start, end, + .. } = resolved; let output = match format { diff --git a/crates/brk_query/src/impl/metrics_legacy.rs b/crates/brk_query/src/impl/metrics_legacy.rs index 89d9ba02c..259601082 100644 --- a/crates/brk_query/src/impl/metrics_legacy.rs +++ b/crates/brk_query/src/impl/metrics_legacy.rs @@ -13,6 +13,7 @@ impl Query { total, start, end, + .. } = resolved; if vecs.is_empty() { diff --git a/crates/brk_query/src/resolved.rs b/crates/brk_query/src/resolved.rs index c3310ea4a..7db662178 100644 --- a/crates/brk_query/src/resolved.rs +++ b/crates/brk_query/src/resolved.rs @@ -10,11 +10,12 @@ pub struct ResolvedQuery { pub(crate) total: usize, pub(crate) start: usize, pub(crate) end: usize, + pub(crate) height: u32, } impl ResolvedQuery { pub fn etag(&self) -> Etag { - Etag::from_metric(self.version, self.total, self.start, self.end) + Etag::from_metric(self.version, self.total, self.start, self.end, self.height) } pub fn format(&self) -> Format { diff --git a/crates/brk_store/src/any.rs b/crates/brk_store/src/any.rs index f1a736869..516e6f61c 100644 --- a/crates/brk_store/src/any.rs +++ b/crates/brk_store/src/any.rs @@ -12,4 +12,5 @@ pub trait AnyStore: Send + Sync { fn export_meta_if_needed(&mut self, height: Height) -> Result<()>; fn keyspace(&self) -> &Keyspace; fn commit(&mut self, height: Height) -> Result<()>; + fn reset(&mut self) -> Result<()>; } diff --git a/crates/brk_store/src/lib.rs b/crates/brk_store/src/lib.rs index bf662e2cf..99f525909 100644 --- a/crates/brk_store/src/lib.rs +++ b/crates/brk_store/src/lib.rs @@ -349,4 +349,15 @@ where Ok(()) } + + fn reset(&mut self) -> Result<()> { + self.meta.reset()?; + self.puts.clear(); + self.dels.clear(); + for cache in &mut self.caches { + cache.clear(); + } + self.keyspace.clear()?; + Ok(()) + } } diff --git a/crates/brk_store/src/meta.rs b/crates/brk_store/src/meta.rs index f11ab0baa..42ac19c84 100644 --- a/crates/brk_store/src/meta.rs +++ b/crates/brk_store/src/meta.rs @@ -82,6 +82,14 @@ impl StoreMeta { pub fn has(&self, height: Height) -> bool { !self.needs(height) } + pub fn reset(&mut self) -> io::Result<()> { + self.height = None; + let path = self.path_height(); + if path.exists() { + fs::remove_file(&path)?; + } + Ok(()) + } fn path_height(&self) -> PathBuf { Self::path_height_(&self.pathbuf) } diff --git a/crates/brk_types/src/dateindex.rs b/crates/brk_types/src/dateindex.rs index f8c0e7919..d47b318ed 100644 --- a/crates/brk_types/src/dateindex.rs +++ b/crates/brk_types/src/dateindex.rs @@ -148,7 +148,7 @@ impl FromCoarserIndex for DateIndex { impl FromCoarserIndex for DateIndex { fn min_from(coarser: QuarterIndex) -> usize { - let coarser = u16::from(coarser); + let coarser = u8::from(coarser); if coarser == 0 { 0 } else { @@ -163,7 +163,7 @@ impl FromCoarserIndex for DateIndex { fn max_from_(coarser: QuarterIndex) -> usize { let d = Date::new(2009, 3, 31) .into_jiff() - .checked_add(Span::new().months(3 * u16::from(coarser))) + .checked_add(Span::new().months(3 * u8::from(coarser))) .unwrap(); DateIndex::try_from(Date::from(d)).unwrap().into() } @@ -171,7 +171,7 @@ impl FromCoarserIndex for DateIndex { impl FromCoarserIndex for DateIndex { fn min_from(coarser: SemesterIndex) -> usize { - let coarser = u16::from(coarser); + let coarser = u8::from(coarser); if coarser == 0 { 0 } else { @@ -186,7 +186,7 @@ impl FromCoarserIndex for DateIndex { fn max_from_(coarser: SemesterIndex) -> usize { let d = Date::new(2009, 5, 31) .into_jiff() - .checked_add(Span::new().months(1 + 6 * u16::from(coarser))) + .checked_add(Span::new().months(1 + 6 * u8::from(coarser))) .unwrap(); DateIndex::try_from(Date::from(d)).unwrap().into() } @@ -194,18 +194,18 @@ impl FromCoarserIndex for DateIndex { impl FromCoarserIndex for DateIndex { fn min_from(coarser: YearIndex) -> usize { - let coarser = u16::from(coarser); + let coarser = u8::from(coarser); if coarser == 0 { 0 } else { - Self::try_from(Date::new(2009 + coarser, 1, 1)) + Self::try_from(Date::new(2009 + coarser as u16, 1, 1)) .unwrap() .into() } } fn max_from_(coarser: YearIndex) -> usize { - Self::try_from(Date::new(2009 + u16::from(coarser), 12, 31)) + Self::try_from(Date::new(2009 + u8::from(coarser) as u16, 12, 31)) .unwrap() .into() } @@ -213,19 +213,19 @@ impl FromCoarserIndex for DateIndex { impl FromCoarserIndex for DateIndex { fn min_from(coarser: DecadeIndex) -> usize { - let coarser = u16::from(coarser); + let coarser = u8::from(coarser); if coarser == 0 { 0 } else { - Self::try_from(Date::new(2000 + 10 * coarser, 1, 1)) + Self::try_from(Date::new(2000 + 10 * coarser as u16, 1, 1)) .unwrap() .into() } } fn max_from_(coarser: DecadeIndex) -> usize { - let coarser = u16::from(coarser); - Self::try_from(Date::new(2009 + (10 * coarser), 12, 31)) + let coarser = u8::from(coarser); + Self::try_from(Date::new(2009 + 10 * coarser as u16, 12, 31)) .unwrap() .into() } diff --git a/crates/brk_types/src/decadeindex.rs b/crates/brk_types/src/decadeindex.rs index 727cf873c..076ebc433 100644 --- a/crates/brk_types/src/decadeindex.rs +++ b/crates/brk_types/src/decadeindex.rs @@ -23,16 +23,16 @@ use super::{Date, DateIndex, YearIndex}; Pco, JsonSchema, )] -pub struct DecadeIndex(u16); +pub struct DecadeIndex(u8); -impl From for DecadeIndex { +impl From for DecadeIndex { #[inline] - fn from(value: u16) -> Self { + fn from(value: u8) -> Self { Self(value) } } -impl From for u16 { +impl From for u8 { #[inline] fn from(value: DecadeIndex) -> Self { value.0 @@ -42,7 +42,7 @@ impl From for u16 { impl From for DecadeIndex { #[inline] fn from(value: usize) -> Self { - Self(value as u16) + Self(value as u8) } } @@ -57,7 +57,7 @@ impl Add for DecadeIndex { type Output = Self; fn add(self, rhs: usize) -> Self::Output { - Self::from(self.0 + rhs as u16) + Self::from(self.0 + rhs as u8) } } @@ -96,7 +96,7 @@ impl From for DecadeIndex { if year < 2000 { panic!("unsupported") } - Self((year - 2000) / 10) + Self(((year - 2000) / 10) as u8) } } @@ -113,7 +113,7 @@ impl From for DecadeIndex { if v == 0 { Self(0) } else { - Self((((v - 1) / 10) + 1) as u16) + Self((((v - 1) / 10) + 1) as u8) } } } diff --git a/crates/brk_types/src/etag.rs b/crates/brk_types/src/etag.rs index 4992050af..62bc7dee6 100644 --- a/crates/brk_types/src/etag.rs +++ b/crates/brk_types/src/etag.rs @@ -44,16 +44,16 @@ impl Etag { /// /// Format varies based on whether the slice touches the end: /// - Slice ends before total: `{version:x}-{start}-{end}` (len irrelevant, data won't change if metric grows) - /// - Slice reaches the end: `{version:x}-{start}-{total}` (len matters, new data would change results) + /// - Slice reaches the end: `{version:x}-{start}-{total}-{height}` (includes height since last value may be recomputed each block) /// /// `version` is the metric version for single queries, or the sum of versions for bulk queries. - pub fn from_metric(version: u64, total: usize, start: usize, end: usize) -> Self { + pub fn from_metric(version: u64, total: usize, start: usize, end: usize, height: u32) -> Self { if end < total { // Fixed window not at the end - len doesn't matter Self(format!("{version:x}-{start}-{end}")) } else { - // Fetching up to current end - len matters - Self(format!("{version:x}-{start}-{total}")) + // Fetching up to current end - include height since last value may change each block + Self(format!("{version:x}-{start}-{total}-{height}")) } } } diff --git a/crates/brk_types/src/halvingepoch.rs b/crates/brk_types/src/halvingepoch.rs index bcc77493b..d6a332b58 100644 --- a/crates/brk_types/src/halvingepoch.rs +++ b/crates/brk_types/src/halvingepoch.rs @@ -25,17 +25,17 @@ pub const BLOCKS_PER_HALVING: u32 = 210_000; Pco, JsonSchema, )] -pub struct HalvingEpoch(u16); +pub struct HalvingEpoch(u8); impl HalvingEpoch { - pub const fn new(value: u16) -> Self { + pub const fn new(value: u8) -> Self { Self(value) } } -impl From for HalvingEpoch { +impl From for HalvingEpoch { #[inline] - fn from(value: u16) -> Self { + fn from(value: u8) -> Self { Self(value) } } @@ -43,7 +43,7 @@ impl From for HalvingEpoch { impl From for HalvingEpoch { #[inline] fn from(value: usize) -> Self { - Self(value as u16) + Self(value as u8) } } @@ -72,14 +72,14 @@ impl Add for HalvingEpoch { type Output = Self; fn add(self, rhs: usize) -> Self::Output { - Self::from(self.0 + rhs as u16) + Self::from(self.0 + rhs as u8) } } impl From for HalvingEpoch { #[inline] fn from(value: Height) -> Self { - Self((u32::from(value) / BLOCKS_PER_HALVING) as u16) + Self((u32::from(value) / BLOCKS_PER_HALVING) as u8) } } diff --git a/crates/brk_types/src/lib.rs b/crates/brk_types/src/lib.rs index b54dd1149..3dfe749c5 100644 --- a/crates/brk_types/src/lib.rs +++ b/crates/brk_types/src/lib.rs @@ -132,6 +132,7 @@ mod stored_bool; mod stored_f32; mod stored_f64; mod stored_i16; +mod stored_i8; mod stored_string; mod stored_u16; mod stored_u32; @@ -302,6 +303,7 @@ pub use stored_bool::*; pub use stored_f32::*; pub use stored_f64::*; pub use stored_i16::*; +pub use stored_i8::*; pub use stored_string::*; pub use stored_u8::*; pub use stored_u16::*; diff --git a/crates/brk_types/src/metricoutput.rs b/crates/brk_types/src/metricoutput.rs index 37e5e16fc..5be794176 100644 --- a/crates/brk_types/src/metricoutput.rs +++ b/crates/brk_types/src/metricoutput.rs @@ -1,4 +1,4 @@ -use crate::{Etag, Output, OutputLegacy}; +use crate::{Output, OutputLegacy}; /// Metric output with metadata for caching. #[derive(Debug)] @@ -10,12 +10,6 @@ pub struct MetricOutput { pub end: usize, } -impl MetricOutput { - pub fn etag(&self) -> Etag { - Etag::from_metric(self.version, self.total, self.start, self.end) - } -} - /// Deprecated: Legacy metric output with metadata for caching. #[derive(Debug)] pub struct MetricOutputLegacy { @@ -25,9 +19,3 @@ pub struct MetricOutputLegacy { pub start: usize, pub end: usize, } - -impl MetricOutputLegacy { - pub fn etag(&self) -> Etag { - Etag::from_metric(self.version, self.total, self.start, self.end) - } -} diff --git a/crates/brk_types/src/monthindex.rs b/crates/brk_types/src/monthindex.rs index 0f05ffa84..b6fe299e7 100644 --- a/crates/brk_types/src/monthindex.rs +++ b/crates/brk_types/src/monthindex.rs @@ -99,7 +99,7 @@ impl From for MonthIndex { impl From for MonthIndex { #[inline] fn from(value: Date) -> Self { - Self(u16::from(YearIndex::from(value)) * 12 + value.month() as u16 - 1) + Self(u8::from(YearIndex::from(value)) as u16 * 12 + value.month() as u16 - 1) } } diff --git a/crates/brk_types/src/outputtype.rs b/crates/brk_types/src/outputtype.rs index 0879b8f72..9cb11280e 100644 --- a/crates/brk_types/src/outputtype.rs +++ b/crates/brk_types/src/outputtype.rs @@ -23,7 +23,7 @@ use crate::AddressBytes; )] #[serde(rename_all = "lowercase")] #[strum(serialize_all = "lowercase")] -#[repr(u16)] +#[repr(u8)] /// Type (P2PKH, P2WPKH, P2SH, P2TR, etc.) pub enum OutputType { P2PK65, @@ -41,8 +41,8 @@ pub enum OutputType { } impl OutputType { - fn is_valid(value: u16) -> bool { - value <= Self::Unknown as u16 + fn is_valid(value: u8) -> bool { + value <= Self::Unknown as u8 } pub fn is_spendable(&self) -> bool { @@ -205,7 +205,7 @@ impl Bytes for OutputType { #[inline] fn to_bytes(&self) -> Self::Array { - (*self as u16).to_le_bytes() + [*self as u8] } #[inline] @@ -216,7 +216,7 @@ impl Bytes for OutputType { received: bytes.len(), }); }; - let value = u16::from_le_bytes([bytes[0], bytes[1]]); + let value = bytes[0]; if !Self::is_valid(value) { return Err(vecdb::Error::InvalidArgument("invalid OutputType")); } @@ -227,7 +227,7 @@ impl Bytes for OutputType { } impl Pco for OutputType { - type NumberType = u16; + type NumberType = u8; } -impl TransparentPco for OutputType {} +impl TransparentPco for OutputType {} diff --git a/crates/brk_types/src/quarterindex.rs b/crates/brk_types/src/quarterindex.rs index 96d55a61b..52fc0252a 100644 --- a/crates/brk_types/src/quarterindex.rs +++ b/crates/brk_types/src/quarterindex.rs @@ -23,11 +23,11 @@ use super::MonthIndex; Pco, JsonSchema, )] -pub struct QuarterIndex(u16); +pub struct QuarterIndex(u8); -impl From for QuarterIndex { +impl From for QuarterIndex { #[inline] - fn from(value: u16) -> Self { + fn from(value: u8) -> Self { Self(value) } } @@ -35,11 +35,11 @@ impl From for QuarterIndex { impl From for QuarterIndex { #[inline] fn from(value: usize) -> Self { - Self(value as u16) + Self(value as u8) } } -impl From for u16 { +impl From for u8 { #[inline] fn from(value: QuarterIndex) -> Self { value.0 @@ -57,7 +57,7 @@ impl Add for QuarterIndex { type Output = Self; fn add(self, rhs: usize) -> Self::Output { - Self::from(self.0 + rhs as u16) + Self::from(self.0 + rhs as u8) } } @@ -85,7 +85,7 @@ impl Div for QuarterIndex { impl From for QuarterIndex { #[inline] fn from(value: MonthIndex) -> Self { - Self((usize::from(value) / 3) as u16) + Self((usize::from(value) / 3) as u8) } } diff --git a/crates/brk_types/src/semesterindex.rs b/crates/brk_types/src/semesterindex.rs index e85b801d1..ea08b142a 100644 --- a/crates/brk_types/src/semesterindex.rs +++ b/crates/brk_types/src/semesterindex.rs @@ -23,11 +23,11 @@ use super::MonthIndex; Pco, JsonSchema, )] -pub struct SemesterIndex(u16); +pub struct SemesterIndex(u8); -impl From for SemesterIndex { +impl From for SemesterIndex { #[inline] - fn from(value: u16) -> Self { + fn from(value: u8) -> Self { Self(value) } } @@ -35,11 +35,11 @@ impl From for SemesterIndex { impl From for SemesterIndex { #[inline] fn from(value: usize) -> Self { - Self(value as u16) + Self(value as u8) } } -impl From for u16 { +impl From for u8 { #[inline] fn from(value: SemesterIndex) -> Self { value.0 @@ -57,7 +57,7 @@ impl Add for SemesterIndex { type Output = Self; fn add(self, rhs: usize) -> Self::Output { - Self::from(self.0 + rhs as u16) + Self::from(self.0 + rhs as u8) } } @@ -85,7 +85,7 @@ impl Div for SemesterIndex { impl From for SemesterIndex { #[inline] fn from(value: MonthIndex) -> Self { - Self((usize::from(value) / 6) as u16) + Self((usize::from(value) / 6) as u8) } } diff --git a/crates/brk_types/src/stored_bool.rs b/crates/brk_types/src/stored_bool.rs index 30670ae6e..ec4aacdff 100644 --- a/crates/brk_types/src/stored_bool.rs +++ b/crates/brk_types/src/stored_bool.rs @@ -3,7 +3,7 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use vecdb::{Formattable, Pco, PrintableIndex}; -/// Fixed-size boolean value optimized for on-disk storage (stored as u16) +/// Fixed-size boolean value optimized for on-disk storage (stored as u8) #[derive( Debug, Deref, @@ -19,7 +19,7 @@ use vecdb::{Formattable, Pco, PrintableIndex}; Pco, JsonSchema, )] -pub struct StoredBool(u16); +pub struct StoredBool(u8); impl StoredBool { pub const FALSE: Self = Self(0); diff --git a/crates/brk_types/src/stored_i8.rs b/crates/brk_types/src/stored_i8.rs new file mode 100644 index 000000000..c448d5ca4 --- /dev/null +++ b/crates/brk_types/src/stored_i8.rs @@ -0,0 +1,123 @@ +use std::ops::{Add, AddAssign, Div}; + +use derive_more::Deref; +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; +use vecdb::{CheckedSub, Formattable, Pco, PrintableIndex}; + +#[derive( + Debug, + Deref, + Clone, + Default, + Copy, + PartialEq, + Eq, + PartialOrd, + Ord, + Serialize, + Deserialize, + Pco, + JsonSchema, +)] +pub struct StoredI8(i8); + +impl StoredI8 { + pub const ZERO: Self = Self(0); + + pub fn new(v: i8) -> Self { + Self(v) + } +} + +impl From for StoredI8 { + #[inline] + fn from(value: i8) -> Self { + Self(value) + } +} + +impl From for StoredI8 { + #[inline] + fn from(value: usize) -> Self { + if value > i8::MAX as usize { + panic!("usize too big (value = {value})") + } + Self(value as i8) + } +} + +impl CheckedSub for StoredI8 { + fn checked_sub(self, rhs: Self) -> Option { + self.0.checked_sub(rhs.0).map(Self) + } +} + +impl Div for StoredI8 { + type Output = Self; + fn div(self, rhs: usize) -> Self::Output { + Self(self.0 / rhs as i8) + } +} + +impl Add for StoredI8 { + type Output = Self; + fn add(self, rhs: Self) -> Self::Output { + Self(self.0 + rhs.0) + } +} + +impl AddAssign for StoredI8 { + fn add_assign(&mut self, rhs: Self) { + *self = *self + rhs + } +} + +impl From for StoredI8 { + #[inline] + fn from(value: f64) -> Self { + if value < i8::MIN as f64 || value > i8::MAX as f64 { + panic!() + } + Self(value as i8) + } +} + +impl From for f64 { + #[inline] + fn from(value: StoredI8) -> Self { + value.0 as f64 + } +} + +impl From for usize { + #[inline] + fn from(value: StoredI8) -> Self { + value.0 as usize + } +} + +impl PrintableIndex for StoredI8 { + fn to_string() -> &'static str { + "i8" + } + + fn to_possible_strings() -> &'static [&'static str] { + &["i8"] + } +} + +impl std::fmt::Display for StoredI8 { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let mut buf = itoa::Buffer::new(); + let str = buf.format(self.0); + f.write_str(str) + } +} + +impl Formattable for StoredI8 { + #[inline(always)] + fn may_need_escaping() -> bool { + false + } +} diff --git a/crates/brk_types/src/txversion.rs b/crates/brk_types/src/txversion.rs index aa8719345..de0f6ed96 100644 --- a/crates/brk_types/src/txversion.rs +++ b/crates/brk_types/src/txversion.rs @@ -3,7 +3,7 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use vecdb::{Formattable, Pco}; -use super::StoredU16; +use super::StoredU8; /// Transaction version number #[derive( @@ -20,13 +20,13 @@ use super::StoredU16; Pco, JsonSchema, )] -pub struct TxVersion(u16); +pub struct TxVersion(u8); impl TxVersion { pub const ONE: Self = Self(1); pub const TWO: Self = Self(2); pub const THREE: Self = Self(3); - pub const NON_STANDARD: Self = Self(u16::MAX); + pub const NON_STANDARD: Self = Self(u8::MAX); } impl From for TxVersion { @@ -48,7 +48,7 @@ impl From for bitcoin::transaction::Version { } } -impl From for StoredU16 { +impl From for StoredU8 { #[inline] fn from(value: TxVersion) -> Self { Self::from(value.0) diff --git a/crates/brk_types/src/yearindex.rs b/crates/brk_types/src/yearindex.rs index 03d8d540c..5eab88cff 100644 --- a/crates/brk_types/src/yearindex.rs +++ b/crates/brk_types/src/yearindex.rs @@ -23,11 +23,11 @@ use super::{Date, DateIndex, MonthIndex}; Pco, JsonSchema, )] -pub struct YearIndex(u16); +pub struct YearIndex(u8); -impl From for YearIndex { +impl From for YearIndex { #[inline] - fn from(value: u16) -> Self { + fn from(value: u8) -> Self { Self(value) } } @@ -35,7 +35,7 @@ impl From for YearIndex { impl From for YearIndex { #[inline] fn from(value: usize) -> Self { - Self(value as u16) + Self(value as u8) } } @@ -57,7 +57,7 @@ impl Add for YearIndex { type Output = Self; fn add(self, rhs: usize) -> Self::Output { - Self::from(self.0 + rhs as u16) + Self::from(self.0 + rhs as u8) } } @@ -92,11 +92,11 @@ impl From for YearIndex { impl From for YearIndex { #[inline] fn from(value: Date) -> Self { - Self(value.year() - 2009) + Self((value.year() - 2009) as u8) } } -impl From for u16 { +impl From for u8 { #[inline] fn from(value: YearIndex) -> Self { value.0 @@ -112,7 +112,7 @@ impl CheckedSub for YearIndex { impl From for YearIndex { #[inline] fn from(value: MonthIndex) -> Self { - Self((usize::from(value) / 12) as u16) + Self((usize::from(value) / 12) as u8) } } diff --git a/modules/brk-client/index.js b/modules/brk-client/index.js index a36623ef9..099f40253 100644 --- a/modules/brk-client/index.js +++ b/modules/brk-client/index.js @@ -606,7 +606,7 @@ */ /** @typedef {number} SemesterIndex */ /** - * Fixed-size boolean value optimized for on-disk storage (stored as u16) + * Fixed-size boolean value optimized for on-disk storage (stored as u8) * * @typedef {number} StoredBool */ @@ -620,7 +620,7 @@ * * @typedef {number} StoredF64 */ -/** @typedef {number} StoredI16 */ +/** @typedef {number} StoredI8 */ /** @typedef {number} StoredU16 */ /** * Fixed-size 32-bit unsigned integer optimized for on-disk storage @@ -839,11 +839,9 @@ class BrkError extends Error { /** * @template T * @typedef {Object} MetricData - * @property {number} version - Data version number * @property {number} total - Total number of data points * @property {number} start - Start index (inclusive) * @property {number} end - End index (exclusive) - * @property {string} stamp - Last update timestamp (ISO 8601) * @property {T[]} data - The metric data */ /** @typedef {MetricData} AnyMetricData */ @@ -2032,17 +2030,17 @@ function createBitcoinPattern(client, acc) { */ function createClassAveragePricePattern(client, acc) { return { - _2015: createMetricPattern4(client, _m(acc, '2015_average_price')), - _2016: createMetricPattern4(client, _m(acc, '2016_average_price')), - _2017: createMetricPattern4(client, _m(acc, '2017_average_price')), - _2018: createMetricPattern4(client, _m(acc, '2018_average_price')), - _2019: createMetricPattern4(client, _m(acc, '2019_average_price')), - _2020: createMetricPattern4(client, _m(acc, '2020_average_price')), - _2021: createMetricPattern4(client, _m(acc, '2021_average_price')), - _2022: createMetricPattern4(client, _m(acc, '2022_average_price')), - _2023: createMetricPattern4(client, _m(acc, '2023_average_price')), - _2024: createMetricPattern4(client, _m(acc, '2024_average_price')), - _2025: createMetricPattern4(client, _m(acc, '2025_average_price')), + _2015: createMetricPattern4(client, _m(acc, '2015_returns')), + _2016: createMetricPattern4(client, _m(acc, '2016_returns')), + _2017: createMetricPattern4(client, _m(acc, '2017_returns')), + _2018: createMetricPattern4(client, _m(acc, '2018_returns')), + _2019: createMetricPattern4(client, _m(acc, '2019_returns')), + _2020: createMetricPattern4(client, _m(acc, '2020_returns')), + _2021: createMetricPattern4(client, _m(acc, '2021_returns')), + _2022: createMetricPattern4(client, _m(acc, '2022_returns')), + _2023: createMetricPattern4(client, _m(acc, '2023_returns')), + _2024: createMetricPattern4(client, _m(acc, '2024_returns')), + _2025: createMetricPattern4(client, _m(acc, '2025_returns')), }; } @@ -2225,41 +2223,6 @@ function createAddrCountPattern(client, acc) { }; } -/** - * @template T - * @typedef {Object} FeeRatePattern - * @property {MetricPattern1} average - * @property {MetricPattern1} max - * @property {MetricPattern11} median - * @property {MetricPattern1} min - * @property {MetricPattern11} pct10 - * @property {MetricPattern11} pct25 - * @property {MetricPattern11} pct75 - * @property {MetricPattern11} pct90 - * @property {MetricPattern27} txindex - */ - -/** - * Create a FeeRatePattern pattern node - * @template T - * @param {BrkClientBase} client - * @param {string} acc - Accumulated metric name - * @returns {FeeRatePattern} - */ -function createFeeRatePattern(client, acc) { - return { - average: createMetricPattern1(client, _m(acc, 'average')), - max: createMetricPattern1(client, _m(acc, 'max')), - median: createMetricPattern11(client, _m(acc, 'median')), - min: createMetricPattern1(client, _m(acc, 'min')), - pct10: createMetricPattern11(client, _m(acc, 'pct10')), - pct25: createMetricPattern11(client, _m(acc, 'pct25')), - pct75: createMetricPattern11(client, _m(acc, 'pct75')), - pct90: createMetricPattern11(client, _m(acc, 'pct90')), - txindex: createMetricPattern27(client, acc), - }; -} - /** * @template T * @typedef {Object} FullnessPattern @@ -2295,6 +2258,41 @@ function createFullnessPattern(client, acc) { }; } +/** + * @template T + * @typedef {Object} FeeRatePattern + * @property {MetricPattern1} average + * @property {MetricPattern1} max + * @property {MetricPattern11} median + * @property {MetricPattern1} min + * @property {MetricPattern11} pct10 + * @property {MetricPattern11} pct25 + * @property {MetricPattern11} pct75 + * @property {MetricPattern11} pct90 + * @property {MetricPattern27} txindex + */ + +/** + * Create a FeeRatePattern pattern node + * @template T + * @param {BrkClientBase} client + * @param {string} acc - Accumulated metric name + * @returns {FeeRatePattern} + */ +function createFeeRatePattern(client, acc) { + return { + average: createMetricPattern1(client, _m(acc, 'average')), + max: createMetricPattern1(client, _m(acc, 'max')), + median: createMetricPattern11(client, _m(acc, 'median')), + min: createMetricPattern1(client, _m(acc, 'min')), + pct10: createMetricPattern11(client, _m(acc, 'pct10')), + pct25: createMetricPattern11(client, _m(acc, 'pct25')), + pct75: createMetricPattern11(client, _m(acc, 'pct75')), + pct90: createMetricPattern11(client, _m(acc, 'pct90')), + txindex: createMetricPattern27(client, acc), + }; +} + /** * @typedef {Object} _0satsPattern * @property {ActivityPattern2} activity @@ -2359,35 +2357,6 @@ function createPhaseDailyCentsPattern(client, acc) { }; } -/** - * @typedef {Object} PeriodCagrPattern - * @property {MetricPattern4} _10y - * @property {MetricPattern4} _2y - * @property {MetricPattern4} _3y - * @property {MetricPattern4} _4y - * @property {MetricPattern4} _5y - * @property {MetricPattern4} _6y - * @property {MetricPattern4} _8y - */ - -/** - * Create a PeriodCagrPattern pattern node - * @param {BrkClientBase} client - * @param {string} acc - Accumulated metric name - * @returns {PeriodCagrPattern} - */ -function createPeriodCagrPattern(client, acc) { - return { - _10y: createMetricPattern4(client, _p('10y', acc)), - _2y: createMetricPattern4(client, _p('2y', acc)), - _3y: createMetricPattern4(client, _p('3y', acc)), - _4y: createMetricPattern4(client, _p('4y', acc)), - _5y: createMetricPattern4(client, _p('5y', acc)), - _6y: createMetricPattern4(client, _p('6y', acc)), - _8y: createMetricPattern4(client, _p('8y', acc)), - }; -} - /** * @typedef {Object} _10yTo12yPattern * @property {ActivityPattern2} activity @@ -2533,6 +2502,35 @@ function createUnrealizedPattern(client, acc) { }; } +/** + * @typedef {Object} PeriodCagrPattern + * @property {MetricPattern4} _10y + * @property {MetricPattern4} _2y + * @property {MetricPattern4} _3y + * @property {MetricPattern4} _4y + * @property {MetricPattern4} _5y + * @property {MetricPattern4} _6y + * @property {MetricPattern4} _8y + */ + +/** + * Create a PeriodCagrPattern pattern node + * @param {BrkClientBase} client + * @param {string} acc - Accumulated metric name + * @returns {PeriodCagrPattern} + */ +function createPeriodCagrPattern(client, acc) { + return { + _10y: createMetricPattern4(client, _p('10y', acc)), + _2y: createMetricPattern4(client, _p('2y', acc)), + _3y: createMetricPattern4(client, _p('3y', acc)), + _4y: createMetricPattern4(client, _p('4y', acc)), + _5y: createMetricPattern4(client, _p('5y', acc)), + _6y: createMetricPattern4(client, _p('6y', acc)), + _8y: createMetricPattern4(client, _p('8y', acc)), + }; +} + /** * @typedef {Object} ActivityPattern2 * @property {BlockCountPattern} coinblocksDestroyed @@ -2584,23 +2582,23 @@ function createSplitPattern2(client, acc) { } /** - * @typedef {Object} CoinbasePattern - * @property {BitcoinPattern} bitcoin - * @property {DollarsPattern} dollars - * @property {DollarsPattern} sats + * @typedef {Object} CostBasisPattern2 + * @property {MetricPattern1} max + * @property {MetricPattern1} min + * @property {PercentilesPattern} percentiles */ /** - * Create a CoinbasePattern pattern node + * Create a CostBasisPattern2 pattern node * @param {BrkClientBase} client * @param {string} acc - Accumulated metric name - * @returns {CoinbasePattern} + * @returns {CostBasisPattern2} */ -function createCoinbasePattern(client, acc) { +function createCostBasisPattern2(client, acc) { return { - bitcoin: createBitcoinPattern(client, _m(acc, 'btc')), - dollars: createDollarsPattern(client, _m(acc, 'usd')), - sats: createDollarsPattern(client, acc), + max: createMetricPattern1(client, _m(acc, 'max_cost_basis')), + min: createMetricPattern1(client, _m(acc, 'min_cost_basis')), + percentiles: createPercentilesPattern(client, _m(acc, 'cost_basis')), }; } @@ -2625,6 +2623,27 @@ function createCoinbasePattern2(client, acc) { }; } +/** + * @typedef {Object} ActiveSupplyPattern + * @property {MetricPattern1} bitcoin + * @property {MetricPattern1} dollars + * @property {MetricPattern1} sats + */ + +/** + * Create a ActiveSupplyPattern pattern node + * @param {BrkClientBase} client + * @param {string} acc - Accumulated metric name + * @returns {ActiveSupplyPattern} + */ +function createActiveSupplyPattern(client, acc) { + return { + bitcoin: createMetricPattern1(client, _m(acc, 'btc')), + dollars: createMetricPattern1(client, _m(acc, 'usd')), + sats: createMetricPattern1(client, acc), + }; +} + /** * @typedef {Object} SegwitAdoptionPattern * @property {MetricPattern11} base @@ -2646,27 +2665,6 @@ function createSegwitAdoptionPattern(client, acc) { }; } -/** - * @typedef {Object} CostBasisPattern2 - * @property {MetricPattern1} max - * @property {MetricPattern1} min - * @property {PercentilesPattern} percentiles - */ - -/** - * Create a CostBasisPattern2 pattern node - * @param {BrkClientBase} client - * @param {string} acc - Accumulated metric name - * @returns {CostBasisPattern2} - */ -function createCostBasisPattern2(client, acc) { - return { - max: createMetricPattern1(client, _m(acc, 'max_cost_basis')), - min: createMetricPattern1(client, _m(acc, 'min_cost_basis')), - percentiles: createPercentilesPattern(client, _m(acc, 'cost_basis')), - }; -} - /** * @typedef {Object} UnclaimedRewardsPattern * @property {BitcoinPattern2} bitcoin @@ -2710,23 +2708,23 @@ function create_2015Pattern(client, acc) { } /** - * @typedef {Object} ActiveSupplyPattern - * @property {MetricPattern1} bitcoin - * @property {MetricPattern1} dollars - * @property {MetricPattern1} sats + * @typedef {Object} CoinbasePattern + * @property {BitcoinPattern} bitcoin + * @property {DollarsPattern} dollars + * @property {DollarsPattern} sats */ /** - * Create a ActiveSupplyPattern pattern node + * Create a CoinbasePattern pattern node * @param {BrkClientBase} client * @param {string} acc - Accumulated metric name - * @returns {ActiveSupplyPattern} + * @returns {CoinbasePattern} */ -function createActiveSupplyPattern(client, acc) { +function createCoinbasePattern(client, acc) { return { - bitcoin: createMetricPattern1(client, _m(acc, 'btc')), - dollars: createMetricPattern1(client, _m(acc, 'usd')), - sats: createMetricPattern1(client, acc), + bitcoin: createBitcoinPattern(client, _m(acc, 'btc')), + dollars: createDollarsPattern(client, _m(acc, 'usd')), + sats: createDollarsPattern(client, acc), }; } @@ -2749,25 +2747,6 @@ function create_1dReturns1mSdPattern(client, acc) { }; } -/** - * @typedef {Object} SupplyPattern2 - * @property {ActiveSupplyPattern} halved - * @property {ActiveSupplyPattern} total - */ - -/** - * Create a SupplyPattern2 pattern node - * @param {BrkClientBase} client - * @param {string} acc - Accumulated metric name - * @returns {SupplyPattern2} - */ -function createSupplyPattern2(client, acc) { - return { - halved: createActiveSupplyPattern(client, _m(acc, 'halved')), - total: createActiveSupplyPattern(client, acc), - }; -} - /** * @typedef {Object} CostBasisPattern * @property {MetricPattern1} max @@ -2806,6 +2785,25 @@ function createRelativePattern4(client, acc) { }; } +/** + * @typedef {Object} SupplyPattern2 + * @property {ActiveSupplyPattern} halved + * @property {ActiveSupplyPattern} total + */ + +/** + * Create a SupplyPattern2 pattern node + * @param {BrkClientBase} client + * @param {string} acc - Accumulated metric name + * @returns {SupplyPattern2} + */ +function createSupplyPattern2(client, acc) { + return { + halved: createActiveSupplyPattern(client, _m(acc, 'halved')), + total: createActiveSupplyPattern(client, acc), + }; +} + /** * @template T * @typedef {Object} BitcoinPattern2 @@ -2827,27 +2825,6 @@ function createBitcoinPattern2(client, acc) { }; } -/** - * @template T - * @typedef {Object} SatsPattern - * @property {MetricPattern1} ohlc - * @property {SplitPattern2} split - */ - -/** - * Create a SatsPattern pattern node - * @template T - * @param {BrkClientBase} client - * @param {string} acc - Accumulated metric name - * @returns {SatsPattern} - */ -function createSatsPattern(client, acc) { - return { - ohlc: createMetricPattern1(client, _m(acc, 'ohlc_sats')), - split: createSplitPattern2(client, _m(acc, 'sats')), - }; -} - /** * @template T * @typedef {Object} BlockCountPattern @@ -2869,6 +2846,27 @@ function createBlockCountPattern(client, acc) { }; } +/** + * @template T + * @typedef {Object} SatsPattern + * @property {MetricPattern1} ohlc + * @property {SplitPattern2} split + */ + +/** + * Create a SatsPattern pattern node + * @template T + * @param {BrkClientBase} client + * @param {string} acc - Accumulated metric name + * @returns {SatsPattern} + */ +function createSatsPattern(client, acc) { + return { + ohlc: createMetricPattern1(client, _m(acc, 'ohlc_sats')), + split: createSplitPattern2(client, _m(acc, 'sats')), + }; +} + /** * @typedef {Object} RealizedPriceExtraPattern * @property {MetricPattern4} ratio @@ -3126,10 +3124,10 @@ function createOutputsPattern(client, acc) { * @property {MetricPattern1} constant618 * @property {MetricPattern1} constant70 * @property {MetricPattern1} constant80 - * @property {MetricPattern1} constantMinus1 - * @property {MetricPattern1} constantMinus2 - * @property {MetricPattern1} constantMinus3 - * @property {MetricPattern1} constantMinus4 + * @property {MetricPattern1} constantMinus1 + * @property {MetricPattern1} constantMinus2 + * @property {MetricPattern1} constantMinus3 + * @property {MetricPattern1} constantMinus4 */ /** @@ -3698,8 +3696,8 @@ function createOutputsPattern(client, acc) { /** * @typedef {Object} MetricsTree_Market_Dca - * @property {ClassAveragePricePattern} classAveragePrice - * @property {MetricsTree_Market_Dca_ClassReturns} classReturns + * @property {MetricsTree_Market_Dca_ClassAveragePrice} classAveragePrice + * @property {ClassAveragePricePattern} classReturns * @property {MetricsTree_Market_Dca_ClassStack} classStack * @property {PeriodAveragePricePattern} periodAveragePrice * @property {PeriodCagrPattern} periodCagr @@ -3709,18 +3707,18 @@ function createOutputsPattern(client, acc) { */ /** - * @typedef {Object} MetricsTree_Market_Dca_ClassReturns - * @property {MetricPattern4} _2015 - * @property {MetricPattern4} _2016 - * @property {MetricPattern4} _2017 - * @property {MetricPattern4} _2018 - * @property {MetricPattern4} _2019 - * @property {MetricPattern4} _2020 - * @property {MetricPattern4} _2021 - * @property {MetricPattern4} _2022 - * @property {MetricPattern4} _2023 - * @property {MetricPattern4} _2024 - * @property {MetricPattern4} _2025 + * @typedef {Object} MetricsTree_Market_Dca_ClassAveragePrice + * @property {MetricPattern4} _2015 + * @property {MetricPattern4} _2016 + * @property {MetricPattern4} _2017 + * @property {MetricPattern4} _2018 + * @property {MetricPattern4} _2019 + * @property {MetricPattern4} _2020 + * @property {MetricPattern4} _2021 + * @property {MetricPattern4} _2022 + * @property {MetricPattern4} _2023 + * @property {MetricPattern4} _2024 + * @property {MetricPattern4} _2025 */ /** @@ -5728,20 +5726,20 @@ class BrkClient extends BrkClientBase { yearsSincePriceAth: createMetricPattern4(this, 'years_since_price_ath'), }, dca: { - classAveragePrice: createClassAveragePricePattern(this, 'dca_class'), - classReturns: { - _2015: createMetricPattern4(this, 'dca_class_2015_returns'), - _2016: createMetricPattern4(this, 'dca_class_2016_returns'), - _2017: createMetricPattern4(this, 'dca_class_2017_returns'), - _2018: createMetricPattern4(this, 'dca_class_2018_returns'), - _2019: createMetricPattern4(this, 'dca_class_2019_returns'), - _2020: createMetricPattern4(this, 'dca_class_2020_returns'), - _2021: createMetricPattern4(this, 'dca_class_2021_returns'), - _2022: createMetricPattern4(this, 'dca_class_2022_returns'), - _2023: createMetricPattern4(this, 'dca_class_2023_returns'), - _2024: createMetricPattern4(this, 'dca_class_2024_returns'), - _2025: createMetricPattern4(this, 'dca_class_2025_returns'), + classAveragePrice: { + _2015: createMetricPattern4(this, 'dca_class_2015_average_price'), + _2016: createMetricPattern4(this, 'dca_class_2016_average_price'), + _2017: createMetricPattern4(this, 'dca_class_2017_average_price'), + _2018: createMetricPattern4(this, 'dca_class_2018_average_price'), + _2019: createMetricPattern4(this, 'dca_class_2019_average_price'), + _2020: createMetricPattern4(this, 'dca_class_2020_average_price'), + _2021: createMetricPattern4(this, 'dca_class_2021_average_price'), + _2022: createMetricPattern4(this, 'dca_class_2022_average_price'), + _2023: createMetricPattern4(this, 'dca_class_2023_average_price'), + _2024: createMetricPattern4(this, 'dca_class_2024_average_price'), + _2025: createMetricPattern4(this, 'dca_class_2025_average_price'), }, + classReturns: createClassAveragePricePattern(this, 'dca_class'), classStack: { _2015: create_2015Pattern(this, 'dca_class_2015_stack'), _2016: create_2015Pattern(this, 'dca_class_2016_stack'), diff --git a/packages/brk_client/brk_client/__init__.py b/packages/brk_client/brk_client/__init__.py index 0236f056f..9bf209c65 100644 --- a/packages/brk_client/brk_client/__init__.py +++ b/packages/brk_client/brk_client/__init__.py @@ -106,13 +106,13 @@ QuarterIndex = int # Transaction locktime RawLockTime = int SemesterIndex = int -# Fixed-size boolean value optimized for on-disk storage (stored as u16) +# Fixed-size boolean value optimized for on-disk storage (stored as u8) StoredBool = int # Stored 32-bit floating point value StoredF32 = float # Fixed-size 64-bit floating point value optimized for on-disk storage StoredF64 = float -StoredI16 = int +StoredI8 = int StoredU16 = int # Fixed-size 32-bit unsigned integer optimized for on-disk storage StoredU32 = int @@ -2054,17 +2054,17 @@ class ClassAveragePricePattern(Generic[T]): def __init__(self, client: BrkClientBase, acc: str): """Create pattern node with accumulated metric name.""" - self._2015: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2015_average_price')) - self._2016: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2016_average_price')) - self._2017: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2017_average_price')) - self._2018: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2018_average_price')) - self._2019: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2019_average_price')) - self._2020: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2020_average_price')) - self._2021: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2021_average_price')) - self._2022: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2022_average_price')) - self._2023: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2023_average_price')) - self._2024: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2024_average_price')) - self._2025: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2025_average_price')) + self._2015: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2015_returns')) + self._2016: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2016_returns')) + self._2017: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2017_returns')) + self._2018: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2018_returns')) + self._2019: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2019_returns')) + self._2020: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2020_returns')) + self._2021: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2021_returns')) + self._2022: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2022_returns')) + self._2023: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2023_returns')) + self._2024: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2024_returns')) + self._2025: MetricPattern4[T] = MetricPattern4(client, _m(acc, '2025_returns')) class DollarsPattern(Generic[T]): """Pattern struct for repeated tree structure.""" @@ -2146,21 +2146,6 @@ class AddrCountPattern: self.p2wpkh: MetricPattern1[StoredU64] = MetricPattern1(client, _p('p2wpkh', acc)) self.p2wsh: MetricPattern1[StoredU64] = MetricPattern1(client, _p('p2wsh', acc)) -class FeeRatePattern(Generic[T]): - """Pattern struct for repeated tree structure.""" - - def __init__(self, client: BrkClientBase, acc: str): - """Create pattern node with accumulated metric name.""" - self.average: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'average')) - self.max: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'max')) - self.median: MetricPattern11[T] = MetricPattern11(client, _m(acc, 'median')) - self.min: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'min')) - self.pct10: MetricPattern11[T] = MetricPattern11(client, _m(acc, 'pct10')) - self.pct25: MetricPattern11[T] = MetricPattern11(client, _m(acc, 'pct25')) - self.pct75: MetricPattern11[T] = MetricPattern11(client, _m(acc, 'pct75')) - self.pct90: MetricPattern11[T] = MetricPattern11(client, _m(acc, 'pct90')) - self.txindex: MetricPattern27[T] = MetricPattern27(client, acc) - class FullnessPattern(Generic[T]): """Pattern struct for repeated tree structure.""" @@ -2176,6 +2161,21 @@ class FullnessPattern(Generic[T]): self.pct75: MetricPattern6[T] = MetricPattern6(client, _m(acc, 'pct75')) self.pct90: MetricPattern6[T] = MetricPattern6(client, _m(acc, 'pct90')) +class FeeRatePattern(Generic[T]): + """Pattern struct for repeated tree structure.""" + + def __init__(self, client: BrkClientBase, acc: str): + """Create pattern node with accumulated metric name.""" + self.average: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'average')) + self.max: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'max')) + self.median: MetricPattern11[T] = MetricPattern11(client, _m(acc, 'median')) + self.min: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'min')) + self.pct10: MetricPattern11[T] = MetricPattern11(client, _m(acc, 'pct10')) + self.pct25: MetricPattern11[T] = MetricPattern11(client, _m(acc, 'pct25')) + self.pct75: MetricPattern11[T] = MetricPattern11(client, _m(acc, 'pct75')) + self.pct90: MetricPattern11[T] = MetricPattern11(client, _m(acc, 'pct90')) + self.txindex: MetricPattern27[T] = MetricPattern27(client, acc) + class _0satsPattern: """Pattern struct for repeated tree structure.""" @@ -2204,19 +2204,6 @@ class PhaseDailyCentsPattern(Generic[T]): self.pct75: MetricPattern6[T] = MetricPattern6(client, _m(acc, 'pct75')) self.pct90: MetricPattern6[T] = MetricPattern6(client, _m(acc, 'pct90')) -class PeriodCagrPattern: - """Pattern struct for repeated tree structure.""" - - def __init__(self, client: BrkClientBase, acc: str): - """Create pattern node with accumulated metric name.""" - self._10y: MetricPattern4[StoredF32] = MetricPattern4(client, _p('10y', acc)) - self._2y: MetricPattern4[StoredF32] = MetricPattern4(client, _p('2y', acc)) - self._3y: MetricPattern4[StoredF32] = MetricPattern4(client, _p('3y', acc)) - self._4y: MetricPattern4[StoredF32] = MetricPattern4(client, _p('4y', acc)) - self._5y: MetricPattern4[StoredF32] = MetricPattern4(client, _p('5y', acc)) - self._6y: MetricPattern4[StoredF32] = MetricPattern4(client, _p('6y', acc)) - self._8y: MetricPattern4[StoredF32] = MetricPattern4(client, _p('8y', acc)) - class _10yTo12yPattern: """Pattern struct for repeated tree structure.""" @@ -2282,6 +2269,19 @@ class UnrealizedPattern: self.unrealized_loss: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'unrealized_loss')) self.unrealized_profit: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'unrealized_profit')) +class PeriodCagrPattern: + """Pattern struct for repeated tree structure.""" + + def __init__(self, client: BrkClientBase, acc: str): + """Create pattern node with accumulated metric name.""" + self._10y: MetricPattern4[StoredF32] = MetricPattern4(client, _p('10y', acc)) + self._2y: MetricPattern4[StoredF32] = MetricPattern4(client, _p('2y', acc)) + self._3y: MetricPattern4[StoredF32] = MetricPattern4(client, _p('3y', acc)) + self._4y: MetricPattern4[StoredF32] = MetricPattern4(client, _p('4y', acc)) + self._5y: MetricPattern4[StoredF32] = MetricPattern4(client, _p('5y', acc)) + self._6y: MetricPattern4[StoredF32] = MetricPattern4(client, _p('6y', acc)) + self._8y: MetricPattern4[StoredF32] = MetricPattern4(client, _p('8y', acc)) + class ActivityPattern2: """Pattern struct for repeated tree structure.""" @@ -2303,14 +2303,14 @@ class SplitPattern2(Generic[T]): self.low: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'low')) self.open: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'open')) -class CoinbasePattern: +class CostBasisPattern2: """Pattern struct for repeated tree structure.""" def __init__(self, client: BrkClientBase, acc: str): """Create pattern node with accumulated metric name.""" - self.bitcoin: BitcoinPattern = BitcoinPattern(client, _m(acc, 'btc')) - self.dollars: DollarsPattern[Dollars] = DollarsPattern(client, _m(acc, 'usd')) - self.sats: DollarsPattern[Sats] = DollarsPattern(client, acc) + self.max: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'max_cost_basis')) + self.min: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'min_cost_basis')) + self.percentiles: PercentilesPattern = PercentilesPattern(client, _m(acc, 'cost_basis')) class CoinbasePattern2: """Pattern struct for repeated tree structure.""" @@ -2321,6 +2321,15 @@ class CoinbasePattern2: self.dollars: BlockCountPattern[Dollars] = BlockCountPattern(client, _m(acc, 'usd')) self.sats: BlockCountPattern[Sats] = BlockCountPattern(client, acc) +class ActiveSupplyPattern: + """Pattern struct for repeated tree structure.""" + + def __init__(self, client: BrkClientBase, acc: str): + """Create pattern node with accumulated metric name.""" + self.bitcoin: MetricPattern1[Bitcoin] = MetricPattern1(client, _m(acc, 'btc')) + self.dollars: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'usd')) + self.sats: MetricPattern1[Sats] = MetricPattern1(client, acc) + class SegwitAdoptionPattern: """Pattern struct for repeated tree structure.""" @@ -2330,15 +2339,6 @@ class SegwitAdoptionPattern: self.cumulative: MetricPattern2[StoredF32] = MetricPattern2(client, _m(acc, 'cumulative')) self.sum: MetricPattern2[StoredF32] = MetricPattern2(client, _m(acc, 'sum')) -class CostBasisPattern2: - """Pattern struct for repeated tree structure.""" - - def __init__(self, client: BrkClientBase, acc: str): - """Create pattern node with accumulated metric name.""" - self.max: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'max_cost_basis')) - self.min: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'min_cost_basis')) - self.percentiles: PercentilesPattern = PercentilesPattern(client, _m(acc, 'cost_basis')) - class UnclaimedRewardsPattern: """Pattern struct for repeated tree structure.""" @@ -2357,14 +2357,14 @@ class _2015Pattern: self.dollars: MetricPattern4[Dollars] = MetricPattern4(client, _m(acc, 'usd')) self.sats: MetricPattern4[Sats] = MetricPattern4(client, acc) -class ActiveSupplyPattern: +class CoinbasePattern: """Pattern struct for repeated tree structure.""" def __init__(self, client: BrkClientBase, acc: str): """Create pattern node with accumulated metric name.""" - self.bitcoin: MetricPattern1[Bitcoin] = MetricPattern1(client, _m(acc, 'btc')) - self.dollars: MetricPattern1[Dollars] = MetricPattern1(client, _m(acc, 'usd')) - self.sats: MetricPattern1[Sats] = MetricPattern1(client, acc) + self.bitcoin: BitcoinPattern = BitcoinPattern(client, _m(acc, 'btc')) + self.dollars: DollarsPattern[Dollars] = DollarsPattern(client, _m(acc, 'usd')) + self.sats: DollarsPattern[Sats] = DollarsPattern(client, acc) class _1dReturns1mSdPattern: """Pattern struct for repeated tree structure.""" @@ -2374,14 +2374,6 @@ class _1dReturns1mSdPattern: self.sd: MetricPattern4[StoredF32] = MetricPattern4(client, _m(acc, 'sd')) self.sma: MetricPattern4[StoredF32] = MetricPattern4(client, _m(acc, 'sma')) -class SupplyPattern2: - """Pattern struct for repeated tree structure.""" - - def __init__(self, client: BrkClientBase, acc: str): - """Create pattern node with accumulated metric name.""" - self.halved: ActiveSupplyPattern = ActiveSupplyPattern(client, _m(acc, 'halved')) - self.total: ActiveSupplyPattern = ActiveSupplyPattern(client, acc) - class CostBasisPattern: """Pattern struct for repeated tree structure.""" @@ -2398,6 +2390,14 @@ class RelativePattern4: self.supply_in_loss_rel_to_own_supply: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'loss_rel_to_own_supply')) self.supply_in_profit_rel_to_own_supply: MetricPattern1[StoredF64] = MetricPattern1(client, _m(acc, 'profit_rel_to_own_supply')) +class SupplyPattern2: + """Pattern struct for repeated tree structure.""" + + def __init__(self, client: BrkClientBase, acc: str): + """Create pattern node with accumulated metric name.""" + self.halved: ActiveSupplyPattern = ActiveSupplyPattern(client, _m(acc, 'halved')) + self.total: ActiveSupplyPattern = ActiveSupplyPattern(client, acc) + class BitcoinPattern2(Generic[T]): """Pattern struct for repeated tree structure.""" @@ -2406,6 +2406,14 @@ class BitcoinPattern2(Generic[T]): self.cumulative: MetricPattern2[T] = MetricPattern2(client, _m(acc, 'cumulative')) self.sum: MetricPattern1[T] = MetricPattern1(client, acc) +class BlockCountPattern(Generic[T]): + """Pattern struct for repeated tree structure.""" + + def __init__(self, client: BrkClientBase, acc: str): + """Create pattern node with accumulated metric name.""" + self.cumulative: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'cumulative')) + self.sum: MetricPattern1[T] = MetricPattern1(client, acc) + class SatsPattern(Generic[T]): """Pattern struct for repeated tree structure.""" @@ -2414,14 +2422,6 @@ class SatsPattern(Generic[T]): self.ohlc: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'ohlc_sats')) self.split: SplitPattern2[T] = SplitPattern2(client, _m(acc, 'sats')) -class BlockCountPattern(Generic[T]): - """Pattern struct for repeated tree structure.""" - - def __init__(self, client: BrkClientBase, acc: str): - """Create pattern node with accumulated metric name.""" - self.cumulative: MetricPattern1[T] = MetricPattern1(client, _m(acc, 'cumulative')) - self.sum: MetricPattern1[T] = MetricPattern1(client, acc) - class RealizedPriceExtraPattern: """Pattern struct for repeated tree structure.""" @@ -2659,10 +2659,10 @@ class MetricsTree_Constants: self.constant_61_8: MetricPattern1[StoredF32] = MetricPattern1(client, 'constant_61_8') self.constant_70: MetricPattern1[StoredU16] = MetricPattern1(client, 'constant_70') self.constant_80: MetricPattern1[StoredU16] = MetricPattern1(client, 'constant_80') - self.constant_minus_1: MetricPattern1[StoredI16] = MetricPattern1(client, 'constant_minus_1') - self.constant_minus_2: MetricPattern1[StoredI16] = MetricPattern1(client, 'constant_minus_2') - self.constant_minus_3: MetricPattern1[StoredI16] = MetricPattern1(client, 'constant_minus_3') - self.constant_minus_4: MetricPattern1[StoredI16] = MetricPattern1(client, 'constant_minus_4') + self.constant_minus_1: MetricPattern1[StoredI8] = MetricPattern1(client, 'constant_minus_1') + self.constant_minus_2: MetricPattern1[StoredI8] = MetricPattern1(client, 'constant_minus_2') + self.constant_minus_3: MetricPattern1[StoredI8] = MetricPattern1(client, 'constant_minus_3') + self.constant_minus_4: MetricPattern1[StoredI8] = MetricPattern1(client, 'constant_minus_4') class MetricsTree_Distribution_AddressCohorts_AmountRange: """Metrics tree node.""" @@ -3269,21 +3269,21 @@ class MetricsTree_Market_Ath: self.price_drawdown: MetricPattern3[StoredF32] = MetricPattern3(client, 'price_drawdown') self.years_since_price_ath: MetricPattern4[StoredF32] = MetricPattern4(client, 'years_since_price_ath') -class MetricsTree_Market_Dca_ClassReturns: +class MetricsTree_Market_Dca_ClassAveragePrice: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): - self._2015: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2015_returns') - self._2016: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2016_returns') - self._2017: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2017_returns') - self._2018: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2018_returns') - self._2019: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2019_returns') - self._2020: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2020_returns') - self._2021: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2021_returns') - self._2022: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2022_returns') - self._2023: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2023_returns') - self._2024: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2024_returns') - self._2025: MetricPattern4[StoredF32] = MetricPattern4(client, 'dca_class_2025_returns') + self._2015: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2015_average_price') + self._2016: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2016_average_price') + self._2017: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2017_average_price') + self._2018: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2018_average_price') + self._2019: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2019_average_price') + self._2020: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2020_average_price') + self._2021: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2021_average_price') + self._2022: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2022_average_price') + self._2023: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2023_average_price') + self._2024: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2024_average_price') + self._2025: MetricPattern4[Dollars] = MetricPattern4(client, 'dca_class_2025_average_price') class MetricsTree_Market_Dca_ClassStack: """Metrics tree node.""" @@ -3305,8 +3305,8 @@ class MetricsTree_Market_Dca: """Metrics tree node.""" def __init__(self, client: BrkClientBase, base_path: str = ''): - self.class_average_price: ClassAveragePricePattern[Dollars] = ClassAveragePricePattern(client, 'dca_class') - self.class_returns: MetricsTree_Market_Dca_ClassReturns = MetricsTree_Market_Dca_ClassReturns(client) + self.class_average_price: MetricsTree_Market_Dca_ClassAveragePrice = MetricsTree_Market_Dca_ClassAveragePrice(client) + self.class_returns: ClassAveragePricePattern[StoredF32] = ClassAveragePricePattern(client, 'dca_class') self.class_stack: MetricsTree_Market_Dca_ClassStack = MetricsTree_Market_Dca_ClassStack(client) self.period_average_price: PeriodAveragePricePattern[Dollars] = PeriodAveragePricePattern(client, 'dca_average_price') self.period_cagr: PeriodCagrPattern = PeriodCagrPattern(client, 'dca_cagr') diff --git a/website/.gitignore b/website/.gitignore index 66e8bf274..4c0699949 100644 --- a/website/.gitignore +++ b/website/.gitignore @@ -1 +1,3 @@ */**/*.md +!scripts/**/_*.js +*_old.js diff --git a/website/scripts/chart/index.js b/website/scripts/chart/index.js index 9570e6593..1a04645a2 100644 --- a/website/scripts/chart/index.js +++ b/website/scripts/chart/index.js @@ -1,5 +1,6 @@ import { createChart as _createChart, + createSeriesMarkers, CandlestickSeries, HistogramSeries, LineSeries, @@ -35,15 +36,15 @@ import { resources } from "../resources.js"; * @template T * @typedef {Object} Series * @property {string} id - * @property {() => ISeries} inner * @property {number} paneIndex * @property {Signal} active + * @property {Signal} highlighted * @property {Signal} hasData * @property {Signal} url - * @property {() => Record} getOptions - * @property {(options: Record) => void} applyOptions * @property {() => readonly T[]} getData * @property {(data: T) => void} update + * @property {(markers: TimeSeriesMarker[]) => void} setMarkers + * @property {VoidFunction} clearMarkers * @property {VoidFunction} remove */ @@ -97,6 +98,10 @@ export function createChartElement({ div.classList.add("chart"); parent.append(div); + // Registry for shared legend signals (same name = linked across panes) + /** @type {Map>} */ + const sharedActiveSignals = new Map(); + const legendTop = createLegend(signals); div.append(legendTop.element); @@ -165,7 +170,10 @@ export function createChartElement({ }); }; - const seriesList = signals.createSignal(/** @type {Set} */ (new Set()), { equals: false }); + const seriesList = signals.createSignal( + /** @type {Set} */ (new Set()), + { equals: false }, + ); const seriesCount = signals.createMemo(() => seriesList().size); const markers = createMinMaxMarkers({ chart: ichart, @@ -186,7 +194,7 @@ export function createChartElement({ () => visibleBarsCountBucket() >= 2, ); const shouldUpdateMarkers = signals.createMemo( - () => visibleBarsCount() * seriesCount() <= 5000, + () => visibleBarsCount() * seriesCount() <= 20_000, ); signals.createEffect(shouldUpdateMarkers, (should) => { @@ -337,12 +345,20 @@ export function createChartElement({ paneIndex, position: "sw", createChild(pane) { - const { field, selected } = createChoiceField({ + const defaultValue = + unit.id === "usd" && seriesType !== "Baseline" ? "log" : "lin"; + const selected = signals.createPersistedSignal({ + defaultValue, + storageKey: `${id}-scale-${paneIndex}`, + urlKey: paneIndex === 0 ? "price_scale" : "unit_scale", + serialize: (v) => v, + deserialize: (s) => /** @type {"lin" | "log"} */ (s), + }); + const field = createChoiceField({ choices: /** @type {const} */ (["lin", "log"]), id: stringToId(`${id} ${paneIndex} ${unit}`), - defaultValue: - unit.id === "usd" && seriesType !== "Baseline" ? "log" : "lin", - key: `${id}-price-scale-${paneIndex}`, + defaultValue, + selected, signals, }); @@ -366,21 +382,19 @@ export function createChartElement({ * @param {number} args.order * @param {Color[]} args.colors * @param {LCSeriesType} args.seriesType - * @param {() => ISeries} args.inner * @param {AnyMetricPattern} [args.metric] * @param {Accessor} [args.data] * @param {number} args.paneIndex * @param {boolean} [args.defaultActive] - * @param {(ctx: { active: Signal }) => void} args.setup + * @param {(ctx: { active: Signal, highlighted: Signal }) => void} args.setup * @param {() => readonly any[]} args.getData * @param {(data: any[]) => void} args.setData * @param {(data: any) => void} args.update - * @param {() => Record} args.getOptions - * @param {(options: Record) => void} args.applyOptions + * @param {(markers: TimeSeriesMarker[]) => void} args.setMarkers + * @param {VoidFunction} args.clearMarkers * @param {() => void} args.onRemove */ function addSeries({ - inner, metric, name, unit, @@ -394,22 +408,34 @@ export function createChartElement({ getData, setData, update, - getOptions, - applyOptions, + setMarkers, + clearMarkers, onRemove, }) { return signals.createRoot((dispose) => { const id = `${stringToId(name)}-${paneIndex}`; + const urlId = stringToId(name); - const active = signals.createSignal(defaultActive ?? true, { - save: { - keyPrefix: "", - key: id, + // Reuse existing signal if same name (links legends across panes) + let active = sharedActiveSignals.get(urlId); + if (!active) { + active = signals.createPersistedSignal({ + defaultValue: defaultActive ?? true, + storageKey: id, + urlKey: urlId, ...serdeBool, - }, - }); + }); + sharedActiveSignals.set(urlId, active); + } - setup({ active }); + const highlighted = signals.createSignal(true); + + setup({ active, highlighted }); + + // Update markers when active changes + signals.createEffect(active, () => { + if (shouldUpdateMarkers()) markers.scheduleUpdate(); + }); const hasData = signals.createSignal(false); let lastTime = -Infinity; @@ -420,15 +446,15 @@ export function createChartElement({ /** @type {AnySeries} */ const series = { active, + highlighted, hasData, id, - inner, paneIndex, url: signals.createSignal(/** @type {string | null} */ (null)), - getOptions, - applyOptions, getData, update, + setMarkers, + clearMarkers, remove() { dispose(); onRemove(); @@ -705,8 +731,10 @@ export function createChartElement({ ) ); + // Marker plugin always on candlestick (has true min/max via high/low) + const markerPlugin = createSeriesMarkers(candlestickISeries, [], { autoScale: false }); + const series = addSeries({ - inner: () => (showLine ? lineISeries : candlestickISeries), colors: [upColor, downColor], name, order, @@ -716,22 +744,34 @@ export function createChartElement({ data, defaultActive, metric, - setup: ({ active }) => { + setup: ({ active, highlighted }) => { candlestickISeries.setSeriesOrder(order); lineISeries.setSeriesOrder(order); signals.createEffect( () => ({ shouldShow: shouldShowLine(), active: active(), + highlighted: highlighted(), barsCount: visibleBarsCount(), }), - ({ shouldShow, active, barsCount }) => { + ({ shouldShow, active, highlighted, barsCount }) => { if (barsCount === Infinity) return; const wasLine = showLine; showLine = shouldShow; - candlestickISeries.applyOptions({ visible: active && !showLine }); + // Use transparent when showing the other mode, otherwise use highlight + const up = showLine ? "transparent" : upColor.highlight(highlighted); + const down = showLine ? "transparent" : downColor.highlight(highlighted); + const line = showLine ? colors.default.highlight(highlighted) : "transparent"; + candlestickISeries.applyOptions({ + visible: active, + upColor: up, + downColor: down, + wickUpColor: up, + wickDownColor: down, + }); lineISeries.applyOptions({ - visible: active && showLine, + visible: active, + color: line, priceLineVisible: active && showLine, }); if (wasLine !== showLine && shouldUpdateMarkers()) @@ -749,12 +789,8 @@ export function createChartElement({ lineISeries.update({ time: data.time, value: data.close }); }, getData: () => candlestickISeries.data(), - getOptions: () => - showLine ? lineISeries.options() : candlestickISeries.options(), - applyOptions: (options) => - showLine - ? lineISeries.applyOptions(options) - : candlestickISeries.applyOptions(options), + setMarkers: (m) => markerPlugin.setMarkers(m), + clearMarkers: () => markerPlugin.setMarkers([]), onRemove: () => { ichart.removeSeries(candlestickISeries); ichart.removeSeries(lineISeries); @@ -803,8 +839,9 @@ export function createChartElement({ ) ); + const markerPlugin = createSeriesMarkers(iseries, [], { autoScale: false }); + const series = addSeries({ - inner: () => iseries, colors: isDualColor ? [positiveColor, negativeColor] : [positiveColor], name, order, @@ -814,10 +851,16 @@ export function createChartElement({ data, defaultActive, metric, - setup: ({ active }) => { + setup: ({ active, highlighted }) => { iseries.setSeriesOrder(order); - signals.createEffect(active, (active) => - iseries.applyOptions({ visible: active }), + signals.createEffect( + () => ({ active: active(), highlighted: highlighted() }), + ({ active, highlighted }) => { + iseries.applyOptions({ + visible: active, + color: positiveColor.highlight(highlighted), + }); + }, ); }, setData: (data) => { @@ -837,8 +880,8 @@ export function createChartElement({ }, update: (data) => iseries.update(data), getData: () => iseries.data(), - getOptions: () => iseries.options(), - applyOptions: (options) => iseries.applyOptions(options), + setMarkers: (m) => markerPlugin.setMarkers(m), + clearMarkers: () => markerPlugin.setMarkers([]), onRemove: () => ichart.removeSeries(iseries), }); return series; @@ -883,8 +926,9 @@ export function createChartElement({ ) ); + const markerPlugin = createSeriesMarkers(iseries, [], { autoScale: false }); + const series = addSeries({ - inner: () => iseries, colors: [color], name, order, @@ -894,17 +938,23 @@ export function createChartElement({ data, defaultActive, metric, - setup: ({ active }) => { + setup: ({ active, highlighted }) => { iseries.setSeriesOrder(order); - signals.createEffect(active, (active) => - iseries.applyOptions({ visible: active }), + signals.createEffect( + () => ({ active: active(), highlighted: highlighted() }), + ({ active, highlighted }) => { + iseries.applyOptions({ + visible: active, + color: color.highlight(highlighted), + }); + }, ); }, setData: (data) => iseries.setData(data), update: (data) => iseries.update(data), getData: () => iseries.data(), - getOptions: () => iseries.options(), - applyOptions: (options) => iseries.applyOptions(options), + setMarkers: (m) => markerPlugin.setMarkers(m), + clearMarkers: () => markerPlugin.setMarkers([]), onRemove: () => ichart.removeSeries(iseries), }); return series; @@ -951,8 +1001,9 @@ export function createChartElement({ ) ); + const markerPlugin = createSeriesMarkers(iseries, [], { autoScale: false }); + const series = addSeries({ - inner: () => iseries, colors: [color], name, order, @@ -962,10 +1013,16 @@ export function createChartElement({ data, defaultActive, metric, - setup: ({ active }) => { + setup: ({ active, highlighted }) => { iseries.setSeriesOrder(order); - signals.createEffect(active, (active) => - iseries.applyOptions({ visible: active }), + signals.createEffect( + () => ({ active: active(), highlighted: highlighted() }), + ({ active, highlighted }) => { + iseries.applyOptions({ + visible: active, + color: color.highlight(highlighted), + }); + }, ); signals.createEffect(visibleBarsCountBucket, (bucket) => { const radius = bucket === 3 ? 1 : bucket >= 1 ? 1.5 : 2; @@ -975,8 +1032,8 @@ export function createChartElement({ setData: (data) => iseries.setData(data), update: (data) => iseries.update(data), getData: () => iseries.data(), - getOptions: () => iseries.options(), - applyOptions: (options) => iseries.applyOptions(options), + setMarkers: (m) => markerPlugin.setMarkers(m), + clearMarkers: () => markerPlugin.setMarkers([]), onRemove: () => ichart.removeSeries(iseries), }); return series; @@ -990,6 +1047,8 @@ export function createChartElement({ * @param {AnyMetricPattern} [args.metric] * @param {number} [args.paneIndex] * @param {boolean} [args.defaultActive] + * @param {Color} [args.topColor] + * @param {Color} [args.bottomColor] * @param {BaselineSeriesPartialOptions} [args.options] */ addBaselineSeries({ @@ -1000,6 +1059,8 @@ export function createChartElement({ paneIndex: _paneIndex, defaultActive, data, + topColor = colors.green, + bottomColor = colors.red, options, }) { const paneIndex = _paneIndex ?? 0; @@ -1015,8 +1076,8 @@ export function createChartElement({ price: options?.baseValue?.price ?? 0, }, ...options, - topLineColor: options?.topLineColor ?? colors.green(), - bottomLineColor: options?.bottomLineColor ?? colors.red(), + topLineColor: topColor(), + bottomLineColor: bottomColor(), priceLineVisible: false, bottomFillColor1: "transparent", bottomFillColor2: "transparent", @@ -1028,12 +1089,10 @@ export function createChartElement({ ) ); + const markerPlugin = createSeriesMarkers(iseries, [], { autoScale: false }); + const series = addSeries({ - inner: () => iseries, - colors: [ - () => options?.topLineColor ?? colors.green(), - () => options?.bottomLineColor ?? colors.red(), - ], + colors: [topColor, bottomColor], name, order, paneIndex, @@ -1042,17 +1101,24 @@ export function createChartElement({ data, defaultActive, metric, - setup: ({ active }) => { + setup: ({ active, highlighted }) => { iseries.setSeriesOrder(order); - signals.createEffect(active, (active) => - iseries.applyOptions({ visible: active }), + signals.createEffect( + () => ({ active: active(), highlighted: highlighted() }), + ({ active, highlighted }) => { + iseries.applyOptions({ + visible: active, + topLineColor: topColor.highlight(highlighted), + bottomLineColor: bottomColor.highlight(highlighted), + }); + }, ); }, setData: (data) => iseries.setData(data), update: (data) => iseries.update(data), getData: () => iseries.data(), - getOptions: () => iseries.options(), - applyOptions: (options) => iseries.applyOptions(options), + setMarkers: (m) => markerPlugin.setMarkers(m), + clearMarkers: () => markerPlugin.setMarkers([]), onRemove: () => ichart.removeSeries(iseries), }); return series; diff --git a/website/scripts/chart/legend.js b/website/scripts/chart/legend.js index 1a09a12f2..93d5b5efe 100644 --- a/website/scripts/chart/legend.js +++ b/website/scripts/chart/legend.js @@ -1,9 +1,6 @@ import { createLabeledInput, createSpanName } from "../utils/dom.js"; import { stringToId } from "../utils/format.js"; -/** @param {string} color */ -const tameColor = (color) => `${color.slice(0, -1)} / 50%)`; - /** * @param {Signals} signals */ @@ -52,6 +49,11 @@ export function createLegend(signals) { type: "checkbox", }); + // Sync checkbox with signal (for shared signals across panes) + signals.createEffect(series.active, (active) => { + input.checked = active; + }); + const spanMain = window.document.createElement("span"); spanMain.classList.add("main"); label.append(spanMain); @@ -72,6 +74,11 @@ export function createLegend(signals) { const shouldHighlight = () => !hovered() || hovered() === series; + // Update series highlighted state + signals.createEffect(shouldHighlight, (shouldHighlight) => { + series.highlighted.set(shouldHighlight); + }); + const spanColors = window.document.createElement("span"); spanColors.classList.add("colors"); spanMain.prepend(spanColors); @@ -80,45 +87,13 @@ export function createLegend(signals) { spanColors.append(spanColor); signals.createEffect( - () => ({ - color: color(), - shouldHighlight: shouldHighlight(), - }), - ({ color, shouldHighlight }) => { - if (shouldHighlight) { - spanColor.style.backgroundColor = color; - } else { - spanColor.style.backgroundColor = tameColor(color); - } + () => color.highlight(shouldHighlight()), + (c) => { + spanColor.style.backgroundColor = c; }, ); }); - const initialColors = /** @type {Record} */ ({}); - const darkenedColors = /** @type {Record} */ ({}); - - const seriesOptions = series.getOptions(); - if (!seriesOptions) return; - - Object.entries(seriesOptions).forEach(([k, v]) => { - if (k.toLowerCase().includes("color") && typeof v === "string") { - if (!v.startsWith("oklch")) return; - initialColors[k] = v; - darkenedColors[k] = tameColor(v); - } else if (k === "lastValueVisible" && v) { - initialColors[k] = true; - darkenedColors[k] = false; - } - }); - - signals.createEffect(shouldHighlight, (shouldHighlight) => { - if (shouldHighlight) { - series.applyOptions(initialColors); - } else { - series.applyOptions(darkenedColors); - } - }); - const anchor = window.document.createElement("a"); signals.createEffect(series.url, (url) => { diff --git a/website/scripts/chart/markers.js b/website/scripts/chart/markers.js index b516f55c7..ecdb6c4bc 100644 --- a/website/scripts/chart/markers.js +++ b/website/scripts/chart/markers.js @@ -1,4 +1,3 @@ -import { createSeriesMarkers } from "../modules/lightweight-charts/5.1.0/dist/lightweight-charts.standalone.production.mjs"; import { throttle } from "../utils/timing.js"; /** @@ -9,20 +8,7 @@ import { throttle } from "../utils/timing.js"; * @param {(value: number) => string} args.formatValue */ export function createMinMaxMarkers({ chart, seriesList, colors, formatValue }) { - /** @type {WeakMap} */ - const pluginCache = new WeakMap(); - - /** @param {ISeries} iseries */ - function getOrCreatePlugin(iseries) { - let plugin = pluginCache.get(iseries); - if (!plugin) { - plugin = createSeriesMarkers(iseries, [], { autoScale: false }); - pluginCache.set(iseries, plugin); - } - return plugin; - } - - /** @type {Set} */ + /** @type {Set} */ const prevMarkerSeries = new Set(); function update() { @@ -37,7 +23,7 @@ export function createMinMaxMarkers({ chart, seriesList, colors, formatValue }) const t1 = /** @type {number} */ (tRight ?? range.to); const color = colors.gray(); - /** @type {Map} */ + /** @type {Map} */ const byPane = new Map(); for (const series of seriesList()) { @@ -57,16 +43,15 @@ export function createMinMaxMarkers({ chart, seriesList, colors, formatValue }) if (lo >= len) continue; const paneIndex = series.paneIndex; - const iseries = series.inner(); let pane = byPane.get(paneIndex); if (!pane) { pane = { minV: Infinity, minT: /** @type {Time} */ (0), - minS: iseries, + minS: series, maxV: -Infinity, maxT: /** @type {Time} */ (0), - maxS: iseries, + maxS: series, }; byPane.set(paneIndex, pane); } @@ -79,17 +64,18 @@ export function createMinMaxMarkers({ chart, seriesList, colors, formatValue }) if (v && v < pane.minV) { pane.minV = v; pane.minT = pt.time; - pane.minS = iseries; + pane.minS = series; } if (h && h > pane.maxV) { pane.maxV = h; pane.maxT = pt.time; - pane.maxS = iseries; + pane.maxS = series; } } } // Set new markers + /** @type {Set} */ const used = new Set(); for (const { minV, minT, minS, maxV, maxT, maxS } of byPane.values()) { if (!Number.isFinite(minV) || !Number.isFinite(maxV) || minT === maxT) @@ -115,23 +101,23 @@ export function createMinMaxMarkers({ chart, seriesList, colors, formatValue }) used.add(minS); used.add(maxS); if (minS === maxS) { - getOrCreatePlugin(minS).setMarkers([minM, maxM]); + minS.setMarkers([minM, maxM]); } else { - getOrCreatePlugin(minS).setMarkers([minM]); - getOrCreatePlugin(maxS).setMarkers([maxM]); + minS.setMarkers([minM]); + maxS.setMarkers([maxM]); } } // Clear stale for (const s of prevMarkerSeries) { - if (!used.has(s)) getOrCreatePlugin(s).setMarkers([]); + if (!used.has(s)) s.clearMarkers(); } prevMarkerSeries.clear(); for (const s of used) prevMarkerSeries.add(s); } function clear() { - for (const s of prevMarkerSeries) getOrCreatePlugin(s).setMarkers([]); + for (const s of prevMarkerSeries) s.clearMarkers(); prevMarkerSeries.clear(); } diff --git a/website/scripts/chart/state.js b/website/scripts/chart/state.js index 53a287bac..44b80cea7 100644 --- a/website/scripts/chart/state.js +++ b/website/scripts/chart/state.js @@ -1,96 +1,59 @@ -import { - readParam, - readNumberParam, - writeParam, -} from "../utils/url.js"; +import { readParam, writeParam } from "../utils/url.js"; +import { readStored, writeToStorage } from "../utils/storage.js"; /** * @typedef {{ from: number | null, to: number | null }} Range */ -const INDEX_KEY = "chart-index"; const RANGES_KEY = "chart-ranges"; +const RANGE_SEP = "_"; /** * @param {Signals} signals */ export function createChartState(signals) { + const index = signals.createPersistedSignal({ + storageKey: "chart-index", + urlKey: "index", + defaultValue: /** @type {ChartableIndexName} */ ("date"), + serialize: (v) => v, + deserialize: (s) => /** @type {ChartableIndexName} */ (s), + }); + + // Ranges stored per-index in localStorage only /** @type {Record} */ let ranges = {}; try { - const stored = localStorage.getItem(RANGES_KEY); + const stored = readStored(RANGES_KEY); if (stored) ranges = JSON.parse(stored); } catch {} - const saveRanges = () => { - try { - localStorage.setItem(RANGES_KEY, JSON.stringify(ranges)); - } catch {} - }; - - // Read index: URL > localStorage > default - /** @type {ChartableIndexName} */ - const defaultIndex = "date"; - const urlIndex = readParam("index"); - /** @type {ChartableIndexName} */ - let initialIndex = defaultIndex; - if (urlIndex) { - initialIndex = /** @type {ChartableIndexName} */ (urlIndex); - } else { - try { - const stored = localStorage.getItem(INDEX_KEY); - if (stored) initialIndex = /** @type {ChartableIndexName} */ (stored); - } catch {} + // Initialize from URL if present + const urlRange = readParam("range"); + if (urlRange) { + const [from, to] = urlRange.split(RANGE_SEP).map(Number); + if (!isNaN(from) && !isNaN(to)) { + ranges[index()] = { from, to }; + writeToStorage(RANGES_KEY, JSON.stringify(ranges)); + } } - // Read range: URL > localStorage (per index) - const urlFrom = readNumberParam("from"); - const urlTo = readNumberParam("to"); - const storedRange = ranges[initialIndex] ?? { from: null, to: null }; - const initialRange = { - from: urlFrom ?? storedRange.from, - to: urlTo ?? storedRange.to, - }; - // Save URL range to localStorage if present - if (urlFrom !== null || urlTo !== null) { - ranges[initialIndex] = initialRange; - saveRanges(); - } - - const index = signals.createSignal(/** @type {ChartableIndexName} */ (initialIndex)); - const currentRange = signals.createSignal(initialRange); - - // Save index changes to localStorage + URL - signals.createEffect(index, (value) => { - try { - localStorage.setItem(INDEX_KEY, value); - } catch {} - writeParam("index", value !== defaultIndex ? value : null); - }); - - // When index changes, switch to that index's saved range - signals.createEffect(index, (i) => { - const range = ranges[i] ?? { from: null, to: null }; - currentRange.set(range); - // Update URL with new range - writeParam("from", range.from !== null ? String(range.from) : null); - writeParam("to", range.to !== null ? String(range.to) : null); - }); - return { index, - /** @type {Accessor} */ - range: currentRange, - /** - * @param {Range} value - */ + /** @returns {Range} */ + range: () => ranges[index()] ?? { from: null, to: null }, + /** @param {Range} value */ setRange(value) { - const i = index(); - ranges[i] = value; - currentRange.set(value); - saveRanges(); - writeParam("from", value.from !== null ? String(value.from) : null); - writeParam("to", value.to !== null ? String(value.to) : null); + ranges[index()] = value; + writeToStorage(RANGES_KEY, JSON.stringify(ranges)); + if (value.from !== null && value.to !== null) { + // Round to 2 decimals for cleaner URLs + const f = Math.floor(value.from * 100) / 100; + const t = Math.floor(value.to * 100) / 100; + writeParam("range", `${f}${RANGE_SEP}${t}`); + } else { + writeParam("range", null); + } }, }; } diff --git a/website/scripts/main.js b/website/scripts/main.js index 559d40b8b..db1ab7c13 100644 --- a/website/scripts/main.js +++ b/website/scripts/main.js @@ -7,10 +7,10 @@ import { BrkClient } from "./modules/brk-client/index.js"; import { initOptions } from "./options/full.js"; import ufuzzy from "./modules/leeoniya-ufuzzy/1.0.19/dist/uFuzzy.mjs"; import * as leanQr from "./modules/lean-qr/2.7.1/index.mjs"; -import { init as initExplorer } from "./panes/explorer.js"; +import { init as initExplorer } from "./panes/_explorer.js"; import { init as initChart } from "./panes/chart/index.js"; import { init as initTable } from "./panes/table.js"; -import { init as initSimulation } from "./panes/simulation.js"; +import { init as initSimulation } from "./panes/_simulation.js"; import { next } from "./utils/timing.js"; import { replaceHistory } from "./utils/url.js"; import { removeStored, writeToStorage } from "./utils/storage.js"; diff --git a/website/scripts/panes/explorer.js b/website/scripts/panes/_explorer.js similarity index 100% rename from website/scripts/panes/explorer.js rename to website/scripts/panes/_explorer.js diff --git a/website/scripts/panes/simulation.js b/website/scripts/panes/_simulation.js similarity index 100% rename from website/scripts/panes/simulation.js rename to website/scripts/panes/_simulation.js diff --git a/website/scripts/panes/chart/index.js b/website/scripts/panes/chart/index.js index 36ab211a3..40d6617bd 100644 --- a/website/scripts/panes/chart/index.js +++ b/website/scripts/panes/chart/index.js @@ -12,6 +12,7 @@ import { createChartElement } from "../../chart/index.js"; import { createChartState } from "../../chart/state.js"; import { webSockets } from "../../utils/ws.js"; import { screenshot } from "./screenshot.js"; +import { debounce } from "../../utils/timing.js"; const keyPrefix = "chart"; const ONE_BTC_IN_SATS = 100_000_000; @@ -89,20 +90,34 @@ export function init({ colors, option, brk }) { }); } + // Sync chart → state.range on user pan/zoom + // Debounce to avoid rapid URL updates while panning + const debouncedSetRange = debounce( + (/** @type {{ from: number, to: number }} */ range) => state.setRange(range), + 500, + ); chart.onVisibleLogicalRangeChange((t) => { - if (!t) return; - state.setRange({ from: t.from, to: t.to }); + if (!t || t.from >= t.to) return; + debouncedSetRange({ from: t.from, to: t.to }); }); chartElement.append(fieldset); - const { field: topUnitField, selected: topUnit } = createChoiceField({ + const unitChoices = /** @type {const} */ ([Unit.usd, Unit.sats]); + /** @type {Signal} */ + const topUnit = signals.createPersistedSignal({ + defaultValue: /** @type {Unit} */ (Unit.usd), + storageKey: `${keyPrefix}-price`, + urlKey: "price", + serialize: (u) => u.id, + deserialize: (s) => /** @type {Unit} */ (unitChoices.find((u) => u.id === s) ?? Unit.usd), + }); + const topUnitField = createChoiceField({ defaultValue: Unit.usd, - keyPrefix, - key: "unit-0", - choices: [Unit.usd, Unit.sats], + choices: unitChoices, toKey: (u) => u.id, toLabel: (u) => u.name, + selected: topUnit, signals, sorted: true, type: "select", @@ -207,23 +222,28 @@ export function init({ colors, option, brk }) { const bottomUnits = Array.from(option.bottom.keys()); - /** @type {{ field: HTMLDivElement, selected: Accessor } | undefined} */ + /** @type {{ field: HTMLDivElement, selected: Signal } | undefined} */ let bottomUnitSelector; if (bottomUnits.length) { - bottomUnitSelector = createChoiceField({ + const selected = signals.createPersistedSignal({ + defaultValue: bottomUnits[0], + storageKey: `${keyPrefix}-unit`, + urlKey: "unit", + serialize: (u) => u.id, + deserialize: (s) => bottomUnits.find((u) => u.id === s) ?? bottomUnits[0], + }); + const field = createChoiceField({ defaultValue: bottomUnits[0], - keyPrefix, - key: "unit-1", choices: bottomUnits, toKey: (u) => u.id, toLabel: (u) => u.name, + selected, signals, sorted: true, type: "select", }); - - const field = bottomUnitSelector.field; + bottomUnitSelector = { field, selected }; chart.addFieldsetIfNeeded({ id: "charts-unit-1", paneIndex: 1, @@ -471,9 +491,9 @@ function createIndexSelector(option, state) { /** @type {ChartableIndexName} */ const defaultIndex = "date"; - const { field } = createChoiceField({ + const field = createChoiceField({ defaultValue: defaultIndex, - signal: state.index, + selected: state.index, choices, id: "index", signals, diff --git a/website/scripts/signals.js b/website/scripts/signals.js index 359117696..9762a027f 100644 --- a/website/scripts/signals.js +++ b/website/scripts/signals.js @@ -24,6 +24,8 @@ import { onCleanup, } from "./modules/solidjs-signals/0.6.3/dist/prod.js"; import { debounce } from "./utils/timing.js"; +import { writeParam, readParam } from "./utils/url.js"; +import { readStored, writeToStorage } from "./utils/storage.js"; let effectCount = 0; @@ -68,14 +70,11 @@ const signals = { /** * @template T * @param {T} initialValue - * @param {SignalOptions & {save?: {keyPrefix: string | Accessor; key: string; serialize: (v: T) => string; deserialize: (v: string) => T; serializeParam?: boolean; saveDefaultValue?: boolean}}} [options] + * @param {SignalOptions} [options] * @returns {Signal} */ createSignal(initialValue, options) { - const [get, set] = this.createSolidSignal( - /** @type {any} */ (initialValue), - options, - ); + const [get, set] = this.createSolidSignal(/** @type {any} */ (initialValue), options); // @ts-ignore get.set = set; @@ -83,148 +82,70 @@ const signals = { // @ts-ignore get.reset = () => set(initialValue); - if (options?.save) { - const save = options.save; - - const paramKey = save.key; - const storageKey = this.createMemo( - () => - `${ - typeof save.keyPrefix === "string" - ? save.keyPrefix - : save.keyPrefix() - }-${paramKey}`, - ); - - // /** @type { ((this: Window, ev: PopStateEvent) => any) | undefined} */ - // let popstateCallback; - - let serialized = /** @type {string | null} */ (null); - if (options.save.serializeParam !== false) { - serialized = new URLSearchParams(window.location.search).get(paramKey); - - // popstateCallback = - // /** @type {(this: Window, ev: PopStateEvent) => any} */ ( - // (_) => { - // serialized = new URLSearchParams(window.location.search).get( - // paramKey, - // ); - // set(() => - // serialized ? save.deserialize(serialized) : initialValue, - // ); - // } - // ); - // if (!popstateCallback) throw "Unreachable"; - // window.addEventListener("popstate", popstateCallback); - // signals.onCleanup(() => { - // if (popstateCallback) - // window.removeEventListener("popstate", popstateCallback); - // }); - } - if (serialized === null) { - try { - serialized = localStorage.getItem(storageKey()); - } catch (_) {} - } - if (serialized) { - set(() => (serialized ? save.deserialize(serialized) : initialValue)); - } - - let firstRun1 = true; - this.createEffect(storageKey, (storageKey) => { - if (!firstRun1) { - try { - serialized = localStorage.getItem(storageKey); - set(() => - serialized ? save.deserialize(serialized) : initialValue, - ); - } catch (_) {} - } - firstRun1 = false; - }); - - let firstRun2 = true; - - const debouncedSave = debounce( - /** @param {T} value */ (value) => { - try { - if ( - value !== undefined && - value !== null && - (initialValue === undefined || - initialValue === null || - save.saveDefaultValue || - save.serialize(value) !== save.serialize(initialValue)) - ) { - localStorage.setItem(storageKey(), save.serialize(value)); - writeParam(paramKey, save.serialize(value)); - } else { - localStorage.removeItem(storageKey()); - removeParam(paramKey); - } - } catch (_) {} - }, - 250, - ); - - this.createEffect(get, (value) => { - if (!save) return; - - if (firstRun2) { - // First run: sync URL params immediately - if ( - value !== undefined && - value !== null && - (initialValue === undefined || - initialValue === null || - save.saveDefaultValue || - save.serialize(value) !== save.serialize(initialValue)) - ) { - writeParam(paramKey, save.serialize(value)); - } else { - removeParam(paramKey); - } - firstRun2 = false; - } else { - // Subsequent runs: debounce - debouncedSave(value); - } - }); - } - // @ts-ignore return get; }, + /** + * @template T + * @param {Object} args + * @param {T} args.defaultValue + * @param {string} args.storageKey + * @param {string} [args.urlKey] + * @param {(v: T) => string} args.serialize + * @param {(s: string) => T} args.deserialize + * @param {boolean} [args.saveDefaultValue] + * @returns {Signal} + */ + createPersistedSignal({ + defaultValue, + storageKey, + urlKey, + serialize, + deserialize, + saveDefaultValue = false, + }) { + const defaultSerialized = serialize(defaultValue); + + // Read: URL > localStorage > default + let serialized = urlKey ? readParam(urlKey) : null; + if (serialized === null) { + serialized = readStored(storageKey); + } + const initialValue = serialized !== null ? deserialize(serialized) : defaultValue; + + const signal = this.createSignal(initialValue); + + /** @param {T} value */ + const write = (value) => { + const s = serialize(value); + const isDefault = s === defaultSerialized; + + if (!isDefault || saveDefaultValue) { + writeToStorage(storageKey, s); + } else { + writeToStorage(storageKey, null); + } + + if (urlKey) { + writeParam(urlKey, !isDefault || saveDefaultValue ? s : null); + } + }; + + const debouncedWrite = debounce(write, 250); + + let firstRun = true; + this.createEffect(signal, (value) => { + if (firstRun) { + write(value); + firstRun = false; + } else { + debouncedWrite(value); + } + }); + + return signal; + }, }; /** @typedef {typeof signals} Signals */ -/** - * @param {string} key - * @param {string | undefined} value - */ -function writeParam(key, value) { - const urlParams = new URLSearchParams(window.location.search); - - if (value !== undefined) { - urlParams.set(key, String(value)); - } else { - urlParams.delete(key); - } - - try { - window.history.replaceState( - null, - "", - `${window.location.pathname}?${urlParams.toString()}`, - ); - } catch (_) {} -} - -/** - * @param {string} key - */ -function removeParam(key) { - writeParam(key, undefined); -} - export default signals; diff --git a/website/scripts/utils/colors.js b/website/scripts/utils/colors.js index 6069546aa..b29ee77bc 100644 --- a/website/scripts/utils/colors.js +++ b/website/scripts/utils/colors.js @@ -1,70 +1,45 @@ +/** + * Reduce color opacity to 50% for dimming effect + * @param {string} color - oklch color string + */ +export function tameColor(color) { + if (color === "transparent") return color; + return `${color.slice(0, -1)} / 50%)`; +} + +/** + * @typedef {Object} ColorMethods + * @property {() => string} tame - Returns tamed (50% opacity) version + * @property {(highlighted: boolean) => string} highlight - Returns normal if highlighted, tamed otherwise + */ + +/** + * @typedef {(() => string) & ColorMethods} Color + */ + +/** + * Creates a Color object that is callable and has utility methods + * @param {() => string} getter + * @returns {Color} + */ +function createColor(getter) { + const color = /** @type {Color} */ (() => getter()); + color.tame = () => tameColor(getter()); + color.highlight = (highlighted) => highlighted ? getter() : tameColor(getter()); + return color; +} + /** * @param {Accessor} dark */ export function createColors(dark) { const globalComputedStyle = getComputedStyle(window.document.documentElement); + /** - * @param {string} color + * @param {string} name */ - function getColor(color) { - return globalComputedStyle.getPropertyValue(`--${color}`); - } - function red() { - return getColor("red"); - } - function orange() { - return getColor("orange"); - } - function amber() { - return getColor("amber"); - } - function yellow() { - return getColor("yellow"); - } - function avocado() { - return getColor("avocado"); - } - function lime() { - return getColor("lime"); - } - function green() { - return getColor("green"); - } - function emerald() { - return getColor("emerald"); - } - function teal() { - return getColor("teal"); - } - function cyan() { - return getColor("cyan"); - } - function sky() { - return getColor("sky"); - } - function blue() { - return getColor("blue"); - } - function indigo() { - return getColor("indigo"); - } - function violet() { - return getColor("violet"); - } - function purple() { - return getColor("purple"); - } - function fuchsia() { - return getColor("fuchsia"); - } - function pink() { - return getColor("pink"); - } - function rose() { - return getColor("rose"); - } - function gray() { - return getColor("gray"); + function getColor(name) { + return globalComputedStyle.getPropertyValue(`--${name}`); } /** @@ -76,41 +51,33 @@ export function createColors(dark) { return dark() ? _dark : light; } - function textColor() { - return getLightDarkValue("--color"); - } - function borderColor() { - return getLightDarkValue("--border-color"); - } - return { - default: textColor, - gray, - border: borderColor, + default: createColor(() => getLightDarkValue("--color")), + gray: createColor(() => getColor("gray")), + border: createColor(() => getLightDarkValue("--border-color")), - red, - orange, - amber, - yellow, - avocado, - lime, - green, - emerald, - teal, - cyan, - sky, - blue, - indigo, - violet, - purple, - fuchsia, - pink, - rose, + red: createColor(() => getColor("red")), + orange: createColor(() => getColor("orange")), + amber: createColor(() => getColor("amber")), + yellow: createColor(() => getColor("yellow")), + avocado: createColor(() => getColor("avocado")), + lime: createColor(() => getColor("lime")), + green: createColor(() => getColor("green")), + emerald: createColor(() => getColor("emerald")), + teal: createColor(() => getColor("teal")), + cyan: createColor(() => getColor("cyan")), + sky: createColor(() => getColor("sky")), + blue: createColor(() => getColor("blue")), + indigo: createColor(() => getColor("indigo")), + violet: createColor(() => getColor("violet")), + purple: createColor(() => getColor("purple")), + fuchsia: createColor(() => getColor("fuchsia")), + pink: createColor(() => getColor("pink")), + rose: createColor(() => getColor("rose")), }; } /** * @typedef {ReturnType} Colors - * @typedef {Colors["orange"]} Color * @typedef {keyof Colors} ColorName */ diff --git a/website/scripts/utils/dom.js b/website/scripts/utils/dom.js index 8a04c6827..4bcf8671f 100644 --- a/website/scripts/utils/dom.js +++ b/website/scripts/utils/dom.js @@ -215,15 +215,13 @@ export function importStyle(href) { /** * @template T * @param {Object} args - * @param {T} args.defaultValue + * @param {T} args.defaultValue - Fallback when selected value is no longer in choices * @param {string} [args.id] * @param {readonly T[] | Accessor} args.choices - * @param {string} [args.keyPrefix] - * @param {string} [args.key] * @param {boolean} [args.sorted] * @param {Signals} args.signals - * @param {Signal} [args.signal] - Optional external signal to use instead of creating one - * @param {(choice: T) => string} [args.toKey] - Extract string key for storage (defaults to identity for strings) + * @param {Signal} args.selected + * @param {(choice: T) => string} [args.toKey] - Extract string key (defaults to identity for strings) * @param {(choice: T) => string} [args.toLabel] - Extract display label (defaults to identity for strings) * @param {"radio" | "select"} [args.type] - Render as radio buttons or select dropdown */ @@ -231,10 +229,8 @@ export function createChoiceField({ id, choices: unsortedChoices, defaultValue, - keyPrefix, - key, signals, - signal: externalSignal, + selected, sorted, toKey = /** @type {(choice: T) => string} */ ((/** @type {any} */ c) => c), toLabel = /** @type {(choice: T) => string} */ ((/** @type {any} */ c) => c), @@ -260,25 +256,8 @@ export function createChoiceField({ : c; }); - /** - * @param {string} storedKey - * @returns {T} - */ - function fromKey(storedKey) { - const found = choices().find((c) => toKey(c) === storedKey); - return found ?? defaultValue; - } - - /** @type {Signal} */ - const selected = externalSignal ?? signals.createSignal(defaultValue, { - save: { - serialize: (v) => toKey(v), - deserialize: (s) => fromKey(s), - keyPrefix: keyPrefix ?? "", - key: key ?? "", - saveDefaultValue: true, - }, - }); + /** @param {string} key */ + const fromKey = (key) => choices().find((c) => toKey(c) === key) ?? defaultValue; const field = window.document.createElement("div"); field.classList.add("field"); @@ -317,8 +296,8 @@ export function createChoiceField({ } } else if (type === "select") { const select = window.document.createElement("select"); - select.id = id ?? key ?? ""; - select.name = id ?? key ?? ""; + select.id = id ?? ""; + select.name = id ?? ""; choices.forEach((choice) => { const option = window.document.createElement("option"); @@ -346,7 +325,7 @@ export function createChoiceField({ } } } else { - const fieldId = id ?? key ?? ""; + const fieldId = id ?? ""; choices.forEach((choice) => { const choiceKey = toKey(choice); const choiceLabel = toLabel(choice); @@ -372,7 +351,7 @@ export function createChoiceField({ } }); - return { field, selected }; + return field; } /** diff --git a/website/scripts/utils/serde.js b/website/scripts/utils/serde.js index cc1e6c2dd..3a88fdb60 100644 --- a/website/scripts/utils/serde.js +++ b/website/scripts/utils/serde.js @@ -104,10 +104,8 @@ export const serdeBool = { deserialize(v) { if (v === "true" || v === "1") { return true; - } else if (v === "false" || v === "0") { - return false; } else { - throw "deser bool err"; + return false; } }, }; diff --git a/website/scripts/utils/storage.js b/website/scripts/utils/storage.js index cecebbcad..8dbb714e3 100644 --- a/website/scripts/utils/storage.js +++ b/website/scripts/utils/storage.js @@ -1,25 +1,3 @@ -/** - * @param {string} key - */ -export function readStoredNumber(key) { - const saved = readStored(key); - if (saved) { - return Number(saved); - } - return null; -} - -/** - * @param {string} key - */ -export function readStoredBool(key) { - const saved = readStored(key); - if (saved) { - return saved === "true" || saved === "1"; - } - return null; -} - /** * @param {string} key */ diff --git a/website/scripts/utils/url.js b/website/scripts/utils/url.js index d77ad8673..7c6fce400 100644 --- a/website/scripts/utils/url.js +++ b/website/scripts/utils/url.js @@ -3,10 +3,12 @@ */ function processPathname(pathname) { pathname ||= window.location.pathname; - return Array.isArray(pathname) ? pathname.join("/") : pathname; + const result = Array.isArray(pathname) ? pathname.join("/") : pathname; + // Strip leading slash to avoid double slashes when prepending / + return result.startsWith("/") ? result.slice(1) : result; } -const chartParamsWhitelist = ["from", "to"]; +const chartParamsWhitelist = ["range"]; /** * @param {string | string[]} pathname @@ -16,7 +18,6 @@ export function pushHistory(pathname) { pathname = processPathname(pathname); try { const url = `/${pathname}?${urlParams.toString()}`; - console.log(`push history: ${url}`); window.history.pushState(null, "", url); } catch (_) {} } @@ -31,7 +32,6 @@ export function replaceHistory({ urlParams, pathname }) { pathname = processPathname(pathname); try { const url = `/${pathname}?${urlParams.toString()}`; - console.log(`replace history: ${url}`); window.history.replaceState(null, "", url); } catch (_) {} } diff --git a/website/service-worker.js b/website/service-worker.js index 50483d117..e6bd25957 100644 --- a/website/service-worker.js +++ b/website/service-worker.js @@ -14,6 +14,19 @@ const offline = () => headers: { "Content-Type": "text/plain" }, }); +/** + * @param {Request | string} req + */ +function fetchAndCache(req) { + return fetch(req).then((res) => { + if (res.ok) { + const clone = res.clone(); + caches.open(CACHE).then((c) => c.put(req, clone)); + } + return res; + }); +} + sw.addEventListener("install", (e) => { e.waitUntil( caches @@ -53,12 +66,9 @@ sw.addEventListener("fetch", (event) => { // Navigation: network-first for shell if (req.mode === "navigate") { event.respondWith( - fetch(ROOT) - .then((res) => { - if (res.ok) caches.open(CACHE).then((c) => c.put(ROOT, res.clone())); - return res; - }) - .catch(() => caches.match(ROOT).then((c) => c || offline())), + fetchAndCache(ROOT).catch(() => + caches.match(ROOT).then((c) => c || offline()), + ), ); return; } @@ -68,15 +78,7 @@ sw.addEventListener("fetch", (event) => { event.respondWith( caches .match(req) - .then( - (cached) => - cached || - fetch(req).then((res) => { - if (res.ok) - caches.open(CACHE).then((c) => c.put(req, res.clone())); - return res; - }), - ) + .then((cached) => cached || fetchAndCache(req)) .catch(() => offline()), ); return; @@ -86,21 +88,16 @@ sw.addEventListener("fetch", (event) => { // SPA routes (no extension) fall back to ROOT, static assets get 503 const isStatic = path.includes(".") && !path.endsWith(".html"); event.respondWith( - fetch(req) - .then((res) => { - if (res.ok) caches.open(CACHE).then((c) => c.put(req, res.clone())); - return res; - }) - .catch(() => - caches - .match(req) - .then( - (cached) => - cached || - (isStatic - ? offline() - : caches.match(ROOT).then((c) => c || offline())), - ), - ), + fetchAndCache(req).catch(() => + caches + .match(req) + .then( + (cached) => + cached || + (isStatic + ? offline() + : caches.match(ROOT).then((c) => c || offline())), + ), + ), ); });