git: reset

This commit is contained in:
k
2024-06-23 17:38:53 +02:00
commit a1a576d088
375 changed files with 40952 additions and 0 deletions

View File

@@ -0,0 +1,16 @@
export function sortedInsert(array: number[], value: number) {
let low = 0;
let high = array.length;
while (low < high) {
const mid = (low + high) >>> 1;
if (array[mid] < value) {
low = mid + 1;
} else {
high = mid;
}
}
array.splice(low, 0, value);
}

View File

@@ -0,0 +1,246 @@
import {
amber as amberTailwind,
blue as blueTailwind,
cyan as cyanTailwind,
emerald as emeraldTailwind,
fuchsia as fuchsiaTailwind,
neutral as grayTailwind,
green as greenTailwind,
indigo as indigoTailwind,
lime as limeTailwind,
orange as orangeTailwind,
pink as pinkTailwind,
purple as purpleTailwind,
red as redTailwind,
rose as roseTailwind,
sky as skyTailwind,
teal as tealTailwind,
violet as violetTailwind,
yellow as yellowTailwind,
} from "tailwindcss/colors";
// ---
// DO NOT USE TRANSPARENCY HERE
// DO NOT USE TRANSPARENCY HERE
// DO NOT USE TRANSPARENCY HERE
// DO NOT USE TRANSPARENCY HERE
// DO NOT USE TRANSPARENCY HERE
// DO NOT USE TRANSPARENCY HERE
// DO NOT USE TRANSPARENCY HERE
// DO NOT USE TRANSPARENCY HERE
// DO NOT USE TRANSPARENCY HERE
// DO NOT USE TRANSPARENCY HERE
// DO NOT USE TRANSPARENCY HERE
// DO NOT USE TRANSPARENCY HERE
// DO NOT USE TRANSPARENCY HERE
// DO NOT USE TRANSPARENCY HERE
// DO NOT USE TRANSPARENCY HERE
// DO NOT USE TRANSPARENCY HERE
// DO NOT USE TRANSPARENCY HERE
// DO NOT USE TRANSPARENCY HERE
// DO NOT USE TRANSPARENCY HERE
// ---
const lightRed = redTailwind[300];
const red = redTailwind[500];
const darkRed = redTailwind[900];
const orange = orangeTailwind[500];
const darkOrange = orangeTailwind[900];
const amber = amberTailwind[500];
const darkAmber = amberTailwind[900];
const yellow = yellowTailwind[500];
const darkYellow = yellowTailwind[500];
const lime = limeTailwind[500];
const darkLime = limeTailwind[900];
const green = greenTailwind[500];
const darkGreen = greenTailwind[900];
const lightEmerald = emeraldTailwind[300];
const emerald = emeraldTailwind[500];
const darkEmerald = emeraldTailwind[900];
const teal = tealTailwind[500];
const darkTeal = tealTailwind[900];
const cyan = cyanTailwind[500];
const darkCyan = cyanTailwind[900];
const sky = skyTailwind[500];
const darkSky = skyTailwind[900];
const blue = blueTailwind[500];
const darkBlue = blueTailwind[900];
const indigo = indigoTailwind[500];
const darkIndigo = indigoTailwind[900];
const violet = violetTailwind[500];
const darkViolet = violetTailwind[900];
const purple = purpleTailwind[500];
const darkPurple = purpleTailwind[900];
const fuchsia = fuchsiaTailwind[500];
const darkFuchsia = fuchsiaTailwind[900];
const pink = pinkTailwind[500];
const darkPink = pinkTailwind[900];
const rose = roseTailwind[500];
const darkRose = roseTailwind[900];
const darkWhite = grayTailwind[400];
const gray = grayTailwind[600];
const black = "#000000";
const white = "#ffffff";
export const convertCandleToCandleColor = (
candle: { close: number; open: number },
inverse?: boolean,
) =>
(candle.close || 1) > (candle.open || 0)
? !inverse
? green
: red
: !inverse
? red
: green;
export const convertCandleToVolumeColor = (
candle: { close: number; open: number },
inverse?: boolean,
) =>
(candle.close || 1) > (candle.open || 0)
? !inverse
? darkGreen
: darkRed
: !inverse
? darkRed
: darkGreen;
export const colors = {
white,
darkWhite,
gray,
lightBitcoin: yellow,
bitcoin: orange,
darkBitcoin: darkOrange,
lightDollars: lime,
dollars: emerald,
darkDollars: darkEmerald,
_1d: lightRed,
_1w: red,
_8d: orange,
_13d: amber,
_21d: yellow,
_1m: lime,
_34d: green,
_55d: emerald,
_89d: teal,
_144d: cyan,
_6m: sky,
_1y: blue,
_2y: indigo,
_200w: violet,
_4y: purple,
_10y: fuchsia,
p2pk: lime,
p2pkh: violet,
p2sh: emerald,
p2wpkh: cyan,
p2wsh: pink,
p2tr: blue,
crab: red,
fish: lime,
humpback: violet,
plankton: emerald,
shark: cyan,
shrimp: pink,
whale: blue,
megalodon: purple,
realizedPrice: orange,
oneMonthHolders: cyan,
threeMonthsHolders: lime,
sth: yellow,
sixMonthsHolder: red,
oneYearHolders: pink,
twoYearsHolders: purple,
lth: fuchsia,
balancedPrice: yellow,
cointimePrice: yellow,
trueMarketMeanPrice: blue,
vaultedPrice: green,
cvdd: lime,
terminalPrice: red,
loss: red,
darkLoss: darkRed,
profit: green,
darkProfit: darkGreen,
thermoCap: green,
investorCap: rose,
realizedCap: orange,
ethereum: indigo,
usdt: emerald,
usdc: blue,
ust: red,
busd: yellow,
usdd: emerald,
frax: gray,
dai: amber,
tusd: indigo,
pyusd: blue,
darkLiveliness: darkRose,
liveliness: rose,
vaultedness: green,
activityToVaultednessRatio: violet,
up_to_1d: lightRed,
up_to_1w: red,
up_to_1m: orange,
up_to_2m: orange,
up_to_3m: orange,
up_to_4m: orange,
up_to_5m: orange,
up_to_6m: orange,
up_to_1y: orange,
up_to_2y: orange,
up_to_3y: orange,
up_to_4y: orange,
up_to_5y: orange,
up_to_7y: orange,
up_to_10y: orange,
up_to_15y: orange,
from_10y_to_15y: purple,
from_7y_to_10y: violet,
from_5y_to_7y: indigo,
from_3y_to_5y: sky,
from_2y_to_3y: teal,
from_1y_to_2y: green,
from_6m_to_1y: lime,
from_3m_to_6m: yellow,
from_1m_to_3m: amber,
from_1w_to_1m: orange,
from_1d_to_1w: red,
from_1y: green,
from_2y: teal,
from_4y: indigo,
from_10y: violet,
from_15y: fuchsia,
coinblocksCreated: purple,
coinblocksDestroyed: red,
coinblocksStored: green,
momentum: [green, yellow, red],
momentumGreen: green,
momentumYellow: yellow,
momentumRed: red,
extremeMax: red,
extremeMiddle: orange,
extremeMin: yellow,
year_2009: yellow,
year_2010: yellow,
year_2011: yellow,
year_2012: yellow,
year_2013: yellow,
year_2014: yellow,
year_2015: yellow,
year_2016: yellow,
year_2017: yellow,
year_2018: yellow,
year_2019: yellow,
year_2020: yellow,
year_2021: yellow,
year_2022: yellow,
year_2023: yellow,
year_2024: yellow,
};

