@omnitron-dev/prism 0.3.1 → 0.3.2

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 (305) hide show
  1. package/README.md +68 -2
  2. package/THIRD-PARTY-NOTICES.txt +26 -0
  3. package/dist/accessibility/index.js +2 -0
  4. package/dist/accessibility/index.js.map +1 -1
  5. package/dist/auth/index.d.ts +4 -0
  6. package/dist/auth/index.d.ts.map +1 -0
  7. package/dist/auth/index.js +4 -0
  8. package/dist/auth/index.js.map +1 -0
  9. package/dist/blocks/auth-block/guards.d.ts +3 -2
  10. package/dist/blocks/auth-block/guards.d.ts.map +1 -1
  11. package/dist/blocks/dashboard-block/dashboard-block.d.ts.map +1 -1
  12. package/dist/blocks/dashboard-block/types.d.ts +4 -2
  13. package/dist/blocks/dashboard-block/types.d.ts.map +1 -1
  14. package/dist/blocks/dashboard-block/use-dashboard-block.d.ts +2 -2
  15. package/dist/blocks/dashboard-block/use-dashboard-block.d.ts.map +1 -1
  16. package/dist/blocks/data-grid-block/data-grid-block.d.ts.map +1 -1
  17. package/dist/blocks/data-grid-block/types.d.ts +3 -0
  18. package/dist/blocks/data-grid-block/types.d.ts.map +1 -1
  19. package/dist/blocks/index.js +80 -255
  20. package/dist/blocks/index.js.map +1 -1
  21. package/dist/chunk-2AB7VGPW.js +447 -0
  22. package/dist/chunk-2AB7VGPW.js.map +1 -0
  23. package/dist/{chunk-LOY2NPCO.js → chunk-2E67PQ4T.js} +3 -3
  24. package/dist/{chunk-LOY2NPCO.js.map → chunk-2E67PQ4T.js.map} +1 -1
  25. package/dist/chunk-2KG2NI73.js +84 -0
  26. package/dist/chunk-2KG2NI73.js.map +1 -0
  27. package/dist/chunk-2UYRW6X3.js +44 -0
  28. package/dist/chunk-2UYRW6X3.js.map +1 -0
  29. package/dist/chunk-36C5H56C.js +208 -0
  30. package/dist/chunk-36C5H56C.js.map +1 -0
  31. package/dist/chunk-36FOXX25.js +73 -0
  32. package/dist/chunk-36FOXX25.js.map +1 -0
  33. package/dist/{chunk-52PQL67Q.js → chunk-3VSM7NZG.js} +18 -15
  34. package/dist/chunk-3VSM7NZG.js.map +1 -0
  35. package/dist/{chunk-GUGTDURV.js → chunk-4B2LTPK2.js} +2 -2
  36. package/dist/{chunk-GUGTDURV.js.map → chunk-4B2LTPK2.js.map} +1 -1
  37. package/dist/chunk-4HUGZJKU.js +108 -0
  38. package/dist/chunk-4HUGZJKU.js.map +1 -0
  39. package/dist/{chunk-PXXPLHIY.js → chunk-4Q5L7LDG.js} +3 -3
  40. package/dist/{chunk-PXXPLHIY.js.map → chunk-4Q5L7LDG.js.map} +1 -1
  41. package/dist/{chunk-BRDWQVRT.js → chunk-4R7EZ7GQ.js} +3 -2
  42. package/dist/chunk-4R7EZ7GQ.js.map +1 -0
  43. package/dist/chunk-6IANOSMD.js +185 -0
  44. package/dist/chunk-6IANOSMD.js.map +1 -0
  45. package/dist/{chunk-YHE7HXSG.js → chunk-7ATBURW2.js} +3 -3
  46. package/dist/{chunk-YHE7HXSG.js.map → chunk-7ATBURW2.js.map} +1 -1
  47. package/dist/{chunk-7G5D5PTC.js → chunk-AATAOOSF.js} +4 -4
  48. package/dist/{chunk-7G5D5PTC.js.map → chunk-AATAOOSF.js.map} +1 -1
  49. package/dist/chunk-AKLRKCYH.js +128 -0
  50. package/dist/chunk-AKLRKCYH.js.map +1 -0
  51. package/dist/chunk-CT46KJOR.js +133 -0
  52. package/dist/chunk-CT46KJOR.js.map +1 -0
  53. package/dist/{chunk-LSPFFEJT.js → chunk-D4GFAJAZ.js} +298 -3900
  54. package/dist/chunk-D4GFAJAZ.js.map +1 -0
  55. package/dist/{chunk-BJE2AKD4.js → chunk-D5J3KW6Q.js} +3 -2
  56. package/dist/chunk-D5J3KW6Q.js.map +1 -0
  57. package/dist/chunk-DEPJRTVT.js +3 -0
  58. package/dist/{chunk-FU52GL2E.js.map → chunk-DEPJRTVT.js.map} +1 -1
  59. package/dist/{chunk-472SOF76.js → chunk-DHTYHUYI.js} +85 -107
  60. package/dist/chunk-DHTYHUYI.js.map +1 -0
  61. package/dist/{chunk-FF5RF32O.js → chunk-E7WM2RXA.js} +3 -2
  62. package/dist/chunk-E7WM2RXA.js.map +1 -0
  63. package/dist/chunk-F6RZ7LW6.js +1271 -0
  64. package/dist/chunk-F6RZ7LW6.js.map +1 -0
  65. package/dist/chunk-FOGY3HA4.js +217 -0
  66. package/dist/chunk-FOGY3HA4.js.map +1 -0
  67. package/dist/chunk-G2GANYMW.js +139 -0
  68. package/dist/chunk-G2GANYMW.js.map +1 -0
  69. package/dist/chunk-I6DILPFE.js +293 -0
  70. package/dist/chunk-I6DILPFE.js.map +1 -0
  71. package/dist/{chunk-HOXFSQUV.js → chunk-IRYU3NTG.js} +2 -2
  72. package/dist/{chunk-HOXFSQUV.js.map → chunk-IRYU3NTG.js.map} +1 -1
  73. package/dist/chunk-JTIUGPW5.js +284 -0
  74. package/dist/chunk-JTIUGPW5.js.map +1 -0
  75. package/dist/{chunk-GUFHFEPZ.js → chunk-JZBSPDED.js} +2 -2
  76. package/dist/{chunk-GUFHFEPZ.js.map → chunk-JZBSPDED.js.map} +1 -1
  77. package/dist/{chunk-PFT2BNYO.js → chunk-KPY7TA4D.js} +5 -5
  78. package/dist/{chunk-PFT2BNYO.js.map → chunk-KPY7TA4D.js.map} +1 -1
  79. package/dist/{chunk-GMIE6III.js → chunk-LFWKGNCX.js} +50 -623
  80. package/dist/chunk-LFWKGNCX.js.map +1 -0
  81. package/dist/chunk-LH4ZZZYB.js +37 -0
  82. package/dist/chunk-LH4ZZZYB.js.map +1 -0
  83. package/dist/chunk-NFJ7CPG3.js +13 -0
  84. package/dist/chunk-NFJ7CPG3.js.map +1 -0
  85. package/dist/chunk-NFPOIHD4.js +3 -0
  86. package/dist/{chunk-JSQTYDPG.js.map → chunk-NFPOIHD4.js.map} +1 -1
  87. package/dist/{chunk-XIXSSI3B.js → chunk-NJM5AVBM.js} +3 -2
  88. package/dist/chunk-NJM5AVBM.js.map +1 -0
  89. package/dist/{chunk-4Z5DE5GK.js → chunk-NSNM53WI.js} +133 -115
  90. package/dist/chunk-NSNM53WI.js.map +1 -0
  91. package/dist/chunk-NTREGTG7.js +31 -0
  92. package/dist/chunk-NTREGTG7.js.map +1 -0
  93. package/dist/{chunk-ADG4HZEP.js → chunk-OKJA6SJM.js} +4 -4
  94. package/dist/chunk-OKJA6SJM.js.map +1 -0
  95. package/dist/{chunk-SU3LVQ7N.js → chunk-Q6JDNFSG.js} +11 -226
  96. package/dist/chunk-Q6JDNFSG.js.map +1 -0
  97. package/dist/chunk-RPOGINR5.js +115 -0
  98. package/dist/chunk-RPOGINR5.js.map +1 -0
  99. package/dist/{chunk-KQ67XB6T.js → chunk-RSWVYIXK.js} +151 -114
  100. package/dist/chunk-RSWVYIXK.js.map +1 -0
  101. package/dist/chunk-SSEHL5VP.js +110 -0
  102. package/dist/chunk-SSEHL5VP.js.map +1 -0
  103. package/dist/chunk-TEIGUOWN.js +523 -0
  104. package/dist/chunk-TEIGUOWN.js.map +1 -0
  105. package/dist/{chunk-AYYFMTMI.js → chunk-TJ7DHXUX.js} +2 -2
  106. package/dist/{chunk-AYYFMTMI.js.map → chunk-TJ7DHXUX.js.map} +1 -1
  107. package/dist/{chunk-75FQ5IW3.js → chunk-TZHWYT34.js} +3 -3
  108. package/dist/{chunk-75FQ5IW3.js.map → chunk-TZHWYT34.js.map} +1 -1
  109. package/dist/chunk-TZWHELY4.js +45 -0
  110. package/dist/chunk-TZWHELY4.js.map +1 -0
  111. package/dist/{chunk-OKTLA23Q.js → chunk-UEINJFLS.js} +6 -6
  112. package/dist/chunk-UEINJFLS.js.map +1 -0
  113. package/dist/chunk-URFQX3I6.js +129 -0
  114. package/dist/chunk-URFQX3I6.js.map +1 -0
  115. package/dist/chunk-VG6FOMOH.js +187 -0
  116. package/dist/chunk-VG6FOMOH.js.map +1 -0
  117. package/dist/{chunk-PGHEP4JD.js → chunk-VQVVHMPG.js} +3 -3
  118. package/dist/{chunk-PGHEP4JD.js.map → chunk-VQVVHMPG.js.map} +1 -1
  119. package/dist/{chunk-DRFNMZLG.js → chunk-VUKOT432.js} +3 -2
  120. package/dist/chunk-VUKOT432.js.map +1 -0
  121. package/dist/chunk-WD4N72DL.js +315 -0
  122. package/dist/chunk-WD4N72DL.js.map +1 -0
  123. package/dist/chunk-XBYMG4QK.js +119 -0
  124. package/dist/chunk-XBYMG4QK.js.map +1 -0
  125. package/dist/chunk-YHM6GIHV.js +3 -0
  126. package/dist/chunk-YHM6GIHV.js.map +1 -0
  127. package/dist/{chunk-SNZK5X6F.js → chunk-Z2AN43YU.js} +4 -2
  128. package/dist/chunk-Z2AN43YU.js.map +1 -0
  129. package/dist/chunk-ZNWHMQRM.js +171 -0
  130. package/dist/chunk-ZNWHMQRM.js.map +1 -0
  131. package/dist/{chunk-YSIG2XYH.js → chunk-ZRJYQN6Y.js} +2 -2
  132. package/dist/{chunk-YSIG2XYH.js.map → chunk-ZRJYQN6Y.js.map} +1 -1
  133. package/dist/{chunk-AD4W7HYC.js → chunk-ZYI3MHLE.js} +3 -2
  134. package/dist/chunk-ZYI3MHLE.js.map +1 -0
  135. package/dist/cli/index.js +59 -421
  136. package/dist/cli/index.js.map +1 -1
  137. package/dist/components/admin-filters/admin-data-table.d.ts +7 -1
  138. package/dist/components/admin-filters/admin-data-table.d.ts.map +1 -1
  139. package/dist/components/admin-filters/filter-toolbar.d.ts.map +1 -1
  140. package/dist/components/admin-filters/index.js +8 -0
  141. package/dist/components/admin-filters/index.js.map +1 -0
  142. package/dist/components/alert/alert.d.ts.map +1 -1
  143. package/dist/components/alert/index.js +5 -0
  144. package/dist/components/alert/index.js.map +1 -0
  145. package/dist/components/animate/index.js +5 -0
  146. package/dist/components/animate/index.js.map +1 -0
  147. package/dist/components/breadcrumbs/breadcrumbs.d.ts.map +1 -1
  148. package/dist/components/breadcrumbs/index.js +4 -0
  149. package/dist/components/breadcrumbs/index.js.map +1 -0
  150. package/dist/components/card/index.js +4 -0
  151. package/dist/components/card/index.js.map +1 -0
  152. package/dist/components/chart/chart.d.ts.map +1 -1
  153. package/dist/components/chart/index.css +52 -0
  154. package/dist/components/chart/index.css.map +1 -0
  155. package/dist/components/chart/index.js +5 -0
  156. package/dist/components/chart/index.js.map +1 -0
  157. package/dist/components/chart/types.d.ts +3 -1
  158. package/dist/components/chart/types.d.ts.map +1 -1
  159. package/dist/components/chart/use-chart.d.ts.map +1 -1
  160. package/dist/components/command-palette/command-palette.d.ts +3 -1
  161. package/dist/components/command-palette/command-palette.d.ts.map +1 -1
  162. package/dist/components/command-palette/index.js +4 -0
  163. package/dist/components/command-palette/index.js.map +1 -0
  164. package/dist/components/confirm-dialog/index.js +4 -0
  165. package/dist/components/confirm-dialog/index.js.map +1 -0
  166. package/dist/components/date-input/date-input.d.ts +1 -0
  167. package/dist/components/date-input/date-input.d.ts.map +1 -1
  168. package/dist/components/date-input/index.d.ts +0 -1
  169. package/dist/components/date-input/index.d.ts.map +1 -1
  170. package/dist/components/doc-layout/index.js +5 -4
  171. package/dist/components/doc-layout/index.js.map +1 -1
  172. package/dist/components/editor/index.js +4 -3
  173. package/dist/components/editor/index.js.map +1 -1
  174. package/dist/components/emoji-picker/index.js +2 -1
  175. package/dist/components/emoji-picker/index.js.map +1 -1
  176. package/dist/components/empty-content/empty-content.d.ts.map +1 -1
  177. package/dist/components/empty-content/index.js +4 -0
  178. package/dist/components/empty-content/index.js.map +1 -0
  179. package/dist/components/error-boundary/index.js +6 -0
  180. package/dist/components/error-boundary/index.js.map +1 -0
  181. package/dist/components/index.css +13 -10
  182. package/dist/components/index.css.map +1 -1
  183. package/dist/components/index.d.ts +1 -0
  184. package/dist/components/index.d.ts.map +1 -1
  185. package/dist/components/index.js +47 -21
  186. package/dist/components/index.js.map +1 -1
  187. package/dist/components/knowledge-graph/edge-labels.d.ts.map +1 -1
  188. package/dist/components/knowledge-graph/index.js +18 -16
  189. package/dist/components/knowledge-graph/index.js.map +1 -1
  190. package/dist/components/label/index.js +5 -0
  191. package/dist/components/label/index.js.map +1 -0
  192. package/dist/components/label/label.d.ts.map +1 -1
  193. package/dist/components/loading-screen/index.js +4 -0
  194. package/dist/components/loading-screen/index.js.map +1 -0
  195. package/dist/components/map/MapPointPicker.d.ts.map +1 -1
  196. package/dist/components/map/index.js +2 -1
  197. package/dist/components/map/index.js.map +1 -1
  198. package/dist/components/navigation-progress/index.js +4 -0
  199. package/dist/components/navigation-progress/index.js.map +1 -0
  200. package/dist/components/page-content/index.js +4 -0
  201. package/dist/components/page-content/index.js.map +1 -0
  202. package/dist/components/popover/index.js +4 -0
  203. package/dist/components/popover/index.js.map +1 -0
  204. package/dist/components/research/diagram.d.ts.map +1 -1
  205. package/dist/components/research/index.js +6 -4
  206. package/dist/components/research/index.js.map +1 -1
  207. package/dist/components/research-editor/extensions.d.ts +1 -1
  208. package/dist/components/research-editor/index.js +11 -10
  209. package/dist/components/research-editor/index.js.map +1 -1
  210. package/dist/components/research-editor/math-navigation.d.ts +2 -2
  211. package/dist/components/research-editor/math-navigation.d.ts.map +1 -1
  212. package/dist/components/scroll-to-top/index.js +4 -0
  213. package/dist/components/scroll-to-top/index.js.map +1 -0
  214. package/dist/components/search-input/index.js +7 -0
  215. package/dist/components/search-input/index.js.map +1 -0
  216. package/dist/components/search-input/search-input.d.ts +3 -1
  217. package/dist/components/search-input/search-input.d.ts.map +1 -1
  218. package/dist/components/skeleton/index.js +4 -0
  219. package/dist/components/skeleton/index.js.map +1 -0
  220. package/dist/components/snackbar/index.js +6 -0
  221. package/dist/components/snackbar/index.js.map +1 -0
  222. package/dist/components/stepper/index.js +4 -0
  223. package/dist/components/stepper/index.js.map +1 -0
  224. package/dist/components/table/index.d.ts +1 -0
  225. package/dist/components/table/index.d.ts.map +1 -1
  226. package/dist/components/table/index.js +5 -0
  227. package/dist/components/table/index.js.map +1 -0
  228. package/dist/components/table/table-viewport.d.ts +13 -0
  229. package/dist/components/table/table-viewport.d.ts.map +1 -0
  230. package/dist/components/table/table.d.ts +3 -1
  231. package/dist/components/table/table.d.ts.map +1 -1
  232. package/dist/components/tabs/index.js +6 -0
  233. package/dist/components/tabs/index.js.map +1 -0
  234. package/dist/components/tabs/tabs.d.ts +12 -1
  235. package/dist/components/tabs/tabs.d.ts.map +1 -1
  236. package/dist/core/index.js +12 -10
  237. package/dist/core/index.js.map +1 -1
  238. package/dist/forms/index.js +2 -0
  239. package/dist/forms/index.js.map +1 -1
  240. package/dist/hooks/index.js +14 -12
  241. package/dist/hooks/index.js.map +1 -1
  242. package/dist/hooks/use-config-from-query.d.ts +2 -0
  243. package/dist/hooks/use-config-from-query.d.ts.map +1 -1
  244. package/dist/hooks/use-image-dimensions.d.ts.map +1 -1
  245. package/dist/hooks/use-keyboard-shortcut.d.ts.map +1 -1
  246. package/dist/hooks/use-scroll-position.d.ts.map +1 -1
  247. package/dist/hooks/use-window-size.d.ts.map +1 -1
  248. package/dist/icons/context.d.ts.map +1 -1
  249. package/dist/icons/index.js +3 -2
  250. package/dist/icons/index.js.map +1 -1
  251. package/dist/index.css +13 -10
  252. package/dist/index.css.map +1 -1
  253. package/dist/index.js +57 -31
  254. package/dist/index.js.map +1 -1
  255. package/dist/internal/research-parser.js +3 -0
  256. package/dist/internal/research-parser.js.map +1 -0
  257. package/dist/layouts/core/header-section.d.ts +1 -0
  258. package/dist/layouts/core/header-section.d.ts.map +1 -1
  259. package/dist/layouts/dashboard/layout.d.ts +3 -1
  260. package/dist/layouts/dashboard/layout.d.ts.map +1 -1
  261. package/dist/layouts/dashboard/sidenav.d.ts.map +1 -1
  262. package/dist/layouts/index.js +9 -8
  263. package/dist/layouts/index.js.map +1 -1
  264. package/dist/netron/index.js +2 -1
  265. package/dist/netron/index.js.map +1 -1
  266. package/dist/registry/index.js +1 -1
  267. package/dist/state/create-store.d.ts.map +1 -1
  268. package/dist/state/index.js +3 -2
  269. package/dist/state/index.js.map +1 -1
  270. package/dist/state/settings-version.d.ts.map +1 -1
  271. package/dist/theme/components/Chip.d.ts.map +1 -1
  272. package/dist/theme/components/Dialog.d.ts.map +1 -1
  273. package/dist/theme/components/TextField.d.ts.map +1 -1
  274. package/dist/theme/components/index.d.ts.map +1 -1
  275. package/dist/theme/components/theme-utils.d.ts +2 -2
  276. package/dist/theme/components/theme-utils.d.ts.map +1 -1
  277. package/dist/theme/index.js +8 -6
  278. package/dist/theme/index.js.map +1 -1
  279. package/dist/theme/palette/overrides.d.ts +1 -0
  280. package/dist/theme/palette/overrides.d.ts.map +1 -1
  281. package/dist/theme/semantic-surface.d.ts +8 -0
  282. package/dist/theme/semantic-surface.d.ts.map +1 -0
  283. package/dist/types/index.js +2 -2
  284. package/dist/ui/index.js +6 -5
  285. package/dist/ui/index.js.map +1 -1
  286. package/dist/utils/async-lock.d.ts.map +1 -1
  287. package/package.json +143 -37
  288. package/dist/chunk-472SOF76.js.map +0 -1
  289. package/dist/chunk-4Z5DE5GK.js.map +0 -1
  290. package/dist/chunk-52PQL67Q.js.map +0 -1
  291. package/dist/chunk-AD4W7HYC.js.map +0 -1
  292. package/dist/chunk-ADG4HZEP.js.map +0 -1
  293. package/dist/chunk-BJE2AKD4.js.map +0 -1
  294. package/dist/chunk-BRDWQVRT.js.map +0 -1
  295. package/dist/chunk-DRFNMZLG.js.map +0 -1
  296. package/dist/chunk-FF5RF32O.js.map +0 -1
  297. package/dist/chunk-FU52GL2E.js +0 -3
  298. package/dist/chunk-GMIE6III.js.map +0 -1
  299. package/dist/chunk-JSQTYDPG.js +0 -3
  300. package/dist/chunk-KQ67XB6T.js.map +0 -1
  301. package/dist/chunk-LSPFFEJT.js.map +0 -1
  302. package/dist/chunk-OKTLA23Q.js.map +0 -1
  303. package/dist/chunk-SNZK5X6F.js.map +0 -1
  304. package/dist/chunk-SU3LVQ7N.js.map +0 -1
  305. package/dist/chunk-XIXSSI3B.js.map +0 -1
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/refs.ts","../src/utils/format-number.ts","../src/utils/format-date.ts","../src/utils/string.ts","../src/utils/storage.ts","../src/utils/font.ts","../src/utils/object.ts","../src/utils/rtl.ts","../src/utils/async-lock.ts","../src/utils/errors.ts","../src/utils/fetch-interceptor.ts","../src/utils/jwt.ts","../src/utils/template-resolver.ts","../src/utils/i18n-text.ts","../src/utils/toast.ts"],"names":["buildUrl","sonner"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Ref Utilities\n *\n * Utilities for working with React refs.\n *\n * @module utils/refs\n */\n\nimport type { MutableRefObject, RefCallback, Ref } from 'react';\n\n/**\n * Supported ref types for merging.\n */\nexport type MergeableRef<T> = Ref<T> | RefCallback<T> | MutableRefObject<T> | null | undefined;\n\n/**\n * Merge multiple refs into a single callback ref.\n * Useful when you need to pass a ref to a component that also needs\n * to be used by a parent component or hook.\n *\n * @example\n * ```tsx\n * function Component({ ref, ...props }: ComponentProps) {\n * const localRef = useRef<HTMLDivElement>(null);\n * const mergedRef = mergeRefs(ref, localRef);\n * return <div ref={mergedRef} />;\n * }\n * ```\n *\n * @param refs - Array of refs to merge\n * @returns A callback ref that updates all provided refs\n */\nexport function mergeRefs<T>(...refs: MergeableRef<T>[]): RefCallback<T> {\n return (value: T | null) => {\n for (const ref of refs) {\n if (typeof ref === 'function') {\n ref(value);\n } else if (ref != null) {\n (ref as MutableRefObject<T | null>).current = value;\n }\n }\n };\n}\n\n/**\n * Create a ref setter that can be used with useImperativeHandle.\n * Useful for exposing a subset of methods from a ref.\n *\n * @example\n * ```tsx\n * function Component({ ref, ...props }: Props & { ref?: Ref<API> }) {\n * const inputRef = useRef<HTMLInputElement>(null);\n *\n * useImperativeHandle(ref, () => ({\n * focus: () => inputRef.current?.focus(),\n * clear: () => { if (inputRef.current) inputRef.current.value = ''; },\n * }), []);\n *\n * return <input ref={inputRef} />;\n * }\n * ```\n *\n * @param ref - The ref to set\n * @param value - The value to set\n */\nexport function setRef<T>(ref: MergeableRef<T>, value: T | null): void {\n if (typeof ref === 'function') {\n ref(value);\n } else if (ref != null) {\n (ref as MutableRefObject<T | null>).current = value;\n }\n}\n\n/**\n * Check if a ref has a current value.\n *\n * @param ref - The ref to check\n * @returns True if the ref has a current value\n */\nexport function hasRefValue<T>(ref: MergeableRef<T>): ref is MutableRefObject<NonNullable<T>> {\n return ref != null && typeof ref !== 'function' && ref.current != null;\n}\n","/**\n * Number Formatting Utilities\n *\n * Locale-aware number formatting utilities.\n *\n * @module utils/format-number\n */\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport interface FormatNumberOptions extends Intl.NumberFormatOptions {\n /** Locale for formatting (default: 'en-US') */\n locale?: string;\n}\n\nexport interface FormatCurrencyOptions extends FormatNumberOptions {\n /** Currency code (default: 'USD') */\n currency?: string;\n}\n\n// =============================================================================\n// NUMBER FORMATTING\n// =============================================================================\n\n/**\n * Format a number with locale-aware formatting.\n *\n * @example\n * ```ts\n * fNumber(1234567.89)\n * // => \"1,234,567.89\"\n *\n * fNumber(1234567.89, { locale: 'de-DE' })\n * // => \"1.234.567,89\"\n *\n * fNumber(0.1234, { style: 'percent' })\n * // => \"12%\"\n * ```\n */\nexport function fNumber(value: number | string | null | undefined, options: FormatNumberOptions = {}): string {\n const { locale = 'en-US', ...formatOptions } = options;\n\n if (value === null || value === undefined || value === '') {\n return '';\n }\n\n const num = typeof value === 'string' ? parseFloat(value) : value;\n\n if (Number.isNaN(num)) {\n return '';\n }\n\n return new Intl.NumberFormat(locale, formatOptions).format(num);\n}\n\n/**\n * Format a number as currency.\n *\n * @example\n * ```ts\n * fCurrency(1234.56)\n * // => \"$1,234.56\"\n *\n * fCurrency(1234.56, { currency: 'EUR', locale: 'de-DE' })\n * // => \"1.234,56 €\"\n *\n * fCurrency(1234.56, { currency: 'JPY' })\n * // => \"¥1,235\" (JPY has no decimal places)\n * ```\n */\nexport function fCurrency(value: number | string | null | undefined, options: FormatCurrencyOptions = {}): string {\n const { currency = 'USD', locale = 'en-US', ...formatOptions } = options;\n\n if (value === null || value === undefined || value === '') {\n return '';\n }\n\n const num = typeof value === 'string' ? parseFloat(value) : value;\n\n if (Number.isNaN(num)) {\n return '';\n }\n\n return new Intl.NumberFormat(locale, {\n style: 'currency',\n currency,\n ...formatOptions,\n }).format(num);\n}\n\n/**\n * Format a number as a percentage.\n *\n * @example\n * ```ts\n * fPercent(0.1234)\n * // => \"12.34%\"\n *\n * fPercent(0.1234, { maximumFractionDigits: 0 })\n * // => \"12%\"\n *\n * fPercent(1.5)\n * // => \"150%\"\n * ```\n */\nexport function fPercent(value: number | string | null | undefined, options: FormatNumberOptions = {}): string {\n const { locale = 'en-US', ...formatOptions } = options;\n\n if (value === null || value === undefined || value === '') {\n return '';\n }\n\n const num = typeof value === 'string' ? parseFloat(value) : value;\n\n if (Number.isNaN(num)) {\n return '';\n }\n\n return new Intl.NumberFormat(locale, {\n style: 'percent',\n minimumFractionDigits: 0,\n maximumFractionDigits: 2,\n ...formatOptions,\n }).format(num);\n}\n\n/**\n * Shorten a large number with K, M, B suffixes.\n *\n * @example\n * ```ts\n * fShortenNumber(1234)\n * // => \"1.23K\"\n *\n * fShortenNumber(1234567)\n * // => \"1.23M\"\n *\n * fShortenNumber(1234567890)\n * // => \"1.23B\"\n *\n * fShortenNumber(1234567890000)\n * // => \"1.23T\"\n * ```\n */\nexport function fShortenNumber(value: number | string | null | undefined, decimals: number = 2): string {\n if (value === null || value === undefined || value === '') {\n return '';\n }\n\n const num = typeof value === 'string' ? parseFloat(value) : value;\n\n if (Number.isNaN(num)) {\n return '';\n }\n\n const absNum = Math.abs(num);\n\n if (absNum >= 1e12) {\n return `${(num / 1e12).toFixed(decimals)}T`;\n }\n if (absNum >= 1e9) {\n return `${(num / 1e9).toFixed(decimals)}B`;\n }\n if (absNum >= 1e6) {\n return `${(num / 1e6).toFixed(decimals)}M`;\n }\n if (absNum >= 1e3) {\n return `${(num / 1e3).toFixed(decimals)}K`;\n }\n\n return num.toFixed(decimals);\n}\n\n/**\n * Format bytes to human-readable size.\n *\n * @example\n * ```ts\n * fBytes(1024)\n * // => \"1 KB\"\n *\n * fBytes(1048576)\n * // => \"1 MB\"\n *\n * fBytes(1073741824)\n * // => \"1 GB\"\n * ```\n */\nexport function fBytes(bytes: number | string | null | undefined, decimals: number = 2): string {\n if (bytes === null || bytes === undefined || bytes === '') {\n return '';\n }\n\n const num = typeof bytes === 'string' ? parseFloat(bytes) : bytes;\n\n if (Number.isNaN(num) || num === 0) {\n return '0 Bytes';\n }\n\n const k = 1024;\n const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB'];\n const i = Math.floor(Math.log(Math.abs(num)) / Math.log(k));\n\n return `${(num / Math.pow(k, i)).toFixed(decimals)} ${sizes[i]}`;\n}\n\n/**\n * Format number with ordinal suffix (1st, 2nd, 3rd, etc.)\n *\n * @example\n * ```ts\n * fOrdinal(1)\n * // => \"1st\"\n *\n * fOrdinal(22)\n * // => \"22nd\"\n *\n * fOrdinal(33)\n * // => \"33rd\"\n *\n * fOrdinal(44)\n * // => \"44th\"\n * ```\n */\nexport function fOrdinal(value: number | null | undefined): string {\n if (value === null || value === undefined) {\n return '';\n }\n\n const num = Math.abs(Math.floor(value));\n const suffixes = ['th', 'st', 'nd', 'rd'];\n const remainder = num % 100;\n\n const suffix = suffixes[(remainder - 20) % 10] || suffixes[remainder] || suffixes[0];\n\n return `${value}${suffix}`;\n}\n\n/**\n * Format a number with decimal places.\n *\n * @example\n * ```ts\n * fDecimal(1234.5678)\n * // => \"1234.57\"\n *\n * fDecimal(1234.5678, 4)\n * // => \"1234.5678\"\n *\n * fDecimal(1234)\n * // => \"1234.00\"\n * ```\n */\nexport function fDecimal(value: number | string | null | undefined, decimals: number = 2): string {\n if (value === null || value === undefined || value === '') {\n return '';\n }\n\n const num = typeof value === 'string' ? parseFloat(value) : value;\n\n if (Number.isNaN(num)) {\n return '';\n }\n\n return num.toFixed(decimals);\n}\n\n// =============================================================================\n// PERCENTAGE CALCULATIONS (Aurora pattern)\n// =============================================================================\n\n/**\n * Calculate percentage of a value relative to a total.\n *\n * @param value - The part value\n * @param total - The total value\n * @param decimals - Decimal places (default: 0)\n * @returns Percentage number (0-100)\n *\n * @example\n * ```ts\n * getPercentage(25, 100)\n * // => 25\n *\n * getPercentage(1, 3)\n * // => 33\n *\n * getPercentage(1, 3, 2)\n * // => 33.33\n *\n * getPercentage(50, 200)\n * // => 25\n * ```\n */\nexport function getPercentage(value: number, total: number, decimals: number = 0): number {\n if (total === 0) return 0;\n const percentage = (value / total) * 100;\n return Number(percentage.toFixed(decimals));\n}\n\n/**\n * Calculate percentage change between two values.\n *\n * @param current - Current value\n * @param previous - Previous value\n * @param decimals - Decimal places (default: 0)\n * @returns Percentage change (positive = increase, negative = decrease)\n *\n * @example\n * ```ts\n * calculatePercentageChange(150, 100)\n * // => 50 (50% increase)\n *\n * calculatePercentageChange(50, 100)\n * // => -50 (50% decrease)\n *\n * calculatePercentageChange(100, 100)\n * // => 0 (no change)\n *\n * calculatePercentageChange(120, 100, 1)\n * // => 20.0\n * ```\n */\nexport function calculatePercentageChange(current: number, previous: number, decimals: number = 0): number {\n if (previous === 0) return current === 0 ? 0 : 100;\n const change = ((current - previous) / Math.abs(previous)) * 100;\n return Number(change.toFixed(decimals));\n}\n\n/**\n * Get currency symbol for a currency code.\n *\n * @param currencyCode - ISO 4217 currency code (e.g., 'USD', 'EUR')\n * @param locale - Locale for formatting (default: 'en-US')\n * @returns Currency symbol (e.g., '$', '€', '¥')\n *\n * @example\n * ```ts\n * getCurrencySymbol('USD')\n * // => \"$\"\n *\n * getCurrencySymbol('EUR')\n * // => \"€\"\n *\n * getCurrencySymbol('JPY')\n * // => \"¥\"\n *\n * getCurrencySymbol('GBP')\n * // => \"£\"\n * ```\n */\nexport function getCurrencySymbol(currencyCode: string, locale: string = 'en-US'): string {\n const parts = new Intl.NumberFormat(locale, {\n style: 'currency',\n currency: currencyCode,\n })\n .formatToParts(0)\n .find((part) => part.type === 'currency');\n\n return parts?.value ?? currencyCode;\n}\n\n/**\n * Format a number with +/- sign prefix.\n *\n * @param value - Number to format\n * @param options - Formatting options\n * @returns Formatted string with sign\n *\n * @example\n * ```ts\n * fNumberWithSign(25)\n * // => \"+25\"\n *\n * fNumberWithSign(-25)\n * // => \"-25\"\n *\n * fNumberWithSign(0)\n * // => \"0\"\n *\n * fNumberWithSign(25.5, { maximumFractionDigits: 1 })\n * // => \"+25.5\"\n * ```\n */\nexport function fNumberWithSign(value: number | string | null | undefined, options: FormatNumberOptions = {}): string {\n if (value === null || value === undefined || value === '') {\n return '';\n }\n\n const num = typeof value === 'string' ? parseFloat(value) : value;\n\n if (Number.isNaN(num)) {\n return '';\n }\n\n const formatted = fNumber(Math.abs(num), options);\n if (num > 0) return `+${formatted}`;\n if (num < 0) return `-${formatted}`;\n return formatted;\n}\n\n/**\n * Format a number as compact notation (1K, 1M, 1B).\n * Uses Intl.NumberFormat with compact notation.\n *\n * @example\n * ```ts\n * fCompact(1234)\n * // => \"1.2K\"\n *\n * fCompact(1234567)\n * // => \"1.2M\"\n *\n * fCompact(1234567890)\n * // => \"1.2B\"\n * ```\n */\nexport function fCompact(value: number | string | null | undefined, options: FormatNumberOptions = {}): string {\n const { locale = 'en-US', ...formatOptions } = options;\n\n if (value === null || value === undefined || value === '') {\n return '';\n }\n\n const num = typeof value === 'string' ? parseFloat(value) : value;\n\n if (Number.isNaN(num)) {\n return '';\n }\n\n return new Intl.NumberFormat(locale, {\n notation: 'compact',\n compactDisplay: 'short',\n maximumFractionDigits: 1,\n ...formatOptions,\n }).format(num);\n}\n","/**\n * Date Formatting Utilities\n *\n * Locale-aware date formatting utilities using Intl.DateTimeFormat.\n * For more complex formatting, consider using dayjs or date-fns.\n *\n * @module utils/format-date\n */\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type DateInput = Date | string | number | null | undefined;\n\nexport interface FormatDateOptions extends Intl.DateTimeFormatOptions {\n /** Locale for formatting (default: 'en-US') */\n locale?: string;\n}\n\n// =============================================================================\n// HELPERS\n// =============================================================================\n\n/**\n * Parse various date inputs into a Date object.\n */\nfunction parseDate(input: DateInput): Date | null {\n if (input === null || input === undefined) {\n return null;\n }\n\n if (input instanceof Date) {\n return input;\n }\n\n const date = new Date(input);\n return Number.isNaN(date.getTime()) ? null : date;\n}\n\n// =============================================================================\n// DATE FORMATTING\n// =============================================================================\n\n/**\n * Format a date with locale-aware formatting.\n *\n * @example\n * ```ts\n * fDate(new Date())\n * // => \"Jan 15, 2025\"\n *\n * fDate(new Date(), { locale: 'ru-RU' })\n * // => \"15 янв. 2025 г.\"\n *\n * fDate('2025-01-15')\n * // => \"Jan 15, 2025\"\n * ```\n */\nexport function fDate(date: DateInput, options: FormatDateOptions = {}): string {\n const { locale = 'en-US', ...formatOptions } = options;\n\n const parsed = parseDate(date);\n if (!parsed) return '';\n\n return new Intl.DateTimeFormat(locale, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n ...formatOptions,\n }).format(parsed);\n}\n\n/**\n * Format a date with time.\n *\n * @example\n * ```ts\n * fDateTime(new Date())\n * // => \"Jan 15, 2025, 2:30 PM\"\n *\n * fDateTime(new Date(), { hour12: false })\n * // => \"Jan 15, 2025, 14:30\"\n * ```\n */\nexport function fDateTime(date: DateInput, options: FormatDateOptions = {}): string {\n const { locale = 'en-US', ...formatOptions } = options;\n\n const parsed = parseDate(date);\n if (!parsed) return '';\n\n return new Intl.DateTimeFormat(locale, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: 'numeric',\n minute: 'numeric',\n ...formatOptions,\n }).format(parsed);\n}\n\n/**\n * Format time only.\n *\n * @example\n * ```ts\n * fTime(new Date())\n * // => \"2:30 PM\"\n *\n * fTime(new Date(), { hour12: false })\n * // => \"14:30\"\n *\n * fTime(new Date(), { second: 'numeric' })\n * // => \"2:30:45 PM\"\n * ```\n */\nexport function fTime(date: DateInput, options: FormatDateOptions = {}): string {\n const { locale = 'en-US', ...formatOptions } = options;\n\n const parsed = parseDate(date);\n if (!parsed) return '';\n\n return new Intl.DateTimeFormat(locale, {\n hour: 'numeric',\n minute: 'numeric',\n ...formatOptions,\n }).format(parsed);\n}\n\n/**\n * Format a date as ISO string (YYYY-MM-DD).\n *\n * @example\n * ```ts\n * fDateISO(new Date())\n * // => \"2025-01-15\"\n * ```\n */\nexport function fDateISO(date: DateInput): string {\n const parsed = parseDate(date);\n if (!parsed) return '';\n\n return parsed.toISOString().split('T')[0];\n}\n\n/**\n * Format a timestamp as relative time (e.g., \"2 hours ago\").\n *\n * @example\n * ```ts\n * fRelativeTime(new Date(Date.now() - 3600000))\n * // => \"1 hour ago\"\n *\n * fRelativeTime(new Date(Date.now() + 86400000))\n * // => \"in 1 day\"\n *\n * fRelativeTime(new Date(Date.now() - 86400000 * 7))\n * // => \"1 week ago\"\n * ```\n */\nexport function fRelativeTime(date: DateInput, options: { locale?: string } = {}): string {\n const { locale = 'en-US' } = options;\n\n const parsed = parseDate(date);\n if (!parsed) return '';\n\n const now = new Date();\n const diffMs = parsed.getTime() - now.getTime();\n const diffSeconds = Math.round(diffMs / 1000);\n const diffMinutes = Math.round(diffSeconds / 60);\n const diffHours = Math.round(diffMinutes / 60);\n const diffDays = Math.round(diffHours / 24);\n const diffWeeks = Math.round(diffDays / 7);\n const diffMonths = Math.round(diffDays / 30);\n const diffYears = Math.round(diffDays / 365);\n\n const rtf = new Intl.RelativeTimeFormat(locale, { numeric: 'auto' });\n\n if (Math.abs(diffSeconds) < 60) {\n return rtf.format(diffSeconds, 'second');\n }\n if (Math.abs(diffMinutes) < 60) {\n return rtf.format(diffMinutes, 'minute');\n }\n if (Math.abs(diffHours) < 24) {\n return rtf.format(diffHours, 'hour');\n }\n if (Math.abs(diffDays) < 7) {\n return rtf.format(diffDays, 'day');\n }\n if (Math.abs(diffWeeks) < 4) {\n return rtf.format(diffWeeks, 'week');\n }\n if (Math.abs(diffMonths) < 12) {\n return rtf.format(diffMonths, 'month');\n }\n return rtf.format(diffYears, 'year');\n}\n\n/**\n * Format a duration in milliseconds to human-readable string.\n *\n * @example\n * ```ts\n * fDuration(3661000)\n * // => \"1h 1m 1s\"\n *\n * fDuration(90000)\n * // => \"1m 30s\"\n *\n * fDuration(1000)\n * // => \"1s\"\n * ```\n */\nexport function fDuration(ms: number | null | undefined): string {\n if (ms === null || ms === undefined || ms < 0) return '';\n\n const seconds = Math.floor((ms / 1000) % 60);\n const minutes = Math.floor((ms / (1000 * 60)) % 60);\n const hours = Math.floor((ms / (1000 * 60 * 60)) % 24);\n const days = Math.floor(ms / (1000 * 60 * 60 * 24));\n\n const parts: string[] = [];\n\n if (days > 0) parts.push(`${days}d`);\n if (hours > 0) parts.push(`${hours}h`);\n if (minutes > 0) parts.push(`${minutes}m`);\n if (seconds > 0 || parts.length === 0) parts.push(`${seconds}s`);\n\n return parts.join(' ');\n}\n\n/**\n * Check if a date is today.\n *\n * @example\n * ```ts\n * isToday(new Date())\n * // => true\n *\n * isToday(new Date('2020-01-01'))\n * // => false\n * ```\n */\nexport function isToday(date: DateInput): boolean {\n const parsed = parseDate(date);\n if (!parsed) return false;\n\n const today = new Date();\n return (\n parsed.getDate() === today.getDate() &&\n parsed.getMonth() === today.getMonth() &&\n parsed.getFullYear() === today.getFullYear()\n );\n}\n\n/**\n * Check if a date is yesterday.\n */\nexport function isYesterday(date: DateInput): boolean {\n const parsed = parseDate(date);\n if (!parsed) return false;\n\n const yesterday = new Date();\n yesterday.setDate(yesterday.getDate() - 1);\n\n return (\n parsed.getDate() === yesterday.getDate() &&\n parsed.getMonth() === yesterday.getMonth() &&\n parsed.getFullYear() === yesterday.getFullYear()\n );\n}\n\n/**\n * Check if a date is within the current week.\n */\nexport function isThisWeek(date: DateInput): boolean {\n const parsed = parseDate(date);\n if (!parsed) return false;\n\n const now = new Date();\n const weekStart = new Date(now);\n weekStart.setDate(now.getDate() - now.getDay());\n weekStart.setHours(0, 0, 0, 0);\n\n const weekEnd = new Date(weekStart);\n weekEnd.setDate(weekStart.getDate() + 6);\n weekEnd.setHours(23, 59, 59, 999);\n\n return parsed >= weekStart && parsed <= weekEnd;\n}\n\n/**\n * Check if a date is in the past.\n */\nexport function isPast(date: DateInput): boolean {\n const parsed = parseDate(date);\n if (!parsed) return false;\n\n return parsed.getTime() < Date.now();\n}\n\n/**\n * Check if a date is in the future.\n */\nexport function isFuture(date: DateInput): boolean {\n const parsed = parseDate(date);\n if (!parsed) return false;\n\n return parsed.getTime() > Date.now();\n}\n\n/**\n * Get the difference between two dates in days.\n */\nexport function diffInDays(date1: DateInput, date2: DateInput): number {\n const d1 = parseDate(date1);\n const d2 = parseDate(date2);\n\n if (!d1 || !d2) return 0;\n\n const diffTime = Math.abs(d2.getTime() - d1.getTime());\n return Math.ceil(diffTime / (1000 * 60 * 60 * 24));\n}\n\n// =============================================================================\n// DATE RANGE UTILITIES (Aurora pattern)\n// =============================================================================\n\n/** One day in milliseconds */\nconst DAY_MS = 1000 * 60 * 60 * 24;\n\n/**\n * Generate an array of dates between start and end.\n *\n * @param startDate - Start date\n * @param endDate - End date\n * @param interval - Interval in milliseconds (default: 1 day)\n * @returns Array of Date objects\n *\n * @example\n * ```ts\n * const dates = getDates(\n * new Date('2025-01-01'),\n * new Date('2025-01-07')\n * );\n * // => [Date(Jan 1), Date(Jan 2), ..., Date(Jan 7)]\n *\n * // With custom interval (every 2 days)\n * const dates = getDates(\n * new Date('2025-01-01'),\n * new Date('2025-01-07'),\n * DAY_MS * 2\n * );\n * // => [Date(Jan 1), Date(Jan 3), Date(Jan 5), Date(Jan 7)]\n * ```\n */\nexport function getDates(startDate: DateInput, endDate: DateInput, interval: number = DAY_MS): Date[] {\n const start = parseDate(startDate);\n const end = parseDate(endDate);\n\n if (!start || !end) return [];\n\n const duration = +end - +start;\n const steps = Math.floor(duration / interval);\n\n return Array.from({ length: steps + 1 }, (_, i) => new Date(start.valueOf() + interval * i));\n}\n\n/**\n * Duration preset for getPastDates.\n */\nexport type DateDurationPreset = 'week' | 'month' | 'quarter' | 'year';\n\n/**\n * Get an array of dates for past duration.\n *\n * @param duration - Duration preset or number of days\n * @returns Array of Date objects from past to present\n *\n * @example\n * ```ts\n * // Last 7 days\n * const weekDates = getPastDates('week');\n *\n * // Last 30 days\n * const monthDates = getPastDates('month');\n *\n * // Last 90 days\n * const quarterDates = getPastDates('quarter');\n *\n * // Last 365 days\n * const yearDates = getPastDates('year');\n *\n * // Custom: last 14 days\n * const customDates = getPastDates(14);\n * ```\n */\nexport function getPastDates(duration: DateDurationPreset | number): Date[] {\n const durationMap: Record<DateDurationPreset, number> = {\n week: 7,\n month: 30,\n quarter: 90,\n year: 365,\n };\n\n const days = typeof duration === 'number' ? duration : durationMap[duration];\n const endDate = new Date();\n const startDate = new Date();\n startDate.setDate(endDate.getDate() - days);\n\n return getDates(startDate, endDate);\n}\n\n/**\n * Get an array of dates for future duration.\n *\n * @param duration - Duration preset or number of days\n * @returns Array of Date objects from present to future\n *\n * @example\n * ```ts\n * // Next 7 days\n * const weekDates = getFutureDates('week');\n *\n * // Next 30 days\n * const monthDates = getFutureDates('month');\n *\n * // Custom: next 14 days\n * const customDates = getFutureDates(14);\n * ```\n */\nexport function getFutureDates(duration: DateDurationPreset | number): Date[] {\n const durationMap: Record<DateDurationPreset, number> = {\n week: 7,\n month: 30,\n quarter: 90,\n year: 365,\n };\n\n const days = typeof duration === 'number' ? duration : durationMap[duration];\n const startDate = new Date();\n const endDate = new Date();\n endDate.setDate(startDate.getDate() + days);\n\n return getDates(startDate, endDate);\n}\n\n/**\n * Get start of day (midnight) for a date.\n *\n * @param date - Input date\n * @returns Date set to 00:00:00.000\n */\nexport function startOfDay(date: DateInput): Date | null {\n const parsed = parseDate(date);\n if (!parsed) return null;\n\n const result = new Date(parsed);\n result.setHours(0, 0, 0, 0);\n return result;\n}\n\n/**\n * Get end of day (23:59:59.999) for a date.\n *\n * @param date - Input date\n * @returns Date set to 23:59:59.999\n */\nexport function endOfDay(date: DateInput): Date | null {\n const parsed = parseDate(date);\n if (!parsed) return null;\n\n const result = new Date(parsed);\n result.setHours(23, 59, 59, 999);\n return result;\n}\n\n/**\n * Add days to a date.\n *\n * @param date - Input date\n * @param days - Number of days to add (can be negative)\n * @returns New date with days added\n */\nexport function addDays(date: DateInput, days: number): Date | null {\n const parsed = parseDate(date);\n if (!parsed) return null;\n\n const result = new Date(parsed);\n result.setDate(result.getDate() + days);\n return result;\n}\n\n/**\n * Add months to a date.\n *\n * @param date - Input date\n * @param months - Number of months to add (can be negative)\n * @returns New date with months added\n */\nexport function addMonths(date: DateInput, months: number): Date | null {\n const parsed = parseDate(date);\n if (!parsed) return null;\n\n const result = new Date(parsed);\n result.setMonth(result.getMonth() + months);\n return result;\n}\n","/**\n * String Utilities\n *\n * Common string manipulation utilities.\n *\n * @module utils/string\n */\n\n// =============================================================================\n// TEXT FORMATTING\n// =============================================================================\n\n/**\n * Truncate text with ellipsis.\n *\n * @example\n * ```ts\n * truncate('Hello, World!', 8)\n * // => \"Hello...\"\n *\n * truncate('Short', 10)\n * // => \"Short\"\n *\n * truncate('Hello, World!', 8, '…')\n * // => \"Hello, W…\"\n * ```\n */\nexport function truncate(text: string | null | undefined, length: number, suffix: string = '...'): string {\n if (!text) return '';\n if (text.length <= length) return text;\n\n return text.slice(0, length - suffix.length) + suffix;\n}\n\n/**\n * Get initials from a name.\n *\n * @example\n * ```ts\n * getInitials('John Doe')\n * // => \"JD\"\n *\n * getInitials('Alice Bob Charlie')\n * // => \"AC\"\n *\n * getInitials('SingleName')\n * // => \"SI\"\n * ```\n */\nexport function getInitials(name: string | null | undefined): string {\n if (!name) return '';\n\n const words = name.trim().split(/\\s+/);\n\n if (words.length === 1) {\n return words[0].slice(0, 2).toUpperCase();\n }\n\n return (words[0][0] + words[words.length - 1][0]).toUpperCase();\n}\n\n/**\n * Capitalize the first letter of a string.\n *\n * @example\n * ```ts\n * capitalize('hello world')\n * // => \"Hello world\"\n * ```\n */\nexport function capitalize(text: string | null | undefined): string {\n if (!text) return '';\n return text.charAt(0).toUpperCase() + text.slice(1);\n}\n\n/**\n * Capitalize the first letter of each word.\n *\n * @example\n * ```ts\n * titleCase('hello world')\n * // => \"Hello World\"\n *\n * titleCase('the quick brown fox')\n * // => \"The Quick Brown Fox\"\n * ```\n */\nexport function titleCase(text: string | null | undefined): string {\n if (!text) return '';\n return text.replace(/\\b\\w/g, (char) => char.toUpperCase());\n}\n\n/**\n * Convert string to kebab-case.\n *\n * @example\n * ```ts\n * kebabCase('Hello World')\n * // => \"hello-world\"\n *\n * kebabCase('camelCaseString')\n * // => \"camel-case-string\"\n * ```\n */\nexport function kebabCase(text: string | null | undefined): string {\n if (!text) return '';\n\n return text\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .replace(/[\\s_]+/g, '-')\n .toLowerCase();\n}\n\n/**\n * Convert string to camelCase.\n *\n * @example\n * ```ts\n * camelCase('Hello World')\n * // => \"helloWorld\"\n *\n * camelCase('kebab-case-string')\n * // => \"kebabCaseString\"\n * ```\n */\nexport function camelCase(text: string | null | undefined): string {\n if (!text) return '';\n\n return text.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (_, char) => char.toUpperCase());\n}\n\n/**\n * Convert string to snake_case.\n *\n * @example\n * ```ts\n * snakeCase('Hello World')\n * // => \"hello_world\"\n *\n * snakeCase('camelCaseString')\n * // => \"camel_case_string\"\n * ```\n */\nexport function snakeCase(text: string | null | undefined): string {\n if (!text) return '';\n\n return text\n .replace(/([a-z])([A-Z])/g, '$1_$2')\n .replace(/[\\s-]+/g, '_')\n .toLowerCase();\n}\n\n// =============================================================================\n// SEARCH & HIGHLIGHT\n// =============================================================================\n\n/**\n * Highlight search query in text by wrapping matches in <mark> tags.\n *\n * @example\n * ```ts\n * highlightText('Hello World', 'wor')\n * // => \"Hello <mark>Wor</mark>ld\"\n *\n * highlightText('Test Case', 'test', '<strong>', '</strong>')\n * // => \"<strong>Test</strong> Case\"\n * ```\n */\nexport function highlightText(\n text: string | null | undefined,\n query: string | null | undefined,\n openTag: string = '<mark>',\n closeTag: string = '</mark>'\n): string {\n if (!text) return '';\n if (!query) return text;\n\n const regex = new RegExp(`(${escapeRegExp(query)})`, 'gi');\n return text.replace(regex, `${openTag}$1${closeTag}`);\n}\n\n/**\n * Escape special regex characters in a string.\n *\n * @example\n * ```ts\n * escapeRegExp('test.string+with[special]chars')\n * // => \"test\\\\.string\\\\+with\\\\[special\\\\]chars\"\n * ```\n */\nexport function escapeRegExp(text: string): string {\n return text.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n/**\n * Check if a string contains a substring (case-insensitive).\n *\n * @example\n * ```ts\n * containsIgnoreCase('Hello World', 'WORLD')\n * // => true\n *\n * containsIgnoreCase('Hello World', 'foo')\n * // => false\n * ```\n */\nexport function containsIgnoreCase(text: string | null | undefined, search: string | null | undefined): boolean {\n if (!text || !search) return false;\n return text.toLowerCase().includes(search.toLowerCase());\n}\n\n// =============================================================================\n// VALIDATION\n// =============================================================================\n\n/**\n * Check if a string is empty or whitespace only.\n *\n * @example\n * ```ts\n * isBlank('')\n * // => true\n *\n * isBlank(' ')\n * // => true\n *\n * isBlank('hello')\n * // => false\n * ```\n */\nexport function isBlank(text: string | null | undefined): boolean {\n return !text || text.trim().length === 0;\n}\n\n/**\n * Check if a string is a valid email address (basic check).\n *\n * @example\n * ```ts\n * isEmail('test@example.com')\n * // => true\n *\n * isEmail('invalid')\n * // => false\n * ```\n */\nexport function isEmail(text: string | null | undefined): boolean {\n if (!text) return false;\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n return emailRegex.test(text);\n}\n\n/**\n * Check if a string is a valid URL (basic check).\n *\n * @example\n * ```ts\n * isUrl('https://example.com')\n * // => true\n *\n * isUrl('not-a-url')\n * // => false\n * ```\n */\nexport function isUrl(text: string | null | undefined): boolean {\n if (!text) return false;\n try {\n new URL(text);\n return true;\n } catch {\n return false;\n }\n}\n\n// =============================================================================\n// GENERATION\n// =============================================================================\n\n/**\n * Generate a random string of specified length.\n *\n * @example\n * ```ts\n * randomString(8)\n * // => \"a3Bx9kPq\"\n *\n * randomString(16, 'abc123')\n * // => \"a1b3c2a1b3c2a1b3\"\n * ```\n */\nexport function randomString(\n length: number = 8,\n chars: string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'\n): string {\n let result = '';\n for (let i = 0; i < length; i++) {\n result += chars.charAt(Math.floor(Math.random() * chars.length));\n }\n return result;\n}\n\n/**\n * Generate a UUID v4.\n *\n * @example\n * ```ts\n * uuid()\n * // => \"550e8400-e29b-41d4-a716-446655440000\"\n * ```\n */\nexport function uuid(): string {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n\n/**\n * Generate a slug from text.\n *\n * @example\n * ```ts\n * slugify('Hello World!')\n * // => \"hello-world\"\n *\n * slugify('This is a Test String')\n * // => \"this-is-a-test-string\"\n * ```\n */\nexport function slugify(text: string | null | undefined): string {\n if (!text) return '';\n\n return text\n .toString()\n .toLowerCase()\n .trim()\n .replace(/\\s+/g, '-') // Replace spaces with -\n .replace(/[^\\w-]+/g, '') // Remove non-word chars\n .replace(/--+/g, '-') // Replace multiple - with single -\n .replace(/^-+/, '') // Trim - from start\n .replace(/-+$/, ''); // Trim - from end\n}\n","/**\n * LocalStorage Utilities\n *\n * SSR-safe localStorage utilities with JSON serialization support.\n * Inspired by minimal-shared/utils/local-storage pattern.\n *\n * @module utils/storage\n */\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport interface StorageOptions {\n /** Storage to use (default: localStorage) */\n storage?: Storage;\n /** Serialize function (default: JSON.stringify) */\n serialize?: (value: unknown) => string;\n /** Deserialize function (default: JSON.parse) */\n deserialize?: (value: string) => unknown;\n}\n\n// =============================================================================\n// AVAILABILITY CHECK\n// =============================================================================\n\n/**\n * Check if localStorage is available in the current environment.\n * Handles SSR, private browsing, and quota exceeded scenarios.\n *\n * @example\n * ```ts\n * if (localStorageAvailable()) {\n * localStorage.setItem('key', 'value');\n * }\n * ```\n */\nexport function localStorageAvailable(): boolean {\n try {\n if (typeof window === 'undefined') {\n return false;\n }\n\n const testKey = '__storage_test__';\n window.localStorage.setItem(testKey, testKey);\n window.localStorage.removeItem(testKey);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Check if sessionStorage is available in the current environment.\n *\n * @example\n * ```ts\n * if (sessionStorageAvailable()) {\n * sessionStorage.setItem('key', 'value');\n * }\n * ```\n */\nexport function sessionStorageAvailable(): boolean {\n try {\n if (typeof window === 'undefined') {\n return false;\n }\n\n const testKey = '__storage_test__';\n window.sessionStorage.setItem(testKey, testKey);\n window.sessionStorage.removeItem(testKey);\n return true;\n } catch {\n return false;\n }\n}\n\n// =============================================================================\n// GET STORAGE\n// =============================================================================\n\n/**\n * Get a value from localStorage with automatic JSON parsing.\n * Returns defaultValue if key doesn't exist, parsing fails, or storage is unavailable.\n *\n * @param key - Storage key\n * @param defaultValue - Value to return if key doesn't exist or parsing fails\n * @param options - Storage options\n * @returns Parsed value or defaultValue\n *\n * @example\n * ```ts\n * // Simple value\n * const count = getStorage('count', 0);\n *\n * // Object value\n * const user = getStorage<User>('user', null);\n *\n * // With sessionStorage\n * const session = getStorage('session', null, {\n * storage: sessionStorage,\n * });\n * ```\n */\nexport function getStorage<T>(key: string, defaultValue: T, options: StorageOptions = {}): T {\n const { storage = typeof window !== 'undefined' ? window.localStorage : undefined, deserialize = JSON.parse } =\n options;\n\n try {\n if (!storage) {\n return defaultValue;\n }\n\n const value = storage.getItem(key);\n\n if (value === null) {\n return defaultValue;\n }\n\n return deserialize(value) as T;\n } catch {\n return defaultValue;\n }\n}\n\n// =============================================================================\n// SET STORAGE\n// =============================================================================\n\n/**\n * Set a value in localStorage with automatic JSON serialization.\n * Silently fails if storage is unavailable.\n *\n * @param key - Storage key\n * @param value - Value to store (will be JSON serialized)\n * @param options - Storage options\n * @returns true if successful, false otherwise\n *\n * @example\n * ```ts\n * // Simple value\n * setStorage('count', 42);\n *\n * // Object value\n * setStorage('user', { id: 1, name: 'John' });\n *\n * // With sessionStorage\n * setStorage('session', sessionData, {\n * storage: sessionStorage,\n * });\n * ```\n */\nexport function setStorage<T>(key: string, value: T, options: StorageOptions = {}): boolean {\n const { storage = typeof window !== 'undefined' ? window.localStorage : undefined, serialize = JSON.stringify } =\n options;\n\n try {\n if (!storage) {\n return false;\n }\n\n storage.setItem(key, serialize(value));\n return true;\n } catch {\n // Quota exceeded or other storage error\n return false;\n }\n}\n\n// =============================================================================\n// REMOVE STORAGE\n// =============================================================================\n\n/**\n * Remove a value from localStorage.\n * Silently fails if storage is unavailable.\n *\n * @param key - Storage key to remove\n * @param options - Storage options\n * @returns true if successful, false otherwise\n *\n * @example\n * ```ts\n * removeStorage('user');\n *\n * // From sessionStorage\n * removeStorage('session', { storage: sessionStorage });\n * ```\n */\nexport function removeStorage(key: string, options: Pick<StorageOptions, 'storage'> = {}): boolean {\n const { storage = typeof window !== 'undefined' ? window.localStorage : undefined } = options;\n\n try {\n if (!storage) {\n return false;\n }\n\n storage.removeItem(key);\n return true;\n } catch {\n return false;\n }\n}\n\n// =============================================================================\n// CLEAR STORAGE\n// =============================================================================\n\n/**\n * Clear all items from localStorage.\n * Silently fails if storage is unavailable.\n *\n * @param options - Storage options\n * @returns true if successful, false otherwise\n *\n * @example\n * ```ts\n * clearStorage();\n *\n * // Clear sessionStorage\n * clearStorage({ storage: sessionStorage });\n * ```\n */\nexport function clearStorage(options: Pick<StorageOptions, 'storage'> = {}): boolean {\n const { storage = typeof window !== 'undefined' ? window.localStorage : undefined } = options;\n\n try {\n if (!storage) {\n return false;\n }\n\n storage.clear();\n return true;\n } catch {\n return false;\n }\n}\n\n// =============================================================================\n// STORAGE KEYS\n// =============================================================================\n\n/**\n * Get all keys from localStorage.\n *\n * @param options - Storage options\n * @returns Array of storage keys\n *\n * @example\n * ```ts\n * const keys = getStorageKeys();\n * // => ['user', 'settings', 'cart']\n * ```\n */\nexport function getStorageKeys(options: Pick<StorageOptions, 'storage'> = {}): string[] {\n const { storage = typeof window !== 'undefined' ? window.localStorage : undefined } = options;\n\n try {\n if (!storage) {\n return [];\n }\n\n const keys: string[] = [];\n for (let i = 0; i < storage.length; i++) {\n const key = storage.key(i);\n if (key !== null) {\n keys.push(key);\n }\n }\n return keys;\n } catch {\n return [];\n }\n}\n\n// =============================================================================\n// STORAGE SIZE\n// =============================================================================\n\n/**\n * Get approximate size of localStorage in bytes.\n *\n * @param options - Storage options\n * @returns Size in bytes\n *\n * @example\n * ```ts\n * const sizeBytes = getStorageSize();\n * console.log(`Using ${sizeBytes} bytes of localStorage`);\n * ```\n */\nexport function getStorageSize(options: Pick<StorageOptions, 'storage'> = {}): number {\n const { storage = typeof window !== 'undefined' ? window.localStorage : undefined } = options;\n\n try {\n if (!storage) {\n return 0;\n }\n\n let total = 0;\n for (let i = 0; i < storage.length; i++) {\n const key = storage.key(i);\n if (key !== null) {\n const value = storage.getItem(key) ?? '';\n // Each character is 2 bytes in JavaScript\n total += (key.length + value.length) * 2;\n }\n }\n return total;\n } catch {\n return 0;\n }\n}\n\n// =============================================================================\n// STORAGE WITH EXPIRY\n// =============================================================================\n\nexport interface StorageWithExpiryOptions extends StorageOptions {\n /** Time to live in milliseconds */\n ttl: number;\n}\n\ninterface StoredWithExpiry<T> {\n value: T;\n expiry: number;\n}\n\n/**\n * Set a value with expiration time.\n *\n * @param key - Storage key\n * @param value - Value to store\n * @param options - Options with TTL in milliseconds\n *\n * @example\n * ```ts\n * // Store for 1 hour\n * setStorageWithExpiry('session', sessionData, {\n * ttl: 60 * 60 * 1000,\n * });\n *\n * // Store for 24 hours\n * setStorageWithExpiry('cache', cacheData, {\n * ttl: 24 * 60 * 60 * 1000,\n * });\n * ```\n */\nexport function setStorageWithExpiry<T>(key: string, value: T, options: StorageWithExpiryOptions): boolean {\n const { ttl, ...storageOptions } = options;\n\n const item: StoredWithExpiry<T> = {\n value,\n expiry: Date.now() + ttl,\n };\n\n return setStorage(key, item, storageOptions);\n}\n\n/**\n * Get a value that was stored with expiration.\n * Returns defaultValue if expired or not found.\n *\n * @param key - Storage key\n * @param defaultValue - Value to return if expired or not found\n * @param options - Storage options\n *\n * @example\n * ```ts\n * const session = getStorageWithExpiry<Session>('session', null);\n * if (!session) {\n * // Session expired or doesn't exist\n * redirectToLogin();\n * }\n * ```\n */\nexport function getStorageWithExpiry<T>(key: string, defaultValue: T, options: StorageOptions = {}): T {\n const item = getStorage<StoredWithExpiry<T> | null>(key, null, options);\n\n if (!item) {\n return defaultValue;\n }\n\n if (Date.now() > item.expiry) {\n // Expired - remove the item\n removeStorage(key, options);\n return defaultValue;\n }\n\n return item.value;\n}\n","/**\n * Font Utilities\n *\n * Font family and unit conversion helpers.\n *\n * @module utils\n */\n\n/**\n * Default system font stack.\n */\nconst DEFAULT_FONT_STACK =\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\"';\n\n/**\n * Create a font family string with fallback stack.\n *\n * @param {string} [fontName] - Primary font name\n * @returns {string} Font family with fallbacks\n *\n * @example\n * ```ts\n * setFont('Inter'); // '\"Inter\", -apple-system, ...'\n * setFont(); // Default system font stack\n * ```\n */\nexport function setFont(fontName?: string): string {\n if (!fontName) {\n return DEFAULT_FONT_STACK;\n }\n\n return `\"${fontName}\", ${DEFAULT_FONT_STACK}`;\n}\n\n/**\n * Convert rem to pixels.\n *\n * @param {string | number} value - Rem value (number or string like '1rem')\n * @returns {number} Value in pixels\n *\n * @example\n * ```ts\n * remToPx(1); // 16\n * remToPx('1rem'); // 16\n * remToPx(1.5); // 24\n * ```\n */\nexport function remToPx(value: string | number): number {\n const numValue = typeof value === 'string' ? parseFloat(value) : value;\n return Math.round(numValue * 16 * 100) / 100;\n}\n\n/**\n * Convert pixels to rem.\n *\n * @param {string | number} value - Pixel value (number or string like '16px')\n * @returns {string} Value in rem with unit\n *\n * @example\n * ```ts\n * pxToRem(16); // '1rem'\n * pxToRem('16px'); // '1rem'\n * pxToRem(24); // '1.5rem'\n * ```\n */\nexport function pxToRem(value: string | number): string {\n const numValue = typeof value === 'string' ? parseFloat(value) : value;\n return `${Math.round((numValue / 16) * 10000) / 10000}rem`;\n}\n\n/**\n * Create responsive font size based on viewport.\n *\n * @param {number} minSize - Minimum font size in px\n * @param {number} maxSize - Maximum font size in px\n * @param {number} [minWidth=320] - Minimum viewport width in px\n * @param {number} [maxWidth=1200] - Maximum viewport width in px\n * @returns {string} CSS clamp() value\n *\n * @example\n * ```ts\n * responsiveFontSize(14, 18);\n * // 'clamp(0.875rem, 0.7955rem + 0.3977vw, 1.125rem)'\n * ```\n */\nexport function responsiveFontSize(minSize: number, maxSize: number, minWidth = 320, maxWidth = 1200): string {\n const minRem = pxToRem(minSize);\n const maxRem = pxToRem(maxSize);\n\n const slope = (maxSize - minSize) / (maxWidth - minWidth);\n const intercept = minSize - slope * minWidth;\n\n const slopeVw = Math.round(slope * 100 * 10000) / 10000;\n const interceptRem = pxToRem(intercept);\n\n return `clamp(${minRem}, ${interceptRem} + ${slopeVw}vw, ${maxRem})`;\n}\n","/**\n * Object Utilities\n *\n * Type-safe object manipulation helpers.\n *\n * @module utils\n */\n\n/**\n * Check if an object has specific keys.\n *\n * Vacuously true when `keys` is empty, in line with `Array.every`\n * — \"every key in the empty set is present\" matches the standard\n * library and avoids surprising callers that pass a dynamically\n * derived list of required keys.\n *\n * @template T - Object type\n * @template K - Key type\n * @param {T | null | undefined} obj - Object to check\n * @param {K[]} keys - Keys to check for\n * @returns {boolean} True if object has all specified keys\n *\n * @example\n * ```ts\n * const user = { name: 'John', email: 'john@example.com' };\n * hasKeys(user, ['name', 'email']); // true\n * hasKeys(user, ['name', 'age']); // false\n * hasKeys(null, ['name']); // false\n * hasKeys(user, []); // true (vacuous)\n * ```\n */\nexport function hasKeys<T extends object, K extends keyof T>(obj: T | null | undefined, keys: K[]): boolean {\n if (!obj || typeof obj !== 'object') {\n return false;\n }\n\n return keys.every((key) => key in obj);\n}\n\n/**\n * Omit specific keys from an object.\n *\n * @template T - Object type\n * @template K - Keys to omit\n * @param {T} obj - Source object\n * @param {K[]} keys - Keys to omit\n * @returns {Omit<T, K>} New object without specified keys\n *\n * @example\n * ```ts\n * const user = { name: 'John', email: 'john@example.com', password: '...' };\n * omit(user, ['password']); // { name: 'John', email: 'john@example.com' }\n * ```\n */\nexport function omit<T extends object, K extends keyof T>(obj: T, keys: K[]): Omit<T, K> {\n const result = { ...obj };\n for (const key of keys) {\n delete result[key];\n }\n return result as Omit<T, K>;\n}\n\n/**\n * Pick specific keys from an object.\n *\n * @template T - Object type\n * @template K - Keys to pick\n * @param {T} obj - Source object\n * @param {K[]} keys - Keys to pick\n * @returns {Pick<T, K>} New object with only specified keys\n *\n * @example\n * ```ts\n * const user = { name: 'John', email: 'john@example.com', password: '...' };\n * pick(user, ['name', 'email']); // { name: 'John', email: 'john@example.com' }\n * ```\n */\nexport function pick<T extends object, K extends keyof T>(obj: T, keys: K[]): Pick<T, K> {\n const result = {} as Pick<T, K>;\n for (const key of keys) {\n if (key in obj) {\n result[key] = obj[key];\n }\n }\n return result;\n}\n\n/**\n * Deep clone an object.\n *\n * @template T - Object type\n * @param {T} obj - Object to clone\n * @returns {T} Deep cloned object\n *\n * @example\n * ```ts\n * const original = { a: 1, b: { c: 2 } };\n * const cloned = deepClone(original);\n * cloned.b.c = 3; // original.b.c is still 2\n * ```\n */\nexport function deepClone<T>(obj: T): T {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => deepClone(item)) as unknown as T;\n }\n\n if (obj instanceof Date) {\n return new Date(obj.getTime()) as unknown as T;\n }\n\n if (obj instanceof RegExp) {\n return new RegExp(obj.source, obj.flags) as unknown as T;\n }\n\n const cloned = {} as T;\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n cloned[key] = deepClone(obj[key]);\n }\n }\n return cloned;\n}\n\n/**\n * Check if a value is empty (null, undefined, empty string, empty array, empty object).\n *\n * @param {unknown} value - Value to check\n * @returns {boolean} True if empty\n *\n * @example\n * ```ts\n * isEmpty(null); // true\n * isEmpty(''); // true\n * isEmpty([]); // true\n * isEmpty({}); // true\n * isEmpty('hello'); // false\n * isEmpty([1]); // false\n * ```\n */\nexport function isEmpty(value: unknown): boolean {\n if (value == null) {\n return true;\n }\n\n if (typeof value === 'string' || Array.isArray(value)) {\n return value.length === 0;\n }\n\n if (typeof value === 'object') {\n return Object.keys(value as object).length === 0;\n }\n\n return false;\n}\n","/**\n * RTL (Right-to-Left) Utilities\n *\n * Helpers for RTL layout support and CSS transformation control.\n *\n * @module utils\n */\n\n/**\n * Prevents automatic RTL (right-to-left) flipping of a CSS declaration.\n *\n * Many CSS-in-JS libraries and RTL plugins automatically flip directional\n * CSS properties (like margin-left → margin-right) for RTL layouts.\n * Use this function to prevent that behavior for specific declarations.\n *\n * Appends the `\\/* @noflip *\\/` comment which is recognized by:\n * - stylis (used by Emotion/styled-components)\n * - rtlcss\n * - cssjanus\n *\n * @param cssValue - A CSS declaration string (e.g., \"margin-left: 10px\")\n * @returns The same declaration with `\\/* @noflip *\\/` appended\n *\n * @example\n * ```tsx\n * import { noRtlFlip } from '@omnitron-dev/prism/utils';\n *\n * // In sx prop or styled components\n * const styles = {\n * // This margin-left will stay as margin-left even in RTL\n * marginLeft: noRtlFlip('10px'),\n *\n * // Or for full declarations\n * transform: noRtlFlip('translateX(100px)'),\n * };\n *\n * // Common use case: icons that shouldn't flip\n * <ChevronIcon sx={{ transform: noRtlFlip('rotate(0deg)') }} />\n *\n * // Progress indicators that fill from left regardless of RTL\n * <ProgressBar sx={{ left: noRtlFlip('0'), right: 'auto' }} />\n * ```\n */\nexport function noRtlFlip(cssValue: unknown): string {\n if (typeof cssValue !== 'string') {\n if (process.env.NODE_ENV !== 'production') {\n console.warn('[noRtlFlip] Invalid CSS value provided:', cssValue);\n }\n return '';\n }\n\n const trimmed = cssValue.trim();\n\n if (!trimmed) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn('[noRtlFlip] Empty CSS value provided');\n }\n return '';\n }\n\n // Already has the noflip comment\n if (trimmed.includes('/* @noflip */')) {\n return trimmed;\n }\n\n return `${trimmed} /* @noflip */`;\n}\n\n/**\n * Check if the current document direction is RTL.\n *\n * @returns True if the document direction is RTL\n *\n * @example\n * ```tsx\n * const isRtl = isRtlDirection();\n *\n * // Conditional styling\n * const style = {\n * marginLeft: isRtl ? '0' : '10px',\n * marginRight: isRtl ? '10px' : '0',\n * };\n * ```\n */\nexport function isRtlDirection(): boolean {\n if (typeof document === 'undefined') {\n return false;\n }\n\n return (\n document.documentElement.dir === 'rtl' ||\n document.body.dir === 'rtl' ||\n document.documentElement.getAttribute('dir') === 'rtl'\n );\n}\n\n/**\n * Get the appropriate directional property name based on RTL state.\n *\n * @param property - Base property name (e.g., 'left', 'marginLeft')\n * @param isRtl - Whether the layout is RTL\n * @returns The appropriate property name\n *\n * @example\n * ```tsx\n * const prop = getDirectionalProperty('left', isRtl);\n * // Returns 'right' if isRtl, 'left' otherwise\n * ```\n */\nexport function getDirectionalProperty(\n property: 'left' | 'right' | 'marginLeft' | 'marginRight' | 'paddingLeft' | 'paddingRight',\n isRtl: boolean\n): string {\n const mappings: Record<string, string> = {\n left: isRtl ? 'right' : 'left',\n right: isRtl ? 'left' : 'right',\n marginLeft: isRtl ? 'marginRight' : 'marginLeft',\n marginRight: isRtl ? 'marginLeft' : 'marginRight',\n paddingLeft: isRtl ? 'paddingRight' : 'paddingLeft',\n paddingRight: isRtl ? 'paddingLeft' : 'paddingRight',\n };\n\n return mappings[property] ?? property;\n}\n","/**\n * AsyncLock Utility\n *\n * Prevents race conditions in async operations like token refresh.\n * Ensures only one operation runs at a time, with subsequent calls\n * waiting for and sharing the result of the in-flight operation.\n *\n * @module utils\n */\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * Options for AsyncLock.\n */\nexport interface AsyncLockOptions {\n /** Timeout in milliseconds for the lock acquisition (default: 30000) */\n timeout?: number;\n /** Custom error message for timeout */\n timeoutMessage?: string;\n}\n\n/**\n * Result from a locked operation.\n */\nexport interface AsyncLockResult<T> {\n /** The result value */\n value: T;\n /** Whether this call executed the operation (vs waiting for another) */\n wasExecutor: boolean;\n}\n\n/**\n * State of the lock.\n */\nexport type AsyncLockState = 'idle' | 'locked' | 'releasing';\n\n// =============================================================================\n// ASYNC LOCK CLASS\n// =============================================================================\n\n/**\n * AsyncLock prevents race conditions in concurrent async operations.\n *\n * Use cases:\n * - Token refresh: Multiple API calls fail simultaneously, only one should refresh\n * - Resource initialization: Expensive setup should happen once\n * - Cache population: Prevent thundering herd problem\n *\n * @example\n * ```tsx\n * import { AsyncLock } from '@omnitron-dev/prism/utils';\n *\n * const tokenRefreshLock = new AsyncLock({ timeout: 10000 });\n *\n * async function refreshToken(): Promise<string> {\n * const { value: newToken } = await tokenRefreshLock.acquire(\n * 'refresh-token',\n * async () => {\n * // This only runs once even if called concurrently\n * const response = await fetch('/auth/refresh', { method: 'POST' });\n * const data = await response.json();\n * return data.accessToken;\n * }\n * );\n * return newToken;\n * }\n *\n * // Multiple concurrent calls share the same result\n * const [token1, token2, token3] = await Promise.all([\n * refreshToken(), // Executes the actual refresh\n * refreshToken(), // Waits for first to complete\n * refreshToken(), // Waits for first to complete\n * ]);\n * // token1 === token2 === token3\n * ```\n */\nexport class AsyncLock {\n private locks: Map<string, Promise<unknown>> = new Map();\n private resolvers: Map<string, (value: unknown) => void> = new Map();\n private rejecters: Map<string, (error: unknown) => void> = new Map();\n private options: Required<AsyncLockOptions>;\n\n constructor(options: AsyncLockOptions = {}) {\n this.options = {\n timeout: options.timeout ?? 30000,\n timeoutMessage: options.timeoutMessage ?? 'Lock acquisition timed out',\n };\n }\n\n /**\n * Current state of a specific lock.\n */\n getState(key: string): AsyncLockState {\n return this.locks.has(key) ? 'locked' : 'idle';\n }\n\n /**\n * Check if a specific lock is currently held.\n */\n isLocked(key: string): boolean {\n return this.locks.has(key);\n }\n\n /**\n * Get all currently active lock keys.\n */\n getActiveLocks(): string[] {\n return Array.from(this.locks.keys());\n }\n\n /**\n * Acquire the lock and execute the operation.\n * If the lock is already held, waits for the existing operation.\n *\n * @param key - Unique identifier for this lock\n * @param operation - Async operation to execute\n * @returns Result with the value and whether this call was the executor\n */\n async acquire<T>(key: string, operation: () => Promise<T>): Promise<AsyncLockResult<T>> {\n // If lock exists, wait for it\n const existingLock = this.locks.get(key);\n if (existingLock) {\n const value = await this.waitWithTimeout(existingLock, key);\n return { value: value as T, wasExecutor: false };\n }\n\n // Create new lock\n let resolvePromise: (value: unknown) => void;\n let rejectPromise: (error: unknown) => void;\n\n const lockPromise = new Promise<unknown>((resolve, reject) => {\n resolvePromise = resolve;\n rejectPromise = reject;\n });\n\n this.locks.set(key, lockPromise);\n this.resolvers.set(key, resolvePromise!);\n this.rejecters.set(key, rejectPromise!);\n\n try {\n const result = await operation();\n\n // Resolve for all waiters\n const resolver = this.resolvers.get(key);\n if (resolver) {\n resolver(result);\n }\n\n return { value: result, wasExecutor: true };\n } catch (error) {\n // Reject for all waiters\n const rejecter = this.rejecters.get(key);\n if (rejecter) {\n rejecter(error);\n }\n\n throw error;\n } finally {\n // Clean up\n this.locks.delete(key);\n this.resolvers.delete(key);\n this.rejecters.delete(key);\n }\n }\n\n /**\n * Try to acquire the lock without waiting.\n * Returns immediately if lock is held.\n *\n * @param key - Unique identifier for this lock\n * @param operation - Async operation to execute\n * @returns Result or null if lock was already held\n */\n async tryAcquire<T>(key: string, operation: () => Promise<T>): Promise<AsyncLockResult<T> | null> {\n if (this.isLocked(key)) {\n return null;\n }\n return this.acquire(key, operation);\n }\n\n /**\n * Force release a lock (use with caution).\n * This will reject all waiters with the provided error.\n */\n forceRelease(key: string, error?: Error): void {\n const rejecter = this.rejecters.get(key);\n if (rejecter) {\n rejecter(error ?? new Error('Lock forcefully released'));\n }\n this.locks.delete(key);\n this.resolvers.delete(key);\n this.rejecters.delete(key);\n }\n\n /**\n * Clear all locks (use with caution, e.g., on logout).\n */\n clearAll(error?: Error): void {\n for (const key of this.locks.keys()) {\n this.forceRelease(key, error);\n }\n }\n\n /**\n * Wait for a promise with timeout.\n */\n private async waitWithTimeout<T>(promise: Promise<T>, key: string): Promise<T> {\n const { timeout, timeoutMessage } = this.options;\n\n if (timeout <= 0) {\n return promise;\n }\n\n return Promise.race([\n promise,\n new Promise<never>((_, reject) => {\n setTimeout(() => {\n reject(new AsyncLockTimeoutError(`${timeoutMessage} (key: ${key})`));\n }, timeout);\n }),\n ]);\n }\n}\n\n// =============================================================================\n// ERROR CLASSES\n// =============================================================================\n\n/**\n * Error thrown when lock acquisition times out.\n */\nexport class AsyncLockTimeoutError extends Error {\n readonly name = 'AsyncLockTimeoutError';\n\n constructor(message: string) {\n super(message);\n Object.setPrototypeOf(this, AsyncLockTimeoutError.prototype);\n }\n}\n\n// =============================================================================\n// FACTORY FUNCTIONS\n// =============================================================================\n\n/**\n * Create a singleton AsyncLock instance for a specific use case.\n *\n * @example\n * ```tsx\n * import { createAsyncLock } from '@omnitron-dev/prism/utils';\n *\n * // Create a singleton lock for token refresh\n * const tokenLock = createAsyncLock({ timeout: 10000 });\n *\n * // Use in multiple places - same lock instance\n * async function apiCall() {\n * if (isTokenExpired()) {\n * await tokenLock.acquire('token', refreshToken);\n * }\n * // Make API call...\n * }\n * ```\n */\nexport function createAsyncLock(options?: AsyncLockOptions): AsyncLock {\n return new AsyncLock(options);\n}\n\n/**\n * Create a pre-configured lock for token refresh operations.\n * Uses sensible defaults for auth token refresh scenarios.\n */\nexport function createTokenRefreshLock(): AsyncLock {\n return new AsyncLock({\n timeout: 15000,\n timeoutMessage: 'Token refresh timed out',\n });\n}\n\n// =============================================================================\n// UTILITY FUNCTIONS\n// =============================================================================\n\n/**\n * Execute an operation with automatic locking.\n * Convenience function for one-off locked operations.\n *\n * @example\n * ```tsx\n * import { withLock } from '@omnitron-dev/prism/utils';\n *\n * const result = await withLock('init-cache', async () => {\n * const data = await fetchData();\n * cache.set('data', data);\n * return data;\n * });\n * ```\n */\nconst globalLock = new AsyncLock();\n\nexport async function withLock<T>(key: string, operation: () => Promise<T>, options?: AsyncLockOptions): Promise<T> {\n const lock = options ? new AsyncLock(options) : globalLock;\n const { value } = await lock.acquire(key, operation);\n return value;\n}\n\n/**\n * Decorator factory for methods that should be locked.\n * Use with class methods to ensure single execution.\n *\n * @example\n * ```tsx\n * import { locked } from '@omnitron-dev/prism/utils';\n *\n * class AuthService {\n * @locked('refresh')\n * async refreshToken(): Promise<string> {\n * // Only one instance runs at a time\n * return await this.doRefresh();\n * }\n * }\n * ```\n */\nexport function locked(key: string, options?: AsyncLockOptions) {\n const lock = new AsyncLock(options);\n\n return function <T extends (...args: unknown[]) => Promise<unknown>>(\n _target: object,\n _propertyKey: string,\n descriptor: TypedPropertyDescriptor<T>\n ): TypedPropertyDescriptor<T> {\n const originalMethod = descriptor.value;\n\n if (!originalMethod) {\n return descriptor;\n }\n\n descriptor.value = async function (this: unknown, ...args: unknown[]) {\n const { value } = await lock.acquire(key, () => originalMethod.apply(this, args));\n return value;\n } as T;\n\n return descriptor;\n };\n}\n","/**\n * Error Handling Utilities\n *\n * Comprehensive error handling with i18n support, error classification,\n * and retry logic for robust frontend applications.\n *\n * @module utils\n */\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * Error codes for classification.\n */\nexport type ErrorCode =\n // Auth errors\n | 'AUTH_REQUIRED'\n | 'AUTH_EXPIRED'\n | 'AUTH_INVALID'\n | 'AUTH_FORBIDDEN'\n | 'AUTH_MFA_REQUIRED'\n | 'AUTH_DEVICE_BLOCKED'\n // Network errors\n | 'NETWORK_ERROR'\n | 'NETWORK_TIMEOUT'\n | 'NETWORK_OFFLINE'\n // Validation errors\n | 'VALIDATION_ERROR'\n | 'VALIDATION_REQUIRED'\n | 'VALIDATION_FORMAT'\n | 'VALIDATION_RANGE'\n // Server errors\n | 'SERVER_ERROR'\n | 'SERVER_UNAVAILABLE'\n | 'SERVER_MAINTENANCE'\n // Client errors\n | 'NOT_FOUND'\n | 'CONFLICT'\n | 'RATE_LIMITED'\n | 'QUOTA_EXCEEDED'\n // Generic\n | 'UNKNOWN_ERROR'\n | string;\n\n/**\n * Severity levels for errors.\n */\nexport type ErrorSeverity = 'error' | 'warning' | 'info';\n\n/**\n * Error context for i18n.\n */\nexport interface ErrorContext {\n /** Error code for lookup */\n code: ErrorCode;\n /** HTTP status code if applicable */\n status?: number;\n /** Field name for validation errors */\n field?: string;\n /** Additional interpolation values */\n values?: Record<string, string | number>;\n /** Original error message (fallback) */\n message?: string;\n /** Retry information */\n retryAfter?: number;\n /** Severity level */\n severity?: ErrorSeverity;\n}\n\n/**\n * Translated error result.\n */\nexport interface TranslatedError {\n /** Translated title */\n title: string;\n /** Translated message */\n message: string;\n /** Error code */\n code: ErrorCode;\n /** Severity */\n severity: ErrorSeverity;\n /** Action hint (e.g., \"Please log in again\") */\n action?: string;\n /** Retry after seconds */\n retryAfter?: number;\n /** Is this a retryable error */\n canRetry: boolean;\n}\n\n/**\n * Translation function type.\n */\nexport type TranslateFn = (key: string, values?: Record<string, string | number>) => string;\n\n/**\n * Error messages dictionary type.\n */\nexport interface ErrorMessages {\n [code: string]: {\n title: string;\n message: string;\n action?: string;\n };\n}\n\n// =============================================================================\n// DEFAULT ERROR MESSAGES\n// =============================================================================\n\n/**\n * Default error messages in English.\n * Can be replaced with i18n translations.\n */\nexport const DEFAULT_ERROR_MESSAGES: ErrorMessages = {\n // Auth\n AUTH_REQUIRED: {\n title: 'Authentication Required',\n message: 'Please log in to continue.',\n action: 'Log in',\n },\n AUTH_EXPIRED: {\n title: 'Session Expired',\n message: 'Your session has expired. Please log in again.',\n action: 'Log in again',\n },\n AUTH_INVALID: {\n title: 'Invalid Credentials',\n message: 'The provided credentials are invalid.',\n action: 'Try again',\n },\n AUTH_FORBIDDEN: {\n title: 'Access Denied',\n message: \"You don't have permission to access this resource.\",\n },\n AUTH_MFA_REQUIRED: {\n title: 'Verification Required',\n message: 'Please complete two-factor authentication.',\n action: 'Verify',\n },\n AUTH_DEVICE_BLOCKED: {\n title: 'Device Blocked',\n message: 'This device has been blocked. Contact support for assistance.',\n },\n // Network\n NETWORK_ERROR: {\n title: 'Connection Error',\n message: 'Unable to connect to the server. Please check your connection.',\n action: 'Retry',\n },\n NETWORK_TIMEOUT: {\n title: 'Request Timeout',\n message: 'The request took too long. Please try again.',\n action: 'Retry',\n },\n NETWORK_OFFLINE: {\n title: 'Offline',\n message: \"You're currently offline. Please check your internet connection.\",\n },\n // Validation\n VALIDATION_ERROR: {\n title: 'Validation Error',\n message: 'Please check your input and try again.',\n },\n VALIDATION_REQUIRED: {\n title: 'Required Field',\n message: 'This field is required.',\n },\n VALIDATION_FORMAT: {\n title: 'Invalid Format',\n message: 'Please enter a valid format.',\n },\n VALIDATION_RANGE: {\n title: 'Out of Range',\n message: 'The value is out of the allowed range.',\n },\n // Server\n SERVER_ERROR: {\n title: 'Server Error',\n message: 'Something went wrong on our end. Please try again later.',\n action: 'Retry',\n },\n SERVER_UNAVAILABLE: {\n title: 'Service Unavailable',\n message: 'The service is temporarily unavailable. Please try again later.',\n action: 'Retry',\n },\n SERVER_MAINTENANCE: {\n title: 'Under Maintenance',\n message: \"We're performing maintenance. Please check back soon.\",\n },\n // Client\n NOT_FOUND: {\n title: 'Not Found',\n message: 'The requested resource could not be found.',\n },\n CONFLICT: {\n title: 'Conflict',\n message: 'The resource was modified. Please refresh and try again.',\n action: 'Refresh',\n },\n RATE_LIMITED: {\n title: 'Too Many Requests',\n message: 'Please slow down and try again later.',\n },\n QUOTA_EXCEEDED: {\n title: 'Quota Exceeded',\n message: 'You have exceeded your usage quota.',\n },\n // Generic\n UNKNOWN_ERROR: {\n title: 'Error',\n message: 'An unexpected error occurred. Please try again.',\n action: 'Retry',\n },\n};\n\n// =============================================================================\n// ERROR CLASSIFICATION\n// =============================================================================\n\n/**\n * Classify an error by HTTP status code.\n */\nexport function classifyHttpError(status: number): ErrorCode {\n switch (status) {\n case 400:\n return 'VALIDATION_ERROR';\n case 401:\n return 'AUTH_REQUIRED';\n case 403:\n return 'AUTH_FORBIDDEN';\n case 404:\n return 'NOT_FOUND';\n case 408:\n return 'NETWORK_TIMEOUT';\n case 409:\n return 'CONFLICT';\n case 429:\n return 'RATE_LIMITED';\n case 500:\n return 'SERVER_ERROR';\n case 502:\n case 503:\n case 504:\n return 'SERVER_UNAVAILABLE';\n default:\n if (status >= 400 && status < 500) return 'VALIDATION_ERROR';\n if (status >= 500) return 'SERVER_ERROR';\n return 'UNKNOWN_ERROR';\n }\n}\n\n/** errno values that mean the transport failed, whatever the message says. */\nconst NETWORK_ERRNOS = new Set([\n 'ECONNREFUSED',\n 'ECONNRESET',\n 'ENOTFOUND',\n 'EHOSTUNREACH',\n 'ENETUNREACH',\n 'ETIMEDOUT',\n 'EPIPE',\n 'EAI_AGAIN',\n]);\n\n/**\n * How each engine words a `fetch` that never reached the server.\n *\n * Chrome and Edge say \"Failed to fetch\", Firefox \"NetworkError when\n * attempting to fetch resource\", React Native \"Network request failed\" — and\n * Safari says \"Load failed\", which contains none of the words the previous\n * version looked for. Every offline request in Safari was therefore reported\n * as an unrecognised error, including a lazy route's chunk, where the\n * recovery a user needs is a reload.\n */\nconst FETCH_FAILURE = /failed to fetch|networkerror when attempting|load failed|network request failed/i;\n\n/**\n * Check if an error is a network error.\n *\n * Deciding by the words a message happens to contain cuts the wrong way in\n * both directions. Matching \"network\", \"connection\" or \"offline\" anywhere in\n * any message classified \"Connection to the payment provider was declined\"\n * and \"This network is not supported in your region\" — ordinary server\n * answers — as the user's connection failing, which sends them to check a\n * router instead of reading what the server said. Against a corpus of the\n * eight shapes a real network failure takes and five that only mention one,\n * the old predicate was right 7 times out of 13.\n *\n * So: an errno if the error carries one, the engine's own wording if `fetch`\n * rejected (it rejects with a TypeError and nothing else for a network-level\n * failure), and axios's exact `Network Error` — which is its whole message,\n * not a fragment of a sentence.\n */\nexport function isNetworkError(error: unknown): boolean {\n if (!(error instanceof Error)) return false;\n\n const code = (error as { code?: unknown }).code;\n if (typeof code === 'string' && NETWORK_ERRNOS.has(code)) return true;\n\n if (error instanceof TypeError) return FETCH_FAILURE.test(error.message);\n\n return /^network error$/i.test(error.message.trim());\n}\n\n/**\n * Check if an error is retryable.\n */\nexport function isRetryableError(code: ErrorCode): boolean {\n const retryableCodes: ErrorCode[] = [\n 'NETWORK_ERROR',\n 'NETWORK_TIMEOUT',\n 'SERVER_ERROR',\n 'SERVER_UNAVAILABLE',\n 'RATE_LIMITED',\n 'CONFLICT',\n ];\n return retryableCodes.includes(code);\n}\n\n/**\n * Get severity for an error code.\n */\nexport function getErrorSeverity(code: ErrorCode): ErrorSeverity {\n // Warnings (recoverable, action possible)\n const warnings: ErrorCode[] = ['AUTH_EXPIRED', 'RATE_LIMITED', 'NETWORK_OFFLINE', 'AUTH_MFA_REQUIRED'];\n\n // Info (informational, not blocking)\n const infos: ErrorCode[] = ['SERVER_MAINTENANCE'];\n\n if (warnings.includes(code)) return 'warning';\n if (infos.includes(code)) return 'info';\n return 'error';\n}\n\n// =============================================================================\n// ERROR TRANSLATION\n// =============================================================================\n\n/**\n * Create an error translator with custom messages or i18n function.\n *\n * @example\n * ```tsx\n * // With custom messages\n * const translate = createErrorTranslator({\n * messages: {\n * AUTH_REQUIRED: {\n * title: 'Необходима авторизация',\n * message: 'Пожалуйста, войдите в систему.',\n * },\n * },\n * });\n *\n * // With i18n library\n * const translate = createErrorTranslator({\n * t: (key, values) => i18n.t(key, values),\n * });\n *\n * const error = translate({ code: 'AUTH_REQUIRED', status: 401 });\n * // { title: 'Необходима авторизация', message: '...', ... }\n * ```\n */\nexport function createErrorTranslator(options: {\n messages?: ErrorMessages;\n t?: TranslateFn;\n fallbackMessages?: ErrorMessages;\n}): (context: ErrorContext) => TranslatedError {\n const { messages = {}, t, fallbackMessages = DEFAULT_ERROR_MESSAGES } = options;\n\n return (context: ErrorContext): TranslatedError => {\n const { code, values, message: originalMessage, severity, retryAfter } = context;\n\n // Try i18n translation first\n if (t) {\n const titleKey = `errors.${code}.title`;\n const messageKey = `errors.${code}.message`;\n const actionKey = `errors.${code}.action`;\n\n const title = t(titleKey, values);\n const translatedMessage = t(messageKey, values);\n const action = t(actionKey, values);\n\n // If translation was found (not equal to key)\n if (title !== titleKey) {\n return {\n title,\n message: translatedMessage !== messageKey ? translatedMessage : originalMessage || '',\n code,\n severity: severity ?? getErrorSeverity(code),\n action: action !== actionKey ? action : undefined,\n retryAfter,\n canRetry: isRetryableError(code),\n };\n }\n }\n\n // Try custom messages, then fallback.\n //\n // Own-property lookups: `code` comes off the wire, and a plain object\n // answers `messages['constructor']` with a function — which would then be\n // read for `.title` / `.message` and render `undefined` to the user\n // instead of an error description.\n const errorDef =\n (Object.hasOwn(messages, code) ? messages[code] : undefined) ??\n (Object.hasOwn(fallbackMessages, code) ? fallbackMessages[code] : undefined) ??\n fallbackMessages.UNKNOWN_ERROR;\n\n return {\n title: errorDef.title,\n message: interpolateMessage(errorDef.message, values) || originalMessage || errorDef.message,\n code,\n severity: severity ?? getErrorSeverity(code),\n action: errorDef.action,\n retryAfter,\n canRetry: isRetryableError(code),\n };\n };\n}\n\n/**\n * Simple message interpolation.\n */\nfunction interpolateMessage(template: string, values?: Record<string, string | number>): string {\n if (!values) return template;\n return Object.entries(values).reduce(\n (msg, [key, value]) => msg.replace(new RegExp(`\\\\{${key}\\\\}`, 'g'), String(value)),\n template\n );\n}\n\n// =============================================================================\n// ERROR EXTRACTION\n// =============================================================================\n\n/**\n * Extract error context from various error types.\n *\n * @example\n * ```tsx\n * try {\n * await api.call();\n * } catch (error) {\n * const context = extractErrorContext(error);\n * const translated = translateError(context);\n * showNotification(translated);\n * }\n * ```\n */\nexport function extractErrorContext(error: unknown): ErrorContext {\n // Already an ErrorContext\n if (isErrorContext(error)) {\n return error;\n }\n\n // Response-like object (fetch Response or similar)\n if (isResponseLike(error)) {\n return {\n code: classifyHttpError(error.status),\n status: error.status,\n message: error.statusText,\n };\n }\n\n // Error with response property (axios-like)\n if (hasResponseProperty(error)) {\n const response = error.response;\n const data = response.data;\n\n // Extract typed values from response data with safe fallbacks\n const code = typeof data?.code === 'string' ? data.code : classifyHttpError(response.status);\n const message = typeof data?.message === 'string' ? data.message : response.statusText;\n const field = typeof data?.field === 'string' ? data.field : undefined;\n const values =\n data?.values !== undefined &&\n typeof data.values === 'object' &&\n data.values !== null &&\n !Array.isArray(data.values)\n ? (data.values as Record<string, string | number>)\n : undefined;\n\n return {\n code,\n status: response.status,\n message,\n values,\n field,\n };\n }\n\n // Network error\n if (isNetworkError(error)) {\n return {\n code: navigator?.onLine === false ? 'NETWORK_OFFLINE' : 'NETWORK_ERROR',\n message: error instanceof Error ? error.message : 'Network error',\n };\n }\n\n // Generic Error\n if (error instanceof Error) {\n return {\n code: 'UNKNOWN_ERROR',\n message: error.message,\n };\n }\n\n // String error\n if (typeof error === 'string') {\n return {\n code: 'UNKNOWN_ERROR',\n message: error,\n };\n }\n\n // Object with message/code\n if (error && typeof error === 'object') {\n const obj = error as Record<string, unknown>;\n return {\n code: (typeof obj.code === 'string' ? obj.code : 'UNKNOWN_ERROR') as ErrorCode,\n message: typeof obj.message === 'string' ? obj.message : undefined,\n status: typeof obj.status === 'number' ? obj.status : undefined,\n };\n }\n\n return { code: 'UNKNOWN_ERROR' };\n}\n\n// Type guards\nfunction isErrorContext(value: unknown): value is ErrorContext {\n return (\n value !== null && typeof value === 'object' && 'code' in value && typeof (value as ErrorContext).code === 'string'\n );\n}\n\nfunction isResponseLike(value: unknown): value is { status: number; statusText: string } {\n return (\n value !== null &&\n typeof value === 'object' &&\n 'status' in value &&\n typeof (value as Record<string, unknown>).status === 'number'\n );\n}\n\nfunction hasResponseProperty(\n value: unknown\n): value is { response: { status: number; statusText: string; data?: Record<string, unknown> } } {\n return (\n value !== null &&\n typeof value === 'object' &&\n 'response' in value &&\n isResponseLike((value as Record<string, unknown>).response)\n );\n}\n\n// =============================================================================\n// RETRY UTILITIES\n// =============================================================================\n\n/**\n * Retry configuration.\n */\nexport interface RetryConfig {\n /** Maximum number of retries */\n maxRetries?: number;\n /** Initial delay in ms */\n initialDelay?: number;\n /** Maximum delay in ms */\n maxDelay?: number;\n /** Exponential backoff factor */\n backoffFactor?: number;\n /** Add jitter to delays */\n jitter?: boolean;\n /** Custom retry condition */\n shouldRetry?: (error: unknown, attempt: number) => boolean;\n /** Called before each retry */\n onRetry?: (error: unknown, attempt: number, delay: number) => void;\n}\n\nconst DEFAULT_RETRY_CONFIG: Required<RetryConfig> = {\n maxRetries: 3,\n initialDelay: 1000,\n maxDelay: 30000,\n backoffFactor: 2,\n jitter: true,\n shouldRetry: (error) => {\n const context = extractErrorContext(error);\n return isRetryableError(context.code);\n },\n onRetry: () => {},\n};\n\n/**\n * Execute an async operation with automatic retry.\n *\n * @example\n * ```tsx\n * const result = await withRetry(\n * () => fetch('/api/data'),\n * {\n * maxRetries: 3,\n * onRetry: (error, attempt, delay) => {\n * console.log(`Retry ${attempt} after ${delay}ms`);\n * },\n * }\n * );\n * ```\n */\nexport async function withRetry<T>(operation: () => Promise<T>, config?: RetryConfig): Promise<T> {\n const opts = { ...DEFAULT_RETRY_CONFIG, ...config };\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= opts.maxRetries; attempt++) {\n try {\n return await operation();\n } catch (error) {\n lastError = error;\n\n if (attempt === opts.maxRetries || !opts.shouldRetry(error, attempt)) {\n throw error;\n }\n\n const delay = calculateDelay(attempt, opts);\n opts.onRetry(error, attempt + 1, delay);\n await sleep(delay);\n }\n }\n\n throw lastError;\n}\n\n/**\n * Calculate delay with exponential backoff and optional jitter.\n */\nfunction calculateDelay(attempt: number, config: Required<RetryConfig>): number {\n let delay = config.initialDelay * Math.pow(config.backoffFactor, attempt);\n delay = Math.min(delay, config.maxDelay);\n\n if (config.jitter) {\n // Add ±25% jitter\n delay = delay * (0.75 + Math.random() * 0.5);\n }\n\n return Math.round(delay);\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n// =============================================================================\n// ERROR BOUNDARY HELPERS\n// =============================================================================\n\n/**\n * Check if error is a chunk load error (code splitting failure).\n */\nexport function isChunkLoadError(error: unknown): boolean {\n if (error instanceof Error) {\n const message = error.message.toLowerCase();\n return (\n message.includes('loading chunk') ||\n message.includes('loading css chunk') ||\n message.includes('dynamically imported module')\n );\n }\n return false;\n}\n\n/**\n * Check if error is a session expiry error.\n */\nexport function isSessionExpiredError(error: unknown): boolean {\n const context = extractErrorContext(error);\n return context.code === 'AUTH_EXPIRED' || context.code === 'AUTH_REQUIRED';\n}\n\n/**\n * Create a handler for error boundary recovery.\n */\nexport function createErrorRecoveryHandler(options: {\n onChunkError?: () => void;\n onSessionExpired?: () => void;\n onNetworkError?: () => void;\n onGenericError?: (error: unknown) => void;\n}): (error: unknown) => void {\n return (error: unknown) => {\n if (isChunkLoadError(error)) {\n options.onChunkError?.();\n return;\n }\n\n if (isSessionExpiredError(error)) {\n options.onSessionExpired?.();\n return;\n }\n\n if (isNetworkError(error)) {\n options.onNetworkError?.();\n return;\n }\n\n options.onGenericError?.(error);\n };\n}\n","/**\n * Fetch Interceptor Factory\n *\n * A flexible fetch wrapper with support for request/response interceptors,\n * automatic token refresh, and retry logic.\n *\n * Designed for production applications that need centralized HTTP handling.\n *\n * @module utils\n */\n\nimport { createAsyncLock, type AsyncLock } from './async-lock.js';\nimport { extractErrorContext, withRetry, type RetryConfig } from './errors.js';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * Extended request init with additional options.\n */\nexport interface FetchRequestInit extends RequestInit {\n /** Skip all interceptors for this request */\n skipInterceptors?: boolean;\n /** Skip request interceptors only */\n skipRequestInterceptors?: boolean;\n /** Skip response interceptors only */\n skipResponseInterceptors?: boolean;\n /** Custom timeout in milliseconds */\n timeout?: number;\n /** Enable automatic retry on failure */\n retry?: boolean | RetryConfig;\n /** Request metadata for logging/debugging */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Request interceptor context.\n */\nexport interface RequestContext {\n url: string;\n init: FetchRequestInit;\n /** Original request info (can be string or Request) */\n input: RequestInfo | URL;\n /** Request metadata */\n metadata: Record<string, unknown>;\n}\n\n/**\n * Response interceptor context.\n */\nexport interface ResponseContext {\n response: Response;\n request: RequestContext;\n /** Time taken for the request in ms */\n duration: number;\n}\n\n/**\n * Error interceptor context.\n */\nexport interface ErrorContext {\n error: unknown;\n request: RequestContext;\n /** Time taken before error in ms */\n duration: number;\n /** Number of retry attempts made */\n retryCount: number;\n}\n\n/**\n * Request interceptor function.\n * Can modify the request or return a new one.\n */\nexport type RequestInterceptor = (ctx: RequestContext) => RequestContext | Promise<RequestContext>;\n\n/**\n * Response interceptor function.\n * Can modify the response or return a new one.\n */\nexport type ResponseInterceptor = (ctx: ResponseContext) => Response | Promise<Response>;\n\n/**\n * Error interceptor function.\n * Can handle the error, retry, or rethrow.\n */\nexport type ErrorInterceptor = (ctx: ErrorContext) => Response | Promise<Response> | never;\n\n/**\n * Interceptor configuration.\n */\nexport interface FetchInterceptorConfig {\n /** Base URL to prepend to relative paths */\n baseUrl?: string;\n /** Default headers for all requests */\n defaultHeaders?: HeadersInit;\n /** Default timeout in milliseconds (0 = no timeout) */\n defaultTimeout?: number;\n /** Request interceptors (run in order) */\n requestInterceptors?: RequestInterceptor[];\n /** Response interceptors (run in order) */\n responseInterceptors?: ResponseInterceptor[];\n /** Error interceptors (run in order, first to handle wins) */\n errorInterceptors?: ErrorInterceptor[];\n /** Default retry configuration */\n defaultRetry?: RetryConfig | false;\n /** Credentials mode for all requests */\n credentials?: RequestCredentials;\n}\n\n/**\n * Token refresh handler configuration.\n */\nexport interface TokenRefreshConfig {\n /** Check if a response indicates token expiration */\n isTokenExpired: (response: Response) => boolean;\n /** Refresh the token (called when token is expired) */\n refreshToken: () => Promise<string | null>;\n /** Get the current access token */\n getAccessToken: () => string | null;\n /** Called when refresh fails (e.g., redirect to login) */\n onRefreshFailure?: () => void;\n /** Maximum number of refresh attempts */\n maxRefreshAttempts?: number;\n}\n\n/**\n * Fetch client interface.\n */\nexport interface FetchClient {\n /** Make a fetch request */\n fetch: (input: RequestInfo | URL, init?: FetchRequestInit) => Promise<Response>;\n /** Add a request interceptor */\n addRequestInterceptor: (interceptor: RequestInterceptor) => () => void;\n /** Add a response interceptor */\n addResponseInterceptor: (interceptor: ResponseInterceptor) => () => void;\n /** Add an error interceptor */\n addErrorInterceptor: (interceptor: ErrorInterceptor) => () => void;\n /** Remove all interceptors */\n clearInterceptors: () => void;\n /** Get current configuration */\n getConfig: () => FetchInterceptorConfig;\n}\n\n// =============================================================================\n// FETCH INTERCEPTOR FACTORY\n// =============================================================================\n\n/**\n * Create a fetch client with interceptor support.\n *\n * @example\n * ```tsx\n * // Basic usage\n * const api = createFetchClient({\n * baseUrl: 'https://api.example.com',\n * defaultHeaders: { 'Content-Type': 'application/json' },\n * defaultTimeout: 30000,\n * });\n *\n * // Add auth header interceptor\n * api.addRequestInterceptor(async (ctx) => {\n * const token = getAccessToken();\n * if (token) {\n * ctx.init.headers = {\n * ...ctx.init.headers,\n * Authorization: `Bearer ${token}`,\n * };\n * }\n * return ctx;\n * });\n *\n * // Add response logging\n * api.addResponseInterceptor(async (ctx) => {\n * console.log(`${ctx.request.init.method} ${ctx.request.url} - ${ctx.response.status} (${ctx.duration}ms)`);\n * return ctx.response;\n * });\n *\n * // Make requests\n * const response = await api.fetch('/users');\n * const data = await response.json();\n * ```\n */\nexport function createFetchClient(config: FetchInterceptorConfig = {}): FetchClient {\n const requestInterceptors: RequestInterceptor[] = [...(config.requestInterceptors ?? [])];\n const responseInterceptors: ResponseInterceptor[] = [...(config.responseInterceptors ?? [])];\n const errorInterceptors: ErrorInterceptor[] = [...(config.errorInterceptors ?? [])];\n\n /**\n * Build the full URL from input.\n */\n function buildUrl(input: RequestInfo | URL): string {\n const baseUrl = config.baseUrl ?? '';\n\n if (typeof input === 'string') {\n // If input is absolute, use it as-is\n if (input.startsWith('http://') || input.startsWith('https://')) {\n return input;\n }\n // Combine with base URL\n const base = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;\n const path = input.startsWith('/') ? input : `/${input}`;\n return `${base}${path}`;\n }\n\n if (input instanceof URL) {\n return input.toString();\n }\n\n // Request object\n return input.url;\n }\n\n /**\n * Merge headers from multiple sources.\n */\n function mergeHeaders(...sources: (HeadersInit | undefined)[]): Record<string, string> {\n const result: Record<string, string> = {};\n\n for (const source of sources) {\n if (!source) continue;\n\n if (source instanceof Headers) {\n source.forEach((value, key) => {\n result[key] = value;\n });\n } else if (Array.isArray(source)) {\n for (const [key, value] of source) {\n result[key] = value;\n }\n } else {\n Object.assign(result, source);\n }\n }\n\n return result;\n }\n\n /**\n * Execute fetch with timeout.\n */\n async function fetchWithTimeout(url: string, init: RequestInit, timeout: number): Promise<Response> {\n if (timeout <= 0) {\n return fetch(url, init);\n }\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n return await fetch(url, {\n ...init,\n signal: controller.signal,\n });\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * The main fetch function.\n */\n async function clientFetch(input: RequestInfo | URL, init: FetchRequestInit = {}): Promise<Response> {\n const startTime = Date.now();\n let retryCount = 0;\n\n // Build initial request context\n let ctx: RequestContext = {\n url: buildUrl(input),\n init: {\n ...init,\n headers: mergeHeaders(config.defaultHeaders, init.headers),\n credentials: init.credentials ?? config.credentials,\n },\n input,\n metadata: init.metadata ?? {},\n };\n\n // Run request interceptors\n if (!init.skipInterceptors && !init.skipRequestInterceptors) {\n for (const interceptor of requestInterceptors) {\n ctx = await interceptor(ctx);\n }\n }\n\n const timeout = init.timeout ?? config.defaultTimeout ?? 0;\n\n /**\n * Execute the actual request.\n */\n async function executeRequest(): Promise<Response> {\n try {\n const response = await fetchWithTimeout(ctx.url, ctx.init, timeout);\n const duration = Date.now() - startTime;\n\n // Run response interceptors\n if (!init.skipInterceptors && !init.skipResponseInterceptors) {\n let finalResponse = response;\n for (const interceptor of responseInterceptors) {\n finalResponse = await interceptor({\n response: finalResponse,\n request: ctx,\n duration,\n });\n }\n return finalResponse;\n }\n\n return response;\n } catch (error) {\n const duration = Date.now() - startTime;\n\n // Run error interceptors\n if (!init.skipInterceptors) {\n for (const interceptor of errorInterceptors) {\n try {\n const recoveredResponse = await interceptor({\n error,\n request: ctx,\n duration,\n retryCount,\n });\n // If interceptor returns a response, use it\n return recoveredResponse;\n } catch {\n // Interceptor didn't handle the error, continue to next\n }\n }\n }\n\n // No interceptor handled the error, rethrow\n throw error;\n }\n }\n\n // Handle retry logic\n const retryConfig = init.retry ?? config.defaultRetry;\n if (retryConfig) {\n const finalConfig = typeof retryConfig === 'boolean' ? {} : retryConfig;\n return withRetry(executeRequest, {\n ...finalConfig,\n onRetry: (error, attempt, delay) => {\n retryCount = attempt;\n finalConfig.onRetry?.(error, attempt, delay);\n },\n });\n }\n\n return executeRequest();\n }\n\n return {\n fetch: clientFetch,\n\n addRequestInterceptor(interceptor) {\n requestInterceptors.push(interceptor);\n return () => {\n const index = requestInterceptors.indexOf(interceptor);\n if (index !== -1) {\n requestInterceptors.splice(index, 1);\n }\n };\n },\n\n addResponseInterceptor(interceptor) {\n responseInterceptors.push(interceptor);\n return () => {\n const index = responseInterceptors.indexOf(interceptor);\n if (index !== -1) {\n responseInterceptors.splice(index, 1);\n }\n };\n },\n\n addErrorInterceptor(interceptor) {\n errorInterceptors.push(interceptor);\n return () => {\n const index = errorInterceptors.indexOf(interceptor);\n if (index !== -1) {\n errorInterceptors.splice(index, 1);\n }\n };\n },\n\n clearInterceptors() {\n requestInterceptors.length = 0;\n responseInterceptors.length = 0;\n errorInterceptors.length = 0;\n },\n\n getConfig() {\n return { ...config };\n },\n };\n}\n\n// =============================================================================\n// TOKEN REFRESH INTERCEPTOR\n// =============================================================================\n\n/**\n * Create a token refresh interceptor that automatically refreshes\n * expired tokens and retries failed requests.\n *\n * Uses AsyncLock to prevent multiple simultaneous refresh attempts.\n *\n * @example\n * ```tsx\n * const api = createFetchClient({ baseUrl: '/api' });\n *\n * const { addToClient } = createTokenRefreshInterceptor({\n * isTokenExpired: (response) => response.status === 401,\n * refreshToken: async () => {\n * const response = await fetch('/auth/refresh', { method: 'POST' });\n * const data = await response.json();\n * localStorage.setItem('token', data.accessToken);\n * return data.accessToken;\n * },\n * getAccessToken: () => localStorage.getItem('token'),\n * onRefreshFailure: () => {\n * localStorage.removeItem('token');\n * window.location.href = '/login';\n * },\n * });\n *\n * addToClient(api);\n * ```\n */\nexport function createTokenRefreshInterceptor(config: TokenRefreshConfig): {\n addToClient: (client: FetchClient) => void;\n refreshLock: AsyncLock;\n} {\n const refreshLock = createAsyncLock({ timeout: 30000 });\n let isRefreshing = false;\n let refreshAttempts = 0;\n const maxAttempts = config.maxRefreshAttempts ?? 3;\n\n const requestInterceptor: RequestInterceptor = async (ctx) => {\n // Add auth header if we have a token\n const token = config.getAccessToken();\n if (token) {\n ctx.init.headers = {\n ...(ctx.init.headers as Record<string, string>),\n Authorization: `Bearer ${token}`,\n };\n }\n return ctx;\n };\n\n const responseInterceptor: ResponseInterceptor = async (ctx) => {\n // Check if token is expired\n if (!config.isTokenExpired(ctx.response)) {\n // Reset refresh attempts on successful request\n refreshAttempts = 0;\n return ctx.response;\n }\n\n // Token expired, try to refresh\n if (refreshAttempts >= maxAttempts) {\n config.onRefreshFailure?.();\n throw new Error('Token refresh failed after maximum attempts');\n }\n\n // Use lock to prevent multiple simultaneous refresh attempts\n const lockResult = await refreshLock.acquire('token-refresh', async () => {\n // Double-check if another request already refreshed\n if (isRefreshing) {\n // Wait for the ongoing refresh to complete\n return config.getAccessToken();\n }\n\n isRefreshing = true;\n refreshAttempts++;\n\n try {\n const token = await config.refreshToken();\n if (!token) {\n config.onRefreshFailure?.();\n throw new Error('Token refresh returned null');\n }\n return token;\n } finally {\n isRefreshing = false;\n }\n });\n\n const newToken = lockResult.value;\n\n // Retry the original request with new token\n if (newToken) {\n const retryInit: RequestInit = {\n ...ctx.request.init,\n headers: {\n ...(ctx.request.init.headers as Record<string, string>),\n Authorization: `Bearer ${newToken}`,\n },\n };\n return fetch(ctx.request.url, retryInit);\n }\n\n return ctx.response;\n };\n\n return {\n addToClient(client) {\n client.addRequestInterceptor(requestInterceptor);\n client.addResponseInterceptor(responseInterceptor);\n },\n refreshLock,\n };\n}\n\n// =============================================================================\n// HELPER FUNCTIONS\n// =============================================================================\n\n/**\n * Create a simple JSON API client.\n *\n * @example\n * ```tsx\n * const api = createJsonApiClient({\n * baseUrl: 'https://api.example.com',\n * getAuthToken: () => localStorage.getItem('token'),\n * });\n *\n * // GET request\n * const users = await api.get<User[]>('/users');\n *\n * // POST request\n * const newUser = await api.post<User>('/users', { name: 'John' });\n *\n * // DELETE request\n * await api.delete('/users/1');\n * ```\n */\nexport function createJsonApiClient(options: {\n baseUrl?: string;\n getAuthToken?: () => string | null;\n defaultHeaders?: Record<string, string>;\n timeout?: number;\n}) {\n const client = createFetchClient({\n baseUrl: options.baseUrl,\n defaultHeaders: {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n ...options.defaultHeaders,\n },\n defaultTimeout: options.timeout,\n credentials: 'include',\n });\n\n if (options.getAuthToken) {\n client.addRequestInterceptor(async (ctx) => {\n const token = options.getAuthToken!();\n if (token) {\n ctx.init.headers = {\n ...(ctx.init.headers as Record<string, string>),\n Authorization: `Bearer ${token}`,\n };\n }\n return ctx;\n });\n }\n\n async function request<T>(method: string, path: string, body?: unknown): Promise<T | null> {\n const response = await client.fetch(path, {\n method,\n body: body ? JSON.stringify(body) : undefined,\n });\n\n if (!response.ok) {\n const errorContext = extractErrorContext(response);\n const error = new Error(errorContext.message || `HTTP ${response.status}`);\n Object.assign(error, { response, context: errorContext });\n throw error;\n }\n\n // Handle empty responses (204 No Content, non-JSON responses)\n const contentType = response.headers.get('content-type');\n if (!contentType || !contentType.includes('application/json')) {\n return null;\n }\n\n const text = await response.text();\n if (!text) {\n return null;\n }\n\n return JSON.parse(text) as T;\n }\n\n return {\n client,\n get: <T>(path: string) => request<T>('GET', path),\n post: <T>(path: string, body?: unknown) => request<T>('POST', path, body),\n put: <T>(path: string, body?: unknown) => request<T>('PUT', path, body),\n patch: <T>(path: string, body?: unknown) => request<T>('PATCH', path, body),\n delete: <T>(path: string) => request<T>('DELETE', path),\n };\n}\n","/**\n * JWT Utilities\n *\n * Client-side JWT decoding and validation utilities.\n * These utilities do NOT verify signatures - they only decode and check expiration.\n * For signature verification, use server-side libraries.\n *\n * @module utils\n */\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * Standard JWT claims.\n * @see https://datatracker.ietf.org/doc/html/rfc7519#section-4.1\n */\nexport interface JwtStandardClaims {\n /** Issuer */\n iss?: string;\n /** Subject */\n sub?: string;\n /** Audience */\n aud?: string | string[];\n /** Expiration time (Unix timestamp in seconds) */\n exp?: number;\n /** Not before (Unix timestamp in seconds) */\n nbf?: number;\n /** Issued at (Unix timestamp in seconds) */\n iat?: number;\n /** JWT ID */\n jti?: string;\n}\n\n/**\n * JWT payload with custom claims.\n * Extends standard claims with any additional properties.\n */\nexport interface JwtPayload extends JwtStandardClaims {\n /** User ID (common custom claim) */\n userId?: string;\n /** Email (common custom claim) */\n email?: string;\n /** Roles (common custom claim) */\n roles?: string[];\n /** Permissions (common custom claim) */\n permissions?: string[];\n /** Any additional custom claims */\n [key: string]: unknown;\n}\n\n/**\n * JWT validation options.\n */\nexport interface JwtValidationOptions {\n /** Clock skew tolerance in seconds (default: 60) */\n clockTolerance?: number;\n /** Require expiration claim (default: true) */\n requireExp?: boolean;\n}\n\n/**\n * JWT decode result.\n */\nexport interface JwtDecodeResult<T extends JwtPayload = JwtPayload> {\n /** Decoded header */\n header: {\n alg: string;\n typ?: string;\n [key: string]: unknown;\n };\n /** Decoded payload */\n payload: T;\n /** Original signature (base64url encoded, NOT verified) */\n signature: string;\n}\n\n// =============================================================================\n// DECODE FUNCTIONS\n// =============================================================================\n\n/**\n * Decode a base64url string to a regular string.\n * Handles URL-safe base64 encoding used in JWTs.\n */\nfunction base64UrlDecode(str: string): string {\n // Replace URL-safe characters with standard base64\n const base64 = str.replace(/-/g, '+').replace(/_/g, '/');\n\n // Add padding if necessary\n const padding = base64.length % 4;\n const paddedBase64 = padding ? base64 + '='.repeat(4 - padding) : base64;\n\n // Decode\n try {\n return atob(paddedBase64);\n } catch {\n throw new Error('Invalid base64url encoding');\n }\n}\n\n/**\n * Decode a JWT token without verifying the signature.\n *\n * ⚠️ WARNING: This function does NOT verify the signature.\n * Only use for client-side display purposes. Never trust decoded\n * data for authorization decisions without server-side verification.\n *\n * @param token - The JWT token string\n * @returns Decoded JWT parts (header, payload, signature)\n * @throws Error if the token is malformed\n *\n * @example\n * ```tsx\n * const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...';\n *\n * try {\n * const { header, payload } = jwtDecode(token);\n * console.log('Algorithm:', header.alg);\n * console.log('User ID:', payload.sub);\n * console.log('Expires:', new Date(payload.exp! * 1000));\n * } catch (error) {\n * console.error('Invalid token:', error.message);\n * }\n * ```\n */\nexport function jwtDecode<T extends JwtPayload = JwtPayload>(token: string): JwtDecodeResult<T> {\n if (!token || typeof token !== 'string') {\n throw new Error('Token must be a non-empty string');\n }\n\n const parts = token.split('.');\n\n if (parts.length !== 3) {\n throw new Error('Invalid token format: expected 3 parts separated by dots');\n }\n\n const [headerPart, payloadPart, signaturePart] = parts;\n\n try {\n const headerJson = base64UrlDecode(headerPart);\n const payloadJson = base64UrlDecode(payloadPart);\n\n const header = JSON.parse(headerJson);\n const payload = JSON.parse(payloadJson) as T;\n\n return {\n header,\n payload,\n signature: signaturePart,\n };\n } catch (error) {\n if (error instanceof SyntaxError) {\n throw new Error('Invalid token: malformed JSON in header or payload', { cause: error });\n }\n throw error;\n }\n}\n\n/**\n * Decode only the payload from a JWT token.\n * Convenience function when you only need the claims.\n *\n * @param token - The JWT token string\n * @returns Decoded payload\n * @throws Error if the token is malformed\n *\n * @example\n * ```tsx\n * const payload = jwtDecodePayload(token);\n * console.log('User:', payload.email);\n * ```\n */\nexport function jwtDecodePayload<T extends JwtPayload = JwtPayload>(token: string): T {\n return jwtDecode<T>(token).payload;\n}\n\n// =============================================================================\n// VALIDATION FUNCTIONS\n// =============================================================================\n\n/**\n * Check if a JWT token is expired.\n *\n * @param token - The JWT token string\n * @param options - Validation options\n * @returns true if the token is expired or invalid, false if still valid\n *\n * @example\n * ```tsx\n * if (isTokenExpired(token)) {\n * // Redirect to login or refresh token\n * refreshAccessToken();\n * }\n * ```\n */\nexport function isTokenExpired(token: string, options: JwtValidationOptions = {}): boolean {\n const { clockTolerance = 60, requireExp = true } = options;\n\n try {\n const { payload } = jwtDecode(token);\n\n // Check if exp claim exists\n if (payload.exp === undefined) {\n // If exp is not required, token is considered valid\n return requireExp;\n }\n\n // Check expiration with clock tolerance\n const currentTime = Math.floor(Date.now() / 1000);\n return payload.exp < currentTime - clockTolerance;\n } catch {\n // If token can't be decoded, consider it expired/invalid\n return true;\n }\n}\n\n/**\n * Check if a JWT token is valid (not expired, not before nbf).\n *\n * @param token - The JWT token string\n * @param options - Validation options\n * @returns true if the token is valid, false otherwise\n *\n * @example\n * ```tsx\n * function AuthProvider({ children }) {\n * const [token] = useLocalStorage('accessToken');\n *\n * if (!token || !isValidToken(token)) {\n * return <Navigate to=\"/login\" />;\n * }\n *\n * return children;\n * }\n * ```\n */\nexport function isValidToken(token: string, options: JwtValidationOptions = {}): boolean {\n const { clockTolerance = 60, requireExp = true } = options;\n\n try {\n const { payload } = jwtDecode(token);\n\n const currentTime = Math.floor(Date.now() / 1000);\n\n // Check expiration\n if (payload.exp !== undefined) {\n if (payload.exp < currentTime - clockTolerance) {\n return false;\n }\n } else if (requireExp) {\n // exp is required but missing\n return false;\n }\n\n // Check not-before\n if (payload.nbf !== undefined) {\n if (payload.nbf > currentTime + clockTolerance) {\n return false;\n }\n }\n\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Get time until token expires in seconds.\n * Returns 0 if token is already expired or invalid.\n *\n * @param token - The JWT token string\n * @returns Seconds until expiration, or 0 if expired/invalid\n *\n * @example\n * ```tsx\n * const secondsLeft = getTokenTimeLeft(token);\n *\n * if (secondsLeft < 300) {\n * // Less than 5 minutes left, refresh proactively\n * refreshToken();\n * }\n * ```\n */\nexport function getTokenTimeLeft(token: string): number {\n try {\n const { payload } = jwtDecode(token);\n\n if (payload.exp === undefined) {\n return Infinity;\n }\n\n const currentTime = Math.floor(Date.now() / 1000);\n const timeLeft = payload.exp - currentTime;\n\n return timeLeft > 0 ? timeLeft : 0;\n } catch {\n return 0;\n }\n}\n\n/**\n * Get expiration date from token.\n *\n * @param token - The JWT token string\n * @returns Date object for expiration, or null if no exp claim or invalid token\n *\n * @example\n * ```tsx\n * const expiresAt = getTokenExpirationDate(token);\n * if (expiresAt) {\n * console.log('Token expires:', expiresAt.toLocaleString());\n * }\n * ```\n */\nexport function getTokenExpirationDate(token: string): Date | null {\n try {\n const { payload } = jwtDecode(token);\n\n if (payload.exp === undefined) {\n return null;\n }\n\n return new Date(payload.exp * 1000);\n } catch {\n return null;\n }\n}\n\n// =============================================================================\n// CLAIM EXTRACTION HELPERS\n// =============================================================================\n\n/**\n * Safely get a claim from a token.\n *\n * @param token - The JWT token string\n * @param claim - The claim name to extract\n * @returns The claim value or undefined if not present/invalid\n *\n * @example\n * ```tsx\n * const userId = getTokenClaim(token, 'sub');\n * const roles = getTokenClaim<string[]>(token, 'roles') ?? [];\n * ```\n */\nexport function getTokenClaim<T>(token: string, claim: string): T | undefined {\n try {\n const { payload } = jwtDecode(token);\n return payload[claim] as T;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Get the subject (user identifier) from a token.\n *\n * @param token - The JWT token string\n * @returns The subject claim or undefined\n */\nexport function getTokenSubject(token: string): string | undefined {\n return getTokenClaim<string>(token, 'sub');\n}\n\n/**\n * Check if token has a specific role.\n *\n * @param token - The JWT token string\n * @param role - The role to check for\n * @param rolesKey - The key in the payload containing roles (default: 'roles')\n * @returns true if the token contains the role\n *\n * @example\n * ```tsx\n * if (tokenHasRole(token, 'admin')) {\n * // Show admin features\n * }\n * ```\n */\nexport function tokenHasRole(token: string, role: string, rolesKey = 'roles'): boolean {\n const roles = getTokenClaim<string[]>(token, rolesKey);\n return Array.isArray(roles) && roles.includes(role);\n}\n\n/**\n * Check if token has a specific permission.\n *\n * @param token - The JWT token string\n * @param permission - The permission to check for\n * @param permissionsKey - The key in the payload containing permissions (default: 'permissions')\n * @returns true if the token contains the permission\n */\nexport function tokenHasPermission(token: string, permission: string, permissionsKey = 'permissions'): boolean {\n const permissions = getTokenClaim<string[]>(token, permissionsKey);\n return Array.isArray(permissions) && permissions.includes(permission);\n}\n","/**\n * Template variable resolver.\n *\n * Replaces `{{namespace.key}}` patterns in text with values from a context map.\n * Used for injecting dynamic config values into help content at render time.\n *\n * @example\n * resolveTemplateVariables(\"Fee: {{config.sellerFee}}%\", { \"config.sellerFee\": \"5\" })\n * // => \"Fee: 5%\"\n */\nexport function resolveTemplateVariables(text: string, context: Record<string, string | number>): string {\n return text.replace(/\\{\\{([a-zA-Z0-9_.]+)\\}\\}/g, (match, key: string) => {\n const value = context[key];\n return value !== undefined ? String(value) : match;\n });\n}\n","/**\n * i18n-text — generic locale resolution for bilingual / multilingual\n * JSONB payloads stored on backend DTOs.\n *\n * Design goals:\n *\n * - Zero hard-coded locale strings. Caller passes the viewer locale\n * and (optionally) a fallback order; the helper does the rest.\n * Adding a new locale to the platform is just config, not a code\n * edit in every consumer.\n * - Locale-agnostic API so it can serve marketplace categories,\n * achievement titles, payments coin names, future post translations\n * — anywhere a `{ [lang]: string }` bag is stored.\n * - O(1) in the happy path (direct map access) with a deterministic\n * fallback walk.\n *\n * @module utils/i18n-text\n */\n\n/** A bag of language-keyed strings. Keys are RFC 5646 language codes\n * (or just `'en'`, `'ru'` for simple two-locale platforms). */\nexport type I18nText = Record<string, string | undefined>;\n\n/** Object shape that carries both a localised bag and a legacy\n * scalar field as final fallback — the canonical wire format for\n * categories, achievements etc. */\nexport interface I18nResolvable {\n /** Bilingual / multilingual bag. */\n nameI18n?: I18nText | null;\n /** Last-resort legacy fallback. The backend keeps this populated\n * even after migrating to JSONB so single-locale consumers keep\n * working without an immediate refactor. */\n name?: string | null;\n}\n\n/**\n * Resolve a `{ nameI18n, name }` object to the viewer-preferred\n * locale, walking through optional fallbacks before bottoming out\n * on the legacy scalar.\n *\n * @example\n * ```ts\n * const label = resolveI18n(category, 'ru', ['en']);\n * // → category.nameI18n.ru\n * // ?? category.nameI18n.en\n * // ?? category.name\n * // ?? ''\n * ```\n *\n * @param obj The resolvable record (e.g. a category DTO).\n * @param lang Viewer's preferred language code.\n * @param fallback Ordered list of secondary languages to try before\n * the legacy scalar. Defaults to `['en']`.\n * @param field Override the I18nText key (defaults to `nameI18n`)\n * + the legacy scalar key (defaults to `name`).\n * Useful for `descriptionI18n` / `description`.\n */\nexport function resolveI18n(\n obj: object | null | undefined,\n lang: string,\n fallback: readonly string[] = ['en'],\n field: { bag?: string; scalar?: string } = {},\n): string {\n if (!obj) return '';\n const bagKey = field.bag ?? 'nameI18n';\n const scalarKey = field.scalar ?? 'name';\n const record = obj as Record<string, unknown>;\n const bag = (record[bagKey] ?? null) as Record<string, unknown> | null;\n\n if (bag) {\n const direct = typeof bag[lang] === 'string' ? (bag[lang] as string).trim() : '';\n if (direct) return direct;\n for (const f of fallback) {\n const v = typeof bag[f] === 'string' ? (bag[f] as string).trim() : '';\n if (v) return v;\n }\n }\n\n const legacy = record[scalarKey];\n if (typeof legacy === 'string' && legacy.trim()) return legacy;\n\n return '';\n}\n\n/**\n * Build a stable searchable haystack from an i18n object — all\n * known translations concatenated lower-case so a single `.includes`\n * check matches against any locale.\n *\n * Useful inside `Autocomplete.filterOptions` to make EN-only users\n * find RU-only entries.\n */\nexport function i18nHaystack(\n bag: object | null | undefined,\n extra: readonly string[] = [],\n): string {\n if (!bag) return extra.join(' ').toLowerCase();\n const values = Object.values(bag as Record<string, unknown>)\n .filter((v): v is string => typeof v === 'string');\n return [...values, ...extra].join(' ').toLowerCase();\n}\n","/**\n * Toast wrapper with short-window deduplication.\n *\n * Problem: identical toast.error() calls fire twice in dev (React\n * StrictMode double-mounts every effect), and can also fire twice\n * in prod when a parent re-fetches mid-flight or a retry wrapper\n * surfaces the same error path. Sonner has no built-in dedupe, so\n * every duplicate landed as a separate snack-bar.\n *\n * Fix: collapse identical {method, message} calls inside a 1.5 s\n * window. The first call lands; subsequent identical calls within\n * the window are silently dropped. We DON'T forward to sonner's\n * own `id` option because then any later call with a different\n * message but the same id would *replace* the visible toast — we\n * want suppression, not replacement.\n *\n * Drop-in replacement for `import { toast } from 'sonner'`.\n * Same surface: error/success/info/warning + the passthroughs.\n *\n * Lives in prism so every UI app on the platform shares one\n * notification policy instead of each app reinventing it.\n */\nimport { toast as sonner } from 'sonner';\n\ntype ToastFn = (message: string, options?: Parameters<typeof sonner.error>[1]) => void;\n\nconst DEDUP_WINDOW_MS = 1500;\nconst recent = new Map<string, number>();\n\nfunction shouldSuppress(key: string): boolean {\n const now = Date.now();\n const last = recent.get(key);\n if (last !== undefined && now - last < DEDUP_WINDOW_MS) {\n recent.set(key, now);\n return true;\n }\n recent.set(key, now);\n // Sweep entries older than 4x the window to keep the map bounded.\n if (recent.size > 64) {\n const cutoff = now - DEDUP_WINDOW_MS * 4;\n for (const [k, t] of recent) if (t < cutoff) recent.delete(k);\n }\n return false;\n}\n\nfunction makeMethod(method: 'error' | 'success' | 'info' | 'warning'): ToastFn {\n return (message, options) => {\n const key = `${method}:${message}`;\n if (shouldSuppress(key)) return;\n sonner[method](message, options);\n };\n}\n\n// Use `typeof sonner` as the public type so we don't have to re-spell\n// every method signature (and so sonner's internal types — e.g.\n// `PromiseIExtendedResult` from `toast.promise` — don't have to be\n// re-exported from prism's DTS bundle).\nexport const toast: typeof sonner = Object.assign(\n // Allow `toast(msg)` (sonner's default = neutral toast) to work too.\n ((message: string, options?: Parameters<typeof sonner>[1]) => {\n const key = `default:${message}`;\n if (shouldSuppress(key)) return;\n sonner(message, options);\n }) as typeof sonner,\n {\n error: makeMethod('error'),\n success: makeMethod('success'),\n info: makeMethod('info'),\n warning: makeMethod('warning'),\n // Pass-through methods that don't need dedup\n loading: sonner.loading.bind(sonner),\n promise: sonner.promise.bind(sonner),\n dismiss: sonner.dismiss.bind(sonner),\n custom: sonner.custom.bind(sonner),\n message: sonner.message.bind(sonner),\n }\n) as typeof sonner;\n"]}
1
+ {"version":3,"sources":["../src/utils/refs.ts","../src/utils/format-number.ts","../src/utils/format-date.ts","../src/utils/string.ts","../src/utils/storage.ts","../src/utils/font.ts","../src/utils/object.ts","../src/utils/rtl.ts","../src/utils/async-lock.ts","../src/utils/errors.ts","../src/utils/fetch-interceptor.ts","../src/utils/jwt.ts","../src/utils/template-resolver.ts","../src/utils/i18n-text.ts","../src/utils/toast.ts"],"names":["buildUrl","sonner"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Ref Utilities\n *\n * Utilities for working with React refs.\n *\n * @module utils/refs\n */\n\nimport type { MutableRefObject, RefCallback, Ref } from 'react';\n\n/**\n * Supported ref types for merging.\n */\nexport type MergeableRef<T> = Ref<T> | RefCallback<T> | MutableRefObject<T> | null | undefined;\n\n/**\n * Merge multiple refs into a single callback ref.\n * Useful when you need to pass a ref to a component that also needs\n * to be used by a parent component or hook.\n *\n * @example\n * ```tsx\n * function Component({ ref, ...props }: ComponentProps) {\n * const localRef = useRef<HTMLDivElement>(null);\n * const mergedRef = mergeRefs(ref, localRef);\n * return <div ref={mergedRef} />;\n * }\n * ```\n *\n * @param refs - Array of refs to merge\n * @returns A callback ref that updates all provided refs\n */\nexport function mergeRefs<T>(...refs: MergeableRef<T>[]): RefCallback<T> {\n return (value: T | null) => {\n for (const ref of refs) {\n if (typeof ref === 'function') {\n ref(value);\n } else if (ref != null) {\n (ref as MutableRefObject<T | null>).current = value;\n }\n }\n };\n}\n\n/**\n * Create a ref setter that can be used with useImperativeHandle.\n * Useful for exposing a subset of methods from a ref.\n *\n * @example\n * ```tsx\n * function Component({ ref, ...props }: Props & { ref?: Ref<API> }) {\n * const inputRef = useRef<HTMLInputElement>(null);\n *\n * useImperativeHandle(ref, () => ({\n * focus: () => inputRef.current?.focus(),\n * clear: () => { if (inputRef.current) inputRef.current.value = ''; },\n * }), []);\n *\n * return <input ref={inputRef} />;\n * }\n * ```\n *\n * @param ref - The ref to set\n * @param value - The value to set\n */\nexport function setRef<T>(ref: MergeableRef<T>, value: T | null): void {\n if (typeof ref === 'function') {\n ref(value);\n } else if (ref != null) {\n (ref as MutableRefObject<T | null>).current = value;\n }\n}\n\n/**\n * Check if a ref has a current value.\n *\n * @param ref - The ref to check\n * @returns True if the ref has a current value\n */\nexport function hasRefValue<T>(ref: MergeableRef<T>): ref is MutableRefObject<NonNullable<T>> {\n return ref != null && typeof ref !== 'function' && ref.current != null;\n}\n","/**\n * Number Formatting Utilities\n *\n * Locale-aware number formatting utilities.\n *\n * @module utils/format-number\n */\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport interface FormatNumberOptions extends Intl.NumberFormatOptions {\n /** Locale for formatting (default: 'en-US') */\n locale?: string;\n}\n\nexport interface FormatCurrencyOptions extends FormatNumberOptions {\n /** Currency code (default: 'USD') */\n currency?: string;\n}\n\n// =============================================================================\n// NUMBER FORMATTING\n// =============================================================================\n\n/**\n * Format a number with locale-aware formatting.\n *\n * @example\n * ```ts\n * fNumber(1234567.89)\n * // => \"1,234,567.89\"\n *\n * fNumber(1234567.89, { locale: 'de-DE' })\n * // => \"1.234.567,89\"\n *\n * fNumber(0.1234, { style: 'percent' })\n * // => \"12%\"\n * ```\n */\nexport function fNumber(value: number | string | null | undefined, options: FormatNumberOptions = {}): string {\n const { locale = 'en-US', ...formatOptions } = options;\n\n if (value === null || value === undefined || value === '') {\n return '';\n }\n\n const num = typeof value === 'string' ? parseFloat(value) : value;\n\n if (Number.isNaN(num)) {\n return '';\n }\n\n return new Intl.NumberFormat(locale, formatOptions).format(num);\n}\n\n/**\n * Format a number as currency.\n *\n * @example\n * ```ts\n * fCurrency(1234.56)\n * // => \"$1,234.56\"\n *\n * fCurrency(1234.56, { currency: 'EUR', locale: 'de-DE' })\n * // => \"1.234,56 €\"\n *\n * fCurrency(1234.56, { currency: 'JPY' })\n * // => \"¥1,235\" (JPY has no decimal places)\n * ```\n */\nexport function fCurrency(value: number | string | null | undefined, options: FormatCurrencyOptions = {}): string {\n const { currency = 'USD', locale = 'en-US', ...formatOptions } = options;\n\n if (value === null || value === undefined || value === '') {\n return '';\n }\n\n const num = typeof value === 'string' ? parseFloat(value) : value;\n\n if (Number.isNaN(num)) {\n return '';\n }\n\n return new Intl.NumberFormat(locale, {\n style: 'currency',\n currency,\n ...formatOptions,\n }).format(num);\n}\n\n/**\n * Format a number as a percentage.\n *\n * @example\n * ```ts\n * fPercent(0.1234)\n * // => \"12.34%\"\n *\n * fPercent(0.1234, { maximumFractionDigits: 0 })\n * // => \"12%\"\n *\n * fPercent(1.5)\n * // => \"150%\"\n * ```\n */\nexport function fPercent(value: number | string | null | undefined, options: FormatNumberOptions = {}): string {\n const { locale = 'en-US', ...formatOptions } = options;\n\n if (value === null || value === undefined || value === '') {\n return '';\n }\n\n const num = typeof value === 'string' ? parseFloat(value) : value;\n\n if (Number.isNaN(num)) {\n return '';\n }\n\n return new Intl.NumberFormat(locale, {\n style: 'percent',\n minimumFractionDigits: 0,\n maximumFractionDigits: 2,\n ...formatOptions,\n }).format(num);\n}\n\n/**\n * Shorten a large number with K, M, B suffixes.\n *\n * @example\n * ```ts\n * fShortenNumber(1234)\n * // => \"1.23K\"\n *\n * fShortenNumber(1234567)\n * // => \"1.23M\"\n *\n * fShortenNumber(1234567890)\n * // => \"1.23B\"\n *\n * fShortenNumber(1234567890000)\n * // => \"1.23T\"\n * ```\n */\nexport function fShortenNumber(value: number | string | null | undefined, decimals: number = 2): string {\n if (value === null || value === undefined || value === '') {\n return '';\n }\n\n const num = typeof value === 'string' ? parseFloat(value) : value;\n\n if (Number.isNaN(num)) {\n return '';\n }\n\n const absNum = Math.abs(num);\n\n if (absNum >= 1e12) {\n return `${(num / 1e12).toFixed(decimals)}T`;\n }\n if (absNum >= 1e9) {\n return `${(num / 1e9).toFixed(decimals)}B`;\n }\n if (absNum >= 1e6) {\n return `${(num / 1e6).toFixed(decimals)}M`;\n }\n if (absNum >= 1e3) {\n return `${(num / 1e3).toFixed(decimals)}K`;\n }\n\n return num.toFixed(decimals);\n}\n\n/**\n * Format bytes to human-readable size.\n *\n * @example\n * ```ts\n * fBytes(1024)\n * // => \"1 KB\"\n *\n * fBytes(1048576)\n * // => \"1 MB\"\n *\n * fBytes(1073741824)\n * // => \"1 GB\"\n * ```\n */\nexport function fBytes(bytes: number | string | null | undefined, decimals: number = 2): string {\n if (bytes === null || bytes === undefined || bytes === '') {\n return '';\n }\n\n const num = typeof bytes === 'string' ? parseFloat(bytes) : bytes;\n\n if (Number.isNaN(num) || num === 0) {\n return '0 Bytes';\n }\n\n const k = 1024;\n const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB'];\n const i = Math.floor(Math.log(Math.abs(num)) / Math.log(k));\n\n return `${(num / Math.pow(k, i)).toFixed(decimals)} ${sizes[i]}`;\n}\n\n/**\n * Format number with ordinal suffix (1st, 2nd, 3rd, etc.)\n *\n * @example\n * ```ts\n * fOrdinal(1)\n * // => \"1st\"\n *\n * fOrdinal(22)\n * // => \"22nd\"\n *\n * fOrdinal(33)\n * // => \"33rd\"\n *\n * fOrdinal(44)\n * // => \"44th\"\n * ```\n */\nexport function fOrdinal(value: number | null | undefined): string {\n if (value === null || value === undefined) {\n return '';\n }\n\n const num = Math.abs(Math.floor(value));\n const suffixes = ['th', 'st', 'nd', 'rd'];\n const remainder = num % 100;\n\n const suffix = suffixes[(remainder - 20) % 10] || suffixes[remainder] || suffixes[0];\n\n return `${value}${suffix}`;\n}\n\n/**\n * Format a number with decimal places.\n *\n * @example\n * ```ts\n * fDecimal(1234.5678)\n * // => \"1234.57\"\n *\n * fDecimal(1234.5678, 4)\n * // => \"1234.5678\"\n *\n * fDecimal(1234)\n * // => \"1234.00\"\n * ```\n */\nexport function fDecimal(value: number | string | null | undefined, decimals: number = 2): string {\n if (value === null || value === undefined || value === '') {\n return '';\n }\n\n const num = typeof value === 'string' ? parseFloat(value) : value;\n\n if (Number.isNaN(num)) {\n return '';\n }\n\n return num.toFixed(decimals);\n}\n\n// =============================================================================\n// PERCENTAGE CALCULATIONS (Aurora pattern)\n// =============================================================================\n\n/**\n * Calculate percentage of a value relative to a total.\n *\n * @param value - The part value\n * @param total - The total value\n * @param decimals - Decimal places (default: 0)\n * @returns Percentage number (0-100)\n *\n * @example\n * ```ts\n * getPercentage(25, 100)\n * // => 25\n *\n * getPercentage(1, 3)\n * // => 33\n *\n * getPercentage(1, 3, 2)\n * // => 33.33\n *\n * getPercentage(50, 200)\n * // => 25\n * ```\n */\nexport function getPercentage(value: number, total: number, decimals: number = 0): number {\n if (total === 0) return 0;\n const percentage = (value / total) * 100;\n return Number(percentage.toFixed(decimals));\n}\n\n/**\n * Calculate percentage change between two values.\n *\n * @param current - Current value\n * @param previous - Previous value\n * @param decimals - Decimal places (default: 0)\n * @returns Percentage change (positive = increase, negative = decrease)\n *\n * @example\n * ```ts\n * calculatePercentageChange(150, 100)\n * // => 50 (50% increase)\n *\n * calculatePercentageChange(50, 100)\n * // => -50 (50% decrease)\n *\n * calculatePercentageChange(100, 100)\n * // => 0 (no change)\n *\n * calculatePercentageChange(120, 100, 1)\n * // => 20.0\n * ```\n */\nexport function calculatePercentageChange(current: number, previous: number, decimals: number = 0): number {\n if (previous === 0) return current === 0 ? 0 : 100;\n const change = ((current - previous) / Math.abs(previous)) * 100;\n return Number(change.toFixed(decimals));\n}\n\n/**\n * Get currency symbol for a currency code.\n *\n * @param currencyCode - ISO 4217 currency code (e.g., 'USD', 'EUR')\n * @param locale - Locale for formatting (default: 'en-US')\n * @returns Currency symbol (e.g., '$', '€', '¥')\n *\n * @example\n * ```ts\n * getCurrencySymbol('USD')\n * // => \"$\"\n *\n * getCurrencySymbol('EUR')\n * // => \"€\"\n *\n * getCurrencySymbol('JPY')\n * // => \"¥\"\n *\n * getCurrencySymbol('GBP')\n * // => \"£\"\n * ```\n */\nexport function getCurrencySymbol(currencyCode: string, locale: string = 'en-US'): string {\n const parts = new Intl.NumberFormat(locale, {\n style: 'currency',\n currency: currencyCode,\n })\n .formatToParts(0)\n .find((part) => part.type === 'currency');\n\n return parts?.value ?? currencyCode;\n}\n\n/**\n * Format a number with +/- sign prefix.\n *\n * @param value - Number to format\n * @param options - Formatting options\n * @returns Formatted string with sign\n *\n * @example\n * ```ts\n * fNumberWithSign(25)\n * // => \"+25\"\n *\n * fNumberWithSign(-25)\n * // => \"-25\"\n *\n * fNumberWithSign(0)\n * // => \"0\"\n *\n * fNumberWithSign(25.5, { maximumFractionDigits: 1 })\n * // => \"+25.5\"\n * ```\n */\nexport function fNumberWithSign(value: number | string | null | undefined, options: FormatNumberOptions = {}): string {\n if (value === null || value === undefined || value === '') {\n return '';\n }\n\n const num = typeof value === 'string' ? parseFloat(value) : value;\n\n if (Number.isNaN(num)) {\n return '';\n }\n\n const formatted = fNumber(Math.abs(num), options);\n if (num > 0) return `+${formatted}`;\n if (num < 0) return `-${formatted}`;\n return formatted;\n}\n\n/**\n * Format a number as compact notation (1K, 1M, 1B).\n * Uses Intl.NumberFormat with compact notation.\n *\n * @example\n * ```ts\n * fCompact(1234)\n * // => \"1.2K\"\n *\n * fCompact(1234567)\n * // => \"1.2M\"\n *\n * fCompact(1234567890)\n * // => \"1.2B\"\n * ```\n */\nexport function fCompact(value: number | string | null | undefined, options: FormatNumberOptions = {}): string {\n const { locale = 'en-US', ...formatOptions } = options;\n\n if (value === null || value === undefined || value === '') {\n return '';\n }\n\n const num = typeof value === 'string' ? parseFloat(value) : value;\n\n if (Number.isNaN(num)) {\n return '';\n }\n\n return new Intl.NumberFormat(locale, {\n notation: 'compact',\n compactDisplay: 'short',\n maximumFractionDigits: 1,\n ...formatOptions,\n }).format(num);\n}\n","/**\n * Date Formatting Utilities\n *\n * Locale-aware date formatting utilities using Intl.DateTimeFormat.\n * For more complex formatting, consider using dayjs or date-fns.\n *\n * @module utils/format-date\n */\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport type DateInput = Date | string | number | null | undefined;\n\nexport interface FormatDateOptions extends Intl.DateTimeFormatOptions {\n /** Locale for formatting (default: 'en-US') */\n locale?: string;\n}\n\n// =============================================================================\n// HELPERS\n// =============================================================================\n\n/**\n * Parse various date inputs into a Date object.\n */\nfunction parseDate(input: DateInput): Date | null {\n if (input === null || input === undefined) {\n return null;\n }\n\n if (input instanceof Date) {\n return input;\n }\n\n const date = new Date(input);\n return Number.isNaN(date.getTime()) ? null : date;\n}\n\n// =============================================================================\n// DATE FORMATTING\n// =============================================================================\n\n/**\n * Format a date with locale-aware formatting.\n *\n * @example\n * ```ts\n * fDate(new Date())\n * // => \"Jan 15, 2025\"\n *\n * fDate(new Date(), { locale: 'ru-RU' })\n * // => \"15 янв. 2025 г.\"\n *\n * fDate('2025-01-15')\n * // => \"Jan 15, 2025\"\n * ```\n */\nexport function fDate(date: DateInput, options: FormatDateOptions = {}): string {\n const { locale = 'en-US', ...formatOptions } = options;\n\n const parsed = parseDate(date);\n if (!parsed) return '';\n\n return new Intl.DateTimeFormat(locale, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n ...formatOptions,\n }).format(parsed);\n}\n\n/**\n * Format a date with time.\n *\n * @example\n * ```ts\n * fDateTime(new Date())\n * // => \"Jan 15, 2025, 2:30 PM\"\n *\n * fDateTime(new Date(), { hour12: false })\n * // => \"Jan 15, 2025, 14:30\"\n * ```\n */\nexport function fDateTime(date: DateInput, options: FormatDateOptions = {}): string {\n const { locale = 'en-US', ...formatOptions } = options;\n\n const parsed = parseDate(date);\n if (!parsed) return '';\n\n return new Intl.DateTimeFormat(locale, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: 'numeric',\n minute: 'numeric',\n ...formatOptions,\n }).format(parsed);\n}\n\n/**\n * Format time only.\n *\n * @example\n * ```ts\n * fTime(new Date())\n * // => \"2:30 PM\"\n *\n * fTime(new Date(), { hour12: false })\n * // => \"14:30\"\n *\n * fTime(new Date(), { second: 'numeric' })\n * // => \"2:30:45 PM\"\n * ```\n */\nexport function fTime(date: DateInput, options: FormatDateOptions = {}): string {\n const { locale = 'en-US', ...formatOptions } = options;\n\n const parsed = parseDate(date);\n if (!parsed) return '';\n\n return new Intl.DateTimeFormat(locale, {\n hour: 'numeric',\n minute: 'numeric',\n ...formatOptions,\n }).format(parsed);\n}\n\n/**\n * Format a date as ISO string (YYYY-MM-DD).\n *\n * @example\n * ```ts\n * fDateISO(new Date())\n * // => \"2025-01-15\"\n * ```\n */\nexport function fDateISO(date: DateInput): string {\n const parsed = parseDate(date);\n if (!parsed) return '';\n\n return parsed.toISOString().split('T')[0];\n}\n\n/**\n * Format a timestamp as relative time (e.g., \"2 hours ago\").\n *\n * @example\n * ```ts\n * fRelativeTime(new Date(Date.now() - 3600000))\n * // => \"1 hour ago\"\n *\n * fRelativeTime(new Date(Date.now() + 86400000))\n * // => \"in 1 day\"\n *\n * fRelativeTime(new Date(Date.now() - 86400000 * 7))\n * // => \"1 week ago\"\n * ```\n */\nexport function fRelativeTime(date: DateInput, options: { locale?: string } = {}): string {\n const { locale = 'en-US' } = options;\n\n const parsed = parseDate(date);\n if (!parsed) return '';\n\n const now = new Date();\n const diffMs = parsed.getTime() - now.getTime();\n const diffSeconds = Math.round(diffMs / 1000);\n const diffMinutes = Math.round(diffSeconds / 60);\n const diffHours = Math.round(diffMinutes / 60);\n const diffDays = Math.round(diffHours / 24);\n const diffWeeks = Math.round(diffDays / 7);\n const diffMonths = Math.round(diffDays / 30);\n const diffYears = Math.round(diffDays / 365);\n\n const rtf = new Intl.RelativeTimeFormat(locale, { numeric: 'auto' });\n\n if (Math.abs(diffSeconds) < 60) {\n return rtf.format(diffSeconds, 'second');\n }\n if (Math.abs(diffMinutes) < 60) {\n return rtf.format(diffMinutes, 'minute');\n }\n if (Math.abs(diffHours) < 24) {\n return rtf.format(diffHours, 'hour');\n }\n if (Math.abs(diffDays) < 7) {\n return rtf.format(diffDays, 'day');\n }\n if (Math.abs(diffWeeks) < 4) {\n return rtf.format(diffWeeks, 'week');\n }\n if (Math.abs(diffMonths) < 12) {\n return rtf.format(diffMonths, 'month');\n }\n return rtf.format(diffYears, 'year');\n}\n\n/**\n * Format a duration in milliseconds to human-readable string.\n *\n * @example\n * ```ts\n * fDuration(3661000)\n * // => \"1h 1m 1s\"\n *\n * fDuration(90000)\n * // => \"1m 30s\"\n *\n * fDuration(1000)\n * // => \"1s\"\n * ```\n */\nexport function fDuration(ms: number | null | undefined): string {\n if (ms === null || ms === undefined || ms < 0) return '';\n\n const seconds = Math.floor((ms / 1000) % 60);\n const minutes = Math.floor((ms / (1000 * 60)) % 60);\n const hours = Math.floor((ms / (1000 * 60 * 60)) % 24);\n const days = Math.floor(ms / (1000 * 60 * 60 * 24));\n\n const parts: string[] = [];\n\n if (days > 0) parts.push(`${days}d`);\n if (hours > 0) parts.push(`${hours}h`);\n if (minutes > 0) parts.push(`${minutes}m`);\n if (seconds > 0 || parts.length === 0) parts.push(`${seconds}s`);\n\n return parts.join(' ');\n}\n\n/**\n * Check if a date is today.\n *\n * @example\n * ```ts\n * isToday(new Date())\n * // => true\n *\n * isToday(new Date('2020-01-01'))\n * // => false\n * ```\n */\nexport function isToday(date: DateInput): boolean {\n const parsed = parseDate(date);\n if (!parsed) return false;\n\n const today = new Date();\n return (\n parsed.getDate() === today.getDate() &&\n parsed.getMonth() === today.getMonth() &&\n parsed.getFullYear() === today.getFullYear()\n );\n}\n\n/**\n * Check if a date is yesterday.\n */\nexport function isYesterday(date: DateInput): boolean {\n const parsed = parseDate(date);\n if (!parsed) return false;\n\n const yesterday = new Date();\n yesterday.setDate(yesterday.getDate() - 1);\n\n return (\n parsed.getDate() === yesterday.getDate() &&\n parsed.getMonth() === yesterday.getMonth() &&\n parsed.getFullYear() === yesterday.getFullYear()\n );\n}\n\n/**\n * Check if a date is within the current week.\n */\nexport function isThisWeek(date: DateInput): boolean {\n const parsed = parseDate(date);\n if (!parsed) return false;\n\n const now = new Date();\n const weekStart = new Date(now);\n weekStart.setDate(now.getDate() - now.getDay());\n weekStart.setHours(0, 0, 0, 0);\n\n const weekEnd = new Date(weekStart);\n weekEnd.setDate(weekStart.getDate() + 6);\n weekEnd.setHours(23, 59, 59, 999);\n\n return parsed >= weekStart && parsed <= weekEnd;\n}\n\n/**\n * Check if a date is in the past.\n */\nexport function isPast(date: DateInput): boolean {\n const parsed = parseDate(date);\n if (!parsed) return false;\n\n return parsed.getTime() < Date.now();\n}\n\n/**\n * Check if a date is in the future.\n */\nexport function isFuture(date: DateInput): boolean {\n const parsed = parseDate(date);\n if (!parsed) return false;\n\n return parsed.getTime() > Date.now();\n}\n\n/**\n * Get the difference between two dates in days.\n */\nexport function diffInDays(date1: DateInput, date2: DateInput): number {\n const d1 = parseDate(date1);\n const d2 = parseDate(date2);\n\n if (!d1 || !d2) return 0;\n\n const diffTime = Math.abs(d2.getTime() - d1.getTime());\n return Math.ceil(diffTime / (1000 * 60 * 60 * 24));\n}\n\n// =============================================================================\n// DATE RANGE UTILITIES (Aurora pattern)\n// =============================================================================\n\n/** One day in milliseconds */\nconst DAY_MS = 1000 * 60 * 60 * 24;\n\n/**\n * Generate an array of dates between start and end.\n *\n * @param startDate - Start date\n * @param endDate - End date\n * @param interval - Interval in milliseconds (default: 1 day)\n * @returns Array of Date objects\n *\n * @example\n * ```ts\n * const dates = getDates(\n * new Date('2025-01-01'),\n * new Date('2025-01-07')\n * );\n * // => [Date(Jan 1), Date(Jan 2), ..., Date(Jan 7)]\n *\n * // With custom interval (every 2 days)\n * const dates = getDates(\n * new Date('2025-01-01'),\n * new Date('2025-01-07'),\n * DAY_MS * 2\n * );\n * // => [Date(Jan 1), Date(Jan 3), Date(Jan 5), Date(Jan 7)]\n * ```\n */\nexport function getDates(startDate: DateInput, endDate: DateInput, interval: number = DAY_MS): Date[] {\n const start = parseDate(startDate);\n const end = parseDate(endDate);\n\n if (!start || !end) return [];\n\n const duration = +end - +start;\n const steps = Math.floor(duration / interval);\n\n return Array.from({ length: steps + 1 }, (_, i) => new Date(start.valueOf() + interval * i));\n}\n\n/**\n * Duration preset for getPastDates.\n */\nexport type DateDurationPreset = 'week' | 'month' | 'quarter' | 'year';\n\n/**\n * Get an array of dates for past duration.\n *\n * @param duration - Duration preset or number of days\n * @returns Array of Date objects from past to present\n *\n * @example\n * ```ts\n * // Last 7 days\n * const weekDates = getPastDates('week');\n *\n * // Last 30 days\n * const monthDates = getPastDates('month');\n *\n * // Last 90 days\n * const quarterDates = getPastDates('quarter');\n *\n * // Last 365 days\n * const yearDates = getPastDates('year');\n *\n * // Custom: last 14 days\n * const customDates = getPastDates(14);\n * ```\n */\nexport function getPastDates(duration: DateDurationPreset | number): Date[] {\n const durationMap: Record<DateDurationPreset, number> = {\n week: 7,\n month: 30,\n quarter: 90,\n year: 365,\n };\n\n const days = typeof duration === 'number' ? duration : durationMap[duration];\n const endDate = new Date();\n const startDate = new Date();\n startDate.setDate(endDate.getDate() - days);\n\n return getDates(startDate, endDate);\n}\n\n/**\n * Get an array of dates for future duration.\n *\n * @param duration - Duration preset or number of days\n * @returns Array of Date objects from present to future\n *\n * @example\n * ```ts\n * // Next 7 days\n * const weekDates = getFutureDates('week');\n *\n * // Next 30 days\n * const monthDates = getFutureDates('month');\n *\n * // Custom: next 14 days\n * const customDates = getFutureDates(14);\n * ```\n */\nexport function getFutureDates(duration: DateDurationPreset | number): Date[] {\n const durationMap: Record<DateDurationPreset, number> = {\n week: 7,\n month: 30,\n quarter: 90,\n year: 365,\n };\n\n const days = typeof duration === 'number' ? duration : durationMap[duration];\n const startDate = new Date();\n const endDate = new Date();\n endDate.setDate(startDate.getDate() + days);\n\n return getDates(startDate, endDate);\n}\n\n/**\n * Get start of day (midnight) for a date.\n *\n * @param date - Input date\n * @returns Date set to 00:00:00.000\n */\nexport function startOfDay(date: DateInput): Date | null {\n const parsed = parseDate(date);\n if (!parsed) return null;\n\n const result = new Date(parsed);\n result.setHours(0, 0, 0, 0);\n return result;\n}\n\n/**\n * Get end of day (23:59:59.999) for a date.\n *\n * @param date - Input date\n * @returns Date set to 23:59:59.999\n */\nexport function endOfDay(date: DateInput): Date | null {\n const parsed = parseDate(date);\n if (!parsed) return null;\n\n const result = new Date(parsed);\n result.setHours(23, 59, 59, 999);\n return result;\n}\n\n/**\n * Add days to a date.\n *\n * @param date - Input date\n * @param days - Number of days to add (can be negative)\n * @returns New date with days added\n */\nexport function addDays(date: DateInput, days: number): Date | null {\n const parsed = parseDate(date);\n if (!parsed) return null;\n\n const result = new Date(parsed);\n result.setDate(result.getDate() + days);\n return result;\n}\n\n/**\n * Add months to a date.\n *\n * @param date - Input date\n * @param months - Number of months to add (can be negative)\n * @returns New date with months added\n */\nexport function addMonths(date: DateInput, months: number): Date | null {\n const parsed = parseDate(date);\n if (!parsed) return null;\n\n const result = new Date(parsed);\n result.setMonth(result.getMonth() + months);\n return result;\n}\n","/**\n * String Utilities\n *\n * Common string manipulation utilities.\n *\n * @module utils/string\n */\n\n// =============================================================================\n// TEXT FORMATTING\n// =============================================================================\n\n/**\n * Truncate text with ellipsis.\n *\n * @example\n * ```ts\n * truncate('Hello, World!', 8)\n * // => \"Hello...\"\n *\n * truncate('Short', 10)\n * // => \"Short\"\n *\n * truncate('Hello, World!', 8, '…')\n * // => \"Hello, W…\"\n * ```\n */\nexport function truncate(text: string | null | undefined, length: number, suffix: string = '...'): string {\n if (!text) return '';\n if (text.length <= length) return text;\n\n return text.slice(0, length - suffix.length) + suffix;\n}\n\n/**\n * Get initials from a name.\n *\n * @example\n * ```ts\n * getInitials('John Doe')\n * // => \"JD\"\n *\n * getInitials('Alice Bob Charlie')\n * // => \"AC\"\n *\n * getInitials('SingleName')\n * // => \"SI\"\n * ```\n */\nexport function getInitials(name: string | null | undefined): string {\n if (!name) return '';\n\n const words = name.trim().split(/\\s+/);\n\n if (words.length === 1) {\n return words[0].slice(0, 2).toUpperCase();\n }\n\n return (words[0][0] + words[words.length - 1][0]).toUpperCase();\n}\n\n/**\n * Capitalize the first letter of a string.\n *\n * @example\n * ```ts\n * capitalize('hello world')\n * // => \"Hello world\"\n * ```\n */\nexport function capitalize(text: string | null | undefined): string {\n if (!text) return '';\n return text.charAt(0).toUpperCase() + text.slice(1);\n}\n\n/**\n * Capitalize the first letter of each word.\n *\n * @example\n * ```ts\n * titleCase('hello world')\n * // => \"Hello World\"\n *\n * titleCase('the quick brown fox')\n * // => \"The Quick Brown Fox\"\n * ```\n */\nexport function titleCase(text: string | null | undefined): string {\n if (!text) return '';\n return text.replace(/\\b\\w/g, (char) => char.toUpperCase());\n}\n\n/**\n * Convert string to kebab-case.\n *\n * @example\n * ```ts\n * kebabCase('Hello World')\n * // => \"hello-world\"\n *\n * kebabCase('camelCaseString')\n * // => \"camel-case-string\"\n * ```\n */\nexport function kebabCase(text: string | null | undefined): string {\n if (!text) return '';\n\n return text\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .replace(/[\\s_]+/g, '-')\n .toLowerCase();\n}\n\n/**\n * Convert string to camelCase.\n *\n * @example\n * ```ts\n * camelCase('Hello World')\n * // => \"helloWorld\"\n *\n * camelCase('kebab-case-string')\n * // => \"kebabCaseString\"\n * ```\n */\nexport function camelCase(text: string | null | undefined): string {\n if (!text) return '';\n\n return text.toLowerCase().replace(/[^a-zA-Z0-9]+(.)/g, (_, char) => char.toUpperCase());\n}\n\n/**\n * Convert string to snake_case.\n *\n * @example\n * ```ts\n * snakeCase('Hello World')\n * // => \"hello_world\"\n *\n * snakeCase('camelCaseString')\n * // => \"camel_case_string\"\n * ```\n */\nexport function snakeCase(text: string | null | undefined): string {\n if (!text) return '';\n\n return text\n .replace(/([a-z])([A-Z])/g, '$1_$2')\n .replace(/[\\s-]+/g, '_')\n .toLowerCase();\n}\n\n// =============================================================================\n// SEARCH & HIGHLIGHT\n// =============================================================================\n\n/**\n * Highlight search query in text by wrapping matches in <mark> tags.\n *\n * @example\n * ```ts\n * highlightText('Hello World', 'wor')\n * // => \"Hello <mark>Wor</mark>ld\"\n *\n * highlightText('Test Case', 'test', '<strong>', '</strong>')\n * // => \"<strong>Test</strong> Case\"\n * ```\n */\nexport function highlightText(\n text: string | null | undefined,\n query: string | null | undefined,\n openTag: string = '<mark>',\n closeTag: string = '</mark>'\n): string {\n if (!text) return '';\n if (!query) return text;\n\n const regex = new RegExp(`(${escapeRegExp(query)})`, 'gi');\n return text.replace(regex, `${openTag}$1${closeTag}`);\n}\n\n/**\n * Escape special regex characters in a string.\n *\n * @example\n * ```ts\n * escapeRegExp('test.string+with[special]chars')\n * // => \"test\\\\.string\\\\+with\\\\[special\\\\]chars\"\n * ```\n */\nexport function escapeRegExp(text: string): string {\n return text.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n/**\n * Check if a string contains a substring (case-insensitive).\n *\n * @example\n * ```ts\n * containsIgnoreCase('Hello World', 'WORLD')\n * // => true\n *\n * containsIgnoreCase('Hello World', 'foo')\n * // => false\n * ```\n */\nexport function containsIgnoreCase(text: string | null | undefined, search: string | null | undefined): boolean {\n if (!text || !search) return false;\n return text.toLowerCase().includes(search.toLowerCase());\n}\n\n// =============================================================================\n// VALIDATION\n// =============================================================================\n\n/**\n * Check if a string is empty or whitespace only.\n *\n * @example\n * ```ts\n * isBlank('')\n * // => true\n *\n * isBlank(' ')\n * // => true\n *\n * isBlank('hello')\n * // => false\n * ```\n */\nexport function isBlank(text: string | null | undefined): boolean {\n return !text || text.trim().length === 0;\n}\n\n/**\n * Check if a string is a valid email address (basic check).\n *\n * @example\n * ```ts\n * isEmail('test@example.com')\n * // => true\n *\n * isEmail('invalid')\n * // => false\n * ```\n */\nexport function isEmail(text: string | null | undefined): boolean {\n if (!text) return false;\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n return emailRegex.test(text);\n}\n\n/**\n * Check if a string is a valid URL (basic check).\n *\n * @example\n * ```ts\n * isUrl('https://example.com')\n * // => true\n *\n * isUrl('not-a-url')\n * // => false\n * ```\n */\nexport function isUrl(text: string | null | undefined): boolean {\n if (!text) return false;\n try {\n new URL(text);\n return true;\n } catch {\n return false;\n }\n}\n\n// =============================================================================\n// GENERATION\n// =============================================================================\n\n/**\n * Generate a random string of specified length.\n *\n * @example\n * ```ts\n * randomString(8)\n * // => \"a3Bx9kPq\"\n *\n * randomString(16, 'abc123')\n * // => \"a1b3c2a1b3c2a1b3\"\n * ```\n */\nexport function randomString(\n length: number = 8,\n chars: string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'\n): string {\n let result = '';\n for (let i = 0; i < length; i++) {\n result += chars.charAt(Math.floor(Math.random() * chars.length));\n }\n return result;\n}\n\n/**\n * Generate a UUID v4.\n *\n * @example\n * ```ts\n * uuid()\n * // => \"550e8400-e29b-41d4-a716-446655440000\"\n * ```\n */\nexport function uuid(): string {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {\n const r = (Math.random() * 16) | 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n}\n\n/**\n * Generate a slug from text.\n *\n * @example\n * ```ts\n * slugify('Hello World!')\n * // => \"hello-world\"\n *\n * slugify('This is a Test String')\n * // => \"this-is-a-test-string\"\n * ```\n */\nexport function slugify(text: string | null | undefined): string {\n if (!text) return '';\n\n return text\n .toString()\n .toLowerCase()\n .trim()\n .replace(/\\s+/g, '-') // Replace spaces with -\n .replace(/[^\\w-]+/g, '') // Remove non-word chars\n .replace(/--+/g, '-') // Replace multiple - with single -\n .replace(/^-+/, '') // Trim - from start\n .replace(/-+$/, ''); // Trim - from end\n}\n","/**\n * LocalStorage Utilities\n *\n * SSR-safe localStorage utilities with JSON serialization support.\n * Inspired by minimal-shared/utils/local-storage pattern.\n *\n * @module utils/storage\n */\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\nexport interface StorageOptions {\n /** Storage to use (default: localStorage) */\n storage?: Storage;\n /** Serialize function (default: JSON.stringify) */\n serialize?: (value: unknown) => string;\n /** Deserialize function (default: JSON.parse) */\n deserialize?: (value: string) => unknown;\n}\n\n// =============================================================================\n// AVAILABILITY CHECK\n// =============================================================================\n\n/**\n * Check if localStorage is available in the current environment.\n * Handles SSR, private browsing, and quota exceeded scenarios.\n *\n * @example\n * ```ts\n * if (localStorageAvailable()) {\n * localStorage.setItem('key', 'value');\n * }\n * ```\n */\nexport function localStorageAvailable(): boolean {\n try {\n if (typeof window === 'undefined') {\n return false;\n }\n\n const testKey = '__storage_test__';\n window.localStorage.setItem(testKey, testKey);\n window.localStorage.removeItem(testKey);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Check if sessionStorage is available in the current environment.\n *\n * @example\n * ```ts\n * if (sessionStorageAvailable()) {\n * sessionStorage.setItem('key', 'value');\n * }\n * ```\n */\nexport function sessionStorageAvailable(): boolean {\n try {\n if (typeof window === 'undefined') {\n return false;\n }\n\n const testKey = '__storage_test__';\n window.sessionStorage.setItem(testKey, testKey);\n window.sessionStorage.removeItem(testKey);\n return true;\n } catch {\n return false;\n }\n}\n\n// =============================================================================\n// GET STORAGE\n// =============================================================================\n\n/**\n * Get a value from localStorage with automatic JSON parsing.\n * Returns defaultValue if key doesn't exist, parsing fails, or storage is unavailable.\n *\n * @param key - Storage key\n * @param defaultValue - Value to return if key doesn't exist or parsing fails\n * @param options - Storage options\n * @returns Parsed value or defaultValue\n *\n * @example\n * ```ts\n * // Simple value\n * const count = getStorage('count', 0);\n *\n * // Object value\n * const user = getStorage<User>('user', null);\n *\n * // With sessionStorage\n * const session = getStorage('session', null, {\n * storage: sessionStorage,\n * });\n * ```\n */\nexport function getStorage<T>(key: string, defaultValue: T, options: StorageOptions = {}): T {\n const { storage = typeof window !== 'undefined' ? window.localStorage : undefined, deserialize = JSON.parse } =\n options;\n\n try {\n if (!storage) {\n return defaultValue;\n }\n\n const value = storage.getItem(key);\n\n if (value === null) {\n return defaultValue;\n }\n\n return deserialize(value) as T;\n } catch {\n return defaultValue;\n }\n}\n\n// =============================================================================\n// SET STORAGE\n// =============================================================================\n\n/**\n * Set a value in localStorage with automatic JSON serialization.\n * Silently fails if storage is unavailable.\n *\n * @param key - Storage key\n * @param value - Value to store (will be JSON serialized)\n * @param options - Storage options\n * @returns true if successful, false otherwise\n *\n * @example\n * ```ts\n * // Simple value\n * setStorage('count', 42);\n *\n * // Object value\n * setStorage('user', { id: 1, name: 'John' });\n *\n * // With sessionStorage\n * setStorage('session', sessionData, {\n * storage: sessionStorage,\n * });\n * ```\n */\nexport function setStorage<T>(key: string, value: T, options: StorageOptions = {}): boolean {\n const { storage = typeof window !== 'undefined' ? window.localStorage : undefined, serialize = JSON.stringify } =\n options;\n\n try {\n if (!storage) {\n return false;\n }\n\n storage.setItem(key, serialize(value));\n return true;\n } catch {\n // Quota exceeded or other storage error\n return false;\n }\n}\n\n// =============================================================================\n// REMOVE STORAGE\n// =============================================================================\n\n/**\n * Remove a value from localStorage.\n * Silently fails if storage is unavailable.\n *\n * @param key - Storage key to remove\n * @param options - Storage options\n * @returns true if successful, false otherwise\n *\n * @example\n * ```ts\n * removeStorage('user');\n *\n * // From sessionStorage\n * removeStorage('session', { storage: sessionStorage });\n * ```\n */\nexport function removeStorage(key: string, options: Pick<StorageOptions, 'storage'> = {}): boolean {\n const { storage = typeof window !== 'undefined' ? window.localStorage : undefined } = options;\n\n try {\n if (!storage) {\n return false;\n }\n\n storage.removeItem(key);\n return true;\n } catch {\n return false;\n }\n}\n\n// =============================================================================\n// CLEAR STORAGE\n// =============================================================================\n\n/**\n * Clear all items from localStorage.\n * Silently fails if storage is unavailable.\n *\n * @param options - Storage options\n * @returns true if successful, false otherwise\n *\n * @example\n * ```ts\n * clearStorage();\n *\n * // Clear sessionStorage\n * clearStorage({ storage: sessionStorage });\n * ```\n */\nexport function clearStorage(options: Pick<StorageOptions, 'storage'> = {}): boolean {\n const { storage = typeof window !== 'undefined' ? window.localStorage : undefined } = options;\n\n try {\n if (!storage) {\n return false;\n }\n\n storage.clear();\n return true;\n } catch {\n return false;\n }\n}\n\n// =============================================================================\n// STORAGE KEYS\n// =============================================================================\n\n/**\n * Get all keys from localStorage.\n *\n * @param options - Storage options\n * @returns Array of storage keys\n *\n * @example\n * ```ts\n * const keys = getStorageKeys();\n * // => ['user', 'settings', 'cart']\n * ```\n */\nexport function getStorageKeys(options: Pick<StorageOptions, 'storage'> = {}): string[] {\n const { storage = typeof window !== 'undefined' ? window.localStorage : undefined } = options;\n\n try {\n if (!storage) {\n return [];\n }\n\n const keys: string[] = [];\n for (let i = 0; i < storage.length; i++) {\n const key = storage.key(i);\n if (key !== null) {\n keys.push(key);\n }\n }\n return keys;\n } catch {\n return [];\n }\n}\n\n// =============================================================================\n// STORAGE SIZE\n// =============================================================================\n\n/**\n * Get approximate size of localStorage in bytes.\n *\n * @param options - Storage options\n * @returns Size in bytes\n *\n * @example\n * ```ts\n * const sizeBytes = getStorageSize();\n * console.log(`Using ${sizeBytes} bytes of localStorage`);\n * ```\n */\nexport function getStorageSize(options: Pick<StorageOptions, 'storage'> = {}): number {\n const { storage = typeof window !== 'undefined' ? window.localStorage : undefined } = options;\n\n try {\n if (!storage) {\n return 0;\n }\n\n let total = 0;\n for (let i = 0; i < storage.length; i++) {\n const key = storage.key(i);\n if (key !== null) {\n const value = storage.getItem(key) ?? '';\n // Each character is 2 bytes in JavaScript\n total += (key.length + value.length) * 2;\n }\n }\n return total;\n } catch {\n return 0;\n }\n}\n\n// =============================================================================\n// STORAGE WITH EXPIRY\n// =============================================================================\n\nexport interface StorageWithExpiryOptions extends StorageOptions {\n /** Time to live in milliseconds */\n ttl: number;\n}\n\ninterface StoredWithExpiry<T> {\n value: T;\n expiry: number;\n}\n\n/**\n * Set a value with expiration time.\n *\n * @param key - Storage key\n * @param value - Value to store\n * @param options - Options with TTL in milliseconds\n *\n * @example\n * ```ts\n * // Store for 1 hour\n * setStorageWithExpiry('session', sessionData, {\n * ttl: 60 * 60 * 1000,\n * });\n *\n * // Store for 24 hours\n * setStorageWithExpiry('cache', cacheData, {\n * ttl: 24 * 60 * 60 * 1000,\n * });\n * ```\n */\nexport function setStorageWithExpiry<T>(key: string, value: T, options: StorageWithExpiryOptions): boolean {\n const { ttl, ...storageOptions } = options;\n\n const item: StoredWithExpiry<T> = {\n value,\n expiry: Date.now() + ttl,\n };\n\n return setStorage(key, item, storageOptions);\n}\n\n/**\n * Get a value that was stored with expiration.\n * Returns defaultValue if expired or not found.\n *\n * @param key - Storage key\n * @param defaultValue - Value to return if expired or not found\n * @param options - Storage options\n *\n * @example\n * ```ts\n * const session = getStorageWithExpiry<Session>('session', null);\n * if (!session) {\n * // Session expired or doesn't exist\n * redirectToLogin();\n * }\n * ```\n */\nexport function getStorageWithExpiry<T>(key: string, defaultValue: T, options: StorageOptions = {}): T {\n const item = getStorage<StoredWithExpiry<T> | null>(key, null, options);\n\n if (!item) {\n return defaultValue;\n }\n\n if (Date.now() > item.expiry) {\n // Expired - remove the item\n removeStorage(key, options);\n return defaultValue;\n }\n\n return item.value;\n}\n","/**\n * Font Utilities\n *\n * Font family and unit conversion helpers.\n *\n * @module utils\n */\n\n/**\n * Default system font stack.\n */\nconst DEFAULT_FONT_STACK =\n '-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\"';\n\n/**\n * Create a font family string with fallback stack.\n *\n * @param {string} [fontName] - Primary font name\n * @returns {string} Font family with fallbacks\n *\n * @example\n * ```ts\n * setFont('Inter'); // '\"Inter\", -apple-system, ...'\n * setFont(); // Default system font stack\n * ```\n */\nexport function setFont(fontName?: string): string {\n if (!fontName) {\n return DEFAULT_FONT_STACK;\n }\n\n return `\"${fontName}\", ${DEFAULT_FONT_STACK}`;\n}\n\n/**\n * Convert rem to pixels.\n *\n * @param {string | number} value - Rem value (number or string like '1rem')\n * @returns {number} Value in pixels\n *\n * @example\n * ```ts\n * remToPx(1); // 16\n * remToPx('1rem'); // 16\n * remToPx(1.5); // 24\n * ```\n */\nexport function remToPx(value: string | number): number {\n const numValue = typeof value === 'string' ? parseFloat(value) : value;\n return Math.round(numValue * 16 * 100) / 100;\n}\n\n/**\n * Convert pixels to rem.\n *\n * @param {string | number} value - Pixel value (number or string like '16px')\n * @returns {string} Value in rem with unit\n *\n * @example\n * ```ts\n * pxToRem(16); // '1rem'\n * pxToRem('16px'); // '1rem'\n * pxToRem(24); // '1.5rem'\n * ```\n */\nexport function pxToRem(value: string | number): string {\n const numValue = typeof value === 'string' ? parseFloat(value) : value;\n return `${Math.round((numValue / 16) * 10000) / 10000}rem`;\n}\n\n/**\n * Create responsive font size based on viewport.\n *\n * @param {number} minSize - Minimum font size in px\n * @param {number} maxSize - Maximum font size in px\n * @param {number} [minWidth=320] - Minimum viewport width in px\n * @param {number} [maxWidth=1200] - Maximum viewport width in px\n * @returns {string} CSS clamp() value\n *\n * @example\n * ```ts\n * responsiveFontSize(14, 18);\n * // 'clamp(0.875rem, 0.7955rem + 0.3977vw, 1.125rem)'\n * ```\n */\nexport function responsiveFontSize(minSize: number, maxSize: number, minWidth = 320, maxWidth = 1200): string {\n const minRem = pxToRem(minSize);\n const maxRem = pxToRem(maxSize);\n\n const slope = (maxSize - minSize) / (maxWidth - minWidth);\n const intercept = minSize - slope * minWidth;\n\n const slopeVw = Math.round(slope * 100 * 10000) / 10000;\n const interceptRem = pxToRem(intercept);\n\n return `clamp(${minRem}, ${interceptRem} + ${slopeVw}vw, ${maxRem})`;\n}\n","/**\n * Object Utilities\n *\n * Type-safe object manipulation helpers.\n *\n * @module utils\n */\n\n/**\n * Check if an object has specific keys.\n *\n * Vacuously true when `keys` is empty, in line with `Array.every`\n * — \"every key in the empty set is present\" matches the standard\n * library and avoids surprising callers that pass a dynamically\n * derived list of required keys.\n *\n * @template T - Object type\n * @template K - Key type\n * @param {T | null | undefined} obj - Object to check\n * @param {K[]} keys - Keys to check for\n * @returns {boolean} True if object has all specified keys\n *\n * @example\n * ```ts\n * const user = { name: 'John', email: 'john@example.com' };\n * hasKeys(user, ['name', 'email']); // true\n * hasKeys(user, ['name', 'age']); // false\n * hasKeys(null, ['name']); // false\n * hasKeys(user, []); // true (vacuous)\n * ```\n */\nexport function hasKeys<T extends object, K extends keyof T>(obj: T | null | undefined, keys: K[]): boolean {\n if (!obj || typeof obj !== 'object') {\n return false;\n }\n\n return keys.every((key) => key in obj);\n}\n\n/**\n * Omit specific keys from an object.\n *\n * @template T - Object type\n * @template K - Keys to omit\n * @param {T} obj - Source object\n * @param {K[]} keys - Keys to omit\n * @returns {Omit<T, K>} New object without specified keys\n *\n * @example\n * ```ts\n * const user = { name: 'John', email: 'john@example.com', password: '...' };\n * omit(user, ['password']); // { name: 'John', email: 'john@example.com' }\n * ```\n */\nexport function omit<T extends object, K extends keyof T>(obj: T, keys: K[]): Omit<T, K> {\n const result = { ...obj };\n for (const key of keys) {\n delete result[key];\n }\n return result as Omit<T, K>;\n}\n\n/**\n * Pick specific keys from an object.\n *\n * @template T - Object type\n * @template K - Keys to pick\n * @param {T} obj - Source object\n * @param {K[]} keys - Keys to pick\n * @returns {Pick<T, K>} New object with only specified keys\n *\n * @example\n * ```ts\n * const user = { name: 'John', email: 'john@example.com', password: '...' };\n * pick(user, ['name', 'email']); // { name: 'John', email: 'john@example.com' }\n * ```\n */\nexport function pick<T extends object, K extends keyof T>(obj: T, keys: K[]): Pick<T, K> {\n const result = {} as Pick<T, K>;\n for (const key of keys) {\n if (key in obj) {\n result[key] = obj[key];\n }\n }\n return result;\n}\n\n/**\n * Deep clone an object.\n *\n * @template T - Object type\n * @param {T} obj - Object to clone\n * @returns {T} Deep cloned object\n *\n * @example\n * ```ts\n * const original = { a: 1, b: { c: 2 } };\n * const cloned = deepClone(original);\n * cloned.b.c = 3; // original.b.c is still 2\n * ```\n */\nexport function deepClone<T>(obj: T): T {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => deepClone(item)) as unknown as T;\n }\n\n if (obj instanceof Date) {\n return new Date(obj.getTime()) as unknown as T;\n }\n\n if (obj instanceof RegExp) {\n return new RegExp(obj.source, obj.flags) as unknown as T;\n }\n\n const cloned = {} as T;\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n cloned[key] = deepClone(obj[key]);\n }\n }\n return cloned;\n}\n\n/**\n * Check if a value is empty (null, undefined, empty string, empty array, empty object).\n *\n * @param {unknown} value - Value to check\n * @returns {boolean} True if empty\n *\n * @example\n * ```ts\n * isEmpty(null); // true\n * isEmpty(''); // true\n * isEmpty([]); // true\n * isEmpty({}); // true\n * isEmpty('hello'); // false\n * isEmpty([1]); // false\n * ```\n */\nexport function isEmpty(value: unknown): boolean {\n if (value == null) {\n return true;\n }\n\n if (typeof value === 'string' || Array.isArray(value)) {\n return value.length === 0;\n }\n\n if (typeof value === 'object') {\n return Object.keys(value as object).length === 0;\n }\n\n return false;\n}\n","/**\n * RTL (Right-to-Left) Utilities\n *\n * Helpers for RTL layout support and CSS transformation control.\n *\n * @module utils\n */\n\n/**\n * Prevents automatic RTL (right-to-left) flipping of a CSS declaration.\n *\n * Many CSS-in-JS libraries and RTL plugins automatically flip directional\n * CSS properties (like margin-left → margin-right) for RTL layouts.\n * Use this function to prevent that behavior for specific declarations.\n *\n * Appends the `\\/* @noflip *\\/` comment which is recognized by:\n * - stylis (used by Emotion/styled-components)\n * - rtlcss\n * - cssjanus\n *\n * @param cssValue - A CSS declaration string (e.g., \"margin-left: 10px\")\n * @returns The same declaration with `\\/* @noflip *\\/` appended\n *\n * @example\n * ```tsx\n * import { noRtlFlip } from '@omnitron-dev/prism/utils';\n *\n * // In sx prop or styled components\n * const styles = {\n * // This margin-left will stay as margin-left even in RTL\n * marginLeft: noRtlFlip('10px'),\n *\n * // Or for full declarations\n * transform: noRtlFlip('translateX(100px)'),\n * };\n *\n * // Common use case: icons that shouldn't flip\n * <ChevronIcon sx={{ transform: noRtlFlip('rotate(0deg)') }} />\n *\n * // Progress indicators that fill from left regardless of RTL\n * <ProgressBar sx={{ left: noRtlFlip('0'), right: 'auto' }} />\n * ```\n */\nexport function noRtlFlip(cssValue: unknown): string {\n if (typeof cssValue !== 'string') {\n if (process.env.NODE_ENV !== 'production') {\n console.warn('[noRtlFlip] Invalid CSS value provided:', cssValue);\n }\n return '';\n }\n\n const trimmed = cssValue.trim();\n\n if (!trimmed) {\n if (process.env.NODE_ENV !== 'production') {\n console.warn('[noRtlFlip] Empty CSS value provided');\n }\n return '';\n }\n\n // Already has the noflip comment\n if (trimmed.includes('/* @noflip */')) {\n return trimmed;\n }\n\n return `${trimmed} /* @noflip */`;\n}\n\n/**\n * Check if the current document direction is RTL.\n *\n * @returns True if the document direction is RTL\n *\n * @example\n * ```tsx\n * const isRtl = isRtlDirection();\n *\n * // Conditional styling\n * const style = {\n * marginLeft: isRtl ? '0' : '10px',\n * marginRight: isRtl ? '10px' : '0',\n * };\n * ```\n */\nexport function isRtlDirection(): boolean {\n if (typeof document === 'undefined') {\n return false;\n }\n\n return (\n document.documentElement.dir === 'rtl' ||\n document.body.dir === 'rtl' ||\n document.documentElement.getAttribute('dir') === 'rtl'\n );\n}\n\n/**\n * Get the appropriate directional property name based on RTL state.\n *\n * @param property - Base property name (e.g., 'left', 'marginLeft')\n * @param isRtl - Whether the layout is RTL\n * @returns The appropriate property name\n *\n * @example\n * ```tsx\n * const prop = getDirectionalProperty('left', isRtl);\n * // Returns 'right' if isRtl, 'left' otherwise\n * ```\n */\nexport function getDirectionalProperty(\n property: 'left' | 'right' | 'marginLeft' | 'marginRight' | 'paddingLeft' | 'paddingRight',\n isRtl: boolean\n): string {\n const mappings: Record<string, string> = {\n left: isRtl ? 'right' : 'left',\n right: isRtl ? 'left' : 'right',\n marginLeft: isRtl ? 'marginRight' : 'marginLeft',\n marginRight: isRtl ? 'marginLeft' : 'marginRight',\n paddingLeft: isRtl ? 'paddingRight' : 'paddingLeft',\n paddingRight: isRtl ? 'paddingLeft' : 'paddingRight',\n };\n\n return mappings[property] ?? property;\n}\n","/**\n * AsyncLock Utility\n *\n * Prevents race conditions in async operations like token refresh.\n * Ensures only one operation runs at a time, with subsequent calls\n * waiting for and sharing the result of the in-flight operation.\n *\n * @module utils\n */\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * Options for AsyncLock.\n */\nexport interface AsyncLockOptions {\n /** Timeout in milliseconds for the lock acquisition (default: 30000) */\n timeout?: number;\n /** Custom error message for timeout */\n timeoutMessage?: string;\n}\n\n/**\n * Result from a locked operation.\n */\nexport interface AsyncLockResult<T> {\n /** The result value */\n value: T;\n /** Whether this call executed the operation (vs waiting for another) */\n wasExecutor: boolean;\n}\n\n/**\n * State of the lock.\n */\nexport type AsyncLockState = 'idle' | 'locked' | 'releasing';\n\n// =============================================================================\n// ASYNC LOCK CLASS\n// =============================================================================\n\n/**\n * AsyncLock prevents race conditions in concurrent async operations.\n *\n * Use cases:\n * - Token refresh: Multiple API calls fail simultaneously, only one should refresh\n * - Resource initialization: Expensive setup should happen once\n * - Cache population: Prevent thundering herd problem\n *\n * @example\n * ```tsx\n * import { AsyncLock } from '@omnitron-dev/prism/utils';\n *\n * const tokenRefreshLock = new AsyncLock({ timeout: 10000 });\n *\n * async function refreshToken(): Promise<string> {\n * const { value: newToken } = await tokenRefreshLock.acquire(\n * 'refresh-token',\n * async () => {\n * // This only runs once even if called concurrently\n * const response = await fetch('/auth/refresh', { method: 'POST' });\n * const data = await response.json();\n * return data.accessToken;\n * }\n * );\n * return newToken;\n * }\n *\n * // Multiple concurrent calls share the same result\n * const [token1, token2, token3] = await Promise.all([\n * refreshToken(), // Executes the actual refresh\n * refreshToken(), // Waits for first to complete\n * refreshToken(), // Waits for first to complete\n * ]);\n * // token1 === token2 === token3\n * ```\n */\nexport class AsyncLock {\n private locks: Map<string, Promise<unknown>> = new Map();\n private resolvers: Map<string, (value: unknown) => void> = new Map();\n private rejecters: Map<string, (error: unknown) => void> = new Map();\n private options: Required<AsyncLockOptions>;\n\n constructor(options: AsyncLockOptions = {}) {\n this.options = {\n timeout: options.timeout ?? 30000,\n timeoutMessage: options.timeoutMessage ?? 'Lock acquisition timed out',\n };\n }\n\n /**\n * Current state of a specific lock.\n */\n getState(key: string): AsyncLockState {\n return this.locks.has(key) ? 'locked' : 'idle';\n }\n\n /**\n * Check if a specific lock is currently held.\n */\n isLocked(key: string): boolean {\n return this.locks.has(key);\n }\n\n /**\n * Get all currently active lock keys.\n */\n getActiveLocks(): string[] {\n return Array.from(this.locks.keys());\n }\n\n /**\n * Acquire the lock and execute the operation.\n * If the lock is already held, waits for the existing operation.\n *\n * @param key - Unique identifier for this lock\n * @param operation - Async operation to execute\n * @returns Result with the value and whether this call was the executor\n */\n async acquire<T>(key: string, operation: () => Promise<T>): Promise<AsyncLockResult<T>> {\n // If lock exists, wait for it\n const existingLock = this.locks.get(key);\n if (existingLock) {\n const value = await this.waitWithTimeout(existingLock, key);\n return { value: value as T, wasExecutor: false };\n }\n\n // Create new lock\n let resolvePromise: (value: unknown) => void;\n let rejectPromise: (error: unknown) => void;\n\n const lockPromise = new Promise<unknown>((resolve, reject) => {\n resolvePromise = resolve;\n rejectPromise = reject;\n });\n\n this.locks.set(key, lockPromise);\n this.resolvers.set(key, resolvePromise!);\n this.rejecters.set(key, rejectPromise!);\n\n try {\n const result = await operation();\n\n // Resolve for all waiters\n const resolver = this.resolvers.get(key);\n if (resolver) {\n resolver(result);\n }\n\n return { value: result, wasExecutor: true };\n } catch (error) {\n // Reject for all waiters\n const rejecter = this.rejecters.get(key);\n if (rejecter) {\n rejecter(error);\n }\n\n throw error;\n } finally {\n // Clean up\n this.locks.delete(key);\n this.resolvers.delete(key);\n this.rejecters.delete(key);\n }\n }\n\n /**\n * Try to acquire the lock without waiting.\n * Returns immediately if lock is held.\n *\n * @param key - Unique identifier for this lock\n * @param operation - Async operation to execute\n * @returns Result or null if lock was already held\n */\n async tryAcquire<T>(key: string, operation: () => Promise<T>): Promise<AsyncLockResult<T> | null> {\n if (this.isLocked(key)) {\n return null;\n }\n return this.acquire(key, operation);\n }\n\n /**\n * Force release a lock (use with caution).\n * This will reject all waiters with the provided error.\n */\n forceRelease(key: string, error?: Error): void {\n const rejecter = this.rejecters.get(key);\n if (rejecter) {\n rejecter(error ?? new Error('Lock forcefully released'));\n }\n this.locks.delete(key);\n this.resolvers.delete(key);\n this.rejecters.delete(key);\n }\n\n /**\n * Clear all locks (use with caution, e.g., on logout).\n */\n clearAll(error?: Error): void {\n for (const key of this.locks.keys()) {\n this.forceRelease(key, error);\n }\n }\n\n /**\n * Wait for a promise with timeout.\n */\n private async waitWithTimeout<T>(promise: Promise<T>, key: string): Promise<T> {\n const { timeout, timeoutMessage } = this.options;\n\n if (timeout <= 0) {\n return promise;\n }\n\n return Promise.race([\n promise,\n new Promise<never>((_, reject) => {\n setTimeout(() => {\n reject(new AsyncLockTimeoutError(`${timeoutMessage} (key: ${key})`));\n }, timeout);\n }),\n ]);\n }\n}\n\n// =============================================================================\n// ERROR CLASSES\n// =============================================================================\n\n/**\n * Error thrown when lock acquisition times out.\n */\nexport class AsyncLockTimeoutError extends Error {\n readonly name = 'AsyncLockTimeoutError';\n\n constructor(message: string) {\n super(message);\n Object.setPrototypeOf(this, AsyncLockTimeoutError.prototype);\n }\n}\n\n// =============================================================================\n// FACTORY FUNCTIONS\n// =============================================================================\n\n/**\n * Create a singleton AsyncLock instance for a specific use case.\n *\n * @example\n * ```tsx\n * import { createAsyncLock } from '@omnitron-dev/prism/utils';\n *\n * // Create a singleton lock for token refresh\n * const tokenLock = createAsyncLock({ timeout: 10000 });\n *\n * // Use in multiple places - same lock instance\n * async function apiCall() {\n * if (isTokenExpired()) {\n * await tokenLock.acquire('token', refreshToken);\n * }\n * // Make API call...\n * }\n * ```\n */\nexport function createAsyncLock(options?: AsyncLockOptions): AsyncLock {\n return new AsyncLock(options);\n}\n\n/**\n * Create a pre-configured lock for token refresh operations.\n * Uses sensible defaults for auth token refresh scenarios.\n */\nexport function createTokenRefreshLock(): AsyncLock {\n return new AsyncLock({\n timeout: 15000,\n timeoutMessage: 'Token refresh timed out',\n });\n}\n\n// =============================================================================\n// UTILITY FUNCTIONS\n// =============================================================================\n\n/**\n * Execute an operation with automatic locking.\n * Convenience function for one-off locked operations.\n *\n * @example\n * ```tsx\n * import { withLock } from '@omnitron-dev/prism/utils';\n *\n * const result = await withLock('init-cache', async () => {\n * const data = await fetchData();\n * cache.set('data', data);\n * return data;\n * });\n * ```\n */\nconst globalLock = new AsyncLock();\n\nexport async function withLock<T>(key: string, operation: () => Promise<T>, options?: AsyncLockOptions): Promise<T> {\n const lock = options ? new AsyncLock(options) : globalLock;\n const { value } = await lock.acquire(key, operation);\n return value;\n}\n\n/**\n * Decorator factory for methods that should be locked.\n * Use with class methods to ensure single execution.\n *\n * @example\n * ```tsx\n * import { locked } from '@omnitron-dev/prism/utils';\n *\n * class AuthService {\n * @locked('refresh')\n * async refreshToken(): Promise<string> {\n * // Only one instance runs at a time\n * return await this.doRefresh();\n * }\n * }\n * ```\n */\nexport function locked(key: string, options?: AsyncLockOptions) {\n const lock = new AsyncLock(options);\n\n return function decorateLockedMethod<T extends (...args: unknown[]) => Promise<unknown>>(\n _target: object,\n _propertyKey: string,\n descriptor: TypedPropertyDescriptor<T>\n ): TypedPropertyDescriptor<T> {\n const originalMethod = descriptor.value;\n\n if (!originalMethod) {\n return descriptor;\n }\n\n descriptor.value = async function runLockedMethod(this: unknown, ...args: unknown[]) {\n const { value } = await lock.acquire(key, () => originalMethod.apply(this, args));\n return value;\n } as T;\n\n return descriptor;\n };\n}\n","/**\n * Error Handling Utilities\n *\n * Comprehensive error handling with i18n support, error classification,\n * and retry logic for robust frontend applications.\n *\n * @module utils\n */\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * Error codes for classification.\n */\nexport type ErrorCode =\n // Auth errors\n | 'AUTH_REQUIRED'\n | 'AUTH_EXPIRED'\n | 'AUTH_INVALID'\n | 'AUTH_FORBIDDEN'\n | 'AUTH_MFA_REQUIRED'\n | 'AUTH_DEVICE_BLOCKED'\n // Network errors\n | 'NETWORK_ERROR'\n | 'NETWORK_TIMEOUT'\n | 'NETWORK_OFFLINE'\n // Validation errors\n | 'VALIDATION_ERROR'\n | 'VALIDATION_REQUIRED'\n | 'VALIDATION_FORMAT'\n | 'VALIDATION_RANGE'\n // Server errors\n | 'SERVER_ERROR'\n | 'SERVER_UNAVAILABLE'\n | 'SERVER_MAINTENANCE'\n // Client errors\n | 'NOT_FOUND'\n | 'CONFLICT'\n | 'RATE_LIMITED'\n | 'QUOTA_EXCEEDED'\n // Generic\n | 'UNKNOWN_ERROR'\n | string;\n\n/**\n * Severity levels for errors.\n */\nexport type ErrorSeverity = 'error' | 'warning' | 'info';\n\n/**\n * Error context for i18n.\n */\nexport interface ErrorContext {\n /** Error code for lookup */\n code: ErrorCode;\n /** HTTP status code if applicable */\n status?: number;\n /** Field name for validation errors */\n field?: string;\n /** Additional interpolation values */\n values?: Record<string, string | number>;\n /** Original error message (fallback) */\n message?: string;\n /** Retry information */\n retryAfter?: number;\n /** Severity level */\n severity?: ErrorSeverity;\n}\n\n/**\n * Translated error result.\n */\nexport interface TranslatedError {\n /** Translated title */\n title: string;\n /** Translated message */\n message: string;\n /** Error code */\n code: ErrorCode;\n /** Severity */\n severity: ErrorSeverity;\n /** Action hint (e.g., \"Please log in again\") */\n action?: string;\n /** Retry after seconds */\n retryAfter?: number;\n /** Is this a retryable error */\n canRetry: boolean;\n}\n\n/**\n * Translation function type.\n */\nexport type TranslateFn = (key: string, values?: Record<string, string | number>) => string;\n\n/**\n * Error messages dictionary type.\n */\nexport interface ErrorMessages {\n [code: string]: {\n title: string;\n message: string;\n action?: string;\n };\n}\n\n// =============================================================================\n// DEFAULT ERROR MESSAGES\n// =============================================================================\n\n/**\n * Default error messages in English.\n * Can be replaced with i18n translations.\n */\nexport const DEFAULT_ERROR_MESSAGES: ErrorMessages = {\n // Auth\n AUTH_REQUIRED: {\n title: 'Authentication Required',\n message: 'Please log in to continue.',\n action: 'Log in',\n },\n AUTH_EXPIRED: {\n title: 'Session Expired',\n message: 'Your session has expired. Please log in again.',\n action: 'Log in again',\n },\n AUTH_INVALID: {\n title: 'Invalid Credentials',\n message: 'The provided credentials are invalid.',\n action: 'Try again',\n },\n AUTH_FORBIDDEN: {\n title: 'Access Denied',\n message: \"You don't have permission to access this resource.\",\n },\n AUTH_MFA_REQUIRED: {\n title: 'Verification Required',\n message: 'Please complete two-factor authentication.',\n action: 'Verify',\n },\n AUTH_DEVICE_BLOCKED: {\n title: 'Device Blocked',\n message: 'This device has been blocked. Contact support for assistance.',\n },\n // Network\n NETWORK_ERROR: {\n title: 'Connection Error',\n message: 'Unable to connect to the server. Please check your connection.',\n action: 'Retry',\n },\n NETWORK_TIMEOUT: {\n title: 'Request Timeout',\n message: 'The request took too long. Please try again.',\n action: 'Retry',\n },\n NETWORK_OFFLINE: {\n title: 'Offline',\n message: \"You're currently offline. Please check your internet connection.\",\n },\n // Validation\n VALIDATION_ERROR: {\n title: 'Validation Error',\n message: 'Please check your input and try again.',\n },\n VALIDATION_REQUIRED: {\n title: 'Required Field',\n message: 'This field is required.',\n },\n VALIDATION_FORMAT: {\n title: 'Invalid Format',\n message: 'Please enter a valid format.',\n },\n VALIDATION_RANGE: {\n title: 'Out of Range',\n message: 'The value is out of the allowed range.',\n },\n // Server\n SERVER_ERROR: {\n title: 'Server Error',\n message: 'Something went wrong on our end. Please try again later.',\n action: 'Retry',\n },\n SERVER_UNAVAILABLE: {\n title: 'Service Unavailable',\n message: 'The service is temporarily unavailable. Please try again later.',\n action: 'Retry',\n },\n SERVER_MAINTENANCE: {\n title: 'Under Maintenance',\n message: \"We're performing maintenance. Please check back soon.\",\n },\n // Client\n NOT_FOUND: {\n title: 'Not Found',\n message: 'The requested resource could not be found.',\n },\n CONFLICT: {\n title: 'Conflict',\n message: 'The resource was modified. Please refresh and try again.',\n action: 'Refresh',\n },\n RATE_LIMITED: {\n title: 'Too Many Requests',\n message: 'Please slow down and try again later.',\n },\n QUOTA_EXCEEDED: {\n title: 'Quota Exceeded',\n message: 'You have exceeded your usage quota.',\n },\n // Generic\n UNKNOWN_ERROR: {\n title: 'Error',\n message: 'An unexpected error occurred. Please try again.',\n action: 'Retry',\n },\n};\n\n// =============================================================================\n// ERROR CLASSIFICATION\n// =============================================================================\n\n/**\n * Classify an error by HTTP status code.\n */\nexport function classifyHttpError(status: number): ErrorCode {\n switch (status) {\n case 400:\n return 'VALIDATION_ERROR';\n case 401:\n return 'AUTH_REQUIRED';\n case 403:\n return 'AUTH_FORBIDDEN';\n case 404:\n return 'NOT_FOUND';\n case 408:\n return 'NETWORK_TIMEOUT';\n case 409:\n return 'CONFLICT';\n case 429:\n return 'RATE_LIMITED';\n case 500:\n return 'SERVER_ERROR';\n case 502:\n case 503:\n case 504:\n return 'SERVER_UNAVAILABLE';\n default:\n if (status >= 400 && status < 500) return 'VALIDATION_ERROR';\n if (status >= 500) return 'SERVER_ERROR';\n return 'UNKNOWN_ERROR';\n }\n}\n\n/** errno values that mean the transport failed, whatever the message says. */\nconst NETWORK_ERRNOS = new Set([\n 'ECONNREFUSED',\n 'ECONNRESET',\n 'ENOTFOUND',\n 'EHOSTUNREACH',\n 'ENETUNREACH',\n 'ETIMEDOUT',\n 'EPIPE',\n 'EAI_AGAIN',\n]);\n\n/**\n * How each engine words a `fetch` that never reached the server.\n *\n * Chrome and Edge say \"Failed to fetch\", Firefox \"NetworkError when\n * attempting to fetch resource\", React Native \"Network request failed\" — and\n * Safari says \"Load failed\", which contains none of the words the previous\n * version looked for. Every offline request in Safari was therefore reported\n * as an unrecognised error, including a lazy route's chunk, where the\n * recovery a user needs is a reload.\n */\nconst FETCH_FAILURE = /failed to fetch|networkerror when attempting|load failed|network request failed/i;\n\n/**\n * Check if an error is a network error.\n *\n * Deciding by the words a message happens to contain cuts the wrong way in\n * both directions. Matching \"network\", \"connection\" or \"offline\" anywhere in\n * any message classified \"Connection to the payment provider was declined\"\n * and \"This network is not supported in your region\" — ordinary server\n * answers — as the user's connection failing, which sends them to check a\n * router instead of reading what the server said. Against a corpus of the\n * eight shapes a real network failure takes and five that only mention one,\n * the old predicate was right 7 times out of 13.\n *\n * So: an errno if the error carries one, the engine's own wording if `fetch`\n * rejected (it rejects with a TypeError and nothing else for a network-level\n * failure), and axios's exact `Network Error` — which is its whole message,\n * not a fragment of a sentence.\n */\nexport function isNetworkError(error: unknown): boolean {\n if (!(error instanceof Error)) return false;\n\n const code = (error as { code?: unknown }).code;\n if (typeof code === 'string' && NETWORK_ERRNOS.has(code)) return true;\n\n if (error instanceof TypeError) return FETCH_FAILURE.test(error.message);\n\n return /^network error$/i.test(error.message.trim());\n}\n\n/**\n * Check if an error is retryable.\n */\nexport function isRetryableError(code: ErrorCode): boolean {\n const retryableCodes: ErrorCode[] = [\n 'NETWORK_ERROR',\n 'NETWORK_TIMEOUT',\n 'SERVER_ERROR',\n 'SERVER_UNAVAILABLE',\n 'RATE_LIMITED',\n 'CONFLICT',\n ];\n return retryableCodes.includes(code);\n}\n\n/**\n * Get severity for an error code.\n */\nexport function getErrorSeverity(code: ErrorCode): ErrorSeverity {\n // Warnings (recoverable, action possible)\n const warnings: ErrorCode[] = ['AUTH_EXPIRED', 'RATE_LIMITED', 'NETWORK_OFFLINE', 'AUTH_MFA_REQUIRED'];\n\n // Info (informational, not blocking)\n const infos: ErrorCode[] = ['SERVER_MAINTENANCE'];\n\n if (warnings.includes(code)) return 'warning';\n if (infos.includes(code)) return 'info';\n return 'error';\n}\n\n// =============================================================================\n// ERROR TRANSLATION\n// =============================================================================\n\n/**\n * Create an error translator with custom messages or i18n function.\n *\n * @example\n * ```tsx\n * // With custom messages\n * const translate = createErrorTranslator({\n * messages: {\n * AUTH_REQUIRED: {\n * title: 'Необходима авторизация',\n * message: 'Пожалуйста, войдите в систему.',\n * },\n * },\n * });\n *\n * // With i18n library\n * const translate = createErrorTranslator({\n * t: (key, values) => i18n.t(key, values),\n * });\n *\n * const error = translate({ code: 'AUTH_REQUIRED', status: 401 });\n * // { title: 'Необходима авторизация', message: '...', ... }\n * ```\n */\nexport function createErrorTranslator(options: {\n messages?: ErrorMessages;\n t?: TranslateFn;\n fallbackMessages?: ErrorMessages;\n}): (context: ErrorContext) => TranslatedError {\n const { messages = {}, t, fallbackMessages = DEFAULT_ERROR_MESSAGES } = options;\n\n return (context: ErrorContext): TranslatedError => {\n const { code, values, message: originalMessage, severity, retryAfter } = context;\n\n // Try i18n translation first\n if (t) {\n const titleKey = `errors.${code}.title`;\n const messageKey = `errors.${code}.message`;\n const actionKey = `errors.${code}.action`;\n\n const title = t(titleKey, values);\n const translatedMessage = t(messageKey, values);\n const action = t(actionKey, values);\n\n // If translation was found (not equal to key)\n if (title !== titleKey) {\n return {\n title,\n message: translatedMessage !== messageKey ? translatedMessage : originalMessage || '',\n code,\n severity: severity ?? getErrorSeverity(code),\n action: action !== actionKey ? action : undefined,\n retryAfter,\n canRetry: isRetryableError(code),\n };\n }\n }\n\n // Try custom messages, then fallback.\n //\n // Own-property lookups: `code` comes off the wire, and a plain object\n // answers `messages['constructor']` with a function — which would then be\n // read for `.title` / `.message` and render `undefined` to the user\n // instead of an error description.\n const errorDef =\n (Object.hasOwn(messages, code) ? messages[code] : undefined) ??\n (Object.hasOwn(fallbackMessages, code) ? fallbackMessages[code] : undefined) ??\n fallbackMessages.UNKNOWN_ERROR;\n\n return {\n title: errorDef.title,\n message: interpolateMessage(errorDef.message, values) || originalMessage || errorDef.message,\n code,\n severity: severity ?? getErrorSeverity(code),\n action: errorDef.action,\n retryAfter,\n canRetry: isRetryableError(code),\n };\n };\n}\n\n/**\n * Simple message interpolation.\n */\nfunction interpolateMessage(template: string, values?: Record<string, string | number>): string {\n if (!values) return template;\n return Object.entries(values).reduce(\n (msg, [key, value]) => msg.replace(new RegExp(`\\\\{${key}\\\\}`, 'g'), String(value)),\n template\n );\n}\n\n// =============================================================================\n// ERROR EXTRACTION\n// =============================================================================\n\n/**\n * Extract error context from various error types.\n *\n * @example\n * ```tsx\n * try {\n * await api.call();\n * } catch (error) {\n * const context = extractErrorContext(error);\n * const translated = translateError(context);\n * showNotification(translated);\n * }\n * ```\n */\nexport function extractErrorContext(error: unknown): ErrorContext {\n // Already an ErrorContext\n if (isErrorContext(error)) {\n return error;\n }\n\n // Response-like object (fetch Response or similar)\n if (isResponseLike(error)) {\n return {\n code: classifyHttpError(error.status),\n status: error.status,\n message: error.statusText,\n };\n }\n\n // Error with response property (axios-like)\n if (hasResponseProperty(error)) {\n const response = error.response;\n const data = response.data;\n\n // Extract typed values from response data with safe fallbacks\n const code = typeof data?.code === 'string' ? data.code : classifyHttpError(response.status);\n const message = typeof data?.message === 'string' ? data.message : response.statusText;\n const field = typeof data?.field === 'string' ? data.field : undefined;\n const values =\n data?.values !== undefined &&\n typeof data.values === 'object' &&\n data.values !== null &&\n !Array.isArray(data.values)\n ? (data.values as Record<string, string | number>)\n : undefined;\n\n return {\n code,\n status: response.status,\n message,\n values,\n field,\n };\n }\n\n // Network error\n if (isNetworkError(error)) {\n return {\n code: navigator?.onLine === false ? 'NETWORK_OFFLINE' : 'NETWORK_ERROR',\n message: error instanceof Error ? error.message : 'Network error',\n };\n }\n\n // Generic Error\n if (error instanceof Error) {\n return {\n code: 'UNKNOWN_ERROR',\n message: error.message,\n };\n }\n\n // String error\n if (typeof error === 'string') {\n return {\n code: 'UNKNOWN_ERROR',\n message: error,\n };\n }\n\n // Object with message/code\n if (error && typeof error === 'object') {\n const obj = error as Record<string, unknown>;\n return {\n code: (typeof obj.code === 'string' ? obj.code : 'UNKNOWN_ERROR') as ErrorCode,\n message: typeof obj.message === 'string' ? obj.message : undefined,\n status: typeof obj.status === 'number' ? obj.status : undefined,\n };\n }\n\n return { code: 'UNKNOWN_ERROR' };\n}\n\n// Type guards\nfunction isErrorContext(value: unknown): value is ErrorContext {\n return (\n value !== null && typeof value === 'object' && 'code' in value && typeof (value as ErrorContext).code === 'string'\n );\n}\n\nfunction isResponseLike(value: unknown): value is { status: number; statusText: string } {\n return (\n value !== null &&\n typeof value === 'object' &&\n 'status' in value &&\n typeof (value as Record<string, unknown>).status === 'number'\n );\n}\n\nfunction hasResponseProperty(\n value: unknown\n): value is { response: { status: number; statusText: string; data?: Record<string, unknown> } } {\n return (\n value !== null &&\n typeof value === 'object' &&\n 'response' in value &&\n isResponseLike((value as Record<string, unknown>).response)\n );\n}\n\n// =============================================================================\n// RETRY UTILITIES\n// =============================================================================\n\n/**\n * Retry configuration.\n */\nexport interface RetryConfig {\n /** Maximum number of retries */\n maxRetries?: number;\n /** Initial delay in ms */\n initialDelay?: number;\n /** Maximum delay in ms */\n maxDelay?: number;\n /** Exponential backoff factor */\n backoffFactor?: number;\n /** Add jitter to delays */\n jitter?: boolean;\n /** Custom retry condition */\n shouldRetry?: (error: unknown, attempt: number) => boolean;\n /** Called before each retry */\n onRetry?: (error: unknown, attempt: number, delay: number) => void;\n}\n\nconst DEFAULT_RETRY_CONFIG: Required<RetryConfig> = {\n maxRetries: 3,\n initialDelay: 1000,\n maxDelay: 30000,\n backoffFactor: 2,\n jitter: true,\n shouldRetry: (error) => {\n const context = extractErrorContext(error);\n return isRetryableError(context.code);\n },\n onRetry: () => {},\n};\n\n/**\n * Execute an async operation with automatic retry.\n *\n * @example\n * ```tsx\n * const result = await withRetry(\n * () => fetch('/api/data'),\n * {\n * maxRetries: 3,\n * onRetry: (error, attempt, delay) => {\n * console.log(`Retry ${attempt} after ${delay}ms`);\n * },\n * }\n * );\n * ```\n */\nexport async function withRetry<T>(operation: () => Promise<T>, config?: RetryConfig): Promise<T> {\n const opts = { ...DEFAULT_RETRY_CONFIG, ...config };\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= opts.maxRetries; attempt++) {\n try {\n return await operation();\n } catch (error) {\n lastError = error;\n\n if (attempt === opts.maxRetries || !opts.shouldRetry(error, attempt)) {\n throw error;\n }\n\n const delay = calculateDelay(attempt, opts);\n opts.onRetry(error, attempt + 1, delay);\n await sleep(delay);\n }\n }\n\n throw lastError;\n}\n\n/**\n * Calculate delay with exponential backoff and optional jitter.\n */\nfunction calculateDelay(attempt: number, config: Required<RetryConfig>): number {\n let delay = config.initialDelay * Math.pow(config.backoffFactor, attempt);\n delay = Math.min(delay, config.maxDelay);\n\n if (config.jitter) {\n // Add ±25% jitter\n delay = delay * (0.75 + Math.random() * 0.5);\n }\n\n return Math.round(delay);\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n// =============================================================================\n// ERROR BOUNDARY HELPERS\n// =============================================================================\n\n/**\n * Check if error is a chunk load error (code splitting failure).\n */\nexport function isChunkLoadError(error: unknown): boolean {\n if (error instanceof Error) {\n const message = error.message.toLowerCase();\n return (\n message.includes('loading chunk') ||\n message.includes('loading css chunk') ||\n message.includes('dynamically imported module')\n );\n }\n return false;\n}\n\n/**\n * Check if error is a session expiry error.\n */\nexport function isSessionExpiredError(error: unknown): boolean {\n const context = extractErrorContext(error);\n return context.code === 'AUTH_EXPIRED' || context.code === 'AUTH_REQUIRED';\n}\n\n/**\n * Create a handler for error boundary recovery.\n */\nexport function createErrorRecoveryHandler(options: {\n onChunkError?: () => void;\n onSessionExpired?: () => void;\n onNetworkError?: () => void;\n onGenericError?: (error: unknown) => void;\n}): (error: unknown) => void {\n return (error: unknown) => {\n if (isChunkLoadError(error)) {\n options.onChunkError?.();\n return;\n }\n\n if (isSessionExpiredError(error)) {\n options.onSessionExpired?.();\n return;\n }\n\n if (isNetworkError(error)) {\n options.onNetworkError?.();\n return;\n }\n\n options.onGenericError?.(error);\n };\n}\n","/**\n * Fetch Interceptor Factory\n *\n * A flexible fetch wrapper with support for request/response interceptors,\n * automatic token refresh, and retry logic.\n *\n * Designed for production applications that need centralized HTTP handling.\n *\n * @module utils\n */\n\nimport { createAsyncLock, type AsyncLock } from './async-lock.js';\nimport { extractErrorContext, withRetry, type RetryConfig } from './errors.js';\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * Extended request init with additional options.\n */\nexport interface FetchRequestInit extends RequestInit {\n /** Skip all interceptors for this request */\n skipInterceptors?: boolean;\n /** Skip request interceptors only */\n skipRequestInterceptors?: boolean;\n /** Skip response interceptors only */\n skipResponseInterceptors?: boolean;\n /** Custom timeout in milliseconds */\n timeout?: number;\n /** Enable automatic retry on failure */\n retry?: boolean | RetryConfig;\n /** Request metadata for logging/debugging */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Request interceptor context.\n */\nexport interface RequestContext {\n url: string;\n init: FetchRequestInit;\n /** Original request info (can be string or Request) */\n input: RequestInfo | URL;\n /** Request metadata */\n metadata: Record<string, unknown>;\n}\n\n/**\n * Response interceptor context.\n */\nexport interface ResponseContext {\n response: Response;\n request: RequestContext;\n /** Time taken for the request in ms */\n duration: number;\n}\n\n/**\n * Error interceptor context.\n */\nexport interface ErrorContext {\n error: unknown;\n request: RequestContext;\n /** Time taken before error in ms */\n duration: number;\n /** Number of retry attempts made */\n retryCount: number;\n}\n\n/**\n * Request interceptor function.\n * Can modify the request or return a new one.\n */\nexport type RequestInterceptor = (ctx: RequestContext) => RequestContext | Promise<RequestContext>;\n\n/**\n * Response interceptor function.\n * Can modify the response or return a new one.\n */\nexport type ResponseInterceptor = (ctx: ResponseContext) => Response | Promise<Response>;\n\n/**\n * Error interceptor function.\n * Can handle the error, retry, or rethrow.\n */\nexport type ErrorInterceptor = (ctx: ErrorContext) => Response | Promise<Response> | never;\n\n/**\n * Interceptor configuration.\n */\nexport interface FetchInterceptorConfig {\n /** Base URL to prepend to relative paths */\n baseUrl?: string;\n /** Default headers for all requests */\n defaultHeaders?: HeadersInit;\n /** Default timeout in milliseconds (0 = no timeout) */\n defaultTimeout?: number;\n /** Request interceptors (run in order) */\n requestInterceptors?: RequestInterceptor[];\n /** Response interceptors (run in order) */\n responseInterceptors?: ResponseInterceptor[];\n /** Error interceptors (run in order, first to handle wins) */\n errorInterceptors?: ErrorInterceptor[];\n /** Default retry configuration */\n defaultRetry?: RetryConfig | false;\n /** Credentials mode for all requests */\n credentials?: RequestCredentials;\n}\n\n/**\n * Token refresh handler configuration.\n */\nexport interface TokenRefreshConfig {\n /** Check if a response indicates token expiration */\n isTokenExpired: (response: Response) => boolean;\n /** Refresh the token (called when token is expired) */\n refreshToken: () => Promise<string | null>;\n /** Get the current access token */\n getAccessToken: () => string | null;\n /** Called when refresh fails (e.g., redirect to login) */\n onRefreshFailure?: () => void;\n /** Maximum number of refresh attempts */\n maxRefreshAttempts?: number;\n}\n\n/**\n * Fetch client interface.\n */\nexport interface FetchClient {\n /** Make a fetch request */\n fetch: (input: RequestInfo | URL, init?: FetchRequestInit) => Promise<Response>;\n /** Add a request interceptor */\n addRequestInterceptor: (interceptor: RequestInterceptor) => () => void;\n /** Add a response interceptor */\n addResponseInterceptor: (interceptor: ResponseInterceptor) => () => void;\n /** Add an error interceptor */\n addErrorInterceptor: (interceptor: ErrorInterceptor) => () => void;\n /** Remove all interceptors */\n clearInterceptors: () => void;\n /** Get current configuration */\n getConfig: () => FetchInterceptorConfig;\n}\n\n// =============================================================================\n// FETCH INTERCEPTOR FACTORY\n// =============================================================================\n\n/**\n * Create a fetch client with interceptor support.\n *\n * @example\n * ```tsx\n * // Basic usage\n * const api = createFetchClient({\n * baseUrl: 'https://api.example.com',\n * defaultHeaders: { 'Content-Type': 'application/json' },\n * defaultTimeout: 30000,\n * });\n *\n * // Add auth header interceptor\n * api.addRequestInterceptor(async (ctx) => {\n * const token = getAccessToken();\n * if (token) {\n * ctx.init.headers = {\n * ...ctx.init.headers,\n * Authorization: `Bearer ${token}`,\n * };\n * }\n * return ctx;\n * });\n *\n * // Add response logging\n * api.addResponseInterceptor(async (ctx) => {\n * console.log(`${ctx.request.init.method} ${ctx.request.url} - ${ctx.response.status} (${ctx.duration}ms)`);\n * return ctx.response;\n * });\n *\n * // Make requests\n * const response = await api.fetch('/users');\n * const data = await response.json();\n * ```\n */\nexport function createFetchClient(config: FetchInterceptorConfig = {}): FetchClient {\n const requestInterceptors: RequestInterceptor[] = [...(config.requestInterceptors ?? [])];\n const responseInterceptors: ResponseInterceptor[] = [...(config.responseInterceptors ?? [])];\n const errorInterceptors: ErrorInterceptor[] = [...(config.errorInterceptors ?? [])];\n\n /**\n * Build the full URL from input.\n */\n function buildUrl(input: RequestInfo | URL): string {\n const baseUrl = config.baseUrl ?? '';\n\n if (typeof input === 'string') {\n // If input is absolute, use it as-is\n if (input.startsWith('http://') || input.startsWith('https://')) {\n return input;\n }\n // Combine with base URL\n const base = baseUrl.endsWith('/') ? baseUrl.slice(0, -1) : baseUrl;\n const path = input.startsWith('/') ? input : `/${input}`;\n return `${base}${path}`;\n }\n\n if (input instanceof URL) {\n return input.toString();\n }\n\n // Request object\n return input.url;\n }\n\n /**\n * Merge headers from multiple sources.\n */\n function mergeHeaders(...sources: (HeadersInit | undefined)[]): Record<string, string> {\n const result: Record<string, string> = {};\n\n for (const source of sources) {\n if (!source) continue;\n\n if (source instanceof Headers) {\n source.forEach((value, key) => {\n result[key] = value;\n });\n } else if (Array.isArray(source)) {\n for (const [key, value] of source) {\n result[key] = value;\n }\n } else {\n Object.assign(result, source);\n }\n }\n\n return result;\n }\n\n /**\n * Execute fetch with timeout.\n */\n async function fetchWithTimeout(url: string, init: RequestInit, timeout: number): Promise<Response> {\n if (timeout <= 0) {\n return fetch(url, init);\n }\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n return await fetch(url, {\n ...init,\n signal: controller.signal,\n });\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * The main fetch function.\n */\n async function clientFetch(input: RequestInfo | URL, init: FetchRequestInit = {}): Promise<Response> {\n const startTime = Date.now();\n let retryCount = 0;\n\n // Build initial request context\n let ctx: RequestContext = {\n url: buildUrl(input),\n init: {\n ...init,\n headers: mergeHeaders(config.defaultHeaders, init.headers),\n credentials: init.credentials ?? config.credentials,\n },\n input,\n metadata: init.metadata ?? {},\n };\n\n // Run request interceptors\n if (!init.skipInterceptors && !init.skipRequestInterceptors) {\n for (const interceptor of requestInterceptors) {\n ctx = await interceptor(ctx);\n }\n }\n\n const timeout = init.timeout ?? config.defaultTimeout ?? 0;\n\n /**\n * Execute the actual request.\n */\n async function executeRequest(): Promise<Response> {\n try {\n const response = await fetchWithTimeout(ctx.url, ctx.init, timeout);\n const duration = Date.now() - startTime;\n\n // Run response interceptors\n if (!init.skipInterceptors && !init.skipResponseInterceptors) {\n let finalResponse = response;\n for (const interceptor of responseInterceptors) {\n finalResponse = await interceptor({\n response: finalResponse,\n request: ctx,\n duration,\n });\n }\n return finalResponse;\n }\n\n return response;\n } catch (error) {\n const duration = Date.now() - startTime;\n\n // Run error interceptors\n if (!init.skipInterceptors) {\n for (const interceptor of errorInterceptors) {\n try {\n const recoveredResponse = await interceptor({\n error,\n request: ctx,\n duration,\n retryCount,\n });\n // If interceptor returns a response, use it\n return recoveredResponse;\n } catch {\n // Interceptor didn't handle the error, continue to next\n }\n }\n }\n\n // No interceptor handled the error, rethrow\n throw error;\n }\n }\n\n // Handle retry logic\n const retryConfig = init.retry ?? config.defaultRetry;\n if (retryConfig) {\n const finalConfig = typeof retryConfig === 'boolean' ? {} : retryConfig;\n return withRetry(executeRequest, {\n ...finalConfig,\n onRetry: (error, attempt, delay) => {\n retryCount = attempt;\n finalConfig.onRetry?.(error, attempt, delay);\n },\n });\n }\n\n return executeRequest();\n }\n\n return {\n fetch: clientFetch,\n\n addRequestInterceptor(interceptor) {\n requestInterceptors.push(interceptor);\n return () => {\n const index = requestInterceptors.indexOf(interceptor);\n if (index !== -1) {\n requestInterceptors.splice(index, 1);\n }\n };\n },\n\n addResponseInterceptor(interceptor) {\n responseInterceptors.push(interceptor);\n return () => {\n const index = responseInterceptors.indexOf(interceptor);\n if (index !== -1) {\n responseInterceptors.splice(index, 1);\n }\n };\n },\n\n addErrorInterceptor(interceptor) {\n errorInterceptors.push(interceptor);\n return () => {\n const index = errorInterceptors.indexOf(interceptor);\n if (index !== -1) {\n errorInterceptors.splice(index, 1);\n }\n };\n },\n\n clearInterceptors() {\n requestInterceptors.length = 0;\n responseInterceptors.length = 0;\n errorInterceptors.length = 0;\n },\n\n getConfig() {\n return { ...config };\n },\n };\n}\n\n// =============================================================================\n// TOKEN REFRESH INTERCEPTOR\n// =============================================================================\n\n/**\n * Create a token refresh interceptor that automatically refreshes\n * expired tokens and retries failed requests.\n *\n * Uses AsyncLock to prevent multiple simultaneous refresh attempts.\n *\n * @example\n * ```tsx\n * const api = createFetchClient({ baseUrl: '/api' });\n *\n * const { addToClient } = createTokenRefreshInterceptor({\n * isTokenExpired: (response) => response.status === 401,\n * refreshToken: async () => {\n * const response = await fetch('/auth/refresh', { method: 'POST' });\n * const data = await response.json();\n * localStorage.setItem('token', data.accessToken);\n * return data.accessToken;\n * },\n * getAccessToken: () => localStorage.getItem('token'),\n * onRefreshFailure: () => {\n * localStorage.removeItem('token');\n * window.location.href = '/login';\n * },\n * });\n *\n * addToClient(api);\n * ```\n */\nexport function createTokenRefreshInterceptor(config: TokenRefreshConfig): {\n addToClient: (client: FetchClient) => void;\n refreshLock: AsyncLock;\n} {\n const refreshLock = createAsyncLock({ timeout: 30000 });\n let isRefreshing = false;\n let refreshAttempts = 0;\n const maxAttempts = config.maxRefreshAttempts ?? 3;\n\n const requestInterceptor: RequestInterceptor = async (ctx) => {\n // Add auth header if we have a token\n const token = config.getAccessToken();\n if (token) {\n ctx.init.headers = {\n ...(ctx.init.headers as Record<string, string>),\n Authorization: `Bearer ${token}`,\n };\n }\n return ctx;\n };\n\n const responseInterceptor: ResponseInterceptor = async (ctx) => {\n // Check if token is expired\n if (!config.isTokenExpired(ctx.response)) {\n // Reset refresh attempts on successful request\n refreshAttempts = 0;\n return ctx.response;\n }\n\n // Token expired, try to refresh\n if (refreshAttempts >= maxAttempts) {\n config.onRefreshFailure?.();\n throw new Error('Token refresh failed after maximum attempts');\n }\n\n // Use lock to prevent multiple simultaneous refresh attempts\n const lockResult = await refreshLock.acquire('token-refresh', async () => {\n // Double-check if another request already refreshed\n if (isRefreshing) {\n // Wait for the ongoing refresh to complete\n return config.getAccessToken();\n }\n\n isRefreshing = true;\n refreshAttempts++;\n\n try {\n const token = await config.refreshToken();\n if (!token) {\n config.onRefreshFailure?.();\n throw new Error('Token refresh returned null');\n }\n return token;\n } finally {\n isRefreshing = false;\n }\n });\n\n const newToken = lockResult.value;\n\n // Retry the original request with new token\n if (newToken) {\n const retryInit: RequestInit = {\n ...ctx.request.init,\n headers: {\n ...(ctx.request.init.headers as Record<string, string>),\n Authorization: `Bearer ${newToken}`,\n },\n };\n return fetch(ctx.request.url, retryInit);\n }\n\n return ctx.response;\n };\n\n return {\n addToClient(client) {\n client.addRequestInterceptor(requestInterceptor);\n client.addResponseInterceptor(responseInterceptor);\n },\n refreshLock,\n };\n}\n\n// =============================================================================\n// HELPER FUNCTIONS\n// =============================================================================\n\n/**\n * Create a simple JSON API client.\n *\n * @example\n * ```tsx\n * const api = createJsonApiClient({\n * baseUrl: 'https://api.example.com',\n * getAuthToken: () => localStorage.getItem('token'),\n * });\n *\n * // GET request\n * const users = await api.get<User[]>('/users');\n *\n * // POST request\n * const newUser = await api.post<User>('/users', { name: 'John' });\n *\n * // DELETE request\n * await api.delete('/users/1');\n * ```\n */\nexport function createJsonApiClient(options: {\n baseUrl?: string;\n getAuthToken?: () => string | null;\n defaultHeaders?: Record<string, string>;\n timeout?: number;\n}) {\n const client = createFetchClient({\n baseUrl: options.baseUrl,\n defaultHeaders: {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n ...options.defaultHeaders,\n },\n defaultTimeout: options.timeout,\n credentials: 'include',\n });\n\n if (options.getAuthToken) {\n client.addRequestInterceptor(async (ctx) => {\n const token = options.getAuthToken!();\n if (token) {\n ctx.init.headers = {\n ...(ctx.init.headers as Record<string, string>),\n Authorization: `Bearer ${token}`,\n };\n }\n return ctx;\n });\n }\n\n async function request<T>(method: string, path: string, body?: unknown): Promise<T | null> {\n const response = await client.fetch(path, {\n method,\n body: body ? JSON.stringify(body) : undefined,\n });\n\n if (!response.ok) {\n const errorContext = extractErrorContext(response);\n const error = new Error(errorContext.message || `HTTP ${response.status}`);\n Object.assign(error, { response, context: errorContext });\n throw error;\n }\n\n // Handle empty responses (204 No Content, non-JSON responses)\n const contentType = response.headers.get('content-type');\n if (!contentType || !contentType.includes('application/json')) {\n return null;\n }\n\n const text = await response.text();\n if (!text) {\n return null;\n }\n\n return JSON.parse(text) as T;\n }\n\n return {\n client,\n get: <T>(path: string) => request<T>('GET', path),\n post: <T>(path: string, body?: unknown) => request<T>('POST', path, body),\n put: <T>(path: string, body?: unknown) => request<T>('PUT', path, body),\n patch: <T>(path: string, body?: unknown) => request<T>('PATCH', path, body),\n delete: <T>(path: string) => request<T>('DELETE', path),\n };\n}\n","/**\n * JWT Utilities\n *\n * Client-side JWT decoding and validation utilities.\n * These utilities do NOT verify signatures - they only decode and check expiration.\n * For signature verification, use server-side libraries.\n *\n * @module utils\n */\n\n// =============================================================================\n// TYPES\n// =============================================================================\n\n/**\n * Standard JWT claims.\n * @see https://datatracker.ietf.org/doc/html/rfc7519#section-4.1\n */\nexport interface JwtStandardClaims {\n /** Issuer */\n iss?: string;\n /** Subject */\n sub?: string;\n /** Audience */\n aud?: string | string[];\n /** Expiration time (Unix timestamp in seconds) */\n exp?: number;\n /** Not before (Unix timestamp in seconds) */\n nbf?: number;\n /** Issued at (Unix timestamp in seconds) */\n iat?: number;\n /** JWT ID */\n jti?: string;\n}\n\n/**\n * JWT payload with custom claims.\n * Extends standard claims with any additional properties.\n */\nexport interface JwtPayload extends JwtStandardClaims {\n /** User ID (common custom claim) */\n userId?: string;\n /** Email (common custom claim) */\n email?: string;\n /** Roles (common custom claim) */\n roles?: string[];\n /** Permissions (common custom claim) */\n permissions?: string[];\n /** Any additional custom claims */\n [key: string]: unknown;\n}\n\n/**\n * JWT validation options.\n */\nexport interface JwtValidationOptions {\n /** Clock skew tolerance in seconds (default: 60) */\n clockTolerance?: number;\n /** Require expiration claim (default: true) */\n requireExp?: boolean;\n}\n\n/**\n * JWT decode result.\n */\nexport interface JwtDecodeResult<T extends JwtPayload = JwtPayload> {\n /** Decoded header */\n header: {\n alg: string;\n typ?: string;\n [key: string]: unknown;\n };\n /** Decoded payload */\n payload: T;\n /** Original signature (base64url encoded, NOT verified) */\n signature: string;\n}\n\n// =============================================================================\n// DECODE FUNCTIONS\n// =============================================================================\n\n/**\n * Decode a base64url string to a regular string.\n * Handles URL-safe base64 encoding used in JWTs.\n */\nfunction base64UrlDecode(str: string): string {\n // Replace URL-safe characters with standard base64\n const base64 = str.replace(/-/g, '+').replace(/_/g, '/');\n\n // Add padding if necessary\n const padding = base64.length % 4;\n const paddedBase64 = padding ? base64 + '='.repeat(4 - padding) : base64;\n\n // Decode\n try {\n return atob(paddedBase64);\n } catch {\n throw new Error('Invalid base64url encoding');\n }\n}\n\n/**\n * Decode a JWT token without verifying the signature.\n *\n * ⚠️ WARNING: This function does NOT verify the signature.\n * Only use for client-side display purposes. Never trust decoded\n * data for authorization decisions without server-side verification.\n *\n * @param token - The JWT token string\n * @returns Decoded JWT parts (header, payload, signature)\n * @throws Error if the token is malformed\n *\n * @example\n * ```tsx\n * const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...';\n *\n * try {\n * const { header, payload } = jwtDecode(token);\n * console.log('Algorithm:', header.alg);\n * console.log('User ID:', payload.sub);\n * console.log('Expires:', new Date(payload.exp! * 1000));\n * } catch (error) {\n * console.error('Invalid token:', error.message);\n * }\n * ```\n */\nexport function jwtDecode<T extends JwtPayload = JwtPayload>(token: string): JwtDecodeResult<T> {\n if (!token || typeof token !== 'string') {\n throw new Error('Token must be a non-empty string');\n }\n\n const parts = token.split('.');\n\n if (parts.length !== 3) {\n throw new Error('Invalid token format: expected 3 parts separated by dots');\n }\n\n const [headerPart, payloadPart, signaturePart] = parts;\n\n try {\n const headerJson = base64UrlDecode(headerPart);\n const payloadJson = base64UrlDecode(payloadPart);\n\n const header = JSON.parse(headerJson);\n const payload = JSON.parse(payloadJson) as T;\n\n return {\n header,\n payload,\n signature: signaturePart,\n };\n } catch (error) {\n if (error instanceof SyntaxError) {\n throw new Error('Invalid token: malformed JSON in header or payload', { cause: error });\n }\n throw error;\n }\n}\n\n/**\n * Decode only the payload from a JWT token.\n * Convenience function when you only need the claims.\n *\n * @param token - The JWT token string\n * @returns Decoded payload\n * @throws Error if the token is malformed\n *\n * @example\n * ```tsx\n * const payload = jwtDecodePayload(token);\n * console.log('User:', payload.email);\n * ```\n */\nexport function jwtDecodePayload<T extends JwtPayload = JwtPayload>(token: string): T {\n return jwtDecode<T>(token).payload;\n}\n\n// =============================================================================\n// VALIDATION FUNCTIONS\n// =============================================================================\n\n/**\n * Check if a JWT token is expired.\n *\n * @param token - The JWT token string\n * @param options - Validation options\n * @returns true if the token is expired or invalid, false if still valid\n *\n * @example\n * ```tsx\n * if (isTokenExpired(token)) {\n * // Redirect to login or refresh token\n * refreshAccessToken();\n * }\n * ```\n */\nexport function isTokenExpired(token: string, options: JwtValidationOptions = {}): boolean {\n const { clockTolerance = 60, requireExp = true } = options;\n\n try {\n const { payload } = jwtDecode(token);\n\n // Check if exp claim exists\n if (payload.exp === undefined) {\n // If exp is not required, token is considered valid\n return requireExp;\n }\n\n // Check expiration with clock tolerance\n const currentTime = Math.floor(Date.now() / 1000);\n return payload.exp < currentTime - clockTolerance;\n } catch {\n // If token can't be decoded, consider it expired/invalid\n return true;\n }\n}\n\n/**\n * Check if a JWT token is valid (not expired, not before nbf).\n *\n * @param token - The JWT token string\n * @param options - Validation options\n * @returns true if the token is valid, false otherwise\n *\n * @example\n * ```tsx\n * function AuthProvider({ children }) {\n * const [token] = useLocalStorage('accessToken');\n *\n * if (!token || !isValidToken(token)) {\n * return <Navigate to=\"/login\" />;\n * }\n *\n * return children;\n * }\n * ```\n */\nexport function isValidToken(token: string, options: JwtValidationOptions = {}): boolean {\n const { clockTolerance = 60, requireExp = true } = options;\n\n try {\n const { payload } = jwtDecode(token);\n\n const currentTime = Math.floor(Date.now() / 1000);\n\n // Check expiration\n if (payload.exp !== undefined) {\n if (payload.exp < currentTime - clockTolerance) {\n return false;\n }\n } else if (requireExp) {\n // exp is required but missing\n return false;\n }\n\n // Check not-before\n if (payload.nbf !== undefined) {\n if (payload.nbf > currentTime + clockTolerance) {\n return false;\n }\n }\n\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Get time until token expires in seconds.\n * Returns 0 if token is already expired or invalid.\n *\n * @param token - The JWT token string\n * @returns Seconds until expiration, or 0 if expired/invalid\n *\n * @example\n * ```tsx\n * const secondsLeft = getTokenTimeLeft(token);\n *\n * if (secondsLeft < 300) {\n * // Less than 5 minutes left, refresh proactively\n * refreshToken();\n * }\n * ```\n */\nexport function getTokenTimeLeft(token: string): number {\n try {\n const { payload } = jwtDecode(token);\n\n if (payload.exp === undefined) {\n return Infinity;\n }\n\n const currentTime = Math.floor(Date.now() / 1000);\n const timeLeft = payload.exp - currentTime;\n\n return timeLeft > 0 ? timeLeft : 0;\n } catch {\n return 0;\n }\n}\n\n/**\n * Get expiration date from token.\n *\n * @param token - The JWT token string\n * @returns Date object for expiration, or null if no exp claim or invalid token\n *\n * @example\n * ```tsx\n * const expiresAt = getTokenExpirationDate(token);\n * if (expiresAt) {\n * console.log('Token expires:', expiresAt.toLocaleString());\n * }\n * ```\n */\nexport function getTokenExpirationDate(token: string): Date | null {\n try {\n const { payload } = jwtDecode(token);\n\n if (payload.exp === undefined) {\n return null;\n }\n\n return new Date(payload.exp * 1000);\n } catch {\n return null;\n }\n}\n\n// =============================================================================\n// CLAIM EXTRACTION HELPERS\n// =============================================================================\n\n/**\n * Safely get a claim from a token.\n *\n * @param token - The JWT token string\n * @param claim - The claim name to extract\n * @returns The claim value or undefined if not present/invalid\n *\n * @example\n * ```tsx\n * const userId = getTokenClaim(token, 'sub');\n * const roles = getTokenClaim<string[]>(token, 'roles') ?? [];\n * ```\n */\nexport function getTokenClaim<T>(token: string, claim: string): T | undefined {\n try {\n const { payload } = jwtDecode(token);\n return payload[claim] as T;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Get the subject (user identifier) from a token.\n *\n * @param token - The JWT token string\n * @returns The subject claim or undefined\n */\nexport function getTokenSubject(token: string): string | undefined {\n return getTokenClaim<string>(token, 'sub');\n}\n\n/**\n * Check if token has a specific role.\n *\n * @param token - The JWT token string\n * @param role - The role to check for\n * @param rolesKey - The key in the payload containing roles (default: 'roles')\n * @returns true if the token contains the role\n *\n * @example\n * ```tsx\n * if (tokenHasRole(token, 'admin')) {\n * // Show admin features\n * }\n * ```\n */\nexport function tokenHasRole(token: string, role: string, rolesKey = 'roles'): boolean {\n const roles = getTokenClaim<string[]>(token, rolesKey);\n return Array.isArray(roles) && roles.includes(role);\n}\n\n/**\n * Check if token has a specific permission.\n *\n * @param token - The JWT token string\n * @param permission - The permission to check for\n * @param permissionsKey - The key in the payload containing permissions (default: 'permissions')\n * @returns true if the token contains the permission\n */\nexport function tokenHasPermission(token: string, permission: string, permissionsKey = 'permissions'): boolean {\n const permissions = getTokenClaim<string[]>(token, permissionsKey);\n return Array.isArray(permissions) && permissions.includes(permission);\n}\n","/**\n * Template variable resolver.\n *\n * Replaces `{{namespace.key}}` patterns in text with values from a context map.\n * Used for injecting dynamic config values into help content at render time.\n *\n * @example\n * resolveTemplateVariables(\"Fee: {{config.sellerFee}}%\", { \"config.sellerFee\": \"5\" })\n * // => \"Fee: 5%\"\n */\nexport function resolveTemplateVariables(text: string, context: Record<string, string | number>): string {\n return text.replace(/\\{\\{([a-zA-Z0-9_.]+)\\}\\}/g, (match, key: string) => {\n const value = context[key];\n return value !== undefined ? String(value) : match;\n });\n}\n","/**\n * i18n-text — generic locale resolution for bilingual / multilingual\n * JSONB payloads stored on backend DTOs.\n *\n * Design goals:\n *\n * - Zero hard-coded locale strings. Caller passes the viewer locale\n * and (optionally) a fallback order; the helper does the rest.\n * Adding a new locale to the platform is just config, not a code\n * edit in every consumer.\n * - Locale-agnostic API so it can serve marketplace categories,\n * achievement titles, payments coin names, future post translations\n * — anywhere a `{ [lang]: string }` bag is stored.\n * - O(1) in the happy path (direct map access) with a deterministic\n * fallback walk.\n *\n * @module utils/i18n-text\n */\n\n/** A bag of language-keyed strings. Keys are RFC 5646 language codes\n * (or just `'en'`, `'ru'` for simple two-locale platforms). */\nexport type I18nText = Record<string, string | undefined>;\n\n/** Object shape that carries both a localised bag and a legacy\n * scalar field as final fallback — the canonical wire format for\n * categories, achievements etc. */\nexport interface I18nResolvable {\n /** Bilingual / multilingual bag. */\n nameI18n?: I18nText | null;\n /** Last-resort legacy fallback. The backend keeps this populated\n * even after migrating to JSONB so single-locale consumers keep\n * working without an immediate refactor. */\n name?: string | null;\n}\n\n/**\n * Resolve a `{ nameI18n, name }` object to the viewer-preferred\n * locale, walking through optional fallbacks before bottoming out\n * on the legacy scalar.\n *\n * @example\n * ```ts\n * const label = resolveI18n(category, 'ru', ['en']);\n * // → category.nameI18n.ru\n * // ?? category.nameI18n.en\n * // ?? category.name\n * // ?? ''\n * ```\n *\n * @param obj The resolvable record (e.g. a category DTO).\n * @param lang Viewer's preferred language code.\n * @param fallback Ordered list of secondary languages to try before\n * the legacy scalar. Defaults to `['en']`.\n * @param field Override the I18nText key (defaults to `nameI18n`)\n * + the legacy scalar key (defaults to `name`).\n * Useful for `descriptionI18n` / `description`.\n */\nexport function resolveI18n(\n obj: object | null | undefined,\n lang: string,\n fallback: readonly string[] = ['en'],\n field: { bag?: string; scalar?: string } = {},\n): string {\n if (!obj) return '';\n const bagKey = field.bag ?? 'nameI18n';\n const scalarKey = field.scalar ?? 'name';\n const record = obj as Record<string, unknown>;\n const bag = (record[bagKey] ?? null) as Record<string, unknown> | null;\n\n if (bag) {\n const direct = typeof bag[lang] === 'string' ? (bag[lang] as string).trim() : '';\n if (direct) return direct;\n for (const f of fallback) {\n const v = typeof bag[f] === 'string' ? (bag[f] as string).trim() : '';\n if (v) return v;\n }\n }\n\n const legacy = record[scalarKey];\n if (typeof legacy === 'string' && legacy.trim()) return legacy;\n\n return '';\n}\n\n/**\n * Build a stable searchable haystack from an i18n object — all\n * known translations concatenated lower-case so a single `.includes`\n * check matches against any locale.\n *\n * Useful inside `Autocomplete.filterOptions` to make EN-only users\n * find RU-only entries.\n */\nexport function i18nHaystack(\n bag: object | null | undefined,\n extra: readonly string[] = [],\n): string {\n if (!bag) return extra.join(' ').toLowerCase();\n const values = Object.values(bag as Record<string, unknown>)\n .filter((v): v is string => typeof v === 'string');\n return [...values, ...extra].join(' ').toLowerCase();\n}\n","/**\n * Toast wrapper with short-window deduplication.\n *\n * Problem: identical toast.error() calls fire twice in dev (React\n * StrictMode double-mounts every effect), and can also fire twice\n * in prod when a parent re-fetches mid-flight or a retry wrapper\n * surfaces the same error path. Sonner has no built-in dedupe, so\n * every duplicate landed as a separate snack-bar.\n *\n * Fix: collapse identical {method, message} calls inside a 1.5 s\n * window. The first call lands; subsequent identical calls within\n * the window are silently dropped. We DON'T forward to sonner's\n * own `id` option because then any later call with a different\n * message but the same id would *replace* the visible toast — we\n * want suppression, not replacement.\n *\n * Drop-in replacement for `import { toast } from 'sonner'`.\n * Same surface: error/success/info/warning + the passthroughs.\n *\n * Lives in prism so every UI app on the platform shares one\n * notification policy instead of each app reinventing it.\n */\nimport { toast as sonner } from 'sonner';\n\ntype ToastFn = (message: string, options?: Parameters<typeof sonner.error>[1]) => void;\n\nconst DEDUP_WINDOW_MS = 1500;\nconst recent = new Map<string, number>();\n\nfunction shouldSuppress(key: string): boolean {\n const now = Date.now();\n const last = recent.get(key);\n if (last !== undefined && now - last < DEDUP_WINDOW_MS) {\n recent.set(key, now);\n return true;\n }\n recent.set(key, now);\n // Sweep entries older than 4x the window to keep the map bounded.\n if (recent.size > 64) {\n const cutoff = now - DEDUP_WINDOW_MS * 4;\n for (const [k, t] of recent) if (t < cutoff) recent.delete(k);\n }\n return false;\n}\n\nfunction makeMethod(method: 'error' | 'success' | 'info' | 'warning'): ToastFn {\n return (message, options) => {\n const key = `${method}:${message}`;\n if (shouldSuppress(key)) return;\n sonner[method](message, options);\n };\n}\n\n// Use `typeof sonner` as the public type so we don't have to re-spell\n// every method signature (and so sonner's internal types — e.g.\n// `PromiseIExtendedResult` from `toast.promise` — don't have to be\n// re-exported from prism's DTS bundle).\nexport const toast: typeof sonner = Object.assign(\n // Allow `toast(msg)` (sonner's default = neutral toast) to work too.\n ((message: string, options?: Parameters<typeof sonner>[1]) => {\n const key = `default:${message}`;\n if (shouldSuppress(key)) return;\n sonner(message, options);\n }) as typeof sonner,\n {\n error: makeMethod('error'),\n success: makeMethod('success'),\n info: makeMethod('info'),\n warning: makeMethod('warning'),\n // Pass-through methods that don't need dedup\n loading: sonner.loading.bind(sonner),\n promise: sonner.promise.bind(sonner),\n dismiss: sonner.dismiss.bind(sonner),\n custom: sonner.custom.bind(sonner),\n message: sonner.message.bind(sonner),\n }\n) as typeof sonner;\n"]}