@parto-system-design/ui 1.1.5 → 1.1.7

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 (301) hide show
  1. package/AGENTS.md +233 -0
  2. package/LICENSE +21 -0
  3. package/README.md +96 -43
  4. package/dist/chunk-2UD3LGVX.cjs +316 -0
  5. package/dist/chunk-2UD3LGVX.cjs.map +1 -0
  6. package/dist/chunk-34JUCX2G.cjs +43 -0
  7. package/dist/chunk-34JUCX2G.cjs.map +1 -0
  8. package/dist/chunk-3AIJKXBV.cjs +242 -0
  9. package/dist/chunk-3AIJKXBV.cjs.map +1 -0
  10. package/dist/chunk-4SVQNEVH.js +173 -0
  11. package/dist/chunk-4SVQNEVH.js.map +1 -0
  12. package/dist/chunk-53QY4PD3.js +908 -0
  13. package/dist/chunk-53QY4PD3.js.map +1 -0
  14. package/dist/chunk-5JJSRGJD.js +31 -0
  15. package/dist/chunk-5JJSRGJD.js.map +1 -0
  16. package/dist/chunk-5K6E4ZSW.cjs +77 -0
  17. package/dist/chunk-5K6E4ZSW.cjs.map +1 -0
  18. package/dist/chunk-5NY26ULO.js +89 -0
  19. package/dist/chunk-5NY26ULO.js.map +1 -0
  20. package/dist/chunk-7RVPG3LE.cjs +231 -0
  21. package/dist/chunk-7RVPG3LE.cjs.map +1 -0
  22. package/dist/chunk-7Y4V3R3Y.cjs +120 -0
  23. package/dist/chunk-7Y4V3R3Y.cjs.map +1 -0
  24. package/dist/chunk-AXAY64KL.js +39 -0
  25. package/dist/chunk-AXAY64KL.js.map +1 -0
  26. package/dist/chunk-AYEK3WOM.js +207 -0
  27. package/dist/chunk-AYEK3WOM.js.map +1 -0
  28. package/dist/chunk-BRMBLIQG.js +53 -0
  29. package/dist/chunk-BRMBLIQG.js.map +1 -0
  30. package/dist/chunk-CAJKSTXX.cjs +54 -0
  31. package/dist/chunk-CAJKSTXX.cjs.map +1 -0
  32. package/dist/chunk-CKFWMHQU.js +401 -0
  33. package/dist/chunk-CKFWMHQU.js.map +1 -0
  34. package/dist/chunk-CV3N3HVK.js +672 -0
  35. package/dist/chunk-CV3N3HVK.js.map +1 -0
  36. package/dist/chunk-D2EBLE2B.cjs +220 -0
  37. package/dist/chunk-D2EBLE2B.cjs.map +1 -0
  38. package/dist/chunk-D5XCQDFS.js +92 -0
  39. package/dist/chunk-D5XCQDFS.js.map +1 -0
  40. package/dist/chunk-GDHRYKVM.js +45 -0
  41. package/dist/chunk-GDHRYKVM.js.map +1 -0
  42. package/dist/chunk-GKRAZGDI.cjs +84 -0
  43. package/dist/chunk-GKRAZGDI.cjs.map +1 -0
  44. package/dist/chunk-HEYMLQOV.cjs +94 -0
  45. package/dist/chunk-HEYMLQOV.cjs.map +1 -0
  46. package/dist/chunk-HF6XU5NI.js +84 -0
  47. package/dist/chunk-HF6XU5NI.js.map +1 -0
  48. package/dist/chunk-HJPDZOMJ.cjs +87 -0
  49. package/dist/chunk-HJPDZOMJ.cjs.map +1 -0
  50. package/dist/chunk-HUCC3QH5.cjs +53 -0
  51. package/dist/chunk-HUCC3QH5.cjs.map +1 -0
  52. package/dist/chunk-HYZ6BQPS.cjs +425 -0
  53. package/dist/chunk-HYZ6BQPS.cjs.map +1 -0
  54. package/dist/chunk-IQHKJ4SS.js +213 -0
  55. package/dist/chunk-IQHKJ4SS.js.map +1 -0
  56. package/dist/chunk-ISCSZMYW.cjs +106 -0
  57. package/dist/chunk-ISCSZMYW.cjs.map +1 -0
  58. package/dist/chunk-IXFEFIDO.js +82 -0
  59. package/dist/chunk-IXFEFIDO.js.map +1 -0
  60. package/dist/chunk-JUBHQAA2.js +53 -0
  61. package/dist/chunk-JUBHQAA2.js.map +1 -0
  62. package/dist/chunk-KCWRCSI7.js +62 -0
  63. package/dist/chunk-KCWRCSI7.js.map +1 -0
  64. package/dist/chunk-L2L5CKC2.js +291 -0
  65. package/dist/chunk-L2L5CKC2.js.map +1 -0
  66. package/dist/chunk-LLJR7FV3.js +135 -0
  67. package/dist/chunk-LLJR7FV3.js.map +1 -0
  68. package/dist/chunk-LZMCMZZF.js +118 -0
  69. package/dist/chunk-LZMCMZZF.js.map +1 -0
  70. package/dist/chunk-M5CHZ5BA.js +124 -0
  71. package/dist/chunk-M5CHZ5BA.js.map +1 -0
  72. package/dist/chunk-MBCTRNTG.js +89 -0
  73. package/dist/chunk-MBCTRNTG.js.map +1 -0
  74. package/dist/chunk-MEK4RSGC.js +65 -0
  75. package/dist/chunk-MEK4RSGC.js.map +1 -0
  76. package/dist/chunk-MFTX2DDQ.js +27 -0
  77. package/dist/chunk-MFTX2DDQ.js.map +1 -0
  78. package/dist/chunk-MKYVQQBV.cjs +114 -0
  79. package/dist/chunk-MKYVQQBV.cjs.map +1 -0
  80. package/dist/chunk-MQGQVI3W.cjs +950 -0
  81. package/dist/chunk-MQGQVI3W.cjs.map +1 -0
  82. package/dist/chunk-NEFZJHE4.cjs +157 -0
  83. package/dist/chunk-NEFZJHE4.cjs.map +1 -0
  84. package/dist/chunk-NEML6RCV.js +405 -0
  85. package/dist/chunk-NEML6RCV.js.map +1 -0
  86. package/dist/chunk-NV4JOKWL.cjs +197 -0
  87. package/dist/chunk-NV4JOKWL.cjs.map +1 -0
  88. package/dist/chunk-O2JG7WY5.cjs +121 -0
  89. package/dist/chunk-O2JG7WY5.cjs.map +1 -0
  90. package/dist/chunk-OEVMKFFL.cjs +140 -0
  91. package/dist/chunk-OEVMKFFL.cjs.map +1 -0
  92. package/dist/chunk-ONO2FTV4.cjs +68 -0
  93. package/dist/chunk-ONO2FTV4.cjs.map +1 -0
  94. package/dist/chunk-OS6CMYAS.cjs +79 -0
  95. package/dist/chunk-OS6CMYAS.cjs.map +1 -0
  96. package/dist/chunk-P5XHPNJG.cjs +430 -0
  97. package/dist/chunk-P5XHPNJG.cjs.map +1 -0
  98. package/dist/chunk-QJ7UB2ZQ.js +98 -0
  99. package/dist/chunk-QJ7UB2ZQ.js.map +1 -0
  100. package/dist/chunk-RA5KZNG5.js +269 -0
  101. package/dist/chunk-RA5KZNG5.js.map +1 -0
  102. package/dist/chunk-RJ3HYZ7S.js +44 -0
  103. package/dist/chunk-RJ3HYZ7S.js.map +1 -0
  104. package/dist/chunk-RZNRIOLT.js +128 -0
  105. package/dist/chunk-RZNRIOLT.js.map +1 -0
  106. package/dist/chunk-S5IPJQZ3.cjs +161 -0
  107. package/dist/chunk-S5IPJQZ3.cjs.map +1 -0
  108. package/dist/chunk-SB5DSYR5.js +211 -0
  109. package/dist/chunk-SB5DSYR5.js.map +1 -0
  110. package/dist/chunk-SCGW2BH4.cjs +69 -0
  111. package/dist/chunk-SCGW2BH4.cjs.map +1 -0
  112. package/dist/chunk-SCX6AR53.cjs +108 -0
  113. package/dist/chunk-SCX6AR53.cjs.map +1 -0
  114. package/dist/chunk-SFXV2DUH.js +106 -0
  115. package/dist/chunk-SFXV2DUH.js.map +1 -0
  116. package/dist/chunk-SXEPGD4Z.cjs +152 -0
  117. package/dist/chunk-SXEPGD4Z.cjs.map +1 -0
  118. package/dist/chunk-SZMVOHT7.cjs +107 -0
  119. package/dist/chunk-SZMVOHT7.cjs.map +1 -0
  120. package/dist/chunk-U5FLLCGC.cjs +151 -0
  121. package/dist/chunk-U5FLLCGC.cjs.map +1 -0
  122. package/dist/chunk-VO3B75F6.cjs +111 -0
  123. package/dist/chunk-VO3B75F6.cjs.map +1 -0
  124. package/dist/chunk-YAJWTNOX.js +106 -0
  125. package/dist/chunk-YAJWTNOX.js.map +1 -0
  126. package/dist/chunk-YC5KLN6I.js +139 -0
  127. package/dist/chunk-YC5KLN6I.js.map +1 -0
  128. package/dist/chunk-YE477L2H.cjs +272 -0
  129. package/dist/chunk-YE477L2H.cjs.map +1 -0
  130. package/dist/chunk-Z2TY4A75.cjs +700 -0
  131. package/dist/chunk-Z2TY4A75.cjs.map +1 -0
  132. package/dist/chunk-Z56O7UEU.cjs +136 -0
  133. package/dist/chunk-Z56O7UEU.cjs.map +1 -0
  134. package/dist/chunk-ZZFNJR2E.js +71 -0
  135. package/dist/chunk-ZZFNJR2E.js.map +1 -0
  136. package/dist/components/charts/PartoAreaChart.cjs +15 -0
  137. package/dist/components/charts/PartoAreaChart.cjs.map +1 -0
  138. package/dist/components/charts/PartoAreaChart.d.cts +51 -0
  139. package/dist/components/charts/PartoAreaChart.d.ts +51 -0
  140. package/dist/components/charts/PartoAreaChart.js +6 -0
  141. package/dist/components/charts/PartoAreaChart.js.map +1 -0
  142. package/dist/components/charts/PartoBarChart.cjs +15 -0
  143. package/dist/components/charts/PartoBarChart.cjs.map +1 -0
  144. package/dist/components/charts/PartoBarChart.d.cts +55 -0
  145. package/dist/components/charts/PartoBarChart.d.ts +55 -0
  146. package/dist/components/charts/PartoBarChart.js +6 -0
  147. package/dist/components/charts/PartoBarChart.js.map +1 -0
  148. package/dist/components/charts/PartoLineChart.cjs +15 -0
  149. package/dist/components/charts/PartoLineChart.cjs.map +1 -0
  150. package/dist/components/charts/PartoLineChart.d.cts +49 -0
  151. package/dist/components/charts/PartoLineChart.d.ts +49 -0
  152. package/dist/components/charts/PartoLineChart.js +6 -0
  153. package/dist/components/charts/PartoLineChart.js.map +1 -0
  154. package/dist/components/charts/PartoPieChart.cjs +15 -0
  155. package/dist/components/charts/PartoPieChart.cjs.map +1 -0
  156. package/dist/components/charts/PartoPieChart.d.cts +44 -0
  157. package/dist/components/charts/PartoPieChart.d.ts +44 -0
  158. package/dist/components/charts/PartoPieChart.js +6 -0
  159. package/dist/components/charts/PartoPieChart.js.map +1 -0
  160. package/dist/components/ui/alert-rule-card.cjs +15 -0
  161. package/dist/components/ui/alert-rule-card.cjs.map +1 -0
  162. package/dist/components/ui/alert-rule-card.d.cts +38 -0
  163. package/dist/components/ui/alert-rule-card.d.ts +38 -0
  164. package/dist/components/ui/alert-rule-card.js +6 -0
  165. package/dist/components/ui/alert-rule-card.js.map +1 -0
  166. package/dist/components/ui/avatar.cjs +21 -0
  167. package/dist/components/ui/avatar.cjs.map +1 -0
  168. package/dist/components/ui/avatar.d.cts +18 -0
  169. package/dist/components/ui/avatar.d.ts +18 -0
  170. package/dist/components/ui/avatar.js +4 -0
  171. package/dist/components/ui/avatar.js.map +1 -0
  172. package/dist/components/ui/badge.cjs +17 -0
  173. package/dist/components/ui/badge.cjs.map +1 -0
  174. package/dist/components/ui/badge.d.cts +16 -0
  175. package/dist/components/ui/badge.d.ts +16 -0
  176. package/dist/components/ui/badge.js +4 -0
  177. package/dist/components/ui/badge.js.map +1 -0
  178. package/dist/components/ui/button.cjs +18 -0
  179. package/dist/components/ui/button.cjs.map +1 -0
  180. package/dist/components/ui/button.d.cts +37 -0
  181. package/dist/components/ui/button.d.ts +37 -0
  182. package/dist/components/ui/button.js +5 -0
  183. package/dist/components/ui/button.js.map +1 -0
  184. package/dist/components/ui/calendar.cjs +15 -0
  185. package/dist/components/ui/calendar.cjs.map +1 -0
  186. package/dist/components/ui/calendar.d.cts +17 -0
  187. package/dist/components/ui/calendar.d.ts +17 -0
  188. package/dist/components/ui/calendar.js +6 -0
  189. package/dist/components/ui/calendar.js.map +1 -0
  190. package/dist/components/ui/card.cjs +37 -0
  191. package/dist/components/ui/card.cjs.map +1 -0
  192. package/dist/components/ui/card.d.cts +18 -0
  193. package/dist/components/ui/card.d.ts +18 -0
  194. package/dist/components/ui/card.js +4 -0
  195. package/dist/components/ui/card.js.map +1 -0
  196. package/dist/components/ui/concept-card.cjs +18 -0
  197. package/dist/components/ui/concept-card.cjs.map +1 -0
  198. package/dist/components/ui/concept-card.d.cts +5 -0
  199. package/dist/components/ui/concept-card.d.ts +5 -0
  200. package/dist/components/ui/concept-card.js +9 -0
  201. package/dist/components/ui/concept-card.js.map +1 -0
  202. package/dist/components/ui/data-table.cjs +18 -0
  203. package/dist/components/ui/data-table.cjs.map +1 -0
  204. package/dist/components/ui/data-table.d.cts +181 -0
  205. package/dist/components/ui/data-table.d.ts +181 -0
  206. package/dist/components/ui/data-table.js +9 -0
  207. package/dist/components/ui/data-table.js.map +1 -0
  208. package/dist/components/ui/dialog.cjs +49 -0
  209. package/dist/components/ui/dialog.cjs.map +1 -0
  210. package/dist/components/ui/dialog.d.cts +22 -0
  211. package/dist/components/ui/dialog.d.ts +22 -0
  212. package/dist/components/ui/dialog.js +4 -0
  213. package/dist/components/ui/dialog.js.map +1 -0
  214. package/dist/components/ui/filter-provider.cjs +20 -0
  215. package/dist/components/ui/filter-provider.cjs.map +1 -0
  216. package/dist/components/ui/filter-provider.d.cts +49 -0
  217. package/dist/components/ui/filter-provider.d.ts +49 -0
  218. package/dist/components/ui/filter-provider.js +3 -0
  219. package/dist/components/ui/filter-provider.js.map +1 -0
  220. package/dist/components/ui/input.cjs +22 -0
  221. package/dist/components/ui/input.cjs.map +1 -0
  222. package/dist/components/ui/input.d.cts +16 -0
  223. package/dist/components/ui/input.d.ts +16 -0
  224. package/dist/components/ui/input.js +5 -0
  225. package/dist/components/ui/input.js.map +1 -0
  226. package/dist/components/ui/iran-province-heat.cjs +13 -0
  227. package/dist/components/ui/iran-province-heat.cjs.map +1 -0
  228. package/dist/components/ui/iran-province-heat.d.cts +64 -0
  229. package/dist/components/ui/iran-province-heat.d.ts +64 -0
  230. package/dist/components/ui/iran-province-heat.js +4 -0
  231. package/dist/components/ui/iran-province-heat.js.map +1 -0
  232. package/dist/components/ui/page-card.cjs +16 -0
  233. package/dist/components/ui/page-card.cjs.map +1 -0
  234. package/dist/components/ui/page-card.d.cts +6 -0
  235. package/dist/components/ui/page-card.d.ts +6 -0
  236. package/dist/components/ui/page-card.js +7 -0
  237. package/dist/components/ui/page-card.js.map +1 -0
  238. package/dist/components/ui/popover.cjs +25 -0
  239. package/dist/components/ui/popover.cjs.map +1 -0
  240. package/dist/components/ui/popover.d.cts +9 -0
  241. package/dist/components/ui/popover.d.ts +9 -0
  242. package/dist/components/ui/popover.js +4 -0
  243. package/dist/components/ui/popover.js.map +1 -0
  244. package/dist/components/ui/saved-query-card.cjs +15 -0
  245. package/dist/components/ui/saved-query-card.cjs.map +1 -0
  246. package/dist/components/ui/saved-query-card.d.cts +41 -0
  247. package/dist/components/ui/saved-query-card.d.ts +41 -0
  248. package/dist/components/ui/saved-query-card.js +6 -0
  249. package/dist/components/ui/saved-query-card.js.map +1 -0
  250. package/dist/components/ui/separator.cjs +13 -0
  251. package/dist/components/ui/separator.cjs.map +1 -0
  252. package/dist/components/ui/separator.d.cts +9 -0
  253. package/dist/components/ui/separator.d.ts +9 -0
  254. package/dist/components/ui/separator.js +4 -0
  255. package/dist/components/ui/separator.js.map +1 -0
  256. package/dist/components/ui/sheet.cjs +45 -0
  257. package/dist/components/ui/sheet.cjs.map +1 -0
  258. package/dist/components/ui/sheet.d.cts +44 -0
  259. package/dist/components/ui/sheet.d.ts +44 -0
  260. package/dist/components/ui/sheet.js +4 -0
  261. package/dist/components/ui/sheet.js.map +1 -0
  262. package/dist/components/ui/sparkline.cjs +13 -0
  263. package/dist/components/ui/sparkline.cjs.map +1 -0
  264. package/dist/components/ui/sparkline.d.cts +36 -0
  265. package/dist/components/ui/sparkline.d.ts +36 -0
  266. package/dist/components/ui/sparkline.js +4 -0
  267. package/dist/components/ui/sparkline.js.map +1 -0
  268. package/dist/components/ui/tooltip.cjs +25 -0
  269. package/dist/components/ui/tooltip.cjs.map +1 -0
  270. package/dist/components/ui/tooltip.d.cts +17 -0
  271. package/dist/components/ui/tooltip.d.ts +17 -0
  272. package/dist/components/ui/tooltip.js +4 -0
  273. package/dist/components/ui/tooltip.js.map +1 -0
  274. package/dist/concept-card-CcOBb2Nz.d.ts +83 -0
  275. package/dist/concept-card-RwPbqJ06.d.cts +83 -0
  276. package/dist/hooks/use-hotkey-registry.cjs +21 -0
  277. package/dist/hooks/use-hotkey-registry.cjs.map +1 -0
  278. package/dist/hooks/use-hotkey-registry.d.cts +65 -0
  279. package/dist/hooks/use-hotkey-registry.d.ts +65 -0
  280. package/dist/hooks/use-hotkey-registry.js +4 -0
  281. package/dist/hooks/use-hotkey-registry.js.map +1 -0
  282. package/dist/hooks/use-hotkeys.cjs +16 -0
  283. package/dist/hooks/use-hotkeys.cjs.map +1 -0
  284. package/dist/hooks/use-hotkeys.d.cts +66 -0
  285. package/dist/hooks/use-hotkeys.d.ts +66 -0
  286. package/dist/hooks/use-hotkeys.js +3 -0
  287. package/dist/hooks/use-hotkeys.js.map +1 -0
  288. package/dist/i18n-ArS3mqj0.d.ts +344 -0
  289. package/dist/i18n-CAd9wGOr.d.cts +344 -0
  290. package/dist/index.cjs +7383 -10955
  291. package/dist/index.cjs.map +1 -1
  292. package/dist/index.css +157 -0
  293. package/dist/index.d.cts +726 -1144
  294. package/dist/index.d.ts +726 -1144
  295. package/dist/index.js +6735 -10912
  296. package/dist/index.js.map +1 -1
  297. package/dist/page-card-CO92oXkc.d.ts +100 -0
  298. package/dist/page-card-DOl50DqJ.d.cts +100 -0
  299. package/dist/utils-DlXWmDZ-.d.cts +35 -0
  300. package/dist/utils-DlXWmDZ-.d.ts +35 -0
  301. package/package.json +160 -4
