persian-data-grid 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (282) hide show
  1. package/OFL.txt +93 -0
  2. package/README.md +179 -22
  3. package/dist/ERPTableGroupRow-J5Z2LRC5.cjs +131 -0
  4. package/dist/ERPTableGroupRow-J5Z2LRC5.cjs.map +1 -0
  5. package/dist/ERPTableGroupRow-PSAPAHGL.js +125 -0
  6. package/dist/ERPTableGroupRow-PSAPAHGL.js.map +1 -0
  7. package/dist/GridPlugin-CJCaYnlw.d.ts +57 -0
  8. package/dist/GridPlugin-oxhq8AsM.d.cts +57 -0
  9. package/dist/GridPresenceService-GEH6535Q.js +3 -0
  10. package/dist/GridPresenceService-GEH6535Q.js.map +1 -0
  11. package/dist/GridPresenceService-RDN5FXHQ.cjs +12 -0
  12. package/dist/GridPresenceService-RDN5FXHQ.cjs.map +1 -0
  13. package/dist/GridSession-B-9lLcoB.d.cts +2492 -0
  14. package/dist/GridSession-Bc7UIawO.d.ts +2492 -0
  15. package/dist/GridSyncService-KTLB4KP3.js +3 -0
  16. package/dist/GridSyncService-KTLB4KP3.js.map +1 -0
  17. package/dist/GridSyncService-TAPAHABV.cjs +12 -0
  18. package/dist/GridSyncService-TAPAHABV.cjs.map +1 -0
  19. package/dist/PdfRenderer-1HFh6UeR.d.ts +22 -0
  20. package/dist/PdfRenderer-CBg7hWNS.d.cts +22 -0
  21. package/dist/RemoteApi-CCQxiSf1.d.cts +28 -0
  22. package/dist/RemoteApi-CCQxiSf1.d.ts +28 -0
  23. package/dist/SelectImpl-NM4O4IGW.js +447 -0
  24. package/dist/SelectImpl-NM4O4IGW.js.map +1 -0
  25. package/dist/SelectImpl-W2EI4T7O.cjs +453 -0
  26. package/dist/SelectImpl-W2EI4T7O.cjs.map +1 -0
  27. package/dist/UITableController-Cuwq481K.d.cts +632 -0
  28. package/dist/UITableController-DU8RopUM.d.ts +632 -0
  29. package/dist/VazirmatnPdfRenderer-BCMpC1zy.d.cts +96 -0
  30. package/dist/VazirmatnPdfRenderer-Dz_G-m3c.d.ts +96 -0
  31. package/dist/adapters/arian-erp.cjs +77 -0
  32. package/dist/adapters/arian-erp.cjs.map +1 -0
  33. package/dist/adapters/arian-erp.d.cts +60 -0
  34. package/dist/adapters/arian-erp.d.ts +60 -0
  35. package/dist/adapters/arian-erp.js +71 -0
  36. package/dist/adapters/arian-erp.js.map +1 -0
  37. package/dist/appendAtEnd-RHIQRG2W.cjs +35 -0
  38. package/dist/appendAtEnd-RHIQRG2W.cjs.map +1 -0
  39. package/dist/appendAtEnd-TJEABLGD.js +33 -0
  40. package/dist/appendAtEnd-TJEABLGD.js.map +1 -0
  41. package/dist/applyImportedRows-BO6yxoAN.d.cts +135 -0
  42. package/dist/applyImportedRows-D4zVY8uD.d.ts +135 -0
  43. package/dist/applyRowVisibilityHandler-KS6TMCBN.js +83 -0
  44. package/dist/applyRowVisibilityHandler-KS6TMCBN.js.map +1 -0
  45. package/dist/applyRowVisibilityHandler-LXCOGESZ.cjs +85 -0
  46. package/dist/applyRowVisibilityHandler-LXCOGESZ.cjs.map +1 -0
  47. package/dist/broadcastChannelTransport-FHUMV76O.cjs +12 -0
  48. package/dist/broadcastChannelTransport-FHUMV76O.cjs.map +1 -0
  49. package/dist/broadcastChannelTransport-MIH53VNZ.js +3 -0
  50. package/dist/broadcastChannelTransport-MIH53VNZ.js.map +1 -0
  51. package/dist/callbackRemoteApi-BlXO5NJz.d.ts +30 -0
  52. package/dist/callbackRemoteApi-DgnXH-i0.d.cts +30 -0
  53. package/dist/cellRenderContext-DB7V_mlu.d.ts +42 -0
  54. package/dist/cellRenderContext-DG5BOlxK.d.cts +42 -0
  55. package/dist/chunk-2BJCRYOS.cjs +936 -0
  56. package/dist/chunk-2BJCRYOS.cjs.map +1 -0
  57. package/dist/chunk-3Y3KKGEC.js +3 -0
  58. package/dist/chunk-3Y3KKGEC.js.map +1 -0
  59. package/dist/chunk-5ALMNLUR.cjs +1408 -0
  60. package/dist/chunk-5ALMNLUR.cjs.map +1 -0
  61. package/dist/chunk-5HKVMPBD.js +937 -0
  62. package/dist/chunk-5HKVMPBD.js.map +1 -0
  63. package/dist/chunk-633KP74Z.js +189 -0
  64. package/dist/chunk-633KP74Z.js.map +1 -0
  65. package/dist/chunk-6XBXZPBW.js +298 -0
  66. package/dist/chunk-6XBXZPBW.js.map +1 -0
  67. package/dist/chunk-77UXAJII.js +112 -0
  68. package/dist/chunk-77UXAJII.js.map +1 -0
  69. package/dist/chunk-ASPTRYRD.cjs +21 -0
  70. package/dist/chunk-ASPTRYRD.cjs.map +1 -0
  71. package/dist/chunk-AU3RDJYQ.js +243 -0
  72. package/dist/chunk-AU3RDJYQ.js.map +1 -0
  73. package/dist/chunk-BHDRUZH5.cjs +33 -0
  74. package/dist/chunk-BHDRUZH5.cjs.map +1 -0
  75. package/dist/chunk-BLYVOV3G.cjs +191 -0
  76. package/dist/chunk-BLYVOV3G.cjs.map +1 -0
  77. package/dist/chunk-CILNIWYW.cjs +100 -0
  78. package/dist/chunk-CILNIWYW.cjs.map +1 -0
  79. package/dist/chunk-DFFP7SJ6.cjs +257 -0
  80. package/dist/chunk-DFFP7SJ6.cjs.map +1 -0
  81. package/dist/chunk-DXRCYW42.cjs +568 -0
  82. package/dist/chunk-DXRCYW42.cjs.map +1 -0
  83. package/dist/chunk-EBV6HGZB.cjs +33 -0
  84. package/dist/chunk-EBV6HGZB.cjs.map +1 -0
  85. package/dist/chunk-EHHHC5JV.js +832 -0
  86. package/dist/chunk-EHHHC5JV.js.map +1 -0
  87. package/dist/chunk-F4PYOYHR.js +112 -0
  88. package/dist/chunk-F4PYOYHR.js.map +1 -0
  89. package/dist/chunk-GQEDLUMB.js +168 -0
  90. package/dist/chunk-GQEDLUMB.js.map +1 -0
  91. package/dist/chunk-H2LESGMX.cjs +319 -0
  92. package/dist/chunk-H2LESGMX.cjs.map +1 -0
  93. package/dist/chunk-HTNJT2QU.js +11674 -0
  94. package/dist/chunk-HTNJT2QU.js.map +1 -0
  95. package/dist/chunk-IIISFUW4.cjs +11786 -0
  96. package/dist/chunk-IIISFUW4.cjs.map +1 -0
  97. package/dist/chunk-IMPCRWYP.cjs +251 -0
  98. package/dist/chunk-IMPCRWYP.cjs.map +1 -0
  99. package/dist/chunk-IPPIXOVQ.js +317 -0
  100. package/dist/chunk-IPPIXOVQ.js.map +1 -0
  101. package/dist/chunk-J4XJ4UBC.js +1404 -0
  102. package/dist/chunk-J4XJ4UBC.js.map +1 -0
  103. package/dist/chunk-J7CPPFXT.cjs +89 -0
  104. package/dist/chunk-J7CPPFXT.cjs.map +1 -0
  105. package/dist/chunk-JOICD47Q.cjs +41 -0
  106. package/dist/chunk-JOICD47Q.cjs.map +1 -0
  107. package/dist/chunk-KHMG6EI2.js +13 -0
  108. package/dist/chunk-KHMG6EI2.js.map +1 -0
  109. package/dist/chunk-KMRURD5J.cjs +15 -0
  110. package/dist/chunk-KMRURD5J.cjs.map +1 -0
  111. package/dist/chunk-KRJG3KMP.cjs +174 -0
  112. package/dist/chunk-KRJG3KMP.cjs.map +1 -0
  113. package/dist/chunk-KUBVDIF7.cjs +653 -0
  114. package/dist/chunk-KUBVDIF7.cjs.map +1 -0
  115. package/dist/chunk-KYAOSBQN.js +31 -0
  116. package/dist/chunk-KYAOSBQN.js.map +1 -0
  117. package/dist/chunk-LJ7LMEXO.js +36 -0
  118. package/dist/chunk-LJ7LMEXO.js.map +1 -0
  119. package/dist/chunk-MT3KLB2Q.cjs +944 -0
  120. package/dist/chunk-MT3KLB2Q.cjs.map +1 -0
  121. package/dist/chunk-MU3RY46O.js +932 -0
  122. package/dist/chunk-MU3RY46O.js.map +1 -0
  123. package/dist/chunk-MUQQKPWR.js +84 -0
  124. package/dist/chunk-MUQQKPWR.js.map +1 -0
  125. package/dist/chunk-N7SJTINL.cjs +4 -0
  126. package/dist/chunk-N7SJTINL.cjs.map +1 -0
  127. package/dist/chunk-NTV2UUAJ.cjs +149 -0
  128. package/dist/chunk-NTV2UUAJ.cjs.map +1 -0
  129. package/dist/chunk-PJQWHF6T.js +31 -0
  130. package/dist/chunk-PJQWHF6T.js.map +1 -0
  131. package/dist/chunk-PQY54EL5.js +248 -0
  132. package/dist/chunk-PQY54EL5.js.map +1 -0
  133. package/dist/chunk-PXCHPZTP.cjs +839 -0
  134. package/dist/chunk-PXCHPZTP.cjs.map +1 -0
  135. package/dist/chunk-Q7TBBUTX.cjs +110 -0
  136. package/dist/chunk-Q7TBBUTX.cjs.map +1 -0
  137. package/dist/chunk-QQMU44KJ.js +612 -0
  138. package/dist/chunk-QQMU44KJ.js.map +1 -0
  139. package/dist/chunk-QZN7R2WP.cjs +114 -0
  140. package/dist/chunk-QZN7R2WP.cjs.map +1 -0
  141. package/dist/chunk-RKVSJU46.js +35 -0
  142. package/dist/chunk-RKVSJU46.js.map +1 -0
  143. package/dist/chunk-RM6ZWNT3.js +561 -0
  144. package/dist/chunk-RM6ZWNT3.js.map +1 -0
  145. package/dist/chunk-SX4VQXAA.cjs +114 -0
  146. package/dist/chunk-SX4VQXAA.cjs.map +1 -0
  147. package/dist/chunk-SZ7BLAY3.js +92 -0
  148. package/dist/chunk-SZ7BLAY3.js.map +1 -0
  149. package/dist/chunk-TN4MG6FY.js +112 -0
  150. package/dist/chunk-TN4MG6FY.js.map +1 -0
  151. package/dist/chunk-UC7PHDM6.cjs +331 -0
  152. package/dist/chunk-UC7PHDM6.cjs.map +1 -0
  153. package/dist/chunk-UXVLYUUW.js +108 -0
  154. package/dist/chunk-UXVLYUUW.js.map +1 -0
  155. package/dist/chunk-VVGYRZ7S.cjs +38 -0
  156. package/dist/chunk-VVGYRZ7S.cjs.map +1 -0
  157. package/dist/chunk-W5256BJ4.js +56 -0
  158. package/dist/chunk-W5256BJ4.js.map +1 -0
  159. package/dist/chunk-WUMOSOEK.cjs +62 -0
  160. package/dist/chunk-WUMOSOEK.cjs.map +1 -0
  161. package/dist/chunk-XLRE2J25.js +140 -0
  162. package/dist/chunk-XLRE2J25.js.map +1 -0
  163. package/dist/chunk-Y6W5V2CI.js +19 -0
  164. package/dist/chunk-Y6W5V2CI.js.map +1 -0
  165. package/dist/chunk-Z4QPZ3Z3.cjs +114 -0
  166. package/dist/chunk-Z4QPZ3Z3.cjs.map +1 -0
  167. package/dist/createEngineGridQuery-Dmq3i5v3.d.cts +884 -0
  168. package/dist/createEngineGridQuery-Mt1hc33m.d.ts +884 -0
  169. package/dist/date-picker-jalali.cjs +263 -0
  170. package/dist/date-picker-jalali.cjs.map +1 -0
  171. package/dist/date-picker-jalali.d.cts +62 -0
  172. package/dist/date-picker-jalali.d.ts +62 -0
  173. package/dist/date-picker-jalali.js +256 -0
  174. package/dist/date-picker-jalali.js.map +1 -0
  175. package/dist/finance.cjs +205 -0
  176. package/dist/finance.cjs.map +1 -0
  177. package/dist/finance.d.cts +90 -0
  178. package/dist/finance.d.ts +90 -0
  179. package/dist/finance.js +157 -0
  180. package/dist/finance.js.map +1 -0
  181. package/dist/foldedColumn-IHDT4ARZ.cjs +66 -0
  182. package/dist/foldedColumn-IHDT4ARZ.cjs.map +1 -0
  183. package/dist/foldedColumn-TFURUKFG.js +64 -0
  184. package/dist/foldedColumn-TFURUKFG.js.map +1 -0
  185. package/dist/headless.cjs +729 -0
  186. package/dist/headless.cjs.map +1 -0
  187. package/dist/headless.d.cts +504 -0
  188. package/dist/headless.d.ts +504 -0
  189. package/dist/headless.js +226 -0
  190. package/dist/headless.js.map +1 -0
  191. package/dist/index-DN8M8Jkq.d.cts +14 -0
  192. package/dist/index-DmzL-F_o.d.ts +14 -0
  193. package/dist/index.cjs +8002 -11409
  194. package/dist/index.cjs.map +1 -1
  195. package/dist/index.d.cts +437 -2305
  196. package/dist/index.d.ts +437 -2305
  197. package/dist/index.js +7244 -11083
  198. package/dist/index.js.map +1 -1
  199. package/dist/locales/ar.cjs +12 -0
  200. package/dist/locales/ar.cjs.map +1 -0
  201. package/dist/locales/ar.d.cts +6 -0
  202. package/dist/locales/ar.d.ts +6 -0
  203. package/dist/locales/ar.js +3 -0
  204. package/dist/locales/ar.js.map +1 -0
  205. package/dist/locales/en.cjs +12 -0
  206. package/dist/locales/en.cjs.map +1 -0
  207. package/dist/locales/en.d.cts +6 -0
  208. package/dist/locales/en.d.ts +6 -0
  209. package/dist/locales/en.js +3 -0
  210. package/dist/locales/en.js.map +1 -0
  211. package/dist/locales/fa.cjs +12 -0
  212. package/dist/locales/fa.cjs.map +1 -0
  213. package/dist/locales/fa.d.cts +6 -0
  214. package/dist/locales/fa.d.ts +6 -0
  215. package/dist/locales/fa.js +3 -0
  216. package/dist/locales/fa.js.map +1 -0
  217. package/dist/locales/index.cjs +51 -0
  218. package/dist/locales/index.cjs.map +1 -0
  219. package/dist/locales/index.d.cts +5 -0
  220. package/dist/locales/index.d.ts +5 -0
  221. package/dist/locales/index.js +6 -0
  222. package/dist/locales/index.js.map +1 -0
  223. package/dist/memoryRecords-AWDKUJ2F.cjs +50 -0
  224. package/dist/memoryRecords-AWDKUJ2F.cjs.map +1 -0
  225. package/dist/memoryRecords-OJTGXLRH.js +47 -0
  226. package/dist/memoryRecords-OJTGXLRH.js.map +1 -0
  227. package/dist/pagedFooterTotals-DXCGDO6F.cjs +27 -0
  228. package/dist/pagedFooterTotals-DXCGDO6F.cjs.map +1 -0
  229. package/dist/pagedFooterTotals-ORWKUNE7.js +25 -0
  230. package/dist/pagedFooterTotals-ORWKUNE7.js.map +1 -0
  231. package/dist/pagedKit-MFGAJFSK.cjs +134 -0
  232. package/dist/pagedKit-MFGAJFSK.cjs.map +1 -0
  233. package/dist/pagedKit-WYWY4LRV.js +127 -0
  234. package/dist/pagedKit-WYWY4LRV.js.map +1 -0
  235. package/dist/pagedSearch-HCPJW7VM.js +38 -0
  236. package/dist/pagedSearch-HCPJW7VM.js.map +1 -0
  237. package/dist/pagedSearch-U3WCG4GN.cjs +42 -0
  238. package/dist/pagedSearch-U3WCG4GN.cjs.map +1 -0
  239. package/dist/plugins/csv.cjs +124 -0
  240. package/dist/plugins/csv.cjs.map +1 -0
  241. package/dist/plugins/csv.d.cts +44 -0
  242. package/dist/plugins/csv.d.ts +44 -0
  243. package/dist/plugins/csv.js +120 -0
  244. package/dist/plugins/csv.js.map +1 -0
  245. package/dist/plugins/excel.cjs +52 -0
  246. package/dist/plugins/excel.cjs.map +1 -0
  247. package/dist/plugins/excel.d.cts +14 -0
  248. package/dist/plugins/excel.d.ts +14 -0
  249. package/dist/plugins/excel.js +7 -0
  250. package/dist/plugins/excel.js.map +1 -0
  251. package/dist/plugins/pdf/fonts/vazirmatn.cjs +50 -0
  252. package/dist/plugins/pdf/fonts/vazirmatn.cjs.map +1 -0
  253. package/dist/plugins/pdf/fonts/vazirmatn.d.cts +24 -0
  254. package/dist/plugins/pdf/fonts/vazirmatn.d.ts +24 -0
  255. package/dist/plugins/pdf/fonts/vazirmatn.js +39 -0
  256. package/dist/plugins/pdf/fonts/vazirmatn.js.map +1 -0
  257. package/dist/plugins/pdf.cjs +24 -0
  258. package/dist/plugins/pdf.cjs.map +1 -0
  259. package/dist/plugins/pdf.d.cts +21 -0
  260. package/dist/plugins/pdf.d.ts +21 -0
  261. package/dist/plugins/pdf.js +7 -0
  262. package/dist/plugins/pdf.js.map +1 -0
  263. package/dist/presence.cjs +56 -0
  264. package/dist/presence.cjs.map +1 -0
  265. package/dist/presence.d.cts +17 -0
  266. package/dist/presence.d.ts +17 -0
  267. package/dist/presence.js +54 -0
  268. package/dist/presence.js.map +1 -0
  269. package/dist/rebuildRowVisibility-66EAZ356.cjs +21 -0
  270. package/dist/rebuildRowVisibility-66EAZ356.cjs.map +1 -0
  271. package/dist/rebuildRowVisibility-6TYM5BP2.js +19 -0
  272. package/dist/rebuildRowVisibility-6TYM5BP2.js.map +1 -0
  273. package/dist/styles.css +1440 -0
  274. package/dist/sync.cjs +148 -0
  275. package/dist/sync.cjs.map +1 -0
  276. package/dist/sync.d.cts +17 -0
  277. package/dist/sync.d.ts +17 -0
  278. package/dist/sync.js +146 -0
  279. package/dist/sync.js.map +1 -0
  280. package/dist/types-D__47BKv.d.cts +23 -0
  281. package/dist/types-D__47BKv.d.ts +23 -0
  282. package/package.json +184 -28
