// @ts-check /** * @import { CohortOption, CohortOptions, Color, DefaultCohortOption, DefaultCohortOptions, OptionsGroup, PartialChartOption, PartialOptionsGroup, PartialOptionsTree, RatioOption, RatioOptions, Unit } from "./types/self" * @import {AnySpecificSeriesBlueprint, SplitSeriesBlueprint} from '../packages/lightweight-charts/types'; */ function initGroups() { const xTermHolders = /** @type {const} */ ([ { id: "sth", key: "sth", name: "Short Term Holders", legend: "Short Term Holders - STH", }, { id: "lth", key: "lth", name: "Long Term Holders", legend: "Long Term Holders - LTH", }, ]); const upTo = /** @type {const} */ ([ { id: "up-to-1d", key: "up_to_1d", name: "Up To 1 Day", legend: "1D", }, { id: "up-to-1w", key: "up_to_1w", name: "Up To 1 Week", legend: "1W", }, { id: "up-to-1m", key: "up_to_1m", name: "Up To 1 Month", legend: "1M", }, { id: "up-to-2m", key: "up_to_2m", name: "Up To 2 Months", legend: "2M", }, { id: "up-to-3m", key: "up_to_3m", name: "Up To 3 Months", legend: "3M", }, { id: "up-to-4m", key: "up_to_4m", name: "Up To 4 Months", legend: "4M", }, { id: "up-to-5m", key: "up_to_5m", name: "Up To 5 Months", legend: "5M", }, { id: "up-to-6m", key: "up_to_6m", name: "Up To 6 Months", legend: "6M", }, { id: "up-to-1y", key: "up_to_1y", name: "Up To 1 Year", legend: "1Y", }, { id: "up-to-2y", key: "up_to_2y", name: "Up To 2 Years", legend: "2Y", }, { id: "up-to-3y", key: "up_to_3y", name: "Up To 3 Years", legend: "3Y", }, { id: "up-to-5y", key: "up_to_5y", name: "Up To 5 Years", legend: "5Y", }, { id: "up-to-7y", key: "up_to_7y", name: "Up To 7 Years", legend: "7Y", }, { id: "up-to-10y", key: "up_to_10y", name: "Up To 10 Years", legend: "10Y", }, { id: "up-to-15y", key: "up_to_15y", name: "Up To 15 Years", legend: "15Y", }, ]); const fromXToY = /** @type {const} */ ([ { id: "up-to-1d", key: "up_to_1d", name: "24h", legend: "24h", }, { id: "from-1d-to-1w", key: "from_1d_to_1w", name: "From 1 Day To 1 Week", legend: "1D — 1W", }, { id: "from-1w-to-1m", key: "from_1w_to_1m", name: "From 1 Week To 1 Month", legend: "1W — 1M", }, { id: "from-1m-to-3m", key: "from_1m_to_3m", name: "From 1 Month To 3 Months", legend: "1M — 3M", }, { id: "from-3m-to-6m", key: "from_3m_to_6m", name: "From 3 Months To 6 Months", legend: "3M — 6M", }, { id: "from-6m-to-1y", key: "from_6m_to_1y", name: "From 6 Months To 1 Year", legend: "6M — 1Y", }, { id: "from-1y-to-2y", key: "from_1y_to_2y", name: "From 1 Year To 2 Years", legend: "1Y — 2Y", }, { id: "from-2y-to-3y", key: "from_2y_to_3y", name: "From 2 Years To 3 Years", legend: "2Y — 3Y", }, { id: "from-3y-to-5y", key: "from_3y_to_5y", name: "From 3 Years To 5 Years", legend: "3Y — 5Y", }, { id: "from-5y-to-7y", key: "from_5y_to_7y", name: "From 5 Years To 7 Years", legend: "5Y — 7Y", }, { id: "from-7y-to-10y", key: "from_7y_to_10y", name: "From 7 Years To 10 Years", legend: "7Y — 10Y", }, { id: "from-10y-to-15y", key: "from_10y_to_15y", name: "From 10 Years To 15 Years", legend: "10Y — 15Y", }, { id: "from-15y", key: "from_15y", name: "From 15 Years To End", legend: "15Y — End", }, ]); const fromX = /** @type {const} */ ([ { id: "from-1y", key: "from_1y", name: "From 1 Year", legend: "1Y+", }, { id: "from-2y", key: "from_2y", name: "From 2 Years", legend: "2Y+", }, { id: "from-4y", key: "from_4y", name: "From 4 Years", legend: "4Y+", }, { id: "from-10y", key: "from_10y", name: "From 10 Years", legend: "10Y+", }, { id: "from-15y", key: "from_15y", name: "From 15 Years", legend: "15Y+", }, ]); const epochs = /** @type {const} */ ([ { id: "epoch-1", key: "epoch_1", name: "Epoch 1" }, { id: "epoch-2", key: "epoch_2", name: "Epoch 2" }, { id: "epoch-3", key: "epoch_3", name: "Epoch 3" }, { id: "epoch-4", key: "epoch_4", name: "Epoch 4" }, { id: "epoch-5", key: "epoch_5", name: "Epoch 5" }, ]); const age = /** @type {const} */ ([ { key: "", id: "", name: "", }, ...xTermHolders, ...upTo, ...fromXToY, ...fromX, ...epochs, ]); const size = /** @type {const} */ ([ { key: "plankton", name: "Plankton", size: "1 sat to 0.1 BTC", }, { key: "shrimp", name: "Shrimp", size: "0.1 sat to 1 BTC", }, { key: "crab", name: "Crab", size: "1 BTC to 10 BTC" }, { key: "fish", name: "Fish", size: "10 BTC to 100 BTC" }, { key: "shark", name: "Shark", size: "100 BTC to 1000 BTC" }, { key: "whale", name: "Whale", size: "1000 BTC to 10 000 BTC" }, { key: "humpback", name: "Humpback", size: "10 000 BTC to 100 000 BTC", }, { key: "megalodon", name: "Megalodon", size: "More than 100 000 BTC", }, ]); const type = /** @type {const} */ ([ { key: "p2pk", name: "P2PK" }, { key: "p2pkh", name: "P2PKH" }, { key: "p2sh", name: "P2SH" }, { key: "p2wpkh", name: "P2WPKH" }, { key: "p2wsh", name: "P2WSH" }, { key: "p2tr", name: "P2TR" }, ]); const address = /** @type {const} */ ([...size, ...type]); const liquidities = /** @type {const} */ ([ { key: "illiquid", id: "illiquid", name: "Illiquid", }, { key: "liquid", id: "liquid", name: "Liquid" }, { key: "highly_liquid", id: "highly-liquid", name: "Highly Liquid", }, ]); const averages = /** @type {const} */ ([ { name: "1 Week", key: "1w", days: 7 }, { name: "8 Days", key: "8d", days: 8 }, { name: "13 Days", key: "13d", days: 13 }, { name: "21 Days", key: "21d", days: 21 }, { name: "1 Month", key: "1m", days: 30 }, { name: "34 Days", key: "34d", days: 34 }, { name: "55 Days", key: "55d", days: 55 }, { name: "89 Days", key: "89d", days: 89 }, { name: "144 Days", key: "144d", days: 144 }, { name: "1 Year", key: "1y", days: 365 }, { name: "2 Years", key: "2y", days: 2 * 365 }, { name: "200 Weeks", key: "200w", days: 200 * 7 }, { name: "4 Years", key: "4y", days: 4 * 365 }, ]); const totalReturns = /** @type {const} */ ([ { name: "1 Day", key: "1d" }, { name: "1 Month", key: "1m" }, { name: "6 Months", key: "6m" }, { name: "1 Year", key: "1y" }, { name: "2 Years", key: "2y" }, { name: "3 Years", key: "3y" }, { name: "4 Years", key: "4y" }, { name: "6 Years", key: "6y" }, { name: "8 Years", key: "8y" }, { name: "10 Years", key: "10y" }, ]); const compoundReturns = /** @type {const} */ ([ { name: "4 Years", key: "4y" }, ]); const percentiles = /** @type {const} */ ([ { key: "median_price_paid", id: "median-price-paid", name: "Median", title: "Median Paid", value: 50, }, { key: "95p_price_paid", id: "95p-price-paid", name: `95%`, title: `95th Percentile Paid`, value: 95, }, { key: "90p_price_paid", id: "90p-price-paid", name: `90%`, title: `90th Percentile Paid`, value: 90, }, { key: "85p_price_paid", id: "85p-price-paid", name: `85%`, title: `85th Percentile Paid`, value: 85, }, { key: "80p_price_paid", id: "80p-price-paid", name: `80%`, title: `80th Percentile Paid`, value: 80, }, { key: "75p_price_paid", id: "75p-price-paid", name: `75%`, title: `75th Percentile Paid`, value: 75, }, { key: "70p_price_paid", id: "70p-price-paid", name: `70%`, title: `70th Percentile Paid`, value: 70, }, { key: "65p_price_paid", id: "65p-price-paid", name: `65%`, title: `65th Percentile Paid`, value: 65, }, { key: "60p_price_paid", id: "60p-price-paid", name: `60%`, title: `60th Percentile Paid`, value: 60, }, { key: "55p_price_paid", id: "55p-price-paid", name: `55%`, title: `55th Percentile Paid`, value: 55, }, { key: "45p_price_paid", id: "45p-price-paid", name: `45%`, title: `45th Percentile Paid`, value: 45, }, { key: "40p_price_paid", id: "40p-price-paid", name: `40%`, title: `40th Percentile Paid`, value: 40, }, { key: "35p_price_paid", id: "35p-price-paid", name: `35%`, title: `35th Percentile Paid`, value: 35, }, { key: "30p_price_paid", id: "30p-price-paid", name: `30%`, title: `30th Percentile Paid`, value: 30, }, { key: "25p_price_paid", id: "25p-price-paid", name: `25%`, title: `25th Percentile Paid`, value: 25, }, { key: "20p_price_paid", id: "20p-price-paid", name: `20%`, title: `20th Percentile Paid`, value: 20, }, { key: "15p_price_paid", id: "15p-price-paid", name: `15%`, title: `15th Percentile Paid`, value: 15, }, { key: "10p_price_paid", id: "10p-price-paid", name: `10%`, title: `10th Percentile Paid`, value: 10, }, { key: "05p_price_paid", id: "05p-price-paid", name: `5%`, title: `5th Percentile Paid`, value: 5, }, ]); return { xTermHolders, upTo, fromX, fromXToY, epochs, age, type, size, address, liquidities, averages, totalReturns, compoundReturns, percentiles, }; } /** * @typedef {ReturnType} Groups * * @typedef {Groups["age"][number]["id"]} AgeCohortId * * @typedef {Exclude} AgeCohortIdSub * * @typedef {Groups["address"][number]["key"]} AddressCohortId * * @typedef {Groups["liquidities"][number]["id"]} LiquidityId * * @typedef {AgeCohortId | AddressCohortId} AnyCohortId * * @typedef {AddressCohortId | LiquidityId} AnyAddressCohortId * * @typedef {AnyCohortId | LiquidityId} AnyPossibleCohortId * * @typedef {'' | `${AgeCohortIdSub | AddressCohortId | LiquidityId}-`} AnyDatasetPrefix * * @typedef {Groups["averages"][number]["key"]} AverageName * * @typedef {Groups["totalReturns"][number]["key"]} TotalReturnKey * * @typedef {Groups["compoundReturns"][number]["key"]} CompoundReturnKey * * @typedef {Groups["percentiles"][number]["id"]} PercentileId */ /** * @param {Colors} colors * @returns {PartialOptionsTree} */ function createPartialOptions(colors) { // const groups = initGroups(); // const bases = { // /** // * @param {TimeScale} scale // * @param {string} [title] // */ // 0(scale, title) { // return /** @type {const} */ ({ // title: title || `Base`, // color: colors.off, // datasetPath: `${scale}-to-0`, // options: { // lineStyle: 3, // lastValueVisible: false, // }, // }); // }, // /** // * @param {TimeScale} scale // * @param {string} [title] // */ // 1(scale, title) { // return /** @type {const} */ ({ // title: title || `Base`, // color: colors.off, // datasetPath: `${scale}-to-1`, // options: { // lineStyle: 3, // lastValueVisible: false, // }, // }); // }, // /** // * @param {TimeScale} scale // * @param {string} [title] // */ // 100(scale, title) { // return /** @type {const} */ ({ // title: title || `Base`, // color: colors.off, // datasetPath: `${scale}-to-100`, // options: { // lineStyle: 3, // lastValueVisible: false, // }, // }); // }, // }; // /** // * @param {AnyPossibleCohortId} datasetId // * @returns {AnyDatasetPrefix} // */ // function datasetIdToPrefix(datasetId) { // return datasetId // ? /** @type {const} */ (`${datasetId}-`) // : /** @type {const} */ (""); // } // /** // * // * @param {Object} args // * @param {TimeScale} args.scale // * @param {string} args.title // * @param {Color} args.color // * @param {Unit} args.unit // * @param {AnyDatasetPath} [args.keySum] // * @param {AnyDatasetPath} [args.keyAverage] // * @param {AnyDatasetPath} [args.keyMax] // * @param {AnyDatasetPath} [args.key90p] // * @param {AnyDatasetPath} [args.key75p] // * @param {AnyDatasetPath} [args.keyMedian] // * @param {AnyDatasetPath} [args.key25p] // * @param {AnyDatasetPath} [args.key10p] // * @param {AnyDatasetPath} [args.keyMin] // * @returns {PartialOptionsTree} // */ // function createRecapOptions({ // scale, // unit, // title, // keyAverage, // color, // keySum, // keyMax, // key90p, // key75p, // keyMedian, // key25p, // key10p, // keyMin, // }) { // return [ // ...(keySum // ? [ // { // scale, // name: "Daily Sum", // title: `${title} Daily Sum`, // description: "", // unit, // bottom: [ // { // title: "Sum", // color, // datasetPath: keySum, // }, // ], // }, // ] // : []), // ...(keyAverage // ? [ // { // scale, // name: "Daily Average", // title: `${title} Daily Average`, // description: "", // unit, // bottom: [ // { // title: "Average", // color, // datasetPath: keyAverage, // }, // ], // }, // ] // : []), // ...(keyMax || key90p || key75p || keyMedian || key25p || key10p || keyMin // ? [ // { // scale, // name: "Daily Percentiles", // title: `${title} Daily Percentiles`, // description: "", // unit, // bottom: [ // ...(keyMax // ? [ // { // title: "Max", // color, // datasetPath: keyMax, // }, // ] // : []), // ...(key90p // ? [ // { // title: "90%", // color, // datasetPath: key90p, // }, // ] // : []), // ...(key75p // ? [ // { // title: "75%", // color, // datasetPath: key75p, // }, // ] // : []), // ...(keyMedian // ? [ // { // title: "Median", // color, // datasetPath: keyMedian, // }, // ] // : []), // ...(key25p // ? [ // { // title: "25%", // color, // datasetPath: key25p, // }, // ] // : []), // ...(key10p // ? [ // { // title: "10%", // color, // datasetPath: key10p, // }, // ] // : []), // ...(keyMin // ? [ // { // title: "Min", // color, // datasetPath: keyMin, // }, // ] // : []), // ], // }, // ] // : []), // ...(keyMax // ? [ // { // scale, // name: "Daily Max", // title: `${title} Daily Max`, // description: "", // unit, // bottom: [ // { // title: "Max", // color, // datasetPath: keyMax, // }, // ], // }, // ] // : []), // ...(key90p // ? [ // { // scale, // name: "Daily 90th Percentile", // title: `${title} Daily 90th Percentile`, // description: "", // unit, // bottom: [ // { // title: "90%", // color, // datasetPath: key90p, // }, // ], // }, // ] // : []), // ...(key75p // ? [ // { // scale, // name: "Daily 75th Percentile", // title: `${title} Size 75th Percentile`, // description: "", // unit, // bottom: [ // { // title: "75%", // color, // datasetPath: key75p, // }, // ], // }, // ] // : []), // ...(keyMedian // ? [ // { // scale, // name: "Daily Median", // title: `${title} Daily Median`, // description: "", // unit, // bottom: [ // { // title: "Median", // color, // datasetPath: keyMedian, // }, // ], // }, // ] // : []), // ...(key25p // ? [ // { // scale, // name: "Daily 25th Percentile", // title: `${title} Daily 25th Percentile`, // description: "", // unit, // bottom: [ // { // title: "25%", // color, // datasetPath: key25p, // }, // ], // }, // ] // : []), // ...(key10p // ? [ // { // scale, // name: "Daily 10th Percentile", // title: `${title} Daily 10th Percentile`, // description: "", // unit, // bottom: [ // { // title: "10%", // color, // datasetPath: key10p, // }, // ], // }, // ] // : []), // ...(keyMin // ? [ // { // scale, // name: "Daily Min", // title: `${title} Daily Min`, // description: "", // unit, // bottom: [ // { // title: "Min", // color, // datasetPath: keyMin, // }, // ], // }, // ] // : []), // ]; // } // /** // * @param {RatioOption | RatioOptions} arg // * @returns {PartialOptionsGroup} // */ // function createRatioOptions(arg) { // const { scale, title } = arg; // const isSingle = !("list" in arg); // /** // * @param {RatioOption | RatioOptions} arg // */ // function toList(arg) { // return "list" in arg ? arg.list : [arg]; // } // /** // * @param {RatioOption | RatioOptions} arg // * @param {string} cohortName // * @param {string} legendName // */ // function toLegendName(arg, cohortName, legendName) { // return "list" in arg ? `${cohortName} ${legendName}` : legendName; // } // return { // name: "Ratio", // tree: [ // { // scale, // name: "Basic", // title: `Market Price To ${title} Ratio`, // unit: "Ratio", // description: "", // top: toList(arg).map( // ({ title, color, valueDatasetPath: datasetPath }) => ({ // title, // color, // datasetPath, // }), // ), // bottom: [ // ...toList(arg).map( // ({ title, color, ratioDatasetPath: datasetPath }) => ({ // title: toLegendName(arg, title, "Ratio"), // color: isSingle ? undefined : color, // type: /** @type {const} */ ("Baseline"), // datasetPath, // options: { // baseValue: { // price: 1, // }, // }, // }), // ), // bases[1](scale), // ], // }, // ...(isSingle // ? /** @satisfies {PartialChartOption[]} */ ([ // { // scale, // name: "Averages", // description: "", // unit: "Ratio", // title: `Market Price To ${title} Ratio Averages`, // top: [ // { // title, // color: arg.color, // datasetPath: arg.valueDatasetPath, // }, // ], // bottom: [ // { // title: `1Y SMA`, // color: colors.red, // datasetPath: /** @type {any} */ ( // `${arg.ratioDatasetPath}-1y-sma` // ), // }, // { // title: `1M SMA`, // color: colors.orange, // datasetPath: `${arg.ratioDatasetPath}-1m-sma`, // }, // { // title: `1W SMA`, // color: colors.yellow, // datasetPath: `${arg.ratioDatasetPath}-1w-sma`, // }, // { // title: `Raw`, // color: colors.default, // datasetPath: arg.ratioDatasetPath, // }, // { // title: `Even`, // color: colors.off, // datasetPath: `${scale}-to-1`, // options: { // lineStyle: 3, // lastValueVisible: false, // }, // }, // ], // }, // ]) // : []), // { // scale, // name: "Momentum Oscillator", // title: `Market Price To ${title} Ratio 1Y SMA Momentum Oscillator`, // description: "", // unit: "Ratio", // top: toList(arg).map( // ({ title, color, valueDatasetPath: datasetPath }) => ({ // title: toLegendName(arg, title, ""), // color, // datasetPath, // }), // ), // bottom: [ // ...toList(arg).map( // ({ title, color, ratioDatasetPath: datasetPath }) => ({ // title: toLegendName(arg, title, "Momentum"), // color: isSingle ? undefined : color, // type: /** @type {const} */ ("Baseline"), // datasetPath: /** @type {any} */ ( // `${datasetPath}-1y-sma-momentum-oscillator` // ), // }), // ), // bases[0](scale), // ], // }, // { // name: "Top", // tree: [ // ...(isSingle // ? /** @satisfies {PartialChartOption[]} */ ([ // { // scale, // name: "Percentiles", // title: `Market Price To ${title} Ratio Top Percentiles`, // description: "", // unit: "Ratio", // top: [ // { // title, // color: arg.color, // datasetPath: arg.valueDatasetPath, // }, // ], // bottom: [ // { // title: `99.9%`, // color: colors.probability0_1p, // datasetPath: /** @type {any} */ ( // `${arg.ratioDatasetPath}-99-9p` // ), // }, // { // title: `99.5%`, // color: colors.probability0_5p, // datasetPath: `${arg.ratioDatasetPath}-99-5p`, // }, // { // title: `99%`, // color: colors.probability1p, // datasetPath: `${arg.ratioDatasetPath}-99p`, // }, // { // title: `Raw`, // color: colors.default, // datasetPath: arg.ratioDatasetPath, // }, // ], // }, // ]) // : []), // { // name: "Prices", // tree: [ // ...(isSingle // ? /** @satisfies {PartialChartOption[]} */ ([ // { // scale, // name: "All", // title: `${title} Top Prices`, // description: "", // unit: "US Dollars", // top: [ // { // title: `99.9%`, // color: colors.probability0_1p, // datasetPath: /** @type {any} */ ( // `${arg.valueDatasetPath}-99-9p` // ), // }, // { // title: `99.5%`, // color: colors.probability0_5p, // datasetPath: `${arg.valueDatasetPath}-99-5p`, // }, // { // title: `99%`, // color: colors.probability1p, // datasetPath: `${arg.valueDatasetPath}-99p`, // }, // ], // }, // ]) // : []), // { // scale, // name: "99%", // title: `${title} Top 99% Price`, // description: "", // unit: "US Dollars", // top: toList(arg).map((cohort) => ({ // title: toLegendName(arg, cohort.title, `99%`), // color: isSingle ? colors.probability1p : cohort.color, // datasetPath: /** @type {any} */ ( // `${cohort.valueDatasetPath}-99p` // ), // })), // }, // { // scale, // name: "99.5%", // title: `${title} Top 99.5% Price`, // description: "", // unit: "US Dollars", // top: toList(arg).map((cohort) => ({ // title: toLegendName(arg, cohort.title, `99.5%`), // color: isSingle ? colors.probability0_5p : cohort.color, // datasetPath: /** @type {any} */ ( // `${cohort.valueDatasetPath}-99-5p` // ), // })), // }, // { // scale, // name: "99.9%", // title: `${title} Top 99.9% Price`, // description: "", // unit: "US Dollars", // top: toList(arg).map((cohort) => ({ // title: toLegendName(arg, cohort.title, `99.9%`), // color: isSingle ? colors.probability0_1p : cohort.color, // datasetPath: /** @type {any} */ ( // `${cohort.valueDatasetPath}-99-9p` // ), // })), // }, // ], // }, // ], // }, // { // name: "Bottom", // tree: [ // ...(isSingle // ? /** @satisfies {PartialChartOption[]} */ ([ // { // scale, // name: "Percentiles", // title: `Market Price To ${title} Ratio Bottom Percentiles`, // description: "", // unit: "Ratio", // top: [ // { // title, // color: arg.color, // datasetPath: arg.valueDatasetPath, // }, // ], // bottom: [ // { // title: `0.1%`, // color: colors.probability0_1p, // datasetPath: `${arg.ratioDatasetPath}-0-1p`, // }, // { // title: `0.5%`, // color: colors.probability0_5p, // datasetPath: `${arg.ratioDatasetPath}-0-5p`, // }, // { // title: `1%`, // color: colors.probability1p, // datasetPath: /** @type {any} */ ( // `${arg.ratioDatasetPath}-1p` // ), // }, // { // title: `Raw`, // color: colors.default, // datasetPath: arg.ratioDatasetPath, // }, // ], // }, // ]) // : []), // { // name: "Prices", // tree: [ // ...(isSingle // ? /** @satisfies {PartialChartOption[]} */ ([ // { // scale, // name: "All", // title: `${title} Bottom Prices`, // description: "", // unit: "US Dollars", // top: [ // { // title: `0.1%`, // color: colors.probability0_1p, // datasetPath: /** @type {any} */ ( // `${arg.valueDatasetPath}-0-1p` // ), // }, // { // title: `0.5%`, // color: colors.probability0_5p, // datasetPath: `${arg.valueDatasetPath}-0-5p`, // }, // { // title: `1%`, // color: colors.probability1p, // datasetPath: `${arg.valueDatasetPath}-1p`, // }, // ], // }, // ]) // : []), // { // scale, // name: "1%", // title: `${title} Bottom 1% Price`, // description: "", // unit: "US Dollars", // top: toList(arg).map((cohort) => ({ // title: toLegendName(arg, cohort.title, `1%`), // color: isSingle ? colors.probability1p : cohort.color, // datasetPath: /** @type {any} */ ( // `${cohort.valueDatasetPath}-1p` // ), // })), // }, // { // scale, // name: "0.5%", // title: `${title} Bottom 0.5% Price`, // description: "", // unit: "US Dollars", // top: toList(arg).map((cohort) => ({ // title: toLegendName(arg, cohort.title, `0.5%`), // color: isSingle ? colors.probability0_5p : cohort.color, // datasetPath: /** @type {any} */ ( // `${cohort.valueDatasetPath}-0-5p` // ), // })), // }, // { // scale, // name: "0.1%", // title: `${title} Bottom 0.1% Price`, // description: "", // unit: "US Dollars", // top: toList(arg).map((cohort) => ({ // title: toLegendName(arg, cohort.title, `0.1%`), // color: isSingle ? colors.probability0_1p : cohort.color, // datasetPath: /** @type {any} */ ( // `${cohort.valueDatasetPath}-0-1p` // ), // })), // }, // ], // }, // ], // }, // ], // }; // } // /** // * @param {TimeScale} scale // * @returns {PartialOptionsGroup} // */ // function createMarketOptions(scale) { // // /** // // * @param {TimeScale} scale // // * @returns {PartialOptionsGroup} // // */ // // function createAllTimeHighOptions(scale) { // // return { // // name: "All Time High", // // tree: [ // // { // // scale, // // name: "Value", // // title: "All Time High", // // description: "", // // unit: "US Dollars", // // top: [ // // { // // title: `ATH`, // // color: colors.dollars, // // datasetPath: `${scale}-to-all-time-high`, // // }, // // ], // // }, // // { // // scale, // // name: "Drawdown", // // title: "All Time High Drawdown", // // description: "", // // unit: "Percentage", // // top: [ // // { // // title: `ATH`, // // color: colors.dollars, // // datasetPath: `${scale}-to-all-time-high`, // // }, // // ], // // bottom: [ // // { // // title: `Drawdown`, // // color: colors.loss, // // datasetPath: `${scale}-to-drawdown`, // // }, // // ], // // }, // // ...(scale === "date" // // ? /** @type {PartialChartOption[]} */ ([ // // { // // scale, // // name: "Days Since", // // title: "Days Since All Time High", // // description: "", // // unit: "Count", // // bottom: [ // // { // // title: `Days`, // // color: colors.red, // // datasetPath: `date-to-days-since-all-time-high`, // // }, // // ], // // }, // // { // // name: "Max Between", // // tree: [ // // { // // scale, // // name: "Days", // // title: "Max Number Of Days Between All Time Highs", // // description: "", // // unit: "Count", // // bottom: [ // // { // // title: `Max`, // // color: colors.red, // // datasetPath: // // "date-to-max-days-between-all-time-highs", // // }, // // ], // // }, // // { // // scale, // // name: "Years", // // title: "Max Number Of Years Between All Time Highs", // // description: "", // // bottom: [ // // { // // title: `Max`, // // color: colors.red, // // datasetPath: // // "date-to-max-years-between-all-time-highs", // // }, // // ], // // }, // // ], // // }, // // ]) // // : []), // // ], // // }; // // } // // /** // // * @param {TimeScale} scale // // * @returns {PartialOptionsGroup} // // */ // // function createAveragesOptions(scale) { // // return { // // name: "Averages", // // tree: [ // // { // // scale, // // name: "All", // // title: "All Moving Averages", // // description: "", // // unit: "US Dollars", // // top: groups.averages.map((average) => ({ // // title: average.key.toUpperCase(), // // color: colors[`_${average.key}`], // // datasetPath: `${scale}-to-price-${average.key}-sma`, // // })), // // }, // // ...groups.averages.map(({ name, key }) => // // createAverageOptions({ // // scale, // // color: colors[`_${key}`], // // name, // // title: `${name} Market Price Moving Average`, // // key, // // }), // // ), // // ], // // }; // // } // // /** // // * // // * @param {Object} args // // * @param {TimeScale} args.scale // // * @param {Color} args.color // // * @param {string} args.name // // * @param {string} args.title // // * @param {AverageName} args.key // // * @returns {PartialOptionsGroup} // // */ // // function createAverageOptions({ scale, color, name, title, key }) { // // return { // // name, // // tree: [ // // { // // scale, // // name: "Average", // // title, // // description: "", // // unit: "US Dollars", // // top: [ // // { // // title: `SMA`, // // color, // // datasetPath: `${scale}-to-price-${key}-sma`, // // }, // // ], // // }, // // createRatioOptions({ // // scale, // // color, // // ratioDatasetPath: `${scale}-to-market-price-to-price-${key}-sma-ratio`, // // valueDatasetPath: `${scale}-to-price-${key}-sma`, // // title, // // }), // // ], // // }; // // } // // /** // // * @returns {PartialOptionsGroup} // // */ // // function createReturnsOptions() { // // return { // // name: "Returns", // // tree: [ // // { // // name: "Total", // // tree: [ // // ...groups.totalReturns.map(({ name, key }) => // // createReturnsOption({ // // scale: "date", // // name, // // title: `${name} Total`, // // key: `${key}-total`, // // }), // // ), // // ], // // }, // // { // // name: "Compound", // // tree: [ // // ...groups.compoundReturns.map(({ name, key }) => // // createReturnsOption({ // // scale: "date", // // name, // // title: `${name} Compound`, // // key: `${key}-compound`, // // }), // // ), // // ], // // }, // // ], // // }; // // } // // /** // // * @param {Object} args // // * @param {TimeScale} args.scale // // * @param {string} args.name // // * @param {string} args.title // // * @param {`${TotalReturnKey}-total` | `${CompoundReturnKey}-compound`} args.key // // * @returns {PartialChartOption} // // */ // // function createReturnsOption({ scale, name, title, key }) { // // return { // // scale, // // name, // // description: "", // // title: `${title} Return`, // // unit: "Percentage", // // bottom: [ // // { // // title: `Return`, // // type: "Baseline", // // datasetPath: `date-to-price-${key}-return`, // // }, // // bases[0](scale), // // ], // // }; // // } // // /** // // * @returns {PartialOptionsGroup} // // */ // // function createIndicatorsOptions() { // // return { // // name: "Indicators", // // tree: [], // // }; // // } // return { // name: "Market", // tree: [ // { // scale, // name: "Dollars Per Bitcoin", // title: "Dollars Per Bitcoin", // description: "", // unit: "US Dollars", // }, // { // scale, // name: "Satoshis Per Dollar", // title: "Satoshis Per Dollar", // description: "", // unit: "Satoshis", // bottom: [ // { // title: "Satoshis", // datasetPath: `${scale}-to-sats-per-dollar`, // color: colors.bitcoin, // }, // ], // }, // // { // // scale, // // name: "Capitalization", // // title: "Market Capitalization", // // description: "", // // unit: "US Dollars", // // bottom: [ // // { // // title: "Capitalization", // // datasetPath: `${scale}-to-market-cap`, // // color: colors.bitcoin, // // }, // // ], // // }, // // createAllTimeHighOptions(scale), // // createAveragesOptions(scale), // // ...(scale === "date" // // ? [createReturnsOptions(), createIndicatorsOptions()] // // : []), // ], // }; // } // /** // * @param {TimeScale} scale // * @returns {PartialOptionsGroup} // */ // function createBlocksOptions(scale) { // return { // name: "Blocks", // tree: [ // ...(scale === "date" // ? /** @type {PartialOptionsTree} */ ([ // { // scale, // name: "Height", // title: "Block Height", // description: "", // unit: "Height", // bottom: [ // { // title: "Height", // color: colors.bitcoin, // datasetPath: `date-to-last-height`, // }, // ], // }, // { // scale, // name: "Mined", // tree: [ // { // scale, // name: "Daily Sum", // title: "Daily Sum Of Blocks Mined", // description: "", // unit: "Count", // bottom: [ // { // title: "Target", // color: colors.off, // datasetPath: `date-to-blocks-mined-1d-target`, // options: { // lineStyle: 3, // }, // }, // { // title: "1W Avg.", // color: colors.momentumYellow, // datasetPath: `date-to-blocks-mined-1w-sma`, // defaultActive: false, // }, // { // title: "1M Avg.", // color: colors.bitcoin, // datasetPath: `date-to-blocks-mined-1m-sma`, // }, // { // title: "Mined", // color: colors.offBitcoin, // datasetPath: `date-to-blocks-mined`, // main: true, // }, // ], // }, // { // scale, // name: "Weekly Sum", // title: "Weekly Sum Of Blocks Mined", // description: "", // unit: "Count", // bottom: [ // { // title: "Target", // color: colors.off, // datasetPath: `date-to-blocks-mined-1w-target`, // options: { // lineStyle: 3, // }, // }, // { // title: "Sum Mined", // color: colors.bitcoin, // datasetPath: `date-to-blocks-mined-1w-sum`, // }, // ], // }, // { // scale, // name: "Monthly Sum", // title: "Monthly Sum Of Blocks Mined", // description: "", // unit: "Count", // bottom: [ // { // title: "Target", // color: colors.off, // datasetPath: `date-to-blocks-mined-1m-target`, // options: { // lineStyle: 3, // }, // }, // { // title: "Sum Mined", // color: colors.bitcoin, // datasetPath: `date-to-blocks-mined-1m-sum`, // }, // ], // }, // { // scale, // name: "Yearly Sum", // title: "Yearly Sum Of Blocks Mined", // description: "", // unit: "Count", // bottom: [ // { // title: "Target", // color: colors.off, // datasetPath: `date-to-blocks-mined-1y-target`, // options: { // lineStyle: 3, // }, // }, // { // title: "Sum Mined", // color: colors.bitcoin, // datasetPath: `date-to-blocks-mined-1y-sum`, // }, // ], // }, // { // scale, // name: "Total", // title: "Total Blocks Mined", // description: "", // unit: "Count", // bottom: [ // { // title: "Mined", // color: colors.bitcoin, // datasetPath: `date-to-total-blocks-mined`, // }, // ], // }, // ], // }, // { // scale, // name: "Size", // tree: [ // { // scale, // name: "Cumulative", // title: "Cumulative Block Size", // description: "", // unit: "Gigabytes", // bottom: [ // { // title: "Size", // color: colors.off, // datasetPath: `${scale}-to-cumulative-block-size-gigabytes`, // }, // ], // }, // ...createRecapOptions({ // scale, // title: "Block Size", // color: colors.off, // unit: "Megabytes", // keySum: "date-to-block-size-1d-sum", // keyAverage: "date-to-block-size-1d-average", // keyMax: "date-to-block-size-1d-max", // key90p: "date-to-block-size-1d-90p", // key75p: "date-to-block-size-1d-75p", // keyMedian: "date-to-block-size-1d-median", // key25p: "date-to-block-size-1d-25p", // key10p: "date-to-block-size-1d-10p", // keyMin: "date-to-block-size-1d-min", // }), // ], // }, // { // scale, // name: "Weight", // tree: createRecapOptions({ // scale, // title: "Block Weight", // color: colors.off, // unit: "Weight", // keyAverage: "date-to-block-weight-1d-average", // keyMax: "date-to-block-weight-1d-max", // key90p: "date-to-block-weight-1d-90p", // key75p: "date-to-block-weight-1d-75p", // keyMedian: "date-to-block-weight-1d-median", // key25p: "date-to-block-weight-1d-25p", // key10p: "date-to-block-weight-1d-10p", // keyMin: "date-to-block-weight-1d-min", // }), // }, // { // scale, // name: "VBytes", // tree: createRecapOptions({ // scale, // title: "Block VBytes", // color: colors.off, // unit: "Virtual Bytes", // keyAverage: "date-to-block-vbytes-1d-average", // keyMax: "date-to-block-vbytes-1d-max", // key90p: "date-to-block-vbytes-1d-90p", // key75p: "date-to-block-vbytes-1d-75p", // keyMedian: "date-to-block-vbytes-1d-median", // key25p: "date-to-block-vbytes-1d-25p", // key10p: "date-to-block-vbytes-1d-10p", // keyMin: "date-to-block-vbytes-1d-min", // }), // }, // { // scale, // name: "Interval", // tree: createRecapOptions({ // scale, // title: "Block Interval", // color: colors.off, // unit: "Seconds", // keyAverage: "date-to-block-interval-1d-average", // keyMax: "date-to-block-interval-1d-max", // key90p: "date-to-block-interval-1d-90p", // key75p: "date-to-block-interval-1d-75p", // keyMedian: "date-to-block-interval-1d-median", // key25p: "date-to-block-interval-1d-25p", // key10p: "date-to-block-interval-1d-10p", // keyMin: "date-to-block-interval-1d-min", // }), // }, // ]) // : /** @type {PartialOptionsTree} */ ([ // { // scale, // name: "Size", // title: "Block Size", // description: "", // unit: "Megabytes", // bottom: [ // { // title: "Size", // color: colors.off, // datasetPath: `height-to-block-size`, // }, // ], // }, // { // scale, // name: "Weight", // title: "Block Weight", // description: "", // unit: "Weight", // bottom: [ // { // title: "Weight", // color: colors.off, // datasetPath: `height-to-block-weight`, // }, // ], // }, // { // scale, // name: "VBytes", // title: "Block VBytes", // description: "", // unit: "Virtual Bytes", // bottom: [ // { // title: "VBytes", // color: colors.off, // datasetPath: `height-to-block-vbytes`, // }, // ], // }, // { // scale, // name: "Interval", // title: "Block Interval", // description: "", // unit: "Seconds", // bottom: [ // { // title: "Interval", // color: colors.off, // datasetPath: `height-to-block-interval`, // }, // ], // }, // ])), // ], // }; // } // /** // * @param {TimeScale} scale // * @returns {PartialOptionsGroup} // */ // function createMinersOptions(scale) { // return { // name: "Miners", // tree: [ // { // name: "Coinbases", // tree: [ // .../** @satisfies {PartialOptionsTree} */ ( // scale === "date" // ? [ // { // scale, // name: "Daily Sum", // tree: [ // { // scale, // name: "In Bitcoin", // title: "Daily Sum Of Coinbases In Bitcoin", // description: "", // unit: "Bitcoin", // bottom: [ // { // title: "Sum", // color: colors.bitcoin, // datasetPath: `${scale}-to-coinbase-1d-sum`, // }, // ], // }, // { // scale, // name: "In Dollars", // title: "Daily Sum Of Coinbases In Dollars", // description: "", // unit: "US Dollars", // bottom: [ // { // title: "Sum", // color: colors.dollars, // datasetPath: `${scale}-to-coinbase-in-dollars-1d-sum`, // }, // ], // }, // ], // }, // { // scale, // name: "Yearly Sum", // tree: [ // { // scale, // name: "In Bitcoin", // title: "Yearly Sum Of Coinbases In Bitcoin", // description: "", // unit: "Bitcoin", // bottom: [ // { // title: "Sum", // color: colors.bitcoin, // datasetPath: `${scale}-to-coinbase-1y-sum`, // }, // ], // }, // { // scale, // name: "In Dollars", // title: "Yearly Sum Of Coinbases In Dollars", // description: "", // unit: "US Dollars", // bottom: [ // { // title: "Sum", // color: colors.dollars, // datasetPath: `${scale}-to-coinbase-in-dollars-1y-sum`, // }, // ], // }, // ], // }, // { // scale, // name: "Cumulative", // tree: [ // { // scale, // name: "In Bitcoin", // title: "Cumulative Coinbases In Bitcoin", // description: "", // unit: "Bitcoin", // bottom: [ // { // title: "Coinbases", // color: colors.bitcoin, // datasetPath: `${scale}-to-cumulative-coinbase`, // }, // ], // }, // { // scale, // name: "In Dollars", // title: "Cumulative Coinbases In Dollars", // description: "", // unit: "US Dollars", // bottom: [ // { // title: "Coinbases", // color: colors.dollars, // datasetPath: `${scale}-to-cumulative-coinbase-in-dollars`, // }, // ], // }, // ], // }, // { // name: "Last Block", // tree: [ // { // scale, // name: "In Bitcoin", // title: "Last Coinbase In Bitcoin", // description: "", // unit: "US Dollars", // bottom: [ // { // title: "Last", // color: colors.bitcoin, // datasetPath: `${scale}-to-last-coinbase`, // }, // ], // }, // { // scale, // name: "In Dollars", // title: "Last Coinbase In Dollars", // description: "", // unit: "US Dollars", // bottom: [ // { // title: "Last", // color: colors.dollars, // datasetPath: `${scale}-to-last-coinbase-in-dollars`, // }, // ], // }, // ], // }, // ] // : [ // { // scale, // name: "In Bitcoin", // title: "Coinbases In Bitcoin", // description: "", // unit: "Bitcoin", // bottom: [ // { // title: "Coinbase", // color: colors.bitcoin, // datasetPath: `${scale}-to-coinbase`, // }, // ], // }, // { // scale, // name: "In Dollars", // title: "Coinbases In Dollars", // description: "", // unit: "US Dollars", // bottom: [ // { // title: "Coinbase", // color: colors.dollars, // datasetPath: `${scale}-to-coinbase-in-dollars`, // }, // ], // }, // ] // ), // ], // }, // { // name: "Subsidies", // tree: [ // .../** @satisfies {PartialOptionsTree} */ ( // scale === "date" // ? [ // { // scale, // name: "Daily Sum", // tree: [ // { // scale, // name: "In Bitcoin", // title: "Daily Sum Of Subsidies In Bitcoin", // description: "", // unit: "Bitcoin", // bottom: [ // { // title: "Sum", // color: colors.bitcoin, // datasetPath: `${scale}-to-subsidy-1d-sum`, // }, // ], // }, // { // scale, // name: "In Dollars", // title: "Daily Sum Of Subsidies In Dollars", // description: "", // unit: "US Dollars", // bottom: [ // { // title: "Sum", // color: colors.dollars, // datasetPath: `${scale}-to-subsidy-in-dollars-1d-sum`, // }, // ], // }, // ], // }, // { // scale, // name: "Yearly Sum", // tree: [ // { // scale, // name: "In Bitcoin", // title: "Yearly Sum Of Subsidies In Bitcoin", // description: "", // unit: "Bitcoin", // bottom: [ // { // title: "Sum", // color: colors.bitcoin, // datasetPath: `${scale}-to-subsidy-1y-sum`, // }, // ], // }, // { // scale, // name: "In Dollars", // title: "Yearly Sum Of Subsidies In Dollars", // description: "", // unit: "US Dollars", // bottom: [ // { // title: "Sum", // color: colors.dollars, // datasetPath: `${scale}-to-subsidy-in-dollars-1y-sum`, // }, // ], // }, // ], // }, // { // scale, // name: "Cumulative", // tree: [ // { // scale, // name: "In Bitcoin", // title: "Cumulative Subsidies In Bitcoin", // description: "", // unit: "Bitcoin", // bottom: [ // { // title: "Subsidies", // color: colors.bitcoin, // datasetPath: `${scale}-to-cumulative-subsidy`, // }, // ], // }, // { // scale, // name: "In Dollars", // title: "Cumulative Subsidies In Dollars", // description: "", // unit: "US Dollars", // bottom: [ // { // title: "Subsidies", // color: colors.dollars, // datasetPath: `${scale}-to-cumulative-subsidy-in-dollars`, // }, // ], // }, // ], // }, // { // name: "Last Block", // tree: [ // { // scale, // name: "In Bitcoin", // title: "Last Subsidy In Bitcoin", // description: "", // unit: "Bitcoin", // bottom: [ // { // title: "Last", // color: colors.bitcoin, // datasetPath: `${scale}-to-last-subsidy`, // }, // ], // }, // { // scale, // name: "In Dollars", // title: "Last Subsidy In Dollars", // description: "", // unit: "US Dollars", // bottom: [ // { // title: "Last", // color: colors.dollars, // datasetPath: `${scale}-to-last-subsidy-in-dollars`, // }, // ], // }, // ], // }, // ] // : [ // { // scale, // name: "In Bitcoin", // title: "Subsidies In Bitcoin", // description: "", // unit: "Bitcoin", // bottom: [ // { // title: "Sum", // color: colors.bitcoin, // datasetPath: `${scale}-to-subsidy`, // }, // ], // }, // { // scale, // name: "In Dollars", // title: "Subsidies In Dollars", // description: "", // unit: "US Dollars", // bottom: [ // { // title: "Sum", // color: colors.dollars, // datasetPath: `${scale}-to-subsidy-in-dollars`, // }, // ], // }, // ] // ), // ], // }, // { // name: "Fees", // tree: [ // .../** @satisfies {PartialOptionsTree} */ ( // scale === "date" // ? [ // { // scale, // name: "Daily Sum", // tree: [ // { // scale, // name: "In Bitcoin", // title: "Daily Sum Of Fees In Bitcoin", // description: "", // unit: "Bitcoin", // bottom: [ // { // title: "Sum", // color: colors.bitcoin, // datasetPath: `${scale}-to-fees-1d-sum`, // }, // ], // }, // { // scale, // name: "In Dollars", // title: "Daily Sum Of Fees In Dollars", // description: "", // unit: "US Dollars", // bottom: [ // { // title: "Sum", // color: colors.dollars, // datasetPath: `${scale}-to-fees-in-dollars-1d-sum`, // }, // ], // }, // ], // }, // { // scale, // name: "Yearly Sum", // tree: [ // { // scale, // name: "In Bitcoin", // title: "Yearly Sum Of Fees In Bitcoin", // description: "", // unit: "Bitcoin", // bottom: [ // { // title: "Sum", // color: colors.bitcoin, // datasetPath: `${scale}-to-fees-1y-sum`, // }, // ], // }, // { // scale, // name: "In Dollars", // title: "Yearly Sum Of Fees In Dollars", // description: "", // unit: "US Dollars", // bottom: [ // { // title: "Sum", // color: colors.dollars, // datasetPath: `${scale}-to-fees-in-dollars-1y-sum`, // }, // ], // }, // ], // }, // { // scale, // name: "Cumulative", // tree: [ // { // scale, // name: "In Bitcoin", // title: "Cumulative Fees In Bitcoin", // description: "", // unit: "Bitcoin", // bottom: [ // { // title: "Fees", // color: colors.bitcoin, // datasetPath: `${scale}-to-cumulative-fees`, // }, // ], // }, // { // scale, // name: "In Dollars", // title: "Cumulative Fees In Dollars", // description: "", // unit: "US Dollars", // bottom: [ // { // title: "Fees", // color: colors.dollars, // datasetPath: `${scale}-to-cumulative-fees-in-dollars`, // }, // ], // }, // ], // }, // { // name: "Last Block", // tree: [ // { // scale, // name: "In Bitcoin", // title: "Last Fees In Bitcoin", // description: "", // unit: "Bitcoin", // bottom: [ // { // title: "Last", // color: colors.bitcoin, // datasetPath: `${scale}-to-last-fees`, // }, // ], // }, // { // scale, // name: "In Dollars", // title: "Last Fees In Dollars", // description: "", // unit: "US Dollars", // bottom: [ // { // title: "Last", // color: colors.dollars, // datasetPath: `${scale}-to-last-fees-in-dollars`, // }, // ], // }, // ], // }, // ] // : [ // { // scale, // name: "In Bitcoin", // title: "Fees In Bitcoin", // description: "", // unit: "Bitcoin", // bottom: [ // { // title: "Sum", // color: colors.bitcoin, // datasetPath: `${scale}-to-fees`, // }, // ], // }, // { // scale, // name: "In Dollars", // title: "Fees In Dollars", // description: "", // unit: "US Dollars", // bottom: [ // { // title: "Sum", // color: colors.dollars, // datasetPath: `${scale}-to-fees-in-dollars`, // }, // ], // }, // ] // ), // ], // }, // { // scale, // name: "Subsidy V. Fees", // title: "Subsidy V. Fees", // description: "", // unit: "Percentage", // bottom: [ // { // title: "Subsidy", // color: colors.bitcoin, // datasetPath: // scale === "date" // ? `${scale}-to-subsidy-to-coinbase-1d-ratio` // : `${scale}-to-subsidy-to-coinbase-ratio`, // }, // { // title: "Fees", // color: colors.offBitcoin, // datasetPath: // scale === "date" // ? `${scale}-to-fees-to-coinbase-1d-ratio` // : `${scale}-to-fees-to-coinbase-ratio`, // }, // ], // }, // ...(scale === "date" // ? /** @type {PartialOptionsTree} */ ([ // { // scale, // name: "Puell Multiple", // title: "Puell Multiple", // description: "", // unit: "", // bottom: [ // { // title: "Multiple", // color: colors.bitcoin, // datasetPath: `date-to-puell-multiple`, // }, // ], // }, // { // name: "Hash", // tree: [ // { // scale, // name: "Rate", // title: "Hash Rate", // description: "", // unit: "ExaHash / Second", // bottom: [ // { // title: "1M SMA", // color: colors.momentumYellow, // datasetPath: `date-to-hash-rate-1m-sma`, // }, // { // title: "1W SMA", // color: colors.bitcoin, // datasetPath: `date-to-hash-rate-1w-sma`, // }, // { // title: "Rate", // color: colors.offBitcoin, // datasetPath: `date-to-hash-rate`, // }, // ], // }, // { // scale, // name: "Ribbon", // title: "Hash Ribbon", // description: "", // unit: "ExaHash / Second", // bottom: [ // { // title: "1M SMA", // color: colors.profit, // datasetPath: `date-to-hash-rate-1m-sma`, // }, // { // title: "2M SMA", // color: colors.loss, // datasetPath: `date-to-hash-rate-2m-sma`, // }, // ], // }, // { // name: "Price", // tree: [ // { // scale, // name: "Price", // title: "Hash Price", // description: "", // unit: "Dollars / (PetaHash / Second)", // bottom: [ // { // title: "Hash Price", // color: colors.dollars, // datasetPath: `date-to-hash-price`, // }, // ], // }, // { // scale, // name: "Min", // title: "Min Hash Price", // description: "", // unit: "Dollars / (PetaHash / Second)", // bottom: [ // { // title: "Min Hash Price", // color: colors.dollars, // datasetPath: `date-to-hash-price-min`, // }, // ], // }, // { // scale, // name: "Rebound", // title: "Hash Price Rebound", // description: "", // unit: "Percentage", // bottom: [ // { // title: "Rebound", // color: colors.yellow, // datasetPath: `date-to-hash-price-rebound`, // }, // ], // }, // ], // }, // ], // }, // ]) // : []), // { // scale, // name: "Difficulty", // title: "Difficulty", // description: "", // unit: "", // bottom: [ // { // title: "Difficulty", // color: colors.bitcoin, // datasetPath: `${scale}-to-difficulty`, // }, // ], // }, // ...(scale === "date" // ? /** @type {PartialOptionsTree} */ ([ // { // scale, // name: "Difficulty Adjustment", // title: "Difficulty Adjustment", // description: "", // unit: "Percentage", // bottom: [ // { // title: "Adjustment", // type: "Baseline", // datasetPath: `${scale}-to-difficulty-adjustment`, // }, // bases[0](scale), // ], // }, // { // scale, // name: "Annualized Issuance", // title: "Annualized Issuance", // description: "", // unit: "Bitcoin", // bottom: [ // { // title: "Issuance", // color: colors.bitcoin, // datasetPath: `${scale}-to-annualized-issuance`, // }, // ], // }, // { // name: "Inflation Rate", // tree: [ // { // scale, // name: "Today", // title: "Inflation Rate", // description: "", // unit: "Percentage", // bottom: [ // { // title: "Rate", // color: colors.bitcoin, // datasetPath: `${scale}-to-inflation-rate`, // }, // ], // }, // { // scale, // name: "Yearly", // title: "Yearly Inflation Rate", // description: "", // unit: "Percentage", // bottom: [ // { // title: "Rate", // color: colors.bitcoin, // datasetPath: `${scale}-to-yearly-inflation-rate`, // }, // ], // }, // ], // }, // ]) // : []), // ], // }; // } // /** // * @param {TimeScale} scale // * @returns {PartialOptionsGroup} // */ // function createTransactionsOptions(scale) { // return { // name: "Transactions", // tree: [ // { // scale, // name: "Count", // title: "Transaction Count", // description: "", // unit: "Count", // bottom: [ // { // title: "1M SMA", // color: colors.momentumYellow, // datasetPath: // scale === "date" // ? `${scale}-to-transaction-count-1d-sum-1m-sma` // : `${scale}-to-transaction-count-1m-sma`, // }, // { // title: "1W SMA", // color: colors.bitcoin, // datasetPath: // scale === "date" // ? `${scale}-to-transaction-count-1d-sum-1w-sma` // : `${scale}-to-transaction-count-1w-sma`, // }, // { // title: "Raw", // color: colors.offBitcoin, // datasetPath: // scale === "date" // ? `${scale}-to-transaction-count-1d-sum` // : `${scale}-to-transaction-count`, // main: true, // }, // ], // }, // { // name: "Volume", // tree: [ // { // scale, // name: "In Bitcoin", // title: "Transaction Volume", // description: "", // unit: "Bitcoin", // bottom: [ // { // title: "1M SMA", // color: colors.momentumYellow, // datasetPath: // scale === "date" // ? `${scale}-to-transaction-volume-1d-sum-1m-sma` // : `${scale}-to-transaction-volume-1m-sma`, // }, // { // title: "1W SMA", // color: colors.bitcoin, // datasetPath: // scale === "date" // ? `${scale}-to-transaction-volume-1d-sum-1w-sma` // : `${scale}-to-transaction-volume-1w-sma`, // }, // { // title: "Raw", // color: colors.offBitcoin, // datasetPath: // scale === "date" // ? `${scale}-to-transaction-volume-1d-sum` // : `${scale}-to-transaction-volume`, // }, // ], // }, // { // scale, // name: "In Dollars", // title: "Transaction Volume In Dollars", // description: "", // unit: "US Dollars", // bottom: [ // { // title: "1M SMA", // color: colors.lightDollars, // datasetPath: // scale === "date" // ? `${scale}-to-transaction-volume-in-dollars-1d-sum-1m-sma` // : `${scale}-to-transaction-volume-in-dollars-1m-sma`, // }, // { // title: "1W SMA", // color: colors.dollars, // datasetPath: // scale === "date" // ? `${scale}-to-transaction-volume-in-dollars-1d-sum-1w-sma` // : `${scale}-to-transaction-volume-in-dollars-1w-sma`, // }, // { // title: "Raw", // color: colors.offDollars, // datasetPath: // scale === "date" // ? `${scale}-to-transaction-volume-in-dollars-1d-sum` // : `${scale}-to-transaction-volume-in-dollars`, // }, // ], // }, // ], // }, // ...(scale === "date" // ? /** @type {PartialOptionsTree} */ ([ // { // name: "Annualized Volume", // tree: [ // { // scale, // name: "In Bitcoin", // title: "Annualized Transaction Volume", // description: "", // unit: "Bitcoin", // bottom: [ // { // title: "Volume", // color: colors.bitcoin, // datasetPath: `date-to-annualized-transaction-volume`, // }, // ], // }, // { // scale, // name: "In Dollars", // title: "Annualized Transaction Volume In Dollars", // description: "", // unit: "US Dollars", // bottom: [ // { // title: "Volume", // color: colors.dollars, // datasetPath: `date-to-annualized-transaction-volume-in-dollars`, // }, // ], // }, // ], // }, // { // scale, // name: "Velocity", // title: "Transactions Velocity", // description: "", // unit: "", // bottom: [ // { // title: "Transactions Velocity", // color: colors.bitcoin, // datasetPath: `date-to-transaction-velocity`, // }, // ], // }, // ]) // : []), // { // scale, // name: "Per Second", // title: "Transactions Per Second", // description: "", // unit: "Transactions", // bottom: [ // { // title: "1M SMA", // color: colors.lightBitcoin, // datasetPath: `${scale}-to-transactions-per-second-1m-sma`, // }, // { // title: "1W SMA", // color: colors.bitcoin, // datasetPath: `${scale}-to-transactions-per-second-1w-sma`, // }, // { // title: "Raw", // color: colors.offBitcoin, // datasetPath: `${scale}-to-transactions-per-second`, // main: true, // }, // ], // }, // ], // }; // } // const cohortOptionOrOptions = { // /** // * @param {DefaultCohortOption | DefaultCohortOptions} arg // */ // toList(arg) { // return "list" in arg ? arg.list : [arg]; // }, // /** // * @param {DefaultCohortOption | DefaultCohortOptions} arg // * @param {string} cohortName // * @param {string} legendName // */ // toLegendName(arg, cohortName, legendName) { // return "list" in arg ? `${cohortName} ${legendName}` : legendName; // }, // /** // * @template {AnyPossibleCohortId} T // * @param {CohortOption | CohortOptions} arg // * @param {{ title: string; singleColor?: Color; genPath: (id: T, scale: TimeScale) => AnyDatasetPath} & Omit} blueprint // */ // generateSeriesBlueprints(arg, blueprint) { // return this.toList(arg).map( // ({ scale, datasetId, color, name }) => // /** @satisfies {SplitSeriesBlueprint} */ ({ // title: cohortOptionOrOptions.toLegendName( // arg, // name, // blueprint.title, // ), // color: "list" in arg ? color : blueprint.singleColor || color, // type: blueprint.type || "Line", // // Don't get why TS is annoying here // // @ts-ignore // datasetPath: blueprint.genPath(datasetId, scale), // options: blueprint.options, // }), // ); // }, // /** // * @param {DefaultCohortOption | DefaultCohortOptions} arg // */ // shouldShowAll(arg) { // return "list" in arg || arg.datasetId; // }, // /** // * @param {DefaultCohortOption | DefaultCohortOptions} arg // * @param {(prefix: AnyDatasetPrefix, arg: DefaultCohortOption) => PartialChartOption[]} genOption // */ // genOptionsIfSingle(arg, genOption) { // if (!("list" in arg)) { // const prefix = datasetIdToPrefix(arg.datasetId); // return genOption(prefix, arg); // } else { // return []; // } // }, // /** // * @param {DefaultCohortOption | DefaultCohortOptions} arg // * @param {(scale: 'date') => PartialChartOption[]} genOption // */ // genOptionsIfDate(arg, genOption) { // if (arg.scale === "date") { // return genOption("date"); // } else { // return []; // } // }, // }; // /** // * @param {DefaultCohortOption | DefaultCohortOptions} arg // * @returns {PartialOptionsGroup} // */ // function createCohortUTXOOptions(arg) { // const { scale, title } = arg; // return { // name: "UTXOs", // tree: [ // { // scale, // name: `Count`, // title: `Number Of ${title} Unspent Transaction Outputs`, // description: "", // unit: "Count", // bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, { // title: "Count", // genPath: (id, scale) => // /** @type {const} */ ( // `${scale}-to-${datasetIdToPrefix(id)}utxo-count` // ), // }), // }, // ], // }; // } /** * @param {DefaultCohortOption | DefaultCohortOptions} arg * @returns {PartialOptionsGroup} // */ // function createCohortRealizedOptions(arg) { // const { scale, title } = arg; // /** // * @param {DefaultCohortOption} arg // * @returns {RatioOption} // */ // function argToRatioArg(arg) { // return { // scale, // color: arg.color, // ratioDatasetPath: `${scale}-to-market-price-to-${datasetIdToPrefix( // arg.datasetId, // )}realized-price-ratio`, // valueDatasetPath: `${scale}-to-${datasetIdToPrefix( // arg.datasetId, // )}realized-price`, // title: `${arg.title} Realized Price`, // }; // } // return { // name: "Realized", // tree: [ // { // scale, // name: `Price`, // title: `${title} Realized Price`, // description: "", // unit: "US Dollars", // top: cohortOptionOrOptions.generateSeriesBlueprints(arg, { // title: "Realized Price", // genPath: (id, scale) => // /** @type {const} */ ( // `${scale}-to-${datasetIdToPrefix(id)}realized-price` // ), // }), // }, // createRatioOptions( // "list" in arg // ? { // ...arg, // list: arg.list.map(argToRatioArg), // } // : argToRatioArg(arg), // ), // { // scale, // name: `Capitalization`, // title: `${title} Realized Capitalization`, // description: "", // unit: "US Dollars", // bottom: [ // ...cohortOptionOrOptions.generateSeriesBlueprints( // arg, // { // title: "Realized Cap.", // genPath: (id, scale) => // /** @type {const} */ ( // `${scale}-to-${datasetIdToPrefix(id)}realized-cap` // ), // }, // ), // ...(cohortOptionOrOptions.shouldShowAll(arg) // ? /** @type {const} */ ([ // { // title: "Realized Cap.", // color: colors.bitcoin, // datasetPath: `${scale}-to-realized-cap`, // defaultActive: false, // }, // ]) // : []), // ], // }, // { // scale, // name: `Capitalization 1M Net Change`, // title: `${title} Realized Capitalization 1 Month Net Change`, // description: "", // unit: "US Dollars", // bottom: [ // ...cohortOptionOrOptions.generateSeriesBlueprints( // arg, // { // title: "Net Change", // type: "Baseline", // genPath: (id, scale) => // `${scale}-to-${datasetIdToPrefix( // id, // )}realized-cap-1m-net-change`, // }, // ), // bases[0](scale), // ], // }, // { // scale, // name: `Profit`, // title: `${title} Realized Profit`, // description: "", // unit: "US Dollars", // bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, { // title: "Realized Profit", // singleColor: colors.profit, // genPath: (id, scale) => { // const prefix = datasetIdToPrefix(id); // return scale === "date" // ? `date-to-${prefix}realized-profit-1d-sum` // : `height-to-${prefix}realized-profit`; // }, // }), // }, // { // scale, // name: "Loss", // title: `${title} Realized Loss`, // description: "", // unit: "US Dollars", // bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, { // title: "Realized Loss", // singleColor: colors.loss, // genPath: (id, scale) => { // const prefix = datasetIdToPrefix(id); // return scale === "date" // ? `date-to-${prefix}realized-loss-1d-sum` // : `height-to-${prefix}realized-loss`; // }, // }), // }, // ...cohortOptionOrOptions.genOptionsIfSingle(arg, (prefix) => [ // { // scale, // name: `PNL - Profit And Loss`, // title: `${title} Realized Profit And Loss`, // description: "", // unit: "US Dollars", // bottom: [ // { // title: "Profit", // color: colors.profit, // datasetPath: // scale === "date" // ? `date-to-${prefix}realized-profit-1d-sum` // : `height-to-${prefix}realized-profit`, // type: "Baseline", // }, // { // title: "Loss", // color: colors.loss, // datasetPath: // scale === "date" // ? `date-to-${prefix}negative-realized-loss-1d-sum` // : `height-to-${prefix}negative-realized-loss`, // type: "Baseline", // }, // bases[0](scale), // ], // }, // ]), // { // scale, // name: `Net PNL - Net Profit And Loss`, // title: `${title} Net Realized Profit And Loss`, // description: "", // unit: "US Dollars", // bottom: [ // ...cohortOptionOrOptions.generateSeriesBlueprints(arg, { // title: "Net PNL", // type: "Baseline", // genPath: (id, scale) => { // const prefix = datasetIdToPrefix(id); // return scale === "date" // ? `date-to-${prefix}net-realized-profit-and-loss-1d-sum` // : `height-to-${prefix}net-realized-profit-and-loss`; // }, // }), // bases[0](scale), // ], // }, // ...cohortOptionOrOptions.genOptionsIfDate(arg, (scale) => [ // { // scale, // name: `Net PNL Relative To Market Cap`, // title: `${title} Net Realized Profit And Loss Relative To Market Capitalization`, // description: "", // unit: "Percentage", // bottom: [ // ...cohortOptionOrOptions.generateSeriesBlueprints(arg, { // title: "Net", // type: "Baseline", // genPath: (id) => // `${scale}-to-${datasetIdToPrefix( // id, // )}net-realized-profit-and-loss-to-market-cap-ratio`, // }), // bases[0](scale), // ], // }, // ]), // { // name: "Cumulative", // tree: [ // { // scale, // name: `Profit`, // title: `${title} Cumulative Realized Profit`, // description: "", // unit: "US Dollars", // bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, { // title: "Cumulative Realized Profit", // singleColor: colors.profit, // genPath: (id, scale) => // `${scale}-to-${datasetIdToPrefix( // id, // )}cumulative-realized-profit`, // }), // }, // { // scale, // name: "Loss", // title: `${title} Cumulative Realized Loss`, // description: "", // unit: "US Dollars", // bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, { // title: "Cumulative Realized Loss", // singleColor: colors.loss, // genPath: (id, scale) => // `${scale}-to-${datasetIdToPrefix( // id, // )}cumulative-realized-loss`, // }), // }, // { // scale, // name: `Net PNL`, // title: `${title} Cumulative Net Realized Profit And Loss`, // description: "", // unit: "US Dollars", // bottom: [ // ...cohortOptionOrOptions.generateSeriesBlueprints(arg, { // title: "Cumulative Net Realized PNL", // type: "Baseline", // genPath: (id, scale) => // `${scale}-to-${datasetIdToPrefix( // id, // )}cumulative-net-realized-profit-and-loss`, // }), // bases[0](scale), // ], // }, // { // scale, // name: `Net PNL 30 Day Change`, // title: `${title} Cumulative Net Realized Profit And Loss 30 Day Change`, // description: "", // unit: "US Dollars", // bottom: [ // ...cohortOptionOrOptions.generateSeriesBlueprints(arg, { // title: "Cumulative Net Realized PNL 30d Change", // type: "Baseline", // genPath: (id, scale) => // `${scale}-to-${datasetIdToPrefix( // id, // )}cumulative-net-realized-profit-and-loss-1m-net-change`, // }), // bases[0](scale), // ], // }, // ], // }, // { // scale, // name: "Profit To Loss Ratio", // title: `${title} Profit To Loss Ratio`, // description: "", // unit: "Ratio", // bottom: [ // ...cohortOptionOrOptions.generateSeriesBlueprints(arg, { // title: "Ratio", // type: "Baseline", // options: { // baseValue: { // price: 1, // }, // }, // genPath: (id, scale) => { // const prefix = datasetIdToPrefix(id); // return scale === "date" // ? `date-to-${prefix}realized-profit-to-loss-1d-sum-ratio` // : `height-to-${prefix}realized-profit-to-loss-ratio`; // }, // }), // bases[1](scale, "Even"), // ], // }, // { // name: `Spent Output Profit Ratio`, // tree: [ // { // scale, // name: `Normal - SOPR`, // title: `${title} Spent Output Profit Ratio`, // description: "", // unit: "Percentage", // bottom: [ // ...cohortOptionOrOptions.generateSeriesBlueprints(arg, { // title: "SOPR", // type: "Baseline", // options: { // baseValue: { // price: 1, // }, // }, // genPath: (id, scale) => // `${scale}-to-${datasetIdToPrefix( // id, // )}spent-output-profit-ratio`, // }), // bases[1](scale), // ], // }, // { // scale, // name: `Adjusted - aSOPR`, // title: `${title} Adjusted Spent Output Profit Ratio`, // description: "", // unit: "Percentage", // bottom: [ // ...cohortOptionOrOptions.generateSeriesBlueprints(arg, { // title: "aSOPR", // type: "Baseline", // options: { // baseValue: { // price: 1, // }, // }, // genPath: (id, scale) => // `${scale}-to-${datasetIdToPrefix( // id, // )}adjusted-spent-output-profit-ratio`, // }), // bases[1](scale), // ], // }, // ], // }, // { // name: "Value", // tree: [ // { // name: "Created", // tree: [ // { // scale, // name: `Normal`, // title: `${title} Value Created`, // description: "", // unit: "US Dollars", // bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, { // title: "Value", // singleColor: colors.profit, // genPath: (id, scale) => { // const prefix = datasetIdToPrefix(id); // return scale === "date" // ? `date-to-${prefix}value-created-1d-sum` // : `height-to-${prefix}value-created`; // }, // }), // }, // { // scale, // name: `Adjusted`, // title: `${title} Adjusted Value Created`, // description: "", // unit: "US Dollars", // bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, { // title: "Adjusted Value", // singleColor: colors.profit, // genPath: (id, scale) => { // const prefix = datasetIdToPrefix(id); // return scale === "date" // ? `date-to-${prefix}adjusted-value-created-1d-sum` // : `height-to-${prefix}adjusted-value-created`; // }, // }), // }, // ], // }, // { // name: "Destroyed", // tree: [ // { // scale, // name: `Normal`, // title: `${title} Value Destroyed`, // description: "", // unit: "US Dollars", // bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, { // title: "Value", // singleColor: colors.loss, // genPath: (id, scale) => { // const prefix = datasetIdToPrefix(id); // return scale === "date" // ? `date-to-${prefix}value-destroyed-1d-sum` // : `height-to-${prefix}value-destroyed`; // }, // }), // }, // { // scale, // name: `Adjusted`, // title: `${title} Adjusted Value Destroyed`, // description: "", // unit: "US Dollars", // bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, { // title: "Adjusted Value", // singleColor: colors.loss, // genPath: (id, scale) => { // const prefix = datasetIdToPrefix(id); // return scale === "date" // ? `date-to-${prefix}adjusted-value-destroyed-1d-sum` // : `height-to-${prefix}adjusted-value-destroyed`; // }, // }), // }, // ], // }, // ], // }, // ...cohortOptionOrOptions.genOptionsIfDate(arg, (scale) => [ // /** @satisfies {PartialChartOption} */ ({ // scale, // name: `Sell Side Risk Ratio`, // title: `${title} Sell Side Risk Ratio`, // description: "", // unit: "Percentage", // bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, { // title: "Ratio", // genPath: (id) => // `${scale}-to-${datasetIdToPrefix(id)}sell-side-risk-ratio`, // }), // }), // ]), // ], // }; // } // /** // * @param {DefaultCohortOption | DefaultCohortOptions} arg // * @returns {PartialOptionsGroup} // */ // function createCohortUnrealizedOptions(arg) { // const { scale, title } = arg; // return { // name: "Unrealized", // tree: [ // { // scale, // name: `Profit`, // title: `${title} Unrealized Profit`, // description: "", // unit: "US Dollars", // bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, { // title: "Profit", // genPath: (id) => // `${scale}-to-${datasetIdToPrefix(id)}unrealized-profit`, // singleColor: colors.profit, // }), // }, // { // scale, // name: "Loss", // title: `${title} Unrealized Loss`, // description: "", // unit: "US Dollars", // bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, { // title: "Loss", // genPath: (id) => // `${scale}-to-${datasetIdToPrefix(id)}unrealized-loss`, // singleColor: colors.loss, // }), // }, // ...cohortOptionOrOptions.genOptionsIfSingle(arg, (prefix) => [ // { // scale, // name: `PNL - Profit And Loss`, // title: `${title} Unrealized Profit And Loss`, // description: "", // unit: "US Dollars", // bottom: [ // { // title: "Profit", // color: colors.profit, // datasetPath: `${scale}-to-${prefix}unrealized-profit`, // type: "Baseline", // }, // { // title: "Loss", // color: colors.loss, // datasetPath: `${scale}-to-${prefix}negative-unrealized-loss`, // type: "Baseline", // }, // bases[0](scale), // ], // }, // ]), // { // scale, // name: `Net PNL - Net Profit And Loss`, // title: `${title} Net Unrealized Profit And Loss`, // description: "", // unit: "US Dollars", // bottom: [ // ...cohortOptionOrOptions.generateSeriesBlueprints(arg, { // title: "Net Unrealized PNL", // genPath: (id) => // `${scale}-to-${datasetIdToPrefix( // id, // )}net-unrealized-profit-and-loss`, // type: "Baseline", // }), // bases[0](scale), // ], // }, // { // scale, // name: `Net PNL Relative To Market Cap - NUPL`, // title: `${title} Net Unrealized Profit And Loss Relative To Total Market Capitalization - NUPL`, // description: "", // unit: "Percentage", // bottom: [ // ...cohortOptionOrOptions.generateSeriesBlueprints(arg, { // title: "Relative Net Unrealized PNL", // genPath: (id) => // `${scale}-to-${datasetIdToPrefix( // id, // )}net-unrealized-profit-and-loss-to-market-cap-ratio`, // type: "Baseline", // }), // bases[0](scale), // ], // }, // ], // }; // } // /** // * @param {DefaultCohortOption | DefaultCohortOptions} arg // * @returns {PartialOptionsGroup} // */ // function createCohortSupplyOptions(arg) { // const { scale, title } = arg; // return { // name: "Supply", // tree: [ // { // name: "Absolute", // tree: [ // ...cohortOptionOrOptions.genOptionsIfSingle(arg, (prefix) => [ // { // scale, // name: "All", // title: `${title} Profit And Loss`, // description: "", // unit: "US Dollars", // bottom: [ // { // title: "In Profit", // color: colors.profit, // datasetPath: `${scale}-to-${prefix}supply-in-profit`, // }, // { // title: "In Loss", // color: colors.loss, // datasetPath: `${scale}-to-${prefix}supply-in-loss`, // }, // { // title: "Total", // color: colors.default, // datasetPath: `${scale}-to-${prefix}supply`, // }, // { // title: "Halved Total", // color: colors.off, // datasetPath: `${scale}-to-${prefix}halved-supply`, // options: { // lineStyle: 4, // }, // }, // ], // }, // ]), // { // scale, // name: `Total`, // title: `${title} Total supply`, // description: "", // unit: "Bitcoin", // bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, { // title: "Supply", // genPath: (id) => `${scale}-to-${datasetIdToPrefix(id)}supply`, // }), // }, // { // scale, // name: "In Profit", // title: `${title} Supply In Profit`, // description: "", // unit: "Bitcoin", // bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, { // title: "Supply", // singleColor: colors.profit, // genPath: (id) => // `${scale}-to-${datasetIdToPrefix(id)}supply-in-profit`, // }), // }, // { // scale, // name: "In Loss", // title: `${title} Supply In Loss`, // description: "", // unit: "Bitcoin", // bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, { // title: "Supply", // singleColor: colors.loss, // genPath: (id) => // `${scale}-to-${datasetIdToPrefix(id)}supply-in-loss`, // }), // }, // ], // }, // { // name: "Relative To Circulating", // tree: [ // ...cohortOptionOrOptions.genOptionsIfSingle(arg, (prefix) => [ // { // scale, // name: "All", // title: `${title} Profit And Loss Relative To Circulating Supply`, // description: "", // unit: "Percentage", // bottom: [ // { // title: "In Profit", // color: colors.profit, // datasetPath: `${scale}-to-${prefix}supply-in-profit-to-circulating-supply-ratio`, // }, // { // title: "In Loss", // color: colors.loss, // datasetPath: `${scale}-to-${prefix}supply-in-loss-to-circulating-supply-ratio`, // }, // { // title: "100%", // color: colors.default, // datasetPath: `${scale}-to-${prefix}supply-to-circulating-supply-ratio`, // }, // { // title: "50%", // color: colors.off, // datasetPath: `${scale}-to-${prefix}halved-supply-to-circulating-supply-ratio`, // options: { // lineStyle: 4, // }, // }, // ], // }, // ]), // { // scale, // name: `Total`, // title: `${title} Total supply Relative To Circulating Supply`, // description: "", // unit: "Percentage", // bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, { // title: "Supply", // genPath: (id) => // `${scale}-to-${datasetIdToPrefix( // id, // )}supply-to-circulating-supply-ratio`, // }), // }, // { // scale, // name: "In Profit", // title: `${title} Supply In Profit Relative To Circulating Supply`, // description: "", // unit: "Percentage", // bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, { // title: "Supply", // singleColor: colors.profit, // genPath: (id) => // `${scale}-to-${datasetIdToPrefix( // id, // )}supply-in-profit-to-circulating-supply-ratio`, // }), // }, // { // scale, // name: "In Loss", // title: `${title} Supply In Loss Relative To Circulating Supply`, // description: "", // unit: "Percentage", // bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, { // title: "Supply", // singleColor: colors.loss, // genPath: (id) => // `${scale}-to-${datasetIdToPrefix( // id, // )}supply-in-loss-to-circulating-supply-ratio`, // }), // }, // ], // }, // { // name: "Relative To Own", // tree: [ // ...cohortOptionOrOptions.genOptionsIfSingle(arg, (prefix) => [ // { // scale, // name: "All", // title: `${title} Supply In Profit And Loss Relative To Own Supply`, // description: "", // unit: "Percentage", // bottom: [ // { // title: "In Profit", // color: colors.profit, // datasetPath: `${scale}-to-${prefix}supply-in-profit-to-own-supply-ratio`, // }, // { // title: "In Loss", // color: colors.loss, // datasetPath: `${scale}-to-${prefix}supply-in-loss-to-own-supply-ratio`, // }, // { // title: "100%", // color: colors.default, // datasetPath: `${scale}-to-100`, // options: { // lastValueVisible: false, // }, // }, // { // title: "50%", // color: colors.off, // datasetPath: `${scale}-to-50`, // options: { // lineStyle: 4, // lastValueVisible: false, // }, // }, // ], // }, // ]), // { // scale, // name: "In Profit", // title: `${title} Supply In Profit Relative To Own Supply`, // description: "", // unit: "Percentage", // bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, { // title: "Supply", // singleColor: colors.profit, // genPath: (id) => // `${scale}-to-${datasetIdToPrefix( // id, // )}supply-in-profit-to-own-supply-ratio`, // }), // }, // { // scale, // name: "In Loss", // title: `${title} Supply In Loss Relative To Own Supply`, // description: "", // unit: "Percentage", // bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, { // title: "Supply", // singleColor: colors.loss, // genPath: (id) => // `${scale}-to-${datasetIdToPrefix( // id, // )}supply-in-loss-to-own-supply-ratio`, // }), // }, // ], // }, // // createMomentumPresetFolder({ // // datasets: datasets[scale], // // scale, // // id: `${scale}-${id}-supply-in-profit-and-loss-percentage-self`, // // title: `${title} Supply In Profit And Loss (% Self)`, // // datasetId: `${datasetId}SupplyPNL%Self`, // // }), // ], // }; // } // /** // * @param {DefaultCohortOption | DefaultCohortOptions} arg // * @returns {PartialOptionsGroup} // */ // function createCohortPricesPaidOptions(arg) { // const { scale, title } = arg; // /** // * @param {Object} args // * @param {TimeScale} args.scale // * @param {AnyDatasetPrefix} args.prefix // * @param {PercentileId} args.id // * @returns {AnyDatasetPath} // */ // function generatePath({ scale, prefix, id }) { // return /** @type {const} */ (`${scale}-to-${prefix}${id}`); // } // return { // name: "Prices Paid", // tree: [ // { // scale, // name: `Average`, // title: `${title} Average Price Paid - Realized Price`, // description: "", // unit: "US Dollars", // top: cohortOptionOrOptions.generateSeriesBlueprints(arg, { // title: "Average", // genPath: (id) => // `${scale}-to-${datasetIdToPrefix(id)}realized-price`, // }), // }, // ...cohortOptionOrOptions.genOptionsIfSingle(arg, (prefix, arg) => [ // { // scale, // name: `Deciles`, // title: `${title} deciles`, // description: "", // unit: "US Dollars", // top: groups.percentiles // .filter(({ value }) => Number(value) % 10 === 0) // .map(({ name, id }) => { // const datasetPath = generatePath({ // scale, // prefix, // id, // }); // return { // datasetPath, // color: arg.color, // title: name, // }; // }), // }, // ]), // ...groups.percentiles.map((percentile) => ({ // scale, // name: percentile.name, // title: `${title} ${percentile.title}`, // description: "", // unit: /** @type {const} */ ("US Dollars"), // top: cohortOptionOrOptions.generateSeriesBlueprints(arg, { // title: "Relative Net Unrealized PNL", // genPath: (id) => // generatePath({ // scale, // prefix: datasetIdToPrefix(id), // id: percentile.id, // }), // }), // })), // ], // }; // } // /** // * @param {DefaultCohortOption | DefaultCohortOptions} arg // * @returns {PartialOptionsTree} // */ // function createCohortOptions(arg) { // return [ // createCohortUTXOOptions(arg), // createCohortRealizedOptions(arg), // createCohortUnrealizedOptions(arg), // createCohortSupplyOptions(arg), // createCohortPricesPaidOptions(arg), // ]; // } // /** // * @param {TimeScale} scale // * @returns {PartialOptionsGroup} // */ // function createAddressLiquidityOptions(scale) { // return createAddressCohortOptionGroups({ // scale, // name: `By Liquidity`, // list: groups.liquidities.map(({ name, id, key }) => ({ // name, // title: name, // scale, // color: colors[key], // datasetId: id, // })), // }); // } /** * * @param {DefaultCohortOption | DefaultCohortOptions} arg * @returns {PartialOptionsGroup} // */ // function createCohortOptionsGroup(arg) { // return { // name: "list" in arg ? "Compare" : arg.name, // tree: createCohortOptions(arg), // }; // } // /** // * @param {TimeScale} scale // * @returns {PartialOptionsGroup} // */ // function createHodlersOptions(scale) { // /** // * @param {Object} arg // * @param {string} arg.name // * @param {string} [arg.title] // * @param {DefaultCohortOption[]} arg.list // */ // function createFolder({ name, title, list }) { // return { // name, // tree: [ // createCohortOptionsGroup({ // scale, // name, // title: title || name, // list, // }), // ...list.map((cohort) => createCohortOptionsGroup(cohort)), // ], // }; // } // return { // name: "Hodlers", // tree: [ // createFolder({ // name: "X Term Holders", // list: groups.xTermHolders.map(({ key, id, name, legend }) => ({ // scale, // color: colors[key], // name: legend, // datasetId: id, // title: name, // })), // }), // createFolder({ // name: "Up To X", // list: groups.upTo.map(({ key, id, name }) => ({ // scale, // color: colors[key], // name, // datasetId: id, // title: name, // })), // }), // createFolder({ // name: "From X To Y", // list: groups.fromXToY.map(({ key, id, name }) => ({ // scale, // color: colors[key], // name, // datasetId: id, // title: name, // })), // }), // createFolder({ // name: "From X", // list: groups.fromX.map(({ key, id, name }) => ({ // scale, // color: colors[key], // name, // datasetId: id, // title: name, // })), // }), // createFolder({ // name: "Epoch X", // title: "Epochs", // list: groups.epochs.map(({ key, id, name }) => ({ // scale, // color: colors[key], // name, // datasetId: id, // title: name, // })), // }), // ], // }; // } // /** // * @param {CohortOption | CohortOptions} arg // * @returns {PartialChartOption} // */ // function createAddressCountOption(arg) { // const { scale, title } = arg; // return { // scale, // name: `Address Count`, // title: `${title} Address Count`, // description: "", // unit: "Count", // bottom: cohortOptionOrOptions.generateSeriesBlueprints(arg, { // title: "Address Count", // genPath: (id) => `${scale}-to-${id}-address-count`, // }), // }; // } // /** // * @param {CohortOption | CohortOptions} arg // * @returns {PartialOptionsGroup} // */ // function createAddressCohortOptionGroup(arg) { // return { // name: // "list" in arg // ? "Compare" // : arg.filenameAddon // ? `${arg.name} - ${arg.filenameAddon}` // : arg.name, // tree: [ // { // name: "Addresses", // tree: [createAddressCountOption(arg)], // }, // ...createCohortOptions(arg), // ], // }; // } // /** // * @param {Object} arg // * @param {TimeScale} arg.scale // * @param {string} arg.name // * @param {string} [arg.title] // * @param {CohortOption[]} arg.list // */ // function createAddressCohortOptionGroups({ scale, name, title, list }) { // return { // name, // tree: [ // createAddressCohortOptionGroup({ // scale, // name, // title: title || name, // list, // }), // ...list.map((cohort) => createAddressCohortOptionGroup(cohort)), // ], // }; // } // /** // * @param {TimeScale} scale // * @returns {PartialOptionsGroup} // */ // function createAddressesOptions(scale) { // return { // name: "Addresses", // tree: [ // { // scale, // name: `Total Non Empty Addresses`, // title: `Total Non Empty Address`, // description: "", // unit: "Count", // bottom: [ // { // title: `Total Non Empty Address`, // color: colors.bitcoin, // datasetPath: `${scale}-to-address-count`, // }, // ], // }, // { // scale, // name: `New Addresses`, // title: `New Addresses`, // description: "", // unit: "Count", // bottom: [ // { // title: `New Addresses`, // color: colors.bitcoin, // datasetPath: `${scale}-to-new-addresses`, // }, // ], // }, // { // scale, // name: `Total Addresses Created`, // title: `Total Addresses Created`, // description: "", // unit: "Count", // bottom: [ // { // title: `Total Addresses Created`, // color: colors.bitcoin, // datasetPath: `${scale}-to-created-addresses`, // }, // ], // }, // { // scale, // name: `Total Empty Addresses`, // title: `Total Empty Addresses`, // description: "", // unit: "Count", // bottom: [ // { // title: `Total Empty Addresses`, // color: colors.off, // datasetPath: `${scale}-to-empty-addresses`, // }, // ], // }, // createAddressCohortOptionGroups({ // scale, // name: "By Size", // title: "Address Sizes", // list: groups.size.map(({ key, name, size }) => ({ // scale, // color: colors[key], // name, // title: name, // filenameAddon: size, // datasetId: key, // })), // }), // createAddressCohortOptionGroups({ // scale, // name: "By Type", // title: "Address Types", // list: groups.type.map(({ key, name }) => ({ // scale, // color: colors[key], // name, // title: name, // datasetId: key, // })), // }), // createAddressLiquidityOptions(scale), // ], // }; // } // /** // * @param {TimeScale} scale // * @returns {PartialOptionsGroup} // */ // function createCointimeOptions(scale) { // return { // name: "Cointime Economics", // tree: [ // { // name: "Prices", // tree: [ // { // scale, // name: "All", // title: "All Cointime Prices", // description: "", // unit: "US Dollars", // top: [ // { // title: "Vaulted Price", // color: colors.vaultedness, // datasetPath: `${scale}-to-vaulted-price`, // }, // { // title: "Active Price", // color: colors.liveliness, // datasetPath: `${scale}-to-active-price`, // }, // { // title: "True Market Mean", // color: colors.trueMarketMeanPrice, // datasetPath: `${scale}-to-true-market-mean`, // }, // { // title: "Realized Price", // color: colors.bitcoin, // datasetPath: `${scale}-to-realized-price`, // }, // { // title: "Cointime", // color: colors.cointimePrice, // datasetPath: `${scale}-to-cointime-price`, // }, // ], // }, // { // name: "Active", // tree: [ // { // scale, // name: "Price", // title: "Active Price", // description: "", // unit: "US Dollars", // top: [ // { // title: "Active Price", // color: colors.liveliness, // datasetPath: `${scale}-to-active-price`, // }, // ], // }, // createRatioOptions({ // color: colors.liveliness, // ratioDatasetPath: `${scale}-to-market-price-to-active-price-ratio`, // scale, // title: "Active Price", // valueDatasetPath: `${scale}-to-active-price`, // }), // ], // }, // { // name: "Vaulted", // tree: [ // { // scale, // name: "Price", // title: "Vaulted Price", // description: "", // unit: "US Dollars", // top: [ // { // title: "Vaulted Price", // color: colors.vaultedness, // datasetPath: `${scale}-to-vaulted-price`, // }, // ], // }, // createRatioOptions({ // color: colors.vaultedness, // ratioDatasetPath: `${scale}-to-market-price-to-vaulted-price-ratio`, // scale, // title: "Vaulted Price", // valueDatasetPath: `${scale}-to-vaulted-price`, // }), // ], // }, // { // name: "True Market Mean", // tree: [ // { // scale, // name: "Price", // title: "True Market Mean", // description: "", // unit: "US Dollars", // top: [ // { // title: "True Market Mean", // color: colors.trueMarketMeanPrice, // datasetPath: `${scale}-to-true-market-mean`, // }, // ], // }, // createRatioOptions({ // color: colors.liveliness, // ratioDatasetPath: `${scale}-to-market-price-to-true-market-mean-ratio`, // scale, // title: "True Market Mean", // valueDatasetPath: `${scale}-to-true-market-mean`, // }), // ], // }, // { // name: "Cointime Price", // tree: [ // { // scale, // name: "Price", // title: "Cointime Price", // description: "", // unit: "US Dollars", // top: [ // { // title: "Cointime", // color: colors.cointimePrice, // datasetPath: `${scale}-to-cointime-price`, // }, // ], // }, // createRatioOptions({ // color: colors.cointimePrice, // ratioDatasetPath: `${scale}-to-market-price-to-cointime-price-ratio`, // scale, // title: "Cointime", // valueDatasetPath: `${scale}-to-cointime-price`, // }), // ], // }, // ], // }, // { // name: "Capitalizations", // tree: [ // { // scale, // name: "All", // title: "Cointime Capitalizations", // description: "", // unit: "US Dollars", // bottom: [ // { // title: "Market Cap", // color: colors.default, // datasetPath: `${scale}-to-market-cap`, // }, // { // title: "Realized Cap", // color: colors.realizedCap, // datasetPath: `${scale}-to-realized-cap`, // }, // { // title: "Investor Cap", // color: colors.investorCap, // datasetPath: `${scale}-to-investor-cap`, // }, // { // title: "Thermo Cap", // color: colors.thermoCap, // datasetPath: `${scale}-to-thermo-cap`, // }, // ], // }, // { // scale, // name: "Thermo Cap", // title: "Thermo Cap", // description: "", // unit: "US Dollars", // bottom: [ // { // title: "Thermo Cap", // color: colors.thermoCap, // datasetPath: `${scale}-to-thermo-cap`, // }, // ], // }, // { // scale, // name: "Investor Cap", // title: "Investor Cap", // description: "", // unit: "US Dollars", // bottom: [ // { // title: "Investor Cap", // color: colors.investorCap, // datasetPath: `${scale}-to-investor-cap`, // }, // ], // }, // { // scale, // name: "Thermo Cap To Investor Cap Ratio", // title: "Thermo Cap To Investor Cap Ratio", // description: "", // unit: "Percentage", // bottom: [ // { // title: "Ratio", // color: colors.bitcoin, // datasetPath: `${scale}-to-thermo-cap-to-investor-cap-ratio`, // }, // ], // }, // ], // }, // { // name: "Coinblocks", // tree: [ // { // scale, // name: "All", // title: "All Coinblocks", // description: "", // unit: "Coinblocks", // bottom: [ // { // title: "Coinblocks Created", // color: colors.coinblocksCreated, // datasetPath: // scale === "date" // ? `date-to-coinblocks-created-1d-sum` // : `height-to-coinblocks-created`, // }, // { // title: "Coinblocks Destroyed", // color: colors.coinblocksDestroyed, // datasetPath: // scale === "date" // ? `date-to-coinblocks-destroyed-1d-sum` // : `height-to-coinblocks-destroyed`, // }, // { // title: "Coinblocks Stored", // color: colors.coinblocksStored, // datasetPath: // scale === "date" // ? `date-to-coinblocks-stored-1d-sum` // : `height-to-coinblocks-stored`, // }, // ], // }, // { // scale, // name: "Created", // title: "Coinblocks Created", // description: "", // unit: "Coinblocks", // bottom: [ // { // title: "Coinblocks Created", // color: colors.coinblocksCreated, // datasetPath: // scale === "date" // ? `date-to-coinblocks-created-1d-sum` // : `height-to-coinblocks-created`, // }, // ], // }, // { // scale, // name: "Destroyed", // title: "Coinblocks Destroyed", // description: "", // unit: "Coinblocks", // bottom: [ // { // title: "Coinblocks Destroyed", // color: colors.coinblocksDestroyed, // datasetPath: // scale === "date" // ? `date-to-coinblocks-destroyed-1d-sum` // : `height-to-coinblocks-destroyed`, // }, // ], // }, // { // scale, // name: "Stored", // title: "Coinblocks Stored", // description: "", // unit: "Coinblocks", // bottom: [ // { // title: "Coinblocks Stored", // color: colors.coinblocksStored, // datasetPath: // scale === "date" // ? `date-to-coinblocks-stored-1d-sum` // : `height-to-coinblocks-stored`, // }, // ], // }, // ], // }, // { // name: "Cumulative Coinblocks", // tree: [ // { // scale, // name: "All", // title: "All Cumulative Coinblocks", // description: "", // unit: "Coinblocks", // bottom: [ // { // title: "Cumulative Coinblocks Created", // color: colors.coinblocksCreated, // datasetPath: `${scale}-to-cumulative-coinblocks-created`, // }, // { // title: "Cumulative Coinblocks Destroyed", // color: colors.coinblocksDestroyed, // datasetPath: `${scale}-to-cumulative-coinblocks-destroyed`, // }, // { // title: "Cumulative Coinblocks Stored", // color: colors.coinblocksStored, // datasetPath: `${scale}-to-cumulative-coinblocks-stored`, // }, // ], // }, // { // scale, // name: "Created", // title: "Cumulative Coinblocks Created", // description: "", // unit: "Coinblocks", // bottom: [ // { // title: "Cumulative Coinblocks Created", // color: colors.coinblocksCreated, // datasetPath: `${scale}-to-cumulative-coinblocks-created`, // }, // ], // }, // { // scale, // name: "Destroyed", // title: "Cumulative Coinblocks Destroyed", // description: "", // unit: "Coinblocks", // bottom: [ // { // title: "Cumulative Coinblocks Destroyed", // color: colors.coinblocksDestroyed, // datasetPath: `${scale}-to-cumulative-coinblocks-destroyed`, // }, // ], // }, // { // scale, // name: "Stored", // title: "Cumulative Coinblocks Stored", // description: "", // unit: "Coinblocks", // bottom: [ // { // title: "Cumulative Coinblocks Stored", // color: colors.coinblocksStored, // datasetPath: `${scale}-to-cumulative-coinblocks-stored`, // }, // ], // }, // ], // }, // { // name: "Liveliness & Vaultedness", // tree: [ // { // scale, // name: "Liveliness - Activity", // title: "Liveliness (Activity)", // description: "", // unit: "", // bottom: [ // { // title: "Liveliness", // color: colors.liveliness, // datasetPath: `${scale}-to-liveliness`, // }, // ], // }, // { // scale, // name: "Vaultedness", // title: "Vaultedness", // description: "", // unit: "", // bottom: [ // { // title: "Vaultedness", // color: colors.vaultedness, // datasetPath: `${scale}-to-vaultedness`, // }, // ], // }, // { // scale, // name: "Versus", // title: "Liveliness V. Vaultedness", // description: "", // unit: "", // bottom: [ // { // title: "Liveliness", // color: colors.liveliness, // datasetPath: `${scale}-to-liveliness`, // }, // { // title: "Vaultedness", // color: colors.vaultedness, // datasetPath: `${scale}-to-vaultedness`, // }, // ], // }, // { // scale, // name: "Activity To Vaultedness Ratio", // title: "Activity To Vaultedness Ratio", // description: "", // unit: "Percentage", // bottom: [ // { // title: "Activity To Vaultedness Ratio", // color: colors.activityToVaultednessRatio, // datasetPath: `${scale}-to-activity-to-vaultedness-ratio`, // }, // ], // }, // ...(scale === "date" // ? /** @satisfies {PartialOptionsTree} */ ([ // { // scale, // name: "Concurrent Liveliness - Supply Adjusted Coindays Destroyed", // title: // "Concurrent Liveliness - Supply Adjusted Coindays Destroyed", // description: "", // unit: "", // bottom: [ // { // title: "Concurrent Liveliness 14d Median", // color: colors.liveliness, // datasetPath: `${scale}-to-concurrent-liveliness-2w-median`, // }, // { // title: "Concurrent Liveliness", // color: colors.offLiveliness, // datasetPath: `${scale}-to-concurrent-liveliness`, // }, // ], // }, // { // scale, // name: "Liveliness Incremental Change", // title: "Liveliness Incremental Change", // description: "", // unit: "", // bottom: [ // { // title: "Liveliness Incremental Change", // color: colors.offLiveliness, // type: "Baseline", // datasetPath: `date-to-liveliness-net-change`, // }, // { // title: "Liveliness Incremental Change 14 Day Median", // color: colors.liveliness, // type: "Baseline", // datasetPath: `date-to-liveliness-net-change-2w-median`, // }, // bases[0]("date"), // ], // }, // ]) // : []), // ], // }, // { // name: "Supply", // tree: [ // { // scale, // name: "Vaulted", // title: "Vaulted Supply", // description: "", // unit: "Bitcoin", // bottom: [ // { // title: "Vaulted Supply", // color: colors.vaultedness, // datasetPath: `${scale}-to-vaulted-supply`, // }, // ], // }, // { // scale, // name: "Active", // title: "Active Supply", // description: "", // unit: "Bitcoin", // bottom: [ // { // title: "Active Supply", // color: colors.liveliness, // datasetPath: `${scale}-to-active-supply`, // }, // ], // }, // { // scale, // name: "Vaulted V. Active", // title: "Vaulted V. Active", // description: "", // unit: "Bitcoin", // bottom: [ // { // title: "Circulating Supply", // color: colors.coinblocksCreated, // datasetPath: `${scale}-to-supply`, // }, // { // title: "Vaulted Supply", // color: colors.vaultedness, // datasetPath: `${scale}-to-vaulted-supply`, // }, // { // title: "Active Supply", // color: colors.liveliness, // datasetPath: `${scale}-to-active-supply`, // }, // ], // }, // // TODO: Fix, Bad data // // { // // id: 'asymptomatic-supply-regions', // // name: 'Asymptomatic Supply Regions', // // title: 'Asymptomatic Supply Regions', // // description: '', // // applyPreset(params) { // // return applyMultipleSeries({ // // ...params, // // priceScaleOptions: { // // halved: true, // // }, // // list: [ // // { // // id: 'min-vaulted', // // title: 'Min Vaulted Supply', // // color: colors.vaultedness, // // dataset: params.`/${scale}-to-dateToMinVaultedSupply, // // }, // // { // // id: 'max-active', // // title: 'Max Active Supply', // // color: colors.liveliness, // // dataset: params.`/${scale}-to-dateToMaxActiveSupply, // // }, // // ], // // }) // // }, // // }, // { // scale, // name: "Vaulted Net Change", // title: "Vaulted Supply Net Change", // description: "", // unit: "Bitcoin", // bottom: [ // { // title: "Vaulted Supply Net Change", // color: colors.vaultedness, // datasetPath: `${scale}-to-vaulted-supply-net-change`, // }, // ], // }, // { // scale, // name: "Active Net Change", // title: "Active Supply Net Change", // description: "", // unit: "Bitcoin", // bottom: [ // { // title: "Active Supply Net Change", // color: colors.liveliness, // datasetPath: `${scale}-to-active-supply-net-change`, // }, // ], // }, // { // scale, // name: "Active VS. Vaulted 90D Net Change", // title: "Active VS. Vaulted 90 Day Supply Net Change", // description: "", // unit: "Bitcoin", // bottom: [ // { // title: "Active Supply Net Change", // color: colors.liveliness, // datasetPath: `${scale}-to-active-supply-3m-net-change`, // type: "Baseline", // }, // { // title: "Vaulted Supply Net Change", // color: colors.vaultedPrice, // type: "Baseline", // datasetPath: `${scale}-to-vaulted-supply-3m-net-change`, // }, // bases[0](scale), // ], // }, // // TODO: Fix, Bad data // // { // // id: 'vaulted-supply-annualized-net-change', // // name: 'Vaulted Annualized Net Change', // // title: 'Vaulted Supply Annualized Net Change', // // description: '', // // applyPreset(params) { // // return applyMultipleSeries({ // // ...params, // // priceScaleOptions: { // // halved: true, // // }, // // list: [ // // { // // id: 'vaulted-annualized-supply-net-change', // // title: 'Vaulted Supply Annualized Net Change', // // color: colors.vaultedness, // // dataset: // // `/${scale}-to-vaultedAnnualizedSupplyNetChange, // // }, // // ], // // }) // // }, // // }, // // TODO: Fix, Bad data // // { // // id: 'vaulting-rate', // // name: 'Vaulting Rate', // // title: 'Vaulting Rate', // // description: '', // // applyPreset(params) { // // return applyMultipleSeries({ // // ...params, // // priceScaleOptions: { // // halved: true, // // }, // // list: [ // // { // // id: 'vaulting-rate', // // title: 'Vaulting Rate', // // color: colors.vaultedness, // // dataset: `${scale}-to-vaultingRate, // // }, // // { // // id: 'nominal-inflation-rate', // // title: 'Nominal Inflation Rate', // // color: colors.orange, // // dataset: params.`/${scale}-to-dateToYearlyInflationRate, // // }, // // ], // // }) // // }, // // }, // // TODO: Fix, Bad data // // { // // id: 'active-supply-net-change-decomposition', // // name: 'Active Supply Net Change Decomposition (90D)', // // title: 'Active Supply Net 90 Day Change Decomposition', // // description: '', // // applyPreset(params) { // // return applyMultipleSeries({ // // ...params, // // priceScaleOptions: { // // halved: true, // // }, // // list: [ // // { // // id: 'issuance-change', // // title: 'Change From Issuance', // // color: colors.emerald, // // dataset: // // params.params.datasets[scale] // // [scale].activeSupplyChangeFromIssuance90dChange, // // }, // // { // // id: 'transactions-change', // // title: 'Change From Transactions', // // color: colors.rose, // // dataset: // // params.params.datasets[scale] // // [scale].activeSupplyChangeFromTransactions90dChange, // // }, // // // { // // // id: 'active', // // // title: 'Active Supply', // // // color: colors.liveliness, // // // dataset: `${scale}-to-activeSupply, // // // }, // // ], // // }) // // }, // // }, // { // scale, // name: "In Profit", // title: "Cointime Supply In Profit", // description: "", // unit: "Bitcoin", // bottom: [ // { // title: "Circulating Supply", // color: colors.coinblocksCreated, // datasetPath: `${scale}-to-supply`, // }, // { // title: "Vaulted Supply", // color: colors.vaultedness, // datasetPath: `${scale}-to-vaulted-supply`, // }, // { // title: "Supply in profit", // color: colors.bitcoin, // datasetPath: `${scale}-to-supply-in-profit`, // }, // ], // }, // { // scale, // name: "In Loss", // title: "Cointime Supply In Loss", // description: "", // unit: "Bitcoin", // bottom: [ // { // title: "Circulating Supply", // color: colors.coinblocksCreated, // datasetPath: `${scale}-to-supply`, // }, // { // title: "Active Supply", // color: colors.liveliness, // datasetPath: `${scale}-to-active-supply`, // }, // { // title: "Supply in Loss", // color: colors.bitcoin, // datasetPath: `${scale}-to-supply-in-loss`, // }, // ], // }, // ], // }, // ...(scale === "date" // ? /** @satisfies {PartialOptionsTree} */ ([ // { // name: "Inflation Rate", // tree: [ // { // scale, // name: "Normal", // title: "Cointime Yearly Inflation Rate", // description: "", // unit: "Percentage", // bottom: [ // { // title: "Cointime Adjusted", // color: colors.coinblocksCreated, // datasetPath: `date-to-cointime-adjusted-inflation-rate`, // }, // { // title: "Nominal", // color: colors.bitcoin, // datasetPath: `date-to-inflation-rate`, // }, // ], // }, // { // scale, // name: "Yearly", // title: "Cointime-Adjusted Yearly Inflation Rate", // description: "", // unit: "Percentage", // bottom: [ // { // title: "Cointime Adjusted", // color: colors.coinblocksCreated, // datasetPath: `date-to-cointime-adjusted-yearly-inflation-rate`, // }, // { // title: "Nominal", // color: colors.bitcoin, // datasetPath: `date-to-yearly-inflation-rate`, // }, // ], // }, // ], // }, // { // scale, // name: "Cointime Velocity", // title: "Cointime-Adjusted Transactions Velocity", // description: "", // unit: "", // bottom: [ // { // title: "Cointime Adjusted", // color: colors.coinblocksCreated, // datasetPath: `date-to-cointime-adjusted-velocity`, // }, // { // title: "Nominal", // color: colors.bitcoin, // datasetPath: `date-to-transaction-velocity`, // }, // ], // }, // ]) // : []), // ], // }; // } // /** // * @param {TimeScale} scale // * @returns {PartialOptionsGroup} // */ // function createResearchOptions(scale) { // return { // name: "Research", // tree: [createCointimeOptions(scale)], // }; // } return [ { name: "Charts", tree: [ // name: "Market", // tree: [ { name: "Price", title: "Bitcoin Price in US Dollars", }, { name: "Blocks", tree: [ { name: "Block Interval", bottom: [ { key: "block-interval", title: "Interval", color: colors.bitcoin, }, { key: "block-interval-average", title: "Average", color: colors.orange, }, { key: "block-interval-median", title: "Median", color: colors.amber, defaultActive: false, }, { key: "block-interval-75p", title: "75p", color: colors.red, defaultActive: false, }, { key: "block-interval-25p", title: "25p", color: colors.yellow, defaultActive: false, }, { key: "block-interval-90p", title: "90p", color: colors.rose, defaultActive: false, }, { key: "block-interval-10p", title: "10p", color: colors.lime, defaultActive: false, }, { key: "block-interval-max", title: "Max", color: colors.pink, defaultActive: false, }, { key: "block-interval-min", title: "Min", color: colors.green, defaultActive: false, }, ], }, ], }, // { // scale, // name: "Satoshis Per Dollar", // title: "Satoshis Per Dollar", // description: "", // unit: "Satoshis", // bottom: [ // { // title: "Satoshis", // datasetPath: `${scale}-to-sats-per-dollar`, // color: colors.bitcoin, // }, // ], // }, // { // name: "By Date", // tree: [ // createMarketOptions("date"), // // createBlocksOptions("date"), // // createMinersOptions("date"), // // createTransactionsOptions("date"), // // ...createCohortOptions({ // // scale: "date", // // color: colors.bitcoin, // // datasetId: "", // // name: "", // // title: "", // // }), // // createHodlersOptions("date"), // // createAddressesOptions("date"), // // createResearchOptions("date"), // ], // }, // { // name: "By Height", // tree: [ // createMarketOptions("height"), // // createBlocksOptions("height"), // // createMinersOptions("height"), // // createTransactionsOptions("height"), // // ...createCohortOptions({ // // scale: "height", // // color: colors.bitcoin, // // datasetId: "", // // name: "", // // title: "", // // }), // // createHodlersOptions("height"), // // createAddressesOptions("height"), // // createResearchOptions("height"), // ], // }, ], }, { name: "Simulations", tree: [ { kind: "simulation", title: "Save In Bitcoin", name: "Save In Bitcoin", }, ], }, { name: "Social", tree: [ { name: "Nostr", url: () => "https://primal.net/p/npub1jagmm3x39lmwfnrtvxcs9ac7g300y3dusv9lgzhk2e4x5frpxlrqa73v44", }, { name: "Discord", url: () => "https://discord.com/invite/Cvrwpv3zEG", }, { name: "Bluesky", url: () => "https://bsky.app/profile/bitcoinresearchkit.org", }, ], }, { name: "Developers", tree: [ { name: "API", url: () => "/api", }, { name: "Github", url: () => "https://github.com/bitcoinresearchkit/brk", }, ], }, { name: "Donations", tree: [ { name: "Bitcoin QR Code", qrcode: true, url: () => "bitcoin:bc1q098zsm89m7kgyze338vfejhpdt92ua9p3peuve", }, { name: "Lightning QR Code", qrcode: true, url: () => "lightning:lnurl1dp68gurn8ghj7ampd3kx2ar0veekzar0wd5xjtnrdakj7tnhv4kxctttdehhwm30d3h82unvwqhkxmmww3jkuar8d35kgetj8yuq363hv4", }, { name: "Geyser", url: () => "https://geyser.fund/project/brk", }, { name: "OpenSats", url: () => "https://opensats.org/", }, ], }, { name: "Share", qrcode: true, url: () => window.location.href, }, ]; } /** * @param {Object} args * @param {Colors} args.colors * @param {Signals} args.signals * @param {Env} args.env * @param {Utilities} args.utils * @param {WebSockets} args.webSockets * @param {Signal} args.qrcode */ export function initOptions({ colors, signals, env, utils, webSockets, qrcode, }) { const LS_SELECTED_KEY = `selected-id`; const urlSelected = utils.url.pathnameToSelectedId(); const savedSelectedId = localStorage.getItem(LS_SELECTED_KEY); /** @type {Signal