qrcode.mjs 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659
  1. // src/utils/invariant.ts
  2. function invariant(condition, message) {
  3. if (condition)
  4. return;
  5. throw new Error(message);
  6. }
  7. // src/utils/ColorUtils.ts
  8. var ColorUtils = class {
  9. static convertHexColorToBytes(hexColor) {
  10. invariant(
  11. typeof hexColor === "string",
  12. `Expected hexColor param to be a string instead got ${typeof hexColor}`
  13. );
  14. let hex = hexColor.replace("#", "");
  15. const isHexColor = /^([0-9A-F]{3}|[0-9A-F]{4}|[0-9A-F]{6}|[0-9A-F]{8})$/i.test(hex);
  16. invariant(
  17. isHexColor,
  18. `Expected hexColor to be of length 3, 4, 6 or 8 with 0-9 A-F characters, instead got ${hex} with length ${hex.length}`
  19. );
  20. const bytes = [];
  21. if (hex.length === 3) {
  22. hex += "F";
  23. } else if (hex.length === 6) {
  24. hex += "FF";
  25. }
  26. if (hex.length === 4) {
  27. bytes.push(...hex.split("").map((h) => parseInt(h.repeat(2), 16)));
  28. } else if (hex.length === 8) {
  29. bytes.push(parseInt(hex.substring(0, 2), 16));
  30. bytes.push(parseInt(hex.substring(2, 4), 16));
  31. bytes.push(parseInt(hex.substring(4, 6), 16));
  32. bytes.push(parseInt(hex.substring(6, 8), 16));
  33. }
  34. return bytes;
  35. }
  36. };
  37. // node_modules/@akamfoad/qr/dist/qr.mjs
  38. var mode_default = {
  39. MODE_NUMBER: 1 << 0,
  40. MODE_ALPHA_NUM: 1 << 1,
  41. MODE_8BIT_BYTE: 1 << 2,
  42. MODE_KANJI: 1 << 3
  43. };
  44. var QR8bitByte = class {
  45. mode;
  46. data;
  47. constructor(data) {
  48. this.mode = mode_default.MODE_8BIT_BYTE;
  49. this.data = data;
  50. }
  51. getLength() {
  52. return this.data.length;
  53. }
  54. // FIXME?
  55. write(buffer) {
  56. for (let i = 0; i < this.data.length; i++) {
  57. buffer.put(this.data.charCodeAt(i), 8);
  58. }
  59. }
  60. };
  61. var ErrorCorrectLevel = {
  62. /**
  63. * Allows recovery of up to 7% data loss
  64. */
  65. L: 1,
  66. /**
  67. * Allows recovery of up to 15% data loss
  68. */
  69. M: 0,
  70. /**
  71. * Allows recovery of up to 25% data loss
  72. */
  73. Q: 3,
  74. /**
  75. * Allows recovery of up to 30% data loss
  76. */
  77. H: 2
  78. };
  79. var QRRSBlock = class _QRRSBlock {
  80. totalCount;
  81. dataCount;
  82. constructor(totalCount, dataCount) {
  83. this.totalCount = totalCount;
  84. this.dataCount = dataCount;
  85. }
  86. static RS_BLOCK_TABLE = [
  87. // L
  88. // M
  89. // Q
  90. // H
  91. // 1
  92. [1, 26, 19],
  93. [1, 26, 16],
  94. [1, 26, 13],
  95. [1, 26, 9],
  96. // 2
  97. [1, 44, 34],
  98. [1, 44, 28],
  99. [1, 44, 22],
  100. [1, 44, 16],
  101. // 3
  102. [1, 70, 55],
  103. [1, 70, 44],
  104. [2, 35, 17],
  105. [2, 35, 13],
  106. // 4
  107. [1, 100, 80],
  108. [2, 50, 32],
  109. [2, 50, 24],
  110. [4, 25, 9],
  111. // 5
  112. [1, 134, 108],
  113. [2, 67, 43],
  114. [2, 33, 15, 2, 34, 16],
  115. [2, 33, 11, 2, 34, 12],
  116. // 6
  117. [2, 86, 68],
  118. [4, 43, 27],
  119. [4, 43, 19],
  120. [4, 43, 15],
  121. // 7
  122. [2, 98, 78],
  123. [4, 49, 31],
  124. [2, 32, 14, 4, 33, 15],
  125. [4, 39, 13, 1, 40, 14],
  126. // 8
  127. [2, 121, 97],
  128. [2, 60, 38, 2, 61, 39],
  129. [4, 40, 18, 2, 41, 19],
  130. [4, 40, 14, 2, 41, 15],
  131. // 9
  132. [2, 146, 116],
  133. [3, 58, 36, 2, 59, 37],
  134. [4, 36, 16, 4, 37, 17],
  135. [4, 36, 12, 4, 37, 13],
  136. // 10
  137. [2, 86, 68, 2, 87, 69],
  138. [4, 69, 43, 1, 70, 44],
  139. [6, 43, 19, 2, 44, 20],
  140. [6, 43, 15, 2, 44, 16],
  141. // 11
  142. [4, 101, 81],
  143. [1, 80, 50, 4, 81, 51],
  144. [4, 50, 22, 4, 51, 23],
  145. [3, 36, 12, 8, 37, 13],
  146. // 12
  147. [2, 116, 92, 2, 117, 93],
  148. [6, 58, 36, 2, 59, 37],
  149. [4, 46, 20, 6, 47, 21],
  150. [7, 42, 14, 4, 43, 15],
  151. // 13
  152. [4, 133, 107],
  153. [8, 59, 37, 1, 60, 38],
  154. [8, 44, 20, 4, 45, 21],
  155. [12, 33, 11, 4, 34, 12],
  156. // 14
  157. [3, 145, 115, 1, 146, 116],
  158. [4, 64, 40, 5, 65, 41],
  159. [11, 36, 16, 5, 37, 17],
  160. [11, 36, 12, 5, 37, 13],
  161. // 15
  162. [5, 109, 87, 1, 110, 88],
  163. [5, 65, 41, 5, 66, 42],
  164. [5, 54, 24, 7, 55, 25],
  165. [11, 36, 12],
  166. // 16
  167. [5, 122, 98, 1, 123, 99],
  168. [7, 73, 45, 3, 74, 46],
  169. [15, 43, 19, 2, 44, 20],
  170. [3, 45, 15, 13, 46, 16],
  171. // 17
  172. [1, 135, 107, 5, 136, 108],
  173. [10, 74, 46, 1, 75, 47],
  174. [1, 50, 22, 15, 51, 23],
  175. [2, 42, 14, 17, 43, 15],
  176. // 18
  177. [5, 150, 120, 1, 151, 121],
  178. [9, 69, 43, 4, 70, 44],
  179. [17, 50, 22, 1, 51, 23],
  180. [2, 42, 14, 19, 43, 15],
  181. // 19
  182. [3, 141, 113, 4, 142, 114],
  183. [3, 70, 44, 11, 71, 45],
  184. [17, 47, 21, 4, 48, 22],
  185. [9, 39, 13, 16, 40, 14],
  186. // 20
  187. [3, 135, 107, 5, 136, 108],
  188. [3, 67, 41, 13, 68, 42],
  189. [15, 54, 24, 5, 55, 25],
  190. [15, 43, 15, 10, 44, 16],
  191. // 21
  192. [4, 144, 116, 4, 145, 117],
  193. [17, 68, 42],
  194. [17, 50, 22, 6, 51, 23],
  195. [19, 46, 16, 6, 47, 17],
  196. // 22
  197. [2, 139, 111, 7, 140, 112],
  198. [17, 74, 46],
  199. [7, 54, 24, 16, 55, 25],
  200. [34, 37, 13],
  201. // 23
  202. [4, 151, 121, 5, 152, 122],
  203. [4, 75, 47, 14, 76, 48],
  204. [11, 54, 24, 14, 55, 25],
  205. [16, 45, 15, 14, 46, 16],
  206. // 24
  207. [6, 147, 117, 4, 148, 118],
  208. [6, 73, 45, 14, 74, 46],
  209. [11, 54, 24, 16, 55, 25],
  210. [30, 46, 16, 2, 47, 17],
  211. // 25
  212. [8, 132, 106, 4, 133, 107],
  213. [8, 75, 47, 13, 76, 48],
  214. [7, 54, 24, 22, 55, 25],
  215. [22, 45, 15, 13, 46, 16],
  216. // 26
  217. [10, 142, 114, 2, 143, 115],
  218. [19, 74, 46, 4, 75, 47],
  219. [28, 50, 22, 6, 51, 23],
  220. [33, 46, 16, 4, 47, 17],
  221. // 27
  222. [8, 152, 122, 4, 153, 123],
  223. [22, 73, 45, 3, 74, 46],
  224. [8, 53, 23, 26, 54, 24],
  225. [12, 45, 15, 28, 46, 16],
  226. // 28
  227. [3, 147, 117, 10, 148, 118],
  228. [3, 73, 45, 23, 74, 46],
  229. [4, 54, 24, 31, 55, 25],
  230. [11, 45, 15, 31, 46, 16],
  231. // 29
  232. [7, 146, 116, 7, 147, 117],
  233. [21, 73, 45, 7, 74, 46],
  234. [1, 53, 23, 37, 54, 24],
  235. [19, 45, 15, 26, 46, 16],
  236. // 30
  237. [5, 145, 115, 10, 146, 116],
  238. [19, 75, 47, 10, 76, 48],
  239. [15, 54, 24, 25, 55, 25],
  240. [23, 45, 15, 25, 46, 16],
  241. // 31
  242. [13, 145, 115, 3, 146, 116],
  243. [2, 74, 46, 29, 75, 47],
  244. [42, 54, 24, 1, 55, 25],
  245. [23, 45, 15, 28, 46, 16],
  246. // 32
  247. [17, 145, 115],
  248. [10, 74, 46, 23, 75, 47],
  249. [10, 54, 24, 35, 55, 25],
  250. [19, 45, 15, 35, 46, 16],
  251. // 33
  252. [17, 145, 115, 1, 146, 116],
  253. [14, 74, 46, 21, 75, 47],
  254. [29, 54, 24, 19, 55, 25],
  255. [11, 45, 15, 46, 46, 16],
  256. // 34
  257. [13, 145, 115, 6, 146, 116],
  258. [14, 74, 46, 23, 75, 47],
  259. [44, 54, 24, 7, 55, 25],
  260. [59, 46, 16, 1, 47, 17],
  261. // 35
  262. [12, 151, 121, 7, 152, 122],
  263. [12, 75, 47, 26, 76, 48],
  264. [39, 54, 24, 14, 55, 25],
  265. [22, 45, 15, 41, 46, 16],
  266. // 36
  267. [6, 151, 121, 14, 152, 122],
  268. [6, 75, 47, 34, 76, 48],
  269. [46, 54, 24, 10, 55, 25],
  270. [2, 45, 15, 64, 46, 16],
  271. // 37
  272. [17, 152, 122, 4, 153, 123],
  273. [29, 74, 46, 14, 75, 47],
  274. [49, 54, 24, 10, 55, 25],
  275. [24, 45, 15, 46, 46, 16],
  276. // 38
  277. [4, 152, 122, 18, 153, 123],
  278. [13, 74, 46, 32, 75, 47],
  279. [48, 54, 24, 14, 55, 25],
  280. [42, 45, 15, 32, 46, 16],
  281. // 39
  282. [20, 147, 117, 4, 148, 118],
  283. [40, 75, 47, 7, 76, 48],
  284. [43, 54, 24, 22, 55, 25],
  285. [10, 45, 15, 67, 46, 16],
  286. // 40
  287. [19, 148, 118, 6, 149, 119],
  288. [18, 75, 47, 31, 76, 48],
  289. [34, 54, 24, 34, 55, 25],
  290. [20, 45, 15, 61, 46, 16]
  291. ];
  292. static getRSBlocks(typeNumber, errorCorrectLevel) {
  293. const rsBlock = _QRRSBlock.getRsBlockTable(typeNumber, errorCorrectLevel);
  294. if (rsBlock == void 0) {
  295. throw new Error(
  296. "bad rs block @ typeNumber:" + typeNumber + "/errorCorrectLevel:" + errorCorrectLevel
  297. );
  298. }
  299. const length = rsBlock.length / 3;
  300. const list = [];
  301. for (let i = 0; i < length; i++) {
  302. const count = rsBlock[i * 3 + 0];
  303. const totalCount = rsBlock[i * 3 + 1];
  304. const dataCount = rsBlock[i * 3 + 2];
  305. for (let j = 0; j < count; j++) {
  306. list.push(new _QRRSBlock(totalCount, dataCount));
  307. }
  308. }
  309. return list;
  310. }
  311. static getRsBlockTable(typeNumber, errorCorrectLevel) {
  312. switch (errorCorrectLevel) {
  313. case ErrorCorrectLevel.L:
  314. return _QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0];
  315. case ErrorCorrectLevel.M:
  316. return _QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1];
  317. case ErrorCorrectLevel.Q:
  318. return _QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2];
  319. case ErrorCorrectLevel.H:
  320. return _QRRSBlock.RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3];
  321. default:
  322. return void 0;
  323. }
  324. }
  325. };
  326. var QRBitBuffer = class {
  327. buffer;
  328. length;
  329. constructor() {
  330. this.buffer = [];
  331. this.length = 0;
  332. }
  333. get(index) {
  334. const bufIndex = Math.floor(index / 8);
  335. return (this.buffer[bufIndex] >>> 7 - index % 8 & 1) == 1;
  336. }
  337. put(num, length) {
  338. for (let i = 0; i < length; i++) {
  339. this.putBit((num >>> length - i - 1 & 1) == 1);
  340. }
  341. }
  342. getLengthInBits() {
  343. return this.length;
  344. }
  345. putBit(bit) {
  346. const bufIndex = Math.floor(this.length / 8);
  347. if (this.buffer.length <= bufIndex) {
  348. this.buffer.push(0);
  349. }
  350. if (bit) {
  351. this.buffer[bufIndex] |= 128 >>> this.length % 8;
  352. }
  353. this.length++;
  354. }
  355. };
  356. var QRMath = {
  357. glog: function(n) {
  358. if (n < 1) {
  359. throw new Error("glog(" + n + ")");
  360. }
  361. return QRMath.LOG_TABLE[n];
  362. },
  363. gexp: function(n) {
  364. while (n < 0) {
  365. n += 255;
  366. }
  367. while (n >= 256) {
  368. n -= 255;
  369. }
  370. return QRMath.EXP_TABLE[n];
  371. },
  372. EXP_TABLE: new Array(256),
  373. LOG_TABLE: new Array(256)
  374. };
  375. for (let i = 0; i < 8; i++) {
  376. QRMath.EXP_TABLE[i] = 1 << i;
  377. }
  378. for (let i = 8; i < 256; i++) {
  379. QRMath.EXP_TABLE[i] = QRMath.EXP_TABLE[i - 4] ^ QRMath.EXP_TABLE[i - 5] ^ QRMath.EXP_TABLE[i - 6] ^ QRMath.EXP_TABLE[i - 8];
  380. }
  381. for (let i = 0; i < 255; i++) {
  382. QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]] = i;
  383. }
  384. var math_default = QRMath;
  385. var QRPolynomial = class _QRPolynomial {
  386. num;
  387. constructor(num, shift) {
  388. if (num.length == void 0) {
  389. throw new Error(num.length + "/" + shift);
  390. }
  391. let offset = 0;
  392. while (offset < num.length && num[offset] == 0) {
  393. offset++;
  394. }
  395. this.num = new Array(num.length - offset + shift);
  396. for (let i = 0; i < num.length - offset; i++) {
  397. this.num[i] = num[i + offset];
  398. }
  399. }
  400. get(index) {
  401. return this.num[index];
  402. }
  403. getLength() {
  404. return this.num.length;
  405. }
  406. multiply(e) {
  407. const num = new Array(this.getLength() + e.getLength() - 1);
  408. for (let i = 0; i < this.getLength(); i++) {
  409. for (let j = 0; j < e.getLength(); j++) {
  410. num[i + j] ^= math_default.gexp(math_default.glog(this.get(i)) + math_default.glog(e.get(j)));
  411. }
  412. }
  413. return new _QRPolynomial(num, 0);
  414. }
  415. mod(e) {
  416. if (this.getLength() - e.getLength() < 0) {
  417. return this;
  418. }
  419. const ratio = math_default.glog(this.get(0)) - math_default.glog(e.get(0));
  420. const num = new Array(this.getLength());
  421. for (let i = 0; i < this.getLength(); i++) {
  422. num[i] = this.get(i);
  423. }
  424. for (let i = 0; i < e.getLength(); i++) {
  425. num[i] ^= math_default.gexp(math_default.glog(e.get(i)) + ratio);
  426. }
  427. return new _QRPolynomial(num, 0).mod(e);
  428. }
  429. };
  430. var QRMaskPattern = {
  431. PATTERN000: 0,
  432. PATTERN001: 1,
  433. PATTERN010: 2,
  434. PATTERN011: 3,
  435. PATTERN100: 4,
  436. PATTERN101: 5,
  437. PATTERN110: 6,
  438. PATTERN111: 7
  439. };
  440. var QRUtil = {
  441. PATTERN_POSITION_TABLE: [
  442. [],
  443. [6, 18],
  444. [6, 22],
  445. [6, 26],
  446. [6, 30],
  447. [6, 34],
  448. [6, 22, 38],
  449. [6, 24, 42],
  450. [6, 26, 46],
  451. [6, 28, 50],
  452. [6, 30, 54],
  453. [6, 32, 58],
  454. [6, 34, 62],
  455. [6, 26, 46, 66],
  456. [6, 26, 48, 70],
  457. [6, 26, 50, 74],
  458. [6, 30, 54, 78],
  459. [6, 30, 56, 82],
  460. [6, 30, 58, 86],
  461. [6, 34, 62, 90],
  462. [6, 28, 50, 72, 94],
  463. [6, 26, 50, 74, 98],
  464. [6, 30, 54, 78, 102],
  465. [6, 28, 54, 80, 106],
  466. [6, 32, 58, 84, 110],
  467. [6, 30, 58, 86, 114],
  468. [6, 34, 62, 90, 118],
  469. [6, 26, 50, 74, 98, 122],
  470. [6, 30, 54, 78, 102, 126],
  471. [6, 26, 52, 78, 104, 130],
  472. [6, 30, 56, 82, 108, 134],
  473. [6, 34, 60, 86, 112, 138],
  474. [6, 30, 58, 86, 114, 142],
  475. [6, 34, 62, 90, 118, 146],
  476. [6, 30, 54, 78, 102, 126, 150],
  477. [6, 24, 50, 76, 102, 128, 154],
  478. [6, 28, 54, 80, 106, 132, 158],
  479. [6, 32, 58, 84, 110, 136, 162],
  480. [6, 26, 54, 82, 110, 138, 166],
  481. [6, 30, 58, 86, 114, 142, 170]
  482. ],
  483. G15: 1 << 10 | 1 << 8 | 1 << 5 | 1 << 4 | 1 << 2 | 1 << 1 | 1 << 0,
  484. G18: 1 << 12 | 1 << 11 | 1 << 10 | 1 << 9 | 1 << 8 | 1 << 5 | 1 << 2 | 1 << 0,
  485. G15_MASK: 1 << 14 | 1 << 12 | 1 << 10 | 1 << 4 | 1 << 1,
  486. getBCHTypeInfo: function(data) {
  487. let d = data << 10;
  488. while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15) >= 0) {
  489. d ^= QRUtil.G15 << QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G15);
  490. }
  491. return (data << 10 | d) ^ QRUtil.G15_MASK;
  492. },
  493. getBCHTypeNumber: function(data) {
  494. let d = data << 12;
  495. while (QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18) >= 0) {
  496. d ^= QRUtil.G18 << QRUtil.getBCHDigit(d) - QRUtil.getBCHDigit(QRUtil.G18);
  497. }
  498. return data << 12 | d;
  499. },
  500. getBCHDigit: function(data) {
  501. let digit = 0;
  502. while (data != 0) {
  503. digit++;
  504. data >>>= 1;
  505. }
  506. return digit;
  507. },
  508. getPatternPosition: function(typeNumber) {
  509. return QRUtil.PATTERN_POSITION_TABLE[typeNumber - 1];
  510. },
  511. getMask: function(maskPattern, i, j) {
  512. switch (maskPattern) {
  513. case QRMaskPattern.PATTERN000:
  514. return (i + j) % 2 == 0;
  515. case QRMaskPattern.PATTERN001:
  516. return i % 2 == 0;
  517. case QRMaskPattern.PATTERN010:
  518. return j % 3 == 0;
  519. case QRMaskPattern.PATTERN011:
  520. return (i + j) % 3 == 0;
  521. case QRMaskPattern.PATTERN100:
  522. return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 == 0;
  523. case QRMaskPattern.PATTERN101:
  524. return i * j % 2 + i * j % 3 == 0;
  525. case QRMaskPattern.PATTERN110:
  526. return (i * j % 2 + i * j % 3) % 2 == 0;
  527. case QRMaskPattern.PATTERN111:
  528. return (i * j % 3 + (i + j) % 2) % 2 == 0;
  529. default:
  530. throw new Error("bad maskPattern:" + maskPattern);
  531. }
  532. },
  533. getErrorCorrectPolynomial: function(errorCorrectLength) {
  534. let a = new QRPolynomial([1], 0);
  535. for (let i = 0; i < errorCorrectLength; i++) {
  536. a = a.multiply(new QRPolynomial([1, math_default.gexp(i)], 0));
  537. }
  538. return a;
  539. },
  540. getLengthInBits: function(mode, type) {
  541. if (1 <= type && type < 10) {
  542. switch (mode) {
  543. case mode_default.MODE_NUMBER:
  544. return 10;
  545. case mode_default.MODE_ALPHA_NUM:
  546. return 9;
  547. case mode_default.MODE_8BIT_BYTE:
  548. return 8;
  549. case mode_default.MODE_KANJI:
  550. return 8;
  551. default:
  552. throw new Error("mode:" + mode);
  553. }
  554. } else if (type < 27) {
  555. switch (mode) {
  556. case mode_default.MODE_NUMBER:
  557. return 12;
  558. case mode_default.MODE_ALPHA_NUM:
  559. return 11;
  560. case mode_default.MODE_8BIT_BYTE:
  561. return 16;
  562. case mode_default.MODE_KANJI:
  563. return 10;
  564. default:
  565. throw new Error("mode:" + mode);
  566. }
  567. } else if (type < 41) {
  568. switch (mode) {
  569. case mode_default.MODE_NUMBER:
  570. return 14;
  571. case mode_default.MODE_ALPHA_NUM:
  572. return 13;
  573. case mode_default.MODE_8BIT_BYTE:
  574. return 16;
  575. case mode_default.MODE_KANJI:
  576. return 12;
  577. default:
  578. throw new Error("mode:" + mode);
  579. }
  580. } else {
  581. throw new Error("type:" + type);
  582. }
  583. },
  584. getLostPoint: function(qrCode) {
  585. const moduleCount = qrCode.getModuleCount();
  586. let lostPoint = 0;
  587. for (let row = 0; row < moduleCount; row++) {
  588. for (let col = 0; col < moduleCount; col++) {
  589. let sameCount = 0;
  590. const dark = qrCode.isDark(row, col);
  591. for (let r = -1; r <= 1; r++) {
  592. if (row + r < 0 || moduleCount <= row + r) {
  593. continue;
  594. }
  595. for (let c = -1; c <= 1; c++) {
  596. if (col + c < 0 || moduleCount <= col + c) {
  597. continue;
  598. }
  599. if (r == 0 && c == 0) {
  600. continue;
  601. }
  602. if (dark == qrCode.isDark(row + r, col + c)) {
  603. sameCount++;
  604. }
  605. }
  606. }
  607. if (sameCount > 5) {
  608. lostPoint += 3 + sameCount - 5;
  609. }
  610. }
  611. }
  612. for (let row = 0; row < moduleCount - 1; row++) {
  613. for (let col = 0; col < moduleCount - 1; col++) {
  614. let count = 0;
  615. if (qrCode.isDark(row, col))
  616. count++;
  617. if (qrCode.isDark(row + 1, col))
  618. count++;
  619. if (qrCode.isDark(row, col + 1))
  620. count++;
  621. if (qrCode.isDark(row + 1, col + 1))
  622. count++;
  623. if (count == 0 || count == 4) {
  624. lostPoint += 3;
  625. }
  626. }
  627. }
  628. for (let row = 0; row < moduleCount; row++) {
  629. for (let col = 0; col < moduleCount - 6; col++) {
  630. if (qrCode.isDark(row, col) && !qrCode.isDark(row, col + 1) && qrCode.isDark(row, col + 2) && qrCode.isDark(row, col + 3) && qrCode.isDark(row, col + 4) && !qrCode.isDark(row, col + 5) && qrCode.isDark(row, col + 6)) {
  631. lostPoint += 40;
  632. }
  633. }
  634. }
  635. for (let col = 0; col < moduleCount; col++) {
  636. for (let row = 0; row < moduleCount - 6; row++) {
  637. if (qrCode.isDark(row, col) && !qrCode.isDark(row + 1, col) && qrCode.isDark(row + 2, col) && qrCode.isDark(row + 3, col) && qrCode.isDark(row + 4, col) && !qrCode.isDark(row + 5, col) && qrCode.isDark(row + 6, col)) {
  638. lostPoint += 40;
  639. }
  640. }
  641. }
  642. let darkCount = 0;
  643. for (let col = 0; col < moduleCount; col++) {
  644. for (let row = 0; row < moduleCount; row++) {
  645. if (qrCode.isDark(row, col)) {
  646. darkCount++;
  647. }
  648. }
  649. }
  650. const ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5;
  651. lostPoint += ratio * 10;
  652. return lostPoint;
  653. }
  654. };
  655. var util_default = QRUtil;
  656. var QRCode = class _QRCode {
  657. typeNumber;
  658. errorCorrectLevel;
  659. modules;
  660. moduleCount;
  661. dataCache;
  662. dataList;
  663. constructor(typeNumber, errorCorrectLevel) {
  664. this.typeNumber = typeNumber;
  665. this.errorCorrectLevel = errorCorrectLevel;
  666. this.modules = null;
  667. this.moduleCount = 0;
  668. this.dataCache = null;
  669. this.dataList = [];
  670. }
  671. // TODO data may be anything, but we start with string
  672. addData(data) {
  673. const newData = new QR8bitByte(data);
  674. this.dataList.push(newData);
  675. this.dataCache = null;
  676. }
  677. isDark(row, col) {
  678. if (row < 0 || this.moduleCount <= row || col < 0 || this.moduleCount <= col) {
  679. throw new Error(row + "," + col);
  680. }
  681. if (this.modules === null) {
  682. throw new Error("this.modules is null");
  683. }
  684. return this.modules[row][col];
  685. }
  686. getModuleCount() {
  687. return this.moduleCount;
  688. }
  689. make() {
  690. if (this.typeNumber < 1) {
  691. let typeNumber = 1;
  692. for (typeNumber = 1; typeNumber < 40; typeNumber++) {
  693. const rsBlocks = QRRSBlock.getRSBlocks(
  694. typeNumber,
  695. this.errorCorrectLevel
  696. );
  697. const buffer = new QRBitBuffer();
  698. let totalDataCount = 0;
  699. for (let i = 0; i < rsBlocks.length; i++) {
  700. totalDataCount += rsBlocks[i].dataCount;
  701. }
  702. for (let i = 0; i < this.dataList.length; i++) {
  703. const data = this.dataList[i];
  704. buffer.put(data.mode, 4);
  705. buffer.put(
  706. data.getLength(),
  707. util_default.getLengthInBits(data.mode, typeNumber)
  708. );
  709. data.write(buffer);
  710. }
  711. if (buffer.getLengthInBits() <= totalDataCount * 8)
  712. break;
  713. }
  714. this.typeNumber = typeNumber;
  715. }
  716. this.makeImpl(false, this.getBestMaskPattern());
  717. }
  718. makeImpl(test, maskPattern) {
  719. this.moduleCount = this.typeNumber * 4 + 17;
  720. this.modules = new Array(this.moduleCount);
  721. for (let row = 0; row < this.moduleCount; row++) {
  722. this.modules[row] = new Array(this.moduleCount);
  723. for (let col = 0; col < this.moduleCount; col++) {
  724. this.modules[row][col] = null;
  725. }
  726. }
  727. this.setupPositionProbePattern(0, 0);
  728. this.setupPositionProbePattern(this.moduleCount - 7, 0);
  729. this.setupPositionProbePattern(0, this.moduleCount - 7);
  730. this.setupPositionAdjustPattern();
  731. this.setupTimingPattern();
  732. this.setupTypeInfo(test, maskPattern);
  733. if (this.typeNumber >= 7) {
  734. this.setupTypeNumber(test);
  735. }
  736. if (this.dataCache == null) {
  737. this.dataCache = _QRCode.createData(
  738. this.typeNumber,
  739. this.errorCorrectLevel,
  740. this.dataList
  741. );
  742. }
  743. this.mapData(this.dataCache, maskPattern);
  744. }
  745. setupPositionProbePattern(row, col) {
  746. for (let r = -1; r <= 7; r++) {
  747. if (row + r <= -1 || this.moduleCount <= row + r)
  748. continue;
  749. for (let c = -1; c <= 7; c++) {
  750. if (col + c <= -1 || this.moduleCount <= col + c)
  751. continue;
  752. if (0 <= r && r <= 6 && (c == 0 || c == 6) || 0 <= c && c <= 6 && (r == 0 || r == 6) || 2 <= r && r <= 4 && 2 <= c && c <= 4) {
  753. if (this.modules === null) {
  754. throw new Error("this.modules is null");
  755. }
  756. this.modules[row + r][col + c] = true;
  757. } else {
  758. if (this.modules === null) {
  759. throw new Error("this.modules is null");
  760. }
  761. this.modules[row + r][col + c] = false;
  762. }
  763. }
  764. }
  765. }
  766. getBestMaskPattern() {
  767. let minLostPoint = 0;
  768. let pattern = 0;
  769. for (let i = 0; i < 8; i++) {
  770. this.makeImpl(true, i);
  771. const lostPoint = util_default.getLostPoint(this);
  772. if (i == 0 || minLostPoint > lostPoint) {
  773. minLostPoint = lostPoint;
  774. pattern = i;
  775. }
  776. }
  777. return pattern;
  778. }
  779. setupTimingPattern() {
  780. if (this.modules === null) {
  781. throw new Error("this.modules is null");
  782. }
  783. for (let r = 8; r < this.moduleCount - 8; r++) {
  784. if (this.modules[r][6] != null) {
  785. continue;
  786. }
  787. this.modules[r][6] = r % 2 == 0;
  788. }
  789. for (let c = 8; c < this.moduleCount - 8; c++) {
  790. if (this.modules[6][c] != null) {
  791. continue;
  792. }
  793. this.modules[6][c] = c % 2 == 0;
  794. }
  795. }
  796. setupPositionAdjustPattern() {
  797. if (this.modules === null) {
  798. throw new Error("this.modules is null");
  799. }
  800. const pos = util_default.getPatternPosition(this.typeNumber);
  801. for (let i = 0; i < pos.length; i++) {
  802. for (let j = 0; j < pos.length; j++) {
  803. const row = pos[i];
  804. const col = pos[j];
  805. if (this.modules[row][col] != null) {
  806. continue;
  807. }
  808. for (let r = -2; r <= 2; r++) {
  809. for (let c = -2; c <= 2; c++) {
  810. if (r == -2 || r == 2 || c == -2 || c == 2 || r == 0 && c == 0) {
  811. this.modules[row + r][col + c] = true;
  812. } else {
  813. this.modules[row + r][col + c] = false;
  814. }
  815. }
  816. }
  817. }
  818. }
  819. }
  820. setupTypeNumber(test) {
  821. if (this.modules === null) {
  822. throw new Error("this.modules is null");
  823. }
  824. const bits = util_default.getBCHTypeNumber(this.typeNumber);
  825. for (let i = 0; i < 18; i++) {
  826. const mod = !test && (bits >> i & 1) == 1;
  827. this.modules[Math.floor(i / 3)][i % 3 + this.moduleCount - 8 - 3] = mod;
  828. }
  829. for (let i = 0; i < 18; i++) {
  830. const mod = !test && (bits >> i & 1) == 1;
  831. this.modules[i % 3 + this.moduleCount - 8 - 3][Math.floor(i / 3)] = mod;
  832. }
  833. }
  834. setupTypeInfo(test, maskPattern) {
  835. if (this.modules === null) {
  836. throw new Error("this.modules is null");
  837. }
  838. const data = this.errorCorrectLevel << 3 | maskPattern;
  839. const bits = util_default.getBCHTypeInfo(data);
  840. for (let i = 0; i < 15; i++) {
  841. const mod = !test && (bits >> i & 1) == 1;
  842. if (i < 6) {
  843. this.modules[i][8] = mod;
  844. } else if (i < 8) {
  845. this.modules[i + 1][8] = mod;
  846. } else {
  847. this.modules[this.moduleCount - 15 + i][8] = mod;
  848. }
  849. }
  850. for (let i = 0; i < 15; i++) {
  851. const mod = !test && (bits >> i & 1) == 1;
  852. if (i < 8) {
  853. this.modules[8][this.moduleCount - i - 1] = mod;
  854. } else if (i < 9) {
  855. this.modules[8][15 - i - 1 + 1] = mod;
  856. } else {
  857. this.modules[8][15 - i - 1] = mod;
  858. }
  859. }
  860. this.modules[this.moduleCount - 8][8] = !test;
  861. }
  862. mapData(data, maskPattern) {
  863. if (this.modules === null) {
  864. throw new Error("this.modules is null");
  865. }
  866. let inc = -1;
  867. let row = this.moduleCount - 1;
  868. let bitIndex = 7;
  869. let byteIndex = 0;
  870. for (let col = this.moduleCount - 1; col > 0; col -= 2) {
  871. if (col == 6)
  872. col--;
  873. while (true) {
  874. for (let c = 0; c < 2; c++) {
  875. if (this.modules[row][col - c] == null) {
  876. let dark = false;
  877. if (byteIndex < data.length) {
  878. dark = (data[byteIndex] >>> bitIndex & 1) == 1;
  879. }
  880. const mask = util_default.getMask(maskPattern, row, col - c);
  881. if (mask) {
  882. dark = !dark;
  883. }
  884. this.modules[row][col - c] = dark;
  885. bitIndex--;
  886. if (bitIndex == -1) {
  887. byteIndex++;
  888. bitIndex = 7;
  889. }
  890. }
  891. }
  892. row += inc;
  893. if (row < 0 || this.moduleCount <= row) {
  894. row -= inc;
  895. inc = -inc;
  896. break;
  897. }
  898. }
  899. }
  900. }
  901. static PAD0 = 236;
  902. static PAD1 = 17;
  903. static createData(typeNumber, errorCorrectLevel, dataList) {
  904. const rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel);
  905. const buffer = new QRBitBuffer();
  906. for (let i = 0; i < dataList.length; i++) {
  907. const data = dataList[i];
  908. buffer.put(data.mode, 4);
  909. buffer.put(data.getLength(), util_default.getLengthInBits(data.mode, typeNumber));
  910. data.write(buffer);
  911. }
  912. let totalDataCount = 0;
  913. for (let i = 0; i < rsBlocks.length; i++) {
  914. totalDataCount += rsBlocks[i].dataCount;
  915. }
  916. if (buffer.getLengthInBits() > totalDataCount * 8) {
  917. throw new Error(
  918. "code length overflow. (" + buffer.getLengthInBits() + ">" + totalDataCount * 8 + ")"
  919. );
  920. }
  921. if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) {
  922. buffer.put(0, 4);
  923. }
  924. while (buffer.getLengthInBits() % 8 != 0) {
  925. buffer.putBit(false);
  926. }
  927. while (true) {
  928. if (buffer.getLengthInBits() >= totalDataCount * 8) {
  929. break;
  930. }
  931. buffer.put(_QRCode.PAD0, 8);
  932. if (buffer.getLengthInBits() >= totalDataCount * 8) {
  933. break;
  934. }
  935. buffer.put(_QRCode.PAD1, 8);
  936. }
  937. return _QRCode.createBytes(buffer, rsBlocks);
  938. }
  939. static createBytes(buffer, rsBlocks) {
  940. let offset = 0;
  941. let maxDcCount = 0;
  942. let maxEcCount = 0;
  943. const dcdata = new Array(rsBlocks.length);
  944. const ecdata = new Array(rsBlocks.length);
  945. for (let r = 0; r < rsBlocks.length; r++) {
  946. const dcCount = rsBlocks[r].dataCount;
  947. const ecCount = rsBlocks[r].totalCount - dcCount;
  948. maxDcCount = Math.max(maxDcCount, dcCount);
  949. maxEcCount = Math.max(maxEcCount, ecCount);
  950. dcdata[r] = new Array(dcCount);
  951. for (let i = 0; i < dcdata[r].length; i++) {
  952. dcdata[r][i] = 255 & buffer.buffer[i + offset];
  953. }
  954. offset += dcCount;
  955. const rsPoly = util_default.getErrorCorrectPolynomial(ecCount);
  956. const rawPoly = new QRPolynomial(dcdata[r], rsPoly.getLength() - 1);
  957. const modPoly = rawPoly.mod(rsPoly);
  958. ecdata[r] = new Array(rsPoly.getLength() - 1);
  959. for (let i = 0; i < ecdata[r].length; i++) {
  960. const modIndex = i + modPoly.getLength() - ecdata[r].length;
  961. ecdata[r][i] = modIndex >= 0 ? modPoly.get(modIndex) : 0;
  962. }
  963. }
  964. let totalCodeCount = 0;
  965. for (let i = 0; i < rsBlocks.length; i++) {
  966. totalCodeCount += rsBlocks[i].totalCount;
  967. }
  968. const data = new Array(totalCodeCount);
  969. let index = 0;
  970. for (let i = 0; i < maxDcCount; i++) {
  971. for (let r = 0; r < rsBlocks.length; r++) {
  972. if (i < dcdata[r].length) {
  973. data[index++] = dcdata[r][i];
  974. }
  975. }
  976. }
  977. for (let i = 0; i < maxEcCount; i++) {
  978. for (let r = 0; r < rsBlocks.length; r++) {
  979. if (i < ecdata[r].length) {
  980. data[index++] = ecdata[r][i];
  981. }
  982. }
  983. }
  984. return data;
  985. }
  986. };
  987. // src/QRCodeRaw.ts
  988. var ERROR_CORRECTION_LEVEL_LOW = "L";
  989. var DEFAULT_CONSTRUCTOR_PARAMS = {
  990. level: ERROR_CORRECTION_LEVEL_LOW,
  991. padding: 1,
  992. invert: false,
  993. typeNumber: 0,
  994. errorsEnabled: false
  995. };
  996. var QRCodeRaw = class {
  997. value;
  998. level;
  999. typeNumber;
  1000. padding;
  1001. errorsEnabled;
  1002. invert;
  1003. qrCodeData;
  1004. constructor(value, options = {}) {
  1005. const params = { ...DEFAULT_CONSTRUCTOR_PARAMS, ...options };
  1006. this.value = value;
  1007. this.level = params.level;
  1008. this.typeNumber = params.typeNumber;
  1009. this.padding = params.padding;
  1010. this.invert = params.invert;
  1011. this.errorsEnabled = params.errorsEnabled;
  1012. }
  1013. setValue(value) {
  1014. this.value = value;
  1015. this._clearCache();
  1016. }
  1017. getDataSize() {
  1018. const data = this.getData();
  1019. return data ? data.length : 0;
  1020. }
  1021. _clearCache() {
  1022. this.qrCodeData = null;
  1023. }
  1024. _getQrCodeData(modules) {
  1025. const qrCodeData = [];
  1026. const padding = this.padding;
  1027. const invert = this.invert;
  1028. const rowPadding = Array(padding * 2 + modules.length).fill(
  1029. invert
  1030. );
  1031. const rowsPadding = Array(padding).fill(rowPadding);
  1032. const columnPadding = Array(padding).fill(invert);
  1033. if (padding) {
  1034. qrCodeData.push(...rowsPadding);
  1035. }
  1036. modules.forEach((row) => {
  1037. const qrCodeRow = [];
  1038. qrCodeRow.push(
  1039. ...columnPadding,
  1040. ...row.map((isBlack) => invert ? !isBlack : isBlack),
  1041. ...columnPadding
  1042. );
  1043. qrCodeData.push(qrCodeRow);
  1044. });
  1045. if (padding) {
  1046. qrCodeData.push(...rowsPadding);
  1047. }
  1048. return qrCodeData;
  1049. }
  1050. getData() {
  1051. if (!this.qrCodeData) {
  1052. try {
  1053. const qrcode = new QRCode(
  1054. this.typeNumber,
  1055. ErrorCorrectLevel[this.level]
  1056. );
  1057. qrcode.addData(this.value);
  1058. qrcode.make();
  1059. if (!qrcode.modules) {
  1060. return null;
  1061. }
  1062. this.qrCodeData = this._getQrCodeData(qrcode.modules);
  1063. Object.freeze(this.qrCodeData);
  1064. } catch (error) {
  1065. if (this.errorsEnabled) {
  1066. throw error;
  1067. }
  1068. return null;
  1069. }
  1070. }
  1071. return this.qrCodeData;
  1072. }
  1073. };
  1074. // src/utils/DimensionUtils.ts
  1075. var DimensionUtils = class {
  1076. static calculateDimension(value, canvasSize) {
  1077. const isNumber = typeof value === "number";
  1078. const isString = typeof value === "string";
  1079. invariant(
  1080. isNumber || isString,
  1081. `value must be either string or number, instead got ${typeof value}`
  1082. );
  1083. if (isNumber) {
  1084. return value;
  1085. }
  1086. if (value.indexOf("%") > 0) {
  1087. return Math.round(parseFloat(value) / 100 * canvasSize) || 0;
  1088. }
  1089. return parseFloat(value) || 0;
  1090. }
  1091. static calculatePosition(value, size, canvasSize) {
  1092. const isNumber = typeof value === "number";
  1093. const isString = typeof value === "string";
  1094. invariant(
  1095. isNumber || isString,
  1096. `value must be either string or number, instead got ${typeof value}`
  1097. );
  1098. if (isNumber)
  1099. return value;
  1100. if (value === "left" || value === "top") {
  1101. return 0;
  1102. }
  1103. if (value === "right" || value === "bottom") {
  1104. return canvasSize - size;
  1105. }
  1106. if (value === "center") {
  1107. return Math.round((canvasSize - size) / 2);
  1108. }
  1109. const match = value.match(
  1110. /^(?:(right|bottom|left|top)\s+)?(-?[0-9.]+)(%)?$/
  1111. );
  1112. invariant(!!match, `Expected position with number, instead got ${value}`);
  1113. const isRight = match[1] === "right" || match[1] === "bottom";
  1114. const isPercent = !!match[3];
  1115. let val = parseFloat(match[2]) || 0;
  1116. if (isPercent) {
  1117. val = Math.round(val / 100 * canvasSize);
  1118. }
  1119. if (isRight) {
  1120. val = canvasSize - val - size;
  1121. }
  1122. return Math.round(val);
  1123. }
  1124. };
  1125. // src/AbstractQRCodeWithImage.ts
  1126. var DEFAULT_OPTIONS = {
  1127. image: null
  1128. };
  1129. var DEFAULT_IMAGE_BORDER = 1;
  1130. var AbstractQRCodeWithImage = class extends QRCodeRaw {
  1131. image = null;
  1132. imageConfig = null;
  1133. constructor(value, options = {}) {
  1134. super(value, options);
  1135. const params = { ...DEFAULT_OPTIONS, ...options };
  1136. this.image = params.image;
  1137. }
  1138. _clearCache() {
  1139. super._clearCache();
  1140. this.imageConfig = null;
  1141. }
  1142. _getImageSource(imageConfig) {
  1143. const source = imageConfig.source;
  1144. if (typeof source === "string") {
  1145. return source;
  1146. }
  1147. if (source instanceof Image) {
  1148. return source.src;
  1149. }
  1150. if (source instanceof HTMLCanvasElement) {
  1151. return source.toDataURL();
  1152. }
  1153. return null;
  1154. }
  1155. _getImageConfig() {
  1156. if (this.imageConfig) {
  1157. return this.imageConfig;
  1158. }
  1159. if (!this.image || !this.image.source || !this.image.width || !this.image.height) {
  1160. return null;
  1161. }
  1162. const dataSize = this.getDataSize();
  1163. if (!dataSize) {
  1164. return null;
  1165. }
  1166. const source = this._getImageSource(this.image);
  1167. if (!source) {
  1168. return null;
  1169. }
  1170. const dataSizeWithoutPadding = dataSize - this.padding * 2;
  1171. const width = DimensionUtils.calculateDimension(
  1172. this.image.width,
  1173. dataSizeWithoutPadding
  1174. );
  1175. const height = DimensionUtils.calculateDimension(
  1176. this.image.height,
  1177. dataSizeWithoutPadding
  1178. );
  1179. const x = DimensionUtils.calculatePosition(
  1180. // @ts-expect-error make types stronger
  1181. this.image.x,
  1182. width,
  1183. dataSizeWithoutPadding
  1184. ) + this.padding;
  1185. const y = DimensionUtils.calculatePosition(
  1186. // @ts-expect-error make types stronger
  1187. this.image.y,
  1188. height,
  1189. dataSizeWithoutPadding
  1190. ) + this.padding;
  1191. let border = DEFAULT_IMAGE_BORDER;
  1192. if (typeof this.image.border === "number" || this.image.border === null) {
  1193. border = this.image.border;
  1194. }
  1195. this.imageConfig = { source, border, x, y, width, height };
  1196. return this.imageConfig;
  1197. }
  1198. getData() {
  1199. if (this.qrCodeData) {
  1200. return this.qrCodeData;
  1201. }
  1202. const data = super.getData();
  1203. if (!data) {
  1204. return data;
  1205. }
  1206. const imageConfig = this._getImageConfig();
  1207. if (imageConfig !== null && imageConfig.width && imageConfig.height) {
  1208. if (typeof imageConfig.border === "number") {
  1209. const begX = Math.max(imageConfig.x - imageConfig.border, 0);
  1210. const begY = Math.max(imageConfig.y - imageConfig.border, 0);
  1211. const endX = Math.min(
  1212. // @ts-expect-error make types stronger
  1213. begX + imageConfig.width + imageConfig.border * 2,
  1214. data.length
  1215. );
  1216. const endY = Math.min(
  1217. // @ts-expect-error make types stronger
  1218. begY + imageConfig.height + imageConfig.border * 2,
  1219. data.length
  1220. );
  1221. for (let y = begY; y < endY; y += 1) {
  1222. for (let x = begX; x < endX; x += 1) {
  1223. data[y][x] = this.invert ? true : false;
  1224. }
  1225. }
  1226. }
  1227. }
  1228. return data;
  1229. }
  1230. };
  1231. // src/loader/ImageLoader.ts
  1232. var loadImage = (url) => {
  1233. return new Promise((resolve, reject) => {
  1234. const img = new Image();
  1235. img.onload = () => resolve(img);
  1236. img.onerror = () => reject(img);
  1237. img.src = url;
  1238. });
  1239. };
  1240. // src/QRCodeCanvas.ts
  1241. var DEFAULT_OPTIONS2 = {
  1242. fgColor: "#000",
  1243. bgColor: "#FFF",
  1244. scale: 10,
  1245. size: null
  1246. };
  1247. var QRCodeCanvas = class extends AbstractQRCodeWithImage {
  1248. fgColor;
  1249. bgColor;
  1250. scale;
  1251. size;
  1252. canvas;
  1253. canvasContext;
  1254. constructor(value, options = {}) {
  1255. super(value, options);
  1256. const params = { ...DEFAULT_OPTIONS2, ...options };
  1257. this.fgColor = params.fgColor;
  1258. this.bgColor = params.bgColor;
  1259. this.scale = params.scale;
  1260. this.size = params.size;
  1261. this.canvas = document.createElement("canvas");
  1262. const canvasContext = this.canvas.getContext("2d");
  1263. if (canvasContext === null) {
  1264. throw new Error("canvas context is null");
  1265. }
  1266. this.canvasContext = canvasContext;
  1267. }
  1268. _clearCache() {
  1269. super._clearCache();
  1270. this.canvas.width = 0;
  1271. }
  1272. _getCanvasSize() {
  1273. const dataSize = this.getDataSize();
  1274. if (!dataSize) {
  1275. return null;
  1276. }
  1277. if (this.size) {
  1278. return this.size;
  1279. }
  1280. if (this.scale) {
  1281. return this.scale * dataSize;
  1282. }
  1283. return dataSize;
  1284. }
  1285. draw(canvas = null) {
  1286. const dataSize = this.getDataSize();
  1287. if (!dataSize) {
  1288. return null;
  1289. }
  1290. const data = this.getData();
  1291. if (!data) {
  1292. return null;
  1293. }
  1294. const fgColor = ColorUtils.convertHexColorToBytes(this.fgColor);
  1295. const bgColor = ColorUtils.convertHexColorToBytes(this.bgColor);
  1296. let index = 0;
  1297. const bytes = new Uint8ClampedArray(dataSize ** 2 * 4);
  1298. data.forEach((row) => {
  1299. row.forEach((isBlack) => {
  1300. if (isBlack) {
  1301. bytes.set(fgColor, index);
  1302. } else {
  1303. bytes.set(bgColor, index);
  1304. }
  1305. index += 4;
  1306. });
  1307. });
  1308. const imageData = new ImageData(bytes, dataSize, dataSize);
  1309. this.canvas.width = dataSize;
  1310. this.canvas.height = dataSize;
  1311. this.canvasContext.putImageData(imageData, 0, 0);
  1312. const canvasSize = this._getCanvasSize();
  1313. const qrCodeCanvas = canvas || document.createElement("canvas");
  1314. qrCodeCanvas.width = canvasSize;
  1315. qrCodeCanvas.height = canvasSize;
  1316. const qrCodeCanvasContext = qrCodeCanvas.getContext("2d");
  1317. qrCodeCanvasContext.imageSmoothingEnabled = false;
  1318. qrCodeCanvasContext.drawImage(this.canvas, 0, 0, canvasSize, canvasSize);
  1319. const drawImageResult = this._drawImage(
  1320. // @ts-expect-error make types stronger
  1321. qrCodeCanvasContext,
  1322. // @ts-expect-error make types stronger
  1323. canvasSize / dataSize
  1324. );
  1325. if (drawImageResult instanceof Promise) {
  1326. return drawImageResult.then(() => {
  1327. return qrCodeCanvas;
  1328. });
  1329. }
  1330. return qrCodeCanvas;
  1331. }
  1332. // @ts-expect-error make types stronger
  1333. _getImageSource(imageConfig) {
  1334. const source = imageConfig.source;
  1335. if (typeof source === "string") {
  1336. return loadImage(source).then((image) => {
  1337. this.image.source = image;
  1338. imageConfig.source = image;
  1339. return image;
  1340. });
  1341. }
  1342. if (source instanceof Image) {
  1343. return source;
  1344. }
  1345. if (source instanceof HTMLCanvasElement) {
  1346. return source;
  1347. }
  1348. return null;
  1349. }
  1350. _drawImage(qrCodeCanvasContext, pixelSize) {
  1351. const imageConfig = this._getImageConfig();
  1352. if (!imageConfig) {
  1353. return null;
  1354. }
  1355. if (imageConfig.source instanceof Promise) {
  1356. return imageConfig.source.then((image) => {
  1357. qrCodeCanvasContext.drawImage(
  1358. image,
  1359. // @ts-expect-error make types stronger
  1360. imageConfig.x * pixelSize,
  1361. // @ts-expect-error make types stronger
  1362. imageConfig.y * pixelSize,
  1363. // @ts-expect-error make types stronger
  1364. imageConfig.width * pixelSize,
  1365. // @ts-expect-error make types stronger
  1366. imageConfig.height * pixelSize
  1367. );
  1368. });
  1369. }
  1370. qrCodeCanvasContext.drawImage(
  1371. imageConfig.source,
  1372. // @ts-expect-error make types stronger
  1373. imageConfig.x * pixelSize,
  1374. // @ts-expect-error make types stronger
  1375. imageConfig.y * pixelSize,
  1376. // @ts-expect-error make types stronger
  1377. imageConfig.width * pixelSize,
  1378. // @ts-expect-error make types stronger
  1379. imageConfig.height * pixelSize
  1380. );
  1381. return true;
  1382. }
  1383. getCanvas() {
  1384. return this.draw();
  1385. }
  1386. toDataUrl(type = "image/png", encoderOptions = 0.92) {
  1387. const canvasOrPromise = this.draw();
  1388. if (!canvasOrPromise) {
  1389. return null;
  1390. }
  1391. if (canvasOrPromise instanceof Promise) {
  1392. return canvasOrPromise.then((qrCodeCanvas) => {
  1393. return qrCodeCanvas.toDataURL(type, encoderOptions);
  1394. });
  1395. }
  1396. return canvasOrPromise.toDataURL(type, encoderOptions);
  1397. }
  1398. };
  1399. // src/QRCodeSVG.ts
  1400. var TYPE_INT_WHITE = 0;
  1401. var TYPE_INT_BLACK = 1;
  1402. var TYPE_INT_PROCESSED = 2;
  1403. var DEFAULT_OPTIONS3 = {
  1404. fgColor: "#000",
  1405. bgColor: "#FFF"
  1406. };
  1407. var QRCodeSVG = class extends AbstractQRCodeWithImage {
  1408. fgColor;
  1409. bgColor;
  1410. qrCodeSVG = null;
  1411. height;
  1412. width;
  1413. qrCodeDataUrl = null;
  1414. constructor(value, options = {}) {
  1415. super(value, options);
  1416. const params = { ...DEFAULT_OPTIONS3, ...options };
  1417. this.fgColor = params.fgColor;
  1418. this.bgColor = params.bgColor;
  1419. this.width = params.width;
  1420. this.height = params.height;
  1421. // console.log("QRCodeSVG", this);
  1422. }
  1423. _clearCache() {
  1424. super._clearCache();
  1425. this.qrCodeSVG = null;
  1426. this.qrCodeDataUrl = null;
  1427. }
  1428. _getDataInt() {
  1429. const data = this.getData();
  1430. if (!data) {
  1431. return null;
  1432. }
  1433. return data.map((row) => {
  1434. return row.map((isBlack) => {
  1435. return isBlack ? TYPE_INT_BLACK : TYPE_INT_WHITE;
  1436. });
  1437. });
  1438. }
  1439. _getRects() {
  1440. const dataInt = this._getDataInt();
  1441. if (!dataInt) {
  1442. return null;
  1443. }
  1444. const rects = [];
  1445. const count = dataInt.length - 1;
  1446. for (let y = 0; y <= count; y += 1) {
  1447. let begX = -1;
  1448. for (let x = 0; x <= count; x += 1) {
  1449. const intType = dataInt[y][x];
  1450. const isLast = x === count;
  1451. const isBlack = intType === TYPE_INT_BLACK;
  1452. if (isBlack && begX === -1) {
  1453. begX = x;
  1454. }
  1455. if (begX !== -1 && (isLast || !isBlack)) {
  1456. const endX = x - (isBlack ? 0 : 1);
  1457. const rect = this._processRect(dataInt, begX, endX, y);
  1458. if (rect) {
  1459. rects.push(rect);
  1460. }
  1461. begX = -1;
  1462. }
  1463. }
  1464. }
  1465. return rects;
  1466. }
  1467. _processRect(dataInt, begX, endX, begY) {
  1468. const count = dataInt.length - 1;
  1469. let isNewRect = false;
  1470. let isStopped = false;
  1471. let height = 0;
  1472. for (let y = begY; y <= count; y += 1) {
  1473. for (let x = begX; x <= endX; x += 1) {
  1474. const intType = dataInt[y][x];
  1475. if (intType === TYPE_INT_WHITE) {
  1476. isStopped = true;
  1477. break;
  1478. }
  1479. }
  1480. if (isStopped) {
  1481. break;
  1482. }
  1483. for (let x = begX; x <= endX; x += 1) {
  1484. if (dataInt[y][x] === TYPE_INT_BLACK) {
  1485. isNewRect = true;
  1486. dataInt[y][x] = TYPE_INT_PROCESSED;
  1487. }
  1488. }
  1489. height += 1;
  1490. }
  1491. if (!isNewRect) {
  1492. return null;
  1493. }
  1494. return {
  1495. x: begX,
  1496. y: begY,
  1497. width: endX - begX + 1,
  1498. height
  1499. };
  1500. }
  1501. _getRelativeRects() {
  1502. const rects = this._getRects();
  1503. if (!rects) {
  1504. return null;
  1505. }
  1506. const relativeRects = [];
  1507. const rectsMap = {};
  1508. let seqRectId = 0;
  1509. rects.forEach((rect) => {
  1510. const key = `${rect.width}:${rect.height}`;
  1511. if (rectsMap[key]) {
  1512. rectsMap[key].count += 1;
  1513. if (!rectsMap[key].id) {
  1514. rectsMap[key].id = `i${seqRectId.toString(32)}`;
  1515. seqRectId += 1;
  1516. }
  1517. } else {
  1518. rectsMap[key] = { count: 1, rect, relative: false, id: null };
  1519. }
  1520. });
  1521. rects.forEach((rect) => {
  1522. const key = `${rect.width}:${rect.height}`;
  1523. const rectsMapItem = rectsMap[key];
  1524. if (rectsMapItem.relative) {
  1525. relativeRects.push({
  1526. id: rectsMapItem.id,
  1527. x: rect.x - rectsMapItem.rect.x,
  1528. y: rect.y - rectsMapItem.rect.y
  1529. });
  1530. } else {
  1531. if (rectsMapItem.id) {
  1532. rect.id = rectsMapItem.id;
  1533. rectsMapItem.relative = true;
  1534. }
  1535. relativeRects.push(rect);
  1536. }
  1537. });
  1538. return relativeRects;
  1539. }
  1540. _buildSVG(rects) {
  1541. const size = this.getDataSize();
  1542. const tags = [
  1543. `<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" shape-rendering="crispEdges" viewBox="0 0 ${size} ${size}"${this.width ? ` width=${this.width}` : ""}${this.height ? ` height=${this.height}` : ""} >`
  1544. ];
  1545. if (this.bgColor) {
  1546. tags.push(
  1547. `<rect x="0" y="0" height="${size}" width="${size}" fill="${this.bgColor}"/>`
  1548. );
  1549. }
  1550. rects.forEach((rect) => {
  1551. if (rect.width && rect.height) {
  1552. const rectId = rect.id ? `id="${rect.id}" ` : "";
  1553. tags.push(
  1554. `<rect ${rectId}x="${rect.x}" y="${rect.y}" height="${rect.height}" width="${rect.width}" fill="${this.fgColor}"/>`
  1555. );
  1556. } else {
  1557. tags.push(
  1558. `<use xlink:href="#${rect.id}" x="${rect.x}" y="${rect.y}"/>`
  1559. );
  1560. }
  1561. });
  1562. const imageConfig = this._getImageConfig();
  1563. if (imageConfig && imageConfig.width && imageConfig.height) {
  1564. tags.push(
  1565. `<image xlink:href="${imageConfig.source}" x="${imageConfig.x}" y="${imageConfig.y}" width="${imageConfig.width}" height="${imageConfig.height}"/>`
  1566. );
  1567. }
  1568. tags.push("</svg>");
  1569. return tags.join("");
  1570. }
  1571. toString() {
  1572. if (!this.qrCodeSVG) {
  1573. const dataSize = this.getDataSize();
  1574. if (!dataSize) {
  1575. return null;
  1576. }
  1577. const rects = this._getRects();
  1578. if (!rects) {
  1579. return null;
  1580. }
  1581. this.qrCodeSVG = this._buildSVG(rects);
  1582. }
  1583. return this.qrCodeSVG;
  1584. }
  1585. toDataUrl() {
  1586. if (!this.qrCodeDataUrl) {
  1587. const dataSize = this.getDataSize();
  1588. if (!dataSize) {
  1589. return null;
  1590. }
  1591. const relativeRects = this._getRelativeRects();
  1592. if (!relativeRects) {
  1593. return null;
  1594. }
  1595. const svg = this._buildSVG(relativeRects);
  1596. this.qrCodeDataUrl = `data:image/svg+xml;base64,${btoa(svg)}`;
  1597. }
  1598. return this.qrCodeDataUrl;
  1599. }
  1600. };
  1601. // src/QRCodeText.ts
  1602. var DEFAULT_OPTIONS4 = {
  1603. blackSymbol: "\u2593\u2593",
  1604. whiteSymbol: " "
  1605. };
  1606. var QRCodeText = class extends QRCodeRaw {
  1607. blackSymbol;
  1608. whiteSymbol;
  1609. qrCodeText;
  1610. constructor(value, options = {}) {
  1611. super(value, options);
  1612. const params = { ...DEFAULT_OPTIONS4, ...options };
  1613. this.blackSymbol = params.blackSymbol;
  1614. this.whiteSymbol = params.whiteSymbol;
  1615. }
  1616. _clearCache() {
  1617. super._clearCache();
  1618. this.qrCodeText = null;
  1619. }
  1620. toString() {
  1621. if (this.qrCodeText) {
  1622. return this.qrCodeText;
  1623. }
  1624. const dataSize = this.getDataSize();
  1625. if (!dataSize) {
  1626. return null;
  1627. }
  1628. const data = this.getData();
  1629. if (data === null) {
  1630. return null;
  1631. }
  1632. const symbols = [];
  1633. for (let y = 0; y < dataSize; y += 1) {
  1634. for (let x = 0; x < dataSize; x += 1) {
  1635. const isBlack = data[y][x];
  1636. symbols.push(isBlack ? this.blackSymbol : this.whiteSymbol);
  1637. }
  1638. symbols.push("\n");
  1639. }
  1640. this.qrCodeText = symbols.join("");
  1641. return this.qrCodeText;
  1642. }
  1643. };
  1644. export {
  1645. AbstractQRCodeWithImage,
  1646. QRCodeCanvas,
  1647. QRCodeRaw,
  1648. QRCodeSVG,
  1649. QRCodeText
  1650. };