View File

@@ -0,0 +1,10 @@
// import { ONE_DAY_IN_MS } from "./time";
import { ONE_DAY_IN_MS } from "./time";
export const dateToString = (date: Date) => date.toJSON().split("T")[0];
// export const FIVE_MONTHS_IN_DAYS = 30 * 5;
export const getNumberOfDaysBetweenTwoDates = (oldest: Date, youngest: Date) =>
Math.round(Math.abs((youngest.valueOf() - oldest.valueOf()) / ONE_DAY_IN_MS));

View File

@@ -0,0 +1,19 @@
export const debounce = <F extends (...args: any[]) => any>(
callback: F,
wait = 250,
) => {
let timeoutId: number | undefined;
let latestArgs: Parameters<F>;
return (...args: Parameters<F>) => {
latestArgs = args;
if (!timeoutId) {
timeoutId = window.setTimeout(async () => {
await callback(...latestArgs);
timeoutId = undefined;
}, wait);
}
};
};

View File

@@ -0,0 +1,12 @@
export function replaceHistory({
urlParams,
pathname,
}: {
urlParams?: URLSearchParams;
pathname?: string;
}) {
urlParams ||= new URLSearchParams(window.location.search);
pathname ||= window.location.pathname;
window.history.replaceState(null, "", `${pathname}?${urlParams.toString()}`);
}

