mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-24 06:39:58 -07:00
clients: snapshot
This commit is contained in:
@@ -3390,6 +3390,39 @@ impl<T: DeserializeOwned> PeriodAveragePricePattern<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct ClassAveragePricePattern<T> {
|
||||
pub _2015: MetricPattern4<T>,
|
||||
pub _2016: MetricPattern4<T>,
|
||||
pub _2017: MetricPattern4<T>,
|
||||
pub _2018: MetricPattern4<T>,
|
||||
pub _2019: MetricPattern4<T>,
|
||||
pub _2020: MetricPattern4<T>,
|
||||
pub _2021: MetricPattern4<T>,
|
||||
pub _2022: MetricPattern4<T>,
|
||||
pub _2023: MetricPattern4<T>,
|
||||
pub _2024: MetricPattern4<T>,
|
||||
pub _2025: MetricPattern4<T>,
|
||||
}
|
||||
|
||||
impl<T: DeserializeOwned> ClassAveragePricePattern<T> {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
_2015: MetricPattern4::new(client.clone(), format!("{base_path}_2015")),
|
||||
_2016: MetricPattern4::new(client.clone(), format!("{base_path}_2016")),
|
||||
_2017: MetricPattern4::new(client.clone(), format!("{base_path}_2017")),
|
||||
_2018: MetricPattern4::new(client.clone(), format!("{base_path}_2018")),
|
||||
_2019: MetricPattern4::new(client.clone(), format!("{base_path}_2019")),
|
||||
_2020: MetricPattern4::new(client.clone(), format!("{base_path}_2020")),
|
||||
_2021: MetricPattern4::new(client.clone(), format!("{base_path}_2021")),
|
||||
_2022: MetricPattern4::new(client.clone(), format!("{base_path}_2022")),
|
||||
_2023: MetricPattern4::new(client.clone(), format!("{base_path}_2023")),
|
||||
_2024: MetricPattern4::new(client.clone(), format!("{base_path}_2024")),
|
||||
_2025: MetricPattern4::new(client.clone(), format!("{base_path}_2025")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct DollarsPattern<T> {
|
||||
pub average: MetricPattern2<T>,
|
||||
@@ -3424,39 +3457,6 @@ impl<T: DeserializeOwned> DollarsPattern<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct ClassAveragePricePattern<T> {
|
||||
pub _2015: MetricPattern4<T>,
|
||||
pub _2016: MetricPattern4<T>,
|
||||
pub _2017: MetricPattern4<T>,
|
||||
pub _2018: MetricPattern4<T>,
|
||||
pub _2019: MetricPattern4<T>,
|
||||
pub _2020: MetricPattern4<T>,
|
||||
pub _2021: MetricPattern4<T>,
|
||||
pub _2022: MetricPattern4<T>,
|
||||
pub _2023: MetricPattern4<T>,
|
||||
pub _2024: MetricPattern4<T>,
|
||||
pub _2025: MetricPattern4<T>,
|
||||
}
|
||||
|
||||
impl<T: DeserializeOwned> ClassAveragePricePattern<T> {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
_2015: MetricPattern4::new(client.clone(), format!("{base_path}_2015")),
|
||||
_2016: MetricPattern4::new(client.clone(), format!("{base_path}_2016")),
|
||||
_2017: MetricPattern4::new(client.clone(), format!("{base_path}_2017")),
|
||||
_2018: MetricPattern4::new(client.clone(), format!("{base_path}_2018")),
|
||||
_2019: MetricPattern4::new(client.clone(), format!("{base_path}_2019")),
|
||||
_2020: MetricPattern4::new(client.clone(), format!("{base_path}_2020")),
|
||||
_2021: MetricPattern4::new(client.clone(), format!("{base_path}_2021")),
|
||||
_2022: MetricPattern4::new(client.clone(), format!("{base_path}_2022")),
|
||||
_2023: MetricPattern4::new(client.clone(), format!("{base_path}_2023")),
|
||||
_2024: MetricPattern4::new(client.clone(), format!("{base_path}_2024")),
|
||||
_2025: MetricPattern4::new(client.clone(), format!("{base_path}_2025")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct FullnessPattern<T> {
|
||||
pub average: MetricPattern2<T>,
|
||||
@@ -3731,6 +3731,84 @@ impl _0satsPattern {
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct _0satsPattern2 {
|
||||
pub activity: ActivityPattern2,
|
||||
pub cost_basis: CostBasisPattern,
|
||||
pub outputs: OutputsPattern,
|
||||
pub realized: RealizedPattern,
|
||||
pub relative: RelativePattern4,
|
||||
pub supply: SupplyPattern2,
|
||||
pub unrealized: UnrealizedPattern,
|
||||
}
|
||||
|
||||
impl _0satsPattern2 {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
activity: ActivityPattern2::new(client.clone(), acc.clone()),
|
||||
cost_basis: CostBasisPattern::new(client.clone(), acc.clone()),
|
||||
outputs: OutputsPattern::new(client.clone(), acc.clone()),
|
||||
realized: RealizedPattern::new(client.clone(), acc.clone()),
|
||||
relative: RelativePattern4::new(client.clone(), _m(&acc, "supply_in")),
|
||||
supply: SupplyPattern2::new(client.clone(), _m(&acc, "supply")),
|
||||
unrealized: UnrealizedPattern::new(client.clone(), acc.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct _100btcPattern {
|
||||
pub activity: ActivityPattern2,
|
||||
pub cost_basis: CostBasisPattern,
|
||||
pub outputs: OutputsPattern,
|
||||
pub realized: RealizedPattern,
|
||||
pub relative: RelativePattern,
|
||||
pub supply: SupplyPattern2,
|
||||
pub unrealized: UnrealizedPattern,
|
||||
}
|
||||
|
||||
impl _100btcPattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
activity: ActivityPattern2::new(client.clone(), acc.clone()),
|
||||
cost_basis: CostBasisPattern::new(client.clone(), acc.clone()),
|
||||
outputs: OutputsPattern::new(client.clone(), acc.clone()),
|
||||
realized: RealizedPattern::new(client.clone(), acc.clone()),
|
||||
relative: RelativePattern::new(client.clone(), acc.clone()),
|
||||
supply: SupplyPattern2::new(client.clone(), _m(&acc, "supply")),
|
||||
unrealized: UnrealizedPattern::new(client.clone(), acc.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct _10yPattern {
|
||||
pub activity: ActivityPattern2,
|
||||
pub cost_basis: CostBasisPattern,
|
||||
pub outputs: OutputsPattern,
|
||||
pub realized: RealizedPattern4,
|
||||
pub relative: RelativePattern,
|
||||
pub supply: SupplyPattern2,
|
||||
pub unrealized: UnrealizedPattern,
|
||||
}
|
||||
|
||||
impl _10yPattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
activity: ActivityPattern2::new(client.clone(), acc.clone()),
|
||||
cost_basis: CostBasisPattern::new(client.clone(), acc.clone()),
|
||||
outputs: OutputsPattern::new(client.clone(), acc.clone()),
|
||||
realized: RealizedPattern4::new(client.clone(), acc.clone()),
|
||||
relative: RelativePattern::new(client.clone(), acc.clone()),
|
||||
supply: SupplyPattern2::new(client.clone(), _m(&acc, "supply")),
|
||||
unrealized: UnrealizedPattern::new(client.clone(), acc.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct PeriodCagrPattern {
|
||||
pub _10y: MetricPattern4<StoredF32>,
|
||||
@@ -3832,58 +3910,6 @@ impl _10yTo12yPattern {
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct _10yPattern {
|
||||
pub activity: ActivityPattern2,
|
||||
pub cost_basis: CostBasisPattern,
|
||||
pub outputs: OutputsPattern,
|
||||
pub realized: RealizedPattern4,
|
||||
pub relative: RelativePattern,
|
||||
pub supply: SupplyPattern2,
|
||||
pub unrealized: UnrealizedPattern,
|
||||
}
|
||||
|
||||
impl _10yPattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
activity: ActivityPattern2::new(client.clone(), acc.clone()),
|
||||
cost_basis: CostBasisPattern::new(client.clone(), acc.clone()),
|
||||
outputs: OutputsPattern::new(client.clone(), acc.clone()),
|
||||
realized: RealizedPattern4::new(client.clone(), acc.clone()),
|
||||
relative: RelativePattern::new(client.clone(), acc.clone()),
|
||||
supply: SupplyPattern2::new(client.clone(), _m(&acc, "supply")),
|
||||
unrealized: UnrealizedPattern::new(client.clone(), acc.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct _100btcPattern {
|
||||
pub activity: ActivityPattern2,
|
||||
pub cost_basis: CostBasisPattern,
|
||||
pub outputs: OutputsPattern,
|
||||
pub realized: RealizedPattern,
|
||||
pub relative: RelativePattern,
|
||||
pub supply: SupplyPattern2,
|
||||
pub unrealized: UnrealizedPattern,
|
||||
}
|
||||
|
||||
impl _100btcPattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
activity: ActivityPattern2::new(client.clone(), acc.clone()),
|
||||
cost_basis: CostBasisPattern::new(client.clone(), acc.clone()),
|
||||
outputs: OutputsPattern::new(client.clone(), acc.clone()),
|
||||
realized: RealizedPattern::new(client.clone(), acc.clone()),
|
||||
relative: RelativePattern::new(client.clone(), acc.clone()),
|
||||
supply: SupplyPattern2::new(client.clone(), _m(&acc, "supply")),
|
||||
unrealized: UnrealizedPattern::new(client.clone(), acc.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct UnrealizedPattern {
|
||||
pub neg_unrealized_loss: MetricPattern1<Dollars>,
|
||||
@@ -3919,32 +3945,6 @@ impl UnrealizedPattern {
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct _0satsPattern2 {
|
||||
pub activity: ActivityPattern2,
|
||||
pub cost_basis: CostBasisPattern,
|
||||
pub outputs: OutputsPattern,
|
||||
pub realized: RealizedPattern,
|
||||
pub relative: RelativePattern4,
|
||||
pub supply: SupplyPattern2,
|
||||
pub unrealized: UnrealizedPattern,
|
||||
}
|
||||
|
||||
impl _0satsPattern2 {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
activity: ActivityPattern2::new(client.clone(), acc.clone()),
|
||||
cost_basis: CostBasisPattern::new(client.clone(), acc.clone()),
|
||||
outputs: OutputsPattern::new(client.clone(), acc.clone()),
|
||||
realized: RealizedPattern::new(client.clone(), acc.clone()),
|
||||
relative: RelativePattern4::new(client.clone(), _m(&acc, "supply_in")),
|
||||
supply: SupplyPattern2::new(client.clone(), _m(&acc, "supply")),
|
||||
unrealized: UnrealizedPattern::new(client.clone(), acc.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct ActivityPattern2 {
|
||||
pub coinblocks_destroyed: BlockCountPattern<StoredF64>,
|
||||
@@ -3996,24 +3996,6 @@ impl<T: DeserializeOwned> SplitPattern2<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct CoinbasePattern {
|
||||
pub bitcoin: FullnessPattern<Bitcoin>,
|
||||
pub dollars: DollarsPattern<Dollars>,
|
||||
pub sats: DollarsPattern<Sats>,
|
||||
}
|
||||
|
||||
impl CoinbasePattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
bitcoin: FullnessPattern::new(client.clone(), _m(&acc, "btc")),
|
||||
dollars: DollarsPattern::new(client.clone(), _m(&acc, "usd")),
|
||||
sats: DollarsPattern::new(client.clone(), acc.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct CostBasisPattern2 {
|
||||
pub max: MetricPattern1<Dollars>,
|
||||
@@ -4034,24 +4016,6 @@ impl CostBasisPattern2 {
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct CoinbasePattern2 {
|
||||
pub bitcoin: BlockCountPattern<Bitcoin>,
|
||||
pub dollars: BlockCountPattern<Dollars>,
|
||||
pub sats: BlockCountPattern<Sats>,
|
||||
}
|
||||
|
||||
impl CoinbasePattern2 {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
bitcoin: BlockCountPattern::new(client.clone(), _m(&acc, "btc")),
|
||||
dollars: BlockCountPattern::new(client.clone(), _m(&acc, "usd")),
|
||||
sats: BlockCountPattern::new(client.clone(), acc.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct ActiveSupplyPattern {
|
||||
pub bitcoin: MetricPattern1<Bitcoin>,
|
||||
@@ -4089,23 +4053,41 @@ impl _2015Pattern {
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct UnclaimedRewardsPattern {
|
||||
pub bitcoin: BitcoinPattern<Bitcoin>,
|
||||
pub struct CoinbasePattern2 {
|
||||
pub bitcoin: BlockCountPattern<Bitcoin>,
|
||||
pub dollars: BlockCountPattern<Dollars>,
|
||||
pub sats: BlockCountPattern<Sats>,
|
||||
}
|
||||
|
||||
impl UnclaimedRewardsPattern {
|
||||
impl CoinbasePattern2 {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
bitcoin: BitcoinPattern::new(client.clone(), _m(&acc, "btc")),
|
||||
bitcoin: BlockCountPattern::new(client.clone(), _m(&acc, "btc")),
|
||||
dollars: BlockCountPattern::new(client.clone(), _m(&acc, "usd")),
|
||||
sats: BlockCountPattern::new(client.clone(), acc.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct CoinbasePattern {
|
||||
pub bitcoin: FullnessPattern<Bitcoin>,
|
||||
pub dollars: DollarsPattern<Dollars>,
|
||||
pub sats: DollarsPattern<Sats>,
|
||||
}
|
||||
|
||||
impl CoinbasePattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
bitcoin: FullnessPattern::new(client.clone(), _m(&acc, "btc")),
|
||||
dollars: DollarsPattern::new(client.clone(), _m(&acc, "usd")),
|
||||
sats: DollarsPattern::new(client.clone(), acc.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct SegwitAdoptionPattern {
|
||||
pub base: MetricPattern11<StoredF32>,
|
||||
@@ -4125,17 +4107,19 @@ impl SegwitAdoptionPattern {
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct SupplyPattern2 {
|
||||
pub halved: ActiveSupplyPattern,
|
||||
pub total: ActiveSupplyPattern,
|
||||
pub struct UnclaimedRewardsPattern {
|
||||
pub bitcoin: BitcoinPattern<Bitcoin>,
|
||||
pub dollars: BlockCountPattern<Dollars>,
|
||||
pub sats: BlockCountPattern<Sats>,
|
||||
}
|
||||
|
||||
impl SupplyPattern2 {
|
||||
impl UnclaimedRewardsPattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
halved: ActiveSupplyPattern::new(client.clone(), _m(&acc, "half")),
|
||||
total: ActiveSupplyPattern::new(client.clone(), acc.clone()),
|
||||
bitcoin: BitcoinPattern::new(client.clone(), _m(&acc, "btc")),
|
||||
dollars: BlockCountPattern::new(client.clone(), _m(&acc, "usd")),
|
||||
sats: BlockCountPattern::new(client.clone(), acc.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4156,6 +4140,22 @@ impl CostBasisPattern {
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct _1dReturns1mSdPattern {
|
||||
pub sd: MetricPattern4<StoredF32>,
|
||||
pub sma: MetricPattern4<StoredF32>,
|
||||
}
|
||||
|
||||
impl _1dReturns1mSdPattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
sd: MetricPattern4::new(client.clone(), _m(&acc, "sd")),
|
||||
sma: MetricPattern4::new(client.clone(), _m(&acc, "sma")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct RelativePattern4 {
|
||||
pub supply_in_loss_rel_to_own_supply: MetricPattern1<StoredF64>,
|
||||
@@ -4179,17 +4179,32 @@ impl RelativePattern4 {
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct _1dReturns1mSdPattern {
|
||||
pub sd: MetricPattern4<StoredF32>,
|
||||
pub sma: MetricPattern4<StoredF32>,
|
||||
pub struct SupplyPattern2 {
|
||||
pub halved: ActiveSupplyPattern,
|
||||
pub total: ActiveSupplyPattern,
|
||||
}
|
||||
|
||||
impl _1dReturns1mSdPattern {
|
||||
impl SupplyPattern2 {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
sd: MetricPattern4::new(client.clone(), _m(&acc, "sd")),
|
||||
sma: MetricPattern4::new(client.clone(), _m(&acc, "sma")),
|
||||
halved: ActiveSupplyPattern::new(client.clone(), _m(&acc, "half")),
|
||||
total: ActiveSupplyPattern::new(client.clone(), acc.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct SatsPattern<T> {
|
||||
pub ohlc: MetricPattern1<T>,
|
||||
pub split: SplitPattern2<T>,
|
||||
}
|
||||
|
||||
impl<T: DeserializeOwned> SatsPattern<T> {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
Self {
|
||||
ohlc: MetricPattern1::new(client.clone(), format!("{base_path}_ohlc")),
|
||||
split: SplitPattern2::new(client.clone(), format!("{base_path}_split")),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4227,16 +4242,15 @@ impl<T: DeserializeOwned> BlockCountPattern<T> {
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct SatsPattern<T> {
|
||||
pub ohlc: MetricPattern1<T>,
|
||||
pub split: SplitPattern2<T>,
|
||||
pub struct RealizedPriceExtraPattern {
|
||||
pub ratio: MetricPattern4<StoredF32>,
|
||||
}
|
||||
|
||||
impl<T: DeserializeOwned> SatsPattern<T> {
|
||||
pub fn new(client: Arc<BrkClientBase>, base_path: String) -> Self {
|
||||
impl RealizedPriceExtraPattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
ohlc: MetricPattern1::new(client.clone(), format!("{base_path}_ohlc")),
|
||||
split: SplitPattern2::new(client.clone(), format!("{base_path}_split")),
|
||||
ratio: MetricPattern4::new(client.clone(), _m(&acc, "ratio")),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4255,20 +4269,6 @@ impl OutputsPattern {
|
||||
}
|
||||
}
|
||||
|
||||
/// Pattern struct for repeated tree structure.
|
||||
pub struct RealizedPriceExtraPattern {
|
||||
pub ratio: MetricPattern4<StoredF32>,
|
||||
}
|
||||
|
||||
impl RealizedPriceExtraPattern {
|
||||
/// Create a new pattern node with accumulated metric name.
|
||||
pub fn new(client: Arc<BrkClientBase>, acc: String) -> Self {
|
||||
Self {
|
||||
ratio: MetricPattern4::new(client.clone(), _m(&acc, "ratio")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Metrics tree
|
||||
|
||||
/// Metrics tree node.
|
||||
@@ -8297,7 +8297,7 @@ impl BrkClient {
|
||||
index: Index,
|
||||
start: Option<i64>,
|
||||
end: Option<i64>,
|
||||
count: Option<i64>,
|
||||
limit: Option<&str>,
|
||||
format: Option<Format>,
|
||||
) -> Result<FormatResponse<MetricData>> {
|
||||
let mut query = Vec::new();
|
||||
@@ -8307,8 +8307,8 @@ impl BrkClient {
|
||||
if let Some(v) = end {
|
||||
query.push(format!("end={}", v));
|
||||
}
|
||||
if let Some(v) = count {
|
||||
query.push(format!("count={}", v));
|
||||
if let Some(v) = limit {
|
||||
query.push(format!("limit={}", v));
|
||||
}
|
||||
if let Some(v) = format {
|
||||
query.push(format!("format={}", v));
|
||||
@@ -8346,7 +8346,7 @@ impl BrkClient {
|
||||
index: Index,
|
||||
start: Option<i64>,
|
||||
end: Option<i64>,
|
||||
count: Option<i64>,
|
||||
limit: Option<&str>,
|
||||
format: Option<Format>,
|
||||
) -> Result<FormatResponse<Vec<MetricData>>> {
|
||||
let mut query = Vec::new();
|
||||
@@ -8358,8 +8358,8 @@ impl BrkClient {
|
||||
if let Some(v) = end {
|
||||
query.push(format!("end={}", v));
|
||||
}
|
||||
if let Some(v) = count {
|
||||
query.push(format!("count={}", v));
|
||||
if let Some(v) = limit {
|
||||
query.push(format!("limit={}", v));
|
||||
}
|
||||
if let Some(v) = format {
|
||||
query.push(format!("format={}", v));
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::{de_unquote_i64, de_unquote_usize};
|
||||
use crate::{de_unquote_i64, de_unquote_limit, Limit};
|
||||
|
||||
/// Range parameters for slicing data
|
||||
#[derive(Default, Debug, Deserialize, JsonSchema)]
|
||||
@@ -16,10 +16,9 @@ pub struct DataRange {
|
||||
#[schemars(example = 1000)]
|
||||
end: Option<i64>,
|
||||
|
||||
/// Number of values to return (ignored if `end` is set)
|
||||
#[serde(default, alias = "c", deserialize_with = "de_unquote_usize")]
|
||||
#[schemars(example = 1, example = 10, example = 100)]
|
||||
count: Option<usize>,
|
||||
/// Maximum number of values to return (ignored if `end` is set)
|
||||
#[serde(default, alias = "l", alias = "count", alias = "c", deserialize_with = "de_unquote_limit")]
|
||||
limit: Option<Limit>,
|
||||
}
|
||||
|
||||
impl DataRange {
|
||||
@@ -33,8 +32,8 @@ impl DataRange {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_count(mut self, count: usize) -> Self {
|
||||
self.count.replace(count);
|
||||
pub fn set_limit(mut self, limit: Limit) -> Self {
|
||||
self.limit.replace(limit);
|
||||
self
|
||||
}
|
||||
|
||||
@@ -43,22 +42,22 @@ impl DataRange {
|
||||
self.start
|
||||
}
|
||||
|
||||
/// Get `end` value, computing it from `start + count` if `end` is unset but `count` is set.
|
||||
/// Requires the vec length to resolve negative `start` indices before adding count.
|
||||
/// Get `end` value, computing it from `start + limit` if `end` is unset but `limit` is set.
|
||||
/// Requires the vec length to resolve negative `start` indices before adding limit.
|
||||
pub fn end_for_len(&self, len: usize) -> Option<i64> {
|
||||
if self.end.is_some() {
|
||||
return self.end;
|
||||
}
|
||||
|
||||
self.count.map(|count| {
|
||||
self.limit.map(|limit| {
|
||||
let resolved_start = self.resolve_index(self.start, len, 0);
|
||||
(resolved_start + count).min(len) as i64
|
||||
(resolved_start + *limit).min(len) as i64
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns a string for etag/cache key generation that captures all range parameters
|
||||
pub fn etag_suffix(&self) -> String {
|
||||
format!("{:?}{:?}{:?}", self.start, self.end, self.count)
|
||||
format!("{:?}{:?}{:?}", self.start, self.end, self.limit)
|
||||
}
|
||||
|
||||
fn resolve_index(&self, idx: Option<i64>, len: usize, default: usize) -> usize {
|
||||
|
||||
@@ -2,7 +2,7 @@ use derive_more::Deref;
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::{DataRange, Format};
|
||||
use crate::{DataRange, Format, Limit};
|
||||
|
||||
/// Data range with output format for API query parameters
|
||||
#[derive(Default, Debug, Deref, Deserialize, JsonSchema)]
|
||||
@@ -31,8 +31,8 @@ impl DataRangeFormat {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_count(mut self, count: usize) -> Self {
|
||||
self.range = self.range.set_count(count);
|
||||
pub fn set_limit(mut self, limit: Limit) -> Self {
|
||||
self.range = self.range.set_limit(limit);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
use serde::{Deserialize, Deserializer};
|
||||
use serde_json::Value;
|
||||
|
||||
use crate::Limit;
|
||||
|
||||
pub fn de_unquote_i64<'de, D>(deserializer: D) -> Result<Option<i64>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
@@ -56,3 +58,10 @@ where
|
||||
Err(serde::de::Error::custom("expected a string or number"))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn de_unquote_limit<'de, D>(deserializer: D) -> Result<Option<Limit>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
de_unquote_usize(deserializer).map(|opt| opt.map(Limit::from))
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
|
||||
/// Maximum number of results to return. Defaults to 100 if not specified.
|
||||
#[derive(Debug, Deref, Deserialize, JsonSchema)]
|
||||
#[derive(Debug, Clone, Copy, Deref, Deserialize, JsonSchema)]
|
||||
#[serde(transparent)]
|
||||
#[allow(clippy::duplicated_attributes)]
|
||||
#[schemars(default, example = 1, example = 10, example = 100)]
|
||||
@@ -27,3 +27,9 @@ impl fmt::Display for Limit {
|
||||
write!(f, "{}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<usize> for Limit {
|
||||
fn from(value: usize) -> Self {
|
||||
Self(value)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@
|
||||
* @typedef {Object} DataRangeFormat
|
||||
* @property {?number=} start - Inclusive starting index, if negative counts from end
|
||||
* @property {?number=} end - Exclusive ending index, if negative counts from end
|
||||
* @property {?number=} count - Number of values to return (ignored if `end` is set)
|
||||
* @property {(Limit|null)=} limit - Maximum number of values to return (ignored if `end` is set)
|
||||
* @property {Format=} format - Format of the output
|
||||
*/
|
||||
/**
|
||||
@@ -385,7 +385,7 @@
|
||||
* @property {Index} index - Index to query
|
||||
* @property {?number=} start - Inclusive starting index, if negative counts from end
|
||||
* @property {?number=} end - Exclusive ending index, if negative counts from end
|
||||
* @property {?number=} count - Number of values to return (ignored if `end` is set)
|
||||
* @property {(Limit|null)=} limit - Maximum number of values to return (ignored if `end` is set)
|
||||
* @property {Format=} format - Format of the output
|
||||
*/
|
||||
/**
|
||||
@@ -396,7 +396,7 @@
|
||||
* @property {Metrics} ids
|
||||
* @property {?number=} start - Inclusive starting index, if negative counts from end
|
||||
* @property {?number=} end - Exclusive ending index, if negative counts from end
|
||||
* @property {?number=} count - Number of values to return (ignored if `end` is set)
|
||||
* @property {(Limit|null)=} limit - Maximum number of values to return (ignored if `end` is set)
|
||||
* @property {Format=} format - Format of the output
|
||||
*/
|
||||
/**
|
||||
@@ -2628,45 +2628,6 @@ function createPeriodAveragePricePattern(client, acc) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @typedef {Object} DollarsPattern
|
||||
* @property {MetricPattern2<T>} average
|
||||
* @property {MetricPattern11<T>} base
|
||||
* @property {MetricPattern1<T>} cumulative
|
||||
* @property {MetricPattern2<T>} max
|
||||
* @property {MetricPattern6<T>} median
|
||||
* @property {MetricPattern2<T>} min
|
||||
* @property {MetricPattern6<T>} pct10
|
||||
* @property {MetricPattern6<T>} pct25
|
||||
* @property {MetricPattern6<T>} pct75
|
||||
* @property {MetricPattern6<T>} pct90
|
||||
* @property {MetricPattern2<T>} sum
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a DollarsPattern pattern node
|
||||
* @template T
|
||||
* @param {BrkClientBase} client
|
||||
* @param {string} acc - Accumulated metric name
|
||||
* @returns {DollarsPattern<T>}
|
||||
*/
|
||||
function createDollarsPattern(client, acc) {
|
||||
return {
|
||||
average: createMetricPattern2(client, _m(acc, 'average')),
|
||||
base: createMetricPattern11(client, acc),
|
||||
cumulative: createMetricPattern1(client, _m(acc, 'cumulative')),
|
||||
max: createMetricPattern2(client, _m(acc, 'max')),
|
||||
median: createMetricPattern6(client, _m(acc, 'median')),
|
||||
min: createMetricPattern2(client, _m(acc, 'min')),
|
||||
pct10: createMetricPattern6(client, _m(acc, 'pct10')),
|
||||
pct25: createMetricPattern6(client, _m(acc, 'pct25')),
|
||||
pct75: createMetricPattern6(client, _m(acc, 'pct75')),
|
||||
pct90: createMetricPattern6(client, _m(acc, 'pct90')),
|
||||
sum: createMetricPattern2(client, _m(acc, 'sum')),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @typedef {Object} ClassAveragePricePattern
|
||||
@@ -2706,6 +2667,45 @@ function createClassAveragePricePattern(client, basePath) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @typedef {Object} DollarsPattern
|
||||
* @property {MetricPattern2<T>} average
|
||||
* @property {MetricPattern11<T>} base
|
||||
* @property {MetricPattern1<T>} cumulative
|
||||
* @property {MetricPattern2<T>} max
|
||||
* @property {MetricPattern6<T>} median
|
||||
* @property {MetricPattern2<T>} min
|
||||
* @property {MetricPattern6<T>} pct10
|
||||
* @property {MetricPattern6<T>} pct25
|
||||
* @property {MetricPattern6<T>} pct75
|
||||
* @property {MetricPattern6<T>} pct90
|
||||
* @property {MetricPattern2<T>} sum
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a DollarsPattern pattern node
|
||||
* @template T
|
||||
* @param {BrkClientBase} client
|
||||
* @param {string} acc - Accumulated metric name
|
||||
* @returns {DollarsPattern<T>}
|
||||
*/
|
||||
function createDollarsPattern(client, acc) {
|
||||
return {
|
||||
average: createMetricPattern2(client, _m(acc, 'average')),
|
||||
base: createMetricPattern11(client, acc),
|
||||
cumulative: createMetricPattern1(client, _m(acc, 'cumulative')),
|
||||
max: createMetricPattern2(client, _m(acc, 'max')),
|
||||
median: createMetricPattern6(client, _m(acc, 'median')),
|
||||
min: createMetricPattern2(client, _m(acc, 'min')),
|
||||
pct10: createMetricPattern6(client, _m(acc, 'pct10')),
|
||||
pct25: createMetricPattern6(client, _m(acc, 'pct25')),
|
||||
pct75: createMetricPattern6(client, _m(acc, 'pct75')),
|
||||
pct90: createMetricPattern6(client, _m(acc, 'pct90')),
|
||||
sum: createMetricPattern2(client, _m(acc, 'sum')),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @typedef {Object} FullnessPattern
|
||||
@@ -2951,6 +2951,93 @@ function create_0satsPattern(client, acc) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} _0satsPattern2
|
||||
* @property {ActivityPattern2} activity
|
||||
* @property {CostBasisPattern} costBasis
|
||||
* @property {OutputsPattern} outputs
|
||||
* @property {RealizedPattern} realized
|
||||
* @property {RelativePattern4} relative
|
||||
* @property {SupplyPattern2} supply
|
||||
* @property {UnrealizedPattern} unrealized
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a _0satsPattern2 pattern node
|
||||
* @param {BrkClientBase} client
|
||||
* @param {string} acc - Accumulated metric name
|
||||
* @returns {_0satsPattern2}
|
||||
*/
|
||||
function create_0satsPattern2(client, acc) {
|
||||
return {
|
||||
activity: createActivityPattern2(client, acc),
|
||||
costBasis: createCostBasisPattern(client, acc),
|
||||
outputs: createOutputsPattern(client, acc),
|
||||
realized: createRealizedPattern(client, acc),
|
||||
relative: createRelativePattern4(client, _m(acc, 'supply_in')),
|
||||
supply: createSupplyPattern2(client, _m(acc, 'supply')),
|
||||
unrealized: createUnrealizedPattern(client, acc),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} _100btcPattern
|
||||
* @property {ActivityPattern2} activity
|
||||
* @property {CostBasisPattern} costBasis
|
||||
* @property {OutputsPattern} outputs
|
||||
* @property {RealizedPattern} realized
|
||||
* @property {RelativePattern} relative
|
||||
* @property {SupplyPattern2} supply
|
||||
* @property {UnrealizedPattern} unrealized
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a _100btcPattern pattern node
|
||||
* @param {BrkClientBase} client
|
||||
* @param {string} acc - Accumulated metric name
|
||||
* @returns {_100btcPattern}
|
||||
*/
|
||||
function create_100btcPattern(client, acc) {
|
||||
return {
|
||||
activity: createActivityPattern2(client, acc),
|
||||
costBasis: createCostBasisPattern(client, acc),
|
||||
outputs: createOutputsPattern(client, acc),
|
||||
realized: createRealizedPattern(client, acc),
|
||||
relative: createRelativePattern(client, acc),
|
||||
supply: createSupplyPattern2(client, _m(acc, 'supply')),
|
||||
unrealized: createUnrealizedPattern(client, acc),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} _10yPattern
|
||||
* @property {ActivityPattern2} activity
|
||||
* @property {CostBasisPattern} costBasis
|
||||
* @property {OutputsPattern} outputs
|
||||
* @property {RealizedPattern4} realized
|
||||
* @property {RelativePattern} relative
|
||||
* @property {SupplyPattern2} supply
|
||||
* @property {UnrealizedPattern} unrealized
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a _10yPattern pattern node
|
||||
* @param {BrkClientBase} client
|
||||
* @param {string} acc - Accumulated metric name
|
||||
* @returns {_10yPattern}
|
||||
*/
|
||||
function create_10yPattern(client, acc) {
|
||||
return {
|
||||
activity: createActivityPattern2(client, acc),
|
||||
costBasis: createCostBasisPattern(client, acc),
|
||||
outputs: createOutputsPattern(client, acc),
|
||||
realized: createRealizedPattern4(client, acc),
|
||||
relative: createRelativePattern(client, acc),
|
||||
supply: createSupplyPattern2(client, _m(acc, 'supply')),
|
||||
unrealized: createUnrealizedPattern(client, acc),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} PeriodCagrPattern
|
||||
* @property {MetricPattern4<StoredF32>} _10y
|
||||
@@ -3009,64 +3096,6 @@ function create_10yTo12yPattern(client, acc) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} _10yPattern
|
||||
* @property {ActivityPattern2} activity
|
||||
* @property {CostBasisPattern} costBasis
|
||||
* @property {OutputsPattern} outputs
|
||||
* @property {RealizedPattern4} realized
|
||||
* @property {RelativePattern} relative
|
||||
* @property {SupplyPattern2} supply
|
||||
* @property {UnrealizedPattern} unrealized
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a _10yPattern pattern node
|
||||
* @param {BrkClientBase} client
|
||||
* @param {string} acc - Accumulated metric name
|
||||
* @returns {_10yPattern}
|
||||
*/
|
||||
function create_10yPattern(client, acc) {
|
||||
return {
|
||||
activity: createActivityPattern2(client, acc),
|
||||
costBasis: createCostBasisPattern(client, acc),
|
||||
outputs: createOutputsPattern(client, acc),
|
||||
realized: createRealizedPattern4(client, acc),
|
||||
relative: createRelativePattern(client, acc),
|
||||
supply: createSupplyPattern2(client, _m(acc, 'supply')),
|
||||
unrealized: createUnrealizedPattern(client, acc),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} _100btcPattern
|
||||
* @property {ActivityPattern2} activity
|
||||
* @property {CostBasisPattern} costBasis
|
||||
* @property {OutputsPattern} outputs
|
||||
* @property {RealizedPattern} realized
|
||||
* @property {RelativePattern} relative
|
||||
* @property {SupplyPattern2} supply
|
||||
* @property {UnrealizedPattern} unrealized
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a _100btcPattern pattern node
|
||||
* @param {BrkClientBase} client
|
||||
* @param {string} acc - Accumulated metric name
|
||||
* @returns {_100btcPattern}
|
||||
*/
|
||||
function create_100btcPattern(client, acc) {
|
||||
return {
|
||||
activity: createActivityPattern2(client, acc),
|
||||
costBasis: createCostBasisPattern(client, acc),
|
||||
outputs: createOutputsPattern(client, acc),
|
||||
realized: createRealizedPattern(client, acc),
|
||||
relative: createRelativePattern(client, acc),
|
||||
supply: createSupplyPattern2(client, _m(acc, 'supply')),
|
||||
unrealized: createUnrealizedPattern(client, acc),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} UnrealizedPattern
|
||||
* @property {MetricPattern1<Dollars>} negUnrealizedLoss
|
||||
@@ -3096,35 +3125,6 @@ function createUnrealizedPattern(client, acc) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} _0satsPattern2
|
||||
* @property {ActivityPattern2} activity
|
||||
* @property {CostBasisPattern} costBasis
|
||||
* @property {OutputsPattern} outputs
|
||||
* @property {RealizedPattern} realized
|
||||
* @property {RelativePattern4} relative
|
||||
* @property {SupplyPattern2} supply
|
||||
* @property {UnrealizedPattern} unrealized
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a _0satsPattern2 pattern node
|
||||
* @param {BrkClientBase} client
|
||||
* @param {string} acc - Accumulated metric name
|
||||
* @returns {_0satsPattern2}
|
||||
*/
|
||||
function create_0satsPattern2(client, acc) {
|
||||
return {
|
||||
activity: createActivityPattern2(client, acc),
|
||||
costBasis: createCostBasisPattern(client, acc),
|
||||
outputs: createOutputsPattern(client, acc),
|
||||
realized: createRealizedPattern(client, acc),
|
||||
relative: createRelativePattern4(client, _m(acc, 'supply_in')),
|
||||
supply: createSupplyPattern2(client, _m(acc, 'supply')),
|
||||
unrealized: createUnrealizedPattern(client, acc),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} ActivityPattern2
|
||||
* @property {BlockCountPattern<StoredF64>} coinblocksDestroyed
|
||||
@@ -3175,27 +3175,6 @@ function createSplitPattern2(client, acc) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} CoinbasePattern
|
||||
* @property {FullnessPattern<Bitcoin>} bitcoin
|
||||
* @property {DollarsPattern<Dollars>} dollars
|
||||
* @property {DollarsPattern<Sats>} sats
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a CoinbasePattern pattern node
|
||||
* @param {BrkClientBase} client
|
||||
* @param {string} acc - Accumulated metric name
|
||||
* @returns {CoinbasePattern}
|
||||
*/
|
||||
function createCoinbasePattern(client, acc) {
|
||||
return {
|
||||
bitcoin: createFullnessPattern(client, _m(acc, 'btc')),
|
||||
dollars: createDollarsPattern(client, _m(acc, 'usd')),
|
||||
sats: createDollarsPattern(client, acc),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} CostBasisPattern2
|
||||
* @property {MetricPattern1<Dollars>} max
|
||||
@@ -3217,27 +3196,6 @@ function createCostBasisPattern2(client, basePath) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} CoinbasePattern2
|
||||
* @property {BlockCountPattern<Bitcoin>} bitcoin
|
||||
* @property {BlockCountPattern<Dollars>} dollars
|
||||
* @property {BlockCountPattern<Sats>} sats
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a CoinbasePattern2 pattern node
|
||||
* @param {BrkClientBase} client
|
||||
* @param {string} acc - Accumulated metric name
|
||||
* @returns {CoinbasePattern2}
|
||||
*/
|
||||
function createCoinbasePattern2(client, acc) {
|
||||
return {
|
||||
bitcoin: createBlockCountPattern(client, _m(acc, 'btc')),
|
||||
dollars: createBlockCountPattern(client, _m(acc, 'usd')),
|
||||
sats: createBlockCountPattern(client, acc),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} ActiveSupplyPattern
|
||||
* @property {MetricPattern1<Bitcoin>} bitcoin
|
||||
@@ -3281,26 +3239,47 @@ function create_2015Pattern(client, acc) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} UnclaimedRewardsPattern
|
||||
* @property {BitcoinPattern<Bitcoin>} bitcoin
|
||||
* @typedef {Object} CoinbasePattern2
|
||||
* @property {BlockCountPattern<Bitcoin>} bitcoin
|
||||
* @property {BlockCountPattern<Dollars>} dollars
|
||||
* @property {BlockCountPattern<Sats>} sats
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a UnclaimedRewardsPattern pattern node
|
||||
* Create a CoinbasePattern2 pattern node
|
||||
* @param {BrkClientBase} client
|
||||
* @param {string} acc - Accumulated metric name
|
||||
* @returns {UnclaimedRewardsPattern}
|
||||
* @returns {CoinbasePattern2}
|
||||
*/
|
||||
function createUnclaimedRewardsPattern(client, acc) {
|
||||
function createCoinbasePattern2(client, acc) {
|
||||
return {
|
||||
bitcoin: createBitcoinPattern(client, _m(acc, 'btc')),
|
||||
bitcoin: createBlockCountPattern(client, _m(acc, 'btc')),
|
||||
dollars: createBlockCountPattern(client, _m(acc, 'usd')),
|
||||
sats: createBlockCountPattern(client, acc),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} CoinbasePattern
|
||||
* @property {FullnessPattern<Bitcoin>} bitcoin
|
||||
* @property {DollarsPattern<Dollars>} dollars
|
||||
* @property {DollarsPattern<Sats>} sats
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a CoinbasePattern pattern node
|
||||
* @param {BrkClientBase} client
|
||||
* @param {string} acc - Accumulated metric name
|
||||
* @returns {CoinbasePattern}
|
||||
*/
|
||||
function createCoinbasePattern(client, acc) {
|
||||
return {
|
||||
bitcoin: createFullnessPattern(client, _m(acc, 'btc')),
|
||||
dollars: createDollarsPattern(client, _m(acc, 'usd')),
|
||||
sats: createDollarsPattern(client, acc),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} SegwitAdoptionPattern
|
||||
* @property {MetricPattern11<StoredF32>} base
|
||||
@@ -3323,21 +3302,23 @@ function createSegwitAdoptionPattern(client, acc) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} SupplyPattern2
|
||||
* @property {ActiveSupplyPattern} halved
|
||||
* @property {ActiveSupplyPattern} total
|
||||
* @typedef {Object} UnclaimedRewardsPattern
|
||||
* @property {BitcoinPattern<Bitcoin>} bitcoin
|
||||
* @property {BlockCountPattern<Dollars>} dollars
|
||||
* @property {BlockCountPattern<Sats>} sats
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a SupplyPattern2 pattern node
|
||||
* Create a UnclaimedRewardsPattern pattern node
|
||||
* @param {BrkClientBase} client
|
||||
* @param {string} acc - Accumulated metric name
|
||||
* @returns {SupplyPattern2}
|
||||
* @returns {UnclaimedRewardsPattern}
|
||||
*/
|
||||
function createSupplyPattern2(client, acc) {
|
||||
function createUnclaimedRewardsPattern(client, acc) {
|
||||
return {
|
||||
halved: createActiveSupplyPattern(client, _m(acc, 'half')),
|
||||
total: createActiveSupplyPattern(client, acc),
|
||||
bitcoin: createBitcoinPattern(client, _m(acc, 'btc')),
|
||||
dollars: createBlockCountPattern(client, _m(acc, 'usd')),
|
||||
sats: createBlockCountPattern(client, acc),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3360,6 +3341,25 @@ function createCostBasisPattern(client, acc) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} _1dReturns1mSdPattern
|
||||
* @property {MetricPattern4<StoredF32>} sd
|
||||
* @property {MetricPattern4<StoredF32>} sma
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a _1dReturns1mSdPattern pattern node
|
||||
* @param {BrkClientBase} client
|
||||
* @param {string} acc - Accumulated metric name
|
||||
* @returns {_1dReturns1mSdPattern}
|
||||
*/
|
||||
function create_1dReturns1mSdPattern(client, acc) {
|
||||
return {
|
||||
sd: createMetricPattern4(client, _m(acc, 'sd')),
|
||||
sma: createMetricPattern4(client, _m(acc, 'sma')),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} RelativePattern4
|
||||
* @property {MetricPattern1<StoredF64>} supplyInLossRelToOwnSupply
|
||||
@@ -3380,21 +3380,42 @@ function createRelativePattern4(client, acc) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} _1dReturns1mSdPattern
|
||||
* @property {MetricPattern4<StoredF32>} sd
|
||||
* @property {MetricPattern4<StoredF32>} sma
|
||||
* @typedef {Object} SupplyPattern2
|
||||
* @property {ActiveSupplyPattern} halved
|
||||
* @property {ActiveSupplyPattern} total
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a _1dReturns1mSdPattern pattern node
|
||||
* Create a SupplyPattern2 pattern node
|
||||
* @param {BrkClientBase} client
|
||||
* @param {string} acc - Accumulated metric name
|
||||
* @returns {_1dReturns1mSdPattern}
|
||||
* @returns {SupplyPattern2}
|
||||
*/
|
||||
function create_1dReturns1mSdPattern(client, acc) {
|
||||
function createSupplyPattern2(client, acc) {
|
||||
return {
|
||||
sd: createMetricPattern4(client, _m(acc, 'sd')),
|
||||
sma: createMetricPattern4(client, _m(acc, 'sma')),
|
||||
halved: createActiveSupplyPattern(client, _m(acc, 'half')),
|
||||
total: createActiveSupplyPattern(client, acc),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @typedef {Object} SatsPattern
|
||||
* @property {MetricPattern1<T>} ohlc
|
||||
* @property {SplitPattern2<T>} split
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a SatsPattern pattern node
|
||||
* @template T
|
||||
* @param {BrkClientBase} client
|
||||
* @param {string} basePath
|
||||
* @returns {SatsPattern<T>}
|
||||
*/
|
||||
function createSatsPattern(client, basePath) {
|
||||
return {
|
||||
ohlc: createMetricPattern1(client, `${basePath}_ohlc`),
|
||||
split: createSplitPattern2(client, `${basePath}_split`),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3441,23 +3462,19 @@ function createBlockCountPattern(client, acc) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @typedef {Object} SatsPattern
|
||||
* @property {MetricPattern1<T>} ohlc
|
||||
* @property {SplitPattern2<T>} split
|
||||
* @typedef {Object} RealizedPriceExtraPattern
|
||||
* @property {MetricPattern4<StoredF32>} ratio
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a SatsPattern pattern node
|
||||
* @template T
|
||||
* Create a RealizedPriceExtraPattern pattern node
|
||||
* @param {BrkClientBase} client
|
||||
* @param {string} basePath
|
||||
* @returns {SatsPattern<T>}
|
||||
* @param {string} acc - Accumulated metric name
|
||||
* @returns {RealizedPriceExtraPattern}
|
||||
*/
|
||||
function createSatsPattern(client, basePath) {
|
||||
function createRealizedPriceExtraPattern(client, acc) {
|
||||
return {
|
||||
ohlc: createMetricPattern1(client, `${basePath}_ohlc`),
|
||||
split: createSplitPattern2(client, `${basePath}_split`),
|
||||
ratio: createMetricPattern4(client, _m(acc, 'ratio')),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3478,23 +3495,6 @@ function createOutputsPattern(client, acc) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {Object} RealizedPriceExtraPattern
|
||||
* @property {MetricPattern4<StoredF32>} ratio
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create a RealizedPriceExtraPattern pattern node
|
||||
* @param {BrkClientBase} client
|
||||
* @param {string} acc - Accumulated metric name
|
||||
* @returns {RealizedPriceExtraPattern}
|
||||
*/
|
||||
function createRealizedPriceExtraPattern(client, acc) {
|
||||
return {
|
||||
ratio: createMetricPattern4(client, _m(acc, 'ratio')),
|
||||
};
|
||||
}
|
||||
|
||||
// Catalog tree typedefs
|
||||
|
||||
/**
|
||||
@@ -7112,15 +7112,15 @@ class BrkClient extends BrkClientBase {
|
||||
* @param {Index} index - Aggregation index
|
||||
* @param {number=} [start] - Inclusive starting index, if negative counts from end
|
||||
* @param {number=} [end] - Exclusive ending index, if negative counts from end
|
||||
* @param {number=} [count] - Number of values to return (ignored if `end` is set)
|
||||
* @param {string=} [limit] - Maximum number of values to return (ignored if `end` is set)
|
||||
* @param {Format=} [format] - Format of the output
|
||||
* @returns {Promise<AnyMetricData | string>}
|
||||
*/
|
||||
async getMetricByIndex(metric, index, start, end, count, format) {
|
||||
async getMetricByIndex(metric, index, start, end, limit, format) {
|
||||
const params = new URLSearchParams();
|
||||
if (start !== undefined) params.set('start', String(start));
|
||||
if (end !== undefined) params.set('end', String(end));
|
||||
if (count !== undefined) params.set('count', String(count));
|
||||
if (limit !== undefined) params.set('limit', String(limit));
|
||||
if (format !== undefined) params.set('format', String(format));
|
||||
const query = params.toString();
|
||||
const path = `/api/metric/${metric}/${index}${query ? '?' + query : ''}`;
|
||||
@@ -7149,17 +7149,17 @@ class BrkClient extends BrkClientBase {
|
||||
* @param {Index} [index] - Index to query
|
||||
* @param {number=} [start] - Inclusive starting index, if negative counts from end
|
||||
* @param {number=} [end] - Exclusive ending index, if negative counts from end
|
||||
* @param {number=} [count] - Number of values to return (ignored if `end` is set)
|
||||
* @param {string=} [limit] - Maximum number of values to return (ignored if `end` is set)
|
||||
* @param {Format=} [format] - Format of the output
|
||||
* @returns {Promise<AnyMetricData[] | string>}
|
||||
*/
|
||||
async getMetricsBulk(metrics, index, start, end, count, format) {
|
||||
async getMetricsBulk(metrics, index, start, end, limit, format) {
|
||||
const params = new URLSearchParams();
|
||||
params.set('metrics', String(metrics));
|
||||
params.set('index', String(index));
|
||||
if (start !== undefined) params.set('start', String(start));
|
||||
if (end !== undefined) params.set('end', String(end));
|
||||
if (count !== undefined) params.set('count', String(count));
|
||||
if (limit !== undefined) params.set('limit', String(limit));
|
||||
if (format !== undefined) params.set('format', String(format));
|
||||
const query = params.toString();
|
||||
const path = `/api/metrics/bulk${query ? '?' + query : ''}`;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1563,7 +1563,7 @@
|
||||
<link rel="modulepreload" href="/scripts/entry.fe229b42.js">
|
||||
<link rel="modulepreload" href="/scripts/lazy.1ae52534.js">
|
||||
<link rel="modulepreload" href="/scripts/main.22a5bd79.js">
|
||||
<link rel="modulepreload" href="/scripts/modules/brk-client/index.22379f83.js">
|
||||
<link rel="modulepreload" href="/scripts/modules/brk-client/index.f69b33ed.js">
|
||||
<link rel="modulepreload" href="/scripts/modules/brk-client/tests/basic.b92ff866.js">
|
||||
<link rel="modulepreload" href="/scripts/modules/brk-client/tests/tree.ba9474f7.js">
|
||||
<link rel="modulepreload" href="/scripts/modules/lean-qr/2.6.1/index.09195c13.mjs">
|
||||
@@ -1634,7 +1634,7 @@
|
||||
"/scripts/entry.js": "/scripts/entry.fe229b42.js",
|
||||
"/scripts/lazy.js": "/scripts/lazy.1ae52534.js",
|
||||
"/scripts/main.js": "/scripts/main.22a5bd79.js",
|
||||
"/scripts/modules/brk-client/index.js": "/scripts/modules/brk-client/index.22379f83.js",
|
||||
"/scripts/modules/brk-client/index.js": "/scripts/modules/brk-client/index.f69b33ed.js",
|
||||
"/scripts/modules/brk-client/tests/basic.js": "/scripts/modules/brk-client/tests/basic.b92ff866.js",
|
||||
"/scripts/modules/brk-client/tests/tree.js": "/scripts/modules/brk-client/tests/tree.ba9474f7.js",
|
||||
"/scripts/modules/lean-qr/2.6.1/index.mjs": "/scripts/modules/lean-qr/2.6.1/index.09195c13.mjs",
|
||||
|
||||
@@ -384,8 +384,8 @@ function createChartElement({
|
||||
/** @type {AnyMetricPattern} */
|
||||
const timeMetric =
|
||||
index === "height"
|
||||
? brk.tree.blocks.time.timestampFixed
|
||||
: brk.tree.blocks.time.timestamp;
|
||||
? brk.metrics.blocks.time.timestampFixed
|
||||
: brk.metrics.blocks.time.timestamp;
|
||||
/** @type {AnyMetricPattern} */
|
||||
const valuesMetric = metric;
|
||||
const timeNode = timeMetric.by[index];
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* @import { Signal, Signals, Accessor } from "./signals.js";
|
||||
*
|
||||
* @import { BrkClient, CatalogTree_Distribution_UtxoCohorts as UtxoCohortTree, CatalogTree_Distribution_AddressCohorts as AddressCohortTree, CatalogTree_Distribution_UtxoCohorts_All as AllUtxoPattern, CatalogTree_Distribution_UtxoCohorts_Term_Short as ShortTermPattern, CatalogTree_Distribution_UtxoCohorts_Term_Long as LongTermPattern, _10yPattern as MaxAgePattern, _10yTo12yPattern as AgeRangePattern, _0satsPattern2 as UtxoAmountPattern, _0satsPattern as AddressAmountPattern, _100btcPattern as BasicUtxoPattern, _0satsPattern2 as EpochPattern, Ratio1ySdPattern, Dollars, Price111dSmaPattern as EmaRatioPattern, Index, BlockCountPattern, SizePattern, FullnessPattern, FeeRatePattern, CoinbasePattern, ActivePriceRatioPattern, _0satsPattern, UnclaimedRewardsPattern as ValuePattern, Metric, MetricPattern, AnyMetricPattern, MetricEndpoint, MetricData, AnyMetricEndpoint, AnyMetricData, AddrCountPattern, CatalogTree_Blocks_Interval as IntervalPattern, _24hCoinbaseSumPattern as SupplyPattern, RelativePattern, RelativePattern2, RelativePattern5, CatalogTree_Distribution_UtxoCohorts_All_Relative as AllRelativePattern } from "./modules/brk-client/index.js"
|
||||
* @import { BrkClient, MetricsTree_Distribution_UtxoCohorts as UtxoCohortTree, MetricsTree_Distribution_AddressCohorts as AddressCohortTree, MetricsTree_Distribution_UtxoCohorts_All as AllUtxoPattern, MetricsTree_Distribution_UtxoCohorts_Term_Short as ShortTermPattern, MetricsTree_Distribution_UtxoCohorts_Term_Long as LongTermPattern, _10yPattern as MaxAgePattern, _10yTo12yPattern as AgeRangePattern, _0satsPattern2 as UtxoAmountPattern, _0satsPattern as AddressAmountPattern, _100btcPattern as BasicUtxoPattern, _0satsPattern2 as EpochPattern, Ratio1ySdPattern, Dollars, Price111dSmaPattern as EmaRatioPattern, Index, BlockCountPattern, SizePattern, FullnessPattern, FeeRatePattern, CoinbasePattern, ActivePriceRatioPattern, _0satsPattern, UnclaimedRewardsPattern as ValuePattern, Metric, MetricPattern, AnyMetricPattern, MetricEndpoint, MetricData, AnyMetricEndpoint, AnyMetricData, AddrCountPattern, MetricsTree_Blocks_Interval as IntervalPattern, _24hCoinbaseSumPattern as SupplyPattern, RelativePattern, RelativePattern2, RelativePattern5, MetricsTree_Distribution_UtxoCohorts_All_Relative as AllRelativePattern } from "./modules/brk-client/index.js"
|
||||
*
|
||||
* @import { Resources, MetricResource } from './resources.js'
|
||||
*
|
||||
|
||||
@@ -31,7 +31,7 @@ export function createChainSection(ctx) {
|
||||
market,
|
||||
scripts,
|
||||
supply,
|
||||
} = brk.tree;
|
||||
} = brk.metrics;
|
||||
|
||||
// Build pools tree dynamically
|
||||
const poolEntries = Object.entries(pools.vecs);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/** Build cohort data arrays from brk.tree */
|
||||
/** Build cohort data arrays from brk.metrics */
|
||||
|
||||
import {
|
||||
termColors,
|
||||
@@ -28,8 +28,8 @@ const entries = (obj) =>
|
||||
* @param {BrkClient} brk
|
||||
*/
|
||||
export function buildCohortData(colors, brk) {
|
||||
const utxoCohorts = brk.tree.distribution.utxoCohorts;
|
||||
const addressCohorts = brk.tree.distribution.addressCohorts;
|
||||
const utxoCohorts = brk.metrics.distribution.utxoCohorts;
|
||||
const addressCohorts = brk.metrics.distribution.addressCohorts;
|
||||
const {
|
||||
TERM_NAMES,
|
||||
EPOCH_NAMES,
|
||||
|
||||
@@ -144,7 +144,7 @@ export function createSingleSupplySeries(ctx, cohort) {
|
||||
*/
|
||||
export function createGroupedSupplyTotalSeries(ctx, list) {
|
||||
const { line, brk } = ctx;
|
||||
const constant100 = brk.tree.constants.constant100;
|
||||
const constant100 = brk.metrics.constants.constant100;
|
||||
|
||||
return list.flatMap(({ color, name, tree }) => [
|
||||
line({ metric: tree.supply.total.sats, name, color, unit: Unit.sats }),
|
||||
|
||||
@@ -172,7 +172,7 @@ function createCointimePriceWithRatioOptions(
|
||||
*/
|
||||
export function createCointimeSection(ctx) {
|
||||
const { colors, brk, line } = ctx;
|
||||
const { cointime, distribution, supply } = brk.tree;
|
||||
const { cointime, distribution, supply } = brk.metrics;
|
||||
const { pricing, cap, activity, supply: cointimeSupply, adjusted } = cointime;
|
||||
const { all } = distribution.utxoCohorts;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { line } from "./series.js";
|
||||
/**
|
||||
* Get constant pattern by number dynamically from tree
|
||||
* Examples: 0 → constant0, 38.2 → constant382, -1 → constantMinus1
|
||||
* @param {BrkClient["tree"]["constants"]} constants
|
||||
* @param {BrkClient["metrics"]["constants"]} constants
|
||||
* @param {number} num
|
||||
* @returns {AnyMetricPattern}
|
||||
*/
|
||||
@@ -24,7 +24,7 @@ export function getConstant(constants, num) {
|
||||
/**
|
||||
* Create a price line series (horizontal reference line)
|
||||
* @param {Object} args
|
||||
* @param {BrkClient["tree"]["constants"]} args.constants
|
||||
* @param {BrkClient["metrics"]["constants"]} args.constants
|
||||
* @param {Colors} args.colors
|
||||
* @param {number} [args.number]
|
||||
* @param {string} [args.name]
|
||||
@@ -61,7 +61,7 @@ export function createPriceLine({
|
||||
/**
|
||||
* Create multiple price lines from an array of numbers
|
||||
* @param {Object} args
|
||||
* @param {BrkClient["tree"]["constants"]} args.constants
|
||||
* @param {BrkClient["metrics"]["constants"]} args.constants
|
||||
* @param {Colors} args.colors
|
||||
* @param {number[]} args.numbers
|
||||
* @param {Unit} args.unit
|
||||
|
||||
@@ -15,7 +15,11 @@ import {
|
||||
fromIntervalPattern,
|
||||
fromSupplyPattern,
|
||||
} from "./series.js";
|
||||
import { createPriceLine, createPriceLines, constantLine } from "./constants.js";
|
||||
import {
|
||||
createPriceLine,
|
||||
createPriceLines,
|
||||
constantLine,
|
||||
} from "./constants.js";
|
||||
|
||||
/**
|
||||
* Create a context object with all dependencies for building partial options
|
||||
@@ -25,7 +29,7 @@ import { createPriceLine, createPriceLines, constantLine } from "./constants.js"
|
||||
* @returns {PartialContext}
|
||||
*/
|
||||
export function createContext({ colors, brk }) {
|
||||
const constants = brk.tree.constants;
|
||||
const constants = brk.metrics.constants;
|
||||
|
||||
return {
|
||||
colors,
|
||||
|
||||
@@ -17,7 +17,7 @@ import { collect, markUsed, logUnused } from "./unused.js";
|
||||
* @param {Signal<string | null>} args.qrcode
|
||||
*/
|
||||
export function initOptions({ colors, signals, brk, qrcode }) {
|
||||
collect(brk.tree);
|
||||
collect(brk.metrics);
|
||||
|
||||
const LS_SELECTED_KEY = `selected_path`;
|
||||
|
||||
@@ -56,9 +56,7 @@ export function initOptions({ colors, signals, brk, qrcode }) {
|
||||
);
|
||||
}
|
||||
if (!blueprint.unit) {
|
||||
throw new Error(
|
||||
`Blueprint missing unit: ${blueprint.title}`,
|
||||
);
|
||||
throw new Error(`Blueprint missing unit: ${blueprint.title}`);
|
||||
}
|
||||
markUsed(blueprint.metric);
|
||||
const unit = blueprint.unit;
|
||||
|
||||
@@ -13,7 +13,7 @@ import { createInvestingSection } from "./investing.js";
|
||||
*/
|
||||
export function createMarketSection(ctx) {
|
||||
const { colors, brk, line } = ctx;
|
||||
const { market, supply } = brk.tree;
|
||||
const { market, supply } = brk.metrics;
|
||||
const {
|
||||
movingAverage,
|
||||
ath,
|
||||
|
||||
@@ -331,7 +331,7 @@ export function init({
|
||||
case null:
|
||||
case CANDLE: {
|
||||
series = chart.addCandlestickSeries({
|
||||
metric: brk.tree.price.usd.ohlc,
|
||||
metric: brk.metrics.price.usd.ohlc,
|
||||
name: "Price",
|
||||
unit: topUnit,
|
||||
setDataCallback: printLatest,
|
||||
@@ -341,7 +341,7 @@ export function init({
|
||||
}
|
||||
case LINE: {
|
||||
series = chart.addLineSeries({
|
||||
metric: brk.tree.price.usd.split.close,
|
||||
metric: brk.metrics.price.usd.split.close,
|
||||
name: "Price",
|
||||
unit: topUnit,
|
||||
color: colors.default,
|
||||
@@ -361,7 +361,7 @@ export function init({
|
||||
case null:
|
||||
case CANDLE: {
|
||||
series = chart.addCandlestickSeries({
|
||||
metric: brk.tree.price.sats.ohlc,
|
||||
metric: brk.metrics.price.sats.ohlc,
|
||||
name: "Price",
|
||||
unit: topUnit,
|
||||
inverse: true,
|
||||
@@ -372,7 +372,7 @@ export function init({
|
||||
}
|
||||
case LINE: {
|
||||
series = chart.addLineSeries({
|
||||
metric: brk.tree.price.sats.split.close,
|
||||
metric: brk.metrics.price.sats.split.close,
|
||||
name: "Price",
|
||||
unit: topUnit,
|
||||
color: colors.default,
|
||||
|
||||
Reference in New Issue
Block a user