@@ -0,0 +1,291 @@
1
+ import { formatLargeNumber, cn, convertToLocalNumbers } from './chunk-4SVQNEVH.js';
2
+ import * as React from 'react';
3
+ import { jsx, jsxs } from 'react/jsx-runtime';
4
+
5
+ // src/lib/iran-provinces.ts
6
+ var IRAN_PROVINCES = [
7
+ {
8
+ slug: "east-azerbaijan",
9
+ iso: "IR-01",
10
+ labels: { fa: "\u0622\u0630\u0631\u0628\u0627\u06CC\u062C\u0627\u0646 \u0634\u0631\u0642\u06CC", ar: "\u0623\u0630\u0631\u0628\u064A\u062C\u0627\u0646 \u0627\u0644\u0634\u0631\u0642\u064A\u0629", en: "East Azerbaijan" }
11
+ },
12
+ {
13
+ slug: "west-azerbaijan",
14
+ iso: "IR-02",
15
+ labels: { fa: "\u0622\u0630\u0631\u0628\u0627\u06CC\u062C\u0627\u0646 \u063A\u0631\u0628\u06CC", ar: "\u0623\u0630\u0631\u0628\u064A\u062C\u0627\u0646 \u0627\u0644\u063A\u0631\u0628\u064A\u0629", en: "West Azerbaijan" }
16
+ },
17
+ { slug: "ardabil", iso: "IR-03", labels: { fa: "\u0627\u0631\u062F\u0628\u06CC\u0644", ar: "\u0623\u0631\u062F\u0628\u064A\u0644", en: "Ardabil" } },
18
+ { slug: "isfahan", iso: "IR-04", labels: { fa: "\u0627\u0635\u0641\u0647\u0627\u0646", ar: "\u0623\u0635\u0641\u0647\u0627\u0646", en: "Isfahan" } },
19
+ { slug: "ilam", iso: "IR-05", labels: { fa: "\u0627\u06CC\u0644\u0627\u0645", ar: "\u0625\u064A\u0644\u0627\u0645", en: "Ilam" } },
20
+ { slug: "bushehr", iso: "IR-06", labels: { fa: "\u0628\u0648\u0634\u0647\u0631", ar: "\u0628\u0648\u0634\u0647\u0631", en: "Bushehr" } },
21
+ { slug: "tehran", iso: "IR-07", labels: { fa: "\u062A\u0647\u0631\u0627\u0646", ar: "\u0637\u0647\u0631\u0627\u0646", en: "Tehran" } },
22
+ {
23
+ slug: "chaharmahal-bakhtiari",
24
+ iso: "IR-08",
25
+ labels: { fa: "\u0686\u0647\u0627\u0631\u0645\u062D\u0627\u0644 \u0648 \u0628\u062E\u062A\u06CC\u0627\u0631\u06CC", ar: "\u062A\u0634\u0647\u0627\u0631\u0645\u062D\u0627\u0644 \u0648\u0628\u062E\u062A\u064A\u0627\u0631\u064A", en: "Chaharmahal and Bakhtiari" }
26
+ },
27
+ { slug: "razavi-khorasan", iso: "IR-09", labels: { fa: "\u062E\u0631\u0627\u0633\u0627\u0646 \u0631\u0636\u0648\u06CC", ar: "\u062E\u0631\u0627\u0633\u0627\u0646 \u0631\u0636\u0648\u064A", en: "Razavi Khorasan" } },
28
+ { slug: "khuzestan", iso: "IR-10", labels: { fa: "\u062E\u0648\u0632\u0633\u062A\u0627\u0646", ar: "\u062E\u0648\u0632\u0633\u062A\u0627\u0646", en: "Khuzestan" } },
29
+ { slug: "zanjan", iso: "IR-11", labels: { fa: "\u0632\u0646\u062C\u0627\u0646", ar: "\u0632\u0646\u062C\u0627\u0646", en: "Zanjan" } },
30
+ { slug: "semnan", iso: "IR-12", labels: { fa: "\u0633\u0645\u0646\u0627\u0646", ar: "\u0633\u0645\u0646\u0627\u0646", en: "Semnan" } },
31
+ {
32
+ slug: "sistan-baluchestan",
33
+ iso: "IR-13",
34
+ labels: { fa: "\u0633\u06CC\u0633\u062A\u0627\u0646 \u0648 \u0628\u0644\u0648\u0686\u0633\u062A\u0627\u0646", ar: "\u0633\u064A\u0633\u062A\u0627\u0646 \u0648\u0628\u0644\u0648\u0634\u0633\u062A\u0627\u0646", en: "Sistan and Baluchestan" }
35
+ },
36
+ { slug: "fars", iso: "IR-14", labels: { fa: "\u0641\u0627\u0631\u0633", ar: "\u0641\u0627\u0631\u0633", en: "Fars" } },
37
+ { slug: "kerman", iso: "IR-15", labels: { fa: "\u06A9\u0631\u0645\u0627\u0646", ar: "\u0643\u0631\u0645\u0627\u0646", en: "Kerman" } },
38
+ { slug: "kurdistan", iso: "IR-16", labels: { fa: "\u06A9\u0631\u062F\u0633\u062A\u0627\u0646", ar: "\u0643\u0631\u062F\u0633\u062A\u0627\u0646", en: "Kurdistan" } },
39
+ { slug: "kermanshah", iso: "IR-17", labels: { fa: "\u06A9\u0631\u0645\u0627\u0646\u0634\u0627\u0647", ar: "\u0643\u0631\u0645\u0627\u0646\u0634\u0627\u0647", en: "Kermanshah" } },
40
+ {
41
+ slug: "kohgiluyeh-boyer-ahmad",
42
+ iso: "IR-18",
43
+ labels: { fa: "\u06A9\u0647\u06AF\u06CC\u0644\u0648\u06CC\u0647 \u0648 \u0628\u0648\u06CC\u0631\u0627\u062D\u0645\u062F", ar: "\u0643\u0647\u063A\u064A\u0644\u0648\u064A\u0629 \u0648\u0628\u0648\u064A\u0631 \u0623\u062D\u0645\u062F", en: "Kohgiluyeh and Boyer-Ahmad" }
44
+ },
45
+ { slug: "gilan", iso: "IR-19", labels: { fa: "\u06AF\u06CC\u0644\u0627\u0646", ar: "\u062C\u064A\u0644\u0627\u0646", en: "Gilan" } },
46
+ { slug: "lorestan", iso: "IR-20", labels: { fa: "\u0644\u0631\u0633\u062A\u0627\u0646", ar: "\u0644\u0631\u0633\u062A\u0627\u0646", en: "Lorestan" } },
47
+ { slug: "mazandaran", iso: "IR-21", labels: { fa: "\u0645\u0627\u0632\u0646\u062F\u0631\u0627\u0646", ar: "\u0645\u0627\u0632\u0646\u062F\u0631\u0627\u0646", en: "Mazandaran" } },
48
+ { slug: "markazi", iso: "IR-22", labels: { fa: "\u0645\u0631\u06A9\u0632\u06CC", ar: "\u0645\u0631\u0643\u0632\u064A", en: "Markazi" } },
49
+ { slug: "hormozgan", iso: "IR-23", labels: { fa: "\u0647\u0631\u0645\u0632\u06AF\u0627\u0646", ar: "\u0647\u0631\u0645\u0632\u063A\u0627\u0646", en: "Hormozgan" } },
50
+ { slug: "hamadan", iso: "IR-24", labels: { fa: "\u0647\u0645\u062F\u0627\u0646", ar: "\u0647\u0645\u062F\u0627\u0646", en: "Hamadan" } },
51
+ { slug: "yazd", iso: "IR-25", labels: { fa: "\u06CC\u0632\u062F", ar: "\u064A\u0632\u062F", en: "Yazd" } },
52
+ { slug: "qom", iso: "IR-26", labels: { fa: "\u0642\u0645", ar: "\u0642\u0645", en: "Qom" } },
53
+ { slug: "golestan", iso: "IR-27", labels: { fa: "\u06AF\u0644\u0633\u062A\u0627\u0646", ar: "\u063A\u0648\u0644\u0633\u062A\u0627\u0646", en: "Golestan" } },
54
+ { slug: "qazvin", iso: "IR-28", labels: { fa: "\u0642\u0632\u0648\u06CC\u0646", ar: "\u0642\u0632\u0648\u064A\u0646", en: "Qazvin" } },
55
+ { slug: "north-khorasan", iso: "IR-29", labels: { fa: "\u062E\u0631\u0627\u0633\u0627\u0646 \u0634\u0645\u0627\u0644\u06CC", ar: "\u062E\u0631\u0627\u0633\u0627\u0646 \u0627\u0644\u0634\u0645\u0627\u0644\u064A\u0629", en: "North Khorasan" } },
56
+ { slug: "south-khorasan", iso: "IR-30", labels: { fa: "\u062E\u0631\u0627\u0633\u0627\u0646 \u062C\u0646\u0648\u0628\u06CC", ar: "\u062E\u0631\u0627\u0633\u0627\u0646 \u0627\u0644\u062C\u0646\u0648\u0628\u064A\u0629", en: "South Khorasan" } },
57
+ { slug: "alborz", iso: "IR-31", labels: { fa: "\u0627\u0644\u0628\u0631\u0632", ar: "\u0627\u0644\u0628\u0631\u0632", en: "Alborz" } }
58
+ ];
59
+ var SLUG_INDEX = new Map(IRAN_PROVINCES.map((p) => [p.slug, p]));
60
+ var ISO_INDEX = new Map(IRAN_PROVINCES.map((p) => [p.iso, p]));
61
+ function findProvince(codeOrSlug) {
62
+ return SLUG_INDEX.get(codeOrSlug) ?? ISO_INDEX.get(codeOrSlug);
63
+ }
64
+ function getProvinceLabel(codeOrSlug, locale = "fa") {
65
+ const p = findProvince(codeOrSlug);
66
+ if (!p) return codeOrSlug;
67
+ return p.labels[locale] ?? p.labels.fa;
68
+ }
69
+ var SCALE_TO_VAR = {
70
+ brand: "--brand-default",
71
+ "sentiment-positive": "--sentiment-positive",
72
+ "sentiment-negative": "--sentiment-negative",
73
+ destructive: "--destructive-default",
74
+ warning: "--warning-default",
75
+ "severity-urgent": "--severity-urgent",
76
+ "severity-high": "--severity-high",
77
+ "flow-pro-gov": "--flow-pro-gov",
78
+ "flow-internal-critic": "--flow-internal-critic"
79
+ };
80
+ var LOCALE_STRINGS = {
81
+ fa: {
82
+ empty: "\u062F\u0627\u062F\u0647\u200C\u0627\u06CC \u0628\u0631\u0627\u06CC \u0627\u0633\u062A\u0627\u0646\u200C\u0647\u0627 \u062F\u0631 \u062F\u0633\u062A\u0631\u0633 \u0646\u06CC\u0633\u062A.",
83
+ more: (n) => `+${n} \u0627\u0633\u062A\u0627\u0646 \u062F\u06CC\u06AF\u0631`,
84
+ loading: "\u062F\u0631 \u062D\u0627\u0644 \u0628\u0627\u0631\u06AF\u0630\u0627\u0631\u06CC"
85
+ },
86
+ ar: {
87
+ empty: "\u0644\u0627 \u062A\u0648\u062C\u062F \u0628\u064A\u0627\u0646\u0627\u062A \u0644\u0644\u0645\u062D\u0627\u0641\u0638\u0627\u062A.",
88
+ more: (n) => `+${n} \u0645\u062D\u0627\u0641\u0638\u0629 \u0623\u062E\u0631\u0649`,
89
+ loading: "\u062C\u0627\u0631\u064D \u0627\u0644\u062A\u062D\u0645\u064A\u0644"
90
+ },
91
+ en: {
92
+ empty: "No province data available.",
93
+ more: (n) => `+${n} more`,
94
+ loading: "Loading"
95
+ }
96
+ };
97
+ var IranProvinceHeat = React.forwardRef(function IranProvinceHeat2({
98
+ data,
99
+ scale = "brand",
100
+ sort = "value-desc",
101
+ topN = 0,
102
+ showRank = false,
103
+ showValue = true,
104
+ hideMissing = false,
105
+ density = "comfortable",
106
+ valueSuffix,
107
+ valueFormatter,
108
+ onProvinceClick,
109
+ onUnknownCode,
110
+ locale = "fa",
111
+ isLoading = false,
112
+ emptyState,
113
+ className,
114
+ ...divProps
115
+ }, ref) {
116
+ const strings = LOCALE_STRINGS[locale] ?? LOCALE_STRINGS.fa;
117
+ const cssVar = SCALE_TO_VAR[scale];
118
+ const rows = React.useMemo(() => {
119
+ if (isLoading) return [];
120
+ const cells = Array.isArray(data) ? data : Object.entries(data).map(([code, value]) => ({ code, value }));
121
+ const valueByProvinceSlug = /* @__PURE__ */ new Map();
122
+ for (const cell of cells) {
123
+ const province = findProvince(cell.code);
124
+ if (!province) {
125
+ onUnknownCode?.(cell.code);
126
+ continue;
127
+ }
128
+ valueByProvinceSlug.set(province.slug, cell.value);
129
+ }
130
+ const candidates = [];
131
+ for (const province of IRAN_PROVINCES) {
132
+ const value = valueByProvinceSlug.get(province.slug) ?? 0;
133
+ if (hideMissing && value === 0) continue;
134
+ candidates.push({
135
+ slug: province.slug,
136
+ iso: province.iso,
137
+ label: province.labels[locale] ?? province.labels.fa,
138
+ value,
139
+ intensity: 0
140
+ // filled below
141
+ });
142
+ }
143
+ if (candidates.length === 0) return [];
144
+ const max = candidates.reduce((m, r) => Math.max(m, r.value), 0);
145
+ if (max > 0) {
146
+ for (const row of candidates) row.intensity = Math.min(1, Math.max(0, row.value / max));
147
+ }
148
+ if (sort === "value-desc") candidates.sort((a, b) => b.value - a.value);
149
+ else if (sort === "value-asc") candidates.sort((a, b) => a.value - b.value);
150
+ else candidates.sort((a, b) => a.label.localeCompare(b.label, locale === "en" ? "en" : "fa"));
151
+ return candidates;
152
+ }, [data, hideMissing, isLoading, locale, onUnknownCode, sort]);
153
+ const visibleRows = topN > 0 ? rows.slice(0, topN) : rows;
154
+ const hiddenCount = rows.length - visibleRows.length;
155
+ const formatValue = React.useCallback(
156
+ (value) => {
157
+ if (valueFormatter) return valueFormatter(value);
158
+ const base = formatLargeNumber(value, locale);
159
+ return valueSuffix ? `${base}${valueSuffix}` : base;
160
+ },
161
+ [locale, valueFormatter, valueSuffix]
162
+ );
163
+ if (isLoading) {
164
+ return /* @__PURE__ */ jsx(
165
+ "div",
166
+ {
167
+ ref,
168
+ "data-slot": "iran-province-heat",
169
+ "data-state": "loading",
170
+ role: "status",
171
+ "aria-label": strings.loading,
172
+ className: cn("flex flex-col gap-1.5 w-full", className),
173
+ ...divProps,
174
+ children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsxs(
175
+ "div",
176
+ {
177
+ "data-slot": "iran-province-heat-skeleton-row",
178
+ className: cn("flex items-center gap-2 animate-pulse", density === "compact" ? "h-7" : "h-9"),
179
+ children: [
180
+ /* @__PURE__ */ jsx("div", { className: "h-3.5 w-24 rounded bg-overlay-hover" }),
181
+ /* @__PURE__ */ jsx("div", { className: "h-2.5 flex-1 rounded bg-overlay-hover" }),
182
+ /* @__PURE__ */ jsx("div", { className: "h-3.5 w-10 rounded bg-overlay-hover" })
183
+ ]
184
+ },
185
+ i
186
+ ))
187
+ }
188
+ );
189
+ }
190
+ if (rows.length === 0) {
191
+ return /* @__PURE__ */ jsx(
192
+ "div",
193
+ {
194
+ ref,
195
+ "data-slot": "iran-province-heat",
196
+ "data-state": "empty",
197
+ className: cn("flex items-center justify-center text-sm text-foreground-muted py-8", className),
198
+ ...divProps,
199
+ children: emptyState ?? strings.empty
200
+ }
201
+ );
202
+ }
203
+ return /* @__PURE__ */ jsxs(
204
+ "div",
205
+ {
206
+ ref,
207
+ "data-slot": "iran-province-heat",
208
+ "data-density": density,
209
+ "data-scale": scale,
210
+ role: "list",
211
+ className: cn("flex flex-col w-full", density === "compact" ? "gap-0.5" : "gap-1", className),
212
+ ...divProps,
213
+ children: [
214
+ visibleRows.map((row, index) => {
215
+ const isInteractive = !!onProvinceClick;
216
+ const Tag = isInteractive ? "button" : "div";
217
+ const intensity = row.intensity;
218
+ const bgAlpha = 0.08 + intensity * 0.55;
219
+ const widthPct = `${Math.max(2, intensity * 100)}%`;
220
+ return /* @__PURE__ */ jsxs(
221
+ Tag,
222
+ {
223
+ type: isInteractive ? "button" : void 0,
224
+ role: "listitem",
225
+ "data-slot": "iran-province-heat-row",
226
+ "data-province": row.slug,
227
+ "data-iso": row.iso,
228
+ "data-rank": index + 1,
229
+ onClick: isInteractive ? () => onProvinceClick({ slug: row.slug, iso: row.iso, value: row.value }) : void 0,
230
+ className: cn(
231
+ "group relative flex items-center gap-2 rounded-md ps-2 pe-2 text-start transition-colors",
232
+ density === "compact" ? "h-7 text-xs" : "h-9 text-sm",
233
+ isInteractive && "hover:bg-overlay-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand",
234
+ !isInteractive && "cursor-default"
235
+ ),
236
+ "aria-label": `${row.label}: ${formatValue(row.value)}`,
237
+ children: [
238
+ /* @__PURE__ */ jsx(
239
+ "div",
240
+ {
241
+ "data-slot": "iran-province-heat-bar",
242
+ "aria-hidden": "true",
243
+ className: "absolute inset-y-0 inset-inline-start-0 rounded-md transition-[width] duration-300",
244
+ style: {
245
+ width: widthPct,
246
+ backgroundColor: `hsl(var(${cssVar}) / ${bgAlpha.toFixed(3)})`
247
+ }
248
+ }
249
+ ),
250
+ showRank && /* @__PURE__ */ jsx(
251
+ "span",
252
+ {
253
+ "data-slot": "iran-province-heat-rank",
254
+ className: "relative z-[1] inline-flex h-5 min-w-5 items-center justify-center rounded bg-background-default px-1 text-[10px] font-medium tabular-nums text-foreground-light",
255
+ children: convertToLocalNumbers(index + 1, locale)
256
+ }
257
+ ),
258
+ /* @__PURE__ */ jsx(
259
+ "span",
260
+ {
261
+ "data-slot": "iran-province-heat-label",
262
+ className: "relative z-[1] flex-1 truncate font-medium text-foreground",
263
+ children: row.label
264
+ }
265
+ ),
266
+ showValue && /* @__PURE__ */ jsx("span", { "data-slot": "iran-province-heat-value", className: "relative z-[1] tabular-nums text-foreground-light", children: formatValue(row.value) })
267
+ ]
268
+ },
269
+ row.slug
270
+ );
271
+ }),
272
+ hiddenCount > 0 && /* @__PURE__ */ jsx(
273
+ "div",
274
+ {
275
+ "data-slot": "iran-province-heat-overflow",
276
+ className: cn(
277
+ "flex items-center justify-center rounded-md text-foreground-muted",
278
+ density === "compact" ? "h-7 text-[11px]" : "h-9 text-xs"
279
+ ),
280
+ children: strings.more(convertToLocalNumbers(hiddenCount, locale))
281
+ }
282
+ )
283
+ ]
284
+ }
285
+ );
286
+ });
287
+ IranProvinceHeat.displayName = "IranProvinceHeat";
288
+
289
+ export { IRAN_PROVINCES, IranProvinceHeat, findProvince, getProvinceLabel };
290
+ //# sourceMappingURL=chunk-L2L5CKC2.js.map
291
+ //# sourceMappingURL=chunk-L2L5CKC2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/iran-provinces.ts","../src/components/ui/iran-province-heat.tsx"],"names":["IranProvinceHeat"],"mappings":"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","file":"chunk-L2L5CKC2.js","sourcesContent":["/**\n * Iran's 31 provinces with trilingual labels and ISO 3166-2 codes.\n *\n * Use as a stable identifier source for `IranProvinceHeat`, `RegionPicker`,\n * and any public-opinion dashboard scoped by استان. The slug (`code`) is the\n * canonical key — never rely on label string equality, since labels are\n * locale-dependent and may evolve.\n *\n * Codes follow ISO 3166-2:IR (e.g. 'IR-07' for Tehran). The slug is the\n * lowercased, hyphenated English name without diacritics, suitable for URLs\n * and CSS selectors. Use `getProvinceLabel(code, locale)` to resolve a label.\n */\n\nimport type { SupportedLocale } from './utils'\n\nexport interface IranProvince {\n /** Stable URL-safe slug. The canonical key for province lookups. */\n slug: string\n /** ISO 3166-2:IR code (e.g. 'IR-07'). */\n iso: string\n /** Trilingual labels — fa is the canonical/native form. */\n labels: Record<SupportedLocale, string>\n}\n\nexport const IRAN_PROVINCES: readonly IranProvince[] = [\n {\n slug: 'east-azerbaijan',\n iso: 'IR-01',\n labels: { fa: 'آذربایجان شرقی', ar: 'أذربيجان الشرقية', en: 'East Azerbaijan' },\n },\n {\n slug: 'west-azerbaijan',\n iso: 'IR-02',\n labels: { fa: 'آذربایجان غربی', ar: 'أذربيجان الغربية', en: 'West Azerbaijan' },\n },\n { slug: 'ardabil', iso: 'IR-03', labels: { fa: 'اردبیل', ar: 'أردبيل', en: 'Ardabil' } },\n { slug: 'isfahan', iso: 'IR-04', labels: { fa: 'اصفهان', ar: 'أصفهان', en: 'Isfahan' } },\n { slug: 'ilam', iso: 'IR-05', labels: { fa: 'ایلام', ar: 'إيلام', en: 'Ilam' } },\n { slug: 'bushehr', iso: 'IR-06', labels: { fa: 'بوشهر', ar: 'بوشهر', en: 'Bushehr' } },\n { slug: 'tehran', iso: 'IR-07', labels: { fa: 'تهران', ar: 'طهران', en: 'Tehran' } },\n {\n slug: 'chaharmahal-bakhtiari',\n iso: 'IR-08',\n labels: { fa: 'چهارمحال و بختیاری', ar: 'تشهارمحال وبختياري', en: 'Chaharmahal and Bakhtiari' },\n },\n { slug: 'razavi-khorasan', iso: 'IR-09', labels: { fa: 'خراسان رضوی', ar: 'خراسان رضوي', en: 'Razavi Khorasan' } },\n { slug: 'khuzestan', iso: 'IR-10', labels: { fa: 'خوزستان', ar: 'خوزستان', en: 'Khuzestan' } },\n { slug: 'zanjan', iso: 'IR-11', labels: { fa: 'زنجان', ar: 'زنجان', en: 'Zanjan' } },\n { slug: 'semnan', iso: 'IR-12', labels: { fa: 'سمنان', ar: 'سمنان', en: 'Semnan' } },\n {\n slug: 'sistan-baluchestan',\n iso: 'IR-13',\n labels: { fa: 'سیستان و بلوچستان', ar: 'سيستان وبلوشستان', en: 'Sistan and Baluchestan' },\n },\n { slug: 'fars', iso: 'IR-14', labels: { fa: 'فارس', ar: 'فارس', en: 'Fars' } },\n { slug: 'kerman', iso: 'IR-15', labels: { fa: 'کرمان', ar: 'كرمان', en: 'Kerman' } },\n { slug: 'kurdistan', iso: 'IR-16', labels: { fa: 'کردستان', ar: 'كردستان', en: 'Kurdistan' } },\n { slug: 'kermanshah', iso: 'IR-17', labels: { fa: 'کرمانشاه', ar: 'كرمانشاه', en: 'Kermanshah' } },\n {\n slug: 'kohgiluyeh-boyer-ahmad',\n iso: 'IR-18',\n labels: { fa: 'کهگیلویه و بویراحمد', ar: 'كهغيلوية وبوير أحمد', en: 'Kohgiluyeh and Boyer-Ahmad' },\n },\n { slug: 'gilan', iso: 'IR-19', labels: { fa: 'گیلان', ar: 'جيلان', en: 'Gilan' } },\n { slug: 'lorestan', iso: 'IR-20', labels: { fa: 'لرستان', ar: 'لرستان', en: 'Lorestan' } },\n { slug: 'mazandaran', iso: 'IR-21', labels: { fa: 'مازندران', ar: 'مازندران', en: 'Mazandaran' } },\n { slug: 'markazi', iso: 'IR-22', labels: { fa: 'مرکزی', ar: 'مركزي', en: 'Markazi' } },\n { slug: 'hormozgan', iso: 'IR-23', labels: { fa: 'هرمزگان', ar: 'هرمزغان', en: 'Hormozgan' } },\n { slug: 'hamadan', iso: 'IR-24', labels: { fa: 'همدان', ar: 'همدان', en: 'Hamadan' } },\n { slug: 'yazd', iso: 'IR-25', labels: { fa: 'یزد', ar: 'يزد', en: 'Yazd' } },\n { slug: 'qom', iso: 'IR-26', labels: { fa: 'قم', ar: 'قم', en: 'Qom' } },\n { slug: 'golestan', iso: 'IR-27', labels: { fa: 'گلستان', ar: 'غولستان', en: 'Golestan' } },\n { slug: 'qazvin', iso: 'IR-28', labels: { fa: 'قزوین', ar: 'قزوين', en: 'Qazvin' } },\n { slug: 'north-khorasan', iso: 'IR-29', labels: { fa: 'خراسان شمالی', ar: 'خراسان الشمالية', en: 'North Khorasan' } },\n { slug: 'south-khorasan', iso: 'IR-30', labels: { fa: 'خراسان جنوبی', ar: 'خراسان الجنوبية', en: 'South Khorasan' } },\n { slug: 'alborz', iso: 'IR-31', labels: { fa: 'البرز', ar: 'البرز', en: 'Alborz' } },\n] as const\n\nexport type IranProvinceSlug = (typeof IRAN_PROVINCES)[number]['slug']\n\nconst SLUG_INDEX = new Map(IRAN_PROVINCES.map((p) => [p.slug, p]))\nconst ISO_INDEX = new Map(IRAN_PROVINCES.map((p) => [p.iso, p]))\n\n/** Look up a province by slug or ISO code. Returns undefined for unknown codes. */\nexport function findProvince(codeOrSlug: string): IranProvince | undefined {\n return SLUG_INDEX.get(codeOrSlug) ?? ISO_INDEX.get(codeOrSlug)\n}\n\n/**\n * Resolve the locale-appropriate label for a province slug or ISO code.\n * Falls back to fa for unknown locales and to the slug itself for unknown\n * provinces (so the row still renders something instead of crashing).\n */\nexport function getProvinceLabel(codeOrSlug: string, locale: SupportedLocale = 'fa'): string {\n const p = findProvince(codeOrSlug)\n if (!p) return codeOrSlug\n return p.labels[locale] ?? p.labels.fa\n}\n","'use client'\n\nimport * as React from 'react'\nimport { cn, convertToLocalNumbers, formatLargeNumber, type SupportedLocale } from '@/lib/utils'\nimport { findProvince, IRAN_PROVINCES } from '@/lib/iran-provinces'\n\n/* -------------------------------------------------------------------------- */\n/* Types */\n/* -------------------------------------------------------------------------- */\n\nexport interface IranProvinceCell {\n /** Province slug or ISO 3166-2:IR code (e.g. 'tehran' or 'IR-07'). */\n code: string\n /** Numeric value to compare across provinces (count, score, percentage…). */\n value: number\n}\n\nexport type IranProvinceHeatScale =\n | 'brand'\n | 'sentiment-positive'\n | 'sentiment-negative'\n | 'destructive'\n | 'warning'\n | 'severity-urgent'\n | 'severity-high'\n | 'flow-pro-gov'\n | 'flow-internal-critic'\n\nexport interface IranProvinceHeatProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * Either an array of `{code, value}` cells, or a record map. Provinces not\n * in the dataset render with value 0 unless `hideMissing` is true. Cells\n * with unknown codes are skipped (and warned via `onUnknownCode` if set).\n */\n data: IranProvinceCell[] | Record<string, number>\n /**\n * Color token to use for the heat bars. Bars within the dataset are tinted\n * with progressively higher alpha based on `value / max`.\n * @default 'brand'\n */\n scale?: IranProvinceHeatScale\n /** Sort order for the rows. @default 'value-desc' */\n sort?: 'value-desc' | 'value-asc' | 'name'\n /**\n * Show only top-N rows (after sorting). When set, a \"+N more\" row collapses\n * the rest. Use 0 to show all 31 — that's the default.\n */\n topN?: number\n /** Display rank (۱، ۲، ۳، …) at the start of each row. @default false */\n showRank?: boolean\n /** Inline numeric value on each row. @default true */\n showValue?: boolean\n /** Hide rows with value 0 (or missing from dataset). @default false */\n hideMissing?: boolean\n /** Compact rows (28px) vs comfortable (36px). @default 'comfortable' */\n density?: 'compact' | 'comfortable'\n /**\n * Suffix on the inline value (e.g. ' نظر', ' %').\n * Useful when consumers don't want to write a custom valueFormatter.\n */\n valueSuffix?: string\n /** Custom value formatter; overrides the locale-aware default. */\n valueFormatter?: (value: number) => string\n /** Click handler — receives slug + ISO + value. Optional. */\n onProvinceClick?: (province: { slug: string; iso: string; value: number }) => void\n /** Called once per unknown code in `data`, useful for telemetry. */\n onUnknownCode?: (code: string) => void\n /** Locale for labels + digit formatting. @default 'fa' */\n locale?: SupportedLocale\n /** Loading skeleton while data fetches. */\n isLoading?: boolean\n /** Empty-state node when `data` is empty (or all-zero with hideMissing). */\n emptyState?: React.ReactNode\n}\n\n/* -------------------------------------------------------------------------- */\n/* Token mapping */\n/* -------------------------------------------------------------------------- */\n\nconst SCALE_TO_VAR: Record<IranProvinceHeatScale, string> = {\n brand: '--brand-default',\n 'sentiment-positive': '--sentiment-positive',\n 'sentiment-negative': '--sentiment-negative',\n destructive: '--destructive-default',\n warning: '--warning-default',\n 'severity-urgent': '--severity-urgent',\n 'severity-high': '--severity-high',\n 'flow-pro-gov': '--flow-pro-gov',\n 'flow-internal-critic': '--flow-internal-critic',\n}\n\nconst LOCALE_STRINGS: Record<SupportedLocale, { empty: string; more: (n: string) => string; loading: string }> = {\n fa: {\n empty: 'داده‌ای برای استان‌ها در دسترس نیست.',\n more: (n) => `+${n} استان دیگر`,\n loading: 'در حال بارگذاری',\n },\n ar: {\n empty: 'لا توجد بيانات للمحافظات.',\n more: (n) => `+${n} محافظة أخرى`,\n loading: 'جارٍ التحميل',\n },\n en: {\n empty: 'No province data available.',\n more: (n) => `+${n} more`,\n loading: 'Loading',\n },\n}\n\n/* -------------------------------------------------------------------------- */\n/* Component */\n/* -------------------------------------------------------------------------- */\n\ninterface ResolvedRow {\n slug: string\n iso: string\n label: string\n value: number\n intensity: number\n}\n\nconst IranProvinceHeat = React.forwardRef<HTMLDivElement, IranProvinceHeatProps>(function IranProvinceHeat(\n {\n data,\n scale = 'brand',\n sort = 'value-desc',\n topN = 0,\n showRank = false,\n showValue = true,\n hideMissing = false,\n density = 'comfortable',\n valueSuffix,\n valueFormatter,\n onProvinceClick,\n onUnknownCode,\n locale = 'fa',\n isLoading = false,\n emptyState,\n className,\n ...divProps\n },\n ref\n) {\n const strings = LOCALE_STRINGS[locale] ?? LOCALE_STRINGS.fa\n const cssVar = SCALE_TO_VAR[scale]\n\n const rows = React.useMemo<ResolvedRow[]>(() => {\n if (isLoading) return []\n\n const cells = Array.isArray(data) ? data : Object.entries(data).map(([code, value]) => ({ code, value }))\n\n // Resolve provinces, drop unknown (with optional callback for telemetry)\n const valueByProvinceSlug = new Map<string, number>()\n for (const cell of cells) {\n const province = findProvince(cell.code)\n if (!province) {\n onUnknownCode?.(cell.code)\n continue\n }\n // If duplicates exist for the same province, the later one wins —\n // consumers normalize upstream if needed.\n valueByProvinceSlug.set(province.slug, cell.value)\n }\n\n // Build rows for ALL 31 provinces unless hideMissing\n const candidates: ResolvedRow[] = []\n for (const province of IRAN_PROVINCES) {\n const value = valueByProvinceSlug.get(province.slug) ?? 0\n if (hideMissing && value === 0) continue\n candidates.push({\n slug: province.slug,\n iso: province.iso,\n label: province.labels[locale] ?? province.labels.fa,\n value,\n intensity: 0, // filled below\n })\n }\n\n if (candidates.length === 0) return []\n\n // Compute intensity = value / max (clamped to [0,1]); when all zero, all intensities are 0\n const max = candidates.reduce((m, r) => Math.max(m, r.value), 0)\n if (max > 0) {\n for (const row of candidates) row.intensity = Math.min(1, Math.max(0, row.value / max))\n }\n\n // Sort\n if (sort === 'value-desc') candidates.sort((a, b) => b.value - a.value)\n else if (sort === 'value-asc') candidates.sort((a, b) => a.value - b.value)\n else candidates.sort((a, b) => a.label.localeCompare(b.label, locale === 'en' ? 'en' : 'fa'))\n\n return candidates\n }, [data, hideMissing, isLoading, locale, onUnknownCode, sort])\n\n const visibleRows = topN > 0 ? rows.slice(0, topN) : rows\n const hiddenCount = rows.length - visibleRows.length\n\n const formatValue = React.useCallback(\n (value: number) => {\n if (valueFormatter) return valueFormatter(value)\n const base = formatLargeNumber(value, locale)\n return valueSuffix ? `${base}${valueSuffix}` : base\n },\n [locale, valueFormatter, valueSuffix]\n )\n\n /* --------------------------------- Render -------------------------------- */\n\n if (isLoading) {\n return (\n <div\n ref={ref}\n data-slot=\"iran-province-heat\"\n data-state=\"loading\"\n role=\"status\"\n aria-label={strings.loading}\n className={cn('flex flex-col gap-1.5 w-full', className)}\n {...divProps}\n >\n {Array.from({ length: 6 }).map((_, i) => (\n <div\n key={i}\n data-slot=\"iran-province-heat-skeleton-row\"\n className={cn('flex items-center gap-2 animate-pulse', density === 'compact' ? 'h-7' : 'h-9')}\n >\n <div className=\"h-3.5 w-24 rounded bg-overlay-hover\" />\n <div className=\"h-2.5 flex-1 rounded bg-overlay-hover\" />\n <div className=\"h-3.5 w-10 rounded bg-overlay-hover\" />\n </div>\n ))}\n </div>\n )\n }\n\n if (rows.length === 0) {\n return (\n <div\n ref={ref}\n data-slot=\"iran-province-heat\"\n data-state=\"empty\"\n className={cn('flex items-center justify-center text-sm text-foreground-muted py-8', className)}\n {...divProps}\n >\n {emptyState ?? strings.empty}\n </div>\n )\n }\n\n return (\n <div\n ref={ref}\n data-slot=\"iran-province-heat\"\n data-density={density}\n data-scale={scale}\n role=\"list\"\n className={cn('flex flex-col w-full', density === 'compact' ? 'gap-0.5' : 'gap-1', className)}\n {...divProps}\n >\n {visibleRows.map((row, index) => {\n const isInteractive = !!onProvinceClick\n const Tag = isInteractive ? 'button' : 'div'\n const intensity = row.intensity\n // The bar background scales alpha from 0.1 to 0.9; the bar itself\n // uses the full token color for a consistent darkest-shade signal.\n const bgAlpha = 0.08 + intensity * 0.55\n const widthPct = `${Math.max(2, intensity * 100)}%` // min 2% so a rendered row is visible\n\n return (\n <Tag\n key={row.slug}\n type={isInteractive ? 'button' : undefined}\n role=\"listitem\"\n data-slot=\"iran-province-heat-row\"\n data-province={row.slug}\n data-iso={row.iso}\n data-rank={index + 1}\n onClick={\n isInteractive ? () => onProvinceClick({ slug: row.slug, iso: row.iso, value: row.value }) : undefined\n }\n className={cn(\n 'group relative flex items-center gap-2 rounded-md ps-2 pe-2 text-start transition-colors',\n density === 'compact' ? 'h-7 text-xs' : 'h-9 text-sm',\n isInteractive &&\n 'hover:bg-overlay-hover focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand',\n !isInteractive && 'cursor-default'\n )}\n aria-label={`${row.label}: ${formatValue(row.value)}`}\n >\n {/* Heat bar — sits behind text, fills logical-start to right */}\n <div\n data-slot=\"iran-province-heat-bar\"\n aria-hidden=\"true\"\n className=\"absolute inset-y-0 inset-inline-start-0 rounded-md transition-[width] duration-300\"\n style={{\n width: widthPct,\n backgroundColor: `hsl(var(${cssVar}) / ${bgAlpha.toFixed(3)})`,\n }}\n />\n\n {/* Foreground content */}\n {showRank && (\n <span\n data-slot=\"iran-province-heat-rank\"\n className=\"relative z-[1] inline-flex h-5 min-w-5 items-center justify-center rounded bg-background-default px-1 text-[10px] font-medium tabular-nums text-foreground-light\"\n >\n {convertToLocalNumbers(index + 1, locale)}\n </span>\n )}\n\n <span\n data-slot=\"iran-province-heat-label\"\n className=\"relative z-[1] flex-1 truncate font-medium text-foreground\"\n >\n {row.label}\n </span>\n\n {showValue && (\n <span data-slot=\"iran-province-heat-value\" className=\"relative z-[1] tabular-nums text-foreground-light\">\n {formatValue(row.value)}\n </span>\n )}\n </Tag>\n )\n })}\n\n {hiddenCount > 0 && (\n <div\n data-slot=\"iran-province-heat-overflow\"\n className={cn(\n 'flex items-center justify-center rounded-md text-foreground-muted',\n density === 'compact' ? 'h-7 text-[11px]' : 'h-9 text-xs'\n )}\n >\n {strings.more(convertToLocalNumbers(hiddenCount, locale))}\n </div>\n )}\n </div>\n )\n})\n\nIranProvinceHeat.displayName = 'IranProvinceHeat'\n\nexport { IranProvinceHeat }\n"]}
@@ -0,0 +1,135 @@
1
+ import { useChartTheme, localeAwareCategoryTick, localeAwareNumberTick, ChartLoadingSkeleton, ChartContainer, ChartTooltip } from './chunk-IQHKJ4SS.js';
2
+ import * as React from 'react';
3
+ import { ResponsiveContainer, BarChart, CartesianGrid, XAxis, YAxis, Tooltip, Bar } from 'recharts';
4
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
+
6
+ var PartoBarChart = React.forwardRef(function PartoBarChart2({
7
+ data,
8
+ keys,
9
+ indexBy,
10
+ groupMode = "grouped",
11
+ layout = "vertical",
12
+ margin = { top: 20, right: 20, bottom: 50, left: 50 },
13
+ barCategoryGap = "35%",
14
+ barGap = 2,
15
+ radius = [6, 6, 0, 0],
16
+ enableGridY = true,
17
+ enableGridX = false,
18
+ enableLabel = false,
19
+ axisBottom,
20
+ axisLeft,
21
+ tooltipFormatter,
22
+ locale = "fa",
23
+ className,
24
+ isLoading = false,
25
+ ariaLabel,
26
+ chartProps
27
+ }, ref) {
28
+ const { chartColors, axisTickStyle, gridStyle, tooltipStyle } = useChartTheme();
29
+ const categoryTick = React.useMemo(() => localeAwareCategoryTick(locale), [locale]);
30
+ const numberTick = React.useMemo(() => localeAwareNumberTick(locale), [locale]);
31
+ if (isLoading) {
32
+ return /* @__PURE__ */ jsx(ChartLoadingSkeleton, { className });
33
+ }
34
+ const rechartsLayout = layout === "horizontal" ? "vertical" : "horizontal";
35
+ const stackId = groupMode === "stacked" ? "stack" : void 0;
36
+ return /* @__PURE__ */ jsx(ChartContainer, { ref, className, dataSlot: "bar-chart", ariaLabel, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(
37
+ BarChart,
38
+ {
39
+ data,
40
+ layout: rechartsLayout,
41
+ margin,
42
+ barCategoryGap,
43
+ barGap,
44
+ ...chartProps,
45
+ children: [
46
+ (enableGridX || enableGridY) && /* @__PURE__ */ jsx(
47
+ CartesianGrid,
48
+ {
49
+ horizontal: enableGridY,
50
+ vertical: enableGridX,
51
+ stroke: gridStyle.stroke,
52
+ strokeDasharray: gridStyle.strokeDasharray,
53
+ strokeOpacity: gridStyle.strokeOpacity
54
+ }
55
+ ),
56
+ rechartsLayout === "horizontal" ? /* @__PURE__ */ jsxs(Fragment, { children: [
57
+ axisBottom !== null && /* @__PURE__ */ jsx(
58
+ XAxis,
59
+ {
60
+ dataKey: indexBy,
61
+ tick: axisTickStyle,
62
+ tickLine: false,
63
+ axisLine: false,
64
+ tickMargin: 12,
65
+ tickFormatter: categoryTick,
66
+ ...axisBottom
67
+ }
68
+ ),
69
+ axisLeft !== null && /* @__PURE__ */ jsx(
70
+ YAxis,
71
+ {
72
+ tick: axisTickStyle,
73
+ tickLine: false,
74
+ axisLine: false,
75
+ tickMargin: 12,
76
+ tickFormatter: numberTick,
77
+ ...axisLeft
78
+ }
79
+ )
80
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
81
+ axisLeft !== null && /* @__PURE__ */ jsx(
82
+ YAxis,
83
+ {
84
+ dataKey: indexBy,
85
+ type: "category",
86
+ tick: axisTickStyle,
87
+ tickLine: false,
88
+ axisLine: false,
89
+ tickMargin: 12,
90
+ tickFormatter: categoryTick,
91
+ ...axisLeft
92
+ }
93
+ ),
94
+ axisBottom !== null && /* @__PURE__ */ jsx(
95
+ XAxis,
96
+ {
97
+ type: "number",
98
+ tick: axisTickStyle,
99
+ tickLine: false,
100
+ axisLine: false,
101
+ tickMargin: 12,
102
+ tickFormatter: numberTick,
103
+ ...axisBottom
104
+ }
105
+ )
106
+ ] }),
107
+ /* @__PURE__ */ jsx(
108
+ Tooltip,
109
+ {
110
+ cursor: { fill: "hsl(0 0% 50% / 0.05)" },
111
+ content: /* @__PURE__ */ jsx(ChartTooltip, { tooltipStyle, formatter: tooltipFormatter, locale })
112
+ }
113
+ ),
114
+ keys.map((key, i) => /* @__PURE__ */ jsx(
115
+ Bar,
116
+ {
117
+ dataKey: key,
118
+ fill: chartColors[i % chartColors.length],
119
+ radius,
120
+ stackId,
121
+ label: enableLabel ? { position: "top", style: axisTickStyle } : false,
122
+ animationDuration: 800,
123
+ animationEasing: "ease-out"
124
+ },
125
+ key
126
+ ))
127
+ ]
128
+ }
129
+ ) }) });
130
+ });
131
+ PartoBarChart.displayName = "PartoBarChart";
132
+
133
+ export { PartoBarChart };
134
+ //# sourceMappingURL=chunk-LLJR7FV3.js.map
135
+ //# sourceMappingURL=chunk-LLJR7FV3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/charts/PartoBarChart.tsx"],"names":["PartoBarChart"],"mappings":"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","file":"chunk-LLJR7FV3.js","sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts'\n\nimport { useChartTheme } from '@/hooks/use-chart-theme'\nimport { type SupportedLocale } from '@/lib/utils'\nimport {\n ChartContainer,\n ChartLoadingSkeleton,\n ChartTooltip,\n localeAwareCategoryTick,\n localeAwareNumberTick,\n} from './chart-utils'\n\nexport interface PartoBarChartProps {\n /** Chart data — row-oriented array of objects */\n data: Array<Record<string, any>>\n /** Data keys to render as bars (e.g. ['فروش', 'هزینه']) */\n keys: string[]\n /** Field name used for X axis categories (e.g. 'ماه') */\n indexBy: string\n /** Stacked or grouped layout */\n groupMode?: 'grouped' | 'stacked'\n /** Bar layout direction */\n layout?: 'vertical' | 'horizontal'\n /** Chart margins */\n margin?: { top?: number; right?: number; bottom?: number; left?: number }\n /** Gap between category groups as percentage */\n barCategoryGap?: string | number\n /** Gap between bars within a group */\n barGap?: number\n /** Border radius for bar tops [topLeft, topRight, bottomRight, bottomLeft] */\n radius?: [number, number, number, number]\n /** Show horizontal grid lines */\n enableGridY?: boolean\n /** Show vertical grid lines */\n enableGridX?: boolean\n /** Show labels inside bars */\n enableLabel?: boolean\n /** Custom X axis config */\n axisBottom?: Record<string, any> | null\n /** Custom Y axis config */\n axisLeft?: Record<string, any> | null\n /** Custom tooltip formatter */\n tooltipFormatter?: (name: string, value: number) => React.ReactNode\n /**\n * Locale for digit formatting in tooltips and axis ticks. fa/ar render\n * Persian/Arabic digits with locale suffixes; en uses Latin K/M/B.\n * Default: 'fa'.\n */\n locale?: SupportedLocale\n className?: string\n isLoading?: boolean\n ariaLabel?: string\n /** Additional Recharts BarChart props */\n chartProps?: Record<string, any>\n}\n\nexport const PartoBarChart = React.forwardRef<HTMLDivElement, PartoBarChartProps>(function PartoBarChart(\n {\n data,\n keys,\n indexBy,\n groupMode = 'grouped',\n layout = 'vertical',\n margin = { top: 20, right: 20, bottom: 50, left: 50 },\n barCategoryGap = '35%',\n barGap = 2,\n radius = [6, 6, 0, 0],\n enableGridY = true,\n enableGridX = false,\n enableLabel = false,\n axisBottom,\n axisLeft,\n tooltipFormatter,\n locale = 'fa',\n className,\n isLoading = false,\n ariaLabel,\n chartProps,\n },\n ref\n) {\n const { chartColors, axisTickStyle, gridStyle, tooltipStyle } = useChartTheme()\n const categoryTick = React.useMemo(() => localeAwareCategoryTick(locale), [locale])\n const numberTick = React.useMemo(() => localeAwareNumberTick(locale), [locale])\n\n if (isLoading) {\n return <ChartLoadingSkeleton className={className} />\n }\n\n // Recharts uses \"horizontal\" for standard vertical bars and \"vertical\" for horizontal bars\n const rechartsLayout = layout === 'horizontal' ? 'vertical' : 'horizontal'\n const stackId = groupMode === 'stacked' ? 'stack' : undefined\n\n return (\n <ChartContainer ref={ref} className={className} dataSlot=\"bar-chart\" ariaLabel={ariaLabel}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <BarChart\n data={data}\n layout={rechartsLayout}\n margin={margin}\n barCategoryGap={barCategoryGap}\n barGap={barGap}\n {...chartProps}\n >\n {(enableGridX || enableGridY) && (\n <CartesianGrid\n horizontal={enableGridY}\n vertical={enableGridX}\n stroke={gridStyle.stroke}\n strokeDasharray={gridStyle.strokeDasharray}\n strokeOpacity={gridStyle.strokeOpacity}\n />\n )}\n\n {rechartsLayout === 'horizontal' ? (\n <>\n {axisBottom !== null && (\n <XAxis\n dataKey={indexBy}\n tick={axisTickStyle}\n tickLine={false}\n axisLine={false}\n tickMargin={12}\n tickFormatter={categoryTick}\n {...axisBottom}\n />\n )}\n {axisLeft !== null && (\n <YAxis\n tick={axisTickStyle}\n tickLine={false}\n axisLine={false}\n tickMargin={12}\n tickFormatter={numberTick}\n {...axisLeft}\n />\n )}\n </>\n ) : (\n <>\n {axisLeft !== null && (\n <YAxis\n dataKey={indexBy}\n type=\"category\"\n tick={axisTickStyle}\n tickLine={false}\n axisLine={false}\n tickMargin={12}\n tickFormatter={categoryTick}\n {...axisLeft}\n />\n )}\n {axisBottom !== null && (\n <XAxis\n type=\"number\"\n tick={axisTickStyle}\n tickLine={false}\n axisLine={false}\n tickMargin={12}\n tickFormatter={numberTick}\n {...axisBottom}\n />\n )}\n </>\n )}\n\n <Tooltip\n cursor={{ fill: 'hsl(0 0% 50% / 0.05)' }}\n content={<ChartTooltip tooltipStyle={tooltipStyle} formatter={tooltipFormatter} locale={locale} />}\n />\n\n {keys.map((key, i) => (\n <Bar\n key={key}\n dataKey={key}\n fill={chartColors[i % chartColors.length]}\n radius={radius}\n stackId={stackId}\n label={enableLabel ? { position: 'top', style: axisTickStyle } : false}\n animationDuration={800}\n animationEasing=\"ease-out\"\n />\n ))}\n </BarChart>\n </ResponsiveContainer>\n </ChartContainer>\n )\n})\nPartoBarChart.displayName = 'PartoBarChart'\n"]}
@@ -0,0 +1,118 @@
1
+ import { useChartTheme, ChartLoadingSkeleton, ChartContainer, ChartTooltip, CHART_FONT_FAMILY } from './chunk-IQHKJ4SS.js';
2
+ import * as React from 'react';
3
+ import { ResponsiveContainer, PieChart, Pie, Cell, Tooltip, Sector } from 'recharts';
4
+ import { jsx, jsxs } from 'react/jsx-runtime';
5
+
6
+ function renderActiveShape(props) {
7
+ const { cx, cy, innerRadius, outerRadius, startAngle, endAngle, fill, cornerRadius } = props;
8
+ return /* @__PURE__ */ jsx(
9
+ Sector,
10
+ {
11
+ cx,
12
+ cy,
13
+ innerRadius: innerRadius - 3,
14
+ outerRadius: outerRadius + 5,
15
+ startAngle,
16
+ endAngle,
17
+ fill,
18
+ cornerRadius,
19
+ forceCornerRadius: true
20
+ }
21
+ );
22
+ }
23
+ function renderArcLinkLabel(props, labelSkipAngle, textColor) {
24
+ const { cx, cy, midAngle, outerRadius, name, percent } = props;
25
+ const angle = percent * 360;
26
+ if (angle < labelSkipAngle) return null;
27
+ const RADIAN = Math.PI / 180;
28
+ const sin = Math.sin(-RADIAN * midAngle);
29
+ const cos = Math.cos(-RADIAN * midAngle);
30
+ const arcX = cx + (outerRadius + 4) * cos;
31
+ const arcY = cy + (outerRadius + 4) * sin;
32
+ const diagLen = 10;
33
+ const diagX = arcX + diagLen * cos;
34
+ const diagY = arcY + diagLen * sin;
35
+ const straightLen = 14;
36
+ const endX = diagX + (cos >= 0 ? straightLen : -straightLen);
37
+ const endY = diagY;
38
+ const textAnchor = cos >= 0 ? "start" : "end";
39
+ const textX = endX + (cos >= 0 ? 4 : -4);
40
+ return /* @__PURE__ */ jsxs("g", { children: [
41
+ /* @__PURE__ */ jsx(
42
+ "path",
43
+ {
44
+ d: `M ${arcX},${arcY} L ${diagX},${diagY} L ${endX},${endY}`,
45
+ fill: "none",
46
+ stroke: textColor,
47
+ strokeWidth: 1,
48
+ strokeOpacity: 0.4
49
+ }
50
+ ),
51
+ /* @__PURE__ */ jsx(
52
+ "text",
53
+ {
54
+ x: textX,
55
+ y: endY,
56
+ textAnchor,
57
+ dominantBaseline: "central",
58
+ fill: textColor,
59
+ fontFamily: CHART_FONT_FAMILY,
60
+ fontSize: 11,
61
+ children: name
62
+ }
63
+ )
64
+ ] });
65
+ }
66
+ var PartoPieChart = React.forwardRef(function PartoPieChart2({
67
+ data,
68
+ innerRadius = "60%",
69
+ outerRadius = "80%",
70
+ paddingAngle = 1.2,
71
+ cornerRadius = 4,
72
+ showLabels = true,
73
+ labelSkipAngle = 14,
74
+ margin = { top: 20, right: 20, bottom: 20, left: 20 },
75
+ tooltipFormatter,
76
+ locale = "fa",
77
+ className,
78
+ isLoading = false,
79
+ ariaLabel
80
+ }, ref) {
81
+ const { chartColors, tooltipStyle, axisTickStyle } = useChartTheme();
82
+ if (isLoading) {
83
+ return /* @__PURE__ */ jsx(ChartLoadingSkeleton, { className, shape: "circle" });
84
+ }
85
+ return /* @__PURE__ */ jsx(ChartContainer, { ref, className, dataSlot: "pie-chart", ariaLabel, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(PieChart, { margin, children: [
86
+ /* @__PURE__ */ jsx(
87
+ Pie,
88
+ {
89
+ data,
90
+ dataKey: "value",
91
+ nameKey: "name",
92
+ cx: "50%",
93
+ cy: "50%",
94
+ innerRadius,
95
+ outerRadius,
96
+ paddingAngle,
97
+ cornerRadius,
98
+ activeShape: renderActiveShape,
99
+ label: showLabels ? (props) => renderArcLinkLabel(props, labelSkipAngle, axisTickStyle.fill) : false,
100
+ labelLine: false,
101
+ animationDuration: 800,
102
+ animationEasing: "ease-out",
103
+ children: data.map((_, i) => /* @__PURE__ */ jsx(Cell, { fill: chartColors[i % chartColors.length], stroke: "none" }, i))
104
+ }
105
+ ),
106
+ /* @__PURE__ */ jsx(
107
+ Tooltip,
108
+ {
109
+ content: /* @__PURE__ */ jsx(ChartTooltip, { tooltipStyle, formatter: tooltipFormatter, locale })
110
+ }
111
+ )
112
+ ] }) }) });
113
+ });
114
+ PartoPieChart.displayName = "PartoPieChart";
115
+
116
+ export { PartoPieChart };
117
+ //# sourceMappingURL=chunk-LZMCMZZF.js.map
118
+ //# sourceMappingURL=chunk-LZMCMZZF.js.map