View File

@@ -0,0 +1,3 @@
export function stringToId(s: string) {
return s.replace(/\W/g, " ").trim().replace(/ +/g, "-").toLowerCase();
}

View File

@@ -0,0 +1,31 @@
export const priceToUSLocale = (price: number, compact = true) => {
const absolutePrice = Math.abs(price);
const lessThan100 = absolutePrice < 100;
const lessThan1000 = absolutePrice < 1_000;
const biggerThanMillion = absolutePrice >= 1_000_000;
return numberToUSLocale(
price,
lessThan1000 ? (lessThan100 ? 2 : 1) : biggerThanMillion ? 3 : 0,
biggerThanMillion && compact
? {
notation: "compact",
compactDisplay: "short",
}
: undefined,
);
};
export const percentageToUSLocale = (percentage: number) =>
numberToUSLocale(percentage, 1);
const numberToUSLocale = (
value: number,
digits: number,
options?: Intl.NumberFormatOptions | undefined,
) =>
value.toLocaleString("en-us", {
...options,
minimumFractionDigits: digits,
maximumFractionDigits: digits,
});

View File

@@ -0,0 +1,22 @@
import { computeSum } from "./sum";
export const computeAverage = (values: number[]) =>
computeSum(values) / values.length;
export const computeMovingAverage = <
T extends SingleValueData = SingleValueData,
>(
dataset: T[],
interval: number,
) => {
if (!dataset.length) return [];
return dataset.map((data, index) => ({
...data,
value: computeAverage(
dataset
.slice(Math.max(index - interval + 1, 0), index + 1)
.map((data) => data.value || 1),
),
}));
};

View File

@@ -0,0 +1,5 @@
export function random<T>(array: T[]) {
if (array && array.length) {
return array[Math.floor(Math.random() * array.length)];
}
}

View File

@@ -0,0 +1,4 @@
export const roundValue = (value: number, decimals = 5) => {
const tenPowerX = 10 ** decimals;
return Math.round(value * tenPowerX) / tenPowerX;
};

View File

@@ -0,0 +1,2 @@
export const computeSum = (values: number[]) =>
values.reduce((total, currentValue) => total + currentValue, 0);

View File

@@ -0,0 +1 @@
export const run = <T>(f: () => T) => f();

View File

@@ -0,0 +1,9 @@
export const scrollIntoView = (
element?: HTMLElement | Element | null,
block: ScrollLogicalPosition = "nearest",
behavior: ScrollBehavior = "instant",
) =>
element?.scrollIntoView({
block,
behavior,
});

View File

@@ -0,0 +1,119 @@
import { createRWS } from "/src/solid/rws";
export const createSelectableList = <T, L extends T[] = T[]>(
list: L,
parameters?: {
selected?: L[number];
selectedIndex?: number | null;
},
) => {
const selected = createRWS<L[number] | null>(null);
const selectedIndex = createRWS<number | null>(null);
const selectableList: SelectableList<L[number], L> = {
selected,
selectedIndex,
list: createRWS(list, {
equals: false,
}),
select(s) {
if (this.selected() !== s) {
batch(() => {
selected.set(() => s);
this.selectIndex(this.list().indexOf(s) ?? null);
});
}
},
resetSelected() {
selected.set(null);
selectedIndex.set(null);
},
selectFind(search, callback) {
const element = this.list().find(
(_element) => callback(_element) === search,
);
if (element) {
this.select(element);
}
return element;
},
selectIndex(i) {
i = i === -1 ? null : i;
if (i && (i < 0 || i >= this.list().length)) {
throw new Error(
`SelectableList: selectIndex: ${i} is incorrect ! (has ${
this.list().length
} elements)`,
);
}
if (i !== this.selectedIndex()) {
selectedIndex.set(i);
const value = getValueFromIndexInList<L[number]>(i, this.list());
if (value !== null) {
this.select(value);
}
}
},
push(value) {
this.list.set((l) => {
l.push(value);
return l;
});
},
pushAndSelect(value) {
batch(() => {
this.push(value);
this.select(value);
});
},
removeIndex(index) {
let value = null;
this.list.set((l) => {
value = l.splice(index, 1)?.[0];
return l;
});
return value;
},
toJSON<TJSON, LJSON extends TJSON[] = TJSON[]>(
transform: (value: T) => TJSON,
filter?: (value: T) => boolean,
): JSONSelectableList<TJSON, LJSON> {
return {
version: 1,
selectedIndex: getIndexOfSelectedInSelectableList(this),
list: (filter ? this.list().filter(filter) : this.list()).map((value) =>
transform(value),
) as LJSON,
};
},
};
if (parameters?.selected !== undefined) {
selectableList.select(parameters.selected);
} else if (parameters?.selectedIndex !== undefined) {
selectableList.selectIndex(parameters.selectedIndex);
}
return selectableList;
};
export const createSL = createSelectableList;
export const getIndexOfSelectedInSelectableList = <T, L extends T[] = T[]>(
sl: SelectableList<L[number], L>,
) => {
const selected = sl.selected();
return selected ? sl.list().indexOf(selected) : null;
};
const getValueFromIndexInList = <T, L extends T[] = T[]>(
index: number | null,
list: L,
) => (index !== null && list.length > 0 ? list.at(index) || list[0] : null);