@@ -0,0 +1,932 @@
1
+ import { downloadBlob } from './chunk-PQY54EL5.js';
2
+ import { formatExportValue } from './chunk-KYAOSBQN.js';
3
+ import { deflateSync } from 'fflate';
4
+
5
+ // packages/plugins/pdf/src/TextPdfRenderer.ts
6
+ var TextPdfRenderer = class {
7
+ async render(source, options) {
8
+ const lines = [options?.title ?? "Export"];
9
+ const columns = source.columns.slice(0, 8);
10
+ lines.push(columns.map((c) => c.fieldCaption ?? c.fieldName).join(" | "));
11
+ for (const row of source.rows.slice(0, 40)) {
12
+ const prefix = row.kind === "group" ? "\u25B8 " : "";
13
+ lines.push(
14
+ prefix + columns.map((col) => {
15
+ const cell = row.cells[col.fieldName];
16
+ const raw = cell?.display ?? cell?.value ?? "";
17
+ return formatExportValue(raw, col.fieldType).slice(0, 24);
18
+ }).join(" | ")
19
+ );
20
+ }
21
+ const content = lines.map((line, i) => {
22
+ const safe = line.replace(/[()\\]/g, " ");
23
+ const y = 750 - i * 14;
24
+ return `BT /F1 10 Tf 40 ${y} Td (${safe}) Tj ET`;
25
+ }).join("\n");
26
+ const stream = content;
27
+ const objects = [
28
+ "1 0 obj<< /Type /Catalog /Pages 2 0 R >>endobj\n",
29
+ "2 0 obj<< /Type /Pages /Kids [3 0 R] /Count 1 >>endobj\n",
30
+ "3 0 obj<< /Type /Page /Parent 2 0 R /MediaBox [0 0 612 792] /Contents 4 0 R /Resources<< /Font<< /F1 5 0 R >> >> >>endobj\n",
31
+ `4 0 obj<< /Length ${stream.length} >>stream
32
+ ${stream}
33
+ endstream
34
+ endobj
35
+ `,
36
+ "5 0 obj<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica >>endobj\n"
37
+ ];
38
+ let body = "%PDF-1.1\n";
39
+ const offsets = [0];
40
+ for (const obj of objects) {
41
+ offsets.push(body.length);
42
+ body += obj;
43
+ }
44
+ const xrefStart = body.length;
45
+ body += `xref
46
+ 0 ${objects.length + 1}
47
+ `;
48
+ body += "0000000000 65535 f \n";
49
+ for (let i = 1; i <= objects.length; i += 1) {
50
+ body += `${String(offsets[i]).padStart(10, "0")} 00000 n
51
+ `;
52
+ }
53
+ body += `trailer<< /Size ${objects.length + 1} /Root 1 0 R >>
54
+ `;
55
+ body += `startxref
56
+ ${xrefStart}
57
+ %%EOF
58
+ `;
59
+ return new Blob([body], { type: "application/pdf" });
60
+ }
61
+ };
62
+
63
+ // packages/plugins/pdf/src/PdfExportPlugin.ts
64
+ var PdfExportPlugin = class {
65
+ constructor(options = {}) {
66
+ this.options = options;
67
+ this.name = "pdf-export";
68
+ this.unsub = null;
69
+ this.renderer = options.renderer ?? new TextPdfRenderer();
70
+ }
71
+ register(ctx) {
72
+ this.unsub = ctx.bus.subscribeAll((event) => {
73
+ void this.onEvent(ctx, event);
74
+ });
75
+ }
76
+ dispose() {
77
+ this.unsub?.();
78
+ this.unsub = null;
79
+ }
80
+ async onEvent(ctx, event) {
81
+ if (event.type !== "EXPORT_REQUESTED") return;
82
+ if (event.tableId !== ctx.tableId) return;
83
+ const payload = event.payload;
84
+ if (payload.format !== "pdf") return;
85
+ try {
86
+ const source = ctx.query.getExportSource(
87
+ payload.collectionScope ?? "active"
88
+ );
89
+ if (!source) {
90
+ throw new Error("NO_EXPORT_SOURCE");
91
+ }
92
+ const blob = await this.renderer.render(source, {
93
+ title: payload.fileName ?? "Export",
94
+ direction: payload.direction,
95
+ template: this.options.template
96
+ });
97
+ const fileName = payload.fileName ?? `export-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}.pdf`;
98
+ const rowCount = source.rows.length;
99
+ if (this.options.download !== false) {
100
+ downloadBlob(blob, fileName);
101
+ }
102
+ this.options.onBlob?.(blob, { fileName, rowCount });
103
+ await ctx.bus.publish({
104
+ eventId: `${Date.now()}-pdf-ok`,
105
+ type: "PDF_EXPORT_COMPLETED",
106
+ tableId: ctx.tableId,
107
+ streamId: `table/${ctx.tableId}/view`,
108
+ version: 0,
109
+ occurredAt: Date.now(),
110
+ actorId: event.actorId,
111
+ correlationId: event.correlationId,
112
+ causationId: event.eventId,
113
+ payload: {
114
+ format: "pdf",
115
+ rowCount,
116
+ blobId: fileName
117
+ }
118
+ });
119
+ } catch (err) {
120
+ const message = err instanceof Error ? err.message : String(err);
121
+ await ctx.bus.publish({
122
+ eventId: `${Date.now()}-pdf-fail`,
123
+ type: "PDF_EXPORT_FAILED",
124
+ tableId: ctx.tableId,
125
+ streamId: `table/${ctx.tableId}/view`,
126
+ version: 0,
127
+ occurredAt: Date.now(),
128
+ actorId: event.actorId,
129
+ correlationId: event.correlationId,
130
+ causationId: event.eventId,
131
+ payload: {
132
+ format: "pdf",
133
+ code: message === "NO_EXPORT_SOURCE" ? message : "EXPORT_FAILED",
134
+ message
135
+ }
136
+ });
137
+ }
138
+ }
139
+ };
140
+ var encoder = new TextEncoder();
141
+ function concat(chunks) {
142
+ let total = 0;
143
+ for (const c of chunks) total += c.length;
144
+ const out = new Uint8Array(total);
145
+ let o = 0;
146
+ for (const c of chunks) {
147
+ out.set(c, o);
148
+ o += c.length;
149
+ }
150
+ return out;
151
+ }
152
+ function pad10(n) {
153
+ return String(n).padStart(10, "0");
154
+ }
155
+ var PdfBuilder = class {
156
+ constructor() {
157
+ this.objects = [];
158
+ }
159
+ addAscii(body) {
160
+ this.objects.push(encoder.encode(body));
161
+ return this.objects.length;
162
+ }
163
+ replaceAscii(objNum, body) {
164
+ this.objects[objNum - 1] = encoder.encode(body);
165
+ }
166
+ addFlate(uncompressed, extraDict = "") {
167
+ const compressed = deflateSync(uncompressed, { level: 9 });
168
+ const dict = `<< /Filter /FlateDecode /Length ${compressed.length} ${extraDict}>>`;
169
+ const header = encoder.encode(`${dict}stream
170
+ `);
171
+ const tail = encoder.encode("\nendstream\n");
172
+ this.objects.push(concat([header, compressed, tail]));
173
+ return this.objects.length;
174
+ }
175
+ /** Raw stream (e.g. JPEG with `/Filter /DCTDecode`). `dict` is a full `<< … >>`. */
176
+ addRawStream(data, dict) {
177
+ const header = encoder.encode(`${dict}
178
+ stream
179
+ `);
180
+ const tail = encoder.encode("\nendstream\n");
181
+ this.objects.push(concat([header, data, tail]));
182
+ return this.objects.length;
183
+ }
184
+ build() {
185
+ const parts = [encoder.encode("%PDF-1.4\n%\x80\x80\x80\x80\n")];
186
+ const offsets = [0];
187
+ let pos = parts[0].length;
188
+ for (let i = 0; i < this.objects.length; i += 1) {
189
+ offsets.push(pos);
190
+ const head = encoder.encode(`${i + 1} 0 obj
191
+ `);
192
+ const tail = encoder.encode("endobj\n");
193
+ const body = this.objects[i];
194
+ parts.push(head, body, tail);
195
+ pos += head.length + body.length + tail.length;
196
+ }
197
+ const xrefStart = pos;
198
+ let xref = `xref
199
+ 0 ${this.objects.length + 1}
200
+ 0000000000 65535 f
201
+ `;
202
+ for (let i = 1; i <= this.objects.length; i += 1) {
203
+ xref += `${pad10(offsets[i] ?? 0)} 00000 n
204
+ `;
205
+ }
206
+ xref += `trailer<< /Size ${this.objects.length + 1} /Root 1 0 R >>
207
+ `;
208
+ xref += `startxref
209
+ ${xrefStart}
210
+ %%EOF
211
+ `;
212
+ parts.push(encoder.encode(xref));
213
+ return concat(parts);
214
+ }
215
+ };
216
+ function pdfEscapeTextHex(gids) {
217
+ return gids.map((g) => g.toString(16).padStart(4, "0")).join("");
218
+ }
219
+
220
+ // packages/plugins/pdf/src/parseTtf.ts
221
+ function u16(buf, offset) {
222
+ return buf[offset] << 8 | buf[offset + 1];
223
+ }
224
+ function u32(buf, offset) {
225
+ return (buf[offset] << 24 | buf[offset + 1] << 16 | buf[offset + 2] << 8 | buf[offset + 3]) >>> 0;
226
+ }
227
+ function i16(buf, offset) {
228
+ const v = u16(buf, offset);
229
+ return v > 32767 ? v - 65536 : v;
230
+ }
231
+ function tagAt(buf, offset) {
232
+ return String.fromCharCode(buf[offset], buf[offset + 1], buf[offset + 2], buf[offset + 3]);
233
+ }
234
+ function tableMap(buf) {
235
+ const numTables = u16(buf, 4);
236
+ const tables = /* @__PURE__ */ new Map();
237
+ for (let i = 0; i < numTables; i += 1) {
238
+ const o = 12 + i * 16;
239
+ tables.set(tagAt(buf, o), { offset: u32(buf, o + 8), length: u32(buf, o + 12) });
240
+ }
241
+ return tables;
242
+ }
243
+ function parseCmap(buf, cmapOffset) {
244
+ const numTables = u16(buf, cmapOffset + 2);
245
+ let format4 = -1;
246
+ let format12 = -1;
247
+ for (let i = 0; i < numTables; i += 1) {
248
+ const rec = cmapOffset + 4 + i * 8;
249
+ const platform = u16(buf, rec);
250
+ const encoding = u16(buf, rec + 2);
251
+ const offset = cmapOffset + u32(buf, rec + 4);
252
+ const format = u16(buf, offset);
253
+ if (format === 12 && (platform === 3 || platform === 0)) format12 = offset;
254
+ if (format === 4 && (platform === 3 || platform === 0) && encoding <= 1) {
255
+ format4 = offset;
256
+ }
257
+ }
258
+ if (format12 >= 0) {
259
+ const nGroups = u32(buf, format12 + 12);
260
+ const groups = [];
261
+ for (let i = 0; i < nGroups; i += 1) {
262
+ const o = format12 + 16 + i * 12;
263
+ groups.push({
264
+ start: u32(buf, o),
265
+ end: u32(buf, o + 4),
266
+ glyph: u32(buf, o + 8)
267
+ });
268
+ }
269
+ return (code) => {
270
+ for (const g of groups) {
271
+ if (code >= g.start && code <= g.end) return g.glyph + (code - g.start);
272
+ }
273
+ return 0;
274
+ };
275
+ }
276
+ if (format4 < 0) {
277
+ return () => 0;
278
+ }
279
+ const segCount = u16(buf, format4 + 6) / 2;
280
+ const endCodes = format4 + 14;
281
+ const startCodes = endCodes + 2 + segCount * 2;
282
+ const idDeltas = startCodes + segCount * 2;
283
+ const idRangeOffsets = idDeltas + segCount * 2;
284
+ return (code) => {
285
+ for (let i = 0; i < segCount; i += 1) {
286
+ const end = u16(buf, endCodes + i * 2);
287
+ if (code > end) continue;
288
+ const start = u16(buf, startCodes + i * 2);
289
+ if (code < start) return 0;
290
+ const rangeOffset = u16(buf, idRangeOffsets + i * 2);
291
+ const delta = i16(buf, idDeltas + i * 2);
292
+ if (rangeOffset === 0) return code + delta & 65535;
293
+ const glyphOffset = idRangeOffsets + i * 2 + rangeOffset + (code - start) * 2;
294
+ const glyph = u16(buf, glyphOffset);
295
+ if (glyph === 0) return 0;
296
+ return glyph + delta & 65535;
297
+ }
298
+ return 0;
299
+ };
300
+ }
301
+ function parseTtf(bytes) {
302
+ const tables = tableMap(bytes);
303
+ const head = tables.get("head");
304
+ const hhea = tables.get("hhea");
305
+ const hmtx = tables.get("hmtx");
306
+ const maxp = tables.get("maxp");
307
+ const cmap = tables.get("cmap");
308
+ if (!head || !hhea || !hmtx || !maxp || !cmap) {
309
+ throw new Error("VAZIRMATN_TTF_TABLES");
310
+ }
311
+ const unitsPerEm = u16(bytes, head.offset + 18);
312
+ const metrics = {
313
+ unitsPerEm,
314
+ xMin: i16(bytes, head.offset + 36),
315
+ yMin: i16(bytes, head.offset + 38),
316
+ xMax: i16(bytes, head.offset + 40),
317
+ yMax: i16(bytes, head.offset + 42),
318
+ ascent: i16(bytes, hhea.offset + 4),
319
+ descent: i16(bytes, hhea.offset + 6),
320
+ italicAngle: 0,
321
+ numGlyphs: u16(bytes, maxp.offset + 4)
322
+ };
323
+ const numberOfHMetrics = u16(bytes, hhea.offset + 34);
324
+ const advances = new Uint16Array(metrics.numGlyphs);
325
+ for (let i = 0; i < numberOfHMetrics; i += 1) {
326
+ advances[i] = u16(bytes, hmtx.offset + i * 4);
327
+ }
328
+ const lastAdvance = advances[numberOfHMetrics - 1] ?? metrics.unitsPerEm;
329
+ for (let i = numberOfHMetrics; i < metrics.numGlyphs; i += 1) {
330
+ advances[i] = lastAdvance;
331
+ }
332
+ const glyphId = parseCmap(bytes, cmap.offset);
333
+ return {
334
+ bytes,
335
+ metrics,
336
+ glyphId,
337
+ advance: (gid) => advances[gid] ?? lastAdvance
338
+ };
339
+ }
340
+ function pdfWidth(advance, unitsPerEm) {
341
+ return advance * 1e3 / unitsPerEm;
342
+ }
343
+
344
+ // packages/plugins/pdf/src/shapeRtl.ts
345
+ var FORMS = {
346
+ 1575: [65165, 65166, 65165, 65166],
347
+ 1576: [65167, 65168, 65169, 65170],
348
+ 1662: [64342, 64343, 64344, 64345],
349
+ 1578: [65173, 65174, 65175, 65176],
350
+ 1579: [65177, 65178, 65179, 65180],
351
+ 1580: [65181, 65182, 65183, 65184],
352
+ 1670: [64378, 64379, 64380, 64381],
353
+ 1581: [65185, 65186, 65187, 65188],
354
+ 1582: [65189, 65190, 65191, 65192],
355
+ 1583: [65193, 65194, 65193, 65194],
356
+ 1584: [65195, 65196, 65195, 65196],
357
+ 1585: [65197, 65198, 65197, 65198],
358
+ 1586: [65199, 65200, 65199, 65200],
359
+ 1688: [64394, 64395, 64394, 64395],
360
+ 1587: [65201, 65202, 65203, 65204],
361
+ 1588: [65205, 65206, 65207, 65208],
362
+ 1589: [65209, 65210, 65211, 65212],
363
+ 1590: [65213, 65214, 65215, 65216],
364
+ 1591: [65217, 65218, 65219, 65220],
365
+ 1592: [65221, 65222, 65223, 65224],
366
+ 1593: [65225, 65226, 65227, 65228],
367
+ 1594: [65229, 65230, 65231, 65232],
368
+ 1601: [65233, 65234, 65235, 65236],
369
+ 1602: [65237, 65238, 65239, 65240],
370
+ 1705: [64398, 64399, 64400, 64401],
371
+ 1603: [65241, 65242, 65243, 65244],
372
+ 1711: [64402, 64403, 64404, 64405],
373
+ 1604: [65245, 65246, 65247, 65248],
374
+ 1605: [65249, 65250, 65251, 65252],
375
+ 1606: [65253, 65254, 65255, 65256],
376
+ 1607: [65257, 65258, 65259, 65260],
377
+ 1608: [65261, 65262, 65261, 65262],
378
+ 1740: [64508, 64509, 64510, 64511],
379
+ 1610: [65265, 65266, 65267, 65268],
380
+ 1570: [65153, 65154, 65153, 65154],
381
+ 1577: [65171, 65172, 65171, 65172]
382
+ };
383
+ var RIGHT_ONLY = /* @__PURE__ */ new Set([
384
+ 1570,
385
+ 1575,
386
+ 1577,
387
+ 1583,
388
+ 1584,
389
+ 1585,
390
+ 1586,
391
+ 1688,
392
+ 1608
393
+ ]);
394
+ function canConnect(cp, side) {
395
+ if (!FORMS[cp]) return false;
396
+ if (RIGHT_ONLY.has(cp)) return side === "right";
397
+ return true;
398
+ }
399
+ function isLetter(cp) {
400
+ return cp in FORMS;
401
+ }
402
+ function shapeArabic(input) {
403
+ const cps = [...input].map((ch) => ch.codePointAt(0) ?? 0);
404
+ const out = [];
405
+ for (let i = 0; i < cps.length; i += 1) {
406
+ const cp = cps[i] ?? 0;
407
+ const forms = FORMS[cp];
408
+ if (!forms) {
409
+ out.push(cp);
410
+ continue;
411
+ }
412
+ let prev = i - 1;
413
+ while (prev >= 0 && (cps[prev] === 1600 || cps[prev] === 8204)) prev -= 1;
414
+ let next = i + 1;
415
+ while (next < cps.length && (cps[next] === 1600 || cps[next] === 8205)) next += 1;
416
+ const joinsPrev = prev >= 0 && isLetter(cps[prev] ?? 0) && canConnect(cps[prev] ?? 0, "left");
417
+ const joinsNext = next < cps.length && isLetter(cps[next] ?? 0) && canConnect(cp, "left");
418
+ const form = joinsPrev && joinsNext ? 3 : joinsNext ? 2 : joinsPrev ? 1 : 0;
419
+ out.push(forms[form] ?? cp);
420
+ }
421
+ return String.fromCodePoint(...out);
422
+ }
423
+ var LTR_RE = /^[0-9A-Za-z۰-۹.,:%/+-]+$/;
424
+ function reverseGraphemes(s) {
425
+ return [...s].reverse().join("");
426
+ }
427
+ function rtlVisual(input) {
428
+ const shaped = shapeArabic(input);
429
+ const parts = shaped.split(/([0-9A-Za-z۰-۹.,:%/+-]+)/);
430
+ const visual = [];
431
+ for (let i = parts.length - 1; i >= 0; i -= 1) {
432
+ const part = parts[i] ?? "";
433
+ if (!part) continue;
434
+ visual.push(LTR_RE.test(part) ? part : reverseGraphemes(part));
435
+ }
436
+ return visual.join("");
437
+ }
438
+
439
+ // packages/plugins/pdf/src/VazirmatnPdfRenderer.ts
440
+ var PAGE_W = 595;
441
+ var PAGE_H = 842;
442
+ var MARGIN = 36;
443
+ var TITLE_SIZE = 12;
444
+ var SUB_SIZE = 9;
445
+ var CELL_SIZE = 8;
446
+ var ROW_H = 16;
447
+ var HEADER_H = 18;
448
+ var FOOTER_H = 22;
449
+ var SIGN_H = 56;
450
+ function cellText(raw, fieldType) {
451
+ if (fieldType === "checkbox") {
452
+ return raw ? "\u0628\u0644\u0647" : "\u062E\u06CC\u0631";
453
+ }
454
+ return formatExportValue(raw, fieldType);
455
+ }
456
+ function measure(font, text, size) {
457
+ let w = 0;
458
+ for (const ch of text) {
459
+ const cp = ch.codePointAt(0) ?? 0;
460
+ const gid = font.glyphId(cp);
461
+ w += pdfWidth(font.advance(gid), font.metrics.unitsPerEm);
462
+ }
463
+ return w * size / 1e3;
464
+ }
465
+ function fitText(font, text, size, maxWidth) {
466
+ if (measure(font, text, size) <= maxWidth) return text;
467
+ const ellipsis = "...";
468
+ let lo = 0;
469
+ let hi = [...text].length;
470
+ while (lo < hi) {
471
+ const mid = Math.ceil((lo + hi) / 2);
472
+ const slice = [...text].slice(0, mid).join("") + ellipsis;
473
+ if (measure(font, slice, size) <= maxWidth) lo = mid;
474
+ else hi = mid - 1;
475
+ }
476
+ if (lo <= 0) return ellipsis;
477
+ return [...text].slice(0, lo).join("") + ellipsis;
478
+ }
479
+ function toGids(font, text) {
480
+ const gids = [];
481
+ for (const ch of text) {
482
+ const cp = ch.codePointAt(0) ?? 0;
483
+ gids.push(font.glyphId(cp));
484
+ }
485
+ return gids;
486
+ }
487
+ function toUnicodeCmap(pairs) {
488
+ const unique = /* @__PURE__ */ new Map();
489
+ for (const p of pairs) {
490
+ if (!unique.has(p.gid)) unique.set(p.gid, p.unicode);
491
+ }
492
+ const entries = [...unique.entries()];
493
+ const chunks = [];
494
+ for (let i = 0; i < entries.length; i += 100) {
495
+ const slice = entries.slice(i, i + 100);
496
+ chunks.push(`${slice.length} beginbfchar`);
497
+ for (const [gid, uni] of slice) {
498
+ const g = gid.toString(16).padStart(4, "0");
499
+ const u = uni.toString(16).padStart(uni > 65535 ? 8 : 4, "0");
500
+ chunks.push(`<${g}> <${u}>`);
501
+ }
502
+ chunks.push("endbfchar");
503
+ }
504
+ return `%!PS-Adobe-3.0 Resource-CMap
505
+ %%BeginResource: CMap (Vazirmatn-UCS)
506
+ /CIDInit /ProcSet findresource begin
507
+ 12 dict begin
508
+ begincmap
509
+ /CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def
510
+ /CMapName /Vazirmatn-UCS def
511
+ /CMapType 2 def
512
+ 1 begincodespacerange
513
+ <0000> <FFFF>
514
+ endcodespacerange
515
+ ${chunks.join("\n")}
516
+ endcmap
517
+ CMapName currentdict /CMap defineresource pop
518
+ end
519
+ end
520
+ %%EndResource
521
+ `;
522
+ }
523
+ function toSumNumber(raw) {
524
+ if (typeof raw === "number" && Number.isFinite(raw)) return Math.trunc(raw);
525
+ if (typeof raw === "bigint") {
526
+ const n = Number(raw);
527
+ return Number.isSafeInteger(n) ? n : null;
528
+ }
529
+ if (typeof raw === "string") {
530
+ const n = Number(
531
+ raw.trim().replace(/[۰-۹]/g, (d) => String("\u06F0\u06F1\u06F2\u06F3\u06F4\u06F5\u06F6\u06F7\u06F8\u06F9".indexOf(d))).replace(/,/g, "")
532
+ );
533
+ return Number.isFinite(n) ? Math.trunc(n) : null;
534
+ }
535
+ return null;
536
+ }
537
+ function readJpegSize(bytes) {
538
+ if (bytes.length < 4 || bytes[0] !== 255 || bytes[1] !== 216) return null;
539
+ let i = 2;
540
+ while (i + 9 < bytes.length) {
541
+ if (bytes[i] !== 255) {
542
+ i += 1;
543
+ continue;
544
+ }
545
+ const marker = bytes[i + 1];
546
+ const len = bytes[i + 2] << 8 | bytes[i + 3];
547
+ if (marker === 192 || marker === 193 || marker === 194) {
548
+ const h = bytes[i + 5] << 8 | bytes[i + 6];
549
+ const w = bytes[i + 7] << 8 | bytes[i + 8];
550
+ return { w, h };
551
+ }
552
+ i += 2 + len;
553
+ }
554
+ return null;
555
+ }
556
+ var VazirmatnPdfRenderer = class {
557
+ constructor(fontBytes) {
558
+ this.fontBytes = fontBytes;
559
+ if (!fontBytes?.byteLength) {
560
+ throw new Error(
561
+ "VazirmatnPdfRenderer requires font bytes from persian-data-grid/plugins/pdf/fonts/vazirmatn"
562
+ );
563
+ }
564
+ }
565
+ async render(source, options) {
566
+ const font = parseTtf(this.fontBytes);
567
+ const rtl = options?.direction !== "ltr";
568
+ const template = options?.template;
569
+ const title = template?.header?.title ?? options?.title ?? "\u0627\u0642\u0644\u0627\u0645 \u0633\u0646\u062F";
570
+ const columns = source.columns.filter((c) => c.fieldName !== "index");
571
+ const colCount = Math.max(1, columns.length);
572
+ const tableWidth = PAGE_W - MARGIN * 2;
573
+ const colW = tableWidth / colCount;
574
+ const used = [];
575
+ const note = (text) => {
576
+ const visual = rtl ? rtlVisual(text) : text;
577
+ for (const ch of visual) {
578
+ const cp = ch.codePointAt(0) ?? 0;
579
+ used.push({ gid: font.glyphId(cp), unicode: cp });
580
+ }
581
+ return visual;
582
+ };
583
+ const titleVisual = note(title);
584
+ const subtitleVisual = template?.header?.subtitle ? note(template.header.subtitle) : null;
585
+ const metaVisuals = (template?.header?.meta ?? []).map((m) => note(m));
586
+ const footerTextVisual = template?.footer?.text ? note(template.footer.text) : null;
587
+ const pageFmt = template?.footer?.pageNumberFormat ?? "{page} / {pages}";
588
+ const showPageNumber = template != null && template.footer?.showPageNumber !== false;
589
+ const repeatHeader = template == null || template.repeatTableHeader !== false;
590
+ const totalsLabelVisual = template?.pageTotals ? note(template.pageTotals.label ?? "\u062C\u0645\u0639 \u0635\u0641\u062D\u0647") : null;
591
+ const signLabelVisual = template?.signature ? note(template.signature.label ?? "\u0627\u0645\u0636\u0627") : null;
592
+ const stampLabelVisual = template?.stamp ? note(template.stamp.label ?? "\u0645\u0647\u0631") : null;
593
+ note("0123456789 /");
594
+ const headers = columns.map(
595
+ (c) => note(c.fieldCaption ?? c.fieldName)
596
+ );
597
+ const body = source.rows.map(
598
+ (row) => columns.map((col) => {
599
+ const cell = row.cells[col.fieldName];
600
+ const raw = cell?.display ?? cell?.value ?? "";
601
+ return note(cellText(raw, col.fieldType));
602
+ })
603
+ );
604
+ const bodyNums = source.rows.map((row) => {
605
+ const map = /* @__PURE__ */ new Map();
606
+ for (const col of columns) {
607
+ const cell = row.cells[col.fieldName];
608
+ const raw = cell?.value ?? cell?.display ?? "";
609
+ map.set(col.fieldName, toSumNumber(raw));
610
+ }
611
+ return map;
612
+ });
613
+ let logoDrawW = template?.logo?.width ?? 64;
614
+ let logoDrawH = template?.logo?.height ?? 48;
615
+ if (template?.logo?.jpegBytes?.byteLength) {
616
+ const size = readJpegSize(template.logo.jpegBytes);
617
+ if (size && template.logo.height == null) {
618
+ logoDrawH = Math.round(logoDrawW * size.h / Math.max(1, size.w));
619
+ }
620
+ }
621
+ const headerBand = template ? Math.max(
622
+ logoDrawH,
623
+ 28 + (subtitleVisual ? 14 : 0) + metaVisuals.length * 12
624
+ ) + 12 : TITLE_SIZE + 16;
625
+ const footerBand = template && (footerTextVisual || showPageNumber) ? FOOTER_H + 8 : 0;
626
+ const signBand = template && (signLabelVisual || stampLabelVisual) ? SIGN_H + 8 : 0;
627
+ const totalsBand = template?.pageTotals ? ROW_H + 4 : 0;
628
+ const usable = (withSign) => PAGE_H - MARGIN * 2 - headerBand - footerBand - (repeatHeader ? HEADER_H : 0) - totalsBand - (withSign ? signBand : 0);
629
+ const pageRowCounts = [];
630
+ let remaining = body.length;
631
+ if (remaining === 0) {
632
+ pageRowCounts.push(0);
633
+ } else {
634
+ while (remaining > 0) {
635
+ const isLikelyLast = remaining <= Math.floor(usable(false) / ROW_H);
636
+ const budget = Math.max(
637
+ 1,
638
+ Math.floor(usable(isLikelyLast && signBand > 0) / ROW_H)
639
+ );
640
+ const take = Math.min(remaining, budget);
641
+ pageRowCounts.push(take);
642
+ remaining -= take;
643
+ if (pageRowCounts.length > 1e4) break;
644
+ }
645
+ if (signBand > 0) {
646
+ const lastBudget = Math.max(1, Math.floor(usable(true) / ROW_H));
647
+ const lastIdx = pageRowCounts.length - 1;
648
+ if ((pageRowCounts[lastIdx] ?? 0) > lastBudget) {
649
+ const overflow = (pageRowCounts[lastIdx] ?? 0) - lastBudget;
650
+ pageRowCounts[lastIdx] = lastBudget;
651
+ pageRowCounts.push(overflow);
652
+ }
653
+ }
654
+ }
655
+ const pageCount = Math.max(1, pageRowCounts.length);
656
+ const pageLabels = Array.from(
657
+ { length: pageCount },
658
+ (_, p) => note(
659
+ pageFmt.replace("{page}", String(p + 1)).replace("{pages}", String(pageCount))
660
+ )
661
+ );
662
+ const pageTotalCells = pageRowCounts.map((take, p) => {
663
+ if (!template?.pageTotals || !totalsLabelVisual) return [];
664
+ const start = pageRowCounts.slice(0, p).reduce((a, n) => a + n, 0);
665
+ const numSlice = bodyNums.slice(start, start + take);
666
+ const sums = /* @__PURE__ */ new Map();
667
+ for (const colId of template.pageTotals.columns) {
668
+ let s = 0;
669
+ for (const row of numSlice) {
670
+ const n = row.get(colId);
671
+ if (n != null) s += n;
672
+ }
673
+ sums.set(colId, s);
674
+ }
675
+ return columns.map((col, colIdx) => {
676
+ const isTotalCol = template.pageTotals.columns.includes(col.fieldName);
677
+ if (isTotalCol) return note(String(sums.get(col.fieldName) ?? 0));
678
+ const labelCol = columns.findIndex(
679
+ (c) => !template.pageTotals.columns.includes(c.fieldName)
680
+ );
681
+ if (colIdx === (labelCol >= 0 ? labelCol : 0)) return totalsLabelVisual;
682
+ return "";
683
+ });
684
+ });
685
+ const metrics = font.metrics;
686
+ const scale = 1e3 / metrics.unitsPerEm;
687
+ const bbox = [
688
+ Math.round(metrics.xMin * scale),
689
+ Math.round(metrics.yMin * scale),
690
+ Math.round(metrics.xMax * scale),
691
+ Math.round(metrics.yMax * scale)
692
+ ];
693
+ const ascent = Math.round(metrics.ascent * scale);
694
+ const descent = Math.round(metrics.descent * scale);
695
+ const usedGids = [...new Set(used.map((u) => u.gid))].sort((a, b) => a - b);
696
+ const wParts = usedGids.map((gid) => {
697
+ const w = Math.round(pdfWidth(font.advance(gid), metrics.unitsPerEm));
698
+ return `${gid} [${w}]`;
699
+ });
700
+ const pdf = new PdfBuilder();
701
+ pdf.addAscii("<< /Type /Catalog /Pages 2 0 R >>\n");
702
+ const pagesObj = 2;
703
+ pdf.addAscii("<< /Type /Pages /Kids [] /Count 0 >>\n");
704
+ const fontFile = pdf.addFlate(
705
+ font.bytes,
706
+ `/Length1 ${font.bytes.length} `
707
+ );
708
+ const descriptor = pdf.addAscii(
709
+ `<< /Type /FontDescriptor /FontName /Vazirmatn /Flags 32 /FontBBox [${bbox.join(" ")}] /ItalicAngle 0 /Ascent ${ascent} /Descent ${descent} /CapHeight ${ascent} /StemV 80 /FontFile2 ${fontFile} 0 R >>
710
+ `
711
+ );
712
+ const cidFont = pdf.addAscii(
713
+ `<< /Type /Font /Subtype /CIDFontType2 /BaseFont /Vazirmatn /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >> /FontDescriptor ${descriptor} 0 R /DW 500 /W [${wParts.join(" ")}] /CIDToGIDMap /Identity >>
714
+ `
715
+ );
716
+ const toUnicode = pdf.addFlate(
717
+ new TextEncoder().encode(toUnicodeCmap(used))
718
+ );
719
+ const type0 = pdf.addAscii(
720
+ `<< /Type /Font /Subtype /Type0 /BaseFont /Vazirmatn /Encoding /Identity-H /DescendantFonts [${cidFont} 0 R] /ToUnicode ${toUnicode} 0 R >>
721
+ `
722
+ );
723
+ let logoXObject = null;
724
+ if (template?.logo?.jpegBytes?.byteLength) {
725
+ const jpeg = template.logo.jpegBytes;
726
+ const size = readJpegSize(jpeg) ?? { w: logoDrawW, h: logoDrawH };
727
+ logoXObject = pdf.addRawStream(
728
+ jpeg,
729
+ `<< /Type /XObject /Subtype /Image /Width ${size.w} /Height ${size.h} /ColorSpace /DeviceRGB /BitsPerComponent 8 /Filter /DCTDecode /Length ${jpeg.length} >>`
730
+ );
731
+ }
732
+ const pageObjNums = [];
733
+ const drawText = (ops, text, size, x, y) => {
734
+ ops.push("BT");
735
+ ops.push(`/F1 ${size} Tf`);
736
+ ops.push(`${x.toFixed(2)} ${y.toFixed(2)} Td`);
737
+ ops.push(`<${pdfEscapeTextHex(toGids(font, text))}> Tj`);
738
+ ops.push("ET");
739
+ };
740
+ const drawCell = (ops, col, top, height, text, header) => {
741
+ const x = rtl ? PAGE_W - MARGIN - (col + 1) * colW : MARGIN + col * colW;
742
+ if (header) {
743
+ ops.push("0.92 g");
744
+ ops.push(
745
+ `${x.toFixed(2)} ${(top - height).toFixed(2)} ${colW.toFixed(2)} ${height.toFixed(2)} re f`
746
+ );
747
+ ops.push("0 g");
748
+ }
749
+ ops.push("0.55 w 0.35 g");
750
+ ops.push(
751
+ `${x.toFixed(2)} ${(top - height).toFixed(2)} ${colW.toFixed(2)} ${height.toFixed(2)} re S`
752
+ );
753
+ ops.push("0 g");
754
+ if (!text) return;
755
+ const fitted = fitText(font, text, CELL_SIZE, colW - 6);
756
+ const tw = measure(font, fitted, CELL_SIZE);
757
+ const tx = rtl ? x + colW - 3 - tw : x + 3;
758
+ const ty = top - height + 4.5;
759
+ drawText(ops, fitted, CELL_SIZE, tx, ty);
760
+ };
761
+ let rowCursor = 0;
762
+ for (let p = 0; p < pageCount; p += 1) {
763
+ const ops = [];
764
+ const isLast = p === pageCount - 1;
765
+ let y = PAGE_H - MARGIN;
766
+ if (template) {
767
+ if (logoXObject != null) {
768
+ const lx = rtl ? PAGE_W - MARGIN - logoDrawW : MARGIN;
769
+ const ly = y - logoDrawH;
770
+ ops.push("q");
771
+ ops.push(
772
+ `${logoDrawW} 0 0 ${logoDrawH} ${lx.toFixed(2)} ${ly.toFixed(2)} cm /Im1 Do`
773
+ );
774
+ ops.push("Q");
775
+ }
776
+ const textOriginX = rtl ? PAGE_W - MARGIN - (logoXObject != null ? logoDrawW + 10 : 0) : MARGIN + (logoXObject != null ? logoDrawW + 10 : 0);
777
+ let ty = y - 12;
778
+ const tw = measure(font, titleVisual, TITLE_SIZE);
779
+ drawText(
780
+ ops,
781
+ titleVisual,
782
+ TITLE_SIZE,
783
+ rtl ? textOriginX - tw : textOriginX,
784
+ ty
785
+ );
786
+ ty -= 14;
787
+ if (subtitleVisual) {
788
+ const sw = measure(font, subtitleVisual, SUB_SIZE);
789
+ drawText(
790
+ ops,
791
+ subtitleVisual,
792
+ SUB_SIZE,
793
+ rtl ? textOriginX - sw : textOriginX,
794
+ ty
795
+ );
796
+ ty -= 12;
797
+ }
798
+ for (const meta of metaVisuals) {
799
+ const mw = measure(font, meta, SUB_SIZE);
800
+ drawText(
801
+ ops,
802
+ meta,
803
+ SUB_SIZE,
804
+ rtl ? textOriginX - mw : textOriginX,
805
+ ty
806
+ );
807
+ ty -= 12;
808
+ }
809
+ y = PAGE_H - MARGIN - headerBand;
810
+ } else {
811
+ const titleW = measure(font, titleVisual, TITLE_SIZE);
812
+ drawText(
813
+ ops,
814
+ titleVisual,
815
+ TITLE_SIZE,
816
+ rtl ? PAGE_W - MARGIN - titleW : MARGIN,
817
+ y - 12
818
+ );
819
+ y = PAGE_H - MARGIN - headerBand;
820
+ }
821
+ if (repeatHeader || p === 0) {
822
+ headers.forEach((h, col) => drawCell(ops, col, y, HEADER_H, h, true));
823
+ y -= HEADER_H;
824
+ }
825
+ const take = pageRowCounts[p] ?? 0;
826
+ const slice = body.slice(rowCursor, rowCursor + take);
827
+ for (const row of slice) {
828
+ row.forEach((cell, col) => drawCell(ops, col, y, ROW_H, cell, false));
829
+ y -= ROW_H;
830
+ }
831
+ const totalRow = pageTotalCells[p];
832
+ if (totalRow && totalRow.length > 0) {
833
+ totalRow.forEach(
834
+ (text, colIdx) => drawCell(ops, colIdx, y, ROW_H, text, true)
835
+ );
836
+ y -= ROW_H;
837
+ }
838
+ if (isLast && (signLabelVisual || stampLabelVisual)) {
839
+ const boxW = (tableWidth - 12) / 2;
840
+ const boxH = SIGN_H - 8;
841
+ const by = MARGIN + footerBand + 4;
842
+ const boxes = [];
843
+ if (rtl) {
844
+ if (signLabelVisual) {
845
+ boxes.push({ label: signLabelVisual, x: PAGE_W - MARGIN - boxW });
846
+ }
847
+ if (stampLabelVisual) {
848
+ boxes.push({
849
+ label: stampLabelVisual,
850
+ x: PAGE_W - MARGIN - boxW * 2 - 12
851
+ });
852
+ }
853
+ } else {
854
+ if (signLabelVisual) boxes.push({ label: signLabelVisual, x: MARGIN });
855
+ if (stampLabelVisual) {
856
+ boxes.push({ label: stampLabelVisual, x: MARGIN + boxW + 12 });
857
+ }
858
+ }
859
+ for (const box of boxes) {
860
+ ops.push("0.55 w 0.35 g");
861
+ ops.push(
862
+ `${box.x.toFixed(2)} ${by.toFixed(2)} ${boxW.toFixed(2)} ${boxH.toFixed(2)} re S`
863
+ );
864
+ ops.push("0 g");
865
+ const lw = measure(font, box.label, SUB_SIZE);
866
+ drawText(
867
+ ops,
868
+ box.label,
869
+ SUB_SIZE,
870
+ rtl ? box.x + boxW - 6 - lw : box.x + 6,
871
+ by + boxH - 14
872
+ );
873
+ const lineCount = template?.signature?.lines ?? 2;
874
+ for (let li = 0; li < lineCount; li += 1) {
875
+ const ly = by + 10 + li * 14;
876
+ ops.push("0.4 w 0.6 g");
877
+ ops.push(
878
+ `${(box.x + 8).toFixed(2)} ${ly.toFixed(2)} m ${(box.x + boxW - 8).toFixed(2)} ${ly.toFixed(2)} l S`
879
+ );
880
+ ops.push("0 g");
881
+ }
882
+ }
883
+ }
884
+ if (footerBand > 0) {
885
+ const fy = MARGIN + 6;
886
+ if (footerTextVisual) {
887
+ const fw = measure(font, footerTextVisual, SUB_SIZE);
888
+ drawText(
889
+ ops,
890
+ footerTextVisual,
891
+ SUB_SIZE,
892
+ rtl ? PAGE_W - MARGIN - fw : MARGIN,
893
+ fy
894
+ );
895
+ }
896
+ if (showPageNumber) {
897
+ const label = pageLabels[p];
898
+ const pw = measure(font, label, SUB_SIZE);
899
+ drawText(
900
+ ops,
901
+ label,
902
+ SUB_SIZE,
903
+ rtl ? MARGIN : PAGE_W - MARGIN - pw,
904
+ fy
905
+ );
906
+ }
907
+ }
908
+ const content = pdf.addFlate(
909
+ new TextEncoder().encode(ops.join("\n") + "\n")
910
+ );
911
+ const xobjRes = logoXObject != null ? `/XObject << /Im1 ${logoXObject} 0 R >>` : "";
912
+ const pageNo = pdf.addAscii(
913
+ `<< /Type /Page /Parent ${pagesObj} 0 R /MediaBox [0 0 ${PAGE_W} ${PAGE_H}] /Contents ${content} 0 R /Resources << /Font << /F1 ${type0} 0 R >> ${xobjRes} >> >>
914
+ `
915
+ );
916
+ pageObjNums.push(pageNo);
917
+ rowCursor += take;
918
+ }
919
+ const kids = pageObjNums.map((n) => `${n} 0 R`).join(" ");
920
+ pdf.replaceAscii(
921
+ pagesObj,
922
+ `<< /Type /Pages /Kids [${kids}] /Count ${pageObjNums.length} >>
923
+ `
924
+ );
925
+ const bytes = pdf.build();
926
+ return new Blob([bytes], { type: "application/pdf" });
927
+ }
928
+ };
929
+
930
+ export { PdfExportPlugin, TextPdfRenderer, VazirmatnPdfRenderer };
931
+ //# sourceMappingURL=chunk-MU3RY46O.js.map
932
+ //# sourceMappingURL=chunk-MU3RY46O.js.map