@aquera/nile-elements 1.5.5 → 1.5.6

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 (216) hide show
  1. package/README.md +4 -0
  2. package/dist/index.cjs.js +1 -1
  3. package/dist/index.esm.js +1 -1
  4. package/dist/index.js +465 -238
  5. package/dist/nile-auto-complete/nile-auto-complete.css.cjs.js +1 -1
  6. package/dist/nile-auto-complete/nile-auto-complete.css.cjs.js.map +1 -1
  7. package/dist/nile-auto-complete/nile-auto-complete.css.esm.js +13 -2
  8. package/dist/nile-button/nile-button.cjs.js +1 -1
  9. package/dist/nile-button/nile-button.cjs.js.map +1 -1
  10. package/dist/nile-button/nile-button.css.cjs.js +1 -1
  11. package/dist/nile-button/nile-button.css.cjs.js.map +1 -1
  12. package/dist/nile-button/nile-button.css.esm.js +89 -33
  13. package/dist/nile-button/nile-button.esm.js +2 -2
  14. package/dist/nile-calendar/nile-calendar.cjs.js +1 -1
  15. package/dist/nile-calendar/nile-calendar.cjs.js.map +1 -1
  16. package/dist/nile-calendar/nile-calendar.css.cjs.js +1 -1
  17. package/dist/nile-calendar/nile-calendar.css.cjs.js.map +1 -1
  18. package/dist/nile-calendar/nile-calendar.css.esm.js +59 -2
  19. package/dist/nile-calendar/nile-calendar.esm.js +16 -10
  20. package/dist/nile-checkbox/nile-checkbox.css.cjs.js +1 -1
  21. package/dist/nile-checkbox/nile-checkbox.css.cjs.js.map +1 -1
  22. package/dist/nile-checkbox/nile-checkbox.css.esm.js +4 -5
  23. package/dist/nile-chip/nile-chip.css.cjs.js +1 -1
  24. package/dist/nile-chip/nile-chip.css.cjs.js.map +1 -1
  25. package/dist/nile-chip/nile-chip.css.esm.js +37 -23
  26. package/dist/nile-code-editor/nile-code-editor.cjs.js +1 -1
  27. package/dist/nile-code-editor/nile-code-editor.cjs.js.map +1 -1
  28. package/dist/nile-code-editor/nile-code-editor.css.cjs.js +1 -1
  29. package/dist/nile-code-editor/nile-code-editor.css.cjs.js.map +1 -1
  30. package/dist/nile-code-editor/nile-code-editor.css.esm.js +7 -6
  31. package/dist/nile-code-editor/nile-code-editor.esm.js +1 -1
  32. package/dist/nile-date-picker/nile-date-picker.cjs.js +1 -1
  33. package/dist/nile-date-picker/nile-date-picker.cjs.js.map +1 -1
  34. package/dist/nile-date-picker/nile-date-picker.esm.js +4 -4
  35. package/dist/nile-dropdown/nile-dropdown.cjs.js +1 -1
  36. package/dist/nile-dropdown/nile-dropdown.cjs.js.map +1 -1
  37. package/dist/nile-dropdown/nile-dropdown.esm.js +1 -1
  38. package/dist/nile-file-upload/utils/file-validation.util.cjs.js +2 -2
  39. package/dist/nile-file-upload/utils/file-validation.util.cjs.js.map +1 -1
  40. package/dist/nile-file-upload/utils/file-validation.util.esm.js +1 -1
  41. package/dist/nile-filter-chip/nile-filter-chip.cjs.js +1 -1
  42. package/dist/nile-filter-chip/nile-filter-chip.cjs.js.map +1 -1
  43. package/dist/nile-filter-chip/nile-filter-chip.css.cjs.js +1 -1
  44. package/dist/nile-filter-chip/nile-filter-chip.css.cjs.js.map +1 -1
  45. package/dist/nile-filter-chip/nile-filter-chip.css.esm.js +24 -2
  46. package/dist/nile-filter-chip/nile-filter-chip.esm.js +2 -2
  47. package/dist/nile-inline-edit/nile-inline-edit.cjs.js +1 -1
  48. package/dist/nile-inline-edit/nile-inline-edit.cjs.js.map +1 -1
  49. package/dist/nile-inline-edit/nile-inline-edit.css.cjs.js +1 -1
  50. package/dist/nile-inline-edit/nile-inline-edit.css.cjs.js.map +1 -1
  51. package/dist/nile-inline-edit/nile-inline-edit.css.esm.js +15 -6
  52. package/dist/nile-inline-edit/nile-inline-edit.esm.js +2 -2
  53. package/dist/nile-input/nile-input.css.cjs.js +1 -1
  54. package/dist/nile-input/nile-input.css.cjs.js.map +1 -1
  55. package/dist/nile-input/nile-input.css.esm.js +4 -4
  56. package/dist/nile-link/nile-link.cjs.js +1 -1
  57. package/dist/nile-link/nile-link.cjs.js.map +1 -1
  58. package/dist/nile-link/nile-link.css.cjs.js +1 -1
  59. package/dist/nile-link/nile-link.css.cjs.js.map +1 -1
  60. package/dist/nile-link/nile-link.css.esm.js +3 -4
  61. package/dist/nile-link/nile-link.esm.js +2 -2
  62. package/dist/nile-qr-code/index.cjs.js +2 -0
  63. package/dist/nile-qr-code/index.cjs.js.map +1 -0
  64. package/dist/nile-qr-code/index.esm.js +1 -0
  65. package/dist/nile-qr-code/nile-qr-code-utils.cjs.js +2 -0
  66. package/dist/nile-qr-code/nile-qr-code-utils.cjs.js.map +1 -0
  67. package/dist/nile-qr-code/nile-qr-code-utils.esm.js +1 -0
  68. package/dist/nile-qr-code/nile-qr-code.cjs.js +2 -0
  69. package/dist/nile-qr-code/nile-qr-code.cjs.js.map +1 -0
  70. package/dist/nile-qr-code/nile-qr-code.css.cjs.js +2 -0
  71. package/dist/nile-qr-code/nile-qr-code.css.cjs.js.map +1 -0
  72. package/dist/nile-qr-code/nile-qr-code.css.esm.js +12 -0
  73. package/dist/nile-qr-code/nile-qr-code.esm.js +9 -0
  74. package/dist/nile-radio/nile-radio.css.cjs.js +1 -1
  75. package/dist/nile-radio/nile-radio.css.cjs.js.map +1 -1
  76. package/dist/nile-radio/nile-radio.css.esm.js +1 -1
  77. package/dist/nile-rich-text-editor/nile-rich-text-editor.cjs.js +1 -1
  78. package/dist/nile-rich-text-editor/nile-rich-text-editor.cjs.js.map +1 -1
  79. package/dist/nile-rich-text-editor/nile-rich-text-editor.css.cjs.js +1 -1
  80. package/dist/nile-rich-text-editor/nile-rich-text-editor.css.cjs.js.map +1 -1
  81. package/dist/nile-rich-text-editor/nile-rich-text-editor.css.esm.js +25 -6
  82. package/dist/nile-rich-text-editor/nile-rich-text-editor.esm.js +1 -1
  83. package/dist/nile-rich-text-editor/nile-rte-select.cjs.js +1 -1
  84. package/dist/nile-rich-text-editor/nile-rte-select.cjs.js.map +1 -1
  85. package/dist/nile-rich-text-editor/nile-rte-select.esm.js +4 -3
  86. package/dist/nile-select/nile-select.css.cjs.js +1 -1
  87. package/dist/nile-select/nile-select.css.cjs.js.map +1 -1
  88. package/dist/nile-select/nile-select.css.esm.js +7 -4
  89. package/dist/nile-slide-toggle/nile-slide-toggle.css.cjs.js +1 -1
  90. package/dist/nile-slide-toggle/nile-slide-toggle.css.cjs.js.map +1 -1
  91. package/dist/nile-slide-toggle/nile-slide-toggle.css.esm.js +5 -1
  92. package/dist/nile-textarea/nile-textarea.css.cjs.js +1 -1
  93. package/dist/nile-textarea/nile-textarea.css.cjs.js.map +1 -1
  94. package/dist/nile-textarea/nile-textarea.css.esm.js +10 -5
  95. package/dist/nile-virtual-select/nile-virtual-select.css.cjs.js +1 -1
  96. package/dist/nile-virtual-select/nile-virtual-select.css.cjs.js.map +1 -1
  97. package/dist/nile-virtual-select/nile-virtual-select.css.esm.js +5 -3
  98. package/dist/src/index.d.ts +1 -0
  99. package/dist/src/index.js +1 -0
  100. package/dist/src/index.js.map +1 -1
  101. package/dist/src/nile-auto-complete/nile-auto-complete.css.js +11 -0
  102. package/dist/src/nile-auto-complete/nile-auto-complete.css.js.map +1 -1
  103. package/dist/src/nile-button/nile-button.css.js +89 -33
  104. package/dist/src/nile-button/nile-button.css.js.map +1 -1
  105. package/dist/src/nile-button/nile-button.js +5 -5
  106. package/dist/src/nile-button/nile-button.js.map +1 -1
  107. package/dist/src/nile-calendar/nile-calendar.css.js +57 -0
  108. package/dist/src/nile-calendar/nile-calendar.css.js.map +1 -1
  109. package/dist/src/nile-calendar/nile-calendar.d.ts +1 -0
  110. package/dist/src/nile-calendar/nile-calendar.js +24 -6
  111. package/dist/src/nile-calendar/nile-calendar.js.map +1 -1
  112. package/dist/src/nile-checkbox/nile-checkbox.css.js +4 -5
  113. package/dist/src/nile-checkbox/nile-checkbox.css.js.map +1 -1
  114. package/dist/src/nile-chip/nile-chip.css.js +35 -21
  115. package/dist/src/nile-chip/nile-chip.css.js.map +1 -1
  116. package/dist/src/nile-code-editor/nile-code-editor.css.js +7 -6
  117. package/dist/src/nile-code-editor/nile-code-editor.css.js.map +1 -1
  118. package/dist/src/nile-code-editor/nile-code-editor.d.ts +1 -1
  119. package/dist/src/nile-code-editor/nile-code-editor.js +7 -1
  120. package/dist/src/nile-code-editor/nile-code-editor.js.map +1 -1
  121. package/dist/src/nile-date-picker/nile-date-picker.d.ts +3 -0
  122. package/dist/src/nile-date-picker/nile-date-picker.js +22 -2
  123. package/dist/src/nile-date-picker/nile-date-picker.js.map +1 -1
  124. package/dist/src/nile-dropdown/nile-dropdown.d.ts +1 -0
  125. package/dist/src/nile-dropdown/nile-dropdown.js +11 -0
  126. package/dist/src/nile-dropdown/nile-dropdown.js.map +1 -1
  127. package/dist/src/nile-file-upload/utils/file-validation.util.js +11 -6
  128. package/dist/src/nile-file-upload/utils/file-validation.util.js.map +1 -1
  129. package/dist/src/nile-filter-chip/nile-filter-chip.css.js +22 -0
  130. package/dist/src/nile-filter-chip/nile-filter-chip.css.js.map +1 -1
  131. package/dist/src/nile-filter-chip/nile-filter-chip.d.ts +1 -0
  132. package/dist/src/nile-filter-chip/nile-filter-chip.js +6 -0
  133. package/dist/src/nile-filter-chip/nile-filter-chip.js.map +1 -1
  134. package/dist/src/nile-inline-edit/nile-inline-edit.css.js +15 -6
  135. package/dist/src/nile-inline-edit/nile-inline-edit.css.js.map +1 -1
  136. package/dist/src/nile-inline-edit/nile-inline-edit.d.ts +2 -0
  137. package/dist/src/nile-inline-edit/nile-inline-edit.js +7 -0
  138. package/dist/src/nile-inline-edit/nile-inline-edit.js.map +1 -1
  139. package/dist/src/nile-input/nile-input.css.js +4 -4
  140. package/dist/src/nile-input/nile-input.css.js.map +1 -1
  141. package/dist/src/nile-link/nile-link.css.js +1 -2
  142. package/dist/src/nile-link/nile-link.css.js.map +1 -1
  143. package/dist/src/nile-link/nile-link.js +1 -0
  144. package/dist/src/nile-link/nile-link.js.map +1 -1
  145. package/dist/src/nile-qr-code/index.d.ts +1 -0
  146. package/dist/src/nile-qr-code/index.js +2 -0
  147. package/dist/src/nile-qr-code/index.js.map +1 -0
  148. package/dist/src/nile-qr-code/nile-qr-code-utils.d.ts +15 -0
  149. package/dist/src/nile-qr-code/nile-qr-code-utils.js +678 -0
  150. package/dist/src/nile-qr-code/nile-qr-code-utils.js.map +1 -0
  151. package/dist/src/nile-qr-code/nile-qr-code.css.d.ts +12 -0
  152. package/dist/src/nile-qr-code/nile-qr-code.css.js +24 -0
  153. package/dist/src/nile-qr-code/nile-qr-code.css.js.map +1 -0
  154. package/dist/src/nile-qr-code/nile-qr-code.d.ts +127 -0
  155. package/dist/src/nile-qr-code/nile-qr-code.js +381 -0
  156. package/dist/src/nile-qr-code/nile-qr-code.js.map +1 -0
  157. package/dist/src/nile-qr-code/nile-qr-code.test.d.ts +1 -0
  158. package/dist/src/nile-qr-code/nile-qr-code.test.js +719 -0
  159. package/dist/src/nile-qr-code/nile-qr-code.test.js.map +1 -0
  160. package/dist/src/nile-radio/nile-radio.css.js +1 -1
  161. package/dist/src/nile-radio/nile-radio.css.js.map +1 -1
  162. package/dist/src/nile-rich-text-editor/nile-rich-text-editor.css.js +25 -6
  163. package/dist/src/nile-rich-text-editor/nile-rich-text-editor.css.js.map +1 -1
  164. package/dist/src/nile-rich-text-editor/nile-rich-text-editor.d.ts +1 -0
  165. package/dist/src/nile-rich-text-editor/nile-rich-text-editor.js +17 -6
  166. package/dist/src/nile-rich-text-editor/nile-rich-text-editor.js.map +1 -1
  167. package/dist/src/nile-rich-text-editor/nile-rte-select.d.ts +1 -0
  168. package/dist/src/nile-rich-text-editor/nile-rte-select.js +7 -2
  169. package/dist/src/nile-rich-text-editor/nile-rte-select.js.map +1 -1
  170. package/dist/src/nile-select/nile-select.css.js +7 -4
  171. package/dist/src/nile-select/nile-select.css.js.map +1 -1
  172. package/dist/src/nile-slide-toggle/nile-slide-toggle.css.js +5 -1
  173. package/dist/src/nile-slide-toggle/nile-slide-toggle.css.js.map +1 -1
  174. package/dist/src/nile-textarea/nile-textarea.css.js +10 -5
  175. package/dist/src/nile-textarea/nile-textarea.css.js.map +1 -1
  176. package/dist/src/nile-virtual-select/nile-virtual-select.css.js +5 -3
  177. package/dist/src/nile-virtual-select/nile-virtual-select.css.js.map +1 -1
  178. package/dist/src/version.js +1 -1
  179. package/dist/src/version.js.map +1 -1
  180. package/dist/tsconfig.tsbuildinfo +1 -1
  181. package/package.json +3 -2
  182. package/src/index.ts +2 -1
  183. package/src/nile-auto-complete/nile-auto-complete.css.ts +11 -0
  184. package/src/nile-button/nile-button.css.ts +89 -33
  185. package/src/nile-button/nile-button.ts +6 -5
  186. package/src/nile-calendar/nile-calendar.css.ts +57 -0
  187. package/src/nile-calendar/nile-calendar.ts +17 -6
  188. package/src/nile-checkbox/nile-checkbox.css.ts +4 -5
  189. package/src/nile-chip/nile-chip.css.ts +35 -21
  190. package/src/nile-code-editor/nile-code-editor.css.ts +7 -6
  191. package/src/nile-code-editor/nile-code-editor.ts +7 -1
  192. package/src/nile-date-picker/nile-date-picker.ts +22 -2
  193. package/src/nile-dropdown/nile-dropdown.ts +11 -0
  194. package/src/nile-file-upload/utils/file-validation.util.ts +10 -5
  195. package/src/nile-filter-chip/nile-filter-chip.css.ts +22 -0
  196. package/src/nile-filter-chip/nile-filter-chip.ts +2 -0
  197. package/src/nile-inline-edit/nile-inline-edit.css.ts +15 -6
  198. package/src/nile-inline-edit/nile-inline-edit.ts +4 -0
  199. package/src/nile-input/nile-input.css.ts +4 -4
  200. package/src/nile-link/nile-link.css.ts +1 -2
  201. package/src/nile-link/nile-link.ts +1 -0
  202. package/src/nile-qr-code/index.ts +1 -0
  203. package/src/nile-qr-code/nile-qr-code-utils.ts +733 -0
  204. package/src/nile-qr-code/nile-qr-code.css.ts +26 -0
  205. package/src/nile-qr-code/nile-qr-code.test.ts +879 -0
  206. package/src/nile-qr-code/nile-qr-code.ts +431 -0
  207. package/src/nile-radio/nile-radio.css.ts +1 -1
  208. package/src/nile-rich-text-editor/nile-rich-text-editor.css.ts +25 -6
  209. package/src/nile-rich-text-editor/nile-rich-text-editor.ts +14 -6
  210. package/src/nile-rich-text-editor/nile-rte-select.ts +5 -2
  211. package/src/nile-select/nile-select.css.ts +7 -4
  212. package/src/nile-slide-toggle/nile-slide-toggle.css.ts +5 -1
  213. package/src/nile-textarea/nile-textarea.css.ts +10 -5
  214. package/src/nile-virtual-select/nile-virtual-select.css.ts +5 -3
  215. package/vscode-html-custom-data.json +108 -6
  216. package/web-test-runner.config.mjs +1 -1
