@isikk/core 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/index.cjs +12 -0
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +8 -1
  4. package/dist/index.d.ts +8 -1
  5. package/dist/index.js +10 -0
  6. package/dist/index.js.map +1 -1
  7. package/dist/next/config/browser.d.ts +18 -0
  8. package/dist/next/config/browser.js +54 -0
  9. package/dist/next/config/browser.js.map +1 -0
  10. package/dist/next/config/index.d.ts +30 -0
  11. package/dist/next/config/index.js +149 -0
  12. package/dist/next/config/index.js.map +1 -0
  13. package/dist/next/config/insert.d.ts +18 -0
  14. package/dist/next/config/insert.js +21 -0
  15. package/dist/next/config/insert.js.map +1 -0
  16. package/dist/next/middleware/index.cjs +22 -2
  17. package/dist/next/middleware/index.cjs.map +1 -1
  18. package/dist/next/middleware/index.d.cts +9 -1
  19. package/dist/next/middleware/index.d.ts +9 -1
  20. package/dist/next/middleware/index.js +22 -1
  21. package/dist/next/middleware/index.js.map +1 -1
  22. package/dist/next/request/index.cjs +51 -0
  23. package/dist/next/request/index.cjs.map +1 -0
  24. package/dist/next/request/index.d.cts +21 -0
  25. package/dist/next/request/index.d.ts +21 -0
  26. package/dist/next/request/index.js +25 -0
  27. package/dist/next/request/index.js.map +1 -0
  28. package/dist/next/session/index.cjs +51 -0
  29. package/dist/next/session/index.cjs.map +1 -0
  30. package/dist/next/session/index.d.cts +22 -0
  31. package/dist/next/session/index.d.ts +22 -0
  32. package/dist/next/session/index.js +26 -0
  33. package/dist/next/session/index.js.map +1 -0
  34. package/dist/node/index.cjs +56 -4
  35. package/dist/node/index.cjs.map +1 -1
  36. package/dist/node/index.d.cts +28 -8
  37. package/dist/node/index.d.ts +28 -8
  38. package/dist/node/index.js +56 -4
  39. package/dist/node/index.js.map +1 -1
  40. package/dist/shared-By0kkXDs.d.ts +31 -0
  41. package/package.json +20 -2
