@parto-system-design/ui 1.1.17 → 1.1.18

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 (300) hide show
  1. package/AGENTS.md +2 -2
  2. package/README.md +1 -1
  3. package/dist/components/brand/parto-logo.cjs +0 -2
  4. package/dist/components/brand/parto-logo.js +0 -2
  5. package/dist/components/charts/PartoAreaChart.cjs +2 -4
  6. package/dist/components/charts/PartoAreaChart.d.cts +1 -1
  7. package/dist/components/charts/PartoAreaChart.d.ts +1 -1
  8. package/dist/components/charts/PartoAreaChart.js +2 -4
  9. package/dist/components/charts/PartoBarChart.cjs +2 -4
  10. package/dist/components/charts/PartoBarChart.d.cts +1 -1
  11. package/dist/components/charts/PartoBarChart.d.ts +1 -1
  12. package/dist/components/charts/PartoBarChart.js +2 -4
  13. package/dist/components/charts/PartoLineChart.cjs +2 -4
  14. package/dist/components/charts/PartoLineChart.d.cts +1 -1
  15. package/dist/components/charts/PartoLineChart.d.ts +1 -1
  16. package/dist/components/charts/PartoLineChart.js +2 -4
  17. package/dist/components/charts/PartoPieChart.cjs +2 -4
  18. package/dist/components/charts/PartoPieChart.d.cts +1 -1
  19. package/dist/components/charts/PartoPieChart.d.ts +1 -1
  20. package/dist/components/charts/PartoPieChart.js +2 -4
  21. package/dist/components/ui/accordion.cjs +0 -2
  22. package/dist/components/ui/accordion.d.cts +4 -5
  23. package/dist/components/ui/accordion.d.ts +4 -5
  24. package/dist/components/ui/accordion.js +0 -2
  25. package/dist/components/ui/alert-dialog.cjs +0 -2
  26. package/dist/components/ui/alert-dialog.d.cts +9 -10
  27. package/dist/components/ui/alert-dialog.d.ts +9 -10
  28. package/dist/components/ui/alert-dialog.js +1 -3
  29. package/dist/components/ui/alert-rule-card.cjs +149 -12
  30. package/dist/components/ui/alert-rule-card.d.cts +2 -2
  31. package/dist/components/ui/alert-rule-card.d.ts +2 -2
  32. package/dist/components/ui/alert-rule-card.js +149 -12
  33. package/dist/components/ui/alert.cjs +3 -5
  34. package/dist/components/ui/alert.js +3 -5
  35. package/dist/components/ui/app-bar.cjs +0 -2
  36. package/dist/components/ui/app-bar.js +0 -2
  37. package/dist/components/ui/avatar.cjs +0 -2
  38. package/dist/components/ui/avatar.d.cts +3 -4
  39. package/dist/components/ui/avatar.d.ts +3 -4
  40. package/dist/components/ui/avatar.js +0 -2
  41. package/dist/components/ui/badge.cjs +0 -2
  42. package/dist/components/ui/badge.d.cts +1 -1
  43. package/dist/components/ui/badge.d.ts +1 -1
  44. package/dist/components/ui/badge.js +0 -2
  45. package/dist/components/ui/breadcrumb.cjs +0 -2
  46. package/dist/components/ui/breadcrumb.d.cts +7 -8
  47. package/dist/components/ui/breadcrumb.d.ts +7 -8
  48. package/dist/components/ui/breadcrumb.js +0 -2
  49. package/dist/components/ui/button.cjs +0 -2
  50. package/dist/components/ui/button.d.cts +2 -2
  51. package/dist/components/ui/button.d.ts +2 -2
  52. package/dist/components/ui/button.js +1 -3
  53. package/dist/components/ui/calendar.cjs +0 -2
  54. package/dist/components/ui/calendar.d.cts +1 -2
  55. package/dist/components/ui/calendar.d.ts +1 -2
  56. package/dist/components/ui/calendar.js +1 -3
  57. package/dist/components/ui/card.cjs +0 -2
  58. package/dist/components/ui/card.js +0 -2
  59. package/dist/components/ui/checkbox.cjs +0 -2
  60. package/dist/components/ui/checkbox.js +0 -2
  61. package/dist/components/ui/concept-card.cjs +179 -61
  62. package/dist/components/ui/concept-card.d.cts +3 -3
  63. package/dist/components/ui/concept-card.d.ts +3 -3
  64. package/dist/components/ui/concept-card.js +179 -61
  65. package/dist/components/ui/data-table.cjs +129 -3
  66. package/dist/components/ui/data-table.d.cts +1 -1
  67. package/dist/components/ui/data-table.d.ts +1 -1
  68. package/dist/components/ui/data-table.js +130 -4
  69. package/dist/components/ui/dialog.cjs +0 -2
  70. package/dist/components/ui/dialog.d.cts +2 -3
  71. package/dist/components/ui/dialog.d.ts +2 -3
  72. package/dist/components/ui/dialog.js +0 -2
  73. package/dist/components/ui/dropdown-menu.cjs +0 -2
  74. package/dist/components/ui/dropdown-menu.d.cts +15 -16
  75. package/dist/components/ui/dropdown-menu.d.ts +15 -16
  76. package/dist/components/ui/dropdown-menu.js +0 -2
  77. package/dist/components/ui/filter-provider.cjs +0 -2
  78. package/dist/components/ui/filter-provider.d.cts +1 -2
  79. package/dist/components/ui/filter-provider.d.ts +1 -2
  80. package/dist/components/ui/filter-provider.js +0 -2
  81. package/dist/components/ui/form.cjs +0 -2
  82. package/dist/components/ui/form.d.cts +7 -8
  83. package/dist/components/ui/form.d.ts +7 -8
  84. package/dist/components/ui/form.js +0 -2
  85. package/dist/components/ui/input.cjs +0 -2
  86. package/dist/components/ui/input.js +0 -2
  87. package/dist/components/ui/iran-province-heat.cjs +1 -3
  88. package/dist/components/ui/iran-province-heat.d.cts +1 -1
  89. package/dist/components/ui/iran-province-heat.d.ts +1 -1
  90. package/dist/components/ui/iran-province-heat.js +1 -3
  91. package/dist/components/ui/label.cjs +0 -2
  92. package/dist/components/ui/label.d.cts +1 -2
  93. package/dist/components/ui/label.d.ts +1 -2
  94. package/dist/components/ui/label.js +0 -2
  95. package/dist/components/ui/page-card.cjs +170 -33
  96. package/dist/components/ui/page-card.d.cts +3 -3
  97. package/dist/components/ui/page-card.d.ts +3 -3
  98. package/dist/components/ui/page-card.js +170 -33
  99. package/dist/components/ui/page-header.cjs +128 -2
  100. package/dist/components/ui/page-header.d.cts +1 -1
  101. package/dist/components/ui/page-header.d.ts +1 -1
  102. package/dist/components/ui/page-header.js +128 -2
  103. package/dist/components/ui/password-input.cjs +0 -2
  104. package/dist/components/ui/password-input.js +0 -2
  105. package/dist/components/ui/popover.cjs +0 -2
  106. package/dist/components/ui/popover.js +0 -2
  107. package/dist/components/ui/progress.cjs +1 -3
  108. package/dist/components/ui/progress.js +1 -3
  109. package/dist/components/ui/radio-card.cjs +0 -2
  110. package/dist/components/ui/radio-card.js +0 -2
  111. package/dist/components/ui/radio-group.cjs +0 -2
  112. package/dist/components/ui/radio-group.js +0 -2
  113. package/dist/components/ui/saved-query-card.cjs +0 -2
  114. package/dist/components/ui/saved-query-card.d.cts +1 -1
  115. package/dist/components/ui/saved-query-card.d.ts +1 -1
  116. package/dist/components/ui/saved-query-card.js +1 -3
  117. package/dist/components/ui/scroll-area.cjs +0 -2
  118. package/dist/components/ui/scroll-area.d.cts +2 -3
  119. package/dist/components/ui/scroll-area.d.ts +2 -3
  120. package/dist/components/ui/scroll-area.js +0 -2
  121. package/dist/components/ui/select.cjs +0 -2
  122. package/dist/components/ui/select.d.cts +1 -2
  123. package/dist/components/ui/select.d.ts +1 -2
  124. package/dist/components/ui/select.js +0 -2
  125. package/dist/components/ui/separator.cjs +0 -2
  126. package/dist/components/ui/separator.js +0 -2
  127. package/dist/components/ui/sheet.cjs +0 -2
  128. package/dist/components/ui/sheet.d.cts +9 -10
  129. package/dist/components/ui/sheet.d.ts +9 -10
  130. package/dist/components/ui/sheet.js +0 -2
  131. package/dist/components/ui/skeleton.cjs +0 -2
  132. package/dist/components/ui/skeleton.d.cts +8 -9
  133. package/dist/components/ui/skeleton.d.ts +8 -9
  134. package/dist/components/ui/skeleton.js +0 -2
  135. package/dist/components/ui/slider.cjs +0 -2
  136. package/dist/components/ui/slider.d.cts +1 -2
  137. package/dist/components/ui/slider.d.ts +1 -2
  138. package/dist/components/ui/slider.js +0 -2
  139. package/dist/components/ui/social-platform-badge.cjs +0 -2
  140. package/dist/components/ui/social-platform-badge.js +1 -3
  141. package/dist/components/ui/sonner.cjs +4 -6
  142. package/dist/components/ui/sonner.d.cts +2 -2
  143. package/dist/components/ui/sonner.d.ts +2 -2
  144. package/dist/components/ui/sonner.js +4 -6
  145. package/dist/components/ui/sparkline.cjs +3 -5
  146. package/dist/components/ui/sparkline.d.cts +1 -1
  147. package/dist/components/ui/sparkline.d.ts +1 -1
  148. package/dist/components/ui/sparkline.js +3 -5
  149. package/dist/components/ui/switch.cjs +0 -2
  150. package/dist/components/ui/switch.d.cts +1 -1
  151. package/dist/components/ui/switch.d.ts +1 -1
  152. package/dist/components/ui/switch.js +0 -2
  153. package/dist/components/ui/table.cjs +0 -2
  154. package/dist/components/ui/table.d.cts +9 -10
  155. package/dist/components/ui/table.d.ts +9 -10
  156. package/dist/components/ui/table.js +0 -2
  157. package/dist/components/ui/tabs.cjs +0 -2
  158. package/dist/components/ui/tabs.js +0 -2
  159. package/dist/components/ui/textarea.cjs +0 -2
  160. package/dist/components/ui/textarea.js +0 -2
  161. package/dist/components/ui/toggle-group.cjs +0 -2
  162. package/dist/components/ui/toggle-group.d.cts +1 -2
  163. package/dist/components/ui/toggle-group.d.ts +1 -2
  164. package/dist/components/ui/toggle-group.js +0 -2
  165. package/dist/components/ui/tooltip.cjs +0 -2
  166. package/dist/components/ui/tooltip.js +0 -2
  167. package/dist/{concept-card-BoJ5gIJD.d.ts → concept-card-BU8JL-gj.d.cts} +5 -5
  168. package/dist/{concept-card-BXra9mr0.d.cts → concept-card-D7PfDkNR.d.ts} +5 -5
  169. package/dist/hooks/use-hotkey-registry.cjs +0 -2
  170. package/dist/hooks/use-hotkey-registry.d.cts +1 -2
  171. package/dist/hooks/use-hotkey-registry.d.ts +1 -2
  172. package/dist/hooks/use-hotkey-registry.js +0 -2
  173. package/dist/hooks/use-hotkeys.cjs +0 -2
  174. package/dist/hooks/use-hotkeys.js +0 -2
  175. package/dist/{i18n-BfRhV5aw.d.cts → i18n-DD3DMY8O.d.cts} +94 -5
  176. package/dist/{i18n-ewyqbKM-.d.ts → i18n-UEClNsBy.d.ts} +94 -5
  177. package/dist/index.cjs +1242 -1173
  178. package/dist/index.css +8010 -5459
  179. package/dist/index.d.cts +212 -991
  180. package/dist/index.d.ts +212 -991
  181. package/dist/index.js +1208 -1153
  182. package/dist/{page-card-C9XXXOVr.d.cts → page-card-DjztZrFM.d.cts} +4 -4
  183. package/dist/{page-card-DAnbez_f.d.ts → page-card-sIE4lvnb.d.ts} +4 -4
  184. package/dist/server-FTUA8opZ.d.cts +829 -0
  185. package/dist/server-m6tiB6DB.d.ts +829 -0
  186. package/dist/server.cjs +1565 -0
  187. package/dist/server.d.cts +8 -0
  188. package/dist/server.d.ts +8 -0
  189. package/dist/server.js +1483 -0
  190. package/dist/theme.css +50 -0
  191. package/dist/{toggle-group-B8r4LOQw.d.cts → toggle-group-Bis6suuR.d.cts} +3 -4
  192. package/dist/{toggle-group-B8r4LOQw.d.ts → toggle-group-Bis6suuR.d.ts} +3 -4
  193. package/dist/{utils-DlXWmDZ-.d.cts → utils-Czyp5Ned.d.cts} +1 -1
  194. package/dist/{utils-DlXWmDZ-.d.ts → utils-Czyp5Ned.d.ts} +1 -1
  195. package/package.json +455 -187
  196. package/tailwind.config.ts +184 -183
  197. package/dist/components/brand/parto-logo.cjs.map +0 -1
  198. package/dist/components/brand/parto-logo.js.map +0 -1
  199. package/dist/components/charts/PartoAreaChart.cjs.map +0 -1
  200. package/dist/components/charts/PartoAreaChart.js.map +0 -1
  201. package/dist/components/charts/PartoBarChart.cjs.map +0 -1
  202. package/dist/components/charts/PartoBarChart.js.map +0 -1
  203. package/dist/components/charts/PartoLineChart.cjs.map +0 -1
  204. package/dist/components/charts/PartoLineChart.js.map +0 -1
  205. package/dist/components/charts/PartoPieChart.cjs.map +0 -1
  206. package/dist/components/charts/PartoPieChart.js.map +0 -1
  207. package/dist/components/ui/accordion.cjs.map +0 -1
  208. package/dist/components/ui/accordion.js.map +0 -1
  209. package/dist/components/ui/alert-dialog.cjs.map +0 -1
  210. package/dist/components/ui/alert-dialog.js.map +0 -1
  211. package/dist/components/ui/alert-rule-card.cjs.map +0 -1
  212. package/dist/components/ui/alert-rule-card.js.map +0 -1
  213. package/dist/components/ui/alert.cjs.map +0 -1
  214. package/dist/components/ui/alert.js.map +0 -1
  215. package/dist/components/ui/app-bar.cjs.map +0 -1
  216. package/dist/components/ui/app-bar.js.map +0 -1
  217. package/dist/components/ui/avatar.cjs.map +0 -1
  218. package/dist/components/ui/avatar.js.map +0 -1
  219. package/dist/components/ui/badge.cjs.map +0 -1
  220. package/dist/components/ui/badge.js.map +0 -1
  221. package/dist/components/ui/breadcrumb.cjs.map +0 -1
  222. package/dist/components/ui/breadcrumb.js.map +0 -1
  223. package/dist/components/ui/button.cjs.map +0 -1
  224. package/dist/components/ui/button.js.map +0 -1
  225. package/dist/components/ui/calendar.cjs.map +0 -1
  226. package/dist/components/ui/calendar.js.map +0 -1
  227. package/dist/components/ui/card.cjs.map +0 -1
  228. package/dist/components/ui/card.js.map +0 -1
  229. package/dist/components/ui/checkbox.cjs.map +0 -1
  230. package/dist/components/ui/checkbox.js.map +0 -1
  231. package/dist/components/ui/concept-card.cjs.map +0 -1
  232. package/dist/components/ui/concept-card.js.map +0 -1
  233. package/dist/components/ui/data-table.cjs.map +0 -1
  234. package/dist/components/ui/data-table.js.map +0 -1
  235. package/dist/components/ui/dialog.cjs.map +0 -1
  236. package/dist/components/ui/dialog.js.map +0 -1
  237. package/dist/components/ui/dropdown-menu.cjs.map +0 -1
  238. package/dist/components/ui/dropdown-menu.js.map +0 -1
  239. package/dist/components/ui/filter-provider.cjs.map +0 -1
  240. package/dist/components/ui/filter-provider.js.map +0 -1
  241. package/dist/components/ui/form.cjs.map +0 -1
  242. package/dist/components/ui/form.js.map +0 -1
  243. package/dist/components/ui/input.cjs.map +0 -1
  244. package/dist/components/ui/input.js.map +0 -1
  245. package/dist/components/ui/iran-province-heat.cjs.map +0 -1
  246. package/dist/components/ui/iran-province-heat.js.map +0 -1
  247. package/dist/components/ui/label.cjs.map +0 -1
  248. package/dist/components/ui/label.js.map +0 -1
  249. package/dist/components/ui/page-card.cjs.map +0 -1
  250. package/dist/components/ui/page-card.js.map +0 -1
  251. package/dist/components/ui/page-header.cjs.map +0 -1
  252. package/dist/components/ui/page-header.js.map +0 -1
  253. package/dist/components/ui/password-input.cjs.map +0 -1
  254. package/dist/components/ui/password-input.js.map +0 -1
  255. package/dist/components/ui/popover.cjs.map +0 -1
  256. package/dist/components/ui/popover.js.map +0 -1
  257. package/dist/components/ui/progress.cjs.map +0 -1
  258. package/dist/components/ui/progress.js.map +0 -1
  259. package/dist/components/ui/radio-card.cjs.map +0 -1
  260. package/dist/components/ui/radio-card.js.map +0 -1
  261. package/dist/components/ui/radio-group.cjs.map +0 -1
  262. package/dist/components/ui/radio-group.js.map +0 -1
  263. package/dist/components/ui/saved-query-card.cjs.map +0 -1
  264. package/dist/components/ui/saved-query-card.js.map +0 -1
  265. package/dist/components/ui/scroll-area.cjs.map +0 -1
  266. package/dist/components/ui/scroll-area.js.map +0 -1
  267. package/dist/components/ui/select.cjs.map +0 -1
  268. package/dist/components/ui/select.js.map +0 -1
  269. package/dist/components/ui/separator.cjs.map +0 -1
  270. package/dist/components/ui/separator.js.map +0 -1
  271. package/dist/components/ui/sheet.cjs.map +0 -1
  272. package/dist/components/ui/sheet.js.map +0 -1
  273. package/dist/components/ui/skeleton.cjs.map +0 -1
  274. package/dist/components/ui/skeleton.js.map +0 -1
  275. package/dist/components/ui/slider.cjs.map +0 -1
  276. package/dist/components/ui/slider.js.map +0 -1
  277. package/dist/components/ui/social-platform-badge.cjs.map +0 -1
  278. package/dist/components/ui/social-platform-badge.js.map +0 -1
  279. package/dist/components/ui/sonner.cjs.map +0 -1
  280. package/dist/components/ui/sonner.js.map +0 -1
  281. package/dist/components/ui/sparkline.cjs.map +0 -1
  282. package/dist/components/ui/sparkline.js.map +0 -1
  283. package/dist/components/ui/switch.cjs.map +0 -1
  284. package/dist/components/ui/switch.js.map +0 -1
  285. package/dist/components/ui/table.cjs.map +0 -1
  286. package/dist/components/ui/table.js.map +0 -1
  287. package/dist/components/ui/tabs.cjs.map +0 -1
  288. package/dist/components/ui/tabs.js.map +0 -1
  289. package/dist/components/ui/textarea.cjs.map +0 -1
  290. package/dist/components/ui/textarea.js.map +0 -1
  291. package/dist/components/ui/toggle-group.cjs.map +0 -1
  292. package/dist/components/ui/toggle-group.js.map +0 -1
  293. package/dist/components/ui/tooltip.cjs.map +0 -1
  294. package/dist/components/ui/tooltip.js.map +0 -1
  295. package/dist/hooks/use-hotkey-registry.cjs.map +0 -1
  296. package/dist/hooks/use-hotkey-registry.js.map +0 -1
  297. package/dist/hooks/use-hotkeys.cjs.map +0 -1
  298. package/dist/hooks/use-hotkeys.js.map +0 -1
  299. package/dist/index.cjs.map +0 -1
  300. package/dist/index.js.map +0 -1