View File

@@ -0,0 +1,33 @@
// ---
// JSON
// ---
interface JSONSelectableList<T, L extends T[] = T[]> {
readonly version: 1;
selectedIndex: number | null;
readonly list: L;
}
// ---
// Object
// ---
interface SelectableList<T, L extends T[] = T[]> {
readonly selected: Accessor<T | null>;
readonly selectedIndex: Accessor<number | null>;
readonly list: RWS<L>;
readonly select: <S extends L[number] = L[number]>(s: S) => void;
readonly selectFind: <K>(
search: K,
callback: (element: T) => K,
) => T | undefined;
readonly selectIndex: (i: number | null) => void;
readonly push: <S extends L[number] = L[number]>(s: S) => void;
readonly pushAndSelect: <S extends L[number] = L[number]>(s: S) => void;
readonly removeIndex: (i: number) => L[number] | null;
readonly resetSelected: VoidFunction;
readonly toJSON: <TJSON, LJSON extends TJSON[] = TJSON[]>(
transform: (value: T) => LJSON[number],
filter?: (value: T) => boolean,
) => JSONSelectableList<TJSON, LJSON>;
}

View File

@@ -0,0 +1,9 @@
export function sleep(ms: number) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
export function tick() {
return sleep(1);
}

View File

@@ -0,0 +1,19 @@
export function saveToStorage(key?: string, value?: string | boolean) {
if (key) {
value !== undefined && value !== null
? localStorage.setItem(key, String(value))
: localStorage.removeItem(key);
}
}
export function readBooleanFromStorage(key: string) {
const saved = localStorage.getItem(key);
if (saved) {
return isSerializedBooleanTrue(saved);
}
return null;
}
export function isSerializedBooleanTrue(serialized: string) {
return serialized === "true" || serialized === "1";
}

View File

@@ -0,0 +1,8 @@
export const ONE_SECOND_IN_MS = 1_000;
export const FIVE_SECOND_IN_MS = 5 * ONE_SECOND_IN_MS;
export const TEN_SECOND_IN_MS = 2 * FIVE_SECOND_IN_MS;
export const ONE_MINUTE_IN_MS = 6 * TEN_SECOND_IN_MS;
export const FIVE_MINUTES_IN_MS = 5 * ONE_MINUTE_IN_MS;
export const TEN_MINUTES_IN_MS = 2 * FIVE_MINUTES_IN_MS;
export const ONE_HOUR_IN_MS = 6 * TEN_MINUTES_IN_MS;
export const ONE_DAY_IN_MS = 24 * ONE_HOUR_IN_MS;

View File

@@ -0,0 +1,40 @@
import { replaceHistory } from "./history";
import { isSerializedBooleanTrue } from "./storage";
const whitelist = ["from", "to"];
export function resetURLParams() {
const urlParams = new URLSearchParams();
[...new URLSearchParams(window.location.search).entries()]
.filter(([key, _]) => whitelist.includes(key))
.forEach(([key, value]) => {
urlParams.set(key, value);
});
replaceHistory({ urlParams });
}
export function writeURLParam(key: string, value?: string | boolean) {
const urlParams = new URLSearchParams(window.location.search);
if (value !== undefined) {
urlParams.set(key, String(value));
} else {
urlParams.delete(key);
}
replaceHistory({ urlParams });
}
export function readBooleanURLParam(key: string) {
const urlParams = new URLSearchParams(window.location.search);
const parameter = urlParams.get(key);
if (parameter) {
return isSerializedBooleanTrue(parameter);
}
return null;
}