@liquid-js/qr-code-styling 3.0.0-2 → 3.0.0-4

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 (34) hide show
  1. package/README.md +1 -2
  2. package/lib/core/{QRCodeStyling.d.ts → qr-code-styling.d.ts} +16 -22
  3. package/lib/core/qr-svg.d.ts +31 -0
  4. package/lib/figures/corner-dot.d.ts +24 -0
  5. package/lib/figures/corner-square.d.ts +22 -0
  6. package/lib/figures/dot.d.ts +28 -0
  7. package/lib/index.d.ts +9 -5
  8. package/lib/kanji.js +1 -1
  9. package/lib/kanji.js.map +1 -1
  10. package/lib/node.d.ts +13 -6
  11. package/lib/qr-code-styling-node.js +891 -1539
  12. package/lib/qr-code-styling-node.js.map +1 -1
  13. package/lib/qr-code-styling.js +1 -1
  14. package/lib/qr-code-styling.js.map +1 -1
  15. package/lib/tools/{browserImageTools.d.ts → browser-image-tools.d.ts} +1 -2
  16. package/lib/tools/browser-utils.d.ts +18 -0
  17. package/lib/types/helper.d.ts +23 -0
  18. package/lib/types/qrcode.d.ts +64 -0
  19. package/lib/utils/canvas-options.d.ts +7 -0
  20. package/lib/utils/gradient.d.ts +26 -0
  21. package/lib/{tools → utils}/merge.d.ts +3 -1
  22. package/lib/{types/index.d.ts → utils/options.d.ts} +29 -151
  23. package/lib/{constants/errorCorrectionPercents.d.ts → utils/qrcode.d.ts} +2 -0
  24. package/lib/utils/svg.d.ts +2 -0
  25. package/package.json +1 -1
  26. package/lib/core/QROptions.d.ts +0 -32
  27. package/lib/core/QRSVG.d.ts +0 -58
  28. package/lib/figures/cornerDot/QRCornerDot.d.ts +0 -27
  29. package/lib/figures/cornerSquare/QRCornerSquare.d.ts +0 -25
  30. package/lib/figures/dot/QRDot.d.ts +0 -31
  31. package/lib/tools/browserUtils.d.ts +0 -11
  32. package/lib/tools/getMode.d.ts +0 -2
  33. package/lib/tools/sanitizeOptions.d.ts +0 -3
  34. /package/lib/{tools/calculateImageSize.d.ts → utils/image.d.ts} +0 -0
@@ -1,199 +1,73 @@
1
- import { DOMImplementation, XMLSerializer as XMLSerializer$1, DOMParser as DOMParser$1 } from '@xmldom/xmldom';
2
- import { fileTypeFromBuffer } from 'file-type';
3
- import sharp from 'sharp';
4
- import qrcode from 'qrcode-generator';
1
+ import qrcode from "qrcode-generator";
5
2
 
6
- var DotType;
7
- (function (DotType) {
8
- DotType["dots"] = "dots";
9
- DotType["randomDots"] = "random-dots";
10
- DotType["rounded"] = "rounded";
11
- DotType["verticalLines"] = "vertical-lines";
12
- DotType["horizontalLines"] = "horizontal-lines";
13
- DotType["classy"] = "classy";
14
- DotType["classyRounded"] = "classy-rounded";
15
- DotType["square"] = "square";
16
- DotType["smallSquare"] = "small-square";
17
- DotType["extraRounded"] = "extra-rounded";
18
- DotType["diamond"] = "diamond";
19
- })(DotType || (DotType = {}));
20
- var CornerDotType;
21
- (function (CornerDotType) {
22
- CornerDotType["dot"] = "dot";
23
- CornerDotType["square"] = "square";
24
- CornerDotType["heart"] = "heart";
25
- CornerDotType["extraRounded"] = "extra-rounded";
26
- CornerDotType["classy"] = "classy";
27
- CornerDotType["outpoint"] = "outpoint";
28
- CornerDotType["inpoint"] = "inpoint";
29
- })(CornerDotType || (CornerDotType = {}));
30
- var CornerSquareType;
31
- (function (CornerSquareType) {
32
- CornerSquareType["dot"] = "dot";
33
- CornerSquareType["square"] = "square";
34
- CornerSquareType["extraRounded"] = "extra-rounded";
35
- CornerSquareType["classy"] = "classy";
36
- CornerSquareType["outpoint"] = "outpoint";
37
- CornerSquareType["inpoint"] = "inpoint";
38
- })(CornerSquareType || (CornerSquareType = {}));
39
- var GradientType;
40
- (function (GradientType) {
41
- GradientType["radial"] = "radial";
42
- GradientType["linear"] = "linear";
43
- })(GradientType || (GradientType = {}));
44
- var ShapeType;
45
- (function (ShapeType) {
46
- ShapeType["square"] = "square";
47
- ShapeType["circle"] = "circle";
48
- })(ShapeType || (ShapeType = {}));
49
- const TypeNumber = Array(41)
50
- .fill(0)
51
- .map((_, i) => i);
52
- var ErrorCorrectionLevel;
53
- (function (ErrorCorrectionLevel) {
54
- ErrorCorrectionLevel["L"] = "L";
55
- ErrorCorrectionLevel["M"] = "M";
56
- ErrorCorrectionLevel["Q"] = "Q";
57
- ErrorCorrectionLevel["H"] = "H";
58
- })(ErrorCorrectionLevel || (ErrorCorrectionLevel = {}));
59
- var Mode;
60
- (function (Mode) {
61
- Mode["numeric"] = "Numeric";
62
- Mode["alphanumeric"] = "Alphanumeric";
63
- Mode["byte"] = "Byte";
64
- Mode["kanji"] = "Kanji";
65
- Mode["unicode"] = "Unicode";
66
- })(Mode || (Mode = {}));
67
- var FileExtension;
68
- (function (FileExtension) {
69
- FileExtension["svg"] = "svg";
70
- FileExtension["png"] = "png";
71
- FileExtension["jpeg"] = "jpeg";
72
- FileExtension["webp"] = "webp";
73
- })(FileExtension || (FileExtension = {}));
3
+ import sharp from "sharp";
74
4
 
75
- const ErrorCorrectionPercents = {
76
- [ErrorCorrectionLevel.L]: 0.07,
77
- [ErrorCorrectionLevel.M]: 0.15,
78
- [ErrorCorrectionLevel.Q]: 0.25,
79
- [ErrorCorrectionLevel.H]: 0.3
80
- };
5
+ import { fileTypeFromBuffer } from "file-type";
81
6
 
82
- function getMode(data) {
83
- switch (true) {
84
- case /^[0-9]*$/.test(data):
85
- return Mode.numeric;
86
- case /^[0-9A-Z $%*+\-./:]*$/.test(data):
87
- return Mode.alphanumeric;
88
- // eslint-disable-next-line no-control-regex
89
- case /[^\u0000-\u00ff]/.test(data):
90
- return Mode.unicode;
91
- default:
92
- return Mode.byte;
93
- }
94
- }
7
+ import { DOMImplementation, XMLSerializer as XMLSerializer$1, DOMParser as DOMParser$1 } from "@xmldom/xmldom";
8
+
9
+ let TypeNumber = Array(41).fill(0).map(((_, i) => i));
10
+
11
+ var ErrorCorrectionLevel, Mode;
12
+
13
+ (ErrorCorrectionLevel = ErrorCorrectionLevel || (ErrorCorrectionLevel = {})).L = "L",
14
+ ErrorCorrectionLevel.M = "M", ErrorCorrectionLevel.Q = "Q", ErrorCorrectionLevel.H = "H",
15
+ (Mode = Mode || (Mode = {})).numeric = "Numeric", Mode.alphanumeric = "Alphanumeric",
16
+ Mode.byte = "Byte", Mode.kanji = "Kanji", Mode.unicode = "Unicode";
17
+
18
+ let isObject = obj => !!obj && "object" == typeof obj && !Array.isArray(obj);
95
19
 
96
- const isObject = (obj) => !!obj && typeof obj === "object" && !Array.isArray(obj);
97
20
  function mergeDeep(target, ...sources) {
98
- if (!sources.length)
99
- return target;
100
- const source = sources.shift();
101
- if (source === undefined || !isObject(target) || !isObject(source))
102
- return target;
103
- target = { ...target };
104
- Object.keys(source).forEach((key) => {
105
- const targetValue = target[key];
106
- const sourceValue = source[key];
107
- if (Array.isArray(targetValue) && Array.isArray(sourceValue)) {
108
- target[key] = sourceValue;
109
- }
110
- else if (isObject(targetValue) && isObject(sourceValue)) {
111
- target[key] = mergeDeep(Object.assign({}, targetValue), sourceValue);
112
- }
113
- else {
114
- target[key] = sourceValue;
115
- }
116
- });
117
- return mergeDeep(target, ...sources);
21
+ if (!sources.length) return target;
22
+ let source = sources.shift();
23
+ return void 0 !== source && isObject(target) && isObject(source) ? (target = {
24
+ ...target
25
+ }, Object.keys(source).forEach((key => {
26
+ let targetValue = target[key], sourceValue = source[key];
27
+ Array.isArray(targetValue) && Array.isArray(sourceValue) ? target[key] = sourceValue : isObject(targetValue) && isObject(sourceValue) ? target[key] = mergeDeep(Object.assign({}, targetValue), sourceValue) : target[key] = sourceValue;
28
+ })), mergeDeep(target, ...sources)) : target;
118
29
  }
119
30
 
