import type { CanvasContent } from '~/types/canvas'; import type { ContentMap, FileType } from '~/types/content'; export const DEFAULT_CONTENT: Record = { map: {}, canvas: { nodes: [], edges: []}, markdown: '', file: '', folder: null, } export function unifySlug(slug: string | string[]): string { return (Array.isArray(slug) ? slug.join('/') : slug); } export function group< T, K extends keyof T, V extends keyof T, KeyType extends string | number | symbol = Extract >( table: T[], key: K & (T[K] extends string | number | symbol ? K : never), value: V ): Record { return table.reduce((p, v) => { p[v[key] as KeyType] = v[value]; return p; }, {} as Record); } export function parsePath(path: string): string { return path.toLowerCase().trim().replaceAll(" ", "-").normalize("NFD").replaceAll(/[\u0300-\u036f]/g, "").replaceAll('(', '').replaceAll(')', ''); } export function parseId(id: string | undefined): string | undefined { return id; return id?.normalize('NFD')?.replace(/[\u0300-\u036f]/g, '')?.replace(/^\d\. */g, '')?.replace(/\s/g, "-")?.replace(/%/g, "-percent")?.replace(/\?/g, "-q")?.toLowerCase(); } export function padLeft(text: string, pad: string, length: number): string { return text.concat(pad.repeat(length - text.length)); } export function padRight(text: string, pad: string, length: number): string { return pad.repeat(length - text.length).concat(text); } export function format(date: Date, template: string): string { const transforms: Record string> = { "yyyy": (date: Date) => date.getUTCFullYear().toString(), "MM": (date: Date) => padRight((date.getUTCMonth() + 1).toString(), '0', 2), "dd": (date: Date) => padRight(date.getUTCDate().toString(), '0', 2), "mm": (date: Date) => padRight(date.getUTCMinutes().toString(), '0', 2), "HH": (date: Date) => padRight(date.getUTCHours().toString(), '0', 2), "ss": (date: Date) => padRight(date.getUTCSeconds().toString(), '0', 2), }; const keys = Object.keys(transforms); for(const key of keys) { template = template.replaceAll(key, () => transforms[key](date)); } return template; } export function clamp(x: number, min: number, max: number): number { return x > max ? max : x < min ? min : x; } export function lerp(x: number, a: number, b: number): number { return (1-x)*a+x*b; } export function convertContentFromText(type: FileType, content: string): CanvasContent | string { switch(type) { case 'canvas': return JSON.parse(content) as CanvasContent; case 'map': case 'file': case 'folder': case 'markdown': return content; default: return content; } } export function convertContentToText(type: FileType, content: any): string { switch(type) { case 'canvas': return JSON.stringify(content); case 'map': case 'file': case 'folder': case 'markdown': return content; default: return content; } } export const iconByType: Record = { 'folder': 'lucide:folder', 'canvas': 'ph:graph-light', 'file': 'radix-icons:file', 'markdown': 'radix-icons:file-text', 'map': 'lucide:map', }