Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | 82x 14x 45x 45x 90x 90x 90x 36x 36x 30x 54x 43x 45x 6x 36x 90x 90x 36x 12x 36x 15x 3x 15x 30x 12x 31x 31x 1x 30x 30x 30x 60x 20x 20x 1x 19x 19x 19x 19x 19x 19x 19x 14x 14x 14x 7x | import { type AutocompleteItemType } from './components/autocomplete-item';
export function getLastIndexOfSubstringIgnoreCase(
string: string,
substring: string
) {
return string.toLowerCase().lastIndexOf(substring.toLowerCase());
}
export type BasicItem<Item> = {
label?: string;
id: string;
tags?: string[];
items?: BasicItem<Item>[];
};
export const getNodePaths = <Item extends BasicItem<Item>>(
items: Item[],
id?: string,
path: Item[] = []
) => {
let nodePaths: Omit<Item, 'items'>[][] = [];
items.forEach((node) => {
const { items, ...thisNode } = node;
const nodePath = [...path, thisNode];
if (items) {
const result = getNodePaths(items, id, nodePath) as Omit<
Item,
'items'
>[][];
if (result.length) {
nodePaths = [...nodePaths, ...result];
}
} else if (!id || thisNode.id === id) {
nodePaths = [...nodePaths, nodePath];
}
});
return nodePaths;
};
export function prepareTreeDataForAutocomplete<Item extends BasicItem<Item>>(
flattenedTreeData: Item[][]
) {
return flattenedTreeData.map((items) => {
const autocompleteItem: AutocompleteItemType = {
id: items[items.length - 1].id,
pathLabel: items.map((item) => item.label).join(' / '),
itemLabel: items[items.length - 1].label || items[items.length - 1].id,
};
const tags = items.flatMap((item) => item.tags || []);
if (tags.length) {
autocompleteItem.tags = tags;
}
return autocompleteItem;
});
}
export function* getSingleChildren<Item extends BasicItem<Item>>(
children: Item[]
): Generator<string, void, never> {
if (children.length === 1) {
yield children[0].id;
}
for (const child of children) {
if (child.items) {
yield* getSingleChildren(child.items);
}
}
}
export function formatLargeNumber(x: string | number) {
const string = x.toString();
// If number is converted to scientific notation return as is
// because commas can't be added as the coefficient will be < 10
if (string.includes('e')) {
return string;
}
const [integer, decimal] = x.toString().split('.');
const integerWithCommas = integer.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
return [integerWithCommas, decimal]
.filter((el) => typeof el !== 'undefined')
.join('.');
}
export function formatBytesNumber(bytes: string | number, decimals = 0) {
const bytesNumber = +bytes;
if (!bytesNumber) {
return '0 Bytes';
}
const positiveDecimals = decimals < 0 ? 0 : decimals;
const baseFactor = 1024;
const units = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
const unitsIndex = Math.min(
Math.floor(Math.log(bytesNumber) / Math.log(baseFactor)),
units.length - 1
);
const number = (bytesNumber / baseFactor ** unitsIndex).toFixed(
positiveDecimals
);
const unit = units[unitsIndex];
return `${formatLargeNumber(parseFloat(number))} ${unit}`;
}
const reProtocol = /^(https?:)?(\/\/)?/;
const reTrailingSlashes = /(\/+$)/;
export const tidyUrlString = (url: string) =>
url.replace(reProtocol, '').replace(reTrailingSlashes, '');
|