120
- function sanitizeGradient(gradient) {
121
- const newGradient = { ...gradient };
122
- if (!newGradient.colorStops || !newGradient.colorStops.length) {
123
- throw "Field 'colorStops' is required in gradient";
124
- }
125
- if (newGradient.rotation) {
126
- newGradient.rotation = Number(newGradient.rotation);
127
- }
128
- else {
129
- newGradient.rotation = 0;
130
- }
131
- newGradient.colorStops = newGradient.colorStops.map((colorStop) => ({
31
+ var GradientType, DotType, CornerDotType, CornerSquareType, ShapeType;
32
+
33
+ function sanitizeGradient(gradient_newGradient) {
34
+ if (!(gradient_newGradient = {
35
+ ...gradient_newGradient
36
+ }).colorStops || !gradient_newGradient.colorStops.length) throw "Field 'colorStops' is required in gradient";
37
+ return gradient_newGradient.rotation = gradient_newGradient.rotation ? Number(gradient_newGradient.rotation) : 0,
38
+ gradient_newGradient.colorStops = gradient_newGradient.colorStops.map((colorStop => ({
132
39
  ...colorStop,
133
40
  offset: Number(colorStop.offset)
134
- }));
135
- return newGradient;
136
- }
137
- function sanitizeOptions(options) {
138
- const newOptions = { ...options };
139
- newOptions.imageOptions = {
140
- ...newOptions.imageOptions,
141
- hideBackgroundDots: Boolean(newOptions.imageOptions.hideBackgroundDots),
142
- imageSize: Math.min(1, Number(newOptions.imageOptions.imageSize)) || 1,
143
- margin: Number(newOptions.imageOptions.margin)
144
- };
145
- newOptions.dotsOptions = {
146
- ...newOptions.dotsOptions
147
- };
148
- if (newOptions.dotsOptions.gradient) {
149
- newOptions.dotsOptions.gradient = sanitizeGradient(newOptions.dotsOptions.gradient);
150
- }
151
- // Ensure integer dot size
152
- newOptions.dotsOptions.size = Math.round(Math.max(0, newOptions.dotsOptions.size) || 10);
153
- if (newOptions.cornersSquareOptions) {
154
- newOptions.cornersSquareOptions = {
155
- ...newOptions.cornersSquareOptions
156
- };
157
- if (newOptions.cornersSquareOptions.gradient) {
158
- newOptions.cornersSquareOptions.gradient = sanitizeGradient(newOptions.cornersSquareOptions.gradient);
159
- }
160
- }
161
- if (newOptions.cornersDotOptions) {
162
- newOptions.cornersDotOptions = {
163
- ...newOptions.cornersDotOptions
164
- };
165
- if (newOptions.cornersDotOptions.gradient) {
166
- newOptions.cornersDotOptions.gradient = sanitizeGradient(newOptions.cornersDotOptions.gradient);
167
- }
168
- }
169
- if (newOptions.backgroundOptions) {
170
- newOptions.backgroundOptions = {
171
- ...newOptions.backgroundOptions
172
- };
173
- if (newOptions.backgroundOptions.gradient) {
174
- newOptions.backgroundOptions.gradient = sanitizeGradient(newOptions.backgroundOptions.gradient);
175
- }
176
- }
177
- if (!newOptions.document)
178
- newOptions.document = document;
179
- return newOptions;
41
+ }))), gradient_newGradient;
180
42
  }
181
43
 
182
- const defaultOptions = {
183
- document: undefined,
44
+ (GradientType = GradientType || (GradientType = {})).radial = "radial", GradientType.linear = "linear",
45
+ (DotType = DotType || (DotType = {})).dot = "dot", DotType.randomDot = "random-dot",
46
+ DotType.rounded = "rounded", DotType.verticalLine = "vertical-line", DotType.horizontalLine = "horizontal-line",
47
+ DotType.classy = "classy", DotType.classyRounded = "classy-rounded", DotType.square = "square",
48
+ DotType.smallSquare = "small-square", DotType.extraRounded = "extra-rounded", DotType.diamond = "diamond",
49
+ (CornerDotType = CornerDotType || (CornerDotType = {})).dot = "dot", CornerDotType.square = "square",
50
+ CornerDotType.heart = "heart", CornerDotType.extraRounded = "extra-rounded", CornerDotType.classy = "classy",
51
+ CornerDotType.outpoint = "outpoint", CornerDotType.inpoint = "inpoint", (CornerSquareType = CornerSquareType || (CornerSquareType = {})).dot = "dot",
52
+ CornerSquareType.square = "square", CornerSquareType.extraRounded = "extra-rounded",
53
+ CornerSquareType.classy = "classy", CornerSquareType.outpoint = "outpoint", CornerSquareType.inpoint = "inpoint",
54
+ (ShapeType = ShapeType || (ShapeType = {})).square = "square", ShapeType.circle = "circle";
55
+
56
+ let defaultOptions = {
57
+ document: void 0,
184
58
  shape: ShapeType.square,
185
- width: undefined,
186
- height: undefined,
59
+ width: void 0,
60
+ height: void 0,
187
61
  data: "",
188
62
  qrOptions: {
189
63
  typeNumber: TypeNumber[0],
190
- mode: undefined,
64
+ mode: void 0,
191
65
  errorCorrectionLevel: ErrorCorrectionLevel.Q
192
66
  },
193
67
  imageOptions: {
194
- hideBackgroundDots: true,
195
- imageSize: 0.4,
196
- crossOrigin: undefined,
68
+ hideBackgroundDots: !0,
69
+ imageSize: .4,
70
+ crossOrigin: void 0,
197
71
  margin: 0
198
72
  },
199
73
  dotsOptions: {
@@ -203,1038 +77,774 @@ const defaultOptions = {
203
77
  }
204
78
  };
205
79
 
80
+ function sanitizeOptions(newOptions_options) {
81
+ return (newOptions_options = {
82
+ ...newOptions_options
83
+ }).imageOptions = {
84
+ ...newOptions_options.imageOptions,
85
+ hideBackgroundDots: !!newOptions_options.imageOptions.hideBackgroundDots,
86
+ imageSize: Math.min(1, Number(newOptions_options.imageOptions.imageSize)) || 1,
87
+ margin: Number(newOptions_options.imageOptions.margin)
88
+ }, newOptions_options.dotsOptions = {
89
+ ...newOptions_options.dotsOptions
90
+ }, newOptions_options.dotsOptions.gradient && (newOptions_options.dotsOptions.gradient = sanitizeGradient(newOptions_options.dotsOptions.gradient)),
91
+ newOptions_options.dotsOptions.size = Math.round(Math.max(0, newOptions_options.dotsOptions.size) || 10),
92
+ newOptions_options.cornersSquareOptions && (newOptions_options.cornersSquareOptions = {
93
+ ...newOptions_options.cornersSquareOptions
94
+ }, newOptions_options.cornersSquareOptions.gradient && (newOptions_options.cornersSquareOptions.gradient = sanitizeGradient(newOptions_options.cornersSquareOptions.gradient))),
95
+ newOptions_options.cornersDotOptions && (newOptions_options.cornersDotOptions = {
96
+ ...newOptions_options.cornersDotOptions
97
+ }, newOptions_options.cornersDotOptions.gradient && (newOptions_options.cornersDotOptions.gradient = sanitizeGradient(newOptions_options.cornersDotOptions.gradient))),
98
+ newOptions_options.backgroundOptions && (newOptions_options.backgroundOptions = {
99
+ ...newOptions_options.backgroundOptions
100
+ }, newOptions_options.backgroundOptions.gradient && (newOptions_options.backgroundOptions.gradient = sanitizeGradient(newOptions_options.backgroundOptions.gradient))),
101
+ newOptions_options.document || (newOptions_options.document = document), newOptions_options;
102
+ }
103
+
104
+ let ErrorCorrectionPercents = {
105
+ [ErrorCorrectionLevel.L]: .07,
106
+ [ErrorCorrectionLevel.M]: .15,
107
+ [ErrorCorrectionLevel.Q]: .25,
108
+ [ErrorCorrectionLevel.H]: .3
109
+ };
110
+
111
+ let rx = /\.?0+$/;
112
+
113
+ function numToAttr(value) {
114
+ return value.toFixed(7).replace(rx, "");
115
+ }
116
+
117
+ function svgPath(strings, ...values) {
118
+ return strings.reduce(((t, v, i) => {
119
+ let p = "";
120
+ return i && (p = values[i - 1]), "number" == typeof p && (p = numToAttr(p)), `${t}${p}${v}`;
121
+ }), "").trim().replace(/[\s\n\r]+/gim, " ");
122
+ }
123
+
206
124
  class QRCornerDot {
207
- constructor({ svg, type, document }) {
208
- this._svg = svg;
209
- this._type = type;
210
- this._document = document;
125
+ get element() {
126
+ return this._element;
211
127
  }
212
- draw(x, y, size, rotation) {
213
- const type = this._type;
128
+ constructor(type, document) {
129
+ this.type = type, this.document = document;
130
+ }
131
+ draw(args) {
214
132
  let drawFunction;
215
- switch (type) {
216
- case CornerDotType.square:
217
- drawFunction = this._drawSquare;
218
- break;
219
- case CornerDotType.heart:
220
- drawFunction = this._drawHeart;
221
- break;
222
- case CornerDotType.extraRounded:
223
- drawFunction = this._drawRounded;
224
- break;
225
- case CornerDotType.classy:
226
- drawFunction = this._drawClassy;
227
- break;
228
- case CornerDotType.inpoint:
229
- drawFunction = this._drawInpoint;
230
- break;
231
- case CornerDotType.outpoint:
232
- drawFunction = this._drawOutpoint;
233
- break;
234
- case CornerDotType.dot:
235
- default:
236
- drawFunction = this._drawDot;
133
+ switch (this.type) {
134
+ case CornerDotType.square:
135
+ drawFunction = this.drawSquare;
136
+ break;
137
+
138
+ case CornerDotType.heart:
139
+ drawFunction = this.drawHeart;
140
+ break;
141
+
142
+ case CornerDotType.extraRounded:
143
+ drawFunction = this.drawRounded;
144
+ break;
145
+
146
+ case CornerDotType.classy:
147
+ drawFunction = this.drawClassy;
148
+ break;
149
+
150
+ case CornerDotType.inpoint:
151
+ drawFunction = this.drawInpoint;
152
+ break;
153
+
154
+ case CornerDotType.outpoint:
155
+ drawFunction = this.drawOutpoint;
156
+ break;
157
+
158
+ default:
159
+ drawFunction = this.drawDot;
237
160
  }
238
- drawFunction.call(this, { x, y, size, rotation });
161
+ drawFunction.call(this, args);
239
162
  }
240
- _rotateFigure({ x, y, size, rotation = 0, draw }) {
241
- const cx = x + size / 2;
242
- const cy = y + size / 2;
243
- draw();
244
- this._element?.setAttribute("transform", `rotate(${(180 * rotation) / Math.PI},${cx},${cy})`);
163
+ rotateFigure({x: cx_x, y: cy_y, size, rotation = 0, draw}) {
164
+ cx_x += size / 2, cy_y += size / 2, draw(), this._element?.setAttribute("transform", `rotate(${numToAttr(180 * rotation / Math.PI)},${cx_x},${cy_y})`);
245
165
  }
246
- _basicDot(args) {
247
- const { size, x, y } = args;
248
- this._rotateFigure({
166
+ basicDot(args) {
167
+ let {size, x, y} = args;
168
+ this.rotateFigure({
249
169
  ...args,
250
170
  draw: () => {
251
- this._element = this._document.createElementNS("http://www.w3.org/2000/svg", "circle");
252
- this._element.setAttribute("cx", String(x + size / 2));
253
- this._element.setAttribute("cy", String(y + size / 2));
254
- this._element.setAttribute("r", String(size / 2));
171
+ this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "circle"),
172
+ this._element.setAttribute("cx", numToAttr(x + size / 2)), this._element.setAttribute("cy", numToAttr(y + size / 2)),
173
+ this._element.setAttribute("r", numToAttr(size / 2));
255
174
  }
256
175
  });
257
176
  }
258
- _basicSquare(args) {
259
- const { size, x, y } = args;
260
- this._rotateFigure({
177
+ basicSquare(args) {
178
+ let {size, x, y} = args;
179
+ this.rotateFigure({
261
180
  ...args,
262
181
  draw: () => {
263
- this._element = this._document.createElementNS("http://www.w3.org/2000/svg", "rect");
264
- this._element.setAttribute("x", String(x));
265
- this._element.setAttribute("y", String(y));
266
- this._element.setAttribute("width", String(size));
267
- this._element.setAttribute("height", String(size));
182
+ this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "rect"),
183
+ this._element.setAttribute("x", numToAttr(x)), this._element.setAttribute("y", numToAttr(y)),
184
+ this._element.setAttribute("width", numToAttr(size)), this._element.setAttribute("height", numToAttr(size));
268
185
  }
269
186
  });
270
187
  }
271
- _basicHeart(args) {
272
- const { size, x, y } = args;
273
- this._element = this._document.createElementNS("http://www.w3.org/2000/svg", "path");
274
- const path = [
275
- "M",
276
- 0.925,
277
- 0.3538125,
278
- "c",
279
- 0,
280
- 0.0325869,
281
- -0.0054931,
282
- 0.0644619,
283
- -0.0164688,
284
- 0.095625,
285
- "S",
286
- 0.87825,
287
- 0.5147812,
288
- 0.850625,
289
- 0.5519688,
290
- "C",
291
- 0.823,
292
- 0.5891563,
293
- 0.7858125,
294
- 0.631125,
295
- 0.7390625,
296
- 0.677875,
297
- "S",
298
- 0.6331632,
299
- 0.7802256,
300
- 0.561625,
301
- 0.8446875,
302
- "L",
303
- 0.5,
304
- 0.8999375,
305
- "l",
306
- -0.061625,
307
- -0.05525,
308
- "C",
309
- 0.3668368,
310
- 0.7802256,
311
- 0.3076875,
312
- 0.724625,
313
- 0.2609375,
314
- 0.677875,
315
- "S",
316
- 0.177,
317
- 0.5891563,
318
- 0.149375,
319
- 0.5519688,
320
- "S",
321
- 0.1024444,
322
- 0.4806007,
323
- 0.0914688,
324
- 0.4494375,
325
- "S",
326
- 0.075,
327
- 0.3863994,
328
- 0.075,
329
- 0.3538125,
330
- "C",
331
- 0.075,
332
- 0.2872256,
333
- 0.0973125,
334
- 0.231625,
335
- 0.1419375,
336
- 0.187,
337
- "S",
338
- 0.2421631,
339
- 0.1200625,
340
- 0.30875,
341
- 0.1200625,
342
- "c",
343
- 0.0368369,
344
- 0,
345
- 0.0718994,
346
- 0.0077881,
347
- 0.1051875,
348
- 0.023375,
349
- "S",
350
- 0.4759131,
351
- 0.1809756,
352
- 0.5,
353
- 0.2093125,
354
- "c",
355
- 0.0240868,
356
- -0.0283369,
357
- 0.0527744,
358
- -0.0502881,
359
- 0.0860625,
360
- -0.065875,
361
- "c",
362
- 0.0332882,
363
- -0.0155869,
364
- 0.0683507,
365
- -0.023375,
366
- 0.1051875,
367
- -0.023375,
368
- "c",
369
- 0.0665869,
370
- 0,
371
- 0.1221875,
372
- 0.0223125,
373
- 0.1668125,
374
- 0.0669375,
375
- "S",
376
- 0.925,
377
- 0.2872256,
378
- 0.925,
379
- 0.3538125,
380
- "z"
381
- ];
382
- let move = false;
383
- let i = 0;
384
- this._element.setAttribute("d", path
385
- .map((v) => {
386
- if (typeof v == "string") {
387
- i = 0;
388
- move = v.toUpperCase() == v;
389
- return v;
390
- }
391
- i++;
392
- v = v * size;
393
- if (move) {
394
- v += i % 2 == 1 ? x : y;
395
- }
396
- return v.toFixed(5);
397
- })
398
- .join(" "));
399
- }
400
- _basicRounded(args) {
401
- const { size, x, y } = args;
402
- this._rotateFigure({
188
+ basicHeart(args) {
189
+ let {size, x, y} = args;
190
+ this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "path");
191
+ let move = !1, i = 0;
192
+ this._element.setAttribute("d", [ "M", .925, .3538125, "c", 0, .0325869, -.0054931, .0644619, -.0164688, .095625, "S", .87825, .5147812, .850625, .5519688, "C", .823, .5891563, .7858125, .631125, .7390625, .677875, "S", .6331632, .7802256, .561625, .8446875, "L", .5, .8999375, "l", -.061625, -.05525, "C", .3668368, .7802256, .3076875, .724625, .2609375, .677875, "S", .177, .5891563, .149375, .5519688, "S", .1024444, .4806007, .0914688, .4494375, "S", .075, .3863994, .075, .3538125, "C", .075, .2872256, .0973125, .231625, .1419375, .187, "S", .2421631, .1200625, .30875, .1200625, "c", .0368369, 0, .0718994, .0077881, .1051875, .023375, "S", .4759131, .1809756, .5, .2093125, "c", .0240868, -.0283369, .0527744, -.0502881, .0860625, -.065875, "c", .0332882, -.0155869, .0683507, -.023375, .1051875, -.023375, "c", .0665869, 0, .1221875, .0223125, .1668125, .0669375, "S", .925, .2872256, .925, .3538125, "z" ].map((v => "string" == typeof v ? (i = 0,
193
+ move = v.toUpperCase() == v, v) : (i++, v *= size, move && (v += 1 == i % 2 ? x : y),
194
+ numToAttr(v)))).join(" "));
195
+ }
196
+ basicRounded(args) {
197
+ let {size, x, y} = args;
198
+ this.rotateFigure({
403
199
  ...args,
404
200
  draw: () => {
405
- this._element = this._document.createElementNS("http://www.w3.org/2000/svg", "rect");
406
- this._element.setAttribute("x", String(x));
407
- this._element.setAttribute("y", String(y));
408
- this._element.setAttribute("width", String(size));
409
- this._element.setAttribute("height", String(size));
410
- this._element.setAttribute("rx", String(size / 4));
411
- this._element.setAttribute("ry", String(size / 4));
201
+ this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "rect"),
202
+ this._element.setAttribute("x", numToAttr(x)), this._element.setAttribute("y", numToAttr(y)),
203
+ this._element.setAttribute("width", numToAttr(size)), this._element.setAttribute("height", numToAttr(size)),
204
+ this._element.setAttribute("rx", numToAttr(size / 4)), this._element.setAttribute("ry", numToAttr(size / 4));
412
205
  }
413
206
  });
414
207
  }
415
- _basicClassy(args) {
416
- const { size, x, y } = args;
417
- const dotSize = size / 7;
418
- this._rotateFigure({
208
+ basicClassy(args) {
209
+ let {size, x, y} = args, dotSize = size / 7;
210
+ this.rotateFigure({
419
211
  ...args,
420
212
  draw: () => {
421
- this._element = this._document.createElementNS("http://www.w3.org/2000/svg", "path");
422
- this._element.setAttribute("clip-rule", "evenodd");
423
- this._element.setAttribute("d", `M ${x} ${y + 2.5 * dotSize}` +
424
- `v ${2 * dotSize}` +
425
- `a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${dotSize * 2.5} ${dotSize * 2.5}` +
426
- `h ${4.5 * dotSize}` +
427
- `v ${-4.5 * dotSize}` +
428
- `a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${-dotSize * 2.5} ${-dotSize * 2.5}` +
429
- `h ${-2 * dotSize}` +
430
- `H ${x}` +
431
- `z`);
213
+ this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "path"),
214
+ this._element.setAttribute("clip-rule", "evenodd"), this._element.setAttribute("d", svgPath`M ${x} ${y + 2.5 * dotSize} v ${2 * dotSize} a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${2.5 * dotSize} ${2.5 * dotSize} h ${4.5 * dotSize} v ${-4.5 * dotSize} a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${2.5 * -dotSize} ${2.5 * -dotSize} h ${-2 * dotSize} H ${x} z`);
432
215
  }
433
216
  });
434
217
  }
435
- _basicInpoint(args) {
436
- const { size, x, y } = args;
437
- const dotSize = size;
438
- this._rotateFigure({
218
+ basicInpoint(args) {
219
+ let {size, x, y} = args;
220
+ this.rotateFigure({
439
221
  ...args,
440
222
  draw: () => {
441
- this._element = this._document.createElementNS("http://www.w3.org/2000/svg", "path");
442
- this._element.setAttribute("clip-rule", "evenodd");
443
- this._element.setAttribute("d", `M ${x} ${y + dotSize / 2}` +
444
- `v ${dotSize / 4}` +
445
- `a ${dotSize / 4}, ${dotSize / 4} 0 0 0 ${dotSize / 4}, ${dotSize / 4}` +
446
- `h ${(dotSize / 4) * 3}` +
447
- `v ${(-dotSize / 4) * 3}` +
448
- `a ${dotSize / 4}, ${dotSize / 4} 0 0 0 ${-dotSize / 4}, ${-dotSize / 4}` +
449
- `h ${-dotSize / 2}` +
450
- `a ${dotSize / 4}, ${dotSize / 4} 0 0 0 ${-dotSize / 4}, ${dotSize / 4}` +
451
- `z`);
223
+ this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "path"),
224
+ this._element.setAttribute("clip-rule", "evenodd"), this._element.setAttribute("d", svgPath`M ${x} ${y + size / 2} v ${size / 4} a ${size / 4}, ${size / 4} 0 0 0 ${size / 4}, ${size / 4} h ${size / 4 * 3} v ${-size / 4 * 3} a ${size / 4}, ${size / 4} 0 0 0 ${-size / 4}, ${-size / 4} h ${-size / 2} a ${size / 4}, ${size / 4} 0 0 0 ${-size / 4}, ${size / 4} z`);
452
225
  }
453
226
  });
454
227
  }
455
- _drawDot({ x, y, size, rotation }) {
456
- this._basicDot({ x, y, size, rotation });
228
+ drawDot({x, y, size, rotation}) {
229
+ this.basicDot({
230
+ x,
231
+ y,
232
+ size,
233
+ rotation
234
+ });
457
235
  }
458
- _drawSquare({ x, y, size, rotation }) {
459
- this._basicSquare({ x, y, size, rotation });
236
+ drawSquare({x, y, size, rotation}) {
237
+ this.basicSquare({
238
+ x,
239
+ y,
240
+ size,
241
+ rotation
242
+ });
460
243
  }
461
- _drawHeart({ x, y, size, rotation }) {
462
- const scaleFactor = 0.2;
463
- this._basicHeart({
464
- x: x - (scaleFactor * size) / 2,
465
- y: y - (scaleFactor * size) / 2,
466
- size: size * (1 + scaleFactor),
244
+ drawHeart({x, y, size, rotation}) {
245
+ this.basicHeart({
246
+ x: x - .2 * size / 2,
247
+ y: y - .2 * size / 2,
248
+ size: 1.2 * size,
467
249
  rotation
468
250
  });
469
251
  }
470
- _drawRounded({ x, y, size, rotation }) {
471
- this._basicRounded({ x, y, size, rotation });
252
+ drawRounded({x, y, size, rotation}) {
253
+ this.basicRounded({
254
+ x,
255
+ y,
256
+ size,
257
+ rotation
258
+ });
472
259
  }
473
- _drawClassy({ x, y, size, rotation }) {
474
- this._basicClassy({ x, y, size, rotation });
260
+ drawClassy({x, y, size, rotation}) {
261
+ this.basicClassy({
262
+ x,
263
+ y,
264
+ size,
265
+ rotation
266
+ });
475
267
  }
476
- _drawInpoint({ x, y, size, rotation }) {
477
- this._basicInpoint({ x, y, size, rotation });
268
+ drawInpoint({x, y, size, rotation}) {
269
+ this.basicInpoint({
270
+ x,
271
+ y,
272
+ size,
273
+ rotation
274
+ });
478
275
  }
479
- _drawOutpoint({ x, y, size, rotation }) {
480
- this._basicInpoint({ x, y, size, rotation: (rotation || 0) + Math.PI });
276
+ drawOutpoint({x, y, size, rotation}) {
277
+ this.basicInpoint({
278
+ x,
279
+ y,
280
+ size,
281
+ rotation: (rotation || 0) + Math.PI
282
+ });
481
283
  }
482
284
  }
483
285
 
484
286
  class QRCornerSquare {
485
- constructor({ svg, type, document }) {
486
- this._svg = svg;
487
- this._type = type;
488
- this._document = document;
287
+ get element() {
288
+ return this._element;
489
289
  }
490
- draw(x, y, size, rotation) {
491
- const type = this._type;
290
+ constructor(type, document) {
291
+ this.type = type, this.document = document;
292
+ }
293
+ draw(args) {
492
294
  let drawFunction;
493
- switch (type) {
494
- case CornerSquareType.square:
495
- drawFunction = this._drawSquare;
496
- break;
497
- case CornerSquareType.extraRounded:
498
- drawFunction = this._drawExtraRounded;
499
- break;
500
- case CornerSquareType.classy:
501
- drawFunction = this._drawClassy;
502
- break;
503
- case CornerSquareType.outpoint:
504
- drawFunction = this._drawOutpoint;
505
- break;
506
- case CornerSquareType.inpoint:
507
- drawFunction = this._drawInpoint;
508
- break;
509
- case CornerSquareType.dot:
510
- default:
511
- drawFunction = this._drawDot;
295
+ switch (this.type) {
296
+ case CornerSquareType.square:
297
+ drawFunction = this.drawSquare;
298
+ break;
299
+
300
+ case CornerSquareType.extraRounded:
301
+ drawFunction = this.drawExtraRounded;
302
+ break;
303
+
304
+ case CornerSquareType.classy:
305
+ drawFunction = this.drawClassy;
306
+ break;
307
+
308
+ case CornerSquareType.outpoint:
309
+ drawFunction = this.drawOutpoint;
310
+ break;
311
+
312
+ case CornerSquareType.inpoint:
313
+ drawFunction = this.drawInpoint;
314
+ break;
315
+
316
+ default:
317
+ drawFunction = this.drawDot;
512
318
  }
513
- drawFunction.call(this, { x, y, size, rotation });
514
- }
515
- _rotateFigure({ x, y, size, rotation = 0, draw }) {
516
- const cx = x + size / 2;
517
- const cy = y + size / 2;
518
- draw();
519
- this._element?.setAttribute("transform", `rotate(${(180 * rotation) / Math.PI},${cx},${cy})`);
520
- }
521
- _basicDot(args) {
522
- const { size, x, y } = args;
523
- const dotSize = size / 7;
524
- this._rotateFigure({
319
+ drawFunction.call(this, args);
320
+ }
321
+ rotateFigure({x: cx, y: cy, size, rotation = 0, draw}) {
322
+ cx += size / 2, cy += size / 2, draw(), this._element?.setAttribute("transform", `rotate(${numToAttr(180 * rotation / Math.PI)},${cx},${cy})`);
323
+ }
324
+ basicDot(args) {
325
+ let {size, x, y} = args, dotSize = size / 7;
326
+ this.rotateFigure({
525
327
  ...args,
526
328
  draw: () => {
527
- this._element = this._document.createElementNS("http://www.w3.org/2000/svg", "path");
528
- this._element.setAttribute("clip-rule", "evenodd");
529
- this._element.setAttribute("d", `M ${x + size / 2} ${y}` + // M cx, y // Move to top of ring
530
- `a ${size / 2} ${size / 2} 0 1 0 0.1 0` + // a outerRadius, outerRadius, 0, 1, 0, 1, 0 // Draw outer arc, but don't close it
531
- `z` + // Z // Close the outer shape
532
- `m 0 ${dotSize}` + // m -1 outerRadius-innerRadius // Move to top point of inner radius
533
- `a ${size / 2 - dotSize} ${size / 2 - dotSize} 0 1 1 -0.1 0` + // a innerRadius, innerRadius, 0, 1, 1, -1, 0 // Draw inner arc, but don't close it
534
- `Z` // Z // Close the inner ring. Actually will still work without, but inner ring will have one unit missing in stroke
535
- );
329
+ this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "path"),
330
+ this._element.setAttribute("clip-rule", "evenodd"), this._element.setAttribute("d", svgPath`M ${x + size / 2} ${y} a ${size / 2} ${size / 2} 0 1 0 0.1 0 z m 0 ${dotSize} a ${size / 2 - dotSize} ${size / 2 - dotSize} 0 1 1 -0.1 0 Z`);
536
331
  }
537
332
  });
538
333
  }
539
- _basicSquare(args) {
540
- const { size, x, y } = args;
541
- const dotSize = size / 7;
542
- this._rotateFigure({
334
+ basicSquare(args) {
335
+ let {size, x, y} = args, dotSize = size / 7;
336
+ this.rotateFigure({
543
337
  ...args,
544
338
  draw: () => {
545
- this._element = this._document.createElementNS("http://www.w3.org/2000/svg", "path");
546
- this._element.setAttribute("clip-rule", "evenodd");
547
- this._element.setAttribute("d", `M ${x} ${y}` +
548
- `v ${size}` +
549
- `h ${size}` +
550
- `v ${-size}` +
551
- `z` +
552
- `M ${x + dotSize} ${y + dotSize}` +
553
- `h ${size - 2 * dotSize}` +
554
- `v ${size - 2 * dotSize}` +
555
- `h ${-size + 2 * dotSize}` +
556
- `z`);
339
+ this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "path"),
340
+ this._element.setAttribute("clip-rule", "evenodd"), this._element.setAttribute("d", svgPath`M ${x} ${y} v ${size} h ${size} v ${-size} z M ${x + dotSize} ${y + dotSize} h ${size - 2 * dotSize} v ${size - 2 * dotSize} h ${2 * dotSize - size} z`);
557
341
  }
558
342
  });
559
343
  }
560
- _basicExtraRounded(args) {
561
- const { size, x, y } = args;
562
- const dotSize = size / 7;
563
- this._rotateFigure({
344
+ basicExtraRounded(args) {
345
+ let {size, x, y} = args, dotSize = size / 7;
346
+ this.rotateFigure({
564
347
  ...args,
565
348
  draw: () => {
566
- this._element = this._document.createElementNS("http://www.w3.org/2000/svg", "path");
567
- this._element.setAttribute("clip-rule", "evenodd");
568
- this._element.setAttribute("d", `M ${x} ${y + 2.5 * dotSize}` +
569
- `v ${2 * dotSize}` +
570
- `a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${dotSize * 2.5} ${dotSize * 2.5}` +
571
- `h ${2 * dotSize}` +
572
- `a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${dotSize * 2.5} ${-dotSize * 2.5}` +
573
- `v ${-2 * dotSize}` +
574
- `a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${-dotSize * 2.5} ${-dotSize * 2.5}` +
575
- `h ${-2 * dotSize}` +
576
- `a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${-dotSize * 2.5} ${dotSize * 2.5}` +
577
- `z` +
578
- `M ${x + 2.5 * dotSize} ${y + dotSize}` +
579
- `h ${2 * dotSize}` +
580
- `a ${1.5 * dotSize} ${1.5 * dotSize}, 0, 0, 1, ${dotSize * 1.5} ${dotSize * 1.5}` +
581
- `v ${2 * dotSize}` +
582
- `a ${1.5 * dotSize} ${1.5 * dotSize}, 0, 0, 1, ${-dotSize * 1.5} ${dotSize * 1.5}` +
583
- `h ${-2 * dotSize}` +
584
- `a ${1.5 * dotSize} ${1.5 * dotSize}, 0, 0, 1, ${-dotSize * 1.5} ${-dotSize * 1.5}` +
585
- `v ${-2 * dotSize}` +
586
- `a ${1.5 * dotSize} ${1.5 * dotSize}, 0, 0, 1, ${dotSize * 1.5} ${-dotSize * 1.5}` +
587
- `z`);
349
+ this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "path"),
350
+ this._element.setAttribute("clip-rule", "evenodd"), this._element.setAttribute("d", svgPath`M ${x} ${y + 2.5 * dotSize} v ${2 * dotSize} a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${2.5 * dotSize} ${2.5 * dotSize} h ${2 * dotSize} a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${2.5 * dotSize} ${2.5 * -dotSize} v ${-2 * dotSize} a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${2.5 * -dotSize} ${2.5 * -dotSize} h ${-2 * dotSize} a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${2.5 * -dotSize} ${2.5 * dotSize} z M ${x + 2.5 * dotSize} ${y + dotSize} h ${2 * dotSize} a ${1.5 * dotSize} ${1.5 * dotSize}, 0, 0, 1, ${1.5 * dotSize} ${1.5 * dotSize} v ${2 * dotSize} a ${1.5 * dotSize} ${1.5 * dotSize}, 0, 0, 1, ${1.5 * -dotSize} ${1.5 * dotSize} h ${-2 * dotSize} a ${1.5 * dotSize} ${1.5 * dotSize}, 0, 0, 1, ${1.5 * -dotSize} ${1.5 * -dotSize} v ${-2 * dotSize} a ${1.5 * dotSize} ${1.5 * dotSize}, 0, 0, 1, ${1.5 * dotSize} ${1.5 * -dotSize} z`);
588
351
  }
589
352
  });
590
353
  }
591
- _basicClassy(args) {
592
- const { size, x, y } = args;
593
- const dotSize = size / 7;
594
- this._rotateFigure({
354
+ basicClassy(args) {
355
+ let {size, x, y} = args, dotSize = size / 7;
356
+ this.rotateFigure({
595
357
  ...args,
596
358
  draw: () => {
597
- this._element = this._document.createElementNS("http://www.w3.org/2000/svg", "path");
598
- this._element.setAttribute("clip-rule", "evenodd");
599
- this._element.setAttribute("d", `M ${x} ${y + 2.5 * dotSize}` +
600
- `v ${2 * dotSize}` +
601
- `a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${dotSize * 2.5} ${dotSize * 2.5}` +
602
- `h ${4.5 * dotSize}` +
603
- `v ${-4.5 * dotSize}` +
604
- `a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${-dotSize * 2.5} ${-dotSize * 2.5}` +
605
- `h ${-2 * dotSize}` +
606
- `H ${x}` +
607
- `z` +
608
- `M ${x + 2.5 * dotSize} ${y + dotSize}` +
609
- `h ${2 * dotSize}` +
610
- `a ${1.5 * dotSize} ${1.5 * dotSize}, 0, 0, 1, ${dotSize * 1.5} ${dotSize * 1.5}` +
611
- `v ${3.5 * dotSize}` +
612
- `h ${-3.5 * dotSize}` +
613
- `a ${1.5 * dotSize} ${1.5 * dotSize}, 0, 0, 1, ${-dotSize * 1.5} ${-dotSize * 1.5}` +
614
- `v ${-3.5 * dotSize}` +
615
- `z`);
359
+ this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "path"),
360
+ this._element.setAttribute("clip-rule", "evenodd"), this._element.setAttribute("d", svgPath`M ${x} ${y + 2.5 * dotSize} v ${2 * dotSize} a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${2.5 * dotSize} ${2.5 * dotSize} h ${4.5 * dotSize} v ${-4.5 * dotSize} a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${2.5 * -dotSize} ${2.5 * -dotSize} h ${-2 * dotSize} H ${x} z M ${x + 2.5 * dotSize} ${y + dotSize} h ${2 * dotSize} a ${1.5 * dotSize} ${1.5 * dotSize}, 0, 0, 1, ${1.5 * dotSize} ${1.5 * dotSize} v ${3.5 * dotSize} h ${-3.5 * dotSize} a ${1.5 * dotSize} ${1.5 * dotSize}, 0, 0, 1, ${1.5 * -dotSize} ${1.5 * -dotSize} v ${-3.5 * dotSize} z`);
616
361
  }
617
362
  });
618
363
  }
619
- _basicInpoint(args) {
620
- const { size, x, y } = args;
621
- const dotSize = size / 7;
622
- this._rotateFigure({
364
+ basicInpoint(args) {
365
+ let {size, x, y} = args, dotSize = size / 7;
366
+ this.rotateFigure({
623
367
  ...args,
624
368
  draw: () => {
625
- this._element = this._document.createElementNS("http://www.w3.org/2000/svg", "path");
626
- this._element.setAttribute("clip-rule", "evenodd");
627
- this._element.setAttribute("d", `M ${x} ${y + 2.5 * dotSize}` +
628
- `v ${2 * dotSize}` +
629
- `a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${dotSize * 2.5} ${dotSize * 2.5}` +
630
- `h ${4.5 * dotSize}` +
631
- `v ${-4.5 * dotSize}` +
632
- `a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${-dotSize * 2.5} ${-dotSize * 2.5}` +
633
- `h ${-2 * dotSize}` +
634
- `a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${-dotSize * 2.5} ${dotSize * 2.5}` +
635
- "z" +
636
- `M ${x + 2.5 * dotSize} ${y + dotSize}` +
637
- `h ${2 * dotSize}` +
638
- `a ${1.5 * dotSize} ${1.5 * dotSize}, 0, 0, 1, ${dotSize * 1.5} ${dotSize * 1.5}` +
639
- `v ${3.5 * dotSize}` +
640
- `h ${-3.5 * dotSize}` +
641
- `a ${1.5 * dotSize} ${1.5 * dotSize}, 0, 0, 1, ${-dotSize * 1.5} ${-dotSize * 1.5}` +
642
- `v ${-2 * dotSize}` +
643
- `a ${1.5 * dotSize} ${1.5 * dotSize}, 0, 0, 1, ${dotSize * 1.5} ${-dotSize * 1.5}` +
644
- `z`);
369
+ this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "path"),
370
+ this._element.setAttribute("clip-rule", "evenodd"), this._element.setAttribute("d", svgPath`M ${x} ${y + 2.5 * dotSize} v ${2 * dotSize} a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${2.5 * dotSize} ${2.5 * dotSize} h ${4.5 * dotSize} v ${-4.5 * dotSize} a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${2.5 * -dotSize} ${2.5 * -dotSize} h ${-2 * dotSize} a ${2.5 * dotSize} ${2.5 * dotSize}, 0, 0, 0, ${2.5 * -dotSize} ${2.5 * dotSize} z M ${x + 2.5 * dotSize} ${y + dotSize} h ${2 * dotSize} a ${1.5 * dotSize} ${1.5 * dotSize}, 0, 0, 1, ${1.5 * dotSize} ${1.5 * dotSize} v ${3.5 * dotSize} h ${-3.5 * dotSize} a ${1.5 * dotSize} ${1.5 * dotSize}, 0, 0, 1, ${1.5 * -dotSize} ${1.5 * -dotSize} v ${-2 * dotSize} a ${1.5 * dotSize} ${1.5 * dotSize}, 0, 0, 1, ${1.5 * dotSize} ${1.5 * -dotSize} z`);
645
371
  }
646
372
  });
647
373
  }
648
- _drawDot({ x, y, size, rotation }) {
649
- this._basicDot({ x, y, size, rotation });
374
+ drawDot({x, y, size, rotation}) {
375
+ this.basicDot({
376
+ x,
377
+ y,
378
+ size,
379
+ rotation
380
+ });
650
381
  }
651
- _drawSquare({ x, y, size, rotation }) {
652
- this._basicSquare({ x, y, size, rotation });
382
+ drawSquare({x, y, size, rotation}) {
383
+ this.basicSquare({
384
+ x,
385
+ y,
386
+ size,
387
+ rotation
388
+ });
653
389
  }
654
- _drawExtraRounded({ x, y, size, rotation }) {
655
- this._basicExtraRounded({ x, y, size, rotation });
390
+ drawExtraRounded({x, y, size, rotation}) {
391
+ this.basicExtraRounded({
392
+ x,
393
+ y,
394
+ size,
395
+ rotation
396
+ });
656
397
  }
657
- _drawClassy({ x, y, size, rotation }) {
658
- this._basicClassy({ x, y, size, rotation });
398
+ drawClassy({x, y, size, rotation}) {
399
+ this.basicClassy({
400
+ x,
401
+ y,
402
+ size,
403
+ rotation
404
+ });
659
405
  }
660
- _drawInpoint({ x, y, size, rotation }) {
661
- this._basicInpoint({ x, y, size, rotation });
406
+ drawInpoint({x, y, size, rotation}) {
407
+ this.basicInpoint({
408
+ x,
409
+ y,
410
+ size,
411
+ rotation
412
+ });
662
413
  }
663
- _drawOutpoint({ x, y, size, rotation }) {
664
- this._basicInpoint({ x, y, size, rotation: (rotation || 0) + Math.PI });
414
+ drawOutpoint({x, y, size, rotation}) {
415
+ this.basicInpoint({
416
+ x,
417
+ y,
418
+ size,
419
+ rotation: (rotation || 0) + Math.PI
420
+ });
665
421
  }
666
422
  }
667
423
 
668
424
  class QRDot {
669
- constructor({ svg, type, document }) {
670
- this._svg = svg;
671
- this._type = type;
672
- this._document = document;
425
+ get element() {
426
+ return this._element;
673
427
  }
674
- draw(x, y, size, getNeighbor) {
675
- const type = this._type;
428
+ constructor(type, document) {
429
+ this.type = type, this.document = document;
430
+ }
431
+ draw(args) {
676
432
  let drawFunction;
677
- switch (type) {
678
- case DotType.dots:
679
- drawFunction = this._drawDot;
680
- break;
681
- case DotType.randomDots:
682
- drawFunction = this._drawRandomDot;
683
- break;
684
- case DotType.classy:
685
- drawFunction = this._drawClassy;
686
- break;
687
- case DotType.classyRounded:
688
- drawFunction = this._drawClassyRounded;
689
- break;
690
- case DotType.rounded:
691
- drawFunction = this._drawRounded;
692
- break;
693
- case DotType.verticalLines:
694
- drawFunction = this._drawVerticalLines;
695
- break;
696
- case DotType.horizontalLines:
697
- drawFunction = this._drawHorizontalLines;
698
- break;
699
- case DotType.extraRounded:
700
- drawFunction = this._drawExtraRounded;
701
- break;
702
- case DotType.diamond:
703
- drawFunction = this._drawDiamond;
704
- break;
705
- case DotType.smallSquare:
706
- drawFunction = this._drawSmallSquare;
707
- break;
708
- case DotType.square:
709
- default:
710
- drawFunction = this._drawSquare;
433
+ switch (this.type) {
434
+ case DotType.dot:
435
+ drawFunction = this.drawDot;
436
+ break;
437
+
438
+ case DotType.randomDot:
439
+ drawFunction = this.drawRandomDot;
440
+ break;
441
+
442
+ case DotType.classy:
443
+ drawFunction = this.drawClassy;
444
+ break;
445
+
446
+ case DotType.classyRounded:
447
+ drawFunction = this.drawClassyRounded;
448
+ break;
449
+
450
+ case DotType.rounded:
451
+ drawFunction = this.drawRounded;
452
+ break;
453
+
454
+ case DotType.verticalLine:
455
+ drawFunction = this.drawVerticalLine;
456
+ break;
457
+
458
+ case DotType.horizontalLine:
459
+ drawFunction = this.drawHorizontalLine;
460
+ break;
461
+
462
+ case DotType.extraRounded:
463
+ drawFunction = this.drawExtraRounded;
464
+ break;
465
+
466
+ case DotType.diamond:
467
+ drawFunction = this.drawDiamond;
468
+ break;
469
+
470
+ case DotType.smallSquare:
471
+ drawFunction = this.drawSmallSquare;
472
+ break;
473
+
474
+ default:
475
+ drawFunction = this.drawSquare;
711
476
  }
712
- drawFunction.call(this, { x, y, size, getNeighbor });
477
+ drawFunction.call(this, args);
713
478
  }
714
- _rotateFigure({ x, y, size, rotation = 0, draw }) {
715
- const cx = x + size / 2;
716
- const cy = y + size / 2;
717
- draw();
718
- this._element?.setAttribute("transform", `rotate(${(180 * rotation) / Math.PI},${cx},${cy})`);
479
+ rotateFigure({x: cx, y: cy, size, rotation = 0, draw}) {
480
+ cx += size / 2, cy += size / 2, draw(), this._element?.setAttribute("transform", `rotate(${numToAttr(180 * rotation / Math.PI)},${cx},${cy})`);
719
481
  }
720
- _basicDot(args) {
721
- const { size, x, y } = args;
722
- this._rotateFigure({
482
+ basicDot(args) {
483
+ let {size, x, y} = args;
484
+ this.rotateFigure({
723
485
  ...args,
724
486
  draw: () => {
725
- this._element = this._document.createElementNS("http://www.w3.org/2000/svg", "circle");
726
- this._element.setAttribute("cx", String(x + size / 2));
727
- this._element.setAttribute("cy", String(y + size / 2));
728
- this._element.setAttribute("r", String(size / 2));
487
+ this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "circle"),
488
+ this._element.setAttribute("cx", numToAttr(x + size / 2)), this._element.setAttribute("cy", numToAttr(y + size / 2)),
489
+ this._element.setAttribute("r", numToAttr(size / 2));
729
490
  }
730
491
  });
731
492
  }
732
- _basicSquare(args) {
733
- const { size, x, y } = args;
734
- this._rotateFigure({
493
+ basicSquare(args) {
494
+ let {size, x, y} = args;
495
+ this.rotateFigure({
735
496
  ...args,
736
497
  draw: () => {
737
- this._element = this._document.createElementNS("http://www.w3.org/2000/svg", "rect");
738
- this._element.setAttribute("x", String(x));
739
- this._element.setAttribute("y", String(y));
740
- this._element.setAttribute("width", String(size));
741
- this._element.setAttribute("height", String(size));
498
+ this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "rect"),
499
+ this._element.setAttribute("x", numToAttr(x)), this._element.setAttribute("y", numToAttr(y)),
500
+ this._element.setAttribute("width", numToAttr(size)), this._element.setAttribute("height", numToAttr(size));
742
501
  }
743
502
  });
744
503
  }
745
- //if rotation === 0 - right side is rounded
746
- _basicSideRounded(args) {
747
- const { size, x, y } = args;
748
- this._rotateFigure({
504
+ basicSideRounded(args) {
505
+ let {size, x, y} = args;
506
+ this.rotateFigure({
749
507
  ...args,
750
508
  draw: () => {
751
- this._element = this._document.createElementNS("http://www.w3.org/2000/svg", "path");
752
- this._element.setAttribute("d", `M ${x} ${y}` + //go to top left position
753
- `v ${size}` + //draw line to left bottom corner
754
- `h ${size / 2}` + //draw line to left bottom corner + half of size right
755
- `a ${size / 2} ${size / 2}, 0, 0, 0, 0 ${-size}` // draw rounded corner
756
- );
509
+ this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "path"),
510
+ this._element.setAttribute("d", svgPath`M ${x} ${y} v ${size} h ${size / 2} a ${size / 2} ${size / 2}, 0, 0, 0, 0 ${-size} z`);
757
511
  }
758
512
  });
759
513
  }
760
- //if rotation === 0 - top right corner is rounded
761
- _basicCornerRounded(args) {
762
- const { size, x, y } = args;
763
- this._rotateFigure({
514
+ basicCornerRounded(args) {
515
+ let {size, x, y} = args;
516
+ this.rotateFigure({
764
517
  ...args,
765
518
  draw: () => {
766
- this._element = this._document.createElementNS("http://www.w3.org/2000/svg", "path");
767
- this._element.setAttribute("d", `M ${x} ${y}` + //go to top left position
768
- `v ${size}` + //draw line to left bottom corner
769
- `h ${size}` + //draw line to right bottom corner
770
- `v ${-size / 2}` + //draw line to right bottom corner + half of size top
771
- `a ${size / 2} ${size / 2}, 0, 0, 0, ${-size / 2} ${-size / 2}` // draw rounded corner
772
- );
519
+ this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "path"),
520
+ this._element.setAttribute("d", svgPath`M ${x} ${y} v ${size} h ${size} v ${-size / 2} a ${size / 2} ${size / 2}, 0, 0, 0, ${-size / 2} ${-size / 2} z`);
773
521
  }
774
522
  });
775
523
  }
776
- //if rotation === 0 - top right corner is rounded
777
- _basicCornerExtraRounded(args) {
778
- const { size, x, y } = args;
779
- this._rotateFigure({
524
+ basicCornerExtraRounded(args) {
525
+ let {size, x, y} = args;
526
+ this.rotateFigure({
780
527
  ...args,
781
528
  draw: () => {
782
- this._element = this._document.createElementNS("http://www.w3.org/2000/svg", "path");
783
- this._element.setAttribute("d", `M ${x} ${y}` + //go to top left position
784
- `v ${size}` + //draw line to left bottom corner
785
- `h ${size}` + //draw line to right bottom corner
786
- `a ${size} ${size}, 0, 0, 0, ${-size} ${-size}` // draw rounded top right corner
787
- );
529
+ this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "path"),
530
+ this._element.setAttribute("d", svgPath`M ${x} ${y} v ${size} h ${size} a ${size} ${size}, 0, 0, 0, ${-size} ${-size} z`);
788
531
  }
789
532
  });
790
533
  }
791
- //if rotation === 0 - left bottom and right top corners are rounded
792
- _basicCornersRounded(args) {
793
- const { size, x, y } = args;
794
- this._rotateFigure({
534
+ basicCornersRounded(args) {
535
+ let {size, x, y} = args;
536
+ this.rotateFigure({
795
537
  ...args,
796
538
  draw: () => {
797
- this._element = this._document.createElementNS("http://www.w3.org/2000/svg", "path");
798
- this._element.setAttribute("d", `M ${x} ${y}` + //go to left top position
799
- `v ${size / 2}` + //draw line to left top corner + half of size bottom
800
- `a ${size / 2} ${size / 2}, 0, 0, 0, ${size / 2} ${size / 2}` + // draw rounded left bottom corner
801
- `h ${size / 2}` + //draw line to right bottom corner
802
- `v ${-size / 2}` + //draw line to right bottom corner + half of size top
803
- `a ${size / 2} ${size / 2}, 0, 0, 0, ${-size / 2} ${-size / 2}` // draw rounded right top corner
804
- );
539
+ this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "path"),
540
+ this._element.setAttribute("d", svgPath`M ${x} ${y} v ${size / 2} a ${size / 2} ${size / 2}, 0, 0, 0, ${size / 2} ${size / 2} h ${size / 2} v ${-size / 2} a ${size / 2} ${size / 2}, 0, 0, 0, ${-size / 2} ${-size / 2} z`);
805
541
  }
806
542
  });
807
543
  }
808
- _drawDot({ x, y, size }) {
809
- this._basicDot({ x, y, size, rotation: 0 });
810
- }
811
- _drawRandomDot({ x, y, size }) {
812
- const randomFactor = Math.random() * (1 - 0.75) + 0.75;
813
- this._basicDot({ x, y, size: size * randomFactor, rotation: 0 });
814
- }
815
- _drawSquare({ x, y, size }) {
816
- this._basicSquare({ x, y, size, rotation: 0 });
817
- }
818
- _drawSmallSquare({ x, y, size }) {
819
- const originalSize = size;
820
- size = originalSize * 0.7;
821
- x = x + originalSize * 0.15;
822
- y = y + originalSize * 0.15;
823
- this._basicSquare({ x, y, size, rotation: 0 });
824
- }
825
- _drawDiamond({ x, y, size }) {
826
- this._basicSquare({ x, y, size, rotation: Math.PI / 4 });
827
- }
828
- _drawRounded({ x, y, size, getNeighbor }) {
829
- const leftNeighbor = getNeighbor ? +getNeighbor(-1, 0) : 0;
830
- const rightNeighbor = getNeighbor ? +getNeighbor(1, 0) : 0;
831
- const topNeighbor = getNeighbor ? +getNeighbor(0, -1) : 0;
832
- const bottomNeighbor = getNeighbor ? +getNeighbor(0, 1) : 0;
833
- const neighborsCount = leftNeighbor + rightNeighbor + topNeighbor + bottomNeighbor;
834
- if (neighborsCount === 0) {
835
- this._basicDot({ x, y, size, rotation: 0 });
836
- return;
837
- }
838
- if (neighborsCount > 2 || (leftNeighbor && rightNeighbor) || (topNeighbor && bottomNeighbor)) {
839
- this._basicSquare({ x, y, size, rotation: 0 });
840
- return;
841
- }
842
- if (neighborsCount === 2) {
843
- let rotation = 0;
844
- if (leftNeighbor && topNeighbor) {
845
- rotation = Math.PI / 2;
846
- }
847
- else if (topNeighbor && rightNeighbor) {
848
- rotation = Math.PI;
849
- }
850
- else if (rightNeighbor && bottomNeighbor) {
851
- rotation = -Math.PI / 2;
852
- }
853
- this._basicCornerRounded({ x, y, size, rotation });
854
- return;
855
- }
856
- if (neighborsCount === 1) {
857
- let rotation = 0;
858
- if (topNeighbor) {
859
- rotation = Math.PI / 2;
860
- }
861
- else if (rightNeighbor) {
862
- rotation = Math.PI;
863
- }
864
- else if (bottomNeighbor) {
865
- rotation = -Math.PI / 2;
866
- }
867
- this._basicSideRounded({ x, y, size, rotation });
868
- return;
869
- }
544
+ drawDot({x, y, size}) {
545
+ this.basicDot({
546
+ x,
547
+ y,
548
+ size,
549
+ rotation: 0
550
+ });
870
551
  }
871
- _drawVerticalLines({ x, y, size, getNeighbor }) {
872
- const leftNeighbor = getNeighbor ? +getNeighbor(-1, 0) : 0;
873
- const rightNeighbor = getNeighbor ? +getNeighbor(1, 0) : 0;
874
- const topNeighbor = getNeighbor ? +getNeighbor(0, -1) : 0;
875
- const bottomNeighbor = getNeighbor ? +getNeighbor(0, 1) : 0;
876
- const neighborsCount = leftNeighbor + rightNeighbor + topNeighbor + bottomNeighbor;
877
- if (neighborsCount === 0 ||
878
- (leftNeighbor && !(topNeighbor || bottomNeighbor)) ||
879
- (rightNeighbor && !(topNeighbor || bottomNeighbor))) {
880
- this._basicDot({ x, y, size, rotation: 0 });
881
- return;
882
- }
883
- if (topNeighbor && bottomNeighbor) {
884
- this._basicSquare({ x, y, size, rotation: 0 });
885
- return;
886
- }
887
- if (topNeighbor && !bottomNeighbor) {
888
- const rotation = Math.PI / 2;
889
- this._basicSideRounded({ x, y, size, rotation });
890
- return;
891
- }
892
- if (bottomNeighbor && !topNeighbor) {
893
- const rotation = -Math.PI / 2;
894
- this._basicSideRounded({ x, y, size, rotation });
895
- return;
896
- }
552
+ drawRandomDot({x, y, size}) {
553
+ this.basicDot({
554
+ x,
555
+ y,
556
+ size: size * (.25 * Math.random() + .75),
557
+ rotation: 0
558
+ });
897
559
  }
898
- _drawHorizontalLines({ x, y, size, getNeighbor }) {
899
- const leftNeighbor = getNeighbor ? +getNeighbor(-1, 0) : 0;
900
- const rightNeighbor = getNeighbor ? +getNeighbor(1, 0) : 0;
901
- const topNeighbor = getNeighbor ? +getNeighbor(0, -1) : 0;
902
- const bottomNeighbor = getNeighbor ? +getNeighbor(0, 1) : 0;
903
- const neighborsCount = leftNeighbor + rightNeighbor + topNeighbor + bottomNeighbor;
904
- if (neighborsCount === 0 ||
905
- (topNeighbor && !(leftNeighbor || rightNeighbor)) ||
906
- (bottomNeighbor && !(leftNeighbor || rightNeighbor))) {
907
- this._basicDot({ x, y, size, rotation: 0 });
908
- return;
909
- }
910
- if (leftNeighbor && rightNeighbor) {
911
- this._basicSquare({ x, y, size, rotation: 0 });
912
- return;
913
- }
914
- if (leftNeighbor && !rightNeighbor) {
915
- const rotation = 0;
916
- this._basicSideRounded({ x, y, size, rotation });
917
- return;
918
- }
919
- if (rightNeighbor && !leftNeighbor) {
920
- const rotation = Math.PI;
921
- this._basicSideRounded({ x, y, size, rotation });
922
- return;
923
- }
560
+ drawSquare({x, y, size}) {
561
+ this.basicSquare({
562
+ x,
563
+ y,
564
+ size,
565
+ rotation: 0
566
+ });
924
567
  }
925
- _drawExtraRounded({ x, y, size, getNeighbor }) {
926
- const leftNeighbor = getNeighbor ? +getNeighbor(-1, 0) : 0;
927
- const rightNeighbor = getNeighbor ? +getNeighbor(1, 0) : 0;
928
- const topNeighbor = getNeighbor ? +getNeighbor(0, -1) : 0;
929
- const bottomNeighbor = getNeighbor ? +getNeighbor(0, 1) : 0;
930
- const neighborsCount = leftNeighbor + rightNeighbor + topNeighbor + bottomNeighbor;
931
- if (neighborsCount === 0) {
932
- this._basicDot({ x, y, size, rotation: 0 });
933
- return;
934
- }
935
- if (neighborsCount > 2 || (leftNeighbor && rightNeighbor) || (topNeighbor && bottomNeighbor)) {
936
- this._basicSquare({ x, y, size, rotation: 0 });
937
- return;
938
- }
939
- if (neighborsCount === 2) {
940
- let rotation = 0;
941
- if (leftNeighbor && topNeighbor) {
942
- rotation = Math.PI / 2;
943
- }
944
- else if (topNeighbor && rightNeighbor) {
945
- rotation = Math.PI;
946
- }
947
- else if (rightNeighbor && bottomNeighbor) {
948
- rotation = -Math.PI / 2;
949
- }
950
- this._basicCornerExtraRounded({ x, y, size, rotation });
951
- return;
952
- }
953
- if (neighborsCount === 1) {
954
- let rotation = 0;
955
- if (topNeighbor) {
956
- rotation = Math.PI / 2;
957
- }
958
- else if (rightNeighbor) {
959
- rotation = Math.PI;
960
- }
961
- else if (bottomNeighbor) {
962
- rotation = -Math.PI / 2;
963
- }
964
- this._basicSideRounded({ x, y, size, rotation });
965
- return;
966
- }
568
+ drawSmallSquare({x, y, size}) {
569
+ this.basicSquare({
570
+ x: x + .15 * size,
571
+ y: y + .15 * size,
572
+ size: .7 * size,
573
+ rotation: 0
574
+ });
967
575
  }
968
- _drawClassy({ x, y, size, getNeighbor }) {
969
- const leftNeighbor = getNeighbor ? +getNeighbor(-1, 0) : 0;
970
- const rightNeighbor = getNeighbor ? +getNeighbor(1, 0) : 0;
971
- const topNeighbor = getNeighbor ? +getNeighbor(0, -1) : 0;
972
- const bottomNeighbor = getNeighbor ? +getNeighbor(0, 1) : 0;
973
- const neighborsCount = leftNeighbor + rightNeighbor + topNeighbor + bottomNeighbor;
974
- if (neighborsCount === 0) {
975
- this._basicCornersRounded({ x, y, size, rotation: Math.PI / 2 });
976
- return;
977
- }
978
- if (!leftNeighbor && !topNeighbor) {
979
- this._basicCornerRounded({ x, y, size, rotation: -Math.PI / 2 });
980
- return;
981
- }
982
- if (!rightNeighbor && !bottomNeighbor) {
983
- this._basicCornerRounded({ x, y, size, rotation: Math.PI / 2 });
984
- return;
985
- }
986
- this._basicSquare({ x, y, size, rotation: 0 });
987
- }
988
- _drawClassyRounded({ x, y, size, getNeighbor }) {
989
- const leftNeighbor = getNeighbor ? +getNeighbor(-1, 0) : 0;
990
- const rightNeighbor = getNeighbor ? +getNeighbor(1, 0) : 0;
991
- const topNeighbor = getNeighbor ? +getNeighbor(0, -1) : 0;
992
- const bottomNeighbor = getNeighbor ? +getNeighbor(0, 1) : 0;
993
- const neighborsCount = leftNeighbor + rightNeighbor + topNeighbor + bottomNeighbor;
994
- if (neighborsCount === 0) {
995
- this._basicCornersRounded({ x, y, size, rotation: Math.PI / 2 });
996
- return;
997
- }
998
- if (!leftNeighbor && !topNeighbor) {
999
- this._basicCornerExtraRounded({ x, y, size, rotation: -Math.PI / 2 });
1000
- return;
1001
- }
1002
- if (!rightNeighbor && !bottomNeighbor) {
1003
- this._basicCornerExtraRounded({ x, y, size, rotation: Math.PI / 2 });
1004
- return;
1005
- }
1006
- this._basicSquare({ x, y, size, rotation: 0 });
576
+ drawDiamond({x, y, size}) {
577
+ this.basicSquare({
578
+ x,
579
+ y,
580
+ size,
581
+ rotation: Math.PI / 4
582
+ });
1007
583
  }
1008
- }
1009
-
1010
- const browserImageTools = {
1011
- toDataURL(url) {
1012
- return new Promise((resolve, reject) => {
1013
- if (typeof url == "string") {
1014
- const xhr = new XMLHttpRequest();
1015
- xhr.onload = function () {
1016
- const reader = new FileReader();
1017
- reader.onloadend = function () {
1018
- resolve(reader.result);
1019
- };
1020
- reader.readAsDataURL(xhr.response);
1021
- };
1022
- xhr.onerror = xhr.onabort = xhr.ontimeout = reject;
1023
- xhr.open("GET", url);
1024
- xhr.responseType = "blob";
1025
- xhr.send();
1026
- }
1027
- else {
1028
- const reader = new FileReader();
1029
- reader.onloadend = function () {
1030
- resolve(reader.result);
1031
- };
1032
- reader.readAsDataURL(url);
1033
- }
584
+ drawRounded({x, y, size, getNeighbor: bottomNeighbor_getNeighbor}) {
585
+ var leftNeighbor_rotation = bottomNeighbor_getNeighbor ? +bottomNeighbor_getNeighbor(-1, 0) : 0;
586
+ let rightNeighbor = bottomNeighbor_getNeighbor ? +bottomNeighbor_getNeighbor(1, 0) : 0, topNeighbor = bottomNeighbor_getNeighbor ? +bottomNeighbor_getNeighbor(0, -1) : 0;
587
+ var neighborsCount_rotation = leftNeighbor_rotation + rightNeighbor + topNeighbor + (bottomNeighbor_getNeighbor = bottomNeighbor_getNeighbor ? +bottomNeighbor_getNeighbor(0, 1) : 0);
588
+ 0 === neighborsCount_rotation ? this.basicDot({
589
+ x,
590
+ y,
591
+ size,
592
+ rotation: 0
593
+ }) : 2 < neighborsCount_rotation || leftNeighbor_rotation && rightNeighbor || topNeighbor && bottomNeighbor_getNeighbor ? this.basicSquare({
594
+ x,
595
+ y,
596
+ size,
597
+ rotation: 0
598
+ }) : 2 === neighborsCount_rotation ? (neighborsCount_rotation = 0, leftNeighbor_rotation && topNeighbor ? neighborsCount_rotation = Math.PI / 2 : topNeighbor && rightNeighbor ? neighborsCount_rotation = Math.PI : rightNeighbor && bottomNeighbor_getNeighbor && (neighborsCount_rotation = -Math.PI / 2),
599
+ this.basicCornerRounded({
600
+ x,
601
+ y,
602
+ size,
603
+ rotation: neighborsCount_rotation
604
+ })) : 1 === neighborsCount_rotation && (leftNeighbor_rotation = 0, topNeighbor ? leftNeighbor_rotation = Math.PI / 2 : rightNeighbor ? leftNeighbor_rotation = Math.PI : bottomNeighbor_getNeighbor && (leftNeighbor_rotation = -Math.PI / 2),
605
+ this.basicSideRounded({
606
+ x,
607
+ y,
608
+ size,
609
+ rotation: leftNeighbor_rotation
610
+ }));
611
+ }
612
+ drawVerticalLine({x, y, size, getNeighbor: bottomNeighbor}) {
613
+ let leftNeighbor = bottomNeighbor ? +bottomNeighbor(-1, 0) : 0, rightNeighbor = bottomNeighbor ? +bottomNeighbor(1, 0) : 0, topNeighbor = bottomNeighbor ? +bottomNeighbor(0, -1) : 0;
614
+ 0 === leftNeighbor + rightNeighbor + topNeighbor + (bottomNeighbor = bottomNeighbor ? +bottomNeighbor(0, 1) : 0) || leftNeighbor && !topNeighbor && !bottomNeighbor || rightNeighbor && !topNeighbor && !bottomNeighbor ? this.basicDot({
615
+ x,
616
+ y,
617
+ size,
618
+ rotation: 0
619
+ }) : topNeighbor && bottomNeighbor ? this.basicSquare({
620
+ x,
621
+ y,
622
+ size,
623
+ rotation: 0
624
+ }) : topNeighbor && !bottomNeighbor ? this.basicSideRounded({
625
+ x,
626
+ y,
627
+ size,
628
+ rotation: Math.PI / 2
629
+ }) : bottomNeighbor && !topNeighbor && this.basicSideRounded({
630
+ x,
631
+ y,
632
+ size,
633
+ rotation: -Math.PI / 2
1034
634
  });
1035
- },
1036
- getSize(options) {
1037
- return new Promise((resolve, reject) => {
1038
- if (!options.image) {
1039
- return reject("Image is not defined");
1040
- }
1041
- const image = new Image();
1042
- if (typeof options.imageOptions?.crossOrigin === "string") {
1043
- image.crossOrigin = options.imageOptions.crossOrigin;
1044
- }
1045
- image.onload = () => {
1046
- resolve({ width: image.width, height: image.height });
1047
- };
1048
- image.onerror = image.onabort = reject;
1049
- if (typeof options.image == "string")
1050
- image.src = options.image;
1051
- else
1052
- browserImageTools
1053
- .toDataURL(options.image)
1054
- .then((url) => (image.src = url))
1055
- .catch(reject);
635
+ }
636
+ drawHorizontalLine({x, y, size, getNeighbor: bottomNeighbor}) {
637
+ let leftNeighbor = bottomNeighbor ? +bottomNeighbor(-1, 0) : 0, rightNeighbor = bottomNeighbor ? +bottomNeighbor(1, 0) : 0, topNeighbor = bottomNeighbor ? +bottomNeighbor(0, -1) : 0;
638
+ 0 === leftNeighbor + rightNeighbor + topNeighbor + (bottomNeighbor = bottomNeighbor ? +bottomNeighbor(0, 1) : 0) || topNeighbor && !leftNeighbor && !rightNeighbor || bottomNeighbor && !leftNeighbor && !rightNeighbor ? this.basicDot({
639
+ x,
640
+ y,
641
+ size,
642
+ rotation: 0
643
+ }) : leftNeighbor && rightNeighbor ? this.basicSquare({
644
+ x,
645
+ y,
646
+ size,
647
+ rotation: 0
648
+ }) : leftNeighbor && !rightNeighbor ? this.basicSideRounded({
649
+ x,
650
+ y,
651
+ size,
652
+ rotation: 0
653
+ }) : rightNeighbor && !leftNeighbor && this.basicSideRounded({
654
+ x,
655
+ y,
656
+ size,
657
+ rotation: Math.PI
1056
658
  });
1057
659
  }
1058
- };
1059
-
1060
- function calculateImageSize({ originalHeight, originalWidth, maxHiddenDots, maxHiddenAxisDots, dotSize, margin }) {
1061
- const hideDots = { x: 0, y: 0 };
1062
- const imageSize = { x: 0, y: 0 };
1063
- if (originalHeight <= 0 ||
1064
- originalWidth <= 0 ||
1065
- maxHiddenDots <= 0 ||
1066
- dotSize <= 0 ||
1067
- 4 * margin ** 2 > maxHiddenDots) {
1068
- return {
1069
- height: 0,
1070
- width: 0,
1071
- hideYDots: 0,
1072
- hideXDots: 0
1073
- };
660
+ drawExtraRounded({x, y, size, getNeighbor: bottomNeighbor}) {
661
+ var leftNeighbor = bottomNeighbor ? +bottomNeighbor(-1, 0) : 0;
662
+ let rightNeighbor = bottomNeighbor ? +bottomNeighbor(1, 0) : 0, topNeighbor = bottomNeighbor ? +bottomNeighbor(0, -1) : 0;
663
+ var neighborsCount = leftNeighbor + rightNeighbor + topNeighbor + (bottomNeighbor = bottomNeighbor ? +bottomNeighbor(0, 1) : 0);
664
+ 0 === neighborsCount ? this.basicDot({
665
+ x,
666
+ y,
667
+ size,
668
+ rotation: 0
669
+ }) : 2 < neighborsCount || leftNeighbor && rightNeighbor || topNeighbor && bottomNeighbor ? this.basicSquare({
670
+ x,
671
+ y,
672
+ size,
673
+ rotation: 0
674
+ }) : 2 === neighborsCount ? (neighborsCount = 0, leftNeighbor && topNeighbor ? neighborsCount = Math.PI / 2 : topNeighbor && rightNeighbor ? neighborsCount = Math.PI : rightNeighbor && bottomNeighbor && (neighborsCount = -Math.PI / 2),
675
+ this.basicCornerExtraRounded({
676
+ x,
677
+ y,
678
+ size,
679
+ rotation: neighborsCount
680
+ })) : 1 === neighborsCount && (leftNeighbor = 0, topNeighbor ? leftNeighbor = Math.PI / 2 : rightNeighbor ? leftNeighbor = Math.PI : bottomNeighbor && (leftNeighbor = -Math.PI / 2),
681
+ this.basicSideRounded({
682
+ x,
683
+ y,
684
+ size,
685
+ rotation: leftNeighbor
686
+ }));
687
+ }
688
+ drawClassy({x, y, size, getNeighbor: bottomNeighbor}) {
689
+ let leftNeighbor = bottomNeighbor ? +bottomNeighbor(-1, 0) : 0, rightNeighbor = bottomNeighbor ? +bottomNeighbor(1, 0) : 0, topNeighbor = bottomNeighbor ? +bottomNeighbor(0, -1) : 0;
690
+ 0 === leftNeighbor + rightNeighbor + topNeighbor + (bottomNeighbor = bottomNeighbor ? +bottomNeighbor(0, 1) : 0) ? this.basicCornersRounded({
691
+ x,
692
+ y,
693
+ size,
694
+ rotation: Math.PI / 2
695
+ }) : leftNeighbor || topNeighbor ? rightNeighbor || bottomNeighbor ? this.basicSquare({
696
+ x,
697
+ y,
698
+ size,
699
+ rotation: 0
700
+ }) : this.basicCornerRounded({
701
+ x,
702
+ y,
703
+ size,
704
+ rotation: Math.PI / 2
705
+ }) : this.basicCornerRounded({
706
+ x,
707
+ y,
708
+ size,
709
+ rotation: -Math.PI / 2
710
+ });
711
+ }
712
+ drawClassyRounded({x, y, size, getNeighbor: bottomNeighbor}) {
713
+ let leftNeighbor = bottomNeighbor ? +bottomNeighbor(-1, 0) : 0, rightNeighbor = bottomNeighbor ? +bottomNeighbor(1, 0) : 0, topNeighbor = bottomNeighbor ? +bottomNeighbor(0, -1) : 0;
714
+ 0 === leftNeighbor + rightNeighbor + topNeighbor + (bottomNeighbor = bottomNeighbor ? +bottomNeighbor(0, 1) : 0) ? this.basicCornersRounded({
715
+ x,
716
+ y,
717
+ size,
718
+ rotation: Math.PI / 2
719
+ }) : leftNeighbor || topNeighbor ? rightNeighbor || bottomNeighbor ? this.basicSquare({
720
+ x,
721
+ y,
722
+ size,
723
+ rotation: 0
724
+ }) : this.basicCornerExtraRounded({
725
+ x,
726
+ y,
727
+ size,
728
+ rotation: Math.PI / 2
729
+ }) : this.basicCornerExtraRounded({
730
+ x,
731
+ y,
732
+ size,
733
+ rotation: -Math.PI / 2
734
+ });
1074
735
  }
1075
- //If set, ensure maxHiddenAxisDots is odd and at least 1
1076
- if (maxHiddenAxisDots && maxHiddenAxisDots % 2 == 0)
1077
- maxHiddenAxisDots = Math.max(1, maxHiddenAxisDots - 1);
1078
- //Determine the bigger and smaller image dimension
1079
- const dimMax = Math.max(originalWidth, originalHeight);
1080
- const dimMin = Math.min(originalWidth, originalHeight);
1081
- //Find max image size along the bigger dimension
1082
- let lower = 0, upper = (maxHiddenAxisDots || maxHiddenDots) - 2 * margin;
1083
- do {
1084
- const size = lower + (upper - lower) / 2;
1085
- let dotsMax = Math.max(1, Math.ceil(size + 2 * margin));
1086
- if (dotsMax % 2 == 0)
1087
- dotsMax++;
1088
- let dotsMin = Math.max(1, Math.ceil((size * dimMin) / dimMax + 2 * margin));
1089
- if (dotsMin % 2 == 0)
1090
- dotsMin++;
1091
- if (dotsMax * dotsMin > maxHiddenDots)
1092
- upper = size;
1093
- else
1094
- lower = size;
1095
- } while (Math.abs(lower - upper) > 0.001);
1096
- //Calculate how many dots the given size corresponds to
1097
- const size = lower;
1098
- let hideMax = Math.max(1, Math.ceil(size + 2 * margin));
1099
- if (hideMax % 2 == 0)
1100
- hideMax++;
1101
- let hideMin = Math.max(1, Math.ceil((size * dimMin) / dimMax + 2 * margin));
1102
- if (hideMin % 2 == 0)
1103
- hideMin++;
1104
- //Set hidden dots along bigger and smaller dimension to the right axis
1105
- if (originalWidth > originalHeight) {
1106
- hideDots.x = hideMax;
1107
- hideDots.y = hideMin;
1108
- }
1109
- else {
1110
- hideDots.x = hideMin;
1111
- hideDots.y = hideMax;
1112
- }
1113
- //Fit image to the hidden dots
1114
- const maxW = (hideDots.x - 2 * margin) * dotSize;
1115
- const maxH = (hideDots.y - 2 * margin) * dotSize;
1116
- imageSize.x = maxW;
1117
- imageSize.y = (maxW * originalHeight) / originalWidth;
1118
- if (imageSize.y > maxH) {
1119
- imageSize.y = maxH;
1120
- imageSize.x = (maxH * originalWidth) / originalHeight;
1121
- }
1122
- return {
1123
- height: Math.round(imageSize.y + 2 * margin * dotSize),
1124
- width: Math.round(imageSize.x + 2 * margin * dotSize),
1125
- hideYDots: hideDots.y,
1126
- hideXDots: hideDots.x
1127
- };
1128
736
  }
1129
737
 
1130
- const squareMask = [
1131
- [1, 1, 1, 1, 1, 1, 1],
1132
- [1, 0, 0, 0, 0, 0, 1],
1133
- [1, 0, 0, 0, 0, 0, 1],
1134
- [1, 0, 0, 0, 0, 0, 1],
1135
- [1, 0, 0, 0, 0, 0, 1],
1136
- [1, 0, 0, 0, 0, 0, 1],
1137
- [1, 1, 1, 1, 1, 1, 1]
1138
- ];
1139
- const dotMask = [
1140
- [0, 0, 0, 0, 0, 0, 0],
1141
- [0, 0, 0, 0, 0, 0, 0],
1142
- [0, 0, 1, 1, 1, 0, 0],
1143
- [0, 0, 1, 1, 1, 0, 0],
1144
- [0, 0, 1, 1, 1, 0, 0],
1145
- [0, 0, 0, 0, 0, 0, 0],
1146
- [0, 0, 0, 0, 0, 0, 0]
1147
- ];
1148
- const alignmentCount = [
1149
- [35, 49],
1150
- [28, 36],
1151
- [21, 25],
1152
- [14, 16],
1153
- [7, 9],
1154
- [2, 4],
1155
- [1, 1]
1156
- ];
738
+ let browserImageTools = {
739
+ toDataURL: url => new Promise(((resolve, reject) => {
740
+ if ("string" == typeof url) {
741
+ const xhr = new XMLHttpRequest;
742
+ xhr.onload = function() {
743
+ const reader = new FileReader;
744
+ reader.onloadend = function() {
745
+ resolve(reader.result);
746
+ }, reader.readAsDataURL(xhr.response);
747
+ }, xhr.onerror = xhr.onabort = xhr.ontimeout = reject, xhr.open("GET", url), xhr.responseType = "blob",
748
+ xhr.send();
749
+ } else {
750
+ const reader = new FileReader;
751
+ reader.onloadend = function() {
752
+ resolve(reader.result);
753
+ }, reader.readAsDataURL(url);
754
+ }
755
+ })),
756
+ getSize: (src, crossOrigin) => new Promise(((resolve, reject) => {
757
+ const image = new Image;
758
+ "string" === crossOrigin && (image.crossOrigin = crossOrigin), image.onload = () => {
759
+ resolve({
760
+ width: image.width,
761
+ height: image.height
762
+ });
763
+ }, image.onerror = image.onabort = reject, "string" == typeof src ? image.src = src : browserImageTools.toDataURL(src).then((url => image.src = url)).catch(reject);
764
+ }))
765
+ };
766
+
767
+ let squareMask = [ [ 1, 1, 1, 1, 1, 1, 1 ], [ 1, 0, 0, 0, 0, 0, 1 ], [ 1, 0, 0, 0, 0, 0, 1 ], [ 1, 0, 0, 0, 0, 0, 1 ], [ 1, 0, 0, 0, 0, 0, 1 ], [ 1, 0, 0, 0, 0, 0, 1 ], [ 1, 1, 1, 1, 1, 1, 1 ] ], dotMask = [ [ 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 1, 1, 1, 0, 0 ], [ 0, 0, 1, 1, 1, 0, 0 ], [ 0, 0, 1, 1, 1, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0 ], [ 0, 0, 0, 0, 0, 0, 0 ] ], alignmentCount = [ [ 35, 49 ], [ 28, 36 ], [ 21, 25 ], [ 14, 16 ], [ 7, 9 ], [ 2, 4 ], [ 1, 1 ] ];
768
+
1157
769
  class QRSVG {
1158
- //TODO don't pass all options to this class
770
+ get element() {
771
+ return this._element;
772
+ }
1159
773
  constructor(options) {
1160
- this._document = options.document;
1161
- this._element = this._document.createElementNS("http://www.w3.org/2000/svg", "svg");
1162
- this._element.setAttribute("width", String(options.width));
1163
- this._element.setAttribute("height", String(options.height));
1164
- this._element.setAttribute("viewBox", `0 0 ${options.width} ${options.height}`);
1165
- this._defs = this._document.createElementNS("http://www.w3.org/2000/svg", "defs");
1166
- this._element.appendChild(this._defs);
1167
- this._imageTools = options.imageTools || browserImageTools;
1168
- this._options = options;
774
+ this.options = options, this.document = options.document, this._element = this.document.createElementNS("http://www.w3.org/2000/svg", "svg");
775
+ let width = numToAttr(options.width), height = numToAttr(options.height);
776
+ this._element.setAttribute("width", width), this._element.setAttribute("height", height),
777
+ this._element.setAttribute("viewBox", `0 0 ${width} ${height}`), this.defs = this.document.createElementNS("http://www.w3.org/2000/svg", "defs"),
778
+ this._element.appendChild(this.defs), this.imageTools = options.imageTools || browserImageTools;
1169
779
  }
1170
780
  get width() {
1171
- return this._options.width;
781
+ return this.options.width;
1172
782
  }
1173
783
  get height() {
1174
- return this._options.height;
1175
- }
1176
- getElement() {
1177
- return this._element;
784
+ return this.options.height;
1178
785
  }
1179
- async drawQR(qr) {
1180
- const count = qr.getModuleCount();
1181
- const typeNumber = parseInt(((count - 17) / 4).toFixed(0), 10);
1182
- const dotSize = this._options.dotsOptions.size;
1183
- let drawImageSize = {
786
+ async drawQR(qr_size) {
787
+ let count = qr_size.getModuleCount(), typeNumber = parseInt(((count - 17) / 4).toFixed(0), 10), dotSize = this.options.dotsOptions.size, drawImageSize = {
1184
788
  hideXDots: 0,
1185
789
  hideYDots: 0,
1186
790
  width: 0,
1187
791
  height: 0
1188
792
  };
1189
- this._qr = qr;
1190
- if (this._options.image) {
1191
- //We need it to get image size
1192
- const size = await this._imageTools.getSize(this._options);
1193
- const { imageOptions, qrOptions } = this._options;
1194
- const coverLevel = imageOptions.imageSize * ErrorCorrectionPercents[qrOptions.errorCorrectionLevel];
1195
- const alignment = alignmentCount.find((v) => v[0] <= typeNumber) || [0, 0];
1196
- const maxHiddenDots = Math.floor(coverLevel * (count * count - 3 * 8 * 8 - 2 * (count - 16) - alignment[1] * 25));
1197
- drawImageSize = calculateImageSize({
1198
- originalWidth: size.width,
1199
- originalHeight: size.height,
1200
- maxHiddenDots,
793
+ if (this.qr = qr_size, this.options.image) {
794
+ qr_size = await this.imageTools.getSize(this.options.image, this.options.imageOptions.crossOrigin);
795
+ let {imageOptions, errorCorrectionPercent} = this.options, coverLevel = imageOptions.imageSize * errorCorrectionPercent, alignment = alignmentCount.find((v => v[0] <= typeNumber)) || [ 0, 0 ];
796
+ drawImageSize = function({originalHeight, originalWidth, maxHiddenDots: JSCompiler_object_inline_x_18_hideMax_maxHiddenDots, maxHiddenAxisDots: JSCompiler_object_inline_y_19_maxHiddenAxisDots_maxW_upper, dotSize, margin}) {
797
+ if (0 >= originalHeight || 0 >= originalWidth || 0 >= JSCompiler_object_inline_x_18_hideMax_maxHiddenDots || 0 >= dotSize || 4 * margin ** 2 > JSCompiler_object_inline_x_18_hideMax_maxHiddenDots) return {
798
+ height: 0,
799
+ width: 0,
800
+ hideYDots: 0,
801
+ hideXDots: 0
802
+ };
803
+ JSCompiler_object_inline_y_19_maxHiddenAxisDots_maxW_upper && 0 == JSCompiler_object_inline_y_19_maxHiddenAxisDots_maxW_upper % 2 && (JSCompiler_object_inline_y_19_maxHiddenAxisDots_maxW_upper = Math.max(1, JSCompiler_object_inline_y_19_maxHiddenAxisDots_maxW_upper - 1));
804
+ var JSCompiler_object_inline_x_16_dimMax = Math.max(originalWidth, originalHeight), JSCompiler_object_inline_y_17_dimMin_hideMin = Math.min(originalWidth, originalHeight), lower_maxH_size = 0;
805
+ JSCompiler_object_inline_y_19_maxHiddenAxisDots_maxW_upper = (JSCompiler_object_inline_y_19_maxHiddenAxisDots_maxW_upper || JSCompiler_object_inline_x_18_hideMax_maxHiddenDots) - 2 * margin;
806
+ do {
807
+ let size = lower_maxH_size + (JSCompiler_object_inline_y_19_maxHiddenAxisDots_maxW_upper - lower_maxH_size) / 2, dotsMax = Math.max(1, Math.ceil(size + 2 * margin));
808
+ 0 == dotsMax % 2 && dotsMax++;
809
+ let dotsMin = Math.max(1, Math.ceil(size * JSCompiler_object_inline_y_17_dimMin_hideMin / JSCompiler_object_inline_x_16_dimMax + 2 * margin));
810
+ 0 == dotsMin % 2 && dotsMin++, dotsMax * dotsMin > JSCompiler_object_inline_x_18_hideMax_maxHiddenDots ? JSCompiler_object_inline_y_19_maxHiddenAxisDots_maxW_upper = size : lower_maxH_size = size;
811
+ } while (.001 < Math.abs(lower_maxH_size - JSCompiler_object_inline_y_19_maxHiddenAxisDots_maxW_upper));
812
+ return 0 == (JSCompiler_object_inline_x_18_hideMax_maxHiddenDots = Math.max(1, Math.ceil(lower_maxH_size + 2 * margin))) % 2 && JSCompiler_object_inline_x_18_hideMax_maxHiddenDots++,
813
+ 0 == (JSCompiler_object_inline_y_17_dimMin_hideMin = Math.max(1, Math.ceil(lower_maxH_size * JSCompiler_object_inline_y_17_dimMin_hideMin / JSCompiler_object_inline_x_16_dimMax + 2 * margin))) % 2 && JSCompiler_object_inline_y_17_dimMin_hideMin++,
814
+ originalWidth > originalHeight ? JSCompiler_object_inline_x_16_dimMax = JSCompiler_object_inline_x_18_hideMax_maxHiddenDots : (JSCompiler_object_inline_x_16_dimMax = JSCompiler_object_inline_y_17_dimMin_hideMin,
815
+ JSCompiler_object_inline_y_17_dimMin_hideMin = JSCompiler_object_inline_x_18_hideMax_maxHiddenDots),
816
+ JSCompiler_object_inline_x_18_hideMax_maxHiddenDots = JSCompiler_object_inline_y_19_maxHiddenAxisDots_maxW_upper = (JSCompiler_object_inline_x_16_dimMax - 2 * margin) * dotSize,
817
+ (JSCompiler_object_inline_y_19_maxHiddenAxisDots_maxW_upper = JSCompiler_object_inline_y_19_maxHiddenAxisDots_maxW_upper * originalHeight / originalWidth) > (lower_maxH_size = (JSCompiler_object_inline_y_17_dimMin_hideMin - 2 * margin) * dotSize) && (JSCompiler_object_inline_y_19_maxHiddenAxisDots_maxW_upper = lower_maxH_size,
818
+ JSCompiler_object_inline_x_18_hideMax_maxHiddenDots = lower_maxH_size * originalWidth / originalHeight),
819
+ {
820
+ height: Math.round(JSCompiler_object_inline_y_19_maxHiddenAxisDots_maxW_upper + 2 * margin * dotSize),
821
+ width: Math.round(JSCompiler_object_inline_x_18_hideMax_maxHiddenDots + 2 * margin * dotSize),
822
+ hideYDots: JSCompiler_object_inline_y_17_dimMin_hideMin,
823
+ hideXDots: JSCompiler_object_inline_x_16_dimMax
824
+ };
825
+ }({
826
+ originalWidth: qr_size.width,
827
+ originalHeight: qr_size.height,
828
+ maxHiddenDots: Math.floor(coverLevel * (count * count - 192 - 2 * (count - 16) - 25 * alignment[1])),
1201
829
  maxHiddenAxisDots: count - 14,
1202
830
  dotSize,
1203
831
  margin: imageOptions.margin
1204
832
  });
1205
833
  }
1206
- this.drawBackground();
1207
- this.drawDots((i, j) => {
1208
- if (this._options.imageOptions.hideBackgroundDots) {
1209
- if (i >= (count - drawImageSize.hideXDots) / 2 &&
1210
- i < (count + drawImageSize.hideXDots) / 2 &&
1211
- j >= (count - drawImageSize.hideYDots) / 2 &&
1212
- j < (count + drawImageSize.hideYDots) / 2) {
1213
- return false;
1214
- }
1215
- }
1216
- if (squareMask[i]?.[j] || squareMask[i - count + 7]?.[j] || squareMask[i]?.[j - count + 7]) {
1217
- return false;
1218
- }
1219
- if (dotMask[i]?.[j] || dotMask[i - count + 7]?.[j] || dotMask[i]?.[j - count + 7]) {
1220
- return false;
1221
- }
1222
- return true;
834
+ this.drawBackground(), this.drawDots(((i, j) => !(this.options.imageOptions.hideBackgroundDots && i >= (count - drawImageSize.hideXDots) / 2 && i < (count + drawImageSize.hideXDots) / 2 && j >= (count - drawImageSize.hideYDots) / 2 && j < (count + drawImageSize.hideYDots) / 2 || squareMask[i]?.[j] || squareMask[i - count + 7]?.[j] || squareMask[i]?.[j - count + 7] || dotMask[i]?.[j] || dotMask[i - count + 7]?.[j] || dotMask[i]?.[j - count + 7]))),
835
+ this.drawCorners(), this.options.image && 0 < drawImageSize.width && 0 < drawImageSize.height && await this.drawImage({
836
+ width: drawImageSize.width,
837
+ height: drawImageSize.height,
838
+ count,
839
+ dotSize
1223
840
  });
1224
- this.drawCorners();
1225
- if (this._options.image && drawImageSize.width > 0 && drawImageSize.height > 0) {
1226
- await this.drawImage({ width: drawImageSize.width, height: drawImageSize.height, count, dotSize });
1227
- }
1228
841
  }
1229
842
  drawBackground() {
1230
- const element = this._element;
1231
- const options = this._options;
1232
- if (element && options.backgroundOptions) {
1233
- const gradientOptions = options.backgroundOptions.gradient;
1234
- const color = options.backgroundOptions.color;
1235
- this._createColor({
1236
- options: gradientOptions,
1237
- color: color,
843
+ let options = this.options;
844
+ if (this._element && options.backgroundOptions) {
845
+ this.createColor({
846
+ options: options.backgroundOptions.gradient,
847
+ color: options.backgroundOptions.color,
1238
848
  additionalRotation: 0,
1239
849
  x: 0,
1240
850
  y: 0,
@@ -1242,102 +852,48 @@ class QRSVG {
1242
852
  width: options.width,
1243
853
  name: "background-color"
1244
854
  });
1245
- const size = Math.min(options.width, options.height);
1246
- const element = this._document.createElementNS("http://www.w3.org/2000/svg", "rect");
1247
- [this._backgroundMask, this._backgroundMaskGroup] = this._createMask("mask-background-color");
1248
- this._defs.appendChild(this._backgroundMask);
1249
- element.setAttribute("x", String((options.width - size) / 2));
1250
- element.setAttribute("y", String((options.height - size) / 2));
1251
- element.setAttribute("width", String(size));
1252
- element.setAttribute("height", String(size));
1253
- element.setAttribute("rx", String((size / 2) * (options.backgroundOptions.round || 0)));
1254
- this._backgroundMaskGroup.appendChild(element);
855
+ let size = Math.min(options.width, options.height), element = this.document.createElementNS("http://www.w3.org/2000/svg", "rect");
856
+ [this.backgroundMask, this.backgroundMaskGroup] = this.createMask("mask-background-color"),
857
+ this.defs.appendChild(this.backgroundMask), element.setAttribute("x", numToAttr((options.width - size) / 2)),
858
+ element.setAttribute("y", numToAttr((options.height - size) / 2)), element.setAttribute("width", numToAttr(size)),
859
+ element.setAttribute("height", numToAttr(size)), element.setAttribute("rx", numToAttr(size / 2 * (options.backgroundOptions.round || 0))),
860
+ this.backgroundMaskGroup.appendChild(element);
1255
861
  }
1256
862
  }
1257
863
  drawDots(filter) {
1258
- if (!this._qr) {
1259
- throw "QR code is not defined";
1260
- }
1261
- const options = this._options;
1262
- const count = this._qr.getModuleCount();
1263
- if (count > options.width || count > options.height) {
1264
- throw "The canvas is too small.";
1265
- }
1266
- const minSize = Math.min(options.width, options.height);
1267
- const dotSize = this._options.dotsOptions.size;
1268
- const xBeginning = Math.floor((options.width - count * dotSize) / 2);
1269
- const yBeginning = Math.floor((options.height - count * dotSize) / 2);
1270
- const dot = new QRDot({ svg: this._element, type: options.dotsOptions.type, document: this._document });
1271
- [this._dotsMask, this._dotsMaskGroup] = this._createMask("mask-dot-color");
1272
- this._defs.appendChild(this._dotsMask);
1273
- for (let i = 0; i < count; i++) {
1274
- for (let j = 0; j < count; j++) {
1275
- if (filter && !filter(i, j)) {
1276
- continue;
1277
- }
1278
- if (!this._qr?.isDark(j, i)) {
1279
- continue;
1280
- }
1281
- dot.draw(xBeginning + i * dotSize, yBeginning + j * dotSize, dotSize, (xOffset, yOffset) => {
1282
- if (i + xOffset < 0 || j + yOffset < 0 || i + xOffset >= count || j + yOffset >= count)
1283
- return false;
1284
- if (filter && !filter(i + xOffset, j + yOffset))
1285
- return false;
1286
- return !!this._qr && this._qr.isDark(j + yOffset, i + xOffset);
1287
- });
1288
- if (dot._element && this._dotsMask) {
1289
- this._dotsMaskGroup.appendChild(dot._element);
1290
- }
1291
- }
1292
- }
1293
- let colorX = xBeginning;
1294
- let colorY = yBeginning;
1295
- let colorCount = count;
864
+ if (!this.qr) throw "QR code is not defined";
865
+ let options = this.options, count = this.qr.getModuleCount();
866
+ if (count > options.width || count > options.height) throw "The canvas is too small.";
867
+ var additionalDots_minSize = Math.min(options.width, options.height);
868
+ let dotSize = this.options.dotsOptions.size;
869
+ var xBeginning_xFakeBeginning = Math.floor((options.width - count * dotSize) / 2), yBeginning_yFakeBeginning = Math.floor((options.height - count * dotSize) / 2);
870
+ let dot = new QRDot(options.dotsOptions.type, this.document);
871
+ [this.dotsMask, this.dotsMaskGroup] = this.createMask("mask-dot-color"), this.defs.appendChild(this.dotsMask);
872
+ for (let i = 0; i < count; i++) for (let j = 0; j < count; j++) filter && !filter(i, j) || !this.qr?.isDark(j, i) || (dot.draw({
873
+ x: xBeginning_xFakeBeginning + i * dotSize,
874
+ y: yBeginning_yFakeBeginning + j * dotSize,
875
+ size: dotSize,
876
+ getNeighbor: (xOffset, yOffset) => !(0 > i + xOffset || 0 > j + yOffset || i + xOffset >= count || j + yOffset >= count || filter && !filter(i + xOffset, j + yOffset)) && (!!this.qr && this.qr.isDark(j + yOffset, i + xOffset))
877
+ }), dot.element && this.dotsMask && this.dotsMaskGroup.appendChild(dot.element));
878
+ let colorX = xBeginning_xFakeBeginning, colorY = yBeginning_yFakeBeginning, colorCount = count;
1296
879
  if (options.shape === ShapeType.circle) {
1297
- const margin = (this._options.backgroundOptions && this._options.backgroundOptions.margin) || 0;
1298
- const additionalDots = Math.floor((minSize / dotSize - count - 2 * margin) / 2);
1299
- const fakeCount = count + additionalDots * 2;
1300
- const xFakeBeginning = xBeginning - additionalDots * dotSize;
1301
- const yFakeBeginning = yBeginning - additionalDots * dotSize;
1302
- colorX = xFakeBeginning;
1303
- colorY = yFakeBeginning;
1304
- colorCount = count + additionalDots * 2;
1305
- const fakeMatrix = [];
1306
- const center = Math.floor(fakeCount / 2);
880
+ additionalDots_minSize = Math.floor((additionalDots_minSize / dotSize - count - 2 * (this.options.backgroundOptions && this.options.backgroundOptions.margin || 0)) / 2);
881
+ let fakeCount = count + 2 * additionalDots_minSize;
882
+ colorX = xBeginning_xFakeBeginning -= additionalDots_minSize * dotSize, colorY = yBeginning_yFakeBeginning -= additionalDots_minSize * dotSize,
883
+ colorCount = count + 2 * additionalDots_minSize;
884
+ let fakeMatrix = [], center = Math.floor(fakeCount / 2);
1307
885
  for (let i = 0; i < fakeCount; i++) {
1308
886
  fakeMatrix[i] = [];
1309
- for (let j = 0; j < fakeCount; j++) {
1310
- if (i >= additionalDots - 1 &&
1311
- i <= fakeCount - additionalDots &&
1312
- j >= additionalDots - 1 &&
1313
- j <= fakeCount - additionalDots) {
1314
- fakeMatrix[i][j] = 0;
1315
- continue;
1316
- }
1317
- if (Math.sqrt((i - center) * (i - center) + (j - center) * (j - center)) > center) {
1318
- fakeMatrix[i][j] = 0;
1319
- continue;
1320
- }
1321
- //Get random dots from QR code to show it outside of QR code
1322
- fakeMatrix[i][j] = this._qr.isDark(j - 2 * additionalDots < 0 ? j : j >= count ? j - 2 * additionalDots : j - additionalDots, i - 2 * additionalDots < 0 ? i : i >= count ? i - 2 * additionalDots : i - additionalDots)
1323
- ? 1
1324
- : 0;
1325
- }
1326
- }
1327
- for (let i = 0; i < fakeCount; i++) {
1328
- for (let j = 0; j < fakeCount; j++) {
1329
- if (!fakeMatrix[i][j])
1330
- continue;
1331
- dot.draw(xFakeBeginning + i * dotSize, yFakeBeginning + j * dotSize, dotSize, (xOffset, yOffset) => {
1332
- return !!fakeMatrix[i + xOffset]?.[j + yOffset];
1333
- });
1334
- if (dot._element && this._dotsMask) {
1335
- this._dotsMaskGroup.appendChild(dot._element);
1336
- }
1337
- }
887
+ for (let j = 0; j < fakeCount; j++) fakeMatrix[i][j] = i >= additionalDots_minSize - 1 && i <= fakeCount - additionalDots_minSize && j >= additionalDots_minSize - 1 && j <= fakeCount - additionalDots_minSize || Math.sqrt((i - center) * (i - center) + (j - center) * (j - center)) > center ? 0 : this.qr.isDark(0 > j - 2 * additionalDots_minSize ? j : j >= count ? j - 2 * additionalDots_minSize : j - additionalDots_minSize, 0 > i - 2 * additionalDots_minSize ? i : i >= count ? i - 2 * additionalDots_minSize : i - additionalDots_minSize) ? 1 : 0;
1338
888
  }
889
+ for (let i = 0; i < fakeCount; i++) for (let j = 0; j < fakeCount; j++) fakeMatrix[i][j] && (dot.draw({
890
+ x: xBeginning_xFakeBeginning + i * dotSize,
891
+ y: yBeginning_yFakeBeginning + j * dotSize,
892
+ size: dotSize,
893
+ getNeighbor: (xOffset, yOffset) => !!fakeMatrix[i + xOffset]?.[j + yOffset]
894
+ }), dot.element && this.dotsMask && this.dotsMaskGroup.appendChild(dot.element));
1339
895
  }
1340
- this._createColor({
896
+ this.createColor({
1341
897
  options: options.dotsOptions?.gradient,
1342
898
  color: options.dotsOptions.color,
1343
899
  additionalRotation: 0,
@@ -1349,431 +905,227 @@ class QRSVG {
1349
905
  });
1350
906
  }
1351
907
  drawCorners() {
1352
- if (!this._qr) {
1353
- throw "QR code is not defined";
1354
- }
1355
- const element = this._element;
1356
- const options = this._options;
1357
- if (!element) {
1358
- throw "Element code is not defined";
1359
- }
1360
- const count = this._qr.getModuleCount();
1361
- const dotSize = this._options.dotsOptions.size;
1362
- const cornersSquareSize = dotSize * 7;
1363
- const cornersDotSize = dotSize * 3;
1364
- const xBeginning = Math.floor((options.width - count * dotSize) / 2);
1365
- const yBeginning = Math.floor((options.height - count * dotSize) / 2);
1366
- [
1367
- [0, 0, 0],
1368
- [1, 0, Math.PI / 2],
1369
- [0, 1, -Math.PI / 2]
1370
- ].forEach(([column, row, rotation]) => {
1371
- const x = xBeginning + column * dotSize * (count - 7);
1372
- const y = yBeginning + row * dotSize * (count - 7);
1373
- let cornersSquareMask = this._dotsMask;
1374
- let cornersSquareMaskGroup = this._dotsMaskGroup;
1375
- let cornersDotMask = this._dotsMask;
1376
- let cornersDotMaskGroup = this._dotsMaskGroup;
1377
- if (options.cornersSquareOptions?.gradient || options.cornersSquareOptions?.color) {
1378
- [cornersSquareMask, cornersSquareMaskGroup] = this._createMask(`mask-corners-square-color-${column}-${row}`);
1379
- this._defs.appendChild(cornersSquareMask);
1380
- this._cornersSquareMask = this._cornersDotMask = cornersDotMask = cornersSquareMask;
1381
- this._cornersSquareMaskGroup = this._cornersDotMaskGroup = cornersDotMaskGroup = cornersSquareMaskGroup;
1382
- this._createColor({
1383
- options: options.cornersSquareOptions?.gradient,
1384
- color: options.cornersSquareOptions?.color,
1385
- additionalRotation: rotation,
1386
- x,
1387
- y,
1388
- height: cornersSquareSize,
1389
- width: cornersSquareSize,
1390
- name: `corners-square-color-${column}-${row}`
1391
- });
1392
- }
1393
- if (options.cornersSquareOptions?.type) {
1394
- const cornersSquare = new QRCornerSquare({
1395
- svg: this._element,
1396
- type: options.cornersSquareOptions.type,
1397
- document: this._document
1398
- });
1399
- cornersSquare.draw(x, y, cornersSquareSize, rotation);
1400
- if (cornersSquare._element && cornersSquareMaskGroup) {
1401
- cornersSquareMaskGroup.appendChild(cornersSquare._element);
1402
- }
1403
- }
1404
- else {
1405
- const dot = new QRDot({ svg: this._element, type: options.dotsOptions.type, document: this._document });
1406
- for (let i = 0; i < squareMask.length; i++) {
1407
- for (let j = 0; j < squareMask[i].length; j++) {
1408
- if (!squareMask[i]?.[j]) {
1409
- continue;
1410
- }
1411
- dot.draw(x + i * dotSize, y + j * dotSize, dotSize, (xOffset, yOffset) => !!squareMask[i + xOffset]?.[j + yOffset]);
1412
- if (dot._element && cornersSquareMaskGroup) {
1413
- cornersSquareMaskGroup.appendChild(dot._element);
1414
- }
1415
- }
1416
- }
1417
- }
1418
- if (options.cornersDotOptions?.gradient || options.cornersDotOptions?.color) {
1419
- [cornersDotMask, cornersDotMaskGroup] = this._createMask(`mask-corners-dot-color-${column}-${row}`);
1420
- this._defs.appendChild(cornersDotMask);
1421
- this._cornersDotMask = cornersDotMask;
1422
- this._cornersDotMaskGroup = cornersDotMaskGroup;
1423
- this._createColor({
1424
- options: options.cornersDotOptions?.gradient,
1425
- color: options.cornersDotOptions?.color,
1426
- additionalRotation: rotation,
1427
- x: x + dotSize * 2,
1428
- y: y + dotSize * 2,
1429
- height: cornersDotSize,
1430
- width: cornersDotSize,
1431
- name: `corners-dot-color-${column}-${row}`
1432
- });
908
+ if (!this.qr) throw "QR code is not defined";
909
+ let options = this.options;
910
+ if (!this._element) throw "Element code is not defined";
911
+ let count = this.qr.getModuleCount(), dotSize = this.options.dotsOptions.size, cornersSquareSize = 7 * dotSize, cornersDotSize = 3 * dotSize, xBeginning = Math.floor((options.width - count * dotSize) / 2), yBeginning = Math.floor((options.height - count * dotSize) / 2);
912
+ [ [ 0, 0, 0 ], [ 1, 0, Math.PI / 2 ], [ 0, 1, -Math.PI / 2 ] ].forEach((([column_cornersDot, row, dot]) => {
913
+ let x = xBeginning + column_cornersDot * dotSize * (count - 7), y = yBeginning + row * dotSize * (count - 7);
914
+ var cornersDotMaskGroup_cornersSquareMask = this.dotsMask;
915
+ let cornersSquareMaskGroup = this.dotsMaskGroup;
916
+ var cornersDotMask_cornersSquare_dot = this.dotsMask;
917
+ if (cornersDotMaskGroup_cornersSquareMask = this.dotsMaskGroup, (options.cornersSquareOptions?.gradient || options.cornersSquareOptions?.color) && ([cornersDotMaskGroup_cornersSquareMask, cornersSquareMaskGroup] = this.createMask(`mask-corners-square-color-${column_cornersDot}-${row}`),
918
+ this.defs.appendChild(cornersDotMaskGroup_cornersSquareMask), cornersDotMask_cornersSquare_dot = cornersDotMaskGroup_cornersSquareMask,
919
+ cornersDotMaskGroup_cornersSquareMask = cornersSquareMaskGroup, this.createColor({
920
+ options: options.cornersSquareOptions?.gradient,
921
+ color: options.cornersSquareOptions?.color,
922
+ additionalRotation: dot,
923
+ x,
924
+ y,
925
+ height: cornersSquareSize,
926
+ width: cornersSquareSize,
927
+ name: `corners-square-color-${column_cornersDot}-${row}`
928
+ })), options.cornersSquareOptions?.type) (cornersDotMask_cornersSquare_dot = new QRCornerSquare(options.cornersSquareOptions.type, this.document)).draw({
929
+ x,
930
+ y,
931
+ size: cornersSquareSize,
932
+ rotation: dot
933
+ }), cornersDotMask_cornersSquare_dot.element && cornersSquareMaskGroup && cornersSquareMaskGroup.appendChild(cornersDotMask_cornersSquare_dot.element); else {
934
+ cornersDotMask_cornersSquare_dot = new QRDot(options.dotsOptions.type, this.document);
935
+ for (let i = 0; i < squareMask.length; i++) for (let j = 0; j < squareMask[i].length; j++) squareMask[i]?.[j] && (cornersDotMask_cornersSquare_dot.draw({
936
+ x: x + i * dotSize,
937
+ y: y + j * dotSize,
938
+ size: dotSize,
939
+ getNeighbor: (xOffset, yOffset) => !!squareMask[i + xOffset]?.[j + yOffset]
940
+ }), cornersDotMask_cornersSquare_dot.element && cornersSquareMaskGroup && cornersSquareMaskGroup.appendChild(cornersDotMask_cornersSquare_dot.element));
1433
941
  }
1434
- if (options.cornersDotOptions?.type) {
1435
- const cornersDot = new QRCornerDot({
1436
- svg: this._element,
1437
- type: options.cornersDotOptions.type,
1438
- document: this._document
1439
- });
1440
- cornersDot.draw(x + dotSize * 2, y + dotSize * 2, cornersDotSize, rotation);
1441
- if (cornersDot._element && cornersDotMaskGroup) {
1442
- cornersDotMaskGroup.appendChild(cornersDot._element);
1443
- }
1444
- }
1445
- else {
1446
- const dot = new QRDot({ svg: this._element, type: options.dotsOptions.type, document: this._document });
1447
- for (let i = 0; i < dotMask.length; i++) {
1448
- for (let j = 0; j < dotMask[i].length; j++) {
1449
- if (!dotMask[i]?.[j]) {
1450
- continue;
1451
- }
1452
- dot.draw(x + i * dotSize, y + j * dotSize, dotSize, (xOffset, yOffset) => !!dotMask[i + xOffset]?.[j + yOffset]);
1453
- if (dot._element && cornersDotMaskGroup) {
1454
- cornersDotMaskGroup.appendChild(dot._element);
1455
- }
1456
- }
1457
- }
1458
- }
1459
- });
1460
- }
1461
- async drawImage({ width, height, count, dotSize }) {
1462
- const options = this._options;
1463
- const xBeginning = Math.floor((options.width - count * dotSize) / 2);
1464
- const yBeginning = Math.floor((options.height - count * dotSize) / 2);
1465
- const margin = options.imageOptions.margin * dotSize;
1466
- const dx = xBeginning + margin + (count * dotSize - width) / 2;
1467
- const dy = yBeginning + margin + (count * dotSize - height) / 2;
1468
- const dw = width - margin * 2;
1469
- const dh = height - margin * 2;
1470
- const imageUrl = await this._imageTools.toDataURL(options.image || "");
1471
- let image = this._document.createElementNS("http://www.w3.org/2000/svg", "image");
1472
- image.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", imageUrl || "");
1473
- if (imageUrl.startsWith("data:image/svg+xml;")) {
1474
- let data = imageUrl.substring(19);
1475
- const i = data.indexOf(",");
1476
- const encoding = data.substring(0, i);
1477
- data = data.substring(i + 1);
1478
- switch (encoding) {
1479
- case "base64":
1480
- data = typeof atob == "function" ? atob(data) : Buffer.from(data, "base64").toString("utf8");
1481
- break;
1482
- default:
1483
- data = "";
1484
- break;
1485
- }
1486
- if (data) {
1487
- const container = new DOMParser().parseFromString(data, "text/xml");
1488
- const rootEl = Array.from(container.getElementsByTagName("svg"));
1489
- if (rootEl.length)
1490
- image = rootEl[0];
942
+ if ((options.cornersDotOptions?.gradient || options.cornersDotOptions?.color) && ([cornersDotMask_cornersSquare_dot, cornersDotMaskGroup_cornersSquareMask] = this.createMask(`mask-corners-dot-color-${column_cornersDot}-${row}`),
943
+ this.defs.appendChild(cornersDotMask_cornersSquare_dot), this.createColor({
944
+ options: options.cornersDotOptions?.gradient,
945
+ color: options.cornersDotOptions?.color,
946
+ additionalRotation: dot,
947
+ x: x + 2 * dotSize,
948
+ y: y + 2 * dotSize,
949
+ height: cornersDotSize,
950
+ width: cornersDotSize,
951
+ name: `corners-dot-color-${column_cornersDot}-${row}`
952
+ })), options.cornersDotOptions?.type) (column_cornersDot = new QRCornerDot(options.cornersDotOptions.type, this.document)).draw({
953
+ x: x + 2 * dotSize,
954
+ y: y + 2 * dotSize,
955
+ size: cornersDotSize,
956
+ rotation: dot
957
+ }), column_cornersDot.element && cornersDotMaskGroup_cornersSquareMask && cornersDotMaskGroup_cornersSquareMask.appendChild(column_cornersDot.element); else {
958
+ dot = new QRDot(options.dotsOptions.type, this.document);
959
+ for (let i = 0; i < dotMask.length; i++) for (let j = 0; j < dotMask[i].length; j++) dotMask[i]?.[j] && (dot.draw({
960
+ x: x + i * dotSize,
961
+ y: y + j * dotSize,
962
+ size: dotSize,
963
+ getNeighbor: (xOffset, yOffset) => !!dotMask[i + xOffset]?.[j + yOffset]
964
+ }), dot.element && cornersDotMaskGroup_cornersSquareMask && cornersDotMaskGroup_cornersSquareMask.appendChild(dot.element));
1491
965
  }
966
+ }));
967
+ }
968
+ async drawImage({width: dw_width, height: dh_height, count, dotSize}) {
969
+ var image = this.options, container_data = image.imageOptions.margin * dotSize;
970
+ let dx = Math.floor((image.width - count * dotSize) / 2) + container_data + (count * dotSize - dw_width) / 2;
971
+ if (count = Math.floor((image.height - count * dotSize) / 2) + container_data + (count * dotSize - dh_height) / 2,
972
+ dw_width -= 2 * container_data, dh_height -= 2 * container_data, container_data = await this.imageTools.toDataURL(image.image || ""),
973
+ (image = this.document.createElementNS("http://www.w3.org/2000/svg", "image")).setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", container_data || ""),
974
+ container_data.startsWith("data:image/svg+xml;")) {
975
+ dotSize = (container_data = container_data.substring(19)).indexOf(",");
976
+ let encoding = container_data.substring(0, dotSize);
977
+ if (container_data = container_data.substring(dotSize + 1), "base64" === encoding) container_data = "function" == typeof atob ? atob(container_data) : Buffer.from(container_data, "base64").toString("utf8"); else container_data = "";
978
+ container_data && (container_data = (new DOMParser).parseFromString(container_data, "text/xml"),
979
+ (container_data = Array.from(container_data.getElementsByTagName("svg"))).length && (image = container_data[0]));
1492
980
  }
1493
- image.setAttribute("x", String(dx));
1494
- image.setAttribute("y", String(dy));
1495
- image.setAttribute("width", `${dw}px`);
1496
- image.setAttribute("height", `${dh}px`);
981
+ image.setAttribute("x", numToAttr(dx)), image.setAttribute("y", numToAttr(count)),
982
+ image.setAttribute("width", `${numToAttr(dw_width)}px`), image.setAttribute("height", `${numToAttr(dh_height)}px`),
1497
983
  this._element.appendChild(image);
1498
984
  }
1499
- /** @ignore */
1500
- _createColor({ options, color, additionalRotation, x, y, height, width, name }) {
1501
- const size = width > height ? width : height;
1502
- const rect = this._document.createElementNS("http://www.w3.org/2000/svg", "rect");
1503
- rect.setAttribute("x", String(x));
1504
- rect.setAttribute("y", String(y));
1505
- rect.setAttribute("height", String(height));
1506
- rect.setAttribute("width", String(width));
1507
- rect.setAttribute("style", `mask:url(#mask-${name})`);
1508
- if (options) {
985
+ createColor({options, color, additionalRotation: additionalRotation_positiveRotation, x, y, height, width, name}) {
986
+ var size = width > height ? width : height;
987
+ let rect = this.document.createElementNS("http://www.w3.org/2000/svg", "rect");
988
+ if (rect.setAttribute("x", numToAttr(x)), rect.setAttribute("y", numToAttr(y)),
989
+ rect.setAttribute("height", numToAttr(height)), rect.setAttribute("width", numToAttr(width)),
990
+ rect.setAttribute("style", `mask:url(#mask-${name})`), options) {
1509
991
  let gradient;
1510
- if (options.type === GradientType.radial) {
1511
- gradient = this._document.createElementNS("http://www.w3.org/2000/svg", "radialGradient");
1512
- gradient.setAttribute("id", name);
1513
- gradient.setAttribute("gradientUnits", "userSpaceOnUse");
1514
- gradient.setAttribute("fx", String(x + width / 2));
1515
- gradient.setAttribute("fy", String(y + height / 2));
1516
- gradient.setAttribute("cx", String(x + width / 2));
1517
- gradient.setAttribute("cy", String(y + height / 2));
1518
- gradient.setAttribute("r", String(size / 2));
1519
- }
1520
- else {
1521
- const rotation = ((options.rotation || 0) + additionalRotation) % (2 * Math.PI);
1522
- const positiveRotation = (rotation + 2 * Math.PI) % (2 * Math.PI);
1523
- let x0 = x + width / 2;
992
+ if (options.type === GradientType.radial) gradient = this.document.createElementNS("http://www.w3.org/2000/svg", "radialGradient"),
993
+ gradient.setAttribute("id", name), gradient.setAttribute("gradientUnits", "userSpaceOnUse"),
994
+ gradient.setAttribute("fx", numToAttr(x + width / 2)), gradient.setAttribute("fy", numToAttr(y + height / 2)),
995
+ gradient.setAttribute("cx", numToAttr(x + width / 2)), gradient.setAttribute("cy", numToAttr(y + height / 2)),
996
+ gradient.setAttribute("r", numToAttr(size / 2)); else {
997
+ size = x + width / 2;
1524
998
  let y0 = y + height / 2;
1525
- let x1 = x + width / 2;
1526
- let y1 = y + height / 2;
1527
- if ((positiveRotation >= 0 && positiveRotation <= 0.25 * Math.PI) ||
1528
- (positiveRotation > 1.75 * Math.PI && positiveRotation <= 2 * Math.PI)) {
1529
- x0 = x0 - width / 2;
1530
- y0 = y0 - (height / 2) * Math.tan(rotation);
1531
- x1 = x1 + width / 2;
1532
- y1 = y1 + (height / 2) * Math.tan(rotation);
1533
- }
1534
- else if (positiveRotation > 0.25 * Math.PI && positiveRotation <= 0.75 * Math.PI) {
1535
- y0 = y0 - height / 2;
1536
- x0 = x0 - width / 2 / Math.tan(rotation);
1537
- y1 = y1 + height / 2;
1538
- x1 = x1 + width / 2 / Math.tan(rotation);
1539
- }
1540
- else if (positiveRotation > 0.75 * Math.PI && positiveRotation <= 1.25 * Math.PI) {
1541
- x0 = x0 + width / 2;
1542
- y0 = y0 + (height / 2) * Math.tan(rotation);
1543
- x1 = x1 - width / 2;
1544
- y1 = y1 - (height / 2) * Math.tan(rotation);
1545
- }
1546
- else if (positiveRotation > 1.25 * Math.PI && positiveRotation <= 1.75 * Math.PI) {
1547
- y0 = y0 + height / 2;
1548
- x0 = x0 + width / 2 / Math.tan(rotation);
1549
- y1 = y1 - height / 2;
1550
- x1 = x1 - width / 2 / Math.tan(rotation);
1551
- }
1552
- gradient = this._document.createElementNS("http://www.w3.org/2000/svg", "linearGradient");
1553
- gradient.setAttribute("id", name);
1554
- gradient.setAttribute("gradientUnits", "userSpaceOnUse");
1555
- gradient.setAttribute("x1", String(Math.round(x0)));
1556
- gradient.setAttribute("y1", String(Math.round(y0)));
1557
- gradient.setAttribute("x2", String(Math.round(x1)));
1558
- gradient.setAttribute("y2", String(Math.round(y1)));
999
+ x += width / 2, y += height / 2, 0 <= (additionalRotation_positiveRotation = ((color = ((options.rotation || 0) + additionalRotation_positiveRotation) % (2 * Math.PI)) + 2 * Math.PI) % (2 * Math.PI)) && additionalRotation_positiveRotation <= .25 * Math.PI || additionalRotation_positiveRotation > 1.75 * Math.PI && additionalRotation_positiveRotation <= 2 * Math.PI ? (size -= width / 2,
1000
+ y0 -= height / 2 * Math.tan(color), x += width / 2, y += height / 2 * Math.tan(color)) : additionalRotation_positiveRotation > .25 * Math.PI && additionalRotation_positiveRotation <= .75 * Math.PI ? (y0 -= height / 2,
1001
+ size -= width / 2 / Math.tan(color), y += height / 2, x += width / 2 / Math.tan(color)) : additionalRotation_positiveRotation > .75 * Math.PI && additionalRotation_positiveRotation <= 1.25 * Math.PI ? (size += width / 2,
1002
+ y0 += height / 2 * Math.tan(color), x -= width / 2, y -= height / 2 * Math.tan(color)) : additionalRotation_positiveRotation > 1.25 * Math.PI && additionalRotation_positiveRotation <= 1.75 * Math.PI && (y0 += height / 2,
1003
+ size += width / 2 / Math.tan(color), y -= height / 2, x -= width / 2 / Math.tan(color)),
1004
+ gradient = this.document.createElementNS("http://www.w3.org/2000/svg", "linearGradient"),
1005
+ gradient.setAttribute("id", name), gradient.setAttribute("gradientUnits", "userSpaceOnUse"),
1006
+ gradient.setAttribute("x1", numToAttr(size)), gradient.setAttribute("y1", numToAttr(y0)),
1007
+ gradient.setAttribute("x2", numToAttr(x)), gradient.setAttribute("y2", numToAttr(y));
1559
1008
  }
1560
- options.colorStops.forEach(({ offset, color }) => {
1561
- const stop = this._document.createElementNS("http://www.w3.org/2000/svg", "stop");
1562
- stop.setAttribute("offset", `${100 * offset}%`);
1563
- stop.setAttribute("stop-color", color);
1009
+ options.colorStops.forEach((({offset, color}) => {
1010
+ let stop = this.document.createElementNS("http://www.w3.org/2000/svg", "stop");
1011
+ stop.setAttribute("offset", `${numToAttr(100 * offset)}%`), stop.setAttribute("stop-color", color),
1564
1012
  gradient.appendChild(stop);
1565
- });
1566
- rect.setAttribute("fill", `url(#${name})`);
1567
- this._defs.appendChild(gradient);
1568
- }
1569
- else if (color) {
1570
- rect.setAttribute("fill", color);
1571
- }
1013
+ })), rect.setAttribute("fill", `url(#${name})`), this.defs.appendChild(gradient);
1014
+ } else color && rect.setAttribute("fill", color);
1572
1015
  this._element.appendChild(rect);
1573
1016
  }
1574
- _createMask(id) {
1575
- const options = this._options;
1576
- const mask = this._document.createElementNS("http://www.w3.org/2000/svg", "mask");
1577
- mask.setAttribute("id", id);
1578
- mask.setAttribute("maskUnits", "userSpaceOnUse");
1579
- mask.setAttribute("x", "0");
1580
- mask.setAttribute("y", "0");
1581
- mask.setAttribute("width", String(options.width));
1582
- mask.setAttribute("height", String(options.height));
1583
- const group = this._document.createElementNS("http://www.w3.org/2000/svg", "g");
1584
- group.setAttribute("fill", "#fff");
1585
- mask.appendChild(group);
1586
- return [mask, group];
1017
+ createMask(group_id) {
1018
+ let options = this.options, mask = this.document.createElementNS("http://www.w3.org/2000/svg", "mask");
1019
+ return mask.setAttribute("id", group_id), mask.setAttribute("maskUnits", "userSpaceOnUse"),
1020
+ mask.setAttribute("x", "0"), mask.setAttribute("y", "0"), mask.setAttribute("width", numToAttr(options.width)),
1021
+ mask.setAttribute("height", numToAttr(options.height)), (group_id = this.document.createElementNS("http://www.w3.org/2000/svg", "g")).setAttribute("fill", "#fff"),
1022
+ mask.appendChild(group_id), [ mask, group_id ];
1587
1023
  }
1588
1024
  }
1589
1025
 
1590
- let QRCodeStyling$1 = class QRCodeStyling {
1026
+ let QRCodeStyling$1 = class {
1027
+ get size() {
1028
+ if (this.qrSVG) return {
1029
+ width: this.qrSVG.width,
1030
+ height: this.qrSVG.height
1031
+ };
1032
+ }
1591
1033
  constructor(options) {
1592
- this._options = options ? sanitizeOptions(mergeDeep(defaultOptions, options)) : defaultOptions;
1034
+ this.options = options ? sanitizeOptions(mergeDeep(defaultOptions, options)) : defaultOptions,
1593
1035
  this.update();
1594
1036
  }
1595
- /** @ignore */
1596
- static _clearContainer(container) {
1597
- if (container) {
1598
- container.innerHTML = "";
1599
- }
1037
+ update(mode) {
1038
+ this.container && (this.container.innerHTML = ""), this.options = mode ? sanitizeOptions(mergeDeep(this.options, mode)) : this.options,
1039
+ this.options.data && (this.options.stringToBytesFuncs && (Object.assign(qrcode.stringToBytesFuncs, this.options.stringToBytesFuncs),
1040
+ delete this.options.stringToBytesFuncs), this.qr = qrcode(this.options.qrOptions.typeNumber, this.options.qrOptions.errorCorrectionLevel),
1041
+ (mode = this.options.qrOptions.mode || function(data) {
1042
+ switch (!0) {
1043
+ case /^[0-9]*$/.test(data):
1044
+ return Mode.numeric;
1045
+
1046
+ case /^[0-9A-Z $%*+\-./:]*$/.test(data):
1047
+ return Mode.alphanumeric;
1048
+
1049
+ case /[^\u0000-\u00ff]/.test(data):
1050
+ return Mode.unicode;
1051
+
1052
+ default:
1053
+ return Mode.byte;
1054
+ }
1055
+ }(this.options.data)) == Mode.unicode ? (qrcode.stringToBytes = qrcode.stringToBytesFuncs["UTF-8"],
1056
+ mode = Mode.byte) : qrcode.stringToBytes = qrcode.stringToBytesFuncs.default, this.qr.addData(this.options.data, mode),
1057
+ this.qr.make(), this.setupSvg(), this.append(this.container));
1600
1058
  }
1601
- /** @ignore */
1602
- _setupSvg() {
1603
- if (!this._qr) {
1604
- return;
1605
- }
1606
- const count = Math.ceil((this._options.shape == ShapeType.circle ? Math.sqrt(2) : 1) * this._qr.getModuleCount());
1607
- const margin = (this._options.backgroundOptions && this._options.backgroundOptions.margin) || 0;
1608
- const size = Math.ceil(this._options.dotsOptions.size * (count + 2 * margin));
1609
- const qrSVG = new QRSVG({
1610
- ...this._options,
1611
- width: size,
1612
- height: size
1613
- });
1614
- this._svg = qrSVG.getElement();
1615
- this._svgDrawingPromise = qrSVG.drawQR(this._qr).then(() => {
1616
- if (!this._svg)
1617
- return;
1618
- this._extension?.(qrSVG.getElement(), this._options);
1619
- });
1059
+ append(container) {
1060
+ container && (this.qrSVG?.element && container.appendChild(this.qrSVG.element),
1061
+ this.container = container);
1620
1062
  }
1621
- /** @ignore */
1622
- async _getElement() {
1623
- if (!this._qr)
1624
- throw "QR code is empty";
1625
- if (!this._svg || !this._svgDrawingPromise) {
1626
- this._setupSvg();
1627
- }
1628
- await this._svgDrawingPromise;
1629
- return this._svg;
1630
- }
1631
- update(
1632
- /** The same options as for initialization */
1633
- options) {
1634
- QRCodeStyling._clearContainer(this._container);
1635
- this._options = options ? sanitizeOptions(mergeDeep(this._options, options)) : this._options;
1636
- if (!this._options.data) {
1637
- return;
1638
- }
1639
- if (this._options.stringToBytesFuncs) {
1640
- Object.assign(qrcode.stringToBytesFuncs, this._options.stringToBytesFuncs);
1641
- delete this._options.stringToBytesFuncs;
1642
- }
1643
- this._qr = qrcode(this._options.qrOptions.typeNumber, this._options.qrOptions.errorCorrectionLevel);
1644
- let mode = this._options.qrOptions.mode || getMode(this._options.data);
1645
- if (mode == Mode.unicode) {
1646
- qrcode.stringToBytes = qrcode.stringToBytesFuncs["UTF-8"];
1647
- mode = Mode.byte;
1648
- }
1649
- else {
1650
- qrcode.stringToBytes = qrcode.stringToBytesFuncs["default"];
1651
- }
1652
- this._qr.addData(this._options.data, mode);
1653
- this._qr.make();
1654
- this._setupSvg();
1655
- this.append(this._container);
1656
- }
1657
- append(
1658
- /** This container will be used for appending of the QR code */
1659
- container) {
1660
- if (!container) {
1661
- return;
1662
- }
1663
- if (typeof container.appendChild !== "function") {
1664
- throw "Container should be a single DOM node";
1665
- }
1666
- if (this._svg) {
1667
- container.appendChild(this._svg);
1668
- }
1669
- this._container = container;
1670
- }
1671
- /**
1672
- *
1673
- * @example
1674
- *
1675
- * ```js
1676
- * const extension = (svg, options) => {
1677
- * const { width, height } = options;
1678
- * const size = Math.min(width, height);
1679
- * const border = options.document.createElementNS("http://www.w3.org/2000/svg", "rect");
1680
- * const borderAttributes = {
1681
- * fill: "none",
1682
- * x: (width - size + 40) / 2,
1683
- * y: (height - size + 40) / 2,
1684
- * width: size - 40,
1685
- * height: size - 40,
1686
- * stroke: "black",
1687
- * "stroke-width": 40,
1688
- * rx: 100
1689
- * };
1690
- * Object.keys(borderAttributes).forEach((attribute) => {
1691
- * border.setAttribute(attribute, borderAttributes[attribute]);
1692
- * });
1693
- * svg.appendChild(border);
1694
- * };
1695
- * ```
1696
- */
1697
- applyExtension(
1698
- /** Extension is a function that takes svg and previously applied options and modifies an svg */
1699
- extension) {
1700
- if (!extension) {
1701
- throw "Extension function should be defined.";
1702
- }
1703
- this._extension = extension;
1704
- this.update();
1063
+ applyExtension(extension) {
1064
+ if (!extension) throw "Extension function should be defined.";
1065
+ this.extension = extension, this.update();
1705
1066
  }
1706
1067
  deleteExtension() {
1707
- this._extension = undefined;
1708
- this.update();
1068
+ this.extension = void 0, this.update();
1709
1069
  }
1710
1070
  async serialize() {
1711
- if (!this._qr)
1712
- throw "QR code is empty";
1713
- const element = await this._getElement();
1714
- if (!element) {
1715
- return;
1071
+ if (!this.qr) throw "QR code is empty";
1072
+ if (this.qrSVG?.element && this.svgDrawingPromise || this.setupSvg(), await this.svgDrawingPromise,
1073
+ this.qrSVG?.element) return '<?xml version="1.0" standalone="no"?>\r\n' + (new XMLSerializer).serializeToString(this.qrSVG.element);
1074
+ }
1075
+ setupSvg() {
1076
+ if (this.qr) {
1077
+ var count = Math.ceil((this.options.shape == ShapeType.circle ? Math.sqrt(2) : 1) * this.qr.getModuleCount());
1078
+ count = Math.ceil(this.options.dotsOptions.size * (count + 2 * (this.options.backgroundOptions && this.options.backgroundOptions.margin || 0))),
1079
+ this.qrSVG = new QRSVG({
1080
+ ...this.options,
1081
+ width: count,
1082
+ height: count,
1083
+ errorCorrectionPercent: ErrorCorrectionPercents[this.options.qrOptions.errorCorrectionLevel]
1084
+ }), this.svgDrawingPromise = this.qrSVG.drawQR(this.qr).then((() => {
1085
+ this.qrSVG?.element && this.extension?.(this.qrSVG.element, this.options);
1086
+ }));
1716
1087
  }
1717
- const serializer = new XMLSerializer();
1718
- let source = serializer.serializeToString(element);
1719
- source = '<?xml version="1.0" standalone="no"?>\r\n' + source;
1720
- return source;
1721
1088
  }
1722
1089
  };
1723
1090
 
1724
- const browserUtils = undefined;
1091
+ var FileExtension;
1092
+
1093
+ (FileExtension = FileExtension || (FileExtension = {})).svg = "svg", FileExtension.png = "png",
1094
+ FileExtension.jpeg = "jpeg", FileExtension.webp = "webp";
1095
+
1725
1096
  class QRCodeStyling extends QRCodeStyling$1 {
1726
1097
  constructor(options) {
1727
- const dom = new DOMImplementation().createDocument(null, null);
1728
- const imageCache = new Map();
1729
- const loadImage = async function (url) {
1730
- if (typeof url == "string") {
1731
- let pr = imageCache.get(url);
1732
- if (pr)
1733
- return pr;
1734
- pr = fetch(url).then((res) => res
1735
- .arrayBuffer()
1736
- .then((buff) => Buffer.from(buff))
1737
- .then(async (data) => ({
1738
- contentType: res.headers.get("Content-Type") || (await fileTypeFromBuffer(data).then((r) => r?.mime)),
1098
+ async function loadImage(buff) {
1099
+ if ("string" == typeof buff) {
1100
+ let pr = imageCache.get(buff);
1101
+ return pr || (pr = fetch(buff).then((res => res.arrayBuffer().then((buff => Buffer.from(buff))).then((async data => ({
1102
+ contentType: res.headers.get("Content-Type") || await fileTypeFromBuffer(data).then((r => r?.mime)),
1739
1103
  data
1740
- })));
1741
- imageCache.set(url, pr);
1742
- return pr;
1104
+ }))))), imageCache.set(buff, pr), pr);
1743
1105
  }
1744
- else {
1745
- const buff = Buffer.from(url);
1746
- const mime = await fileTypeFromBuffer(buff).then((r) => r?.mime);
1747
- return {
1748
- contentType: mime,
1749
- data: buff
1750
- };
1751
- }
1752
- };
1753
- global.XMLSerializer = XMLSerializer$1;
1754
- global.DOMParser = DOMParser$1;
1755
- super({
1106
+ return buff = Buffer.from(buff), {
1107
+ contentType: await fileTypeFromBuffer(buff).then((r => r?.mime)),
1108
+ data: buff
1109
+ };
1110
+ }
1111
+ let dom = (new DOMImplementation).createDocument(null, null), imageCache = new Map;
1112
+ global.XMLSerializer = XMLSerializer$1, global.DOMParser = DOMParser$1, super({
1756
1113
  ...options,
1757
1114
  document: options.document || dom,
1758
1115
  imageTools: options.imageTools || {
1759
- toDataURL: (url) => loadImage(url).then(({ contentType, data }) => `data:${contentType?.replace("application/xml", "image/svg+xml")};base64,${data.toString("base64")}`),
1760
- getSize: async function (options) {
1761
- if (!options.image) {
1762
- throw new Error("Image is not defined");
1763
- }
1764
- const { data } = Buffer.isBuffer(options.image) ? { data: options.image } : await loadImage(options.image);
1765
- const meta = await sharp(data).metadata();
1766
- return {
1767
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
1768
- width: meta.width,
1769
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
1770
- height: meta.height
1771
- };
1772
- }
1116
+ toDataURL: url => loadImage(url).then((({contentType, data}) => `data:${contentType?.replace("application/xml", "image/svg+xml")};base64,${data.toString("base64")}`)),
1117
+ getSize: async data => (({data} = Buffer.isBuffer(options.image) ? {
1118
+ data: options.image
1119
+ } : await loadImage(data)), {
1120
+ width: (data = await sharp(data).metadata()).width,
1121
+ height: data.height
1122
+ })
1773
1123
  }
1774
1124
  });
1775
1125
  }
1776
1126
  }
1777
1127
 
1128
+ var browserUtils = void 0;
1129
+
1778
1130
  export { CornerDotType, CornerSquareType, DotType, ErrorCorrectionLevel, ErrorCorrectionPercents, FileExtension, GradientType, Mode, QRCodeStyling, ShapeType, TypeNumber, browserUtils };
1779
1131
  //# sourceMappingURL=qr-code-styling-node.js.map