global: snapshot part 16

This commit is contained in:
nym21
2026-03-21 17:15:53 +01:00
parent b45c6ec05f
commit 2991562234
31 changed files with 355 additions and 423 deletions
@@ -41,7 +41,7 @@ function volumeTree(tv, color, title) {
return [
...satsBtcUsdFullTree({
pattern: tv,
title: title("Sent Volume"),
title: title("Transfer Volume"),
color,
}),
{
@@ -49,7 +49,7 @@ function volumeTree(tv, color, title) {
tree: [
...ROLLING_WINDOWS.map((w) => ({
name: w.name,
title: title(`Sent Volume Profitability (${w.title})`),
title: title(`Transfer Volume Profitability (${w.title})`),
bottom: [
...satsBtcUsd({
pattern: tv.inProfit.sum[w.key],
@@ -65,7 +65,7 @@ function volumeTree(tv, color, title) {
})),
{
name: "Cumulative",
title: title("Cumulative Sent Volume Profitability"),
title: title("Cumulative Transfer Volume"),
bottom: [
...satsBtcUsd({
pattern: tv.inProfit.cumulative,
@@ -83,7 +83,7 @@ function volumeTree(tv, color, title) {
name: "In Profit",
tree: satsBtcUsdFullTree({
pattern: tv.inProfit,
title: title("Sent In Profit"),
title: title("Transfer Volume In Profit"),
color: colors.profit,
}),
},
@@ -91,7 +91,7 @@ function volumeTree(tv, color, title) {
name: "In Loss",
tree: satsBtcUsdFullTree({
pattern: tv.inLoss,
title: title("Sent In Loss"),
title: title("Transfer Volume In Loss"),
color: colors.loss,
}),
},
@@ -360,7 +360,7 @@ export function createActivitySectionMinimal({ cohort, title }) {
name: "Activity",
tree: satsBtcUsdFullTree({
pattern: cohort.tree.activity.transferVolume,
title: title("Volume"),
title: title("Transfer Volume"),
}),
};
}
@@ -399,7 +399,7 @@ function groupedProfitabilityArray(list, all, title, getInProfit, getInLoss) {
list,
all,
title,
metricTitle: "Sent In Profit",
metricTitle: "Transfer Volume In Profit",
getMetric: (c) => getInProfit(c),
}),
},
@@ -409,7 +409,7 @@ function groupedProfitabilityArray(list, all, title, getInProfit, getInLoss) {
list,
all,
title,
metricTitle: "Sent In Loss",
metricTitle: "Transfer Volume In Loss",
getMetric: (c) => getInLoss(c),
}),
},
@@ -431,7 +431,7 @@ function groupedVolumeTree(list, all, title, getTransferVolume) {
list,
all,
title,
metricTitle: "Sent Volume",
metricTitle: "Transfer Volume",
getMetric: (c) => getTransferVolume(c),
}),
...groupedProfitabilityArray(
@@ -136,7 +136,7 @@ function groupedWeightFolder({ list, all, getAvgPrice, getInProfit, getInLoss, g
return [
{
name: "Average",
title: title(`${avgTitle} Comparison`),
title: title(`Cost Basis ${avgTitle} (${weightLabel})`),
top: mapCohortsWithAll(list, all, (c) =>
price({ series: getAvgPrice(c), name: c.name, color: c.color }),
),
@@ -82,7 +82,7 @@ function singleDeltaItems(delta, unit, title, name) {
{
...rollingPercentRatioTree({
windows: delta.rate,
title: title(`${name} Rate`),
title: title(`${name} Growth Rate`),
}),
name: "Growth Rate",
},
@@ -121,7 +121,7 @@ function groupedDeltaItems(list, all, getDelta, unit, title, name) {
name: "Growth Rate",
tree: ROLLING_WINDOWS.map((w) => ({
name: w.name,
title: title(`${name} Rate (${w.title})`),
title: title(`${name} Growth Rate (${w.title})`),
bottom: flatMapCohortsWithAll(list, all, (c) =>
percentRatioBaseline({
pattern: getDelta(c).rate[w.key],
@@ -212,17 +212,18 @@ function ownSupplyChart(supply, title) {
* Count folder (UTXO or Address) with value + change
* @param {{ base: AnySeriesPattern, delta: DeltaPattern }} pattern
* @param {string} name
* @param {string} chartTitle
* @param {Color} color
* @param {(name: string) => string} title
* @returns {PartialOptionsGroup}
*/
function countFolder(pattern, name, color, title) {
function countFolder(pattern, name, chartTitle, color, title) {
return {
name,
tree: [
{
name: "Count",
title: title(name),
title: title(chartTitle),
bottom: [
line({
series: pattern.base,
@@ -259,7 +260,7 @@ export function createHoldingsSection({ cohort, title }) {
...singleDeltaItems(supply.delta, Unit.sats, title, "Change"),
],
},
countFolder(cohort.tree.outputs.unspentCount, "UTXOs", cohort.color, title),
countFolder(cohort.tree.outputs.unspentCount, "UTXOs", "UTXO Count", cohort.color, title),
];
}
@@ -283,8 +284,8 @@ export function createHoldingsSectionAll({ cohort, title }) {
...singleDeltaItems(supply.delta, Unit.sats, title, "Change"),
],
},
countFolder(cohort.tree.outputs.unspentCount, "UTXOs", cohort.color, title),
countFolder(cohort.addressCount, "Addresses", cohort.color, title),
countFolder(cohort.tree.outputs.unspentCount, "UTXOs", "UTXO Count", cohort.color, title),
countFolder(cohort.addressCount, "Addresses", "Address Count", cohort.color, title),
];
}
@@ -309,7 +310,7 @@ export function createHoldingsSectionWithRelative({ cohort, title }) {
...singleDeltaItems(supply.delta, Unit.sats, title, "Change"),
],
},
countFolder(cohort.tree.outputs.unspentCount, "UTXOs", cohort.color, title),
countFolder(cohort.tree.outputs.unspentCount, "UTXOs", "UTXO Count", cohort.color, title),
];
}
@@ -333,7 +334,7 @@ export function createHoldingsSectionWithOwnSupply({ cohort, title }) {
...singleDeltaItems(supply.delta, Unit.sats, title, "Change"),
],
},
countFolder(cohort.tree.outputs.unspentCount, "UTXOs", cohort.color, title),
countFolder(cohort.tree.outputs.unspentCount, "UTXOs", "UTXO Count", cohort.color, title),
];
}
@@ -356,7 +357,7 @@ export function createHoldingsSectionWithProfitLoss({ cohort, title }) {
...singleDeltaItems(supply.delta, Unit.sats, title, "Change"),
],
},
countFolder(cohort.tree.outputs.unspentCount, "UTXOs", cohort.color, title),
countFolder(cohort.tree.outputs.unspentCount, "UTXOs", "UTXO Count", cohort.color, title),
];
}
@@ -379,8 +380,8 @@ export function createHoldingsSectionAddress({ cohort, title }) {
...singleDeltaItems(supply.delta, Unit.sats, title, "Change"),
],
},
countFolder(cohort.tree.outputs.unspentCount, "UTXOs", cohort.color, title),
countFolder(cohort.addressCount, "Addresses", cohort.color, title),
countFolder(cohort.tree.outputs.unspentCount, "UTXOs", "UTXO Count", cohort.color, title),
countFolder(cohort.addressCount, "Addresses", "Address Count", cohort.color, title),
];
}
@@ -402,8 +403,8 @@ export function createHoldingsSectionAddressAmount({ cohort, title }) {
...singleDeltaItems(supply.delta, Unit.sats, title, "Change"),
],
},
countFolder(cohort.tree.outputs.unspentCount, "UTXOs", cohort.color, title),
countFolder(cohort.addressCount, "Addresses", cohort.color, title),
countFolder(cohort.tree.outputs.unspentCount, "UTXOs", "UTXO Count", cohort.color, title),
countFolder(cohort.addressCount, "Addresses", "Address Count", cohort.color, title),
];
}
+13 -12
View File
@@ -65,6 +65,7 @@ import {
createProfitabilitySectionWithInvestedCapitalPct,
createProfitabilitySectionLongTerm,
createGroupedProfitabilitySection,
createGroupedProfitabilitySectionWithProfitLoss,
createGroupedProfitabilitySectionWithNupl,
createGroupedProfitabilitySectionWithInvestedCapitalPct,
} from "./profitability.js";
@@ -91,7 +92,7 @@ export { buildCohortData } from "./data.js";
* @returns {PartialOptionsGroup}
*/
export function createCohortFolderAll(cohort) {
const title = formatCohortTitle(cohort.name);
const title = formatCohortTitle(cohort.title);
return {
name: cohort.name || "all",
tree: [
@@ -111,7 +112,7 @@ export function createCohortFolderAll(cohort) {
* @returns {PartialOptionsGroup}
*/
export function createCohortFolderFull(cohort) {
const title = formatCohortTitle(cohort.name);
const title = formatCohortTitle(cohort.title);
return {
name: cohort.name || "all",
tree: [
@@ -131,7 +132,7 @@ export function createCohortFolderFull(cohort) {
* @returns {PartialOptionsGroup}
*/
export function createCohortFolderWithAdjusted(cohort) {
const title = formatCohortTitle(cohort.name);
const title = formatCohortTitle(cohort.title);
return {
name: cohort.name || "all",
tree: [
@@ -150,7 +151,7 @@ export function createCohortFolderWithAdjusted(cohort) {
* @returns {PartialOptionsGroup}
*/
export function createCohortFolderWithNupl(cohort) {
const title = formatCohortTitle(cohort.name);
const title = formatCohortTitle(cohort.title);
return {
name: cohort.name || "all",
tree: [
@@ -170,7 +171,7 @@ export function createCohortFolderWithNupl(cohort) {
* @returns {PartialOptionsGroup}
*/
export function createCohortFolderLongTerm(cohort) {
const title = formatCohortTitle(cohort.name);
const title = formatCohortTitle(cohort.title);
return {
name: cohort.name || "all",
tree: [
@@ -190,7 +191,7 @@ export function createCohortFolderLongTerm(cohort) {
* @returns {PartialOptionsGroup}
*/
export function createCohortFolderAgeRange(cohort) {
const title = formatCohortTitle(cohort.name);
const title = formatCohortTitle(cohort.title);
return {
name: cohort.name || "all",
tree: [
@@ -210,7 +211,7 @@ export function createCohortFolderAgeRange(cohort) {
*/
export function createCohortFolderAgeRangeWithMatured(cohort) {
const folder = createCohortFolderAgeRange(cohort);
const title = formatCohortTitle(cohort.name);
const title = formatCohortTitle(cohort.title);
folder.tree.push({
name: "Matured",
tree: satsBtcUsdFullTree({
@@ -227,7 +228,7 @@ export function createCohortFolderAgeRangeWithMatured(cohort) {
* @returns {PartialOptionsGroup}
*/
export function createCohortFolderBasicWithMarketCap(cohort) {
const title = formatCohortTitle(cohort.name);
const title = formatCohortTitle(cohort.title);
return {
name: cohort.name || "all",
tree: [
@@ -247,7 +248,7 @@ export function createCohortFolderBasicWithMarketCap(cohort) {
* @returns {PartialOptionsGroup}
*/
export function createCohortFolderAddress(cohort) {
const title = formatCohortTitle(cohort.name);
const title = formatCohortTitle(cohort.title);
return {
name: cohort.name || "all",
tree: [
@@ -266,7 +267,7 @@ export function createCohortFolderAddress(cohort) {
* @returns {PartialOptionsGroup}
*/
export function createCohortFolderWithoutRelative(cohort) {
const title = formatCohortTitle(cohort.name);
const title = formatCohortTitle(cohort.title);
return {
name: cohort.name || "all",
tree: [
@@ -285,7 +286,7 @@ export function createCohortFolderWithoutRelative(cohort) {
* @returns {PartialOptionsGroup}
*/
export function createAddressCohortFolder(cohort) {
const title = formatCohortTitle(cohort.name);
const title = formatCohortTitle(cohort.title);
return {
name: cohort.name || "all",
tree: [
@@ -455,7 +456,7 @@ export function createGroupedCohortFolderAddress({
...createGroupedHoldingsSectionAddress({ list, all, title }),
createGroupedValuationSection({ list, all, title }),
createGroupedPricesSection({ list, all, title }),
createGroupedProfitabilitySection({
createGroupedProfitabilitySectionWithProfitLoss({
list,
all,
title,
@@ -100,6 +100,19 @@ function relPnlChart(profit, loss, name, title) {
};
}
/** @param {{ percent: AnySeriesPattern, ratio: AnySeriesPattern }} net @param {{ percent: AnySeriesPattern, ratio: AnySeriesPattern }} profit @param {{ percent: AnySeriesPattern, ratio: AnySeriesPattern }} loss @param {string} name @param {(name: string) => string} title */
function relPnlChartWithNet(net, profit, loss, name, title) {
return {
name,
title: title(`Unrealized P&L (${name})`),
bottom: [
...percentRatioBaseline({ pattern: net, name: "Net" }),
...percentRatio({ pattern: profit, name: "Profit", color: colors.profit }),
...percentRatio({ pattern: loss, name: "Loss", color: colors.loss }),
],
};
}
/**
* Core unrealized items: Overview + Net + NUPL + Profit + Loss
* @param {{ profit: { usd: AnySeriesPattern }, loss: { usd: AnySeriesPattern, negative: AnySeriesPattern }, netPnl: { usd: AnySeriesPattern }, nupl: NuplPattern }} u
@@ -142,6 +155,30 @@ function unrealizedCore(u, title) {
];
}
/**
* Core unrealized items + Gross
* @param {{ profit: { usd: AnySeriesPattern }, loss: { usd: AnySeriesPattern, negative: AnySeriesPattern }, netPnl: { usd: AnySeriesPattern }, grossPnl: { usd: AnySeriesPattern }, nupl: NuplPattern }} u
* @param {(name: string) => string} title
* @returns {PartialOptionsTree}
*/
function unrealizedCoreWithGross(u, title) {
return [
...unrealizedCore(u, title),
{
name: "Gross",
title: title("Gross Unrealized P&L"),
bottom: [
line({
series: u.grossPnl.usd,
name: "Gross",
color: colors.gross,
unit: Unit.usd,
}),
],
},
];
}
/**
* % of Own P&L chart
* @param {AllRelativePattern | FullRelativePattern} u
@@ -173,7 +210,7 @@ function ownPnlChart(u, title) {
/** @param {AllRelativePattern} u @param {(name: string) => string} title */
function unrealizedTreeAll(u, title) {
return [
...unrealizedCore(u, title),
...unrealizedCoreWithGross(u, title),
ownPnlChart(u, title),
relPnlChart(u.profit.toMcap, u.loss.toMcap, "% of Market Cap", title),
];
@@ -182,22 +219,17 @@ function unrealizedTreeAll(u, title) {
/** @param {FullRelativePattern} u @param {(name: string) => string} title */
function unrealizedTreeFull(u, title) {
return [
...unrealizedCore(u, title),
...unrealizedCoreWithGross(u, title),
ownPnlChart(u, title),
relPnlChart(u.profit.toMcap, u.loss.toMcap, "% of Market Cap", title),
relPnlChart(
u.profit.toOwnMcap,
u.loss.toOwnMcap,
"% of Own Market Cap",
title,
),
relPnlChartWithNet(u.netPnl.toOwnMcap, u.profit.toOwnMcap, u.loss.toOwnMcap, "% of Own Market Cap", title),
];
}
/** @param {FullRelativePattern} u @param {(name: string) => string} title */
function unrealizedTreeLongTerm(u, title) {
return [
...unrealizedCore(u, title),
...unrealizedCoreWithGross(u, title),
ownPnlChart(u, title),
{
name: "% of Market Cap",
@@ -208,12 +240,7 @@ function unrealizedTreeLongTerm(u, title) {
color: colors.loss,
}),
},
relPnlChart(
u.profit.toOwnMcap,
u.loss.toOwnMcap,
"% of Own Market Cap",
title,
),
relPnlChartWithNet(u.netPnl.toOwnMcap, u.profit.toOwnMcap, u.loss.toOwnMcap, "% of Own Market Cap", title),
];
}
@@ -300,7 +327,7 @@ function realizedMetricFolder({ pattern, metricTitle, color, title }) {
})),
{
name: "Cumulative",
title: title(`Realized ${metricTitle} (Total)`),
title: title(`Cumulative Realized ${metricTitle}`),
bottom: [
line({
series: pattern.cumulative.usd,
@@ -350,7 +377,7 @@ function realizedNetFolder({ netPnl, title, extraChange = [] }) {
})),
{
name: "Cumulative",
title: title("Net Realized P&L (Total)"),
title: title("Cumulative Net Realized P&L"),
bottom: [
baseline({
series: netPnl.cumulative.usd,
@@ -372,7 +399,7 @@ function realizedNetFolder({ netPnl, title, extraChange = [] }) {
tree: [
...rollingPercentRatioTree({
windows: netPnl.delta.rate,
title: title("Net Realized P&L Rate"),
title: title("Net Realized P&L Growth Rate"),
}).tree,
...extraChange,
],
@@ -587,7 +614,7 @@ function realizedSubfolderFull(r, title) {
})),
{
name: "Cumulative",
title: title("Peak Regret (Total)"),
title: title("Cumulative Peak Regret"),
bottom: [
line({
series: r.peakRegret.cumulative.usd,
@@ -706,6 +733,16 @@ export function createProfitabilitySectionWithProfitLoss({ cohort, title }) {
{
name: "Unrealized",
tree: [
{
name: "Overview",
title: title("Unrealized P&L"),
bottom: [
line({ series: u.profit.usd, name: "Profit", color: colors.profit, unit: Unit.usd }),
line({ series: u.loss.negative, name: "Neg. Loss", color: colors.loss, unit: Unit.usd }),
line({ series: u.loss.usd, name: "Loss", color: colors.loss, unit: Unit.usd, defaultActive: false }),
priceLine({ unit: Unit.usd }),
],
},
{ name: "NUPL", title: title("NUPL"), bottom: nuplSeries(u.nupl) },
{
name: "Profit",
@@ -840,32 +877,49 @@ export function createProfitabilitySectionWithInvestedCapitalPct({
* @param {(name: string) => string} title
* @returns {PartialOptionsGroup}
*/
/**
* Grouped realized profit + loss items
* @param {readonly UtxoCohortObject[]} list
* @param {CohortAll} all
* @param {(name: string) => string} title
* @returns {PartialOptionsTree}
*/
function groupedRealizedProfitLossItems(list, all, title) {
return [
{ name: "Profit", tree: groupedWindowsCumulativeUsd({ list, all, title, metricTitle: "Realized Profit", getMetric: (c) => c.tree.realized.profit }) },
{ name: "Loss", tree: groupedWindowsCumulativeUsd({ list, all, title, metricTitle: "Realized Loss", getMetric: (c) => c.tree.realized.loss }) },
];
}
/**
* Grouped realized net item
* @param {readonly (CohortAgeRange | CohortWithAdjusted | CohortAll | CohortFull | CohortLongTerm)[]} list
* @param {CohortAll} all
* @param {(name: string) => string} title
* @returns {PartialOptionsGroup}
*/
function groupedRealizedNetItem(list, all, title) {
return { name: "Net", tree: groupedWindowsCumulativeUsd({ list, all, title, metricTitle: "Net Realized P&L", getMetric: (c) => c.tree.realized.netPnl, seriesFn: baseline }) };
}
/**
* @param {readonly UtxoCohortObject[]} list
* @param {CohortAll} all
* @param {(name: string) => string} title
* @returns {PartialOptionsGroup}
*/
function groupedRealizedSubfolder(list, all, title) {
return {
name: "Realized",
tree: [
{
name: "Profit",
tree: groupedWindowsCumulativeUsd({
list,
all,
title,
metricTitle: "Realized Profit",
getMetric: (c) => c.tree.realized.profit,
}),
},
{
name: "Loss",
tree: groupedWindowsCumulativeUsd({
list,
all,
title,
metricTitle: "Realized Loss",
getMetric: (c) => c.tree.realized.loss,
}),
},
],
};
return { name: "Realized", tree: groupedRealizedProfitLossItems(list, all, title) };
}
/**
* @param {readonly (CohortAgeRange | CohortWithAdjusted)[]} list
* @param {CohortAll} all
* @param {(name: string) => string} title
* @returns {PartialOptionsGroup}
*/
function groupedRealizedSubfolderMid(list, all, title) {
return { name: "Realized", tree: [groupedRealizedNetItem(list, all, title), ...groupedRealizedProfitLossItems(list, all, title)] };
}
/**
@@ -896,7 +950,7 @@ function groupedRealizedNetPnlDeltaItems(list, all, title) {
name: "Growth Rate",
tree: ROLLING_WINDOWS.map((w) => ({
name: w.name,
title: title(`Net Realized P&L Rate (${w.title})`),
title: title(`Net Realized P&L Growth Rate (${w.title})`),
bottom: flatMapCohortsWithAll(list, all, ({ name, color, tree }) =>
percentRatioBaseline({
pattern: tree.realized.netPnl.delta.rate[w.key],
@@ -934,26 +988,7 @@ function groupedRealizedSubfolderFull(list, all, title) {
...groupedRealizedNetPnlDeltaItems(list, all, title),
],
},
{
name: "Profit",
tree: groupedWindowsCumulativeUsd({
list,
all,
title,
metricTitle: "Realized Profit",
getMetric: (c) => c.tree.realized.profit,
}),
},
{
name: "Loss",
tree: groupedWindowsCumulativeUsd({
list,
all,
title,
metricTitle: "Realized Loss",
getMetric: (c) => c.tree.realized.loss,
}),
},
...groupedRealizedProfitLossItems(list, all, title),
{
name: "Gross",
tree: groupedWindowsCumulativeUsd({
@@ -1234,7 +1269,7 @@ export function createGroupedProfitabilitySectionWithInvestedCapitalPct({
name: "Profitability",
tree: [
{ name: "Unrealized", tree: groupedUnrealizedMid(list, all, title) },
groupedRealizedSubfolder(list, all, title),
groupedRealizedSubfolderMid(list, all, title),
],
};
}
@@ -20,7 +20,7 @@ import { ratioBottomSeries, mapCohortsWithAll, flatMapCohortsWithAll } from "../
function singleDeltaItems(tree, title) {
return [
{ ...sumsTreeBaseline({ windows: mapWindows(tree.realized.cap.delta.absolute, (c) => c.usd), title: title("Realized Cap Change"), unit: Unit.usd }), name: "Change" },
{ ...rollingPercentRatioTree({ windows: tree.realized.cap.delta.rate, title: title("Realized Cap Rate") }), name: "Growth Rate" },
{ ...rollingPercentRatioTree({ windows: tree.realized.cap.delta.rate, title: title("Realized Cap Growth Rate") }), name: "Growth Rate" },
];
}
@@ -54,7 +54,7 @@ function groupedDeltaAndMvrv(list, all, title) {
name: "Growth Rate",
tree: ROLLING_WINDOWS.map((w) => ({
name: w.name,
title: title(`Realized Cap Rate (${w.title})`),
title: title(`Realized Cap Growth Rate (${w.title})`),
bottom: flatMapCohortsWithAll(list, all, ({ name, color, tree }) =>
percentRatioBaseline({ pattern: tree.realized.cap.delta.rate[w.key], name, color }),
),
+2 -2
View File
@@ -5,13 +5,13 @@ import { entries, includes } from "../utils/array.js";
import { colors } from "../utils/colors.js";
import {
line,
baseline,
dots,
dotted,
distributionBtcSatsUsd,
statsAtWindow,
ROLLING_WINDOWS,
percentRatio,
percentRatioBaseline,
chartsFromCount,
} from "./series.js";
import {
@@ -438,7 +438,7 @@ export function createMiningSection() {
{
name: "Adjustment",
title: "Difficulty Adjustment",
bottom: [baseline({ series: blocks.difficulty.adjustment.percent, name: "Change", unit: Unit.percentage })],
bottom: percentRatioBaseline({ pattern: blocks.difficulty.adjustment, name: "Change" }),
},
{
name: "Countdown",
+13 -22
View File
@@ -15,40 +15,31 @@ function walkSeries(node, map, path) {
for (const [key, value] of Object.entries(node)) {
const kn = key.toLowerCase();
if (
key === "lookback" ||
key === "cumulativeMarketCap" ||
key === "sd24h" ||
key === "spot" ||
key === "ohlc" ||
key === "state" ||
key === "emaSlow" ||
key === "emaFast" ||
key.endsWith("Raw") ||
key.endsWith("Cents") ||
key.endsWith("State") ||
key.endsWith("Start") ||
kn === "cents" ||
kn === "bps" ||
kn === "mvrv" ||
kn === "constants" ||
kn === "blockhash" ||
kn === "date" ||
kn === "ohlc" ||
kn === "split" ||
kn === "outpoint" ||
kn === "positions" ||
kn === "heighttopool" ||
kn === "txid" ||
kn === "spot" ||
kn.startsWith("timestamp") ||
kn.startsWith("satdays") ||
kn.startsWith("satblocks") ||
kn.startsWith("coinyears") ||
kn.endsWith("index") ||
kn.endsWith("indexes")
)
continue;
walkSeries(/** @type {TreeNode | null | undefined} */ (value), map, [
...path,
key,
]);
const newPath = [...path, key];
const joined = newPath.join(".");
if (
joined.endsWith(".count.total.average") ||
joined.endsWith(".versions.v1.average") ||
joined.endsWith(".versions.v2.average") ||
joined.endsWith(".versions.v3.average")
)
continue;
walkSeries(/** @type {TreeNode | null | undefined} */ (value), map, newPath);
}
}
}