@@ -0,0 +1,678 @@
1
+ /**
2
+ * Copyright Aquera Inc 2023
3
+ *
4
+ * This source code is licensed under the BSD-3-Clause license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ // ---------------------------------------------------------------------------
8
+ // Constants
9
+ // ---------------------------------------------------------------------------
10
+ /** Error-correction level ordinals used as array indices. */
11
+ const EC_ORDINALS = { L: 0, M: 1, Q: 2, H: 3 };
12
+ /**
13
+ * Maximum number of *data* codewords for each (version, ecl) combination.
14
+ * Index: [version-1][ecl ordinal] (versions 1–40).
15
+ * Source: ISO/IEC 18004 Table 7.
16
+ */
17
+ const DATA_CODEWORDS = [
18
+ [19, 16, 13, 9],
19
+ [34, 28, 22, 16],
20
+ [55, 44, 34, 26],
21
+ [80, 64, 48, 36],
22
+ [108, 86, 62, 46],
23
+ [136, 108, 76, 60],
24
+ [156, 124, 88, 66],
25
+ [194, 154, 110, 86],
26
+ [232, 182, 132, 100],
27
+ [274, 216, 154, 122],
28
+ [324, 254, 180, 140],
29
+ [370, 290, 206, 158],
30
+ [428, 334, 244, 180],
31
+ [461, 365, 261, 197],
32
+ [523, 415, 295, 223],
33
+ [589, 453, 325, 253],
34
+ [647, 507, 367, 283],
35
+ [721, 563, 397, 313],
36
+ [795, 627, 445, 341],
37
+ [861, 669, 485, 385],
38
+ [932, 714, 512, 406],
39
+ [1006, 782, 568, 442],
40
+ [1094, 860, 614, 464],
41
+ [1174, 914, 664, 514],
42
+ [1276, 1000, 718, 538],
43
+ [1370, 1062, 754, 596],
44
+ [1468, 1128, 808, 628],
45
+ [1531, 1193, 871, 661],
46
+ [1631, 1267, 911, 701],
47
+ [1735, 1373, 985, 745],
48
+ [1843, 1455, 1033, 793],
49
+ [1955, 1541, 1115, 845],
50
+ [2071, 1631, 1171, 901],
51
+ [2191, 1725, 1231, 961],
52
+ [2306, 1812, 1286, 986],
53
+ [2434, 1914, 1354, 1054],
54
+ [2566, 1992, 1426, 1096],
55
+ [2702, 2102, 1502, 1142],
56
+ [2812, 2216, 1582, 1222],
57
+ [2956, 2334, 1666, 1276],
58
+ ];
59
+ /**
60
+ * Total codewords per version (data + EC).
61
+ */
62
+ const TOTAL_CODEWORDS = [
63
+ 26, 44, 70, 100, 134, 172, 196, 242, 292, 346,
64
+ 404, 466, 532, 581, 655, 733, 815, 901, 991, 1085,
65
+ 1156, 1258, 1364, 1474, 1588, 1706, 1828, 1921, 2051, 2185,
66
+ 2323, 2465, 2611, 2761, 2876, 3034, 3196, 3362, 3532, 3706,
67
+ ];
68
+ /**
69
+ * Number of EC blocks (group-1 count, group-1 data-cw, group-2 count, group-2 data-cw)
70
+ * for each (version, ecl).
71
+ * Index: [version-1][ecl ordinal] → [g1Count, g1DataCw, g2Count, g2DataCw]
72
+ */
73
+ const EC_BLOCKS = [
74
+ /* v1 */ [[1, 19, 0, 0], [1, 16, 0, 0], [1, 13, 0, 0], [1, 9, 0, 0]],
75
+ /* v2 */ [[1, 34, 0, 0], [1, 28, 0, 0], [1, 22, 0, 0], [1, 16, 0, 0]],
76
+ /* v3 */ [[1, 55, 0, 0], [1, 44, 0, 0], [2, 17, 0, 0], [2, 13, 0, 0]],
77
+ /* v4 */ [[1, 80, 0, 0], [2, 32, 0, 0], [2, 24, 0, 0], [4, 9, 0, 0]],
78
+ /* v5 */ [[1, 108, 0, 0], [2, 43, 0, 0], [2, 15, 2, 16], [2, 11, 2, 12]],
79
+ /* v6 */ [[2, 68, 0, 0], [4, 27, 0, 0], [4, 19, 0, 0], [4, 15, 0, 0]],
80
+ /* v7 */ [[2, 78, 0, 0], [4, 31, 0, 0], [2, 14, 4, 15], [4, 13, 1, 14]],
81
+ /* v8 */ [[2, 97, 0, 0], [2, 38, 2, 39], [4, 18, 2, 19], [4, 14, 2, 15]],
82
+ /* v9 */ [[2, 116, 0, 0], [3, 36, 2, 37], [4, 16, 4, 17], [4, 12, 4, 13]],
83
+ /* v10 */ [[2, 68, 2, 69], [4, 43, 1, 44], [6, 19, 2, 20], [6, 15, 2, 16]],
84
+ /* v11 */ [[4, 81, 0, 0], [1, 50, 4, 51], [4, 22, 4, 23], [3, 12, 8, 13]],
85
+ /* v12 */ [[2, 92, 2, 93], [6, 36, 2, 37], [4, 20, 6, 21], [7, 14, 4, 15]],
86
+ /* v13 */ [[4, 107, 0, 0], [8, 37, 1, 38], [8, 20, 4, 21], [12, 11, 4, 12]],
87
+ /* v14 */ [[3, 115, 1, 116], [4, 40, 5, 41], [11, 16, 5, 17], [11, 12, 5, 13]],
88
+ /* v15 */ [[5, 87, 1, 88], [5, 41, 5, 42], [5, 24, 7, 25], [11, 12, 7, 13]],
89
+ /* v16 */ [[5, 98, 1, 99], [7, 45, 3, 46], [15, 19, 2, 20], [3, 15, 13, 16]],
90
+ /* v17 */ [[1, 107, 5, 108], [10, 46, 1, 47], [1, 22, 15, 23], [2, 14, 17, 15]],
91
+ /* v18 */ [[5, 120, 1, 121], [9, 43, 4, 44], [17, 22, 1, 23], [2, 14, 19, 15]],
92
+ /* v19 */ [[3, 113, 4, 114], [3, 44, 11, 45], [17, 21, 4, 22], [9, 13, 16, 14]],
93
+ /* v20 */ [[3, 107, 5, 108], [3, 41, 13, 42], [15, 24, 5, 25], [15, 15, 10, 16]],
94
+ /* v21 */ [[4, 116, 4, 117], [17, 42, 0, 0], [17, 22, 6, 23], [19, 16, 6, 17]],
95
+ /* v22 */ [[2, 111, 7, 112], [17, 46, 0, 0], [7, 24, 16, 25], [34, 13, 0, 0]],
96
+ /* v23 */ [[4, 121, 5, 122], [4, 47, 14, 48], [11, 24, 14, 25], [16, 15, 14, 16]],
97
+ /* v24 */ [[6, 117, 4, 118], [6, 45, 14, 46], [11, 24, 16, 25], [30, 16, 2, 17]],
98
+ /* v25 */ [[8, 106, 4, 107], [8, 47, 13, 48], [7, 24, 22, 25], [22, 15, 13, 16]],
99
+ /* v26 */ [[10, 114, 2, 115], [19, 46, 4, 47], [28, 22, 6, 23], [33, 16, 4, 17]],
100
+ /* v27 */ [[8, 122, 4, 123], [22, 45, 3, 46], [8, 23, 26, 24], [12, 15, 28, 16]],
101
+ /* v28 */ [[3, 117, 10, 118], [3, 45, 23, 46], [4, 24, 31, 25], [11, 15, 31, 16]],
102
+ /* v29 */ [[7, 116, 7, 117], [21, 45, 7, 46], [1, 23, 37, 24], [19, 15, 26, 16]],
103
+ /* v30 */ [[5, 115, 10, 116], [19, 47, 10, 48], [15, 24, 25, 25], [23, 15, 25, 16]],
104
+ /* v31 */ [[13, 115, 3, 116], [2, 46, 29, 47], [42, 24, 1, 25], [23, 15, 28, 16]],
105
+ /* v32 */ [[17, 115, 0, 0], [10, 46, 23, 47], [10, 24, 35, 25], [19, 15, 35, 16]],
106
+ /* v33 */ [[17, 115, 1, 116], [14, 46, 21, 47], [29, 24, 19, 25], [11, 15, 46, 16]],
107
+ /* v34 */ [[13, 115, 6, 116], [14, 46, 23, 47], [44, 24, 7, 25], [59, 16, 1, 17]],
108
+ /* v35 */ [[12, 121, 7, 122], [12, 47, 26, 48], [39, 24, 14, 25], [22, 15, 41, 16]],
109
+ /* v36 */ [[6, 121, 14, 122], [6, 47, 34, 48], [46, 24, 10, 25], [2, 15, 64, 16]],
110
+ /* v37 */ [[17, 122, 4, 123], [29, 46, 14, 47], [49, 24, 10, 25], [24, 15, 46, 16]],
111
+ /* v38 */ [[4, 122, 18, 123], [13, 46, 32, 47], [48, 24, 14, 25], [42, 15, 32, 16]],
112
+ /* v39 */ [[20, 117, 4, 118], [40, 47, 7, 48], [43, 24, 22, 25], [10, 15, 67, 16]],
113
+ /* v40 */ [[19, 118, 6, 119], [18, 47, 31, 48], [34, 24, 34, 25], [20, 15, 61, 16]],
114
+ ];
115
+ /**
116
+ * Alignment-pattern center coordinates per version (empty for v1).
117
+ */
118
+ const ALIGNMENT_COORDS = [
119
+ [],
120
+ [6, 18],
121
+ [6, 22],
122
+ [6, 26],
123
+ [6, 30],
124
+ [6, 34],
125
+ [6, 22, 38],
126
+ [6, 24, 42],
127
+ [6, 26, 46],
128
+ [6, 28, 50],
129
+ [6, 30, 54],
130
+ [6, 32, 58],
131
+ [6, 34, 62],
132
+ [6, 26, 46, 66],
133
+ [6, 26, 48, 70],
134
+ [6, 26, 50, 74],
135
+ [6, 30, 54, 78],
136
+ [6, 30, 56, 82],
137
+ [6, 30, 58, 86],
138
+ [6, 34, 62, 90],
139
+ [6, 28, 50, 72, 94],
140
+ [6, 26, 50, 74, 98],
141
+ [6, 30, 54, 78, 102],
142
+ [6, 28, 54, 80, 106],
143
+ [6, 32, 58, 84, 110],
144
+ [6, 30, 58, 86, 114],
145
+ [6, 34, 62, 90, 118],
146
+ [6, 26, 50, 74, 98, 122],
147
+ [6, 30, 54, 78, 102, 126],
148
+ [6, 26, 52, 78, 104, 130],
149
+ [6, 30, 56, 82, 108, 134],
150
+ [6, 34, 60, 86, 112, 138],
151
+ [6, 30, 58, 86, 114, 142],
152
+ [6, 34, 62, 90, 118, 146],
153
+ [6, 30, 54, 78, 102, 126, 150],
154
+ [6, 24, 50, 76, 102, 128, 154],
155
+ [6, 28, 54, 80, 106, 132, 158],
156
+ [6, 32, 58, 84, 110, 136, 162],
157
+ [6, 26, 54, 82, 110, 138, 166],
158
+ [6, 30, 58, 86, 114, 142, 170],
159
+ ];
160
+ /** Format information bits (15-bit BCH) for each (ecl, mask) pair. */
161
+ const FORMAT_INFO = [
162
+ /* L */ [0x77C4, 0x72F3, 0x7DAA, 0x789D, 0x662F, 0x6318, 0x6C41, 0x6976],
163
+ /* M */ [0x5412, 0x5125, 0x5E7C, 0x5B4B, 0x45F9, 0x40CE, 0x4F97, 0x4AA0],
164
+ /* Q */ [0x355F, 0x3068, 0x3F31, 0x3A06, 0x24B4, 0x2183, 0x2EDA, 0x2BED],
165
+ /* H */ [0x1689, 0x13BE, 0x1CE7, 0x19D0, 0x0762, 0x0255, 0x0D0C, 0x083B],
166
+ ];
167
+ /** Version information bits (18-bit BCH) for versions 7–40. */
168
+ const VERSION_INFO = [
169
+ 0x07C94, 0x085BC, 0x09A99, 0x0A4D3, 0x0BBF6, 0x0C762, 0x0D847, 0x0E60D,
170
+ 0x0F928, 0x10B78, 0x1145D, 0x12A17, 0x13532, 0x149A6, 0x15683, 0x168C9,
171
+ 0x177EC, 0x18EC4, 0x191E1, 0x1AFAB, 0x1B08E, 0x1CC1A, 0x1D33F, 0x1ED75,
172
+ 0x1F250, 0x209D5, 0x216F0, 0x228BA, 0x2379F, 0x24B0B, 0x2542E, 0x26A64,
173
+ 0x27541, 0x28C69,
174
+ ];
175
+ // ---------------------------------------------------------------------------
176
+ // GF(256) arithmetic for Reed-Solomon
177
+ // ---------------------------------------------------------------------------
178
+ const GF_EXP = new Uint8Array(512);
179
+ const GF_LOG = new Uint8Array(256);
180
+ (function initGF() {
181
+ let x = 1;
182
+ for (let i = 0; i < 255; i++) {
183
+ GF_EXP[i] = x;
184
+ GF_LOG[x] = i;
185
+ x <<= 1;
186
+ if (x >= 256)
187
+ x ^= 0x11D; // primitive polynomial
188
+ }
189
+ for (let i = 255; i < 512; i++) {
190
+ GF_EXP[i] = GF_EXP[i - 255];
191
+ }
192
+ })();
193
+ function gfMul(a, b) {
194
+ if (a === 0 || b === 0)
195
+ return 0;
196
+ return GF_EXP[GF_LOG[a] + GF_LOG[b]];
197
+ }
198
+ // ---------------------------------------------------------------------------
199
+ // Reed-Solomon EC codeword generation
200
+ // ---------------------------------------------------------------------------
201
+ function rsGeneratorPoly(degree) {
202
+ const gen = new Uint8Array(degree + 1);
203
+ gen[0] = 1;
204
+ for (let i = 0; i < degree; i++) {
205
+ for (let j = degree; j >= 1; j--) {
206
+ gen[j] = gen[j] ^ gfMul(gen[j - 1], GF_EXP[i]);
207
+ }
208
+ // gen[0] stays 1 (leading coeff)
209
+ }
210
+ return gen;
211
+ }
212
+ function rsEncode(data, ecCount) {
213
+ const gen = rsGeneratorPoly(ecCount);
214
+ const result = new Uint8Array(ecCount);
215
+ for (let i = 0; i < data.length; i++) {
216
+ const coeff = data[i] ^ result[0];
217
+ // shift result left
218
+ for (let j = 0; j < ecCount - 1; j++) {
219
+ result[j] = result[j + 1] ^ gfMul(gen[j + 1], coeff);
220
+ }
221
+ result[ecCount - 1] = gfMul(gen[ecCount], coeff);
222
+ }
223
+ return result;
224
+ }
225
+ // ---------------------------------------------------------------------------
226
+ // Data encoding (Byte mode only)
227
+ // ---------------------------------------------------------------------------
228
+ function encodeData(text, version, ecl) {
229
+ const eclOrd = EC_ORDINALS[ecl];
230
+ const totalDataCw = DATA_CODEWORDS[version - 1][eclOrd];
231
+ const bytes = new TextEncoder().encode(text);
232
+ // Build bit stream
233
+ const bits = [];
234
+ const pushBits = (value, length) => {
235
+ for (let i = length - 1; i >= 0; i--) {
236
+ bits.push((value >>> i) & 1);
237
+ }
238
+ };
239
+ // Mode indicator: byte = 0100
240
+ pushBits(0b0100, 4);
241
+ // Character count indicator
242
+ const ccBits = version <= 9 ? 8 : 16;
243
+ pushBits(bytes.length, ccBits);
244
+ // Data
245
+ for (const b of bytes) {
246
+ pushBits(b, 8);
247
+ }
248
+ // Terminator (up to 4 bits of zeros)
249
+ const totalDataBits = totalDataCw * 8;
250
+ const terminatorLen = Math.min(4, totalDataBits - bits.length);
251
+ pushBits(0, terminatorLen);
252
+ // Pad to byte boundary
253
+ while (bits.length % 8 !== 0) {
254
+ bits.push(0);
255
+ }
256
+ // Pad codewords
257
+ const padBytes = [0xEC, 0x11];
258
+ let padIdx = 0;
259
+ while (bits.length < totalDataBits) {
260
+ pushBits(padBytes[padIdx], 8);
261
+ padIdx ^= 1;
262
+ }
263
+ // Convert to byte array
264
+ const codewords = new Uint8Array(totalDataCw);
265
+ for (let i = 0; i < totalDataCw; i++) {
266
+ let byte = 0;
267
+ for (let b = 0; b < 8; b++) {
268
+ byte = (byte << 1) | bits[i * 8 + b];
269
+ }
270
+ codewords[i] = byte;
271
+ }
272
+ return codewords;
273
+ }
274
+ // ---------------------------------------------------------------------------
275
+ // Interleave data + EC blocks
276
+ // ---------------------------------------------------------------------------
277
+ function buildFinalMessage(data, version, ecl) {
278
+ const eclOrd = EC_ORDINALS[ecl];
279
+ const [g1Count, g1DataCw, g2Count, g2DataCw] = EC_BLOCKS[version - 1][eclOrd];
280
+ const totalCw = TOTAL_CODEWORDS[version - 1];
281
+ const totalBlocks = g1Count + g2Count;
282
+ const ecCwPerBlock = Math.floor((totalCw - DATA_CODEWORDS[version - 1][eclOrd]) / totalBlocks);
283
+ // Split data into blocks
284
+ const dataBlocks = [];
285
+ const ecBlocks = [];
286
+ let offset = 0;
287
+ for (let i = 0; i < g1Count; i++) {
288
+ const block = data.slice(offset, offset + g1DataCw);
289
+ dataBlocks.push(block);
290
+ ecBlocks.push(rsEncode(block, ecCwPerBlock));
291
+ offset += g1DataCw;
292
+ }
293
+ for (let i = 0; i < g2Count; i++) {
294
+ const block = data.slice(offset, offset + g2DataCw);
295
+ dataBlocks.push(block);
296
+ ecBlocks.push(rsEncode(block, ecCwPerBlock));
297
+ offset += g2DataCw;
298
+ }
299
+ // Interleave data codewords
300
+ const result = [];
301
+ const maxDataCw = Math.max(g1DataCw, g2DataCw);
302
+ for (let i = 0; i < maxDataCw; i++) {
303
+ for (let j = 0; j < totalBlocks; j++) {
304
+ if (i < dataBlocks[j].length) {
305
+ result.push(dataBlocks[j][i]);
306
+ }
307
+ }
308
+ }
309
+ // Interleave EC codewords
310
+ for (let i = 0; i < ecCwPerBlock; i++) {
311
+ for (let j = 0; j < totalBlocks; j++) {
312
+ result.push(ecBlocks[j][i]);
313
+ }
314
+ }
315
+ return new Uint8Array(result);
316
+ }
317
+ // ---------------------------------------------------------------------------
318
+ // QR matrix construction
319
+ // ---------------------------------------------------------------------------
320
+ /** Module size = 4 * version + 17 */
321
+ function getModuleCount(version) {
322
+ return version * 4 + 17;
323
+ }
324
+ /** Create a blank matrix (-1 = unset). */
325
+ function createMatrix(size) {
326
+ return Array.from({ length: size }, () => Array(size).fill(-1));
327
+ }
328
+ function setModule(matrix, row, col, value) {
329
+ if (row >= 0 && row < matrix.length && col >= 0 && col < matrix.length) {
330
+ matrix[row][col] = value;
331
+ }
332
+ }
333
+ /** Place a finder pattern with its separator. */
334
+ function placeFinderPattern(matrix, row, col) {
335
+ for (let r = -1; r <= 7; r++) {
336
+ for (let c = -1; c <= 7; c++) {
337
+ const isPattern = r >= 0 && r <= 6 && c >= 0 && c <= 6;
338
+ let value = 0;
339
+ if (isPattern) {
340
+ if (r === 0 || r === 6 || c === 0 || c === 6 ||
341
+ (r >= 2 && r <= 4 && c >= 2 && c <= 4)) {
342
+ value = 1;
343
+ }
344
+ }
345
+ setModule(matrix, row + r, col + c, value);
346
+ }
347
+ }
348
+ }
349
+ /** Place alignment patterns. */
350
+ function placeAlignmentPatterns(matrix, version) {
351
+ if (version < 2)
352
+ return;
353
+ const coords = ALIGNMENT_COORDS[version - 1];
354
+ for (const r of coords) {
355
+ for (const c of coords) {
356
+ // Skip if overlapping finder patterns
357
+ if (matrix[r][c] !== -1)
358
+ continue;
359
+ for (let dr = -2; dr <= 2; dr++) {
360
+ for (let dc = -2; dc <= 2; dc++) {
361
+ const value = (Math.abs(dr) === 2 || Math.abs(dc) === 2 ||
362
+ (dr === 0 && dc === 0)) ? 1 : 0;
363
+ setModule(matrix, r + dr, c + dc, value);
364
+ }
365
+ }
366
+ }
367
+ }
368
+ }
369
+ /** Place timing patterns. */
370
+ function placeTimingPatterns(matrix) {
371
+ const size = matrix.length;
372
+ for (let i = 8; i < size - 8; i++) {
373
+ if (matrix[6][i] === -1)
374
+ matrix[6][i] = (i + 1) % 2;
375
+ if (matrix[i][6] === -1)
376
+ matrix[i][6] = (i + 1) % 2;
377
+ }
378
+ }
379
+ /** Reserve format info areas (filled later). */
380
+ function reserveFormatAreas(matrix) {
381
+ const size = matrix.length;
382
+ // Around top-left finder
383
+ for (let i = 0; i <= 8; i++) {
384
+ if (matrix[8][i] === -1)
385
+ matrix[8][i] = 0;
386
+ if (matrix[i][8] === -1)
387
+ matrix[i][8] = 0;
388
+ }
389
+ // Around top-right finder
390
+ for (let i = 0; i <= 7; i++) {
391
+ if (matrix[8][size - 1 - i] === -1)
392
+ matrix[8][size - 1 - i] = 0;
393
+ }
394
+ // Around bottom-left finder
395
+ for (let i = 0; i <= 7; i++) {
396
+ if (matrix[size - 1 - i][8] === -1)
397
+ matrix[size - 1 - i][8] = 0;
398
+ }
399
+ // Dark module
400
+ matrix[size - 8][8] = 1;
401
+ }
402
+ /** Reserve version info areas (versions >= 7). */
403
+ function reserveVersionAreas(matrix, version) {
404
+ if (version < 7)
405
+ return;
406
+ const size = matrix.length;
407
+ for (let i = 0; i < 6; i++) {
408
+ for (let j = 0; j < 3; j++) {
409
+ if (matrix[i][size - 11 + j] === -1)
410
+ matrix[i][size - 11 + j] = 0;
411
+ if (matrix[size - 11 + j][i] === -1)
412
+ matrix[size - 11 + j][i] = 0;
413
+ }
414
+ }
415
+ }
416
+ /** Place data bits in the matrix using the zigzag pattern. */
417
+ function placeDataBits(matrix, data) {
418
+ const size = matrix.length;
419
+ let bitIndex = 0;
420
+ const totalBits = data.length * 8;
421
+ let upward = true;
422
+ for (let right = size - 1; right >= 1; right -= 2) {
423
+ // Skip timing pattern column
424
+ if (right === 6)
425
+ right = 5;
426
+ for (let vert = 0; vert < size; vert++) {
427
+ const row = upward ? size - 1 - vert : vert;
428
+ for (let colOffset = 0; colOffset <= 1; colOffset++) {
429
+ const col = right - colOffset;
430
+ if (matrix[row][col] !== -1)
431
+ continue;
432
+ if (bitIndex < totalBits) {
433
+ const byteIdx = bitIndex >>> 3;
434
+ const bitIdx = 7 - (bitIndex & 7);
435
+ matrix[row][col] = (data[byteIdx] >>> bitIdx) & 1;
436
+ bitIndex++;
437
+ }
438
+ else {
439
+ matrix[row][col] = 0;
440
+ }
441
+ }
442
+ }
443
+ upward = !upward;
444
+ }
445
+ }
446
+ const MASK_FUNCTIONS = [
447
+ (r, c) => (r + c) % 2 === 0,
448
+ (r, _c) => r % 2 === 0,
449
+ (_r, c) => c % 3 === 0,
450
+ (r, c) => (r + c) % 3 === 0,
451
+ (r, c) => (Math.floor(r / 2) + Math.floor(c / 3)) % 2 === 0,
452
+ (r, c) => ((r * c) % 2 + (r * c) % 3) === 0,
453
+ (r, c) => ((r * c) % 2 + (r * c) % 3) % 2 === 0,
454
+ (r, c) => ((r + c) % 2 + (r * c) % 3) % 2 === 0,
455
+ ];
456
+ /** Check if a module is a function pattern (not data). */
457
+ function isFunctionModule(matrix, reserved, row, col) {
458
+ return reserved[row][col] !== -1;
459
+ }
460
+ function applyMask(matrix, reserved, maskIdx) {
461
+ const size = matrix.length;
462
+ const result = matrix.map(row => [...row]);
463
+ const fn = MASK_FUNCTIONS[maskIdx];
464
+ for (let r = 0; r < size; r++) {
465
+ for (let c = 0; c < size; c++) {
466
+ if (!isFunctionModule(result, reserved, r, c) && fn(r, c)) {
467
+ result[r][c] ^= 1;
468
+ }
469
+ }
470
+ }
471
+ return result;
472
+ }
473
+ // ---------------------------------------------------------------------------
474
+ // Format & version info writing
475
+ // ---------------------------------------------------------------------------
476
+ function writeFormatInfo(matrix, ecl, maskIdx) {
477
+ const eclOrd = EC_ORDINALS[ecl];
478
+ const bits = FORMAT_INFO[eclOrd][maskIdx];
479
+ const size = matrix.length;
480
+ for (let i = 0; i <= 5; i++) {
481
+ matrix[8][i] = (bits >>> (14 - i)) & 1;
482
+ }
483
+ matrix[8][7] = (bits >>> 8) & 1;
484
+ matrix[8][8] = (bits >>> 7) & 1;
485
+ matrix[7][8] = (bits >>> 6) & 1;
486
+ for (let i = 0; i <= 5; i++) {
487
+ matrix[5 - i][8] = (bits >>> (i)) & 1;
488
+ }
489
+ for (let i = 0; i <= 7; i++) {
490
+ matrix[8][size - 1 - i] = (bits >>> i) & 1;
491
+ }
492
+ for (let i = 0; i <= 6; i++) {
493
+ matrix[size - 1 - i][8] = (bits >>> (14 - i)) & 1;
494
+ }
495
+ matrix[size - 8][8] = 1; // dark module
496
+ }
497
+ function writeVersionInfo(matrix, version) {
498
+ if (version < 7)
499
+ return;
500
+ const bits = VERSION_INFO[version - 7];
501
+ const size = matrix.length;
502
+ for (let i = 0; i < 6; i++) {
503
+ for (let j = 0; j < 3; j++) {
504
+ const bitIdx = i * 3 + j;
505
+ const bit = (bits >>> bitIdx) & 1;
506
+ matrix[i][size - 11 + j] = bit;
507
+ matrix[size - 11 + j][i] = bit;
508
+ }
509
+ }
510
+ }
511
+ // ---------------------------------------------------------------------------
512
+ // Penalty scoring
513
+ // ---------------------------------------------------------------------------
514
+ function penaltyScore(matrix) {
515
+ const size = matrix.length;
516
+ let score = 0;
517
+ // Rule 1: 5+ consecutive same-color modules in row/col
518
+ for (let r = 0; r < size; r++) {
519
+ let count = 1;
520
+ for (let c = 1; c < size; c++) {
521
+ if (matrix[r][c] === matrix[r][c - 1]) {
522
+ count++;
523
+ }
524
+ else {
525
+ if (count >= 5)
526
+ score += count - 2;
527
+ count = 1;
528
+ }
529
+ }
530
+ if (count >= 5)
531
+ score += count - 2;
532
+ }
533
+ for (let c = 0; c < size; c++) {
534
+ let count = 1;
535
+ for (let r = 1; r < size; r++) {
536
+ if (matrix[r][c] === matrix[r - 1][c]) {
537
+ count++;
538
+ }
539
+ else {
540
+ if (count >= 5)
541
+ score += count - 2;
542
+ count = 1;
543
+ }
544
+ }
545
+ if (count >= 5)
546
+ score += count - 2;
547
+ }
548
+ // Rule 2: 2x2 blocks of same color
549
+ for (let r = 0; r < size - 1; r++) {
550
+ for (let c = 0; c < size - 1; c++) {
551
+ const val = matrix[r][c];
552
+ if (val === matrix[r][c + 1] && val === matrix[r + 1][c] && val === matrix[r + 1][c + 1]) {
553
+ score += 3;
554
+ }
555
+ }
556
+ }
557
+ // Rule 3: Finder-like patterns
558
+ const pattern1 = [1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0];
559
+ const pattern2 = [0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1];
560
+ for (let r = 0; r < size; r++) {
561
+ for (let c = 0; c <= size - 11; c++) {
562
+ let match1 = true;
563
+ let match2 = true;
564
+ for (let i = 0; i < 11; i++) {
565
+ if (matrix[r][c + i] !== pattern1[i])
566
+ match1 = false;
567
+ if (matrix[r][c + i] !== pattern2[i])
568
+ match2 = false;
569
+ }
570
+ if (match1 || match2)
571
+ score += 40;
572
+ }
573
+ }
574
+ for (let c = 0; c < size; c++) {
575
+ for (let r = 0; r <= size - 11; r++) {
576
+ let match1 = true;
577
+ let match2 = true;
578
+ for (let i = 0; i < 11; i++) {
579
+ if (matrix[r + i][c] !== pattern1[i])
580
+ match1 = false;
581
+ if (matrix[r + i][c] !== pattern2[i])
582
+ match2 = false;
583
+ }
584
+ if (match1 || match2)
585
+ score += 40;
586
+ }
587
+ }
588
+ // Rule 4: Proportion of dark modules
589
+ let dark = 0;
590
+ for (let r = 0; r < size; r++) {
591
+ for (let c = 0; c < size; c++) {
592
+ if (matrix[r][c] === 1)
593
+ dark++;
594
+ }
595
+ }
596
+ const total = size * size;
597
+ const percent = (dark / total) * 100;
598
+ const prev5 = Math.floor(percent / 5) * 5;
599
+ const next5 = prev5 + 5;
600
+ score += Math.min(Math.abs(prev5 - 50) / 5, Math.abs(next5 - 50) / 5) * 10;
601
+ return score;
602
+ }
603
+ // ---------------------------------------------------------------------------
604
+ // Public API
605
+ // ---------------------------------------------------------------------------
606
+ /**
607
+ * Find the minimum version that can hold the given data.
608
+ */
609
+ function findMinVersion(text, ecl) {
610
+ const bytes = new TextEncoder().encode(text);
611
+ const dataLen = bytes.length;
612
+ const eclOrd = EC_ORDINALS[ecl];
613
+ for (let v = 1; v <= 40; v++) {
614
+ const ccBits = v <= 9 ? 8 : 16;
615
+ const totalBits = 4 + ccBits + dataLen * 8;
616
+ const capacity = DATA_CODEWORDS[v - 1][eclOrd] * 8;
617
+ if (totalBits <= capacity)
618
+ return v;
619
+ }
620
+ throw new Error('Data too long for any QR version');
621
+ }
622
+ /**
623
+ * Generate a QR code matrix from a string.
624
+ *
625
+ * @param text The text to encode.
626
+ * @param ecl Error-correction level (L, M, Q, H).
627
+ * @returns A 2-D boolean-like matrix where `1` = dark module.
628
+ */
629
+ export function generateQR(text, ecl = 'H') {
630
+ if (!text) {
631
+ // Return a minimal empty 21x21 (version 1) blank grid
632
+ return Array.from({ length: 21 }, () => Array(21).fill(0));
633
+ }
634
+ const version = findMinVersion(text, ecl);
635
+ const moduleCount = getModuleCount(version);
636
+ // 1. Build function-pattern matrix (reserved areas)
637
+ const reserved = createMatrix(moduleCount);
638
+ placeFinderPattern(reserved, 0, 0);
639
+ placeFinderPattern(reserved, 0, moduleCount - 7);
640
+ placeFinderPattern(reserved, moduleCount - 7, 0);
641
+ placeAlignmentPatterns(reserved, version);
642
+ placeTimingPatterns(reserved);
643
+ reserveFormatAreas(reserved);
644
+ reserveVersionAreas(reserved, version);
645
+ // 2. Build actual matrix with function patterns
646
+ const matrix = createMatrix(moduleCount);
647
+ placeFinderPattern(matrix, 0, 0);
648
+ placeFinderPattern(matrix, 0, moduleCount - 7);
649
+ placeFinderPattern(matrix, moduleCount - 7, 0);
650
+ placeAlignmentPatterns(matrix, version);
651
+ placeTimingPatterns(matrix);
652
+ reserveFormatAreas(matrix);
653
+ reserveVersionAreas(matrix, version);
654
+ // 3. Encode & place data
655
+ const dataCw = encodeData(text, version, ecl);
656
+ const finalMsg = buildFinalMessage(dataCw, version, ecl);
657
+ placeDataBits(matrix, finalMsg);
658
+ // 4. Try all 8 masks, pick the best
659
+ let bestMask = 0;
660
+ let bestScore = Infinity;
661
+ let bestMatrix = matrix;
662
+ for (let mask = 0; mask < 8; mask++) {
663
+ const candidate = applyMask(matrix, reserved, mask);
664
+ writeFormatInfo(candidate, ecl, mask);
665
+ writeVersionInfo(candidate, version);
666
+ const score = penaltyScore(candidate);
667
+ if (score < bestScore) {
668
+ bestScore = score;
669
+ bestMask = mask;
670
+ bestMatrix = candidate;
671
+ }
672
+ }
673
+ // Re-apply best mask (already stored)
674
+ writeFormatInfo(bestMatrix, ecl, bestMask);
675
+ writeVersionInfo(bestMatrix, version);
676
+ return bestMatrix;
677
+ }
678
+ //# sourceMappingURL=nile-qr-code-utils.js.map