@@ -0,0 +1,829 @@
1
+ import { S as SupportedLocale } from './utils-Czyp5Ned.js';
2
+ import './i18n-UEClNsBy.js';
3
+ import { LucideIcon } from 'lucide-react';
4
+ import { SocialPlatform } from './components/ui/social-platform-badge.js';
5
+
6
+ /**
7
+ * Persian (Jalali / Solar Hijri) calendar utilities.
8
+ *
9
+ * Backed by **date-fns-jalali** — a Jalali-native fork of date-fns v4.
10
+ * Chosen over moment-jalaali (unmaintained since 2019) because:
11
+ * • Tree-shakeable, zero dependencies
12
+ * • Built-in TypeScript types
13
+ * • Tracks upstream date-fns releases
14
+ * • Built-in fa-IR locale with month/weekday names
15
+ * • ~5-10KB gzipped for typical usage
16
+ *
17
+ * DO NOT replace this library again. This decision was made after
18
+ * evaluating date-fns-jalali, jalaali-js, jalaliday (dayjs), moment-jalaali,
19
+ * and persian-date in April 2026. date-fns-jalali is the clear winner
20
+ * for a design system that needs formatting, parsing, and locale support.
21
+ */
22
+ /**
23
+ * Persian/Farsi month names
24
+ */
25
+ declare const PERSIAN_MONTHS: string[];
26
+ /**
27
+ * Persian/Farsi short month names
28
+ */
29
+ declare const PERSIAN_MONTHS_SHORT: string[];
30
+ /**
31
+ * Persian/Farsi weekday names
32
+ */
33
+ declare const PERSIAN_WEEKDAYS: string[];
34
+ /**
35
+ * Persian/Farsi short weekday names
36
+ */
37
+ declare const PERSIAN_WEEKDAYS_SHORT: string[];
38
+ /**
39
+ * Convert English digits to Persian/Farsi digits
40
+ */
41
+ declare function toPersianDigits(num: number | string): string;
42
+ /**
43
+ * Convert Persian/Farsi digits to English digits
44
+ */
45
+ declare function toEnglishDigits(str: string): string;
46
+ /**
47
+ * Format a Date object to Persian/Jalali date string.
48
+ *
49
+ * Uses date-fns-jalali format tokens:
50
+ * yyyy = Jalali year, MM = month (01-12), dd = day (01-31)
51
+ * MMMM = full month name, EEEE = full weekday name
52
+ * HH:mm = 24h time, hh:mm a = 12h time
53
+ */
54
+ declare function formatJalaliDate(date: Date, formatStr?: string): string;
55
+ /**
56
+ * Get Persian month name from a Date object
57
+ */
58
+ declare function getPersianMonthName(date: Date): string;
59
+ /**
60
+ * Get Persian short month name from a Date object
61
+ */
62
+ declare function getPersianMonthNameShort(date: Date): string;
63
+ /**
64
+ * Get Persian weekday name from a Date object
65
+ */
66
+ declare function getPersianWeekdayName(date: Date, short?: boolean): string;
67
+ /**
68
+ * Get Persian year from a Date object
69
+ */
70
+ declare function getPersianYear(date: Date): number;
71
+ /**
72
+ * Get Persian month (0-11) from a Date object
73
+ */
74
+ declare function getPersianMonth(date: Date): number;
75
+ /**
76
+ * Get Persian day from a Date object
77
+ */
78
+ declare function getPersianDay(date: Date): number;
79
+ /**
80
+ * Create a Date object from Persian/Jalali date
81
+ */
82
+ declare function jalaliToGregorian(year: number, month: number, day: number): Date;
83
+ /**
84
+ * Format date range in Persian
85
+ */
86
+ declare function formatPersianDateRange(from: Date, to: Date): string;
87
+ /**
88
+ * Get all months for a dropdown (returns array of {value, label})
89
+ */
90
+ declare function getPersianMonthsForDropdown(): Array<{
91
+ value: number;
92
+ label: string;
93
+ }>;
94
+ /**
95
+ * Get years range for a dropdown
96
+ */
97
+ declare function getPersianYearsForDropdown(fromYear: number, toYear: number): Array<{
98
+ value: number;
99
+ label: string;
100
+ }>;
101
+
102
+ type EngagementTier = 'excellent' | 'veryGood' | 'good' | 'average' | 'couldBeImproved' | 'low';
103
+ type FollowerGroup = 'nano' | 'micro' | 'mid' | 'macro' | 'mega';
104
+ interface EngagementRange {
105
+ label: string;
106
+ min: number;
107
+ max: number;
108
+ color: string;
109
+ colorFaded: string;
110
+ hoverColor: string;
111
+ /** Accessible text color for use on hoverColor background */
112
+ contrastText: string;
113
+ }
114
+ interface EngagementRangeWithDisplay extends EngagementRange {
115
+ display: string;
116
+ }
117
+ interface GroupThresholds {
118
+ followers: [number, number];
119
+ excellent: number;
120
+ veryGood: [number, number];
121
+ good: [number, number];
122
+ average: [number, number];
123
+ couldBeImproved: [number, number];
124
+ low: number;
125
+ }
126
+ declare const ENGAGEMENT_RANGES: Record<FollowerGroup, GroupThresholds>;
127
+ declare const TIER_LABELS: Record<SupportedLocale, Record<EngagementTier, string>>;
128
+ declare const GROUP_LABELS: Record<SupportedLocale, Record<FollowerGroup, string>>;
129
+ declare function getFollowerGroup(followers: number): FollowerGroup;
130
+ declare function getEngagementRanges(followers: number, locale: SupportedLocale): EngagementRangeWithDisplay[];
131
+ declare function getCurrentRangeIndex(currentRate: number, ranges: EngagementRange[]): number;
132
+
133
+ /**
134
+ * Iran's 31 provinces with trilingual labels and ISO 3166-2 codes.
135
+ *
136
+ * Use as a stable identifier source for `IranProvinceHeat`, `RegionPicker`,
137
+ * and any public-opinion dashboard scoped by استان. The slug (`code`) is the
138
+ * canonical key — never rely on label string equality, since labels are
139
+ * locale-dependent and may evolve.
140
+ *
141
+ * Codes follow ISO 3166-2:IR (e.g. 'IR-07' for Tehran). The slug is the
142
+ * lowercased, hyphenated English name without diacritics, suitable for URLs
143
+ * and CSS selectors. Use `getProvinceLabel(code, locale)` to resolve a label.
144
+ */
145
+
146
+ interface IranProvince {
147
+ /** Stable URL-safe slug. The canonical key for province lookups. */
148
+ slug: string;
149
+ /** ISO 3166-2:IR code (e.g. 'IR-07'). */
150
+ iso: string;
151
+ /** Trilingual labels — fa is the canonical/native form. */
152
+ labels: Record<SupportedLocale, string>;
153
+ }
154
+ declare const IRAN_PROVINCES: readonly IranProvince[];
155
+ type IranProvinceSlug = (typeof IRAN_PROVINCES)[number]['slug'];
156
+ /** Look up a province by slug or ISO code. Returns undefined for unknown codes. */
157
+ declare function findProvince(codeOrSlug: string): IranProvince | undefined;
158
+ /**
159
+ * Resolve the locale-appropriate label for a province slug or ISO code.
160
+ * Falls back to fa for unknown locales and to the slug itself for unknown
161
+ * provinces (so the row still renders something instead of crashing).
162
+ */
163
+ declare function getProvinceLabel(codeOrSlug: string, locale?: SupportedLocale): string;
164
+
165
+ /**
166
+ * Curated country list with trilingual labels + flag emoji.
167
+ *
168
+ * Scope: ISO 3166-1 alpha-2 codes for ~80 countries that recur in افکارسنجی
169
+ * and influencer dashboards we serve — neighbors of Iran, the Gulf, MENA,
170
+ * major Western markets, and Asian/African markets relevant to Persian-
171
+ * speaking audiences. The flag emoji is the regional-indicator pair for the
172
+ * code; modern OS fonts render it as a flag.
173
+ *
174
+ * This is NOT an exhaustive ISO 3166 dataset — for country-level analytics
175
+ * outside this scope, consumers should pass their own list to `CountryPicker`
176
+ * via the `options` prop.
177
+ */
178
+
179
+ interface Country {
180
+ /** ISO 3166-1 alpha-2 code (uppercase). The canonical key. */
181
+ code: string;
182
+ /** Trilingual labels — fa is the canonical/native form. */
183
+ labels: Record<SupportedLocale, string>;
184
+ }
185
+ /** Convert an ISO 3166-1 alpha-2 code to its flag-emoji pair. */
186
+ declare function countryFlag(code: string): string;
187
+ declare const COUNTRIES: readonly Country[];
188
+ type CountryCode = (typeof COUNTRIES)[number]['code'];
189
+ /** Look up a country by ISO 3166-1 alpha-2 code. Returns undefined for unknown codes. */
190
+ declare function findCountry(code: string): Country | undefined;
191
+ /** Resolve the locale-appropriate label for a country code. */
192
+ declare function getCountryLabel(code: string, locale: SupportedLocale): string;
193
+
194
+ /**
195
+ * Standard size scale used across the design system.
196
+ * Components should accept these values for their `size` prop.
197
+ */
198
+ type StandardSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
199
+ /** @deprecated Use `StandardSize` instead — legacy names have been removed */
200
+ type LegacySize = StandardSize;
201
+ /** @deprecated Use `StandardSize` instead */
202
+ type SizeWithLegacy = StandardSize;
203
+ /**
204
+ * Normalizes a size value to standard names.
205
+ * @deprecated All sizes are standard now — this function is a no-op passthrough.
206
+ */
207
+ declare function normalizeSize(size: StandardSize): StandardSize;
208
+
209
+ /**
210
+ * The full set of sources a post can originate from in Parto's social-listening +
211
+ * افکارسنجی pipeline. Extends `SocialPlatform` (7 social networks) with broadcast
212
+ * (tv, radio) and editorial (press, web) sources.
213
+ */
214
+ type PostSource = SocialPlatform | 'tv' | 'radio' | 'press' | 'web';
215
+ /** High-level grouping that drives header layout and default metric ordering. */
216
+ type PostSourceCategory = 'social' | 'broadcast' | 'editorial';
217
+ /**
218
+ * Derive the source category from a `PostSource` value.
219
+ * Used internally by `<PostHeader>`, metric label helpers, and default-actions config.
220
+ */
221
+ declare function sourceCategory(source: PostSource): PostSourceCategory;
222
+ /**
223
+ * @deprecated Use {@link PostSource} for new code. `PostPlatform` is retained with its
224
+ * historical meaning (the 7 social networks only) so existing components that target
225
+ * social-specific APIs (e.g. `<SocialPlatformBadge>`) keep their narrow contract.
226
+ * `PostSource` is the expanded superset (adds tv / radio / press / web).
227
+ */
228
+ type PostPlatform = SocialPlatform;
229
+ /**
230
+ * Canonical render mode for `<PostList>` and `<PostCard>`:
231
+ * - `compact` — dense list row with side thumbnail and 1-line preview
232
+ * - `comfortable` — full vertical card with header, body, media, metrics, signals
233
+ * - `grid` — magazine/visual layout (aspect-square media-dominant tile)
234
+ */
235
+ type PostView = 'compact' | 'comfortable' | 'grid';
236
+ /**
237
+ * Two-mode subset used by sub-components that don't ship a `grid` layout
238
+ * (`<PostHeader>`, `<PostHeaderBroadcast>`, `<PostHeaderEditorial>`,
239
+ * `<PostMetadata>`, `<PostSignals>`). `<PostCard>` internally narrows its
240
+ * `view` down to this when rendering those sub-components.
241
+ */
242
+ type PostDensity = 'compact' | 'comfortable';
243
+ type PostSentiment = 'positive' | 'negative' | 'neutral' | 'mixed';
244
+ type PostEmotion = 'anger' | 'anticipation' | 'joy' | 'trust' | 'fear' | 'surprise' | 'sadness' | 'disgust' | 'neutral';
245
+ /** Audience-stance classification — see CLAUDE.md domain concepts. */
246
+ type PostFlow = 'pro-gov' | 'internal-critic' | 'internal-opponent' | 'external-opponent' | 'grey';
247
+ type PostSeverity = 'low' | 'medium' | 'high' | 'critical';
248
+ type PostStatus = 'normal' | 'warning' | 'critical';
249
+ type PostAuthorityTier = 'nano' | 'micro' | 'macro' | 'mega';
250
+ interface PostAuthor {
251
+ name: string;
252
+ handle?: string;
253
+ avatarUrl?: string;
254
+ verified?: boolean;
255
+ /** Optional follower / subscriber count. */
256
+ followers?: number;
257
+ /** Optional following / friends count — rendered in the author HoverCard. */
258
+ following?: number;
259
+ /** Optional total post count — rendered in the author HoverCard. */
260
+ postCount?: number;
261
+ /** Short bio / description from the author's profile (1-2 sentences). */
262
+ bio?: string;
263
+ /** Influence score 0..100 — used to render the authority chip on the card. */
264
+ authorityScore?: number;
265
+ /** Categorical author tier inferred from follower count + engagement. */
266
+ authorityTier?: PostAuthorityTier;
267
+ }
268
+ /**
269
+ * Editorial / broadcast actor. Used when the post originates from press, web, tv, radio
270
+ * instead of an individual social-platform account.
271
+ */
272
+ interface PostOutlet {
273
+ name: string;
274
+ logoUrl?: string;
275
+ /** Editorial only: web domain ("hamshahrionline.ir"). */
276
+ domain?: string;
277
+ /** Editorial only: 0..100 SEO/credibility signal. */
278
+ domainAuthority?: number;
279
+ /** Broadcast only: TV channel or radio station ("شبکه ۱", "رادیو پیام"). */
280
+ channel?: string;
281
+ /** Broadcast only: program / show name. */
282
+ program?: string;
283
+ /** Editorial only: byline / journalist name. */
284
+ reporterName?: string;
285
+ }
286
+ /**
287
+ * Per-item ingestion status. Drives how `<PostMedia>` renders each item:
288
+ * - `ready`: image/video/audio is downloaded and viewable.
289
+ * - `loading`: the panel is fetching the media right now — render a shimmer.
290
+ * - `failed`: download failed — render retry placeholder.
291
+ * - `unavailable`: source has media but we never captured it — render "ذخیره نشده" placeholder.
292
+ */
293
+ type PostMediaStatus = 'ready' | 'loading' | 'failed' | 'unavailable';
294
+ /** Sensitive-content classifications. Used at media-level and post-level. */
295
+ type PostMediaSensitivity = 'nsfw' | 'graphic' | 'spoiler';
296
+ interface PostMediaItem {
297
+ url: string;
298
+ thumbnailUrl?: string;
299
+ /** Natural aspect ratio (width / height). Defaults to 1. */
300
+ aspectRatio?: number;
301
+ alt?: string;
302
+ type?: 'image' | 'video' | 'audio';
303
+ /** Duration in seconds for video / audio. */
304
+ duration?: number;
305
+ /** Ingestion status. Defaults to 'ready'. */
306
+ status?: PostMediaStatus;
307
+ /** Sensitivity tag — if set, the renderer blurs the media until revealed. */
308
+ sensitivity?: PostMediaSensitivity;
309
+ /** Audio only: URL of a waveform peaks file or a pre-rendered SVG / inline data URI. */
310
+ waveformUrl?: string;
311
+ }
312
+ /** Open Graph–style URL preview embedded inside a text body. */
313
+ interface PostUrlPreview {
314
+ url: string;
315
+ domain: string;
316
+ title?: string;
317
+ description?: string;
318
+ thumbnailUrl?: string;
319
+ }
320
+ /**
321
+ * Sticker overlays found on Instagram stories (mentions, polls, location, music, etc.).
322
+ * Captured to preserve story context after crawling. Coordinates are normalized 0..1.
323
+ */
324
+ interface StoryStickerOverlay {
325
+ /** Type of sticker — drives the icon and label in `<PostMediaStory>`. */
326
+ type: 'mention' | 'location' | 'hashtag' | 'music' | 'poll' | 'question' | 'time' | 'link' | 'other';
327
+ /** Human-readable label (e.g. "@digikala", "Tehran", "#خرید_آنلاین"). */
328
+ label: string;
329
+ /** Optional secondary text — for polls/questions, the question text. */
330
+ secondaryText?: string;
331
+ /** Normalized x/y position on the story canvas (0..1). */
332
+ x?: number;
333
+ y?: number;
334
+ }
335
+ /** Per-story metadata extracted at crawl time. */
336
+ interface StoryItem {
337
+ /** The captured media (image or video). */
338
+ media: PostMediaItem;
339
+ /** OCR-extracted text from the story canvas (visible Persian/English text). */
340
+ ocrText?: string;
341
+ /** Transcript for video stories. */
342
+ transcript?: string;
343
+ /** Story sticker overlays (mentions, polls, location, etc.). */
344
+ stickers?: StoryStickerOverlay[];
345
+ /** Story publication time — distinct from the post wrapper's timestamp. */
346
+ publishedAt?: Date | string | number;
347
+ /** Outbound "swipe up" / link sticker URL. */
348
+ swipeUpUrl?: string;
349
+ /** Story view count (Stories use viewers, not likes). */
350
+ viewCount?: number;
351
+ }
352
+ /**
353
+ * Discriminated union of body shapes. The renderer in `<PostBody>` switches on `type`.
354
+ *
355
+ * Story-related variants:
356
+ * - `story` — single ephemeral story (9:16, OCR text overlay, optional swipe-up link)
357
+ * - `highlight` — saved-story collection under a titled cover; renders as a strip of stories
358
+ * Other social media coverage:
359
+ * - `media-grid`, `media-carousel`, `video`, `audio`, `text` — generic
360
+ * Failure states:
361
+ * - `missing-media`, `source-removed`
362
+ */
363
+ type PostBodyData = {
364
+ type: 'text';
365
+ text: string;
366
+ urlPreview?: PostUrlPreview;
367
+ } | {
368
+ type: 'media-single';
369
+ media: PostMediaItem;
370
+ caption?: string;
371
+ urlPreview?: PostUrlPreview;
372
+ } | {
373
+ type: 'media-grid';
374
+ items: PostMediaItem[];
375
+ caption?: string;
376
+ } | {
377
+ type: 'media-carousel';
378
+ items: PostMediaItem[];
379
+ caption?: string;
380
+ } | {
381
+ type: 'video';
382
+ media: PostMediaItem;
383
+ caption?: string;
384
+ } | {
385
+ type: 'audio';
386
+ media: PostMediaItem;
387
+ caption?: string;
388
+ } | {
389
+ type: 'story';
390
+ story: StoryItem;
391
+ caption?: string;
392
+ } | {
393
+ type: 'highlight';
394
+ title: string;
395
+ coverUrl?: string;
396
+ stories: StoryItem[];
397
+ caption?: string;
398
+ } | {
399
+ type: 'missing-media';
400
+ caption?: string;
401
+ reason?: string;
402
+ } | {
403
+ type: 'source-removed';
404
+ archivedAt?: Date | string | number;
405
+ archiveUrl?: string;
406
+ caption?: string;
407
+ };
408
+ /**
409
+ * Unified metric envelope. Labels are platform-aware via `getMetricLabel(source, key, locale)`;
410
+ * the same `views` field is rendered as "بازدید" (Instagram/YouTube), "تماشا" (TikTok),
411
+ * "نمایش" (X), "بیننده" (TV), "شنونده" (Radio) depending on the post's source.
412
+ */
413
+ interface PostMetrics {
414
+ /** Generic "consumption" metric — viewers / impressions / plays / page-views. */
415
+ views?: number;
416
+ likes?: number;
417
+ comments?: number;
418
+ /** Generic share count. */
419
+ shares?: number;
420
+ /** Reposts: X retweets, Threads reposts, Telegram forwards. */
421
+ reposts?: number;
422
+ /** Quote-with-comment: X quote-tweets, Threads quotes. */
423
+ quotes?: number;
424
+ /** Saves/bookmarks: IG, TikTok, LinkedIn. */
425
+ saves?: number;
426
+ /** Estimated reach / potential audience. */
427
+ reach?: number;
428
+ /** Engagement rate as 0..1 decimal (e.g. 0.034 = 3.4%). */
429
+ engagementRate?: number;
430
+ /** Broadcast: TV viewers / Radio listeners. Editorial: readers. One field, label per source. */
431
+ audience?: number;
432
+ /** Editorial: actual page-views distinct from `views`. */
433
+ reads?: number;
434
+ /** Editorial: SEO domain authority signal — also surfaced via `PostOutlet.domainAuthority`. */
435
+ domainAuthority?: number;
436
+ /** Reaction breakdown (Telegram emoji, LinkedIn 7-type, Facebook-style). */
437
+ reactions?: ReactionBreakdown;
438
+ }
439
+ /**
440
+ * Typed reaction breakdown. Sparse — only platforms that emit a given reaction fill it.
441
+ * LinkedIn fills like/celebrate/support/love/insightful/funny.
442
+ * Facebook fills like/love/care/haha/wow/sad/angry.
443
+ * Telegram fills `emoji` with the raw map.
444
+ */
445
+ interface ReactionBreakdown {
446
+ like?: number;
447
+ love?: number;
448
+ celebrate?: number;
449
+ support?: number;
450
+ insightful?: number;
451
+ funny?: number;
452
+ /** Facebook-only — empathy reaction. */
453
+ care?: number;
454
+ /** Facebook-only — laughing reaction. */
455
+ haha?: number;
456
+ /** Facebook-only — surprised reaction. */
457
+ wow?: number;
458
+ /** Facebook-only — sad reaction. */
459
+ sad?: number;
460
+ /** Facebook-only — anger reaction. */
461
+ angry?: number;
462
+ /** Raw emoji → count map (Telegram channel reactions). */
463
+ emoji?: Record<string, number>;
464
+ }
465
+ interface PostTag {
466
+ id: string;
467
+ label: string;
468
+ /** Optional CSS var (e.g. `--chart-1`) or hex color. Auto-assigned from label if omitted. */
469
+ color?: string;
470
+ }
471
+ /**
472
+ * Flags indicate which enrichments the product has attached to this post.
473
+ * Consumers set these to show the matching chip in `<PostHeader>`.
474
+ */
475
+ interface PostEnrichmentFlags {
476
+ ocr?: boolean;
477
+ transcript?: boolean;
478
+ aiAnalysis?: boolean;
479
+ commentCount?: number;
480
+ }
481
+ /**
482
+ * Contextual flags surfaced as chips or banners on the card. Independent of media-level status.
483
+ */
484
+ interface PostFlags {
485
+ pinned?: boolean;
486
+ edited?: boolean;
487
+ /** Optional edit count, surfaced in tooltip. */
488
+ editCount?: number;
489
+ sponsored?: boolean;
490
+ /** Post was deleted at source after we ingested it. */
491
+ deletedAtSource?: boolean;
492
+ /** Snapshot URL to our archived copy. */
493
+ archivedSnapshotUrl?: string;
494
+ /** Post-level sensitivity (distinct from per-media `sensitivity`). */
495
+ sensitive?: PostMediaSensitivity;
496
+ }
497
+ /** Cluster / topic membership — links the post to a parent analytical grouping. */
498
+ interface PostCluster {
499
+ id: string;
500
+ label: string;
501
+ tone?: 'brand' | 'neutral' | 'warning';
502
+ }
503
+ /** "X reposted at Y" wrapper info. */
504
+ interface PostRepostInfo {
505
+ by: PostAuthor;
506
+ at: Date | string | number;
507
+ /** Optional retweet-with-comment / Telegram forward note. */
508
+ comment?: string;
509
+ }
510
+ /** Position info when a post belongs to a multi-post thread. */
511
+ interface PostThreadInfo {
512
+ threadId: string;
513
+ /** 1-indexed position in the thread. */
514
+ position: number;
515
+ total: number;
516
+ /** Optional id of the next thread post — used to draw the connector to the next visible card. */
517
+ nextId?: string;
518
+ }
519
+ type PlatformMetadata = {
520
+ platform: 'instagram';
521
+ postType?: 'feed' | 'reel' | 'story' | 'carousel' | 'igtv';
522
+ location?: string;
523
+ music?: {
524
+ title: string;
525
+ artist?: string;
526
+ };
527
+ saveCount?: number;
528
+ collaborators?: string[];
529
+ hashtags?: string[];
530
+ } | {
531
+ platform: 'twitter';
532
+ tweetType?: 'original' | 'retweet' | 'quote' | 'reply';
533
+ quotedTweetUrl?: string;
534
+ inReplyTo?: string;
535
+ retweetCount?: number;
536
+ quoteCount?: number;
537
+ bookmarkCount?: number;
538
+ isThread?: boolean;
539
+ threadLength?: number;
540
+ } | {
541
+ platform: 'youtube';
542
+ videoType?: 'video' | 'short' | 'live' | 'premiere';
543
+ channelSubscribers?: number;
544
+ dislikes?: number;
545
+ category?: string;
546
+ tags?: string[];
547
+ } | {
548
+ platform: 'telegram';
549
+ channelName?: string;
550
+ channelSubscribers?: number;
551
+ forwardCount?: number;
552
+ isChannel?: boolean;
553
+ /** Map of emoji → count, e.g. { '👍': 42, '❤️': 12 }. */
554
+ reactionCounts?: Record<string, number>;
555
+ } | {
556
+ platform: 'tiktok';
557
+ videoType?: 'video' | 'duet' | 'stitch' | 'live';
558
+ music?: {
559
+ title: string;
560
+ artist?: string;
561
+ };
562
+ duetWith?: string;
563
+ saveCount?: number;
564
+ effects?: string[];
565
+ } | {
566
+ platform: 'linkedin';
567
+ postType?: 'post' | 'article' | 'poll' | 'document';
568
+ reactions?: {
569
+ like?: number;
570
+ celebrate?: number;
571
+ support?: number;
572
+ love?: number;
573
+ insightful?: number;
574
+ funny?: number;
575
+ };
576
+ repostCount?: number;
577
+ industry?: string;
578
+ } | {
579
+ platform: 'threads';
580
+ replyControls?: 'anyone' | 'followed' | 'mentioned';
581
+ repostCount?: number;
582
+ quoteCount?: number;
583
+ } | {
584
+ platform: 'facebook';
585
+ postType?: 'post' | 'photo' | 'video' | 'reel' | 'story' | 'event' | 'shared';
586
+ reactions?: {
587
+ like?: number;
588
+ love?: number;
589
+ care?: number;
590
+ haha?: number;
591
+ wow?: number;
592
+ sad?: number;
593
+ angry?: number;
594
+ };
595
+ shareCount?: number;
596
+ /** Page name if posted on behalf of a page (vs personal profile). */
597
+ pageName?: string;
598
+ pageFollowers?: number;
599
+ } | {
600
+ platform: 'tv';
601
+ airDate?: Date | string | number;
602
+ durationSec?: number;
603
+ programType?: 'news' | 'talk-show' | 'documentary' | 'interview' | 'live' | 'other';
604
+ viewers?: number;
605
+ replays?: number;
606
+ } | {
607
+ platform: 'radio';
608
+ airDate?: Date | string | number;
609
+ durationSec?: number;
610
+ programType?: 'news' | 'talk-show' | 'music' | 'interview' | 'live' | 'other';
611
+ listeners?: number;
612
+ } | {
613
+ platform: 'press';
614
+ printedAt?: Date | string | number;
615
+ /** Print edition: issue / page reference. */
616
+ issue?: string;
617
+ pageNumber?: number;
618
+ /** Optional AVE (Ad Value Equivalent) — common press metric. */
619
+ adValueEquivalent?: number;
620
+ hashtags?: string[];
621
+ } | {
622
+ platform: 'web';
623
+ contentType?: 'blog' | 'forum' | 'news' | 'review' | 'comment' | 'other';
624
+ /** Reference to a parent thread / discussion if part of one. */
625
+ threadUrl?: string;
626
+ hashtags?: string[];
627
+ };
628
+ interface PostData {
629
+ id: string;
630
+ /**
631
+ * Source platform — full 11-source taxonomy (social + broadcast + editorial).
632
+ * Header layout and metric labels dispatch on this value via `sourceCategory(source)`.
633
+ */
634
+ source: PostSource;
635
+ /** Headline (editorial), program/segment (broadcast), video title (YouTube). */
636
+ title?: string;
637
+ /** Present for social posts; optional for editorial/broadcast where `outlet` is the actor. */
638
+ author?: PostAuthor;
639
+ /** Editorial/broadcast outlet — used for press, web, tv, radio header variants. */
640
+ outlet?: PostOutlet;
641
+ body: PostBodyData;
642
+ /** Post creation / publish / air time. Accepts Date, ISO string, or unix ms. */
643
+ timestamp: Date | string | number;
644
+ metrics?: PostMetrics;
645
+ sentiment?: PostSentiment;
646
+ /** Dominant emotion (9-class) — surfaced as a chip on the card. */
647
+ emotion?: PostEmotion;
648
+ /** Audience-stance classification — surfaced as a chip on the card. */
649
+ flow?: PostFlow;
650
+ severity?: PostSeverity;
651
+ enrichments?: PostEnrichmentFlags;
652
+ flags?: PostFlags;
653
+ cluster?: PostCluster;
654
+ /** User-defined category tags. */
655
+ tags?: PostTag[];
656
+ /** @deprecated Use `author.authorityScore` instead. Kept for backward compat. */
657
+ authorityScore?: number;
658
+ /** ISO language code detected for the post. */
659
+ language?: string;
660
+ /** URL to the post at the source platform. */
661
+ sourceUrl?: string;
662
+ /** Quoted/embedded post (X quote-tweets, Threads quotes, Telegram forwards-with-comment). */
663
+ quoted?: PostData;
664
+ /** Parent post when this is a reply. */
665
+ parent?: PostData;
666
+ /** Repost wrapper info — when present, render "X reposted" header strip above the card. */
667
+ reposted?: PostRepostInfo;
668
+ /** Thread position info — when present, draw the thread-connector hairline. */
669
+ thread?: PostThreadInfo;
670
+ /** Platform-specific metadata block (discriminated by source). */
671
+ platformMeta?: PlatformMetadata;
672
+ }
673
+ interface PostAction {
674
+ id: string;
675
+ label: string;
676
+ icon: LucideIcon;
677
+ variant?: 'default' | 'danger';
678
+ onClick: (post: PostData) => void;
679
+ disabled?: boolean;
680
+ hidden?: boolean;
681
+ }
682
+ /** Bulk action surfaced in the floating bottom bar when posts are selected. */
683
+ interface PostBulkAction {
684
+ id: string;
685
+ label: string;
686
+ icon: LucideIcon;
687
+ variant?: 'default' | 'danger' | 'brand';
688
+ /** Optional sub-options — rendered as dropdown menu when present. */
689
+ options?: Array<{
690
+ id: string;
691
+ label: string;
692
+ icon?: LucideIcon;
693
+ }>;
694
+ onClick: (selectedIds: string[], optionId?: string) => void;
695
+ disabled?: boolean;
696
+ hidden?: boolean;
697
+ }
698
+ interface PostCommentAuthor {
699
+ name: string;
700
+ handle?: string;
701
+ avatarUrl?: string;
702
+ verified?: boolean;
703
+ /** Optional badge: "Moderator", "Subscriber", "Author", etc. — surfaced as a chip next to the name. */
704
+ badge?: string;
705
+ }
706
+ interface PostComment {
707
+ id: string;
708
+ author: PostCommentAuthor;
709
+ text: string;
710
+ timestamp: Date | string | number;
711
+ sentiment?: PostSentiment;
712
+ likes?: number;
713
+ replies?: PostComment[];
714
+ /**
715
+ * Total reply count (may exceed `replies.length` if pagination caps the nested
716
+ * replies). Drives the "نمایش ۲۳ پاسخ" affordance.
717
+ */
718
+ replyCount?: number;
719
+ /** Pinned by post author (Instagram, YouTube). */
720
+ pinned?: boolean;
721
+ /** Indicates this is a reply from the original post author. */
722
+ authorReply?: boolean;
723
+ /** Comment was edited at source — show ویرایش‌شده chip. */
724
+ edited?: boolean;
725
+ /** ISO language code; enables translation toggle when different from current locale. */
726
+ language?: string;
727
+ /** Hidden by source moderator / shadow-banned. */
728
+ hiddenByModerator?: boolean;
729
+ /** Typed reaction breakdown (Facebook 7-type, LinkedIn 7-type, YouTube hearts, etc.). */
730
+ reactions?: ReactionBreakdown;
731
+ /** AI-detected toxicity / hate-speech / spam score (0..1). Surfaces a flag chip when set. */
732
+ toxicityScore?: number;
733
+ /** Pre-translated body (if cached). */
734
+ translatedText?: string;
735
+ }
736
+ type PostIntent = 'complaint' | 'praise' | 'question' | 'announcement' | 'comparison' | 'opinion' | 'info';
737
+ interface PostAiEntity {
738
+ text: string;
739
+ type: 'person' | 'brand' | 'place' | 'product' | 'event' | 'organization';
740
+ }
741
+ interface PostAiAnalysis {
742
+ /** Auto-generated summary of the post. */
743
+ summary?: string;
744
+ /** Key topics mentioned in the post. */
745
+ topics?: string[];
746
+ /** Named entities detected. */
747
+ entities?: PostAiEntity[];
748
+ /** Primary intent classification. */
749
+ intent?: PostIntent;
750
+ /** 9-class emotion distribution (raw counts or normalized). */
751
+ emotions?: Partial<Record<PostEmotion, number>>;
752
+ /** Flagged risks / sensitive content categories. */
753
+ risks?: string[];
754
+ /** Influence tier estimate for the author. */
755
+ influenceTier?: PostAuthorityTier;
756
+ /** Model confidence 0..1 for overall analysis. */
757
+ confidence?: number;
758
+ /** Analysis generation timestamp. */
759
+ generatedAt?: Date | string | number;
760
+ }
761
+ /** Extended post details — optionally attached to PostData when fetching full view. */
762
+ interface PostDetails {
763
+ comments?: PostComment[];
764
+ aiAnalysis?: PostAiAnalysis;
765
+ /** Text extracted from images via OCR. */
766
+ ocrText?: string;
767
+ /** Transcript for audio / video content. */
768
+ transcript?: string;
769
+ /** Platform-specific metadata block. */
770
+ platformMeta?: PlatformMetadata;
771
+ }
772
+
773
+ type SupportedMetricLocale = 'fa' | 'en';
774
+ type MetricKey = keyof PostMetrics;
775
+ /**
776
+ * Resolve a metric label for a given source + key + locale.
777
+ *
778
+ * Lookup order:
779
+ * 1. Source-specific override (e.g. tiktok.views → "تماشا")
780
+ * 2. Default for that locale (e.g. views → "بازدید")
781
+ *
782
+ * Never returns `undefined` — falls back to default labels.
783
+ */
784
+ declare function getMetricLabel(source: PostSource, key: MetricKey, locale?: SupportedMetricLocale): string;
785
+
786
+ /**
787
+ * Per-source metadata used by `<PostHeader>`, `<PostMetrics>`, badges, and the source-aware
788
+ * default actions. This is the single source of truth — adding a new platform = adding
789
+ * one entry here + one CSS var + one label entry in `post-metric-labels.ts`.
790
+ *
791
+ * Brand colors are referenced as CSS variables (`--social-platform-*`) and resolved at
792
+ * runtime so the dark/light theme can adapt where needed (twitter, threads, press, web).
793
+ */
794
+ type SourceIconSource =
795
+ /** Icon comes from the brand-SVG set in `<SocialPlatformBadge>` (7 social platforms). */
796
+ {
797
+ kind: 'social-brand';
798
+ }
799
+ /** Icon is a generic Lucide glyph (broadcast / editorial sources). */
800
+ | {
801
+ kind: 'lucide';
802
+ icon: LucideIcon;
803
+ };
804
+ interface PostSourceConfig {
805
+ /** English label, displayed when `showLabel` is on. */
806
+ label: string;
807
+ /** Persian (fa) label, for fa-locale headers and tooltips. */
808
+ labelFa: string;
809
+ /** Category: drives header layout switch. */
810
+ category: PostSourceCategory;
811
+ /** CSS variable name (without the `var()` wrapper). */
812
+ colorVar: string;
813
+ /** How to render the icon for this source. */
814
+ icon: SourceIconSource;
815
+ /**
816
+ * Default metric order — which metric keys to show by default and in what order.
817
+ * Consumers can override per-card via PostMetadata's `metricsOrder` prop.
818
+ */
819
+ defaultMetrics: ReadonlyArray<keyof PostMetrics>;
820
+ }
821
+ /** Look up the per-source config block. */
822
+ declare function getPostSourceConfig(source: PostSource): PostSourceConfig;
823
+ /**
824
+ * Convenience: read the brand color CSS variable for a source.
825
+ * Use as: `style={{ color: getSourceColorVar('instagram') }}` → `var(--social-platform-instagram)`.
826
+ */
827
+ declare function getSourceColorVar(source: PostSource): string;
828
+
829
+ export { type SizeWithLegacy as $, PERSIAN_MONTHS as A, PERSIAN_MONTHS_SHORT as B, type Country as C, PERSIAN_WEEKDAYS as D, ENGAGEMENT_RANGES as E, type FollowerGroup as F, GROUP_LABELS as G, PERSIAN_WEEKDAYS_SHORT as H, type IranProvinceSlug as I, type PlatformMetadata as J, type PostAiAnalysis as K, type LegacySize as L, type PostAiEntity as M, type PostAuthorityTier as N, type PostCommentAuthor as O, type PostData as P, type PostEmotion as Q, type PostFlags as R, type StoryItem as S, type PostFlow as T, type PostIntent as U, type PostMediaSensitivity as V, type PostMediaStatus as W, type PostSource as X, type PostSourceCategory as Y, type PostStatus as Z, type ReactionBreakdown as _, type PostView as a, type StandardSize as a0, TIER_LABELS as a1, countryFlag as a2, findCountry as a3, findProvince as a4, formatJalaliDate as a5, formatPersianDateRange as a6, getCountryLabel as a7, getCurrentRangeIndex as a8, getEngagementRanges as a9, getFollowerGroup as aa, getMetricLabel as ab, getPersianDay as ac, getPersianMonth as ad, getPersianMonthName as ae, getPersianMonthNameShort as af, getPersianMonthsForDropdown as ag, getPersianWeekdayName as ah, getPersianYear as ai, getPersianYearsForDropdown as aj, getPostSourceConfig as ak, getProvinceLabel as al, getSourceColorVar as am, jalaliToGregorian as an, normalizeSize as ao, sourceCategory as ap, toEnglishDigits as aq, toPersianDigits as ar, type PostAction as b, type PostMediaItem as c, type PostAuthor as d, type PostPlatform as e, type PostSentiment as f, type PostEnrichmentFlags as g, type PostDensity as h, type PostOutlet as i, type PostBodyData as j, type PostMetrics as k, type PostSeverity as l, type PostCluster as m, type PostRepostInfo as n, type PostThreadInfo as o, type PostUrlPreview as p, type PostBulkAction as q, type PostDetails as r, type PostComment as s, COUNTRIES as t, type CountryCode as u, type EngagementRange as v, type EngagementRangeWithDisplay as w, type EngagementTier as x, IRAN_PROVINCES as y, type IranProvince as z };