package/dist/index.cjs CHANGED
@@ -50,8 +50,10 @@ __export(src_exports, {
50
50
  optionalDate: () => optionalDate,
51
51
  preventDefault: () => preventDefault,
52
52
  raises: () => raises,
53
+ removeCookie: () => removeCookie,
53
54
  requireExclusiveKeys: () => requireExclusiveKeys,
54
55
  safeFileName: () => safeFileName,
56
+ setCookie: () => setCookie,
55
57
  setKeyValueToObjectIfValue: () => setKeyValueToObjectIfValue,
56
58
  shortFormattedDate: () => shortFormattedDate,
57
59
  shortFormattedDateTime: () => shortFormattedDateTime,
@@ -387,6 +389,14 @@ function getCookie(name) {
387
389
  }
388
390
  return void 0;
389
391
  }
392
+ function setCookie(name, value, options = {}) {
393
+ const { days, path = "/" } = options;
394
+ const expires = days === void 0 ? "" : `; expires=${new Date(Date.now() + days * 864e5).toUTCString()}`;
395
+ document.cookie = `${name}=${value}${expires}; path=${path}`;
396
+ }
397
+ function removeCookie(name, path = "/") {
398
+ document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=${path}`;
399
+ }
390
400
 
391
401
  // src/console/index.ts
392
402
  var patchedWindows = /* @__PURE__ */ new WeakMap();
@@ -542,8 +552,10 @@ function hexToHslTriplet(hex, precision = 1) {
542
552
  optionalDate,
543
553
  preventDefault,
544
554
  raises,
555
+ removeCookie,
545
556
  requireExclusiveKeys,
546
557
  safeFileName,
558
+ setCookie,
547
559
  setKeyValueToObjectIfValue,
548
560
  shortFormattedDate,
549
561
  shortFormattedDateTime,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/types/index.ts","../src/arrays/index.ts","../src/functions/index.ts","../src/objects/index.ts","../src/strings/index.ts","../src/dates/_format.ts","../src/dates/index.ts","../src/files/index.ts","../src/cookies/index.ts","../src/console/index.ts","../src/colors/index.ts"],"sourcesContent":["export * from './types'\nexport * from './arrays'\nexport * from './functions'\nexport * from './objects'\nexport * from './strings'\nexport * from './dates'\nexport * from './files'\nexport * from './cookies'\nexport * from './console'\nexport * from './colors'\n","export const getKeys = Object.keys as <T extends object>(obj: T) => Array<keyof T>\n\nexport type RecursivePartial<T> = { [P in keyof T]?: RecursivePartial<T[P]> }\n\nexport type RecursiveRecord = {\n [key: string]: string | number | boolean | RecursiveRecord | Array<RecursiveRecord>\n}\n\nexport function forcedType<T>(obj: unknown): T {\n return obj as unknown as T\n}\n","export function notNone<T>(value: T | null | undefined): value is T {\n return value !== null && value !== undefined\n}\n\nfunction combinationsOfSize<T>(items: T[], size: number): T[][] {\n if (size === 0) {\n return [[]]\n }\n if (size > items.length) {\n return []\n }\n const [first, ...rest] = items\n const withFirst = combinationsOfSize(rest, size - 1).map((combination) => [first, ...combination])\n const withoutFirst = combinationsOfSize(rest, size)\n return [...withFirst, ...withoutFirst]\n}\n\nexport function allCombinations<T>(options: T[]): T[][] {\n const result: T[][] = []\n for (let size = 1; size <= options.length; size++) {\n result.push(...combinationsOfSize(options, size))\n }\n return result\n}\n","export function withAttributes<Fn extends (...args: never[]) => unknown, Attrs extends Record<string, unknown>>(\n fn: Fn,\n attributes: Attrs\n): Fn & Attrs {\n for (const key of Object.keys(attributes)) {\n // Object.defineProperty (unlike a plain `fn[key] = value` assignment) always creates/\n // overwrites an own property, even when key is \"__proto__\" - a plain assignment would instead\n // be intercepted by Object.prototype's special __proto__ accessor and reassign fn's own\n // prototype instead of setting a property on it.\n Object.defineProperty(fn, key, {\n value: attributes[key],\n writable: true,\n configurable: true,\n enumerable: true,\n })\n }\n return fn as Fn & Attrs\n}\n\nexport function makeCallable<T, R>(originalCallable: (arg: T) => R) {\n return (data: T) => () => originalCallable(data)\n}\n\nexport function getLazyValue<T>(input: T | (() => T)): T {\n if (typeof input === 'function') {\n return (input as () => T)()\n }\n return input\n}\n\nexport async function getLazyValueAsync<T>(input: T | (() => Promise<T>) | (() => T)): Promise<T> {\n if (typeof input === 'function') {\n const result = (input as () => Promise<T>)()\n if (result instanceof Promise) {\n return await result\n }\n return result as unknown as T\n }\n return input\n}\n\nexport function suppress<T, ERT>(\n exceptions: Array<new (message?: string) => Error>,\n fn: () => T,\n onError?: (error: unknown) => ERT\n): T | ERT | undefined {\n try {\n return fn()\n } catch (error) {\n if (exceptions.some((exception) => error instanceof exception)) {\n return onError ? onError(error) : undefined\n }\n throw error\n }\n}\n\nexport function preventDefault<E extends Event, R>(callable: (event: E) => R): (event: E) => Promise<Awaited<R>> {\n return async function (event: E): Promise<Awaited<R>> {\n event.preventDefault()\n return await callable(event)\n }\n}\n\nexport function isPathMatched(pathname: string, pattern: RegExp, exemptPatterns: RegExp[] = []): boolean {\n if (exemptPatterns.some((exempt) => exempt.test(pathname))) {\n return false\n }\n return pattern.test(pathname)\n}\n\nexport function raises(error: Error): (...args: unknown[]) => never {\n return () => {\n throw error\n }\n}\n\nexport function cloned<Fn extends (...args: never[]) => unknown>(fn: Fn): Fn {\n return ((...args: Parameters<Fn>) => fn(...args)) as Fn\n}\n\nexport function enabledIf<R>(condition: boolean | (() => boolean), options: { ifNotEnabledReturnValue: R }) {\n const enabled = typeof condition === 'function' ? condition() : condition\n\n return function <Fn extends (...args: never[]) => R>(fn: Fn): Fn {\n if (!enabled) {\n return cloned((() => options.ifNotEnabledReturnValue) as Fn)\n }\n return cloned(fn)\n }\n}\n\nexport function transformExceptions<E extends Error>(\n exceptionTypes: Array<new (...args: never[]) => E>,\n transform: (error: E) => Error,\n options: { keepOriginal?: boolean } = {}\n) {\n const { keepOriginal = true } = options\n\n return function <Fn extends (...args: never[]) => unknown>(fn: Fn): Fn {\n return ((...args: Parameters<Fn>) => {\n try {\n return fn(...args)\n } catch (error) {\n if (!exceptionTypes.some((ExceptionType) => error instanceof ExceptionType)) {\n throw error\n }\n const newError = transform(error as E)\n if (keepOriginal) {\n newError.cause = error\n }\n throw newError\n }\n }) as Fn\n }\n}\n","export function checkRequiredKeys<T extends Record<string, unknown>, C extends Record<string, Array<keyof T>>>(\n obj: T,\n conditions: C\n): keyof C {\n const matchingConditions = Object.entries(conditions).filter(\n ([, keys]) =>\n keys.every((key) => obj[key] !== undefined) &&\n Object.keys(obj).every((key) => keys.includes(key as keyof T) || obj[key] === undefined)\n )\n\n if (matchingConditions.length !== 1) {\n throw new Error(`Object keys do not match exactly one required condition. ${JSON.stringify(conditions)}`)\n }\n\n return matchingConditions[0][0] as keyof C\n}\n\nexport function requireExclusiveKeys<T extends Record<string, unknown>, C extends Record<string, Array<keyof T>>>(\n conditions: C,\n options: { allowEmpty?: boolean } = {}\n) {\n const conditionEntries = Object.entries(conditions) as Array<[string, Array<keyof T>]>\n if (conditionEntries.length === 0) {\n throw new Error('At least one condition must be provided.')\n }\n const { allowEmpty = false } = options\n const governedKeys = new Set(conditionEntries.flatMap(([, keys]) => keys))\n\n return function <Fn extends (arg: T) => unknown>(fn: Fn): Fn {\n return ((arg: T) => {\n // Only keys that are actually governed by a condition are considered - unlike\n // checkRequiredKeys, any other key on `arg` is fully unconstrained and ignored here\n // regardless of its value, since this is meant to validate one options object that may\n // legitimately carry other, unrelated fields alongside the mutually-exclusive ones.\n const provided = new Set(\n Object.keys(arg).filter((key) => governedKeys.has(key as keyof T) && arg[key] !== undefined)\n )\n\n if (allowEmpty && provided.size === 0) {\n return fn(arg)\n }\n\n const matches = conditionEntries.filter(\n ([, keys]) => keys.length === provided.size && keys.every((key) => provided.has(key as string))\n )\n if (matches.length !== 1) {\n throw new Error(`Object keys do not match exactly one required condition. ${JSON.stringify(conditions)}`)\n }\n return fn(arg)\n }) as Fn\n }\n}\n\nexport function setKeyValueToObjectIfValue(key: string, value: unknown, object: Record<string, unknown>) {\n if (value) {\n // Object.defineProperty (unlike a plain `object[key] = value` assignment) always creates/\n // overwrites an own property, even when key is \"__proto__\" - a plain assignment would instead\n // be intercepted by Object.prototype's special __proto__ accessor and reassign this object's\n // prototype instead of setting a property on it.\n Object.defineProperty(object, key, { value, writable: true, configurable: true, enumerable: true })\n }\n}\n","export function slugify(value: string, allowUnicode: boolean = false): string {\n if (allowUnicode) {\n value = value.normalize('NFKC').replace(/[^\\p{L}\\p{N}_\\s-]/gu, '')\n } else {\n value = value\n .normalize('NFKD')\n // eslint-disable-next-line no-control-regex\n .replace(/[^\\x00-\\x7F]/g, '')\n .replace(/[\\r\\n]+/g, ' ')\n .trim()\n .replace(/[^\\w\\s-]/g, '')\n }\n\n value = value.toLowerCase()\n\n return value.replace(/[-\\s]+/g, '-').replace(/^[-_]+|[-_]+$/g, '')\n}\n","import { format } from 'date-fns'\n\nexport function formatDate(date: Date, pattern: string): string {\n return format(date, pattern)\n}\n","import { formatDate } from './_format'\n\nexport const LONG_DATE_FORMAT = \"EEEE, MMMM dd, yyyy 'at' hh:mm a\"\nexport const SHORT_DATE_FORMAT = 'dd.MM.yyyy'\nexport const SHORT_DATETIME_FORMAT = 'dd.MM.yyyy HH:mm a'\n\nexport function formattedDate(pattern: string, date: Date = new Date()): string {\n return formatDate(date, pattern)\n}\n\nexport function longFormattedDate(date: Date = new Date()): string {\n return formattedDate(LONG_DATE_FORMAT, date)\n}\n\nexport function shortFormattedDate(date: Date = new Date()): string {\n return formattedDate(SHORT_DATE_FORMAT, date)\n}\n\nexport function shortFormattedDateTime(date: Date = new Date()): string {\n return formattedDate(SHORT_DATETIME_FORMAT, date)\n}\n\nexport function optionalDate(date?: string): Date | undefined {\n return date ? new Date(date) : undefined\n}\n","type MimeType = 'image/png' | 'image/jpeg' | 'image/webp'\n\nexport function guessImageMimeType(filename: string): MimeType {\n const withoutQueryOrHash = filename.split(/[?#]/)[0]\n const extension = withoutQueryOrHash.split('.').pop()?.toLowerCase()\n switch (extension) {\n case 'png':\n return 'image/png'\n case 'jfif':\n case 'jpg':\n case 'jpeg':\n return 'image/jpeg'\n case 'webp':\n return 'image/webp'\n default:\n return 'image/png'\n }\n}\n\nexport function isImageMimeType(mimeType: string): mimeType is MimeType {\n return mimeType === 'image/png' || mimeType === 'image/jpeg' || mimeType === 'image/webp'\n}\n\nexport function escapeName(name: string): string {\n return name.replace(/[^a-zA-Z0-9-_.]/g, '_')\n}\n\nexport function safeFileName(filename: string, maxLength: number = 255): string {\n if (filename.length <= maxLength) return filename\n\n const dotIndex = filename.lastIndexOf('.')\n const hasExtension = dotIndex > 0\n const extension = escapeName(hasExtension ? filename.slice(dotIndex) : '')\n const name = escapeName(hasExtension ? filename.slice(0, dotIndex) : filename)\n\n return name.slice(0, Math.max(0, maxLength - extension.length)) + extension\n}\n\nexport async function downloadAndFormatImage(\n src: string,\n name: string = 'image.png',\n mimeType: MimeType = guessImageMimeType(name),\n quality: number = 1\n): Promise<void> {\n name = safeFileName(name)\n try {\n const img = new Image()\n img.crossOrigin = 'anonymous'\n\n await new Promise((resolve, reject) => {\n img.onload = resolve\n img.onerror = reject\n img.src = src\n })\n\n const canvas = document.createElement('canvas')\n canvas.width = img.width\n canvas.height = img.height\n const ctx = canvas.getContext('2d')\n\n if (!ctx) {\n throw new Error('Could not get canvas context')\n }\n\n ctx.drawImage(img, 0, 0)\n\n const blob = await new Promise<Blob | null>((resolve) => {\n canvas.toBlob(resolve, mimeType, quality)\n })\n\n if (!blob) {\n throw new Error('Could not generate blob')\n }\n\n const link = document.createElement('a')\n const downloadUrl = URL.createObjectURL(blob)\n try {\n link.href = downloadUrl\n link.download = name\n document.body.appendChild(link)\n link.click()\n } finally {\n document.body.removeChild(link)\n URL.revokeObjectURL(downloadUrl)\n }\n } catch (error) {\n console.error('Failed to download image:', error)\n }\n}\n\nexport async function fileToBase64Native(file: File): Promise<string> {\n const result = await new Promise<string | ArrayBuffer | null>((resolve, reject) => {\n const reader = new FileReader()\n reader.readAsDataURL(file)\n reader.onload = () => resolve(reader.result)\n reader.onerror = (error) => reject(error)\n })\n\n if (typeof result === 'string') {\n return result\n } else {\n throw new Error('Failed to read file as Data URL')\n }\n}\n\nexport async function fileToBase64(file: File, quality: number = 1): Promise<string> {\n if (isImageMimeType(file.type)) {\n const img = new Image()\n const url = URL.createObjectURL(file)\n try {\n await new Promise<void>((resolve, reject) => {\n img.onload = () => resolve()\n img.onerror = () => reject(new Error('Failed to load image for metadata removal'))\n img.src = url\n })\n\n const canvas = document.createElement('canvas')\n canvas.width = img.width\n canvas.height = img.height\n\n const ctx = canvas.getContext('2d')\n if (!ctx) {\n throw new Error('Failed to get canvas context')\n }\n ctx.drawImage(img, 0, 0)\n\n const cleanDataUrl = canvas.toDataURL(file.type, quality)\n if (cleanDataUrl === 'data:,') {\n return await fileToBase64Native(file)\n }\n\n return cleanDataUrl\n } finally {\n URL.revokeObjectURL(url)\n }\n } else {\n return await fileToBase64Native(file)\n }\n}\n","export function getCookie(name: string): string | undefined {\n for (const pair of document.cookie.split('; ')) {\n const separatorIndex = pair.indexOf('=')\n if (separatorIndex === -1) {\n continue\n }\n if (pair.slice(0, separatorIndex) === name) {\n return pair.slice(separatorIndex + 1)\n }\n }\n return undefined\n}\n","type ConsoleMethod = (...args: unknown[]) => void\ntype WindowLike = Window & typeof globalThis\n\nconst patchedWindows = new WeakMap<WindowLike, Set<string>>()\n\nexport function createConsoleDebugSwitch(targetWindow: WindowLike, options: { namespace: string }): void {\n if (!targetWindow) {\n return\n }\n\n const { namespace } = options\n\n let enabledNamespaces = patchedWindows.get(targetWindow)\n if (!enabledNamespaces) {\n enabledNamespaces = new Set<string>()\n patchedWindows.set(targetWindow, enabledNamespaces)\n\n const original = {\n log: targetWindow.console.log.bind(targetWindow.console),\n info: targetWindow.console.info.bind(targetWindow.console),\n warn: targetWindow.console.warn.bind(targetWindow.console),\n error: targetWindow.console.error.bind(targetWindow.console),\n }\n\n const conditional =\n (method: ConsoleMethod): ConsoleMethod =>\n (...args) => {\n if (enabledNamespaces!.size > 0) {\n method(...args)\n }\n }\n\n targetWindow.console.log = conditional(original.log)\n targetWindow.console.info = conditional(original.info)\n targetWindow.console.warn = conditional(original.warn)\n targetWindow.console.error = conditional(original.error)\n }\n\n type Namespace = { debug: (enabled: boolean) => void }\n const globals = targetWindow as unknown as Record<string, Namespace | undefined>\n const existing = Object.prototype.hasOwnProperty.call(globals, namespace)\n ? (Object.getOwnPropertyDescriptor(globals, namespace)?.value as Namespace | undefined)\n : undefined\n const target = existing ?? ({} as Namespace)\n target.debug = (flag: boolean) => {\n if (flag) {\n enabledNamespaces!.add(namespace)\n } else {\n enabledNamespaces!.delete(namespace)\n }\n }\n // Object.defineProperty (unlike a plain `globals[namespace] = target` assignment) always\n // creates/overwrites an own property, even when namespace is a name like \"__proto__\" that\n // would otherwise be intercepted by Object.prototype's special __proto__ accessor and\n // pollute the shared prototype instead of setting a property on this specific object.\n Object.defineProperty(globals, namespace, { value: target, writable: true, configurable: true, enumerable: true })\n}\n","export type TailwindShade = 50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 950\n\nexport type TailwindColorScale = Record<TailwindShade, string>\n\ninterface Rgb {\n r: number\n g: number\n b: number\n}\n\nconst HEX_PATTERN = /^#?([0-9a-f]{3}|[0-9a-f]{6})$/i\n\nfunction hexToRgb(hex: string): Rgb {\n const match = HEX_PATTERN.exec(hex.trim())\n if (!match) {\n throw new Error(`Invalid hex color: \"${hex}\"`)\n }\n\n const digits = match[1]\n const normalized =\n digits.length === 3\n ? digits\n .split('')\n .map((char) => char + char)\n .join('')\n : digits\n\n return {\n r: parseInt(normalized.slice(0, 2), 16),\n g: parseInt(normalized.slice(2, 4), 16),\n b: parseInt(normalized.slice(4, 6), 16),\n }\n}\n\nfunction rgbToHex({ r, g, b }: Rgb): string {\n return `#${[r, g, b].map((channel) => Math.round(channel).toString(16).padStart(2, '0')).join('')}`\n}\n\nfunction mixRgb(base: Rgb, target: Rgb, weight: number): Rgb {\n return {\n r: base.r + (target.r - base.r) * weight,\n g: base.g + (target.g - base.g) * weight,\n b: base.b + (target.b - base.b) * weight,\n }\n}\n\nconst WHITE: Rgb = { r: 255, g: 255, b: 255 }\nconst BLACK: Rgb = { r: 0, g: 0, b: 0 }\n\n// Weight of white/black mixed into the base color at each shade, tuned so 500 is the input\n// color unchanged and the rest approximate the spread of Tailwind's own default palettes.\nconst TINT_WEIGHTS: Record<50 | 100 | 200 | 300 | 400, number> = { 50: 0.95, 100: 0.9, 200: 0.75, 300: 0.6, 400: 0.3 }\nconst SHADE_WEIGHTS: Record<600 | 700 | 800 | 900 | 950, number> = {\n 600: 0.15,\n 700: 0.3,\n 800: 0.45,\n 900: 0.6,\n 950: 0.8,\n}\n\n/**\n * Generates a Tailwind-style 50-950 color scale from a single base hex color, treated as the 500 shade.\n */\nexport function generateTailwindColorScale(baseColor: string): TailwindColorScale {\n const base = hexToRgb(baseColor)\n\n return {\n 50: rgbToHex(mixRgb(base, WHITE, TINT_WEIGHTS[50])),\n 100: rgbToHex(mixRgb(base, WHITE, TINT_WEIGHTS[100])),\n 200: rgbToHex(mixRgb(base, WHITE, TINT_WEIGHTS[200])),\n 300: rgbToHex(mixRgb(base, WHITE, TINT_WEIGHTS[300])),\n 400: rgbToHex(mixRgb(base, WHITE, TINT_WEIGHTS[400])),\n 500: rgbToHex(base),\n 600: rgbToHex(mixRgb(base, BLACK, SHADE_WEIGHTS[600])),\n 700: rgbToHex(mixRgb(base, BLACK, SHADE_WEIGHTS[700])),\n 800: rgbToHex(mixRgb(base, BLACK, SHADE_WEIGHTS[800])),\n 900: rgbToHex(mixRgb(base, BLACK, SHADE_WEIGHTS[900])),\n 950: rgbToHex(mixRgb(base, BLACK, SHADE_WEIGHTS[950])),\n }\n}\n\n/**\n * Like {@link generateTailwindColorScale}, but prefixes each shade with `name` (e.g. `primary500`)\n * so multiple scales can be spread into one flat palette object.\n */\nexport function generateNamedTailwindColorScale<T extends string>(\n baseColor: string,\n name: T\n): Record<`${T}${TailwindShade}`, string> {\n const scale = generateTailwindColorScale(baseColor)\n\n return Object.fromEntries(Object.entries(scale).map(([shade, hex]) => [`${name}${shade}`, hex])) as Record<\n `${T}${TailwindShade}`,\n string\n >\n}\n\nfunction rgbToHsl({ r, g, b }: Rgb): { h: number; s: number; l: number } {\n const rN = r / 255\n const gN = g / 255\n const bN = b / 255\n\n const max = Math.max(rN, gN, bN)\n const min = Math.min(rN, gN, bN)\n const l = (max + min) / 2\n\n if (max === min) {\n return { h: 0, s: 0, l: l * 100 }\n }\n\n const delta = max - min\n const s = l > 0.5 ? delta / (2 - max - min) : delta / (max + min)\n\n let h: number\n if (max === rN) {\n h = ((gN - bN) / delta + (gN < bN ? 6 : 0)) * 60\n } else if (max === gN) {\n h = ((bN - rN) / delta + 2) * 60\n } else {\n h = ((rN - gN) / delta + 4) * 60\n }\n\n return { h, s: s * 100, l: l * 100 }\n}\n\n/**\n * Formats a hex color as the \"H S% L%\" triplet shadcn/Tailwind CSS variable themes expect,\n * e.g. for `--primary: 240 5.9% 10%;` consumed as `hsl(var(--primary))`.\n */\nexport function hexToHslTriplet(hex: string, precision: number = 1): string {\n const { h, s, l } = rgbToHsl(hexToRgb(hex))\n const round = (value: number) => Number(value.toFixed(precision))\n\n return `${round(h)} ${round(s)}% ${round(l)}%`\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/types/index.ts","../src/arrays/index.ts","../src/functions/index.ts","../src/objects/index.ts","../src/strings/index.ts","../src/dates/_format.ts","../src/dates/index.ts","../src/files/index.ts","../src/cookies/index.ts","../src/console/index.ts","../src/colors/index.ts"],"sourcesContent":["export * from './types'\nexport * from './arrays'\nexport * from './functions'\nexport * from './objects'\nexport * from './strings'\nexport * from './dates'\nexport * from './files'\nexport * from './cookies'\nexport * from './console'\nexport * from './colors'\n","export const getKeys = Object.keys as <T extends object>(obj: T) => Array<keyof T>\n\nexport type RecursivePartial<T> = { [P in keyof T]?: RecursivePartial<T[P]> }\n\nexport type RecursiveRecord = {\n [key: string]: string | number | boolean | RecursiveRecord | Array<RecursiveRecord>\n}\n\nexport function forcedType<T>(obj: unknown): T {\n return obj as unknown as T\n}\n","export function notNone<T>(value: T | null | undefined): value is T {\n return value !== null && value !== undefined\n}\n\nfunction combinationsOfSize<T>(items: T[], size: number): T[][] {\n if (size === 0) {\n return [[]]\n }\n if (size > items.length) {\n return []\n }\n const [first, ...rest] = items\n const withFirst = combinationsOfSize(rest, size - 1).map((combination) => [first, ...combination])\n const withoutFirst = combinationsOfSize(rest, size)\n return [...withFirst, ...withoutFirst]\n}\n\nexport function allCombinations<T>(options: T[]): T[][] {\n const result: T[][] = []\n for (let size = 1; size <= options.length; size++) {\n result.push(...combinationsOfSize(options, size))\n }\n return result\n}\n","export function withAttributes<Fn extends (...args: never[]) => unknown, Attrs extends Record<string, unknown>>(\n fn: Fn,\n attributes: Attrs\n): Fn & Attrs {\n for (const key of Object.keys(attributes)) {\n // Object.defineProperty (unlike a plain `fn[key] = value` assignment) always creates/\n // overwrites an own property, even when key is \"__proto__\" - a plain assignment would instead\n // be intercepted by Object.prototype's special __proto__ accessor and reassign fn's own\n // prototype instead of setting a property on it.\n Object.defineProperty(fn, key, {\n value: attributes[key],\n writable: true,\n configurable: true,\n enumerable: true,\n })\n }\n return fn as Fn & Attrs\n}\n\nexport function makeCallable<T, R>(originalCallable: (arg: T) => R) {\n return (data: T) => () => originalCallable(data)\n}\n\nexport function getLazyValue<T>(input: T | (() => T)): T {\n if (typeof input === 'function') {\n return (input as () => T)()\n }\n return input\n}\n\nexport async function getLazyValueAsync<T>(input: T | (() => Promise<T>) | (() => T)): Promise<T> {\n if (typeof input === 'function') {\n const result = (input as () => Promise<T>)()\n if (result instanceof Promise) {\n return await result\n }\n return result as unknown as T\n }\n return input\n}\n\nexport function suppress<T, ERT>(\n exceptions: Array<new (message?: string) => Error>,\n fn: () => T,\n onError?: (error: unknown) => ERT\n): T | ERT | undefined {\n try {\n return fn()\n } catch (error) {\n if (exceptions.some((exception) => error instanceof exception)) {\n return onError ? onError(error) : undefined\n }\n throw error\n }\n}\n\nexport function preventDefault<E extends Event, R>(callable: (event: E) => R): (event: E) => Promise<Awaited<R>> {\n return async function (event: E): Promise<Awaited<R>> {\n event.preventDefault()\n return await callable(event)\n }\n}\n\nexport function isPathMatched(pathname: string, pattern: RegExp, exemptPatterns: RegExp[] = []): boolean {\n if (exemptPatterns.some((exempt) => exempt.test(pathname))) {\n return false\n }\n return pattern.test(pathname)\n}\n\nexport function raises(error: Error): (...args: unknown[]) => never {\n return () => {\n throw error\n }\n}\n\nexport function cloned<Fn extends (...args: never[]) => unknown>(fn: Fn): Fn {\n return ((...args: Parameters<Fn>) => fn(...args)) as Fn\n}\n\nexport function enabledIf<R>(condition: boolean | (() => boolean), options: { ifNotEnabledReturnValue: R }) {\n const enabled = typeof condition === 'function' ? condition() : condition\n\n return function <Fn extends (...args: never[]) => R>(fn: Fn): Fn {\n if (!enabled) {\n return cloned((() => options.ifNotEnabledReturnValue) as Fn)\n }\n return cloned(fn)\n }\n}\n\nexport function transformExceptions<E extends Error>(\n exceptionTypes: Array<new (...args: never[]) => E>,\n transform: (error: E) => Error,\n options: { keepOriginal?: boolean } = {}\n) {\n const { keepOriginal = true } = options\n\n return function <Fn extends (...args: never[]) => unknown>(fn: Fn): Fn {\n return ((...args: Parameters<Fn>) => {\n try {\n return fn(...args)\n } catch (error) {\n if (!exceptionTypes.some((ExceptionType) => error instanceof ExceptionType)) {\n throw error\n }\n const newError = transform(error as E)\n if (keepOriginal) {\n newError.cause = error\n }\n throw newError\n }\n }) as Fn\n }\n}\n","export function checkRequiredKeys<T extends Record<string, unknown>, C extends Record<string, Array<keyof T>>>(\n obj: T,\n conditions: C\n): keyof C {\n const matchingConditions = Object.entries(conditions).filter(\n ([, keys]) =>\n keys.every((key) => obj[key] !== undefined) &&\n Object.keys(obj).every((key) => keys.includes(key as keyof T) || obj[key] === undefined)\n )\n\n if (matchingConditions.length !== 1) {\n throw new Error(`Object keys do not match exactly one required condition. ${JSON.stringify(conditions)}`)\n }\n\n return matchingConditions[0][0] as keyof C\n}\n\nexport function requireExclusiveKeys<T extends Record<string, unknown>, C extends Record<string, Array<keyof T>>>(\n conditions: C,\n options: { allowEmpty?: boolean } = {}\n) {\n const conditionEntries = Object.entries(conditions) as Array<[string, Array<keyof T>]>\n if (conditionEntries.length === 0) {\n throw new Error('At least one condition must be provided.')\n }\n const { allowEmpty = false } = options\n const governedKeys = new Set(conditionEntries.flatMap(([, keys]) => keys))\n\n return function <Fn extends (arg: T) => unknown>(fn: Fn): Fn {\n return ((arg: T) => {\n // Only keys that are actually governed by a condition are considered - unlike\n // checkRequiredKeys, any other key on `arg` is fully unconstrained and ignored here\n // regardless of its value, since this is meant to validate one options object that may\n // legitimately carry other, unrelated fields alongside the mutually-exclusive ones.\n const provided = new Set(\n Object.keys(arg).filter((key) => governedKeys.has(key as keyof T) && arg[key] !== undefined)\n )\n\n if (allowEmpty && provided.size === 0) {\n return fn(arg)\n }\n\n const matches = conditionEntries.filter(\n ([, keys]) => keys.length === provided.size && keys.every((key) => provided.has(key as string))\n )\n if (matches.length !== 1) {\n throw new Error(`Object keys do not match exactly one required condition. ${JSON.stringify(conditions)}`)\n }\n return fn(arg)\n }) as Fn\n }\n}\n\nexport function setKeyValueToObjectIfValue(key: string, value: unknown, object: Record<string, unknown>) {\n if (value) {\n // Object.defineProperty (unlike a plain `object[key] = value` assignment) always creates/\n // overwrites an own property, even when key is \"__proto__\" - a plain assignment would instead\n // be intercepted by Object.prototype's special __proto__ accessor and reassign this object's\n // prototype instead of setting a property on it.\n Object.defineProperty(object, key, { value, writable: true, configurable: true, enumerable: true })\n }\n}\n","export function slugify(value: string, allowUnicode: boolean = false): string {\n if (allowUnicode) {\n value = value.normalize('NFKC').replace(/[^\\p{L}\\p{N}_\\s-]/gu, '')\n } else {\n value = value\n .normalize('NFKD')\n // eslint-disable-next-line no-control-regex\n .replace(/[^\\x00-\\x7F]/g, '')\n .replace(/[\\r\\n]+/g, ' ')\n .trim()\n .replace(/[^\\w\\s-]/g, '')\n }\n\n value = value.toLowerCase()\n\n return value.replace(/[-\\s]+/g, '-').replace(/^[-_]+|[-_]+$/g, '')\n}\n","import { format } from 'date-fns'\n\nexport function formatDate(date: Date, pattern: string): string {\n return format(date, pattern)\n}\n","import { formatDate } from './_format'\n\nexport const LONG_DATE_FORMAT = \"EEEE, MMMM dd, yyyy 'at' hh:mm a\"\nexport const SHORT_DATE_FORMAT = 'dd.MM.yyyy'\nexport const SHORT_DATETIME_FORMAT = 'dd.MM.yyyy HH:mm a'\n\nexport function formattedDate(pattern: string, date: Date = new Date()): string {\n return formatDate(date, pattern)\n}\n\nexport function longFormattedDate(date: Date = new Date()): string {\n return formattedDate(LONG_DATE_FORMAT, date)\n}\n\nexport function shortFormattedDate(date: Date = new Date()): string {\n return formattedDate(SHORT_DATE_FORMAT, date)\n}\n\nexport function shortFormattedDateTime(date: Date = new Date()): string {\n return formattedDate(SHORT_DATETIME_FORMAT, date)\n}\n\nexport function optionalDate(date?: string): Date | undefined {\n return date ? new Date(date) : undefined\n}\n","type MimeType = 'image/png' | 'image/jpeg' | 'image/webp'\n\nexport function guessImageMimeType(filename: string): MimeType {\n const withoutQueryOrHash = filename.split(/[?#]/)[0]\n const extension = withoutQueryOrHash.split('.').pop()?.toLowerCase()\n switch (extension) {\n case 'png':\n return 'image/png'\n case 'jfif':\n case 'jpg':\n case 'jpeg':\n return 'image/jpeg'\n case 'webp':\n return 'image/webp'\n default:\n return 'image/png'\n }\n}\n\nexport function isImageMimeType(mimeType: string): mimeType is MimeType {\n return mimeType === 'image/png' || mimeType === 'image/jpeg' || mimeType === 'image/webp'\n}\n\nexport function escapeName(name: string): string {\n return name.replace(/[^a-zA-Z0-9-_.]/g, '_')\n}\n\nexport function safeFileName(filename: string, maxLength: number = 255): string {\n if (filename.length <= maxLength) return filename\n\n const dotIndex = filename.lastIndexOf('.')\n const hasExtension = dotIndex > 0\n const extension = escapeName(hasExtension ? filename.slice(dotIndex) : '')\n const name = escapeName(hasExtension ? filename.slice(0, dotIndex) : filename)\n\n return name.slice(0, Math.max(0, maxLength - extension.length)) + extension\n}\n\nexport async function downloadAndFormatImage(\n src: string,\n name: string = 'image.png',\n mimeType: MimeType = guessImageMimeType(name),\n quality: number = 1\n): Promise<void> {\n name = safeFileName(name)\n try {\n const img = new Image()\n img.crossOrigin = 'anonymous'\n\n await new Promise((resolve, reject) => {\n img.onload = resolve\n img.onerror = reject\n img.src = src\n })\n\n const canvas = document.createElement('canvas')\n canvas.width = img.width\n canvas.height = img.height\n const ctx = canvas.getContext('2d')\n\n if (!ctx) {\n throw new Error('Could not get canvas context')\n }\n\n ctx.drawImage(img, 0, 0)\n\n const blob = await new Promise<Blob | null>((resolve) => {\n canvas.toBlob(resolve, mimeType, quality)\n })\n\n if (!blob) {\n throw new Error('Could not generate blob')\n }\n\n const link = document.createElement('a')\n const downloadUrl = URL.createObjectURL(blob)\n try {\n link.href = downloadUrl\n link.download = name\n document.body.appendChild(link)\n link.click()\n } finally {\n document.body.removeChild(link)\n URL.revokeObjectURL(downloadUrl)\n }\n } catch (error) {\n console.error('Failed to download image:', error)\n }\n}\n\nexport async function fileToBase64Native(file: File): Promise<string> {\n const result = await new Promise<string | ArrayBuffer | null>((resolve, reject) => {\n const reader = new FileReader()\n reader.readAsDataURL(file)\n reader.onload = () => resolve(reader.result)\n reader.onerror = (error) => reject(error)\n })\n\n if (typeof result === 'string') {\n return result\n } else {\n throw new Error('Failed to read file as Data URL')\n }\n}\n\nexport async function fileToBase64(file: File, quality: number = 1): Promise<string> {\n if (isImageMimeType(file.type)) {\n const img = new Image()\n const url = URL.createObjectURL(file)\n try {\n await new Promise<void>((resolve, reject) => {\n img.onload = () => resolve()\n img.onerror = () => reject(new Error('Failed to load image for metadata removal'))\n img.src = url\n })\n\n const canvas = document.createElement('canvas')\n canvas.width = img.width\n canvas.height = img.height\n\n const ctx = canvas.getContext('2d')\n if (!ctx) {\n throw new Error('Failed to get canvas context')\n }\n ctx.drawImage(img, 0, 0)\n\n const cleanDataUrl = canvas.toDataURL(file.type, quality)\n if (cleanDataUrl === 'data:,') {\n return await fileToBase64Native(file)\n }\n\n return cleanDataUrl\n } finally {\n URL.revokeObjectURL(url)\n }\n } else {\n return await fileToBase64Native(file)\n }\n}\n","export function getCookie(name: string): string | undefined {\n for (const pair of document.cookie.split('; ')) {\n const separatorIndex = pair.indexOf('=')\n if (separatorIndex === -1) {\n continue\n }\n if (pair.slice(0, separatorIndex) === name) {\n return pair.slice(separatorIndex + 1)\n }\n }\n return undefined\n}\n\nexport interface SetCookieOptions {\n /** Days until the cookie expires. Omit for a session cookie (cleared when the browser closes). */\n days?: number\n path?: string\n}\n\nexport function setCookie(name: string, value: string, options: SetCookieOptions = {}): void {\n const { days, path = '/' } = options\n const expires = days === undefined ? '' : `; expires=${new Date(Date.now() + days * 86_400_000).toUTCString()}`\n document.cookie = `${name}=${value}${expires}; path=${path}`\n}\n\nexport function removeCookie(name: string, path: string = '/'): void {\n document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=${path}`\n}\n","type ConsoleMethod = (...args: unknown[]) => void\ntype WindowLike = Window & typeof globalThis\n\nconst patchedWindows = new WeakMap<WindowLike, Set<string>>()\n\nexport function createConsoleDebugSwitch(targetWindow: WindowLike, options: { namespace: string }): void {\n if (!targetWindow) {\n return\n }\n\n const { namespace } = options\n\n let enabledNamespaces = patchedWindows.get(targetWindow)\n if (!enabledNamespaces) {\n enabledNamespaces = new Set<string>()\n patchedWindows.set(targetWindow, enabledNamespaces)\n\n const original = {\n log: targetWindow.console.log.bind(targetWindow.console),\n info: targetWindow.console.info.bind(targetWindow.console),\n warn: targetWindow.console.warn.bind(targetWindow.console),\n error: targetWindow.console.error.bind(targetWindow.console),\n }\n\n const conditional =\n (method: ConsoleMethod): ConsoleMethod =>\n (...args) => {\n if (enabledNamespaces!.size > 0) {\n method(...args)\n }\n }\n\n targetWindow.console.log = conditional(original.log)\n targetWindow.console.info = conditional(original.info)\n targetWindow.console.warn = conditional(original.warn)\n targetWindow.console.error = conditional(original.error)\n }\n\n type Namespace = { debug: (enabled: boolean) => void }\n const globals = targetWindow as unknown as Record<string, Namespace | undefined>\n const existing = Object.prototype.hasOwnProperty.call(globals, namespace)\n ? (Object.getOwnPropertyDescriptor(globals, namespace)?.value as Namespace | undefined)\n : undefined\n const target = existing ?? ({} as Namespace)\n target.debug = (flag: boolean) => {\n if (flag) {\n enabledNamespaces!.add(namespace)\n } else {\n enabledNamespaces!.delete(namespace)\n }\n }\n // Object.defineProperty (unlike a plain `globals[namespace] = target` assignment) always\n // creates/overwrites an own property, even when namespace is a name like \"__proto__\" that\n // would otherwise be intercepted by Object.prototype's special __proto__ accessor and\n // pollute the shared prototype instead of setting a property on this specific object.\n Object.defineProperty(globals, namespace, { value: target, writable: true, configurable: true, enumerable: true })\n}\n","export type TailwindShade = 50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 950\n\nexport type TailwindColorScale = Record<TailwindShade, string>\n\ninterface Rgb {\n r: number\n g: number\n b: number\n}\n\nconst HEX_PATTERN = /^#?([0-9a-f]{3}|[0-9a-f]{6})$/i\n\nfunction hexToRgb(hex: string): Rgb {\n const match = HEX_PATTERN.exec(hex.trim())\n if (!match) {\n throw new Error(`Invalid hex color: \"${hex}\"`)\n }\n\n const digits = match[1]\n const normalized =\n digits.length === 3\n ? digits\n .split('')\n .map((char) => char + char)\n .join('')\n : digits\n\n return {\n r: parseInt(normalized.slice(0, 2), 16),\n g: parseInt(normalized.slice(2, 4), 16),\n b: parseInt(normalized.slice(4, 6), 16),\n }\n}\n\nfunction rgbToHex({ r, g, b }: Rgb): string {\n return `#${[r, g, b].map((channel) => Math.round(channel).toString(16).padStart(2, '0')).join('')}`\n}\n\nfunction mixRgb(base: Rgb, target: Rgb, weight: number): Rgb {\n return {\n r: base.r + (target.r - base.r) * weight,\n g: base.g + (target.g - base.g) * weight,\n b: base.b + (target.b - base.b) * weight,\n }\n}\n\nconst WHITE: Rgb = { r: 255, g: 255, b: 255 }\nconst BLACK: Rgb = { r: 0, g: 0, b: 0 }\n\n// Weight of white/black mixed into the base color at each shade, tuned so 500 is the input\n// color unchanged and the rest approximate the spread of Tailwind's own default palettes.\nconst TINT_WEIGHTS: Record<50 | 100 | 200 | 300 | 400, number> = { 50: 0.95, 100: 0.9, 200: 0.75, 300: 0.6, 400: 0.3 }\nconst SHADE_WEIGHTS: Record<600 | 700 | 800 | 900 | 950, number> = {\n 600: 0.15,\n 700: 0.3,\n 800: 0.45,\n 900: 0.6,\n 950: 0.8,\n}\n\n/**\n * Generates a Tailwind-style 50-950 color scale from a single base hex color, treated as the 500 shade.\n */\nexport function generateTailwindColorScale(baseColor: string): TailwindColorScale {\n const base = hexToRgb(baseColor)\n\n return {\n 50: rgbToHex(mixRgb(base, WHITE, TINT_WEIGHTS[50])),\n 100: rgbToHex(mixRgb(base, WHITE, TINT_WEIGHTS[100])),\n 200: rgbToHex(mixRgb(base, WHITE, TINT_WEIGHTS[200])),\n 300: rgbToHex(mixRgb(base, WHITE, TINT_WEIGHTS[300])),\n 400: rgbToHex(mixRgb(base, WHITE, TINT_WEIGHTS[400])),\n 500: rgbToHex(base),\n 600: rgbToHex(mixRgb(base, BLACK, SHADE_WEIGHTS[600])),\n 700: rgbToHex(mixRgb(base, BLACK, SHADE_WEIGHTS[700])),\n 800: rgbToHex(mixRgb(base, BLACK, SHADE_WEIGHTS[800])),\n 900: rgbToHex(mixRgb(base, BLACK, SHADE_WEIGHTS[900])),\n 950: rgbToHex(mixRgb(base, BLACK, SHADE_WEIGHTS[950])),\n }\n}\n\n/**\n * Like {@link generateTailwindColorScale}, but prefixes each shade with `name` (e.g. `primary500`)\n * so multiple scales can be spread into one flat palette object.\n */\nexport function generateNamedTailwindColorScale<T extends string>(\n baseColor: string,\n name: T\n): Record<`${T}${TailwindShade}`, string> {\n const scale = generateTailwindColorScale(baseColor)\n\n return Object.fromEntries(Object.entries(scale).map(([shade, hex]) => [`${name}${shade}`, hex])) as Record<\n `${T}${TailwindShade}`,\n string\n >\n}\n\nfunction rgbToHsl({ r, g, b }: Rgb): { h: number; s: number; l: number } {\n const rN = r / 255\n const gN = g / 255\n const bN = b / 255\n\n const max = Math.max(rN, gN, bN)\n const min = Math.min(rN, gN, bN)\n const l = (max + min) / 2\n\n if (max === min) {\n return { h: 0, s: 0, l: l * 100 }\n }\n\n const delta = max - min\n const s = l > 0.5 ? delta / (2 - max - min) : delta / (max + min)\n\n let h: number\n if (max === rN) {\n h = ((gN - bN) / delta + (gN < bN ? 6 : 0)) * 60\n } else if (max === gN) {\n h = ((bN - rN) / delta + 2) * 60\n } else {\n h = ((rN - gN) / delta + 4) * 60\n }\n\n return { h, s: s * 100, l: l * 100 }\n}\n\n/**\n * Formats a hex color as the \"H S% L%\" triplet shadcn/Tailwind CSS variable themes expect,\n * e.g. for `--primary: 240 5.9% 10%;` consumed as `hsl(var(--primary))`.\n */\nexport function hexToHslTriplet(hex: string, precision: number = 1): string {\n const { h, s, l } = rgbToHsl(hexToRgb(hex))\n const round = (value: number) => Number(value.toFixed(precision))\n\n return `${round(h)} ${round(s)}% ${round(l)}%`\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAO,IAAM,UAAU,OAAO;AAQvB,SAAS,WAAc,KAAiB;AAC7C,SAAO;AACT;;;ACVO,SAAS,QAAW,OAAyC;AAClE,SAAO,UAAU,QAAQ,UAAU;AACrC;AAEA,SAAS,mBAAsB,OAAY,MAAqB;AAC9D,MAAI,SAAS,GAAG;AACd,WAAO,CAAC,CAAC,CAAC;AAAA,EACZ;AACA,MAAI,OAAO,MAAM,QAAQ;AACvB,WAAO,CAAC;AAAA,EACV;AACA,QAAM,CAAC,OAAO,GAAG,IAAI,IAAI;AACzB,QAAM,YAAY,mBAAmB,MAAM,OAAO,CAAC,EAAE,IAAI,CAAC,gBAAgB,CAAC,OAAO,GAAG,WAAW,CAAC;AACjG,QAAM,eAAe,mBAAmB,MAAM,IAAI;AAClD,SAAO,CAAC,GAAG,WAAW,GAAG,YAAY;AACvC;AAEO,SAAS,gBAAmB,SAAqB;AACtD,QAAM,SAAgB,CAAC;AACvB,WAAS,OAAO,GAAG,QAAQ,QAAQ,QAAQ,QAAQ;AACjD,WAAO,KAAK,GAAG,mBAAmB,SAAS,IAAI,CAAC;AAAA,EAClD;AACA,SAAO;AACT;;;ACvBO,SAAS,eACd,IACA,YACY;AACZ,aAAW,OAAO,OAAO,KAAK,UAAU,GAAG;AAKzC,WAAO,eAAe,IAAI,KAAK;AAAA,MAC7B,OAAO,WAAW,GAAG;AAAA,MACrB,UAAU;AAAA,MACV,cAAc;AAAA,MACd,YAAY;AAAA,IACd,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEO,SAAS,aAAmB,kBAAiC;AAClE,SAAO,CAAC,SAAY,MAAM,iBAAiB,IAAI;AACjD;AAEO,SAAS,aAAgB,OAAyB;AACvD,MAAI,OAAO,UAAU,YAAY;AAC/B,WAAQ,MAAkB;AAAA,EAC5B;AACA,SAAO;AACT;AAEA,eAAsB,kBAAqB,OAAuD;AAChG,MAAI,OAAO,UAAU,YAAY;AAC/B,UAAM,SAAU,MAA2B;AAC3C,QAAI,kBAAkB,SAAS;AAC7B,aAAO,MAAM;AAAA,IACf;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEO,SAAS,SACd,YACA,IACA,SACqB;AACrB,MAAI;AACF,WAAO,GAAG;AAAA,EACZ,SAAS,OAAO;AACd,QAAI,WAAW,KAAK,CAAC,cAAc,iBAAiB,SAAS,GAAG;AAC9D,aAAO,UAAU,QAAQ,KAAK,IAAI;AAAA,IACpC;AACA,UAAM;AAAA,EACR;AACF;AAEO,SAAS,eAAmC,UAA8D;AAC/G,SAAO,eAAgB,OAA+B;AACpD,UAAM,eAAe;AACrB,WAAO,MAAM,SAAS,KAAK;AAAA,EAC7B;AACF;AAEO,SAAS,cAAc,UAAkB,SAAiB,iBAA2B,CAAC,GAAY;AACvG,MAAI,eAAe,KAAK,CAAC,WAAW,OAAO,KAAK,QAAQ,CAAC,GAAG;AAC1D,WAAO;AAAA,EACT;AACA,SAAO,QAAQ,KAAK,QAAQ;AAC9B;AAEO,SAAS,OAAO,OAA6C;AAClE,SAAO,MAAM;AACX,UAAM;AAAA,EACR;AACF;AAEO,SAAS,OAAiD,IAAY;AAC3E,UAAQ,IAAI,SAAyB,GAAG,GAAG,IAAI;AACjD;AAEO,SAAS,UAAa,WAAsC,SAAyC;AAC1G,QAAM,UAAU,OAAO,cAAc,aAAa,UAAU,IAAI;AAEhE,SAAO,SAA8C,IAAY;AAC/D,QAAI,CAAC,SAAS;AACZ,aAAO,QAAQ,MAAM,QAAQ,wBAA8B;AAAA,IAC7D;AACA,WAAO,OAAO,EAAE;AAAA,EAClB;AACF;AAEO,SAAS,oBACd,gBACA,WACA,UAAsC,CAAC,GACvC;AACA,QAAM,EAAE,eAAe,KAAK,IAAI;AAEhC,SAAO,SAAoD,IAAY;AACrE,YAAQ,IAAI,SAAyB;AACnC,UAAI;AACF,eAAO,GAAG,GAAG,IAAI;AAAA,MACnB,SAAS,OAAO;AACd,YAAI,CAAC,eAAe,KAAK,CAAC,kBAAkB,iBAAiB,aAAa,GAAG;AAC3E,gBAAM;AAAA,QACR;AACA,cAAM,WAAW,UAAU,KAAU;AACrC,YAAI,cAAc;AAChB,mBAAS,QAAQ;AAAA,QACnB;AACA,cAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;;;AClHO,SAAS,kBACd,KACA,YACS;AACT,QAAM,qBAAqB,OAAO,QAAQ,UAAU,EAAE;AAAA,IACpD,CAAC,CAAC,EAAE,IAAI,MACN,KAAK,MAAM,CAAC,QAAQ,IAAI,GAAG,MAAM,MAAS,KAC1C,OAAO,KAAK,GAAG,EAAE,MAAM,CAAC,QAAQ,KAAK,SAAS,GAAc,KAAK,IAAI,GAAG,MAAM,MAAS;AAAA,EAC3F;AAEA,MAAI,mBAAmB,WAAW,GAAG;AACnC,UAAM,IAAI,MAAM,4DAA4D,KAAK,UAAU,UAAU,CAAC,EAAE;AAAA,EAC1G;AAEA,SAAO,mBAAmB,CAAC,EAAE,CAAC;AAChC;AAEO,SAAS,qBACd,YACA,UAAoC,CAAC,GACrC;AACA,QAAM,mBAAmB,OAAO,QAAQ,UAAU;AAClD,MAAI,iBAAiB,WAAW,GAAG;AACjC,UAAM,IAAI,MAAM,0CAA0C;AAAA,EAC5D;AACA,QAAM,EAAE,aAAa,MAAM,IAAI;AAC/B,QAAM,eAAe,IAAI,IAAI,iBAAiB,QAAQ,CAAC,CAAC,EAAE,IAAI,MAAM,IAAI,CAAC;AAEzE,SAAO,SAA0C,IAAY;AAC3D,YAAQ,CAAC,QAAW;AAKlB,YAAM,WAAW,IAAI;AAAA,QACnB,OAAO,KAAK,GAAG,EAAE,OAAO,CAAC,QAAQ,aAAa,IAAI,GAAc,KAAK,IAAI,GAAG,MAAM,MAAS;AAAA,MAC7F;AAEA,UAAI,cAAc,SAAS,SAAS,GAAG;AACrC,eAAO,GAAG,GAAG;AAAA,MACf;AAEA,YAAM,UAAU,iBAAiB;AAAA,QAC/B,CAAC,CAAC,EAAE,IAAI,MAAM,KAAK,WAAW,SAAS,QAAQ,KAAK,MAAM,CAAC,QAAQ,SAAS,IAAI,GAAa,CAAC;AAAA,MAChG;AACA,UAAI,QAAQ,WAAW,GAAG;AACxB,cAAM,IAAI,MAAM,4DAA4D,KAAK,UAAU,UAAU,CAAC,EAAE;AAAA,MAC1G;AACA,aAAO,GAAG,GAAG;AAAA,IACf;AAAA,EACF;AACF;AAEO,SAAS,2BAA2B,KAAa,OAAgB,QAAiC;AACvG,MAAI,OAAO;AAKT,WAAO,eAAe,QAAQ,KAAK,EAAE,OAAO,UAAU,MAAM,cAAc,MAAM,YAAY,KAAK,CAAC;AAAA,EACpG;AACF;;;AC7DO,SAAS,QAAQ,OAAe,eAAwB,OAAe;AAC5E,MAAI,cAAc;AAChB,YAAQ,MAAM,UAAU,MAAM,EAAE,QAAQ,uBAAuB,EAAE;AAAA,EACnE,OAAO;AACL,YAAQ,MACL,UAAU,MAAM,EAEhB,QAAQ,iBAAiB,EAAE,EAC3B,QAAQ,YAAY,GAAG,EACvB,KAAK,EACL,QAAQ,aAAa,EAAE;AAAA,EAC5B;AAEA,UAAQ,MAAM,YAAY;AAE1B,SAAO,MAAM,QAAQ,WAAW,GAAG,EAAE,QAAQ,kBAAkB,EAAE;AACnE;;;AChBA,sBAAuB;AAEhB,SAAS,WAAW,MAAY,SAAyB;AAC9D,aAAO,wBAAO,MAAM,OAAO;AAC7B;;;ACFO,IAAM,mBAAmB;AACzB,IAAM,oBAAoB;AAC1B,IAAM,wBAAwB;AAE9B,SAAS,cAAc,SAAiB,OAAa,oBAAI,KAAK,GAAW;AAC9E,SAAO,WAAW,MAAM,OAAO;AACjC;AAEO,SAAS,kBAAkB,OAAa,oBAAI,KAAK,GAAW;AACjE,SAAO,cAAc,kBAAkB,IAAI;AAC7C;AAEO,SAAS,mBAAmB,OAAa,oBAAI,KAAK,GAAW;AAClE,SAAO,cAAc,mBAAmB,IAAI;AAC9C;AAEO,SAAS,uBAAuB,OAAa,oBAAI,KAAK,GAAW;AACtE,SAAO,cAAc,uBAAuB,IAAI;AAClD;AAEO,SAAS,aAAa,MAAiC;AAC5D,SAAO,OAAO,IAAI,KAAK,IAAI,IAAI;AACjC;;;ACtBO,SAAS,mBAAmB,UAA4B;AAC7D,QAAM,qBAAqB,SAAS,MAAM,MAAM,EAAE,CAAC;AACnD,QAAM,YAAY,mBAAmB,MAAM,GAAG,EAAE,IAAI,GAAG,YAAY;AACnE,UAAQ,WAAW;AAAA,IACjB,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAEO,SAAS,gBAAgB,UAAwC;AACtE,SAAO,aAAa,eAAe,aAAa,gBAAgB,aAAa;AAC/E;AAEO,SAAS,WAAW,MAAsB;AAC/C,SAAO,KAAK,QAAQ,oBAAoB,GAAG;AAC7C;AAEO,SAAS,aAAa,UAAkB,YAAoB,KAAa;AAC9E,MAAI,SAAS,UAAU,UAAW,QAAO;AAEzC,QAAM,WAAW,SAAS,YAAY,GAAG;AACzC,QAAM,eAAe,WAAW;AAChC,QAAM,YAAY,WAAW,eAAe,SAAS,MAAM,QAAQ,IAAI,EAAE;AACzE,QAAM,OAAO,WAAW,eAAe,SAAS,MAAM,GAAG,QAAQ,IAAI,QAAQ;AAE7E,SAAO,KAAK,MAAM,GAAG,KAAK,IAAI,GAAG,YAAY,UAAU,MAAM,CAAC,IAAI;AACpE;AAEA,eAAsB,uBACpB,KACA,OAAe,aACf,WAAqB,mBAAmB,IAAI,GAC5C,UAAkB,GACH;AACf,SAAO,aAAa,IAAI;AACxB,MAAI;AACF,UAAM,MAAM,IAAI,MAAM;AACtB,QAAI,cAAc;AAElB,UAAM,IAAI,QAAQ,CAAC,SAAS,WAAW;AACrC,UAAI,SAAS;AACb,UAAI,UAAU;AACd,UAAI,MAAM;AAAA,IACZ,CAAC;AAED,UAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,WAAO,QAAQ,IAAI;AACnB,WAAO,SAAS,IAAI;AACpB,UAAM,MAAM,OAAO,WAAW,IAAI;AAElC,QAAI,CAAC,KAAK;AACR,YAAM,IAAI,MAAM,8BAA8B;AAAA,IAChD;AAEA,QAAI,UAAU,KAAK,GAAG,CAAC;AAEvB,UAAM,OAAO,MAAM,IAAI,QAAqB,CAAC,YAAY;AACvD,aAAO,OAAO,SAAS,UAAU,OAAO;AAAA,IAC1C,CAAC;AAED,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,MAAM,yBAAyB;AAAA,IAC3C;AAEA,UAAM,OAAO,SAAS,cAAc,GAAG;AACvC,UAAM,cAAc,IAAI,gBAAgB,IAAI;AAC5C,QAAI;AACF,WAAK,OAAO;AACZ,WAAK,WAAW;AAChB,eAAS,KAAK,YAAY,IAAI;AAC9B,WAAK,MAAM;AAAA,IACb,UAAE;AACA,eAAS,KAAK,YAAY,IAAI;AAC9B,UAAI,gBAAgB,WAAW;AAAA,IACjC;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,MAAM,6BAA6B,KAAK;AAAA,EAClD;AACF;AAEA,eAAsB,mBAAmB,MAA6B;AACpE,QAAM,SAAS,MAAM,IAAI,QAAqC,CAAC,SAAS,WAAW;AACjF,UAAM,SAAS,IAAI,WAAW;AAC9B,WAAO,cAAc,IAAI;AACzB,WAAO,SAAS,MAAM,QAAQ,OAAO,MAAM;AAC3C,WAAO,UAAU,CAAC,UAAU,OAAO,KAAK;AAAA,EAC1C,CAAC;AAED,MAAI,OAAO,WAAW,UAAU;AAC9B,WAAO;AAAA,EACT,OAAO;AACL,UAAM,IAAI,MAAM,iCAAiC;AAAA,EACnD;AACF;AAEA,eAAsB,aAAa,MAAY,UAAkB,GAAoB;AACnF,MAAI,gBAAgB,KAAK,IAAI,GAAG;AAC9B,UAAM,MAAM,IAAI,MAAM;AACtB,UAAM,MAAM,IAAI,gBAAgB,IAAI;AACpC,QAAI;AACF,YAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,YAAI,SAAS,MAAM,QAAQ;AAC3B,YAAI,UAAU,MAAM,OAAO,IAAI,MAAM,2CAA2C,CAAC;AACjF,YAAI,MAAM;AAAA,MACZ,CAAC;AAED,YAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,aAAO,QAAQ,IAAI;AACnB,aAAO,SAAS,IAAI;AAEpB,YAAM,MAAM,OAAO,WAAW,IAAI;AAClC,UAAI,CAAC,KAAK;AACR,cAAM,IAAI,MAAM,8BAA8B;AAAA,MAChD;AACA,UAAI,UAAU,KAAK,GAAG,CAAC;AAEvB,YAAM,eAAe,OAAO,UAAU,KAAK,MAAM,OAAO;AACxD,UAAI,iBAAiB,UAAU;AAC7B,eAAO,MAAM,mBAAmB,IAAI;AAAA,MACtC;AAEA,aAAO;AAAA,IACT,UAAE;AACA,UAAI,gBAAgB,GAAG;AAAA,IACzB;AAAA,EACF,OAAO;AACL,WAAO,MAAM,mBAAmB,IAAI;AAAA,EACtC;AACF;;;AC1IO,SAAS,UAAU,MAAkC;AAC1D,aAAW,QAAQ,SAAS,OAAO,MAAM,IAAI,GAAG;AAC9C,UAAM,iBAAiB,KAAK,QAAQ,GAAG;AACvC,QAAI,mBAAmB,IAAI;AACzB;AAAA,IACF;AACA,QAAI,KAAK,MAAM,GAAG,cAAc,MAAM,MAAM;AAC1C,aAAO,KAAK,MAAM,iBAAiB,CAAC;AAAA,IACtC;AAAA,EACF;AACA,SAAO;AACT;AAQO,SAAS,UAAU,MAAc,OAAe,UAA4B,CAAC,GAAS;AAC3F,QAAM,EAAE,MAAM,OAAO,IAAI,IAAI;AAC7B,QAAM,UAAU,SAAS,SAAY,KAAK,aAAa,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAU,EAAE,YAAY,CAAC;AAC7G,WAAS,SAAS,GAAG,IAAI,IAAI,KAAK,GAAG,OAAO,UAAU,IAAI;AAC5D;AAEO,SAAS,aAAa,MAAc,OAAe,KAAW;AACnE,WAAS,SAAS,GAAG,IAAI,kDAAkD,IAAI;AACjF;;;ACxBA,IAAM,iBAAiB,oBAAI,QAAiC;AAErD,SAAS,yBAAyB,cAA0B,SAAsC;AACvG,MAAI,CAAC,cAAc;AACjB;AAAA,EACF;AAEA,QAAM,EAAE,UAAU,IAAI;AAEtB,MAAI,oBAAoB,eAAe,IAAI,YAAY;AACvD,MAAI,CAAC,mBAAmB;AACtB,wBAAoB,oBAAI,IAAY;AACpC,mBAAe,IAAI,cAAc,iBAAiB;AAElD,UAAM,WAAW;AAAA,MACf,KAAK,aAAa,QAAQ,IAAI,KAAK,aAAa,OAAO;AAAA,MACvD,MAAM,aAAa,QAAQ,KAAK,KAAK,aAAa,OAAO;AAAA,MACzD,MAAM,aAAa,QAAQ,KAAK,KAAK,aAAa,OAAO;AAAA,MACzD,OAAO,aAAa,QAAQ,MAAM,KAAK,aAAa,OAAO;AAAA,IAC7D;AAEA,UAAM,cACJ,CAAC,WACD,IAAI,SAAS;AACX,UAAI,kBAAmB,OAAO,GAAG;AAC/B,eAAO,GAAG,IAAI;AAAA,MAChB;AAAA,IACF;AAEF,iBAAa,QAAQ,MAAM,YAAY,SAAS,GAAG;AACnD,iBAAa,QAAQ,OAAO,YAAY,SAAS,IAAI;AACrD,iBAAa,QAAQ,OAAO,YAAY,SAAS,IAAI;AACrD,iBAAa,QAAQ,QAAQ,YAAY,SAAS,KAAK;AAAA,EACzD;AAGA,QAAM,UAAU;AAChB,QAAM,WAAW,OAAO,UAAU,eAAe,KAAK,SAAS,SAAS,IACnE,OAAO,yBAAyB,SAAS,SAAS,GAAG,QACtD;AACJ,QAAM,SAAS,YAAa,CAAC;AAC7B,SAAO,QAAQ,CAAC,SAAkB;AAChC,QAAI,MAAM;AACR,wBAAmB,IAAI,SAAS;AAAA,IAClC,OAAO;AACL,wBAAmB,OAAO,SAAS;AAAA,IACrC;AAAA,EACF;AAKA,SAAO,eAAe,SAAS,WAAW,EAAE,OAAO,QAAQ,UAAU,MAAM,cAAc,MAAM,YAAY,KAAK,CAAC;AACnH;;;AC9CA,IAAM,cAAc;AAEpB,SAAS,SAAS,KAAkB;AAClC,QAAM,QAAQ,YAAY,KAAK,IAAI,KAAK,CAAC;AACzC,MAAI,CAAC,OAAO;AACV,UAAM,IAAI,MAAM,uBAAuB,GAAG,GAAG;AAAA,EAC/C;AAEA,QAAM,SAAS,MAAM,CAAC;AACtB,QAAM,aACJ,OAAO,WAAW,IACd,OACG,MAAM,EAAE,EACR,IAAI,CAAC,SAAS,OAAO,IAAI,EACzB,KAAK,EAAE,IACV;AAEN,SAAO;AAAA,IACL,GAAG,SAAS,WAAW,MAAM,GAAG,CAAC,GAAG,EAAE;AAAA,IACtC,GAAG,SAAS,WAAW,MAAM,GAAG,CAAC,GAAG,EAAE;AAAA,IACtC,GAAG,SAAS,WAAW,MAAM,GAAG,CAAC,GAAG,EAAE;AAAA,EACxC;AACF;AAEA,SAAS,SAAS,EAAE,GAAG,GAAG,EAAE,GAAgB;AAC1C,SAAO,IAAI,CAAC,GAAG,GAAG,CAAC,EAAE,IAAI,CAAC,YAAY,KAAK,MAAM,OAAO,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC;AACnG;AAEA,SAAS,OAAO,MAAW,QAAa,QAAqB;AAC3D,SAAO;AAAA,IACL,GAAG,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK;AAAA,IAClC,GAAG,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK;AAAA,IAClC,GAAG,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK;AAAA,EACpC;AACF;AAEA,IAAM,QAAa,EAAE,GAAG,KAAK,GAAG,KAAK,GAAG,IAAI;AAC5C,IAAM,QAAa,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAItC,IAAM,eAA2D,EAAE,IAAI,MAAM,KAAK,KAAK,KAAK,MAAM,KAAK,KAAK,KAAK,IAAI;AACrH,IAAM,gBAA6D;AAAA,EACjE,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AACP;AAKO,SAAS,2BAA2B,WAAuC;AAChF,QAAM,OAAO,SAAS,SAAS;AAE/B,SAAO;AAAA,IACL,IAAI,SAAS,OAAO,MAAM,OAAO,aAAa,EAAE,CAAC,CAAC;AAAA,IAClD,KAAK,SAAS,OAAO,MAAM,OAAO,aAAa,GAAG,CAAC,CAAC;AAAA,IACpD,KAAK,SAAS,OAAO,MAAM,OAAO,aAAa,GAAG,CAAC,CAAC;AAAA,IACpD,KAAK,SAAS,OAAO,MAAM,OAAO,aAAa,GAAG,CAAC,CAAC;AAAA,IACpD,KAAK,SAAS,OAAO,MAAM,OAAO,aAAa,GAAG,CAAC,CAAC;AAAA,IACpD,KAAK,SAAS,IAAI;AAAA,IAClB,KAAK,SAAS,OAAO,MAAM,OAAO,cAAc,GAAG,CAAC,CAAC;AAAA,IACrD,KAAK,SAAS,OAAO,MAAM,OAAO,cAAc,GAAG,CAAC,CAAC;AAAA,IACrD,KAAK,SAAS,OAAO,MAAM,OAAO,cAAc,GAAG,CAAC,CAAC;AAAA,IACrD,KAAK,SAAS,OAAO,MAAM,OAAO,cAAc,GAAG,CAAC,CAAC;AAAA,IACrD,KAAK,SAAS,OAAO,MAAM,OAAO,cAAc,GAAG,CAAC,CAAC;AAAA,EACvD;AACF;AAMO,SAAS,gCACd,WACA,MACwC;AACxC,QAAM,QAAQ,2BAA2B,SAAS;AAElD,SAAO,OAAO,YAAY,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAC,OAAO,GAAG,MAAM,CAAC,GAAG,IAAI,GAAG,KAAK,IAAI,GAAG,CAAC,CAAC;AAIjG;AAEA,SAAS,SAAS,EAAE,GAAG,GAAG,EAAE,GAA6C;AACvE,QAAM,KAAK,IAAI;AACf,QAAM,KAAK,IAAI;AACf,QAAM,KAAK,IAAI;AAEf,QAAM,MAAM,KAAK,IAAI,IAAI,IAAI,EAAE;AAC/B,QAAM,MAAM,KAAK,IAAI,IAAI,IAAI,EAAE;AAC/B,QAAM,KAAK,MAAM,OAAO;AAExB,MAAI,QAAQ,KAAK;AACf,WAAO,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,IAAI;AAAA,EAClC;AAEA,QAAM,QAAQ,MAAM;AACpB,QAAM,IAAI,IAAI,MAAM,SAAS,IAAI,MAAM,OAAO,SAAS,MAAM;AAE7D,MAAI;AACJ,MAAI,QAAQ,IAAI;AACd,UAAM,KAAK,MAAM,SAAS,KAAK,KAAK,IAAI,MAAM;AAAA,EAChD,WAAW,QAAQ,IAAI;AACrB,UAAM,KAAK,MAAM,QAAQ,KAAK;AAAA,EAChC,OAAO;AACL,UAAM,KAAK,MAAM,QAAQ,KAAK;AAAA,EAChC;AAEA,SAAO,EAAE,GAAG,GAAG,IAAI,KAAK,GAAG,IAAI,IAAI;AACrC;AAMO,SAAS,gBAAgB,KAAa,YAAoB,GAAW;AAC1E,QAAM,EAAE,GAAG,GAAG,EAAE,IAAI,SAAS,SAAS,GAAG,CAAC;AAC1C,QAAM,QAAQ,CAAC,UAAkB,OAAO,MAAM,QAAQ,SAAS,CAAC;AAEhE,SAAO,GAAG,MAAM,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC;AAC7C;","names":[]}
package/dist/index.d.cts CHANGED
@@ -53,6 +53,13 @@ declare function fileToBase64Native(file: File): Promise<string>;
53
53
  declare function fileToBase64(file: File, quality?: number): Promise<string>;
54
54
 
55
55
  declare function getCookie(name: string): string | undefined;
56
+ interface SetCookieOptions {
57
+ /** Days until the cookie expires. Omit for a session cookie (cleared when the browser closes). */
58
+ days?: number;
59
+ path?: string;
60
+ }
61
+ declare function setCookie(name: string, value: string, options?: SetCookieOptions): void;
62
+ declare function removeCookie(name: string, path?: string): void;
56
63
 
57
64
  type WindowLike = Window & typeof globalThis;
58
65
  declare function createConsoleDebugSwitch(targetWindow: WindowLike, options: {
@@ -76,4 +83,4 @@ declare function generateNamedTailwindColorScale<T extends string>(baseColor: st
76
83
  */
77
84
  declare function hexToHslTriplet(hex: string, precision?: number): string;
78
85
 
79
- export { LONG_DATE_FORMAT, type RecursivePartial, type RecursiveRecord, SHORT_DATETIME_FORMAT, SHORT_DATE_FORMAT, type TailwindColorScale, type TailwindShade, allCombinations, checkRequiredKeys, cloned, createConsoleDebugSwitch, downloadAndFormatImage, enabledIf, escapeName, fileToBase64, fileToBase64Native, forcedType, formattedDate, generateNamedTailwindColorScale, generateTailwindColorScale, getCookie, getKeys, getLazyValue, getLazyValueAsync, guessImageMimeType, hexToHslTriplet, isImageMimeType, isPathMatched, longFormattedDate, makeCallable, notNone, optionalDate, preventDefault, raises, requireExclusiveKeys, safeFileName, setKeyValueToObjectIfValue, shortFormattedDate, shortFormattedDateTime, slugify, suppress, transformExceptions, withAttributes };
86
+ export { LONG_DATE_FORMAT, type RecursivePartial, type RecursiveRecord, SHORT_DATETIME_FORMAT, SHORT_DATE_FORMAT, type SetCookieOptions, type TailwindColorScale, type TailwindShade, allCombinations, checkRequiredKeys, cloned, createConsoleDebugSwitch, downloadAndFormatImage, enabledIf, escapeName, fileToBase64, fileToBase64Native, forcedType, formattedDate, generateNamedTailwindColorScale, generateTailwindColorScale, getCookie, getKeys, getLazyValue, getLazyValueAsync, guessImageMimeType, hexToHslTriplet, isImageMimeType, isPathMatched, longFormattedDate, makeCallable, notNone, optionalDate, preventDefault, raises, removeCookie, requireExclusiveKeys, safeFileName, setCookie, setKeyValueToObjectIfValue, shortFormattedDate, shortFormattedDateTime, slugify, suppress, transformExceptions, withAttributes };
package/dist/index.d.ts CHANGED
@@ -53,6 +53,13 @@ declare function fileToBase64Native(file: File): Promise<string>;
53
53
  declare function fileToBase64(file: File, quality?: number): Promise<string>;
54
54
 
55
55
  declare function getCookie(name: string): string | undefined;
56
+ interface SetCookieOptions {
57
+ /** Days until the cookie expires. Omit for a session cookie (cleared when the browser closes). */
58
+ days?: number;
59
+ path?: string;
60
+ }
61
+ declare function setCookie(name: string, value: string, options?: SetCookieOptions): void;
62
+ declare function removeCookie(name: string, path?: string): void;
56
63
 
57
64
  type WindowLike = Window & typeof globalThis;
58
65
  declare function createConsoleDebugSwitch(targetWindow: WindowLike, options: {
@@ -76,4 +83,4 @@ declare function generateNamedTailwindColorScale<T extends string>(baseColor: st
76
83
  */
77
84
  declare function hexToHslTriplet(hex: string, precision?: number): string;
78
85
 
79
- export { LONG_DATE_FORMAT, type RecursivePartial, type RecursiveRecord, SHORT_DATETIME_FORMAT, SHORT_DATE_FORMAT, type TailwindColorScale, type TailwindShade, allCombinations, checkRequiredKeys, cloned, createConsoleDebugSwitch, downloadAndFormatImage, enabledIf, escapeName, fileToBase64, fileToBase64Native, forcedType, formattedDate, generateNamedTailwindColorScale, generateTailwindColorScale, getCookie, getKeys, getLazyValue, getLazyValueAsync, guessImageMimeType, hexToHslTriplet, isImageMimeType, isPathMatched, longFormattedDate, makeCallable, notNone, optionalDate, preventDefault, raises, requireExclusiveKeys, safeFileName, setKeyValueToObjectIfValue, shortFormattedDate, shortFormattedDateTime, slugify, suppress, transformExceptions, withAttributes };
86
+ export { LONG_DATE_FORMAT, type RecursivePartial, type RecursiveRecord, SHORT_DATETIME_FORMAT, SHORT_DATE_FORMAT, type SetCookieOptions, type TailwindColorScale, type TailwindShade, allCombinations, checkRequiredKeys, cloned, createConsoleDebugSwitch, downloadAndFormatImage, enabledIf, escapeName, fileToBase64, fileToBase64Native, forcedType, formattedDate, generateNamedTailwindColorScale, generateTailwindColorScale, getCookie, getKeys, getLazyValue, getLazyValueAsync, guessImageMimeType, hexToHslTriplet, isImageMimeType, isPathMatched, longFormattedDate, makeCallable, notNone, optionalDate, preventDefault, raises, removeCookie, requireExclusiveKeys, safeFileName, setCookie, setKeyValueToObjectIfValue, shortFormattedDate, shortFormattedDateTime, slugify, suppress, transformExceptions, withAttributes };
package/dist/index.js CHANGED
@@ -323,6 +323,14 @@ function getCookie(name) {
323
323
  }
324
324
  return void 0;
325
325
  }
326
+ function setCookie(name, value, options = {}) {
327
+ const { days, path = "/" } = options;
328
+ const expires = days === void 0 ? "" : `; expires=${new Date(Date.now() + days * 864e5).toUTCString()}`;
329
+ document.cookie = `${name}=${value}${expires}; path=${path}`;
330
+ }
331
+ function removeCookie(name, path = "/") {
332
+ document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=${path}`;
333
+ }
326
334
 
327
335
  // src/console/index.ts
328
336
  var patchedWindows = /* @__PURE__ */ new WeakMap();
@@ -477,8 +485,10 @@ export {
477
485
  optionalDate,
478
486
  preventDefault,
479
487
  raises,
488
+ removeCookie,
480
489
  requireExclusiveKeys,
481
490
  safeFileName,
491
+ setCookie,
482
492
  setKeyValueToObjectIfValue,
483
493
  shortFormattedDate,
484
494
  shortFormattedDateTime,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types/index.ts","../src/arrays/index.ts","../src/functions/index.ts","../src/objects/index.ts","../src/strings/index.ts","../src/dates/_format.ts","../src/dates/index.ts","../src/files/index.ts","../src/cookies/index.ts","../src/console/index.ts","../src/colors/index.ts"],"sourcesContent":["export const getKeys = Object.keys as <T extends object>(obj: T) => Array<keyof T>\n\nexport type RecursivePartial<T> = { [P in keyof T]?: RecursivePartial<T[P]> }\n\nexport type RecursiveRecord = {\n [key: string]: string | number | boolean | RecursiveRecord | Array<RecursiveRecord>\n}\n\nexport function forcedType<T>(obj: unknown): T {\n return obj as unknown as T\n}\n","export function notNone<T>(value: T | null | undefined): value is T {\n return value !== null && value !== undefined\n}\n\nfunction combinationsOfSize<T>(items: T[], size: number): T[][] {\n if (size === 0) {\n return [[]]\n }\n if (size > items.length) {\n return []\n }\n const [first, ...rest] = items\n const withFirst = combinationsOfSize(rest, size - 1).map((combination) => [first, ...combination])\n const withoutFirst = combinationsOfSize(rest, size)\n return [...withFirst, ...withoutFirst]\n}\n\nexport function allCombinations<T>(options: T[]): T[][] {\n const result: T[][] = []\n for (let size = 1; size <= options.length; size++) {\n result.push(...combinationsOfSize(options, size))\n }\n return result\n}\n","export function withAttributes<Fn extends (...args: never[]) => unknown, Attrs extends Record<string, unknown>>(\n fn: Fn,\n attributes: Attrs\n): Fn & Attrs {\n for (const key of Object.keys(attributes)) {\n // Object.defineProperty (unlike a plain `fn[key] = value` assignment) always creates/\n // overwrites an own property, even when key is \"__proto__\" - a plain assignment would instead\n // be intercepted by Object.prototype's special __proto__ accessor and reassign fn's own\n // prototype instead of setting a property on it.\n Object.defineProperty(fn, key, {\n value: attributes[key],\n writable: true,\n configurable: true,\n enumerable: true,\n })\n }\n return fn as Fn & Attrs\n}\n\nexport function makeCallable<T, R>(originalCallable: (arg: T) => R) {\n return (data: T) => () => originalCallable(data)\n}\n\nexport function getLazyValue<T>(input: T | (() => T)): T {\n if (typeof input === 'function') {\n return (input as () => T)()\n }\n return input\n}\n\nexport async function getLazyValueAsync<T>(input: T | (() => Promise<T>) | (() => T)): Promise<T> {\n if (typeof input === 'function') {\n const result = (input as () => Promise<T>)()\n if (result instanceof Promise) {\n return await result\n }\n return result as unknown as T\n }\n return input\n}\n\nexport function suppress<T, ERT>(\n exceptions: Array<new (message?: string) => Error>,\n fn: () => T,\n onError?: (error: unknown) => ERT\n): T | ERT | undefined {\n try {\n return fn()\n } catch (error) {\n if (exceptions.some((exception) => error instanceof exception)) {\n return onError ? onError(error) : undefined\n }\n throw error\n }\n}\n\nexport function preventDefault<E extends Event, R>(callable: (event: E) => R): (event: E) => Promise<Awaited<R>> {\n return async function (event: E): Promise<Awaited<R>> {\n event.preventDefault()\n return await callable(event)\n }\n}\n\nexport function isPathMatched(pathname: string, pattern: RegExp, exemptPatterns: RegExp[] = []): boolean {\n if (exemptPatterns.some((exempt) => exempt.test(pathname))) {\n return false\n }\n return pattern.test(pathname)\n}\n\nexport function raises(error: Error): (...args: unknown[]) => never {\n return () => {\n throw error\n }\n}\n\nexport function cloned<Fn extends (...args: never[]) => unknown>(fn: Fn): Fn {\n return ((...args: Parameters<Fn>) => fn(...args)) as Fn\n}\n\nexport function enabledIf<R>(condition: boolean | (() => boolean), options: { ifNotEnabledReturnValue: R }) {\n const enabled = typeof condition === 'function' ? condition() : condition\n\n return function <Fn extends (...args: never[]) => R>(fn: Fn): Fn {\n if (!enabled) {\n return cloned((() => options.ifNotEnabledReturnValue) as Fn)\n }\n return cloned(fn)\n }\n}\n\nexport function transformExceptions<E extends Error>(\n exceptionTypes: Array<new (...args: never[]) => E>,\n transform: (error: E) => Error,\n options: { keepOriginal?: boolean } = {}\n) {\n const { keepOriginal = true } = options\n\n return function <Fn extends (...args: never[]) => unknown>(fn: Fn): Fn {\n return ((...args: Parameters<Fn>) => {\n try {\n return fn(...args)\n } catch (error) {\n if (!exceptionTypes.some((ExceptionType) => error instanceof ExceptionType)) {\n throw error\n }\n const newError = transform(error as E)\n if (keepOriginal) {\n newError.cause = error\n }\n throw newError\n }\n }) as Fn\n }\n}\n","export function checkRequiredKeys<T extends Record<string, unknown>, C extends Record<string, Array<keyof T>>>(\n obj: T,\n conditions: C\n): keyof C {\n const matchingConditions = Object.entries(conditions).filter(\n ([, keys]) =>\n keys.every((key) => obj[key] !== undefined) &&\n Object.keys(obj).every((key) => keys.includes(key as keyof T) || obj[key] === undefined)\n )\n\n if (matchingConditions.length !== 1) {\n throw new Error(`Object keys do not match exactly one required condition. ${JSON.stringify(conditions)}`)\n }\n\n return matchingConditions[0][0] as keyof C\n}\n\nexport function requireExclusiveKeys<T extends Record<string, unknown>, C extends Record<string, Array<keyof T>>>(\n conditions: C,\n options: { allowEmpty?: boolean } = {}\n) {\n const conditionEntries = Object.entries(conditions) as Array<[string, Array<keyof T>]>\n if (conditionEntries.length === 0) {\n throw new Error('At least one condition must be provided.')\n }\n const { allowEmpty = false } = options\n const governedKeys = new Set(conditionEntries.flatMap(([, keys]) => keys))\n\n return function <Fn extends (arg: T) => unknown>(fn: Fn): Fn {\n return ((arg: T) => {\n // Only keys that are actually governed by a condition are considered - unlike\n // checkRequiredKeys, any other key on `arg` is fully unconstrained and ignored here\n // regardless of its value, since this is meant to validate one options object that may\n // legitimately carry other, unrelated fields alongside the mutually-exclusive ones.\n const provided = new Set(\n Object.keys(arg).filter((key) => governedKeys.has(key as keyof T) && arg[key] !== undefined)\n )\n\n if (allowEmpty && provided.size === 0) {\n return fn(arg)\n }\n\n const matches = conditionEntries.filter(\n ([, keys]) => keys.length === provided.size && keys.every((key) => provided.has(key as string))\n )\n if (matches.length !== 1) {\n throw new Error(`Object keys do not match exactly one required condition. ${JSON.stringify(conditions)}`)\n }\n return fn(arg)\n }) as Fn\n }\n}\n\nexport function setKeyValueToObjectIfValue(key: string, value: unknown, object: Record<string, unknown>) {\n if (value) {\n // Object.defineProperty (unlike a plain `object[key] = value` assignment) always creates/\n // overwrites an own property, even when key is \"__proto__\" - a plain assignment would instead\n // be intercepted by Object.prototype's special __proto__ accessor and reassign this object's\n // prototype instead of setting a property on it.\n Object.defineProperty(object, key, { value, writable: true, configurable: true, enumerable: true })\n }\n}\n","export function slugify(value: string, allowUnicode: boolean = false): string {\n if (allowUnicode) {\n value = value.normalize('NFKC').replace(/[^\\p{L}\\p{N}_\\s-]/gu, '')\n } else {\n value = value\n .normalize('NFKD')\n // eslint-disable-next-line no-control-regex\n .replace(/[^\\x00-\\x7F]/g, '')\n .replace(/[\\r\\n]+/g, ' ')\n .trim()\n .replace(/[^\\w\\s-]/g, '')\n }\n\n value = value.toLowerCase()\n\n return value.replace(/[-\\s]+/g, '-').replace(/^[-_]+|[-_]+$/g, '')\n}\n","import { format } from 'date-fns'\n\nexport function formatDate(date: Date, pattern: string): string {\n return format(date, pattern)\n}\n","import { formatDate } from './_format'\n\nexport const LONG_DATE_FORMAT = \"EEEE, MMMM dd, yyyy 'at' hh:mm a\"\nexport const SHORT_DATE_FORMAT = 'dd.MM.yyyy'\nexport const SHORT_DATETIME_FORMAT = 'dd.MM.yyyy HH:mm a'\n\nexport function formattedDate(pattern: string, date: Date = new Date()): string {\n return formatDate(date, pattern)\n}\n\nexport function longFormattedDate(date: Date = new Date()): string {\n return formattedDate(LONG_DATE_FORMAT, date)\n}\n\nexport function shortFormattedDate(date: Date = new Date()): string {\n return formattedDate(SHORT_DATE_FORMAT, date)\n}\n\nexport function shortFormattedDateTime(date: Date = new Date()): string {\n return formattedDate(SHORT_DATETIME_FORMAT, date)\n}\n\nexport function optionalDate(date?: string): Date | undefined {\n return date ? new Date(date) : undefined\n}\n","type MimeType = 'image/png' | 'image/jpeg' | 'image/webp'\n\nexport function guessImageMimeType(filename: string): MimeType {\n const withoutQueryOrHash = filename.split(/[?#]/)[0]\n const extension = withoutQueryOrHash.split('.').pop()?.toLowerCase()\n switch (extension) {\n case 'png':\n return 'image/png'\n case 'jfif':\n case 'jpg':\n case 'jpeg':\n return 'image/jpeg'\n case 'webp':\n return 'image/webp'\n default:\n return 'image/png'\n }\n}\n\nexport function isImageMimeType(mimeType: string): mimeType is MimeType {\n return mimeType === 'image/png' || mimeType === 'image/jpeg' || mimeType === 'image/webp'\n}\n\nexport function escapeName(name: string): string {\n return name.replace(/[^a-zA-Z0-9-_.]/g, '_')\n}\n\nexport function safeFileName(filename: string, maxLength: number = 255): string {\n if (filename.length <= maxLength) return filename\n\n const dotIndex = filename.lastIndexOf('.')\n const hasExtension = dotIndex > 0\n const extension = escapeName(hasExtension ? filename.slice(dotIndex) : '')\n const name = escapeName(hasExtension ? filename.slice(0, dotIndex) : filename)\n\n return name.slice(0, Math.max(0, maxLength - extension.length)) + extension\n}\n\nexport async function downloadAndFormatImage(\n src: string,\n name: string = 'image.png',\n mimeType: MimeType = guessImageMimeType(name),\n quality: number = 1\n): Promise<void> {\n name = safeFileName(name)\n try {\n const img = new Image()\n img.crossOrigin = 'anonymous'\n\n await new Promise((resolve, reject) => {\n img.onload = resolve\n img.onerror = reject\n img.src = src\n })\n\n const canvas = document.createElement('canvas')\n canvas.width = img.width\n canvas.height = img.height\n const ctx = canvas.getContext('2d')\n\n if (!ctx) {\n throw new Error('Could not get canvas context')\n }\n\n ctx.drawImage(img, 0, 0)\n\n const blob = await new Promise<Blob | null>((resolve) => {\n canvas.toBlob(resolve, mimeType, quality)\n })\n\n if (!blob) {\n throw new Error('Could not generate blob')\n }\n\n const link = document.createElement('a')\n const downloadUrl = URL.createObjectURL(blob)\n try {\n link.href = downloadUrl\n link.download = name\n document.body.appendChild(link)\n link.click()\n } finally {\n document.body.removeChild(link)\n URL.revokeObjectURL(downloadUrl)\n }\n } catch (error) {\n console.error('Failed to download image:', error)\n }\n}\n\nexport async function fileToBase64Native(file: File): Promise<string> {\n const result = await new Promise<string | ArrayBuffer | null>((resolve, reject) => {\n const reader = new FileReader()\n reader.readAsDataURL(file)\n reader.onload = () => resolve(reader.result)\n reader.onerror = (error) => reject(error)\n })\n\n if (typeof result === 'string') {\n return result\n } else {\n throw new Error('Failed to read file as Data URL')\n }\n}\n\nexport async function fileToBase64(file: File, quality: number = 1): Promise<string> {\n if (isImageMimeType(file.type)) {\n const img = new Image()\n const url = URL.createObjectURL(file)\n try {\n await new Promise<void>((resolve, reject) => {\n img.onload = () => resolve()\n img.onerror = () => reject(new Error('Failed to load image for metadata removal'))\n img.src = url\n })\n\n const canvas = document.createElement('canvas')\n canvas.width = img.width\n canvas.height = img.height\n\n const ctx = canvas.getContext('2d')\n if (!ctx) {\n throw new Error('Failed to get canvas context')\n }\n ctx.drawImage(img, 0, 0)\n\n const cleanDataUrl = canvas.toDataURL(file.type, quality)\n if (cleanDataUrl === 'data:,') {\n return await fileToBase64Native(file)\n }\n\n return cleanDataUrl\n } finally {\n URL.revokeObjectURL(url)\n }\n } else {\n return await fileToBase64Native(file)\n }\n}\n","export function getCookie(name: string): string | undefined {\n for (const pair of document.cookie.split('; ')) {\n const separatorIndex = pair.indexOf('=')\n if (separatorIndex === -1) {\n continue\n }\n if (pair.slice(0, separatorIndex) === name) {\n return pair.slice(separatorIndex + 1)\n }\n }\n return undefined\n}\n","type ConsoleMethod = (...args: unknown[]) => void\ntype WindowLike = Window & typeof globalThis\n\nconst patchedWindows = new WeakMap<WindowLike, Set<string>>()\n\nexport function createConsoleDebugSwitch(targetWindow: WindowLike, options: { namespace: string }): void {\n if (!targetWindow) {\n return\n }\n\n const { namespace } = options\n\n let enabledNamespaces = patchedWindows.get(targetWindow)\n if (!enabledNamespaces) {\n enabledNamespaces = new Set<string>()\n patchedWindows.set(targetWindow, enabledNamespaces)\n\n const original = {\n log: targetWindow.console.log.bind(targetWindow.console),\n info: targetWindow.console.info.bind(targetWindow.console),\n warn: targetWindow.console.warn.bind(targetWindow.console),\n error: targetWindow.console.error.bind(targetWindow.console),\n }\n\n const conditional =\n (method: ConsoleMethod): ConsoleMethod =>\n (...args) => {\n if (enabledNamespaces!.size > 0) {\n method(...args)\n }\n }\n\n targetWindow.console.log = conditional(original.log)\n targetWindow.console.info = conditional(original.info)\n targetWindow.console.warn = conditional(original.warn)\n targetWindow.console.error = conditional(original.error)\n }\n\n type Namespace = { debug: (enabled: boolean) => void }\n const globals = targetWindow as unknown as Record<string, Namespace | undefined>\n const existing = Object.prototype.hasOwnProperty.call(globals, namespace)\n ? (Object.getOwnPropertyDescriptor(globals, namespace)?.value as Namespace | undefined)\n : undefined\n const target = existing ?? ({} as Namespace)\n target.debug = (flag: boolean) => {\n if (flag) {\n enabledNamespaces!.add(namespace)\n } else {\n enabledNamespaces!.delete(namespace)\n }\n }\n // Object.defineProperty (unlike a plain `globals[namespace] = target` assignment) always\n // creates/overwrites an own property, even when namespace is a name like \"__proto__\" that\n // would otherwise be intercepted by Object.prototype's special __proto__ accessor and\n // pollute the shared prototype instead of setting a property on this specific object.\n Object.defineProperty(globals, namespace, { value: target, writable: true, configurable: true, enumerable: true })\n}\n","export type TailwindShade = 50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 950\n\nexport type TailwindColorScale = Record<TailwindShade, string>\n\ninterface Rgb {\n r: number\n g: number\n b: number\n}\n\nconst HEX_PATTERN = /^#?([0-9a-f]{3}|[0-9a-f]{6})$/i\n\nfunction hexToRgb(hex: string): Rgb {\n const match = HEX_PATTERN.exec(hex.trim())\n if (!match) {\n throw new Error(`Invalid hex color: \"${hex}\"`)\n }\n\n const digits = match[1]\n const normalized =\n digits.length === 3\n ? digits\n .split('')\n .map((char) => char + char)\n .join('')\n : digits\n\n return {\n r: parseInt(normalized.slice(0, 2), 16),\n g: parseInt(normalized.slice(2, 4), 16),\n b: parseInt(normalized.slice(4, 6), 16),\n }\n}\n\nfunction rgbToHex({ r, g, b }: Rgb): string {\n return `#${[r, g, b].map((channel) => Math.round(channel).toString(16).padStart(2, '0')).join('')}`\n}\n\nfunction mixRgb(base: Rgb, target: Rgb, weight: number): Rgb {\n return {\n r: base.r + (target.r - base.r) * weight,\n g: base.g + (target.g - base.g) * weight,\n b: base.b + (target.b - base.b) * weight,\n }\n}\n\nconst WHITE: Rgb = { r: 255, g: 255, b: 255 }\nconst BLACK: Rgb = { r: 0, g: 0, b: 0 }\n\n// Weight of white/black mixed into the base color at each shade, tuned so 500 is the input\n// color unchanged and the rest approximate the spread of Tailwind's own default palettes.\nconst TINT_WEIGHTS: Record<50 | 100 | 200 | 300 | 400, number> = { 50: 0.95, 100: 0.9, 200: 0.75, 300: 0.6, 400: 0.3 }\nconst SHADE_WEIGHTS: Record<600 | 700 | 800 | 900 | 950, number> = {\n 600: 0.15,\n 700: 0.3,\n 800: 0.45,\n 900: 0.6,\n 950: 0.8,\n}\n\n/**\n * Generates a Tailwind-style 50-950 color scale from a single base hex color, treated as the 500 shade.\n */\nexport function generateTailwindColorScale(baseColor: string): TailwindColorScale {\n const base = hexToRgb(baseColor)\n\n return {\n 50: rgbToHex(mixRgb(base, WHITE, TINT_WEIGHTS[50])),\n 100: rgbToHex(mixRgb(base, WHITE, TINT_WEIGHTS[100])),\n 200: rgbToHex(mixRgb(base, WHITE, TINT_WEIGHTS[200])),\n 300: rgbToHex(mixRgb(base, WHITE, TINT_WEIGHTS[300])),\n 400: rgbToHex(mixRgb(base, WHITE, TINT_WEIGHTS[400])),\n 500: rgbToHex(base),\n 600: rgbToHex(mixRgb(base, BLACK, SHADE_WEIGHTS[600])),\n 700: rgbToHex(mixRgb(base, BLACK, SHADE_WEIGHTS[700])),\n 800: rgbToHex(mixRgb(base, BLACK, SHADE_WEIGHTS[800])),\n 900: rgbToHex(mixRgb(base, BLACK, SHADE_WEIGHTS[900])),\n 950: rgbToHex(mixRgb(base, BLACK, SHADE_WEIGHTS[950])),\n }\n}\n\n/**\n * Like {@link generateTailwindColorScale}, but prefixes each shade with `name` (e.g. `primary500`)\n * so multiple scales can be spread into one flat palette object.\n */\nexport function generateNamedTailwindColorScale<T extends string>(\n baseColor: string,\n name: T\n): Record<`${T}${TailwindShade}`, string> {\n const scale = generateTailwindColorScale(baseColor)\n\n return Object.fromEntries(Object.entries(scale).map(([shade, hex]) => [`${name}${shade}`, hex])) as Record<\n `${T}${TailwindShade}`,\n string\n >\n}\n\nfunction rgbToHsl({ r, g, b }: Rgb): { h: number; s: number; l: number } {\n const rN = r / 255\n const gN = g / 255\n const bN = b / 255\n\n const max = Math.max(rN, gN, bN)\n const min = Math.min(rN, gN, bN)\n const l = (max + min) / 2\n\n if (max === min) {\n return { h: 0, s: 0, l: l * 100 }\n }\n\n const delta = max - min\n const s = l > 0.5 ? delta / (2 - max - min) : delta / (max + min)\n\n let h: number\n if (max === rN) {\n h = ((gN - bN) / delta + (gN < bN ? 6 : 0)) * 60\n } else if (max === gN) {\n h = ((bN - rN) / delta + 2) * 60\n } else {\n h = ((rN - gN) / delta + 4) * 60\n }\n\n return { h, s: s * 100, l: l * 100 }\n}\n\n/**\n * Formats a hex color as the \"H S% L%\" triplet shadcn/Tailwind CSS variable themes expect,\n * e.g. for `--primary: 240 5.9% 10%;` consumed as `hsl(var(--primary))`.\n */\nexport function hexToHslTriplet(hex: string, precision: number = 1): string {\n const { h, s, l } = rgbToHsl(hexToRgb(hex))\n const round = (value: number) => Number(value.toFixed(precision))\n\n return `${round(h)} ${round(s)}% ${round(l)}%`\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/types/index.ts","../src/arrays/index.ts","../src/functions/index.ts","../src/objects/index.ts","../src/strings/index.ts","../src/dates/_format.ts","../src/dates/index.ts","../src/files/index.ts","../src/cookies/index.ts","../src/console/index.ts","../src/colors/index.ts"],"sourcesContent":["export const getKeys = Object.keys as <T extends object>(obj: T) => Array<keyof T>\n\nexport type RecursivePartial<T> = { [P in keyof T]?: RecursivePartial<T[P]> }\n\nexport type RecursiveRecord = {\n [key: string]: string | number | boolean | RecursiveRecord | Array<RecursiveRecord>\n}\n\nexport function forcedType<T>(obj: unknown): T {\n return obj as unknown as T\n}\n","export function notNone<T>(value: T | null | undefined): value is T {\n return value !== null && value !== undefined\n}\n\nfunction combinationsOfSize<T>(items: T[], size: number): T[][] {\n if (size === 0) {\n return [[]]\n }\n if (size > items.length) {\n return []\n }\n const [first, ...rest] = items\n const withFirst = combinationsOfSize(rest, size - 1).map((combination) => [first, ...combination])\n const withoutFirst = combinationsOfSize(rest, size)\n return [...withFirst, ...withoutFirst]\n}\n\nexport function allCombinations<T>(options: T[]): T[][] {\n const result: T[][] = []\n for (let size = 1; size <= options.length; size++) {\n result.push(...combinationsOfSize(options, size))\n }\n return result\n}\n","export function withAttributes<Fn extends (...args: never[]) => unknown, Attrs extends Record<string, unknown>>(\n fn: Fn,\n attributes: Attrs\n): Fn & Attrs {\n for (const key of Object.keys(attributes)) {\n // Object.defineProperty (unlike a plain `fn[key] = value` assignment) always creates/\n // overwrites an own property, even when key is \"__proto__\" - a plain assignment would instead\n // be intercepted by Object.prototype's special __proto__ accessor and reassign fn's own\n // prototype instead of setting a property on it.\n Object.defineProperty(fn, key, {\n value: attributes[key],\n writable: true,\n configurable: true,\n enumerable: true,\n })\n }\n return fn as Fn & Attrs\n}\n\nexport function makeCallable<T, R>(originalCallable: (arg: T) => R) {\n return (data: T) => () => originalCallable(data)\n}\n\nexport function getLazyValue<T>(input: T | (() => T)): T {\n if (typeof input === 'function') {\n return (input as () => T)()\n }\n return input\n}\n\nexport async function getLazyValueAsync<T>(input: T | (() => Promise<T>) | (() => T)): Promise<T> {\n if (typeof input === 'function') {\n const result = (input as () => Promise<T>)()\n if (result instanceof Promise) {\n return await result\n }\n return result as unknown as T\n }\n return input\n}\n\nexport function suppress<T, ERT>(\n exceptions: Array<new (message?: string) => Error>,\n fn: () => T,\n onError?: (error: unknown) => ERT\n): T | ERT | undefined {\n try {\n return fn()\n } catch (error) {\n if (exceptions.some((exception) => error instanceof exception)) {\n return onError ? onError(error) : undefined\n }\n throw error\n }\n}\n\nexport function preventDefault<E extends Event, R>(callable: (event: E) => R): (event: E) => Promise<Awaited<R>> {\n return async function (event: E): Promise<Awaited<R>> {\n event.preventDefault()\n return await callable(event)\n }\n}\n\nexport function isPathMatched(pathname: string, pattern: RegExp, exemptPatterns: RegExp[] = []): boolean {\n if (exemptPatterns.some((exempt) => exempt.test(pathname))) {\n return false\n }\n return pattern.test(pathname)\n}\n\nexport function raises(error: Error): (...args: unknown[]) => never {\n return () => {\n throw error\n }\n}\n\nexport function cloned<Fn extends (...args: never[]) => unknown>(fn: Fn): Fn {\n return ((...args: Parameters<Fn>) => fn(...args)) as Fn\n}\n\nexport function enabledIf<R>(condition: boolean | (() => boolean), options: { ifNotEnabledReturnValue: R }) {\n const enabled = typeof condition === 'function' ? condition() : condition\n\n return function <Fn extends (...args: never[]) => R>(fn: Fn): Fn {\n if (!enabled) {\n return cloned((() => options.ifNotEnabledReturnValue) as Fn)\n }\n return cloned(fn)\n }\n}\n\nexport function transformExceptions<E extends Error>(\n exceptionTypes: Array<new (...args: never[]) => E>,\n transform: (error: E) => Error,\n options: { keepOriginal?: boolean } = {}\n) {\n const { keepOriginal = true } = options\n\n return function <Fn extends (...args: never[]) => unknown>(fn: Fn): Fn {\n return ((...args: Parameters<Fn>) => {\n try {\n return fn(...args)\n } catch (error) {\n if (!exceptionTypes.some((ExceptionType) => error instanceof ExceptionType)) {\n throw error\n }\n const newError = transform(error as E)\n if (keepOriginal) {\n newError.cause = error\n }\n throw newError\n }\n }) as Fn\n }\n}\n","export function checkRequiredKeys<T extends Record<string, unknown>, C extends Record<string, Array<keyof T>>>(\n obj: T,\n conditions: C\n): keyof C {\n const matchingConditions = Object.entries(conditions).filter(\n ([, keys]) =>\n keys.every((key) => obj[key] !== undefined) &&\n Object.keys(obj).every((key) => keys.includes(key as keyof T) || obj[key] === undefined)\n )\n\n if (matchingConditions.length !== 1) {\n throw new Error(`Object keys do not match exactly one required condition. ${JSON.stringify(conditions)}`)\n }\n\n return matchingConditions[0][0] as keyof C\n}\n\nexport function requireExclusiveKeys<T extends Record<string, unknown>, C extends Record<string, Array<keyof T>>>(\n conditions: C,\n options: { allowEmpty?: boolean } = {}\n) {\n const conditionEntries = Object.entries(conditions) as Array<[string, Array<keyof T>]>\n if (conditionEntries.length === 0) {\n throw new Error('At least one condition must be provided.')\n }\n const { allowEmpty = false } = options\n const governedKeys = new Set(conditionEntries.flatMap(([, keys]) => keys))\n\n return function <Fn extends (arg: T) => unknown>(fn: Fn): Fn {\n return ((arg: T) => {\n // Only keys that are actually governed by a condition are considered - unlike\n // checkRequiredKeys, any other key on `arg` is fully unconstrained and ignored here\n // regardless of its value, since this is meant to validate one options object that may\n // legitimately carry other, unrelated fields alongside the mutually-exclusive ones.\n const provided = new Set(\n Object.keys(arg).filter((key) => governedKeys.has(key as keyof T) && arg[key] !== undefined)\n )\n\n if (allowEmpty && provided.size === 0) {\n return fn(arg)\n }\n\n const matches = conditionEntries.filter(\n ([, keys]) => keys.length === provided.size && keys.every((key) => provided.has(key as string))\n )\n if (matches.length !== 1) {\n throw new Error(`Object keys do not match exactly one required condition. ${JSON.stringify(conditions)}`)\n }\n return fn(arg)\n }) as Fn\n }\n}\n\nexport function setKeyValueToObjectIfValue(key: string, value: unknown, object: Record<string, unknown>) {\n if (value) {\n // Object.defineProperty (unlike a plain `object[key] = value` assignment) always creates/\n // overwrites an own property, even when key is \"__proto__\" - a plain assignment would instead\n // be intercepted by Object.prototype's special __proto__ accessor and reassign this object's\n // prototype instead of setting a property on it.\n Object.defineProperty(object, key, { value, writable: true, configurable: true, enumerable: true })\n }\n}\n","export function slugify(value: string, allowUnicode: boolean = false): string {\n if (allowUnicode) {\n value = value.normalize('NFKC').replace(/[^\\p{L}\\p{N}_\\s-]/gu, '')\n } else {\n value = value\n .normalize('NFKD')\n // eslint-disable-next-line no-control-regex\n .replace(/[^\\x00-\\x7F]/g, '')\n .replace(/[\\r\\n]+/g, ' ')\n .trim()\n .replace(/[^\\w\\s-]/g, '')\n }\n\n value = value.toLowerCase()\n\n return value.replace(/[-\\s]+/g, '-').replace(/^[-_]+|[-_]+$/g, '')\n}\n","import { format } from 'date-fns'\n\nexport function formatDate(date: Date, pattern: string): string {\n return format(date, pattern)\n}\n","import { formatDate } from './_format'\n\nexport const LONG_DATE_FORMAT = \"EEEE, MMMM dd, yyyy 'at' hh:mm a\"\nexport const SHORT_DATE_FORMAT = 'dd.MM.yyyy'\nexport const SHORT_DATETIME_FORMAT = 'dd.MM.yyyy HH:mm a'\n\nexport function formattedDate(pattern: string, date: Date = new Date()): string {\n return formatDate(date, pattern)\n}\n\nexport function longFormattedDate(date: Date = new Date()): string {\n return formattedDate(LONG_DATE_FORMAT, date)\n}\n\nexport function shortFormattedDate(date: Date = new Date()): string {\n return formattedDate(SHORT_DATE_FORMAT, date)\n}\n\nexport function shortFormattedDateTime(date: Date = new Date()): string {\n return formattedDate(SHORT_DATETIME_FORMAT, date)\n}\n\nexport function optionalDate(date?: string): Date | undefined {\n return date ? new Date(date) : undefined\n}\n","type MimeType = 'image/png' | 'image/jpeg' | 'image/webp'\n\nexport function guessImageMimeType(filename: string): MimeType {\n const withoutQueryOrHash = filename.split(/[?#]/)[0]\n const extension = withoutQueryOrHash.split('.').pop()?.toLowerCase()\n switch (extension) {\n case 'png':\n return 'image/png'\n case 'jfif':\n case 'jpg':\n case 'jpeg':\n return 'image/jpeg'\n case 'webp':\n return 'image/webp'\n default:\n return 'image/png'\n }\n}\n\nexport function isImageMimeType(mimeType: string): mimeType is MimeType {\n return mimeType === 'image/png' || mimeType === 'image/jpeg' || mimeType === 'image/webp'\n}\n\nexport function escapeName(name: string): string {\n return name.replace(/[^a-zA-Z0-9-_.]/g, '_')\n}\n\nexport function safeFileName(filename: string, maxLength: number = 255): string {\n if (filename.length <= maxLength) return filename\n\n const dotIndex = filename.lastIndexOf('.')\n const hasExtension = dotIndex > 0\n const extension = escapeName(hasExtension ? filename.slice(dotIndex) : '')\n const name = escapeName(hasExtension ? filename.slice(0, dotIndex) : filename)\n\n return name.slice(0, Math.max(0, maxLength - extension.length)) + extension\n}\n\nexport async function downloadAndFormatImage(\n src: string,\n name: string = 'image.png',\n mimeType: MimeType = guessImageMimeType(name),\n quality: number = 1\n): Promise<void> {\n name = safeFileName(name)\n try {\n const img = new Image()\n img.crossOrigin = 'anonymous'\n\n await new Promise((resolve, reject) => {\n img.onload = resolve\n img.onerror = reject\n img.src = src\n })\n\n const canvas = document.createElement('canvas')\n canvas.width = img.width\n canvas.height = img.height\n const ctx = canvas.getContext('2d')\n\n if (!ctx) {\n throw new Error('Could not get canvas context')\n }\n\n ctx.drawImage(img, 0, 0)\n\n const blob = await new Promise<Blob | null>((resolve) => {\n canvas.toBlob(resolve, mimeType, quality)\n })\n\n if (!blob) {\n throw new Error('Could not generate blob')\n }\n\n const link = document.createElement('a')\n const downloadUrl = URL.createObjectURL(blob)\n try {\n link.href = downloadUrl\n link.download = name\n document.body.appendChild(link)\n link.click()\n } finally {\n document.body.removeChild(link)\n URL.revokeObjectURL(downloadUrl)\n }\n } catch (error) {\n console.error('Failed to download image:', error)\n }\n}\n\nexport async function fileToBase64Native(file: File): Promise<string> {\n const result = await new Promise<string | ArrayBuffer | null>((resolve, reject) => {\n const reader = new FileReader()\n reader.readAsDataURL(file)\n reader.onload = () => resolve(reader.result)\n reader.onerror = (error) => reject(error)\n })\n\n if (typeof result === 'string') {\n return result\n } else {\n throw new Error('Failed to read file as Data URL')\n }\n}\n\nexport async function fileToBase64(file: File, quality: number = 1): Promise<string> {\n if (isImageMimeType(file.type)) {\n const img = new Image()\n const url = URL.createObjectURL(file)\n try {\n await new Promise<void>((resolve, reject) => {\n img.onload = () => resolve()\n img.onerror = () => reject(new Error('Failed to load image for metadata removal'))\n img.src = url\n })\n\n const canvas = document.createElement('canvas')\n canvas.width = img.width\n canvas.height = img.height\n\n const ctx = canvas.getContext('2d')\n if (!ctx) {\n throw new Error('Failed to get canvas context')\n }\n ctx.drawImage(img, 0, 0)\n\n const cleanDataUrl = canvas.toDataURL(file.type, quality)\n if (cleanDataUrl === 'data:,') {\n return await fileToBase64Native(file)\n }\n\n return cleanDataUrl\n } finally {\n URL.revokeObjectURL(url)\n }\n } else {\n return await fileToBase64Native(file)\n }\n}\n","export function getCookie(name: string): string | undefined {\n for (const pair of document.cookie.split('; ')) {\n const separatorIndex = pair.indexOf('=')\n if (separatorIndex === -1) {\n continue\n }\n if (pair.slice(0, separatorIndex) === name) {\n return pair.slice(separatorIndex + 1)\n }\n }\n return undefined\n}\n\nexport interface SetCookieOptions {\n /** Days until the cookie expires. Omit for a session cookie (cleared when the browser closes). */\n days?: number\n path?: string\n}\n\nexport function setCookie(name: string, value: string, options: SetCookieOptions = {}): void {\n const { days, path = '/' } = options\n const expires = days === undefined ? '' : `; expires=${new Date(Date.now() + days * 86_400_000).toUTCString()}`\n document.cookie = `${name}=${value}${expires}; path=${path}`\n}\n\nexport function removeCookie(name: string, path: string = '/'): void {\n document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=${path}`\n}\n","type ConsoleMethod = (...args: unknown[]) => void\ntype WindowLike = Window & typeof globalThis\n\nconst patchedWindows = new WeakMap<WindowLike, Set<string>>()\n\nexport function createConsoleDebugSwitch(targetWindow: WindowLike, options: { namespace: string }): void {\n if (!targetWindow) {\n return\n }\n\n const { namespace } = options\n\n let enabledNamespaces = patchedWindows.get(targetWindow)\n if (!enabledNamespaces) {\n enabledNamespaces = new Set<string>()\n patchedWindows.set(targetWindow, enabledNamespaces)\n\n const original = {\n log: targetWindow.console.log.bind(targetWindow.console),\n info: targetWindow.console.info.bind(targetWindow.console),\n warn: targetWindow.console.warn.bind(targetWindow.console),\n error: targetWindow.console.error.bind(targetWindow.console),\n }\n\n const conditional =\n (method: ConsoleMethod): ConsoleMethod =>\n (...args) => {\n if (enabledNamespaces!.size > 0) {\n method(...args)\n }\n }\n\n targetWindow.console.log = conditional(original.log)\n targetWindow.console.info = conditional(original.info)\n targetWindow.console.warn = conditional(original.warn)\n targetWindow.console.error = conditional(original.error)\n }\n\n type Namespace = { debug: (enabled: boolean) => void }\n const globals = targetWindow as unknown as Record<string, Namespace | undefined>\n const existing = Object.prototype.hasOwnProperty.call(globals, namespace)\n ? (Object.getOwnPropertyDescriptor(globals, namespace)?.value as Namespace | undefined)\n : undefined\n const target = existing ?? ({} as Namespace)\n target.debug = (flag: boolean) => {\n if (flag) {\n enabledNamespaces!.add(namespace)\n } else {\n enabledNamespaces!.delete(namespace)\n }\n }\n // Object.defineProperty (unlike a plain `globals[namespace] = target` assignment) always\n // creates/overwrites an own property, even when namespace is a name like \"__proto__\" that\n // would otherwise be intercepted by Object.prototype's special __proto__ accessor and\n // pollute the shared prototype instead of setting a property on this specific object.\n Object.defineProperty(globals, namespace, { value: target, writable: true, configurable: true, enumerable: true })\n}\n","export type TailwindShade = 50 | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | 950\n\nexport type TailwindColorScale = Record<TailwindShade, string>\n\ninterface Rgb {\n r: number\n g: number\n b: number\n}\n\nconst HEX_PATTERN = /^#?([0-9a-f]{3}|[0-9a-f]{6})$/i\n\nfunction hexToRgb(hex: string): Rgb {\n const match = HEX_PATTERN.exec(hex.trim())\n if (!match) {\n throw new Error(`Invalid hex color: \"${hex}\"`)\n }\n\n const digits = match[1]\n const normalized =\n digits.length === 3\n ? digits\n .split('')\n .map((char) => char + char)\n .join('')\n : digits\n\n return {\n r: parseInt(normalized.slice(0, 2), 16),\n g: parseInt(normalized.slice(2, 4), 16),\n b: parseInt(normalized.slice(4, 6), 16),\n }\n}\n\nfunction rgbToHex({ r, g, b }: Rgb): string {\n return `#${[r, g, b].map((channel) => Math.round(channel).toString(16).padStart(2, '0')).join('')}`\n}\n\nfunction mixRgb(base: Rgb, target: Rgb, weight: number): Rgb {\n return {\n r: base.r + (target.r - base.r) * weight,\n g: base.g + (target.g - base.g) * weight,\n b: base.b + (target.b - base.b) * weight,\n }\n}\n\nconst WHITE: Rgb = { r: 255, g: 255, b: 255 }\nconst BLACK: Rgb = { r: 0, g: 0, b: 0 }\n\n// Weight of white/black mixed into the base color at each shade, tuned so 500 is the input\n// color unchanged and the rest approximate the spread of Tailwind's own default palettes.\nconst TINT_WEIGHTS: Record<50 | 100 | 200 | 300 | 400, number> = { 50: 0.95, 100: 0.9, 200: 0.75, 300: 0.6, 400: 0.3 }\nconst SHADE_WEIGHTS: Record<600 | 700 | 800 | 900 | 950, number> = {\n 600: 0.15,\n 700: 0.3,\n 800: 0.45,\n 900: 0.6,\n 950: 0.8,\n}\n\n/**\n * Generates a Tailwind-style 50-950 color scale from a single base hex color, treated as the 500 shade.\n */\nexport function generateTailwindColorScale(baseColor: string): TailwindColorScale {\n const base = hexToRgb(baseColor)\n\n return {\n 50: rgbToHex(mixRgb(base, WHITE, TINT_WEIGHTS[50])),\n 100: rgbToHex(mixRgb(base, WHITE, TINT_WEIGHTS[100])),\n 200: rgbToHex(mixRgb(base, WHITE, TINT_WEIGHTS[200])),\n 300: rgbToHex(mixRgb(base, WHITE, TINT_WEIGHTS[300])),\n 400: rgbToHex(mixRgb(base, WHITE, TINT_WEIGHTS[400])),\n 500: rgbToHex(base),\n 600: rgbToHex(mixRgb(base, BLACK, SHADE_WEIGHTS[600])),\n 700: rgbToHex(mixRgb(base, BLACK, SHADE_WEIGHTS[700])),\n 800: rgbToHex(mixRgb(base, BLACK, SHADE_WEIGHTS[800])),\n 900: rgbToHex(mixRgb(base, BLACK, SHADE_WEIGHTS[900])),\n 950: rgbToHex(mixRgb(base, BLACK, SHADE_WEIGHTS[950])),\n }\n}\n\n/**\n * Like {@link generateTailwindColorScale}, but prefixes each shade with `name` (e.g. `primary500`)\n * so multiple scales can be spread into one flat palette object.\n */\nexport function generateNamedTailwindColorScale<T extends string>(\n baseColor: string,\n name: T\n): Record<`${T}${TailwindShade}`, string> {\n const scale = generateTailwindColorScale(baseColor)\n\n return Object.fromEntries(Object.entries(scale).map(([shade, hex]) => [`${name}${shade}`, hex])) as Record<\n `${T}${TailwindShade}`,\n string\n >\n}\n\nfunction rgbToHsl({ r, g, b }: Rgb): { h: number; s: number; l: number } {\n const rN = r / 255\n const gN = g / 255\n const bN = b / 255\n\n const max = Math.max(rN, gN, bN)\n const min = Math.min(rN, gN, bN)\n const l = (max + min) / 2\n\n if (max === min) {\n return { h: 0, s: 0, l: l * 100 }\n }\n\n const delta = max - min\n const s = l > 0.5 ? delta / (2 - max - min) : delta / (max + min)\n\n let h: number\n if (max === rN) {\n h = ((gN - bN) / delta + (gN < bN ? 6 : 0)) * 60\n } else if (max === gN) {\n h = ((bN - rN) / delta + 2) * 60\n } else {\n h = ((rN - gN) / delta + 4) * 60\n }\n\n return { h, s: s * 100, l: l * 100 }\n}\n\n/**\n * Formats a hex color as the \"H S% L%\" triplet shadcn/Tailwind CSS variable themes expect,\n * e.g. for `--primary: 240 5.9% 10%;` consumed as `hsl(var(--primary))`.\n */\nexport function hexToHslTriplet(hex: string, precision: number = 1): string {\n const { h, s, l } = rgbToHsl(hexToRgb(hex))\n const round = (value: number) => Number(value.toFixed(precision))\n\n return `${round(h)} ${round(s)}% ${round(l)}%`\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,18 @@
1
+ import { C as ConfigSchema, P as PublicConfigOptions, a as PublicConfig } from '../../shared-By0kkXDs.js';
2
+ import 'react';
3
+
4
+ /**
5
+ * The browser half of `publicConfig()`, substituted for the server module by the `browser`
6
+ * export condition in package.json rather than branched to at runtime. That substitution is what
7
+ * makes the split safe: this file contains no reference to `process.env` at all, so bundling the
8
+ * config module for the client cannot ship a server value no matter what the schema says. It is a
9
+ * property of what the file contains, not a discipline anyone has to maintain.
10
+ *
11
+ * The schema argument is accepted and ignored - values arrive already cast, through the injected
12
+ * global. It stays in the signature so `InferConfig<S>` produces the identical type on both
13
+ * sides, which is what lets one `app/config.ts` be imported by server and client components
14
+ * alike.
15
+ */
16
+ declare function publicConfig<S extends ConfigSchema>(_schema: S, options?: PublicConfigOptions): PublicConfig<S>;
17
+
18
+ export { publicConfig };
@@ -0,0 +1,54 @@
1
+ // src/node/configError.ts
2
+ var ConfigError = class extends Error {
3
+ };
4
+
5
+ // src/next/config/shared.ts
6
+ var GLOBAL_KEY_BASE = "__ISIK_PUBLIC_CONFIG__";
7
+ function globalKeyFor(prefix) {
8
+ return prefix === "" ? GLOBAL_KEY_BASE : `${GLOBAL_KEY_BASE}${prefix}__`;
9
+ }
10
+ function memoize(resolve) {
11
+ let value;
12
+ let resolved = false;
13
+ return () => {
14
+ if (!resolved) {
15
+ value = resolve();
16
+ resolved = true;
17
+ }
18
+ return value;
19
+ };
20
+ }
21
+ function lazyConfigProxy(resolve) {
22
+ return new Proxy({}, {
23
+ get: (_target, property) => Reflect.get(resolve(), property),
24
+ has: (_target, property) => Reflect.has(resolve(), property),
25
+ ownKeys: () => Reflect.ownKeys(resolve()),
26
+ getOwnPropertyDescriptor: (_target, property) => {
27
+ const descriptor = Reflect.getOwnPropertyDescriptor(resolve(), property);
28
+ return descriptor === void 0 ? void 0 : { ...descriptor, configurable: true };
29
+ }
30
+ });
31
+ }
32
+
33
+ // src/next/config/browser.ts
34
+ function publicConfig(_schema, options = {}) {
35
+ const globalKey = globalKeyFor(options.prefix ?? "");
36
+ return {
37
+ CONFIG: lazyConfigProxy(memoize(() => readInjectedConfig(globalKey))),
38
+ // Injection is a server-render concern; there is nothing to emit once the document exists.
39
+ PublicConfigScript: () => null
40
+ };
41
+ }
42
+ function readInjectedConfig(globalKey) {
43
+ const injected = globalThis[globalKey];
44
+ if (injected === void 0) {
45
+ throw new ConfigError(
46
+ `window.${globalKey} is not set, so there is no public config to read. Render <PublicConfigScript /> once in your root layout (inside a <Suspense> boundary if Cache Components is enabled). If this is a test or a non-Next renderer, assign the object yourself before anything reads the config.`
47
+ );
48
+ }
49
+ return injected;
50
+ }
51
+ export {
52
+ publicConfig
53
+ };
54
+ //# sourceMappingURL=browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/node/configError.ts","../../../src/next/config/shared.ts","../../../src/next/config/browser.ts"],"sourcesContent":["/**\n * Isolated in its own module - with no `process.env` access anywhere in it - so that the browser\n * half of `@isikk/core/next/config` can throw the same error type without importing\n * anything that reads the environment. Keeping the split structural means the guarantee holds\n * because of what the file contains, not because a bundler happened to tree-shake it away.\n */\nexport class ConfigError extends Error {}\n","import type { ReactNode } from 'react'\n\nimport type { ConfigSchema, InferConfig } from '../../node/configCore'\n\nexport interface PublicConfigOptions {\n /** Prepended to every environment variable name this call reads, joined with `sep`. */\n prefix?: string\n /** Joins the prefix and the nested key path into a variable name. Defaults to `\"__\"`. */\n sep?: string\n}\n\nexport interface PublicConfigScriptProps {\n /** Forwarded to the injected `<script>` so a CSP with a per-request nonce keeps working. */\n nonce?: string\n}\n\nexport type PublicConfigScriptComponent = (props: PublicConfigScriptProps) => ReactNode | Promise<ReactNode>\n\nexport interface PublicConfig<S extends ConfigSchema> {\n CONFIG: InferConfig<S>\n PublicConfigScript: PublicConfigScriptComponent\n}\n\nconst GLOBAL_KEY_BASE = '__ISIK_PUBLIC_CONFIG__'\n\n/**\n * Namespaces the injected global by prefix, so two `publicConfig()` calls land on two properties\n * instead of the second one failing to redefine the first. Prefixes are already required to be\n * distinct from any server namespace, which makes them a usable key.\n */\nexport function globalKeyFor(prefix: string): string {\n return prefix === '' ? GLOBAL_KEY_BASE : `${GLOBAL_KEY_BASE}${prefix}__`\n}\n\n/**\n * Encodes a string as a JavaScript string literal that is safe to interpolate into a `<script>`\n * body. `JSON.stringify` alone is not: `</script>` inside a value closes the tag early and drops\n * the rest of the payload into the document as markup, and U+2028/U+2029 are literal line\n * terminators in JavaScript source, so a value containing one produces a syntax error. Escaping\n * `<` covers the first (the sequence can no longer be written) and the two explicit replacements\n * cover the second. `>` and `&` need no handling - a script element is raw text, so nothing in it\n * is parsed as markup or entities once `<` can't start a closing tag.\n */\nexport function jsStringLiteral(value: string): string {\n return JSON.stringify(value)\n .replace(/</g, '\\\\u003c')\n .replace(/\\u2028/g, '\\\\u2028')\n .replace(/\\u2029/g, '\\\\u2029')\n}\n\n/**\n * The script that hands the resolved config to the browser. Values travel as a JSON string parsed\n * at runtime rather than as an object literal: it parses faster than equivalent JS source, and it\n * narrows everything that needs escaping down to the single quoted string handled above.\n *\n * The definition is deep-frozen and non-writable, so nothing can reshape config after hydration,\n * and re-entrant if the script somehow runs twice - redefining a non-configurable property would\n * throw, so an existing key means there is nothing left to do.\n */\nexport function serializePublicConfigScript(key: string, value: unknown): string {\n return (\n '(function(w,k,v){if(k in w)return;' +\n 'var f=function(o){if(o&&typeof o==\"object\"){for(var p in o)f(o[p]);Object.freeze(o)}};' +\n 'f(v);Object.defineProperty(w,k,{value:v,enumerable:true})})' +\n `(window,${jsStringLiteral(key)},JSON.parse(${jsStringLiteral(JSON.stringify(value))}))`\n )\n}\n\nexport function memoize<T>(resolve: () => T): () => T {\n let value: T\n let resolved = false\n return () => {\n if (!resolved) {\n value = resolve()\n resolved = true\n }\n return value\n }\n}\n\n/**\n * Presents `resolve()`'s result as a plain object without calling it until something is actually\n * read. That deferral is load-bearing on both sides of the package. On the server it keeps\n * `next build` from resolving anything while collecting page data, so a missing variable no\n * longer fails the build - \"can this build\" stops depending on \"is this configured\". In the\n * browser it means the injected global is read at access time rather than at chunk-evaluation\n * time, so an async chunk that happens to run before the inline script still sees the config.\n */\nexport function lazyConfigProxy<T>(resolve: () => T): T {\n return new Proxy({} as object, {\n get: (_target, property) => Reflect.get(resolve() as object, property),\n has: (_target, property) => Reflect.has(resolve() as object, property),\n ownKeys: () => Reflect.ownKeys(resolve() as object),\n getOwnPropertyDescriptor: (_target, property) => {\n const descriptor = Reflect.getOwnPropertyDescriptor(resolve() as object, property)\n // The proxy target is an empty object, and a proxy may not report a non-configurable\n // property that its target doesn't have - so re-mark descriptors as configurable, or\n // Object.keys()/JSON.stringify() over the config throw a TypeError.\n return descriptor === undefined ? undefined : { ...descriptor, configurable: true }\n },\n }) as T\n}\n","import type { ConfigSchema, InferConfig } from '../../node/configCore'\nimport { ConfigError } from '../../node/configError'\nimport { type PublicConfig, type PublicConfigOptions, globalKeyFor, lazyConfigProxy, memoize } from './shared'\n\n/**\n * The browser half of `publicConfig()`, substituted for the server module by the `browser`\n * export condition in package.json rather than branched to at runtime. That substitution is what\n * makes the split safe: this file contains no reference to `process.env` at all, so bundling the\n * config module for the client cannot ship a server value no matter what the schema says. It is a\n * property of what the file contains, not a discipline anyone has to maintain.\n *\n * The schema argument is accepted and ignored - values arrive already cast, through the injected\n * global. It stays in the signature so `InferConfig<S>` produces the identical type on both\n * sides, which is what lets one `app/config.ts` be imported by server and client components\n * alike.\n */\nexport function publicConfig<S extends ConfigSchema>(_schema: S, options: PublicConfigOptions = {}): PublicConfig<S> {\n const globalKey = globalKeyFor(options.prefix ?? '')\n\n return {\n CONFIG: lazyConfigProxy<InferConfig<S>>(memoize(() => readInjectedConfig<S>(globalKey))),\n // Injection is a server-render concern; there is nothing to emit once the document exists.\n PublicConfigScript: () => null,\n }\n}\n\nfunction readInjectedConfig<S extends ConfigSchema>(globalKey: string): InferConfig<S> {\n const injected = (globalThis as unknown as Record<string, unknown>)[globalKey]\n\n if (injected === undefined) {\n throw new ConfigError(\n `window.${globalKey} is not set, so there is no public config to read. Render <PublicConfigScript /> ` +\n 'once in your root layout (inside a <Suspense> boundary if Cache Components is enabled). If this is a ' +\n 'test or a non-Next renderer, assign the object yourself before anything reads the config.'\n )\n }\n\n return injected as InferConfig<S>\n}\n"],"mappings":";AAMO,IAAM,cAAN,cAA0B,MAAM;AAAC;;;ACiBxC,IAAM,kBAAkB;AAOjB,SAAS,aAAa,QAAwB;AACnD,SAAO,WAAW,KAAK,kBAAkB,GAAG,eAAe,GAAG,MAAM;AACtE;AAoCO,SAAS,QAAW,SAA2B;AACpD,MAAI;AACJ,MAAI,WAAW;AACf,SAAO,MAAM;AACX,QAAI,CAAC,UAAU;AACb,cAAQ,QAAQ;AAChB,iBAAW;AAAA,IACb;AACA,WAAO;AAAA,EACT;AACF;AAUO,SAAS,gBAAmB,SAAqB;AACtD,SAAO,IAAI,MAAM,CAAC,GAAa;AAAA,IAC7B,KAAK,CAAC,SAAS,aAAa,QAAQ,IAAI,QAAQ,GAAa,QAAQ;AAAA,IACrE,KAAK,CAAC,SAAS,aAAa,QAAQ,IAAI,QAAQ,GAAa,QAAQ;AAAA,IACrE,SAAS,MAAM,QAAQ,QAAQ,QAAQ,CAAW;AAAA,IAClD,0BAA0B,CAAC,SAAS,aAAa;AAC/C,YAAM,aAAa,QAAQ,yBAAyB,QAAQ,GAAa,QAAQ;AAIjF,aAAO,eAAe,SAAY,SAAY,EAAE,GAAG,YAAY,cAAc,KAAK;AAAA,IACpF;AAAA,EACF,CAAC;AACH;;;ACrFO,SAAS,aAAqC,SAAY,UAA+B,CAAC,GAAoB;AACnH,QAAM,YAAY,aAAa,QAAQ,UAAU,EAAE;AAEnD,SAAO;AAAA,IACL,QAAQ,gBAAgC,QAAQ,MAAM,mBAAsB,SAAS,CAAC,CAAC;AAAA;AAAA,IAEvF,oBAAoB,MAAM;AAAA,EAC5B;AACF;AAEA,SAAS,mBAA2C,WAAmC;AACrF,QAAM,WAAY,WAAkD,SAAS;AAE7E,MAAI,aAAa,QAAW;AAC1B,UAAM,IAAI;AAAA,MACR,UAAU,SAAS;AAAA,IAGrB;AAAA,EACF;AAEA,SAAO;AACT;","names":[]}
@@ -0,0 +1,30 @@
1
+ import { C as ConfigSchema, P as PublicConfigOptions, a as PublicConfig } from '../../shared-By0kkXDs.js';
2
+ export { I as InferConfig, b as PublicConfigScriptComponent, c as PublicConfigScriptProps } from '../../shared-By0kkXDs.js';
3
+ import 'react';
4
+
5
+ /**
6
+ * Isolated in its own module - with no `process.env` access anywhere in it - so that the browser
7
+ * half of `@isikk/core/next/config` can throw the same error type without importing
8
+ * anything that reads the environment. Keeping the split structural means the guarantee holds
9
+ * because of what the file contains, not because a bundler happened to tree-shake it away.
10
+ */
11
+ declare class ConfigError extends Error {
12
+ }
13
+
14
+ /**
15
+ * The browser-visible sibling of `config()`: same schema, same casters, same variable naming, but
16
+ * the resolved values are serialized into the document so client components can read them at
17
+ * runtime. Returns the config object plus the component that injects it, which the root layout
18
+ * renders exactly once.
19
+ *
20
+ * Everything in `schema` ends up in the HTML of every page, in plaintext. The prefix claimed here
21
+ * must not overlap one already claimed by `config()`, so a server-only key pasted into this
22
+ * schema by mistake resolves to nothing and throws rather than getting published.
23
+ *
24
+ * Values are read per request, not baked in at build - which is the entire point next to
25
+ * `NEXT_PUBLIC_*`, and what lets one image run in staging and production. Nothing resolves until
26
+ * something reads it, so `next build` needs none of these variables set.
27
+ */
28
+ declare function publicConfig<S extends ConfigSchema>(schema: S, options?: PublicConfigOptions): PublicConfig<S>;
29
+
30
+ export { ConfigError, ConfigSchema, PublicConfig, PublicConfigOptions, publicConfig };