@tapple.io/qr-code-generator 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Tapple Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,578 @@
1
+ # Tapple QR
2
+
3
+ A lightweight QR code generator with full TypeScript support. Generate QR codes as SVG, PNG, or ASCII with extensive customization options.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/qr-code-generator.svg)](https://www.npmjs.com/package/qr-code-generator)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
7
+ [![npm downloads](https://img.shields.io/npm/dm/qr-code-generator.svg)](https://www.npmjs.com/package/qr-code-generator)
8
+ [![Bundle size](https://img.shields.io/bundlephobia/minzip/qr-code-generator)](https://bundlephobia.com/package/qr-code-generator)
9
+
10
+ ## Features
11
+
12
+ - 🚀 **Platform-optimized architecture** - Zero browser dependencies (native Canvas API) + one Node.js dependency (`@resvg/resvg-js`)
13
+ - 🌐 **Universal API** - Identical API across Node.js, browsers, and bundlers (ESM & CommonJS)
14
+ - 🎯 **Multiple outputs** - Generate SVG, PNG (Buffer/DataURL), or ASCII art in any environment
15
+ - 🎨 **Highly customizable** - Control colors, shapes, borders, logos, and more
16
+ - 📱 **Smart formatting** - Built-in support for WiFi, vCards, URLs, SMS, and calendar events
17
+ - 🔒 **Type-safe** - Full TypeScript support with comprehensive type definitions
18
+ - ⚡ **Auto-optimized** - Automatic version selection, error correction, and mask patterns
19
+
20
+ ## Installation
21
+
22
+ ```bash
23
+ npm install qr-code-generator
24
+ ```
25
+
26
+ That's it! The package automatically provides platform-optimized bundles:
27
+
28
+ - **Browser**: Zero dependencies - uses native Canvas API
29
+ - **Node.js**: One dependency (`@resvg/resvg-js`) - installed automatically
30
+
31
+ **Why this matters:** Most QR libraries bundle heavy dependencies (~2.5MB) that work everywhere but bloat browser bundles. We use environment-specific implementations - Canvas API in browsers (built-in) and `@resvg/resvg-js` in Node.js (acceptable for server environments) - automatically delivering the optimal bundle for your platform.
32
+
33
+ ## Quick Start
34
+
35
+ The following examples work universally in both Node.js and browsers:
36
+
37
+ ```typescript
38
+ import { genQrImage, genQrText } from 'qr-code-generator';
39
+
40
+ // Generate PNG buffer (default)
41
+ const pngBuffer = await genQrImage('https://tapple.io');
42
+
43
+ // Generate PNG data URL
44
+ const pngDataUrl = await genQrImage('https://tapple.io', {
45
+ output: { format: 'png', type: 'dataURL' }
46
+ });
47
+
48
+ // Generate SVG string
49
+ const svg = await genQrImage('Hello World', {
50
+ output: { format: 'svg', type: 'string' }
51
+ });
52
+
53
+ // Generate SVG data URL
54
+ const svgDataUrl = await genQrImage('Hello World', {
55
+ output: { format: 'svg', type: 'dataURL' }
56
+ });
57
+
58
+ // Generate ASCII art (synchronous)
59
+ const ascii = genQrText('Terminal QR');
60
+ console.log(ascii);
61
+ ```
62
+
63
+ ### Platform-Specific Examples
64
+
65
+ #### Saving to File (Node.js)
66
+
67
+ ```typescript
68
+ import { genQrImage } from 'qr-code-generator';
69
+ import fs from 'fs';
70
+
71
+ // Save PNG to file
72
+ const buffer = await genQrImage('https://tapple.io', {
73
+ output: { format: 'png', type: 'buffer' }
74
+ });
75
+ fs.writeFileSync('qrcode.png', buffer);
76
+
77
+ // Save SVG to file
78
+ const svg = await genQrImage('https://tapple.io', {
79
+ output: { format: 'svg', type: 'string' }
80
+ });
81
+ fs.writeFileSync('qrcode.svg', svg);
82
+ ```
83
+
84
+ #### Using in HTML (Browser)
85
+
86
+ ```typescript
87
+ import { genQrImage } from 'qr-code-generator';
88
+
89
+ // Display PNG as image (returns dataURL string)
90
+ const img = document.getElementById('qr-image');
91
+ img.src = await genQrImage('https://tapple.io', {
92
+ output: { format: 'png', type: 'dataURL' }
93
+ });
94
+
95
+ // Or use SVG data URL
96
+ img.src = await genQrImage('https://tapple.io', {
97
+ output: { format: 'svg', type: 'dataURL' }
98
+ });
99
+ ```
100
+
101
+ ## API Reference
102
+
103
+ ### Render Functions
104
+
105
+ #### `genQrImage(input, options?)`
106
+
107
+ Generates a QR code image. Returns a Promise that resolves to the output format specified.
108
+
109
+ **Return types:**
110
+ - PNG buffer: `Buffer` (Node.js) or `Uint8Array` (browser)
111
+ - PNG dataURL: `string`
112
+ - SVG string: `string`
113
+ - SVG dataURL: `string`
114
+
115
+ ```typescript
116
+ // Default: PNG buffer
117
+ const buffer = await genQrImage('https://tapple.io');
118
+
119
+ // PNG data URL
120
+ const dataURL = await genQrImage('https://tapple.io', {
121
+ size: 400,
122
+ output: { format: 'png', type: 'dataURL' }
123
+ });
124
+
125
+ // SVG string
126
+ const svg = await genQrImage('https://tapple.io', {
127
+ output: { format: 'svg', type: 'string' }
128
+ });
129
+
130
+ // SVG data URL
131
+ const svgDataURL = await genQrImage('https://tapple.io', {
132
+ output: { format: 'svg', type: 'dataURL' }
133
+ });
134
+ ```
135
+
136
+ #### `genQrText(input, options?)`
137
+
138
+ Generates ASCII art representation. This function is synchronous.
139
+
140
+ ```typescript
141
+ const ascii = genQrText('Hello', {
142
+ margin: 2,
143
+ darkChar: '██',
144
+ lightChar: ' '
145
+ });
146
+ ```
147
+
148
+ ## Customization Options
149
+
150
+ ### Image Options (PNG & SVG)
151
+
152
+ ```typescript
153
+ import { genQrImage, EyeFrameShape, DotShape, BorderShape } from 'qr-code-generator';
154
+
155
+ const options = {
156
+ size: 300, // QR matrix size in pixels
157
+ margin: 24, // Margin in pixels
158
+ backgroundColor: '#ffffff', // Background color
159
+
160
+ // Eye (position marker) styling
161
+ eyes: {
162
+ shape: EyeFrameShape.SQUIRCLE, // 'square' | 'squircle'
163
+ color: '#0066ff'
164
+ },
165
+
166
+ // Pupil (center of eyes) styling
167
+ pupils: {
168
+ color: '#000000'
169
+ },
170
+
171
+ // Data dot styling
172
+ dots: {
173
+ shape: DotShape.DOTS, // 'classic' | 'dots' | 'square'
174
+ color: '#000000',
175
+ scale: 1.0 // 0.75 to 1.25
176
+ },
177
+
178
+ // Add a logo in the center
179
+ logo: {
180
+ src: 'data:image/png;base64,...', // Data URL or SVG string
181
+ scale: 0.2 // 0.1 to 0.3
182
+ },
183
+
184
+ // Border styling
185
+ border: {
186
+ shape: BorderShape.SQUIRCLE, // 'none' | 'square' | 'squircle' | 'circle'
187
+ width: 10, // Border width in pixels
188
+ color: '#000000',
189
+ style: 'solid' // 'solid' | 'dashed'
190
+ },
191
+
192
+ // Output configuration
193
+ output: {
194
+ format: 'png', // 'png' | 'svg'
195
+ type: 'buffer' // 'buffer' | 'dataURL' for PNG; 'string' | 'dataURL' for SVG
196
+ }
197
+ };
198
+
199
+ const qr = await genQrImage('https://tapple.io', options);
200
+ ```
201
+
202
+ ### ImageOptions Reference
203
+
204
+ Complete reference for PNG and SVG rendering options:
205
+
206
+ | Option | Type | Default | Valid Range | Description |
207
+ |--------|------|---------|-------------|-------------|
208
+ | `size` | number | `300` | >= 21 | QR matrix size in pixels |
209
+ | `margin` | number | `24` | >= 0 | Spacing around QR code in pixels |
210
+ | `backgroundColor` | string | `'#ffffff'` | Hex color | Background color |
211
+ | **Eyes (Position Markers)** |
212
+ | `eyes.shape` | enum | `'square'` | `'square'` \| `'squircle'` | Outer frame shape of position markers |
213
+ | `eyes.color` | string | `'#000000'` | Hex color | Color of eye frames |
214
+ | **Pupils (Eye Centers)** |
215
+ | `pupils.color` | string | `'#000000'` | Hex color | Color of pupil (inner square of eyes) |
216
+ | **Dots (Data Modules)** |
217
+ | `dots.shape` | enum | `'classic'` | `'classic'` \| `'dots'` \| `'square'` | Shape of data modules |
218
+ | `dots.color` | string | `'#000000'` | Hex color | Color of data modules |
219
+ | `dots.scale` | number | `1.0` | 0.75 - 1.25 | Visual size multiplier |
220
+ | **Logo** |
221
+ | `logo.src` | string | - | Data URL or SVG string | Image source |
222
+ | `logo.scale` | number | `0.2` | 0.1 - 0.3 | Logo size as percentage of QR width |
223
+ | **Border** |
224
+ | `border.shape` | enum | `'none'` | `'none'` \| `'square'` \| `'squircle'` \| `'circle'` | Border shape wrapping the QR code |
225
+ | `border.width` | number | `10` | >=0 | Border thickness in pixels |
226
+ | `border.color` | string | `'#000000'` | Hex color | Border color |
227
+ | `border.style` | enum | `'solid'` | `'solid'` \| `'dashed'` | Border line style |
228
+ | **Output** |
229
+ | `output.format` | enum | `'png'` | `'png'` \| `'svg'` | Output image format |
230
+ | `output.type` | enum | `'buffer'` | `'buffer'` \| `'dataURL'` (png), `'string'` \| `'dataURL'` (svg) | Output type |
231
+
232
+ > **Note:** Error correction level is automatically selected based on input length and logo presence (not user-configurable).
233
+
234
+ ### TextOptions Reference
235
+
236
+ Options for ASCII text rendering:
237
+
238
+ | Option | Type | Default | Valid Range | Description |
239
+ |--------|------|---------|-------------|-------------|
240
+ | `margin` | number | `2` | >= 0 | Margin in modules (not pixels) |
241
+ | `darkChar` | string | `'██'` | Any string | Character(s) representing dark modules |
242
+ | `lightChar` | string | `' '` | Any string | Character(s) representing light modules |
243
+
244
+ ## Structured Content Types
245
+
246
+ ### WiFi Network
247
+
248
+ ```typescript
249
+ const qr = await genQrImage({
250
+ type: 'wifi',
251
+ data: {
252
+ ssid: 'MyNetwork',
253
+ password: 'SecurePassword123',
254
+ encryption: 'WPA', // 'WPA' | 'WPA2' | 'WEP' | 'nopass'
255
+ hidden: false
256
+ }
257
+ });
258
+ ```
259
+
260
+ ### Contact Card (vCard)
261
+
262
+ ```typescript
263
+ const qr = await genQrImage({
264
+ type: 'vcard',
265
+ data: {
266
+ name: 'John Doe',
267
+ phone: '+1-555-123-4567',
268
+ email: 'john@tapple.io',
269
+ organization: 'Acme Corp',
270
+ title: 'Software Engineer',
271
+ url: 'https://johndoe.com',
272
+ address: {
273
+ street: '123 Main St',
274
+ city: 'San Francisco',
275
+ state: 'CA',
276
+ zip: '94105',
277
+ country: 'USA'
278
+ }
279
+ }
280
+ });
281
+ ```
282
+
283
+ ### Calendar Event
284
+
285
+ ```typescript
286
+ const qr = await genQrImage({
287
+ type: 'calendar',
288
+ data: {
289
+ title: 'Team Meeting',
290
+ startDate: new Date('2024-12-30T14:00:00'),
291
+ endDate: new Date('2024-12-30T15:00:00'),
292
+ location: 'Conference Room A',
293
+ description: 'Quarterly planning session'
294
+ }
295
+ });
296
+ ```
297
+
298
+ ### Email, SMS, Phone
299
+
300
+ ```typescript
301
+ // Email with subject and body
302
+ const emailQR = await genQrImage({
303
+ type: 'email',
304
+ email: 'support@tapple.io',
305
+ subject: 'Support Request',
306
+ body: 'I need help with...'
307
+ });
308
+
309
+ // SMS message
310
+ const smsQR = await genQrImage({
311
+ type: 'sms',
312
+ phone: '+1-555-123-4567',
313
+ message: 'Hello from QR code!'
314
+ });
315
+
316
+ // Phone number
317
+ const phoneQR = await genQrImage({
318
+ type: 'phone',
319
+ phone: '+1-555-123-4567'
320
+ });
321
+ ```
322
+
323
+ ### URL (explicit)
324
+
325
+ ```typescript
326
+ const qr = await genQrImage({
327
+ type: 'url',
328
+ url: 'https://tapple.io'
329
+ });
330
+
331
+ // Or just pass the URL directly:
332
+ const qr = await genQrImage('https://tapple.io');
333
+ ```
334
+
335
+ ## Shape Enums
336
+
337
+ Import shape enums for type-safe customization:
338
+
339
+ ```typescript
340
+ import { EyeFrameShape, DotShape, BorderShape, BorderStyle } from 'qr-code-generator';
341
+
342
+ // Eye shapes
343
+ EyeFrameShape.SQUARE
344
+ EyeFrameShape.SQUIRCLE
345
+
346
+ // Dot shapes
347
+ DotShape.CLASSIC
348
+ DotShape.DOTS
349
+ DotShape.SQUARE
350
+
351
+ // Border shapes
352
+ BorderShape.NONE
353
+ BorderShape.SQUARE
354
+ BorderShape.SQUIRCLE
355
+ BorderShape.CIRCLE
356
+
357
+ // Border styles
358
+ BorderStyle.SOLID
359
+ BorderStyle.DASHED
360
+ ```
361
+
362
+ ## Advanced Examples
363
+
364
+ ### Custom Styled QR Code
365
+
366
+ ```typescript
367
+ import { genQrImage, EyeFrameShape, DotShape, BorderShape } from 'qr-code-generator';
368
+
369
+ const styledQR = await genQrImage('https://tapple.io', {
370
+ size: 500,
371
+ margin: 30,
372
+ backgroundColor: '#f8f9fa',
373
+ eyes: {
374
+ shape: EyeFrameShape.SQUIRCLE,
375
+ color: '#0066ff'
376
+ },
377
+ pupils: {
378
+ color: '#ff6600'
379
+ },
380
+ dots: {
381
+ shape: DotShape.DOTS,
382
+ color: '#333333',
383
+ scale: 0.9
384
+ },
385
+ border: {
386
+ shape: BorderShape.SQUIRCLE,
387
+ width: 15,
388
+ color: '#0066ff',
389
+ style: 'solid'
390
+ },
391
+ output: { format: 'png', type: 'dataURL' }
392
+ });
393
+ ```
394
+
395
+ ### QR Code with Logo
396
+
397
+ ```typescript
398
+ import { genQrImage } from 'qr-code-generator';
399
+ import fs from 'fs';
400
+
401
+ // Load logo as data URL
402
+ const logoBuffer = fs.readFileSync('logo.png');
403
+ const logoDataURL = `data:image/png;base64,${logoBuffer.toString('base64')}`;
404
+
405
+ const qr = await genQrImage('https://tapple.io', {
406
+ size: 400,
407
+ logo: {
408
+ src: logoDataURL,
409
+ scale: 0.25 // Logo takes up 25% of QR width
410
+ },
411
+ output: { format: 'png', type: 'dataURL' }
412
+ });
413
+ ```
414
+
415
+ ## Browser Usage
416
+
417
+ ### Via Module Bundler (Recommended)
418
+
419
+ ```typescript
420
+ import { genQrImage } from 'qr-code-generator';
421
+
422
+ const qr = await genQrImage('https://tapple.io', {
423
+ output: { format: 'png', type: 'dataURL' }
424
+ });
425
+ document.querySelector('#qr-image').src = qr;
426
+ ```
427
+
428
+ ### Via CDN (ESM)
429
+
430
+ ```html
431
+ <script type="module">
432
+ import { genQrImage } from 'https://cdn.jsdelivr.net/npm/qr-code-generator/+esm';
433
+
434
+ const qr = await genQrImage('https://tapple.io', {
435
+ output: { format: 'png', type: 'dataURL' }
436
+ });
437
+ document.querySelector('#qr-image').src = qr;
438
+ </script>
439
+ ```
440
+
441
+ ## Technical Details
442
+
443
+ - **QR Versions**: Supports QR versions 1-10 (automatically selected based on input length)
444
+ - **Error Correction**: Levels L, M, Q, H (automatically optimized)
445
+ - **Encoding Modes**: Numeric, Alphanumeric, Byte (automatically detected)
446
+ - **Mask Patterns**: All 8 patterns with automatic penalty score optimization
447
+ - **Architecture**: SVG-first rendering with environment-specific raster conversion
448
+ - **Browser**: Uses native Canvas API for SVG→PNG conversion
449
+ - **Node.js**: Uses `@resvg/resvg-js` for high-quality SVG→PNG conversion
450
+
451
+ ## TypeScript Support
452
+
453
+ Full TypeScript support with comprehensive type definitions:
454
+
455
+ ```typescript
456
+ import type { ImageOptions, QRInput, VCardData, OutputConfig } from 'qr-code-generator';
457
+
458
+ const options: ImageOptions = {
459
+ size: 400,
460
+ backgroundColor: '#ffffff',
461
+ output: { format: 'svg', type: 'string' }
462
+ };
463
+
464
+ const input: QRInput = {
465
+ type: 'vcard',
466
+ data: { name: 'John Doe' }
467
+ };
468
+ ```
469
+
470
+ ## Performance
471
+
472
+ - **Small bundle size** - Zero browser dependencies means minimal footprint
473
+ - **Tree-shakeable** - Only import what you need with full ESM support
474
+ - **Efficient architecture** - SVG-first rendering with environment-specific raster conversion
475
+ - **No DOM dependency** - Works in Node.js, browsers, and Web Workers
476
+ - **Fast execution** - Optimized algorithms for matrix generation and mask selection
477
+
478
+ ## Contributing
479
+
480
+ Contributions are welcome! Please feel free to submit a Pull Request.
481
+
482
+ 1. Fork the repository
483
+ 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
484
+ 3. Commit your changes (`git commit -m 'Add amazing feature'`)
485
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
486
+ 5. Open a Pull Request
487
+
488
+ ## Development
489
+
490
+ ### Available Scripts
491
+
492
+ ```bash
493
+ # Building
494
+ npm run build # Full build (types + bundles)
495
+ npm run clean # Remove build artifacts
496
+
497
+ # Testing
498
+ npm test # Run all tests
499
+ npm run test:unit # Unit tests only
500
+ npm run test:integration # Integration tests only
501
+ npm run test:e2e # End-to-end scannability tests
502
+ npm run test:dist # Test built packages (requires build)
503
+ npm run test:fast # Skip slow e2e tests
504
+ npm run test:watch # Watch mode
505
+ npm run test:ui # Interactive test UI
506
+
507
+ # Demo
508
+ npm run demo # Build and serve interactive demo at localhost:8080
509
+
510
+ # Code Quality
511
+ npm run lint # Check code for issues
512
+ npm run lint:fix # Auto-fix linting issues
513
+ npm run format # Format code with Prettier
514
+ npm run format:check # Check formatting without changes
515
+ ```
516
+
517
+ ### Project Structure
518
+
519
+ ```
520
+ src/
521
+ ├── index.ts - Public API exports
522
+ ├── qrcode.ts - Render function implementations
523
+ ├── types.ts - Public type definitions
524
+ └── internal/ - Private implementation
525
+ ├── core/ - Constants, defaults, validation
526
+ ├── encoding/ - Data encoding & error correction
527
+ ├── matrix/ - QR matrix generation & masking
528
+ └── rendering/ - Output format renderers
529
+ ├── svg-renderer.ts - SVG generation
530
+ ├── ascii-renderer.ts - ASCII text output
531
+ ├── output-handler.ts - Output routing (SVG/PNG)
532
+ ├── svg-to-raster-browser.ts - Browser PNG converter (Canvas API)
533
+ └── svg-to-raster-node.ts - Node.js PNG converter (resvg)
534
+ ```
535
+
536
+ ## Testing
537
+
538
+ The library includes comprehensive test coverage:
539
+ - **Unit tests**: Core encoding, error correction, matrix generation
540
+ - **Integration tests**: Full pipeline rendering across all formats
541
+ - **E2E tests**: QR code scannability validation with dual decoders (jsQR + @nuintun/qrcode)
542
+ - **Distribution tests**: Validates built packages work in Node.js and browser environments
543
+
544
+ ## Interactive Demo
545
+
546
+ The demo showcases real-time QR code generation with all available options including colors, shapes, borders, logos, and more.
547
+
548
+ **Try it locally:**
549
+
550
+ ```bash
551
+ # Clone the repository
552
+ git clone https://github.com/tappleinc/qr-code-generator.git
553
+ cd qr-code-generator
554
+
555
+ # Install dependencies and run demo
556
+ npm install
557
+ npm run demo
558
+ ```
559
+
560
+ Then open [http://localhost:8080/demo/](http://localhost:8080/demo/) in your browser.
561
+
562
+ **Quick try without cloning:**
563
+
564
+ You can also experiment using online playgrounds like [CodeSandbox](https://codesandbox.io) or [StackBlitz](https://stackblitz.com) by creating a new project and installing `qr-code-generator`.
565
+
566
+ ## License
567
+
568
+ MIT © [Tapple Inc.](https://github.com/tappleinc)
569
+
570
+ ## Support
571
+
572
+ - 🐛 [Report Issues](https://github.com/tappleinc/qr-code-generator/issues)
573
+ - 📖 [View Documentation](https://github.com/tappleinc/qr-code-generator)
574
+ - 💬 Questions? Open an issue for discussion
575
+
576
+ ---
577
+
578
+ Made with ❤️ by [Tapple Inc.](https://tappleinc.com)
@@ -0,0 +1,29 @@
1
+ var j={L:[7,10,15,20,26,18,20,24,30,18],M:[10,16,26,18,24,16,18,22,22,26],Q:[13,22,18,26,18,24,18,22,20,24],H:[17,28,22,16,22,28,26,26,24,28]},M={L:[19,34,55,80,108,136,156,194,232,274],M:[16,28,44,64,86,108,124,154,182,216],Q:[13,22,34,48,62,76,88,110,132,154],H:[9,16,26,36,46,60,66,86,100,122]},Y={L:[[1,19,0,0],[1,34,0,0],[1,55,0,0],[1,80,0,0],[1,108,0,0],[2,68,0,0],[2,78,0,0],[2,97,0,0],[2,116,0,0],[2,68,2,69]],M:[[1,16,0,0],[1,28,0,0],[1,44,0,0],[2,32,0,0],[2,43,0,0],[4,27,0,0],[4,31,0,0],[2,38,2,39],[3,36,2,37],[4,43,1,44]],Q:[[1,13,0,0],[1,22,0,0],[2,17,0,0],[2,24,0,0],[2,15,2,16],[4,19,0,0],[2,14,4,15],[4,18,2,19],[4,16,4,17],[6,19,2,20]],H:[[1,9,0,0],[1,16,0,0],[2,13,0,0],[4,9,0,0],[2,11,2,12],[4,15,0,0],[4,13,1,14],[4,14,2,15],[4,12,4,13],[6,15,2,16]]},S="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:",ve={1:[10,12,14],2:[9,11,13],4:[8,16,16]},B={L:1,M:0,Q:3,H:2},P=[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50]],X=[31892,34236,39577,42195],Z=[0,7,7,7,7,7,0,0,0,0];function R(e){return e*4+17}function L(e,r){let t=r<10?0:r<27?1:2;return ve[e][t]}var K=(t=>(t.SQUARE="square",t.SQUIRCLE="squircle",t))(K||{}),J=(o=>(o.CLASSIC="classic",o.DOTS="dots",o.SQUARE="square",o))(J||{}),ee=(n=>(n.NONE="none",n.SQUARE="square",n.SQUIRCLE="squircle",n.CIRCLE="circle",n))(ee||{}),te=(t=>(t.SOLID="solid",t.DASHED="dashed",t))(te||{});function y(e,r){let t=r/2;return e<=-t?0:e>=t?255:Math.round((e+t)/r*255)}function F(e,r,t=.01){return y(r-e,t)}function ke(e,r,t,o){let n=Math.abs(e)-t+o,s=Math.abs(r)-t+o,a=Math.sqrt(Math.max(n,0)**2+Math.max(s,0)**2),i=Math.min(Math.max(n,s),0);return a+i-o}function Te(e,r){let n=r*3,s=r*2,a=n+s,i=Math.max(1,Math.round(e/a)),c=e/i,u=c*(3/5),l=c*(2/5),d=l/2;return{dashArray:`${u} ${l}`,offset:d}}function V(e,r){let t=r*3,o=r*2,n=t+o,s=Math.round(e/n);s=Math.round(s/4)*4,s=Math.max(4,s);let a=e/s,i=a*.6,c=a*.4,u=i/2;return{dashArray:`${i} ${c}`,offset:u}}function N(e,r,t,o,n){return n==="circle"?De(e,r,t,o):n==="squircle"?Be(e,r,t,o):Fe(e,r,t,o)}function De(e,r,t,o){let s=(Math.atan2(r,e)+Math.PI)/(2*Math.PI),a=t/2-o/2,i=2*Math.PI*a,c=o*3,u=o*2,l=Math.floor(i/(c+u)),d=l%2===0?l:l-1,f=Math.max(4,d);return s*f%1<.6}function Be(e,r,t,o){let s=t/2-o/2,a=t*z,i=Math.max(0,a-o/2),c=s-i,u=2*c,l=.5*Math.PI*i,d=4*u+4*l,f=Ne(e,r,c,i,u,l,d),{dashArray:m}=V(d,o),[h,g]=m.split(" ").map(Number),b=h+g;return(f+h/2)%b<h}function Ne(e,r,t,o,n,s,a){if(r<-t)if(e>t){let i=Math.atan2(r- -t,e-t)+Math.PI/2;return t+i*o}else if(e<-t){let i=Math.atan2(r- -t,e- -t)+Math.PI;return t+3*s+3*n+i*o}else return e>=0?e:a+e;else if(r>t)if(e>t){let i=Math.atan2(r-t,e-t);return t+s+n+i*o}else if(e<-t){let i=Math.atan2(r-t,e- -t)-Math.PI/2;return t+2*s+2*n+i*o}else return t+2*s+n+(t-e);else return e>t?t+s+(r- -t):e<-t?t+3*s+2*n+(t-r):e>=0?e:a+e}function Fe(e,r,t,o){let n=t/2,s=Math.abs(e),i=Math.abs(r)>=s?n+e:n+r,c=t-o,u=3,l=2,d=o*(u+l),f=Math.max(1,Math.round(c/d)),m=c/f,h=m*(u/(u+l)),b=(m-h)/2;return(i+b)%m<h}var z=.12,Ve={EYE_FRAME:.90909},E={square:{renderSVG(e,r,t,o){return`<rect x="${e}" y="${r}" width="${t}" height="${t}" fill="${o}"/>`},renderPixel(e,r,t,o){let n=t/2,s=o?.pixelSize??.01,a=Math.min(n-Math.abs(e),n-Math.abs(r));return y(a,s)}},squircle:{renderSVG(e,r,t,o){let n=t/2,s=n*Ve.EYE_FRAME,a=e+n,i=r+n;return`<path d="${`M${a},${i-n}
2
+ C${a+s},${i-n} ${a+n},${i-s} ${a+n},${i}
3
+ S${a+s},${i+n} ${a},${i+n}
4
+ S${a-n},${i+s} ${a-n},${i}
5
+ S${a-s},${i-n} ${a},${i-n}Z`}" fill="${o}"/>`},renderPixel(e,r,t,o){let n=t/2,s=o?.pixelSize??.01,a=4,i=Math.abs(e),c=Math.abs(r),u=i/n,l=c/n;if(i<.001&&c<.001)return 255;let d=Math.pow(u,a)+Math.pow(l,a),f=a/n*Math.sqrt(Math.pow(u,2*a-2)+Math.pow(l,2*a-2)),m=(1-d)/f;return y(m,s)}}},I={classic:{renderSVG(){return""},renderPixel(e,r,t,o){let n=t/2,s=o?.pixelSize??.01;if(t>=.99&&o&&o.qrcode&&o.row!==void 0&&o.col!==void 0){let{qrcode:i,row:c,col:u}=o,l=o.qrSize||i.length,d=u>0&&i[c][u-1],f=u<l-1&&i[c][u+1],m=c>0&&i[c-1][u],h=c<l-1&&i[c+1][u],g=d?1/0:n+e,b=f?1/0:n-e,$=m?1/0:n+r,C=h?1/0:n-r,D=Math.min(Math.min(g,b),Math.min($,C));return y(D,s)}let a=Math.min(n-Math.abs(e),n-Math.abs(r));return y(a,s)}},dots:{renderSVG(e,r,t,o){let n=e+t/2,s=r+t/2,a=t*.35;return`<circle cx="${n}" cy="${s}" r="${a}" fill="${o}"/>`},renderPixel(e,r,t,o){let n=t*.35,s=o?.pixelSize??.01,a=Math.sqrt(e*e+r*r);return F(a,n,s)}},square:{renderSVG(e,r,t,o){let n=t*.7,s=(t-n)/2,a=e+s,i=r+s;return`<rect x="${a}" y="${i}" width="${n}" height="${n}" fill="${o}"/>`},renderPixel(e,r,t,o){let s=t*.7/2,a=o?.pixelSize??.01,i=Math.min(s-Math.abs(e),s-Math.abs(r));return y(i,a)}}},v={square:{getDiagonalFactor(){return Math.sqrt(2)},renderSVG(e,r,t,o,n){let s=n?.borderWidth??1;if((n?.borderStyle??"solid")==="dashed"){let f=s/2,m=t-s,{dashArray:h,offset:g}=Te(m,s);return`<rect x="${e+f}" y="${r+f}" width="${m}" height="${m}" fill="none" stroke="${o}" stroke-width="${s}" stroke-dasharray="${h}" stroke-dashoffset="${-g}"/>`}let i=`M${e},${r}h${t}v${t}h${-t}z`,c=e+s,u=r+s,l=t-s*2,d=`M${c},${u}h${l}v${l}h${-l}z`;return`<path d="${i} ${d}" fill="${o}" fill-rule="evenodd"/>`},renderPixel(e,r,t,o){let n=o?.borderWidth??1,s=o?.borderStyle??"solid",a=o?.pixelSize??.01,i=t/2,c=i-n,u=i-Math.abs(e),l=i-Math.abs(r),d=c-Math.abs(e),f=c-Math.abs(r),m=Math.min(u,l),h=Math.min(d,f);if(m>=0&&h<=0){if(s==="dashed"&&!N(e,r,t,n,"square"))return 0;let g=y(m,a),b=255-y(h,a);return Math.min(g,b)}return 0}},squircle:{getDiagonalFactor(){return Math.pow(2,.25)},renderSVG(e,r,t,o,n){let s=n?.borderWidth??1,a=n?.borderStyle??"solid",i=t/2,c=e+i,u=r+i,l=i-s/2,d=t*z,f=Math.max(0,d-s/2),m=l-f,h=`M${c},${u-l}
6
+ H${c+m}
7
+ A${f},${f} 0 0 1 ${c+l},${u-m}
8
+ V${u+m}
9
+ A${f},${f} 0 0 1 ${c+m},${u+l}
10
+ H${c-m}
11
+ A${f},${f} 0 0 1 ${c-l},${u+m}
12
+ V${u-m}
13
+ A${f},${f} 0 0 1 ${c-m},${u-l}
14
+ Z`;if(a==="dashed"){let g=2*m,b=.5*Math.PI*f,$=4*g+4*b,{dashArray:C,offset:D}=V($,s);return`<path d="${h}" fill="none" stroke="${o}" stroke-width="${s}" stroke-dasharray="${C}" stroke-dashoffset="${D}"/>`}return`<path d="${h}" fill="none" stroke="${o}" stroke-width="${s}"/>`},renderPixel(e,r,t,o){let n=o?.borderWidth??1,s=o?.borderStyle??"solid",a=o?.pixelSize??.01,c=t/2-n/2,u=t*z,l=Math.max(0,u-n/2),d=Math.abs(ke(e,r,c,l)),f=n/2-d;return f>-a?s==="dashed"&&!N(e,r,t,n,"squircle")?0:y(f,a):0}},circle:{getDiagonalFactor(){return 1},renderSVG(e,r,t,o,n){let s=n?.borderWidth??1,a=n?.borderStyle??"solid",i=e+t/2,c=r+t/2,u=t/2;if(a==="dashed"){let m=u-s/2,h=2*Math.PI*m,{dashArray:g,offset:b}=V(h,s);return`<circle cx="${i}" cy="${c}" r="${m}" fill="none" stroke="${o}" stroke-width="${s}" stroke-dasharray="${g}" stroke-dashoffset="${b}"/>`}let l=u-s,d=`M${i},${c-u}
15
+ A${u},${u} 0 1,1 ${i},${c+u}
16
+ A${u},${u} 0 1,1 ${i},${c-u}Z`,f=`M${i},${c-l}
17
+ A${l},${l} 0 1,0 ${i},${c+l}
18
+ A${l},${l} 0 1,0 ${i},${c-l}Z`;return`<path d="${d} ${f}" fill="${o}" fill-rule="evenodd"/>`},renderPixel(e,r,t,o){let n=o?.borderWidth??1,s=o?.borderStyle??"solid",a=o?.pixelSize??.01,i=t/2,c=i-n,u=Math.sqrt(e*e+r*r);if(u<=i&&u>=c){if(s==="dashed"&&!N(e,r,t,n,"circle"))return 0;let l=F(u,i,a),d=255-F(u,c,a);return Math.min(l,d)}return 0}}};var w=class extends Error{constructor(r){let t=r.map(o=>` - ${o.field}: ${o.message}`).join(`
19
+ `);super(`QR Code validation failed:
20
+ ${t}`),this.name="QRValidationError",this.errors=r}};function x(e,r,t,o,n=!1){return typeof e!="number"||!isFinite(e)?{field:r,value:e,message:"must be a finite number"}:n&&!Number.isInteger(e)?{field:r,value:e,message:"must be an integer"}:e<t?{field:r,value:e,message:`must be at least ${t}`}:o!==null&&e>o?{field:r,value:e,message:`must be at most ${o}`}:null}function O(e,r){return typeof e!="string"?{field:r,value:e,message:"must be a string"}:/^#[0-9A-Fa-f]{6}$/.test(e)?null:{field:r,value:e,message:"must be a valid hex color (e.g., #000000)"}}function _(e,r,t){if(typeof e!="string")return{field:r,value:e,message:"must be a string"};if(!(e in t)){let o=Object.keys(t).join(", ");return{field:r,value:e,message:`must be one of: ${o}`}}return null}function re(e){let r=[];if(e.size!==void 0){let t=x(e.size,"size",21,null,!0);t&&r.push(t)}if(e.margin!==void 0){let t=x(e.margin,"margin",0,null,!0);t&&r.push(t)}if(e.backgroundColor!==void 0){let t=O(e.backgroundColor,"backgroundColor");t&&r.push(t)}if(e.eyes?.shape!==void 0){let t=_(e.eyes.shape,"eyes.shape",E);t&&r.push(t)}if(e.eyes?.color!==void 0){let t=O(e.eyes.color,"eyes.color");t&&r.push(t)}if(e.pupils?.color!==void 0){let t=O(e.pupils.color,"pupils.color");t&&r.push(t)}if(e.dots?.shape!==void 0){let t=_(e.dots.shape,"dots.shape",I);t&&r.push(t)}if(e.dots?.color!==void 0){let t=O(e.dots.color,"dots.color");t&&r.push(t)}if(e.dots?.scale!==void 0){let t=x(e.dots.scale,"dots.scale",.75,1.25,!1);t&&r.push(t)}if(e.border?.shape!==void 0&&e.border.shape!=="none"){let t=_(e.border.shape,"border.shape",v);t&&r.push(t)}if(e.border?.width!==void 0){let t=x(e.border.width,"border.width",0,null,!0);t&&r.push(t)}if(e.border?.color!==void 0){let t=O(e.border.color,"border.color");t&&r.push(t)}if(e.border?.style!==void 0&&(typeof e.border.style!="string"||e.border.style!=="solid"&&e.border.style!=="dashed")&&r.push({field:"border.style",value:e.border.style,message:'must be either "solid" or "dashed"'}),e.logo&&((!e.logo.src||typeof e.logo.src!="string")&&r.push({field:"logo.src",value:e.logo.src,message:"must be a non-empty string"}),e.logo.scale!==void 0)){let t=x(e.logo.scale,"logo.scale",.1,.3,!1);t&&r.push(t)}if(r.length>0)throw new w(r)}function ne(e){let r=[];if(e.margin!==void 0){let t=x(e.margin,"margin",0,null,!0);t&&r.push(t)}if(e.darkChar!==void 0&&typeof e.darkChar!="string"&&r.push({field:"darkChar",value:e.darkChar,message:"must be a string"}),e.lightChar!==void 0&&typeof e.lightChar!="string"&&r.push({field:"lightChar",value:e.lightChar,message:"must be a string"}),r.length>0)throw new w(r)}var p={size:300,margin:24,backgroundColor:"#ffffff",eyes:{shape:"square",color:"#000000"},pupils:{color:"#000000"},dots:{shape:"classic",color:"#000000",scale:1},logo:{scale:.2},border:{shape:"none",width:10,color:"#000000",style:"solid"},output:{format:"png",type:"buffer"}},k={margin:2,darkChar:"\u2588\u2588",lightChar:" "};function oe(e){if(!e){let{logo:t,...o}=p;return o}return re(e),{size:e.size??p.size,margin:e.margin??p.margin,backgroundColor:e.backgroundColor??p.backgroundColor,eyes:{shape:e.eyes?.shape??p.eyes.shape,color:e.eyes?.color??p.eyes.color},pupils:{color:e.pupils?.color??p.pupils.color},dots:{shape:e.dots?.shape??p.dots.shape,color:e.dots?.color??p.dots.color,scale:e.dots?.scale??p.dots.scale},logo:e.logo?{src:e.logo.src,scale:e.logo.scale??p.logo.scale}:void 0,border:{shape:e.border?.shape??p.border.shape,width:e.border?.width??p.border.width,color:e.border?.color??p.border.color,style:e.border?.style??p.border.style},output:e.output??p.output}}function se(e){return e?(ne(e),{margin:e.margin??k.margin,darkChar:e.darkChar??k.darkChar,lightChar:e.lightChar??k.lightChar}):{...k}}function ae(e){return/^\d+$/.test(e)?1:[...e].every(r=>S.includes(r))?2:4}function ze(e){let r=[];for(let t=0;t<e.length;t+=3){let o=e.substring(t,Math.min(t+3,e.length)),n=parseInt(o,10),s=o.length===3?10:o.length===2?7:4;for(let a=s-1;a>=0;a--)r.push(n>>a&1)}return r}function _e(e){let r=[];for(let t=0;t<e.length;t+=2)if(t+1<e.length){let o=S.indexOf(e[t])*45+S.indexOf(e[t+1]);for(let n=10;n>=0;n--)r.push(o>>n&1)}else{let o=S.indexOf(e[t]);for(let n=5;n>=0;n--)r.push(o>>n&1)}return r}function qe(e){let r=[],t=new TextEncoder().encode(e);for(let o of t)for(let n=7;n>=0;n--)r.push(o>>n&1);return r}function Qe(e,r,t,o){let n=[];for(let a=3;a>=0;a--)n.push(r>>a&1);let s=L(r,o);for(let a=s-1;a>=0;a--)n.push(t>>a&1);return[...n,...e]}function Ue(e){let r=[];for(let t=0;t<e.length;t+=8){let o=0;for(let n=0;n<8&&t+n<e.length;n++)o=o<<1|e[t+n];t+8>e.length&&(o<<=8-e.length%8),r.push(o)}return r}function Ge(e,r){let t=[...e],o=[236,17],n=0;for(;t.length<r;)t.push(o[n]),n=1-n;return t}function ie(e,r,t){let o=ae(e),n,s;o===1?(n=ze(e),s=e.length):o===2?(n=_e(e),s=e.length):(n=qe(e),s=new TextEncoder().encode(e).length);let a=Qe(n,o,s,r),i=Math.min(4,t*8-a.length);for(let u=0;u<i;u++)a.push(0);for(;a.length%8!==0;)a.push(0);let c=Ue(a);return Ge(c,t)}function T(e,r){let t=ae(e),o=t===4?new TextEncoder().encode(e).length:e.length;for(let c=1;c<=10;c++){let u=L(t,c),l=t===1?Math.ceil(o/3)*10-(o%3===1?6:o%3===2?3:0):t===2?Math.floor(o/2)*11+o%2*6:o*8,d=4+u+l;if(Math.ceil(d/8)<=r[c-1])return c}let n=L(t,10),s=t===1?Math.ceil(o/3)*10-(o%3===1?6:o%3===2?3:0):t===2?Math.floor(o/2)*11+o%2*6:o*8,a=4+n+s,i=Math.ceil(a/8);throw new Error(`Input too long for QR code version 10. Required capacity: ${i} bytes, Maximum available: ${r[9]} bytes. Current data length: ${e.length} characters (${o} bytes encoded).`)}function ce(e,r){if(r)try{if(T(e,M.H)<=10)return"H"}catch{throw new Error(`Data too large for QR code with logo. Data length: ${e.length} characters. Maximum capacity with logo (EC level H): ~122 bytes (version 10). Logos require high error correction (H) which reduces data capacity. Consider: reducing data length, removing logo, or using multiple QR codes.`)}let t=["H","Q","M","L"];for(let o of t)try{if(T(e,M[o])<=10)return o}catch{continue}throw new Error(`Data too large for QR code version 10 at any error correction level. Data length: ${e.length} characters. Maximum capacity: ~274 bytes (version 10, EC level L). Please reduce input length or split into multiple QR codes.`)}var A=new Array(256),q=new Array(256);function We(){let e=1;for(let r=0;r<255;r++)A[r]=e,q[e]=r,e<<=1,e&256&&(e^=285);for(let r=255;r<512;r++)A[r]=A[r-255]}We();function le(e,r){return e===0||r===0?0:A[q[e]+q[r]]}function He(e){let r=[1];for(let t=0;t<e;t++){let o=r.length+1,n=new Array(o).fill(0);for(let s=0;s<r.length;s++)n[s]^=r[s],n[s+1]^=le(r[s],A[t]);r=n}return r}function ue(e,r){let t=He(r),o=[...e,...new Array(r).fill(0)];for(let n=0;n<e.length;n++){let s=o[n];if(s!==0)for(let a=0;a<t.length;a++)o[n+a]^=le(t[a],s)}return o.slice(e.length)}function fe(e,r,t){let o=[],n=[],[s,a,i,c]=t,u=0;for(let l=0;l<s;l++){let d=e.slice(u,u+a);o.push(d);let f=ue(d,r);n.push(f),u+=a}for(let l=0;l<i;l++){let d=e.slice(u,u+c);o.push(d);let f=ue(d,r);n.push(f),u+=c}return{dataBlocks:o,ecBlocks:n}}function de(e,r){let t=[],o=Math.max(...e.map(s=>s.length));for(let s=0;s<o;s++)for(let a of e)s<a.length&&t.push(a[s]);let n=Math.max(...r.map(s=>s.length));for(let s=0;s<n;s++)for(let a of r)s<a.length&&t.push(a[s]);return t}function me(e){let r=R(e);return Array.from({length:r},()=>Array(r).fill(!1))}function he(e){let r=R(e),t=Array.from({length:r},()=>Array(r).fill(!1));for(let n=0;n<=7;n++)for(let s=0;s<=7;s++)t[n][s]=!0;for(let n=0;n<=7;n++)for(let s=0;s<=7;s++)t[n][r-8+s]=!0;for(let n=0;n<=7;n++)for(let s=0;s<=7;s++)t[r-8+n][s]=!0;for(let n=8;n<r-8;n++)t[6][n]=!0,t[n][6]=!0;t[4*e+9][8]=!0;for(let n=0;n<6;n++)t[n][8]=!0;t[7][8]=!0,t[8][8]=!0;for(let n=r-8;n<r;n++)t[n][8]=!0;for(let n=0;n<9;n++)t[8][n]=!0;for(let n=r-8;n<r;n++)t[8][n]=!0;let o=P[e-1]||[];for(let n of o)for(let s of o)if(!(n<9&&s<9||n<9&&s>r-9||n>r-9&&s<9))for(let i=-2;i<=2;i++)for(let c=-2;c<=2;c++)t[n+i][s+c]=!0;if(e>=7){for(let n=0;n<6;n++)for(let s=r-11;s<r-8;s++)t[n][s]=!0;for(let n=r-11;n<r-8;n++)for(let s=0;s<6;s++)t[n][s]=!0}return t}function Q(e,r,t){for(let o=-1;o<=7;o++)for(let n=-1;n<=7;n++){let s=r+o,a=t+n;if(s<0||s>=e.length||a<0||a>=e.length)continue;let i=o>=0&&o<=6&&n>=0&&n<=6&&(o===0||o===6||n===0||n===6),c=o>=2&&o<=4&&n>=2&&n<=4;e[s][a]=i||c}}function je(e,r,t){for(let o=-2;o<=2;o++)for(let n=-2;n<=2;n++){let s=o===-2||o===2||n===-2||n===2,a=o===0&&n===0;e[r+o][t+n]=s||a}}function ge(e){let r=e.length;for(let t=8;t<r-8;t++)e[6][t]=t%2===0,e[t][6]=t%2===0}function be(e){Q(e,0,0),Q(e,0,e.length-7),Q(e,e.length-7,0)}function pe(e,r){let t=e.length,o=P[r-1]||[];for(let n of o)for(let s of o)n<9&&s<9||n<9&&s>t-9||n>t-9&&s<9||je(e,n,s)}function $e(e,r){e[4*r+9][8]=!0}function Ce(e,r,t){let o=e.length,n=0,s=-1,a=o-1;for(let i=o-1;i>0;i-=2)for(i===6&&i--;;){for(let c=0;c<2;c++)if(!r[a][i-c]){let u=n<t.length?t[n]:!1;e[a][i-c]=u,n++}if(a+=s,a<0||o<=a){a-=s,s=-s;break}}}function U(e,r,t){let o=e.length;for(let n=0;n<o;n++)for(let s=0;s<o;s++){if(r[n][s])continue;let a=!1;switch(t){case 0:a=(n+s)%2===0;break;case 1:a=n%2===0;break;case 2:a=s%3===0;break;case 3:a=(n+s)%3===0;break;case 4:a=(Math.floor(n/2)+Math.floor(s/3))%2===0;break;case 5:a=n*s%2+n*s%3===0;break;case 6:a=(n*s%2+n*s%3)%2===0;break;case 7:a=((n+s)%2+n*s%3)%2===0;break}a&&(e[n][s]=!e[n][s])}}function Ye(e){let r=e.length,t=0;for(let a=0;a<r;a++){let i=e[a][0],c=e[0][a],u=1,l=1;for(let d=1;d<r;d++)e[a][d]===i?u++:(u>=5&&(t+=3+(u-5)),i=e[a][d],u=1),e[d][a]===c?l++:(l>=5&&(t+=3+(l-5)),c=e[d][a],l=1);u>=5&&(t+=3+(u-5)),l>=5&&(t+=3+(l-5))}for(let a=0;a<r-1;a++)for(let i=0;i<r-1;i++){let c=e[a][i];e[a][i+1]===c&&e[a+1][i]===c&&e[a+1][i+1]===c&&(t+=3)}for(let a=0;a<r;a++){let i=0,c=0;for(let u=0;u<r;u++)i=i<<1&2047|(e[a][u]?1:0),u>=10&&(i===1488||i===93)&&(t+=40),c=c<<1&2047|(e[u][a]?1:0),u>=10&&(c===1488||c===93)&&(t+=40)}let o=0,n=r*r;for(let a=0;a<r;a++)for(let i=0;i<r;i++)e[a][i]&&o++;let s=Math.abs(Math.ceil(o*100/n/5)-10);return t+=s*10,t}function ye(e,r,t,o){let n=0,s=1/0;for(let a=0;a<8;a++){let i=e.map(u=>[...u]);U(i,r,a),o(i,t,a);let c=Ye(i);c<s&&(s=c,n=a)}return n}function G(e,r,t){let o=e.length,n=B[r]<<3|t,s=n<<10;for(let i=0;i<5;i++)s&1<<14-i&&(s^=1335<<4-i);let a=(n<<10|s)^21522;for(let i=0;i<15;i++){let c=(a>>14-i&1)===1;i<=5?e[8][i]=c:i===6?e[8][7]=c:i===7?e[8][8]=c:i===8?e[7][8]=c:e[5-(i-9)][8]=c,i<=6?e[o-1-i][8]=c:e[8][o-8+(i-7)]=c}}function Me(e,r){if(r<7)return;let t=e.length,o=X[r-7];for(let n=0;n<18;n++){let s=(o>>n&1)===1,a=Math.floor(n/3),i=t-11+n%3;e[a][i]=s;let c=t-11+n%3,u=Math.floor(n/3);e[c][u]=s}}function xe(e,r){return B[e]<<3|r}function Se(e,r,t,o,n){let s=me(e),a=he(e);be(s),ge(s),pe(s,e),$e(s,e),Ce(s,a,t);let i=n?s.map(u=>[...u]):void 0,c=o??ye(s,a,r,G);return U(s,a,c),G(s,r,c),Me(s,e),{matrix:s,mask:c,formatInfo:n?xe(r,c):void 0,unmaskedMatrix:i}}function W(e,r,t){return e<7&&r<7||e<7&&r>=t-7||e>=t-7&&r<7}function Re(e){return[{x:0,y:0},{x:e-7,y:0},{x:0,y:e-7}]}function Ee(e,r){let o=Math.max(.1,Math.min(.3,r));return e*o}function Xe(e,r,t,o,n,s,a){let i=E[t]||E.square,c=i.renderSVG(e,r,7*a,o),u=i.renderSVG(e+a,r+a,5*a,s),l=i.renderSVG(e+2*a,r+2*a,3*a,n);return c+u+l}function Ze(e,r,t,o){let n=o/2;if(e.includes("data:image/svg")||e.trim().startsWith("<svg")){let s=e;if(e.includes("data:image/svg")){let u=e.match(/data:image\/svg\+xml[^,]*,(.+)/);if(u)try{s=decodeURIComponent(u[1])}catch{return""}}let a=s.match(/viewBox=["']([^"']+)["']/),i=a?a[1]:"0 0 100 100",c=s.replace(/<\?xml[^>]*>|<svg[^>]*>|<\/svg>/gi,"");return`<g transform="translate(${r-n}, ${t-n})">
21
+ <svg width="${o}" height="${o}" viewBox="${i}">
22
+ ${c}
23
+ </svg>
24
+ </g>`}else return`<image x="${r-n}" y="${t-n}" width="${o}" height="${o}" href="${e}" preserveAspectRatio="xMidYMid meet"/>`}function Ke(e,r,t,o,n){let s=e.matrixSize,a="",i=I[t]||I.classic;if(t==="classic"){a=`<path fill="${o}" d="`;for(let c=0;c<s;c++)for(let u=0;u<s;u++)if(e.modules[c][u]&&!W(c,u,s)){let l=u*r,d=c*r,f=n*r,m=(1-n)*r/2,h=l+m,g=d+m;a+=`M${h},${g}h${f}v${f}h${-f}z`}return a+='"/>',a}for(let c=0;c<s;c++)for(let u=0;u<s;u++)if(e.modules[c][u]&&!W(c,u,s)){let l=u*r,d=c*r,f=n*r,m=(1-n)*r/2,h=l+m,g=d+m,b={qrcode:e.modules,qrSize:s,row:c,col:u};a+=i.renderSVG(h,g,f,o,b)}return a}function Ie(e,r){let{size:t,margin:o,backgroundColor:n,eyes:s,pupils:a,dots:i}=r,c=t/e.matrixSize,u=r.border.shape==="none"?0:r.border.width,l=t+2*o+2*u,d=o+u,f=`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${l} ${l}" width="${l}" height="${l}">`;if(f+=`<rect width="${l}" height="${l}" fill="${n}"/>`,r.border.shape!=="none"&&u>0){let $=v[r.border.shape];if($){let C={borderWidth:u,borderStyle:r.border.style};f+=$.renderSVG(0,0,l,r.border.color,C)}}r.border.shape!=="none"&&u>0&&(f+=`<rect x="${d}" y="${d}" width="${t}" height="${t}" fill="${n}"/>`),f+=`<g transform="translate(${d}, ${d})">`;let m=Re(e.matrixSize),h="";for(let $ of m)h+=Xe($.x*c,$.y*c,s.shape,s.color,a.color,n,c);let g=Ke(e,c,i.shape,i.color,i.scale);f+=h+g+"</g>";let b="";if(r.logo){let $=Ee(e.matrixSize,r.logo.scale)*c,C=l/2;b=Ze(r.logo.src,C,C,$)}return f+=b+"</svg>",f}function Oe(e,r){let{margin:t,lightChar:o,darkChar:n}=r,s="",a=e.matrixSize+t*2;for(let i=0;i<t;i++)s+=o.repeat(a)+`
25
+ `;for(let i=0;i<e.matrixSize;i++){s+=o.repeat(t);for(let c=0;c<e.matrixSize;c++)s+=e.modules[i][c]?n:o;s+=o.repeat(t)+`
26
+ `}for(let i=0;i<t;i++)s+=o.repeat(a)+`
27
+ `;return s}async function we(e,r){let{output:t,size:o,margin:n,border:s}=r,a=s.shape==="none"?0:s.width,i=o+2*n+2*a;return new Promise((c,u)=>{let l=document.createElement("canvas");l.width=i,l.height=i;let d=l.getContext("2d");if(!d){u(new Error("Failed to get canvas context"));return}let f=new Image,m=null;try{let h=new Blob([e],{type:"image/svg+xml;charset=utf-8"});m=URL.createObjectURL(h)}catch{u(new Error("Failed to create SVG blob for rasterization"));return}f.onload=()=>{if(m&&URL.revokeObjectURL(m),d.drawImage(f,0,0,i,i),t.type==="dataURL"){let h=l.toDataURL("image/png");c(h)}else l.toBlob(h=>{if(!h){u(new Error("Failed to convert PNG to blob"));return}h.arrayBuffer().then(g=>{c(new Uint8Array(g))})},"image/png")},f.onerror=()=>{m&&URL.revokeObjectURL(m),u(new Error("Failed to load SVG for rasterization"))},f.src=m})}async function Ae(e,r){let{format:t,type:o}=r.output;return t==="svg"?o==="string"?e:`data:image/svg+xml;charset=utf-8,${encodeURIComponent(e)}`:await we(e,r)}function H(e){if(typeof e=="string")return e;switch(e.type){case"url":return Je(e.url);case"vcard":return et(e.data);case"wifi":return tt(e.data);case"calendar":return rt(e.data);case"email":return nt(e.email,e.subject,e.body);case"sms":return ot(e.phone,e.message);case"phone":return st(e.phone)}}function Je(e){return!e.startsWith("http://")&&!e.startsWith("https://")?`https://${e}`:e}function et(e){let r=["BEGIN:VCARD","VERSION:3.0",`FN:${e.name}`];if(e.phone&&r.push(`TEL:${e.phone}`),e.email&&r.push(`EMAIL:${e.email}`),e.organization&&r.push(`ORG:${e.organization}`),e.url&&r.push(`URL:${e.url}`),e.title&&r.push(`TITLE:${e.title}`),e.note&&r.push(`NOTE:${e.note}`),e.address){let{street:t,city:o,state:n,zip:s,country:a}=e.address,i=["","",t||"",o||"",n||"",s||"",a||""];r.push(`ADR:${i.join(";")}`)}return r.push("END:VCARD"),r.join(`
28
+ `)}function tt(e){let r=e.encryption||"WPA",t=e.hidden?"H:true;":"",o=Pe(e.ssid),n=Pe(e.password);return`WIFI:T:${r};S:${o};P:${n};${t};`}function Pe(e){return e.replace(/([\\;,":])/g,"\\$1")}function rt(e){let r=o=>(typeof o=="string"?new Date(o):o).toISOString().replace(/[-:]/g,"").split(".")[0]+"Z",t=["BEGIN:VCALENDAR","VERSION:2.0","BEGIN:VEVENT",`SUMMARY:${e.title}`,`DTSTART:${r(e.startDate)}`,`DTEND:${r(e.endDate)}`];return e.location&&t.push(`LOCATION:${e.location}`),e.description&&t.push(`DESCRIPTION:${e.description}`),t.push("END:VEVENT","END:VCALENDAR"),t.join(`
29
+ `)}function nt(e,r,t){let o=`mailto:${e}`,n=[];return r&&n.push(`subject=${encodeURIComponent(r)}`),t&&n.push(`body=${encodeURIComponent(t)}`),n.length>0&&(o+=`?${n.join("&")}`),o}function ot(e,r){return r?`sms:${e}:${r}`:`sms:${e}`}function st(e){return`tel:${e}`}function at(e,r){let t=[];for(let n of e)for(let s=7;s>=0;s--)t.push((n>>s&1)===1);let o=Z[r-1];for(let n=0;n<o;n++)t.push(!1);return t}function Le(e,r){if(!e)throw new Error("QR Code input cannot be empty. Please provide text or structured content to encode.");let t=ce(e,r),o=M[t],n=T(e,o);if(n<1||n>10)throw new Error(`Input data is too large for QR code version 10. Data length: ${e.length} characters. Maximum capacity at EC level ${t}: ~${M[t][9]} bytes. Try reducing input length or removing logo for higher capacity.`);let s=ie(e,n,o[n-1]),a=j[t][n-1],i=Y[t][n-1],{dataBlocks:c,ecBlocks:u}=fe(s,a,i),l=de(c,u),d=at(l,n),{matrix:f,mask:m}=Se(n,t,d);return{version:n,matrixSize:R(n),modules:f,mask:m,errorCorrectionLevel:t}}async function it(e,r){let t=H(e),o=oe(r),n=Le(t,!!o.logo),s=Ie(n,o);return await Ae(s,o)}function ct(e,r){let t=H(e),o=se(r),n=Le(t,!1);return Oe(n,o)}export{ee as BorderShape,te as BorderStyle,J as DotShape,K as EyeFrameShape,w as QRValidationError,it as genQrImage,ct as genQrText};
@@ -0,0 +1,230 @@
1
+ // Generated by dts-bundle-generator v9.5.1
2
+
3
+ /**
4
+ * Public API Type Definitions
5
+ *
6
+ * This file contains all types, interfaces, and enums that are part of the public API.
7
+ * Internal types used only within the library are in internal/core/types.ts
8
+ */
9
+ /**
10
+ * Eye frame (outer 7x7 position marker) shape options
11
+ */
12
+ export declare enum EyeFrameShape {
13
+ SQUARE = "square",
14
+ SQUIRCLE = "squircle"
15
+ }
16
+ /**
17
+ * Data dot (module) shape options
18
+ */
19
+ export declare enum DotShape {
20
+ CLASSIC = "classic",
21
+ DOTS = "dots",
22
+ SQUARE = "square"
23
+ }
24
+ /**
25
+ * Border shape options
26
+ */
27
+ export declare enum BorderShape {
28
+ NONE = "none",
29
+ SQUARE = "square",
30
+ SQUIRCLE = "squircle",
31
+ CIRCLE = "circle"
32
+ }
33
+ /**
34
+ * Border style options
35
+ */
36
+ export declare enum BorderStyle {
37
+ SOLID = "solid",
38
+ DASHED = "dashed"
39
+ }
40
+ /**
41
+ * vCard contact information
42
+ */
43
+ export interface VCardData {
44
+ /** Full name (required) */
45
+ name: string;
46
+ /** Phone number */
47
+ phone?: string;
48
+ /** Email address */
49
+ email?: string;
50
+ /** Organization/company name */
51
+ organization?: string;
52
+ /** Website URL */
53
+ url?: string;
54
+ /** Postal address */
55
+ address?: {
56
+ street?: string;
57
+ city?: string;
58
+ state?: string;
59
+ zip?: string;
60
+ country?: string;
61
+ };
62
+ /** Job title */
63
+ title?: string;
64
+ /** Notes/additional info */
65
+ note?: string;
66
+ }
67
+ /**
68
+ * WiFi network credentials
69
+ */
70
+ export interface WiFiData {
71
+ /** Network SSID (name) */
72
+ ssid: string;
73
+ /** Network password */
74
+ password: string;
75
+ /** Encryption type (default: 'WPA') */
76
+ encryption?: "WPA" | "WPA2" | "WEP" | "nopass";
77
+ /** Whether network is hidden (default: false) */
78
+ hidden?: boolean;
79
+ }
80
+ /**
81
+ * Calendar event data
82
+ */
83
+ export interface CalendarData {
84
+ /** Event title (required) */
85
+ title: string;
86
+ /** Event start date/time */
87
+ startDate: Date | string;
88
+ /** Event end date/time */
89
+ endDate: Date | string;
90
+ /** Event location */
91
+ location?: string;
92
+ /** Event description */
93
+ description?: string;
94
+ }
95
+ /**
96
+ * QR Code input - accepts either raw string or structured content types
97
+ */
98
+ export type QRInput = string | {
99
+ type: "url";
100
+ url: string;
101
+ } | {
102
+ type: "vcard";
103
+ data: VCardData;
104
+ } | {
105
+ type: "wifi";
106
+ data: WiFiData;
107
+ } | {
108
+ type: "calendar";
109
+ data: CalendarData;
110
+ } | {
111
+ type: "email";
112
+ email: string;
113
+ subject?: string;
114
+ body?: string;
115
+ } | {
116
+ type: "sms";
117
+ phone: string;
118
+ message?: string;
119
+ } | {
120
+ type: "phone";
121
+ phone: string;
122
+ };
123
+ /**
124
+ * Output format and type configuration
125
+ * Uses union type to prevent invalid combinations
126
+ */
127
+ export type OutputConfig = {
128
+ format: "png";
129
+ type: "dataURL" | "buffer";
130
+ } | {
131
+ format: "svg";
132
+ type: "dataURL" | "string";
133
+ };
134
+ /**
135
+ * Image-based rendering options for PNG and SVG (public API)
136
+ * All fields are optional - unspecified values use defaults from internal/core/defaults.ts
137
+ */
138
+ export interface ImageOptions {
139
+ /** QR code matrix size in pixels (default: 300) - margin and border are added to this */
140
+ size?: number;
141
+ /** Margin around QR code in pixels (default: 24) */
142
+ margin?: number;
143
+ /** Background color in hex format (default: '#ffffff') */
144
+ backgroundColor?: string;
145
+ /** Eye (outer frame) styling */
146
+ eyes?: {
147
+ /** Eye frame shape (default: 'square') */
148
+ shape?: EyeFrameShape;
149
+ /** Eye frame color in hex format (default: '#000000') */
150
+ color?: string;
151
+ };
152
+ /** Pupil (inner core) styling */
153
+ pupils?: {
154
+ /** Pupil color in hex format (default: '#000000') */
155
+ color?: string;
156
+ };
157
+ /** Data dot (module) styling */
158
+ dots?: {
159
+ /** Data dot shape (default: 'classic') */
160
+ shape?: DotShape;
161
+ /** Data dot color in hex format (default: '#000000') */
162
+ color?: string;
163
+ /** Data dot scale (0.75 to 1.25, default: 1.0) - adjusts visual size of dots while keeping overall dimensions fixed */
164
+ scale?: number;
165
+ };
166
+ /** Logo image to place in center of QR code (jpg, png, svg, or webp) */
167
+ logo?: {
168
+ /** Image source - data URL (recommended) or raw SVG string */
169
+ src: string;
170
+ /** Logo scale as percentage of QR code width (0-1, default: 0.2 = 20%, max: 0.3 = 30%) */
171
+ scale?: number;
172
+ };
173
+ /** Border styling (surrounds margin area) */
174
+ border?: {
175
+ /** Border shape (default: 'none') */
176
+ shape?: BorderShape;
177
+ /**
178
+ * Border width in pixels (default: 10)
179
+ * Total output size = size + 2×margin + 2×width
180
+ */
181
+ width?: number;
182
+ /** Border color in hex format (default: '#000000') */
183
+ color?: string;
184
+ /** Border style - solid or dashed pattern (default: 'solid') */
185
+ style?: BorderStyle;
186
+ };
187
+ /** Output format and type (default: { format: 'png', type: 'buffer' }) */
188
+ output?: OutputConfig;
189
+ }
190
+ /**
191
+ * Text-based rendering options for ASCII (public API)
192
+ * All fields are optional - unspecified values use defaults from internal/core/defaults.ts
193
+ */
194
+ export interface TextOptions {
195
+ /** Margin in modules (default: 2) */
196
+ margin?: number;
197
+ /** Dark character(s) for modules (default: '██') */
198
+ darkChar?: string;
199
+ /** Light/background character(s) (default: ' ') */
200
+ lightChar?: string;
201
+ }
202
+ /**
203
+ * Generate QR code image with configurable output format
204
+ * @param input - Content to encode (string or structured content type)
205
+ * @param options - Styling and output options
206
+ * @returns Promise resolving to Buffer, Uint8Array, or string based on output config
207
+ */
208
+ export declare function genQrImage(input: QRInput, options?: ImageOptions): Promise<string | Buffer | Uint8Array>;
209
+ /**
210
+ * Generate ASCII QR code
211
+ * @param input - Content to encode (string or structured content type)
212
+ * @param options - Text styling options
213
+ * @returns ASCII string representation
214
+ */
215
+ export declare function genQrText(input: QRInput, options?: TextOptions): string;
216
+ export interface ValidationError {
217
+ field: string;
218
+ value: unknown;
219
+ message: string;
220
+ }
221
+ /**
222
+ * Custom error for validation failures
223
+ * Contains array of all validation errors found
224
+ */
225
+ export declare class QRValidationError extends Error {
226
+ errors: ValidationError[];
227
+ constructor(errors: ValidationError[]);
228
+ }
229
+
230
+ export {};
package/dist/node.cjs ADDED
@@ -0,0 +1,29 @@
1
+ "use strict";var Ve=Object.create;var P=Object.defineProperty;var ze=Object.getOwnPropertyDescriptor;var Fe=Object.getOwnPropertyNames;var qe=Object.getPrototypeOf,_e=Object.prototype.hasOwnProperty;var Qe=(e,r)=>{for(var t in r)P(e,t,{get:r[t],enumerable:!0})},ee=(e,r,t,o)=>{if(r&&typeof r=="object"||typeof r=="function")for(let n of Fe(r))!_e.call(e,n)&&n!==t&&P(e,n,{get:()=>r[n],enumerable:!(o=ze(r,n))||o.enumerable});return e};var Ge=(e,r,t)=>(t=e!=null?Ve(qe(e)):{},ee(r||!e||!e.__esModule?P(t,"default",{value:e,enumerable:!0}):t,e)),Ue=e=>ee(P({},"__esModule",{value:!0}),e);var xt={};Qe(xt,{BorderShape:()=>q,BorderStyle:()=>_,DotShape:()=>F,EyeFrameShape:()=>z,QRValidationError:()=>S,genQrImage:()=>Be,genQrText:()=>Ne});module.exports=Ue(xt);var te={L:[7,10,15,20,26,18,20,24,30,18],M:[10,16,26,18,24,16,18,22,22,26],Q:[13,22,18,26,18,24,18,22,20,24],H:[17,28,22,16,22,28,26,26,24,28]},y={L:[19,34,55,80,108,136,156,194,232,274],M:[16,28,44,64,86,108,124,154,182,216],Q:[13,22,34,48,62,76,88,110,132,154],H:[9,16,26,36,46,60,66,86,100,122]},re={L:[[1,19,0,0],[1,34,0,0],[1,55,0,0],[1,80,0,0],[1,108,0,0],[2,68,0,0],[2,78,0,0],[2,97,0,0],[2,116,0,0],[2,68,2,69]],M:[[1,16,0,0],[1,28,0,0],[1,44,0,0],[2,32,0,0],[2,43,0,0],[4,27,0,0],[4,31,0,0],[2,38,2,39],[3,36,2,37],[4,43,1,44]],Q:[[1,13,0,0],[1,22,0,0],[2,17,0,0],[2,24,0,0],[2,15,2,16],[4,19,0,0],[2,14,4,15],[4,18,2,19],[4,16,4,17],[6,19,2,20]],H:[[1,9,0,0],[1,16,0,0],[2,13,0,0],[4,9,0,0],[2,11,2,12],[4,15,0,0],[4,13,1,14],[4,14,2,15],[4,12,4,13],[6,15,2,16]]},R="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:",We={1:[10,12,14],2:[9,11,13],4:[8,16,16]},V={L:1,M:0,Q:3,H:2},A=[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50]],ne=[31892,34236,39577,42195],oe=[0,7,7,7,7,7,0,0,0,0];function I(e){return e*4+17}function L(e,r){let t=r<10?0:r<27?1:2;return We[e][t]}var z=(t=>(t.SQUARE="square",t.SQUIRCLE="squircle",t))(z||{}),F=(o=>(o.CLASSIC="classic",o.DOTS="dots",o.SQUARE="square",o))(F||{}),q=(n=>(n.NONE="none",n.SQUARE="square",n.SQUIRCLE="squircle",n.CIRCLE="circle",n))(q||{}),_=(t=>(t.SOLID="solid",t.DASHED="dashed",t))(_||{});function M(e,r){let t=r/2;return e<=-t?0:e>=t?255:Math.round((e+t)/r*255)}function G(e,r,t=.01){return M(r-e,t)}function je(e,r,t,o){let n=Math.abs(e)-t+o,s=Math.abs(r)-t+o,a=Math.sqrt(Math.max(n,0)**2+Math.max(s,0)**2),i=Math.min(Math.max(n,s),0);return a+i-o}function He(e,r){let n=r*3,s=r*2,a=n+s,i=Math.max(1,Math.round(e/a)),c=e/i,u=c*(3/5),l=c*(2/5),d=l/2;return{dashArray:`${u} ${l}`,offset:d}}function U(e,r){let t=r*3,o=r*2,n=t+o,s=Math.round(e/n);s=Math.round(s/4)*4,s=Math.max(4,s);let a=e/s,i=a*.6,c=a*.4,u=i/2;return{dashArray:`${i} ${c}`,offset:u}}function Q(e,r,t,o,n){return n==="circle"?Ye(e,r,t,o):n==="squircle"?Xe(e,r,t,o):Ke(e,r,t,o)}function Ye(e,r,t,o){let s=(Math.atan2(r,e)+Math.PI)/(2*Math.PI),a=t/2-o/2,i=2*Math.PI*a,c=o*3,u=o*2,l=Math.floor(i/(c+u)),d=l%2===0?l:l-1,f=Math.max(4,d);return s*f%1<.6}function Xe(e,r,t,o){let s=t/2-o/2,a=t*W,i=Math.max(0,a-o/2),c=s-i,u=2*c,l=.5*Math.PI*i,d=4*u+4*l,f=Ze(e,r,c,i,u,l,d),{dashArray:m}=U(d,o),[h,g]=m.split(" ").map(Number),b=h+g;return(f+h/2)%b<h}function Ze(e,r,t,o,n,s,a){if(r<-t)if(e>t){let i=Math.atan2(r- -t,e-t)+Math.PI/2;return t+i*o}else if(e<-t){let i=Math.atan2(r- -t,e- -t)+Math.PI;return t+3*s+3*n+i*o}else return e>=0?e:a+e;else if(r>t)if(e>t){let i=Math.atan2(r-t,e-t);return t+s+n+i*o}else if(e<-t){let i=Math.atan2(r-t,e- -t)-Math.PI/2;return t+2*s+2*n+i*o}else return t+2*s+n+(t-e);else return e>t?t+s+(r- -t):e<-t?t+3*s+2*n+(t-r):e>=0?e:a+e}function Ke(e,r,t,o){let n=t/2,s=Math.abs(e),i=Math.abs(r)>=s?n+e:n+r,c=t-o,u=3,l=2,d=o*(u+l),f=Math.max(1,Math.round(c/d)),m=c/f,h=m*(u/(u+l)),b=(m-h)/2;return(i+b)%m<h}var W=.12,Je={EYE_FRAME:.90909},E={square:{renderSVG(e,r,t,o){return`<rect x="${e}" y="${r}" width="${t}" height="${t}" fill="${o}"/>`},renderPixel(e,r,t,o){let n=t/2,s=o?.pixelSize??.01,a=Math.min(n-Math.abs(e),n-Math.abs(r));return M(a,s)}},squircle:{renderSVG(e,r,t,o){let n=t/2,s=n*Je.EYE_FRAME,a=e+n,i=r+n;return`<path d="${`M${a},${i-n}
2
+ C${a+s},${i-n} ${a+n},${i-s} ${a+n},${i}
3
+ S${a+s},${i+n} ${a},${i+n}
4
+ S${a-n},${i+s} ${a-n},${i}
5
+ S${a-s},${i-n} ${a},${i-n}Z`}" fill="${o}"/>`},renderPixel(e,r,t,o){let n=t/2,s=o?.pixelSize??.01,a=4,i=Math.abs(e),c=Math.abs(r),u=i/n,l=c/n;if(i<.001&&c<.001)return 255;let d=Math.pow(u,a)+Math.pow(l,a),f=a/n*Math.sqrt(Math.pow(u,2*a-2)+Math.pow(l,2*a-2)),m=(1-d)/f;return M(m,s)}}},O={classic:{renderSVG(){return""},renderPixel(e,r,t,o){let n=t/2,s=o?.pixelSize??.01;if(t>=.99&&o&&o.qrcode&&o.row!==void 0&&o.col!==void 0){let{qrcode:i,row:c,col:u}=o,l=o.qrSize||i.length,d=u>0&&i[c][u-1],f=u<l-1&&i[c][u+1],m=c>0&&i[c-1][u],h=c<l-1&&i[c+1][u],g=d?1/0:n+e,b=f?1/0:n-e,$=m?1/0:n+r,C=h?1/0:n-r,N=Math.min(Math.min(g,b),Math.min($,C));return M(N,s)}let a=Math.min(n-Math.abs(e),n-Math.abs(r));return M(a,s)}},dots:{renderSVG(e,r,t,o){let n=e+t/2,s=r+t/2,a=t*.35;return`<circle cx="${n}" cy="${s}" r="${a}" fill="${o}"/>`},renderPixel(e,r,t,o){let n=t*.35,s=o?.pixelSize??.01,a=Math.sqrt(e*e+r*r);return G(a,n,s)}},square:{renderSVG(e,r,t,o){let n=t*.7,s=(t-n)/2,a=e+s,i=r+s;return`<rect x="${a}" y="${i}" width="${n}" height="${n}" fill="${o}"/>`},renderPixel(e,r,t,o){let s=t*.7/2,a=o?.pixelSize??.01,i=Math.min(s-Math.abs(e),s-Math.abs(r));return M(i,a)}}},T={square:{getDiagonalFactor(){return Math.sqrt(2)},renderSVG(e,r,t,o,n){let s=n?.borderWidth??1;if((n?.borderStyle??"solid")==="dashed"){let f=s/2,m=t-s,{dashArray:h,offset:g}=He(m,s);return`<rect x="${e+f}" y="${r+f}" width="${m}" height="${m}" fill="none" stroke="${o}" stroke-width="${s}" stroke-dasharray="${h}" stroke-dashoffset="${-g}"/>`}let i=`M${e},${r}h${t}v${t}h${-t}z`,c=e+s,u=r+s,l=t-s*2,d=`M${c},${u}h${l}v${l}h${-l}z`;return`<path d="${i} ${d}" fill="${o}" fill-rule="evenodd"/>`},renderPixel(e,r,t,o){let n=o?.borderWidth??1,s=o?.borderStyle??"solid",a=o?.pixelSize??.01,i=t/2,c=i-n,u=i-Math.abs(e),l=i-Math.abs(r),d=c-Math.abs(e),f=c-Math.abs(r),m=Math.min(u,l),h=Math.min(d,f);if(m>=0&&h<=0){if(s==="dashed"&&!Q(e,r,t,n,"square"))return 0;let g=M(m,a),b=255-M(h,a);return Math.min(g,b)}return 0}},squircle:{getDiagonalFactor(){return Math.pow(2,.25)},renderSVG(e,r,t,o,n){let s=n?.borderWidth??1,a=n?.borderStyle??"solid",i=t/2,c=e+i,u=r+i,l=i-s/2,d=t*W,f=Math.max(0,d-s/2),m=l-f,h=`M${c},${u-l}
6
+ H${c+m}
7
+ A${f},${f} 0 0 1 ${c+l},${u-m}
8
+ V${u+m}
9
+ A${f},${f} 0 0 1 ${c+m},${u+l}
10
+ H${c-m}
11
+ A${f},${f} 0 0 1 ${c-l},${u+m}
12
+ V${u-m}
13
+ A${f},${f} 0 0 1 ${c-m},${u-l}
14
+ Z`;if(a==="dashed"){let g=2*m,b=.5*Math.PI*f,$=4*g+4*b,{dashArray:C,offset:N}=U($,s);return`<path d="${h}" fill="none" stroke="${o}" stroke-width="${s}" stroke-dasharray="${C}" stroke-dashoffset="${N}"/>`}return`<path d="${h}" fill="none" stroke="${o}" stroke-width="${s}"/>`},renderPixel(e,r,t,o){let n=o?.borderWidth??1,s=o?.borderStyle??"solid",a=o?.pixelSize??.01,c=t/2-n/2,u=t*W,l=Math.max(0,u-n/2),d=Math.abs(je(e,r,c,l)),f=n/2-d;return f>-a?s==="dashed"&&!Q(e,r,t,n,"squircle")?0:M(f,a):0}},circle:{getDiagonalFactor(){return 1},renderSVG(e,r,t,o,n){let s=n?.borderWidth??1,a=n?.borderStyle??"solid",i=e+t/2,c=r+t/2,u=t/2;if(a==="dashed"){let m=u-s/2,h=2*Math.PI*m,{dashArray:g,offset:b}=U(h,s);return`<circle cx="${i}" cy="${c}" r="${m}" fill="none" stroke="${o}" stroke-width="${s}" stroke-dasharray="${g}" stroke-dashoffset="${b}"/>`}let l=u-s,d=`M${i},${c-u}
15
+ A${u},${u} 0 1,1 ${i},${c+u}
16
+ A${u},${u} 0 1,1 ${i},${c-u}Z`,f=`M${i},${c-l}
17
+ A${l},${l} 0 1,0 ${i},${c+l}
18
+ A${l},${l} 0 1,0 ${i},${c-l}Z`;return`<path d="${d} ${f}" fill="${o}" fill-rule="evenodd"/>`},renderPixel(e,r,t,o){let n=o?.borderWidth??1,s=o?.borderStyle??"solid",a=o?.pixelSize??.01,i=t/2,c=i-n,u=Math.sqrt(e*e+r*r);if(u<=i&&u>=c){if(s==="dashed"&&!Q(e,r,t,n,"circle"))return 0;let l=G(u,i,a),d=255-G(u,c,a);return Math.min(l,d)}return 0}}};var S=class extends Error{constructor(r){let t=r.map(o=>` - ${o.field}: ${o.message}`).join(`
19
+ `);super(`QR Code validation failed:
20
+ ${t}`),this.name="QRValidationError",this.errors=r}};function x(e,r,t,o,n=!1){return typeof e!="number"||!isFinite(e)?{field:r,value:e,message:"must be a finite number"}:n&&!Number.isInteger(e)?{field:r,value:e,message:"must be an integer"}:e<t?{field:r,value:e,message:`must be at least ${t}`}:o!==null&&e>o?{field:r,value:e,message:`must be at most ${o}`}:null}function v(e,r){return typeof e!="string"?{field:r,value:e,message:"must be a string"}:/^#[0-9A-Fa-f]{6}$/.test(e)?null:{field:r,value:e,message:"must be a valid hex color (e.g., #000000)"}}function j(e,r,t){if(typeof e!="string")return{field:r,value:e,message:"must be a string"};if(!(e in t)){let o=Object.keys(t).join(", ");return{field:r,value:e,message:`must be one of: ${o}`}}return null}function se(e){let r=[];if(e.size!==void 0){let t=x(e.size,"size",21,null,!0);t&&r.push(t)}if(e.margin!==void 0){let t=x(e.margin,"margin",0,null,!0);t&&r.push(t)}if(e.backgroundColor!==void 0){let t=v(e.backgroundColor,"backgroundColor");t&&r.push(t)}if(e.eyes?.shape!==void 0){let t=j(e.eyes.shape,"eyes.shape",E);t&&r.push(t)}if(e.eyes?.color!==void 0){let t=v(e.eyes.color,"eyes.color");t&&r.push(t)}if(e.pupils?.color!==void 0){let t=v(e.pupils.color,"pupils.color");t&&r.push(t)}if(e.dots?.shape!==void 0){let t=j(e.dots.shape,"dots.shape",O);t&&r.push(t)}if(e.dots?.color!==void 0){let t=v(e.dots.color,"dots.color");t&&r.push(t)}if(e.dots?.scale!==void 0){let t=x(e.dots.scale,"dots.scale",.75,1.25,!1);t&&r.push(t)}if(e.border?.shape!==void 0&&e.border.shape!=="none"){let t=j(e.border.shape,"border.shape",T);t&&r.push(t)}if(e.border?.width!==void 0){let t=x(e.border.width,"border.width",0,null,!0);t&&r.push(t)}if(e.border?.color!==void 0){let t=v(e.border.color,"border.color");t&&r.push(t)}if(e.border?.style!==void 0&&(typeof e.border.style!="string"||e.border.style!=="solid"&&e.border.style!=="dashed")&&r.push({field:"border.style",value:e.border.style,message:'must be either "solid" or "dashed"'}),e.logo&&((!e.logo.src||typeof e.logo.src!="string")&&r.push({field:"logo.src",value:e.logo.src,message:"must be a non-empty string"}),e.logo.scale!==void 0)){let t=x(e.logo.scale,"logo.scale",.1,.3,!1);t&&r.push(t)}if(r.length>0)throw new S(r)}function ae(e){let r=[];if(e.margin!==void 0){let t=x(e.margin,"margin",0,null,!0);t&&r.push(t)}if(e.darkChar!==void 0&&typeof e.darkChar!="string"&&r.push({field:"darkChar",value:e.darkChar,message:"must be a string"}),e.lightChar!==void 0&&typeof e.lightChar!="string"&&r.push({field:"lightChar",value:e.lightChar,message:"must be a string"}),r.length>0)throw new S(r)}var p={size:300,margin:24,backgroundColor:"#ffffff",eyes:{shape:"square",color:"#000000"},pupils:{color:"#000000"},dots:{shape:"classic",color:"#000000",scale:1},logo:{scale:.2},border:{shape:"none",width:10,color:"#000000",style:"solid"},output:{format:"png",type:"buffer"}},k={margin:2,darkChar:"\u2588\u2588",lightChar:" "};function ie(e){if(!e){let{logo:t,...o}=p;return o}return se(e),{size:e.size??p.size,margin:e.margin??p.margin,backgroundColor:e.backgroundColor??p.backgroundColor,eyes:{shape:e.eyes?.shape??p.eyes.shape,color:e.eyes?.color??p.eyes.color},pupils:{color:e.pupils?.color??p.pupils.color},dots:{shape:e.dots?.shape??p.dots.shape,color:e.dots?.color??p.dots.color,scale:e.dots?.scale??p.dots.scale},logo:e.logo?{src:e.logo.src,scale:e.logo.scale??p.logo.scale}:void 0,border:{shape:e.border?.shape??p.border.shape,width:e.border?.width??p.border.width,color:e.border?.color??p.border.color,style:e.border?.style??p.border.style},output:e.output??p.output}}function ce(e){return e?(ae(e),{margin:e.margin??k.margin,darkChar:e.darkChar??k.darkChar,lightChar:e.lightChar??k.lightChar}):{...k}}function ue(e){return/^\d+$/.test(e)?1:[...e].every(r=>R.includes(r))?2:4}function et(e){let r=[];for(let t=0;t<e.length;t+=3){let o=e.substring(t,Math.min(t+3,e.length)),n=parseInt(o,10),s=o.length===3?10:o.length===2?7:4;for(let a=s-1;a>=0;a--)r.push(n>>a&1)}return r}function tt(e){let r=[];for(let t=0;t<e.length;t+=2)if(t+1<e.length){let o=R.indexOf(e[t])*45+R.indexOf(e[t+1]);for(let n=10;n>=0;n--)r.push(o>>n&1)}else{let o=R.indexOf(e[t]);for(let n=5;n>=0;n--)r.push(o>>n&1)}return r}function rt(e){let r=[],t=new TextEncoder().encode(e);for(let o of t)for(let n=7;n>=0;n--)r.push(o>>n&1);return r}function nt(e,r,t,o){let n=[];for(let a=3;a>=0;a--)n.push(r>>a&1);let s=L(r,o);for(let a=s-1;a>=0;a--)n.push(t>>a&1);return[...n,...e]}function ot(e){let r=[];for(let t=0;t<e.length;t+=8){let o=0;for(let n=0;n<8&&t+n<e.length;n++)o=o<<1|e[t+n];t+8>e.length&&(o<<=8-e.length%8),r.push(o)}return r}function st(e,r){let t=[...e],o=[236,17],n=0;for(;t.length<r;)t.push(o[n]),n=1-n;return t}function le(e,r,t){let o=ue(e),n,s;o===1?(n=et(e),s=e.length):o===2?(n=tt(e),s=e.length):(n=rt(e),s=new TextEncoder().encode(e).length);let a=nt(n,o,s,r),i=Math.min(4,t*8-a.length);for(let u=0;u<i;u++)a.push(0);for(;a.length%8!==0;)a.push(0);let c=ot(a);return st(c,t)}function D(e,r){let t=ue(e),o=t===4?new TextEncoder().encode(e).length:e.length;for(let c=1;c<=10;c++){let u=L(t,c),l=t===1?Math.ceil(o/3)*10-(o%3===1?6:o%3===2?3:0):t===2?Math.floor(o/2)*11+o%2*6:o*8,d=4+u+l;if(Math.ceil(d/8)<=r[c-1])return c}let n=L(t,10),s=t===1?Math.ceil(o/3)*10-(o%3===1?6:o%3===2?3:0):t===2?Math.floor(o/2)*11+o%2*6:o*8,a=4+n+s,i=Math.ceil(a/8);throw new Error(`Input too long for QR code version 10. Required capacity: ${i} bytes, Maximum available: ${r[9]} bytes. Current data length: ${e.length} characters (${o} bytes encoded).`)}function fe(e,r){if(r)try{if(D(e,y.H)<=10)return"H"}catch{throw new Error(`Data too large for QR code with logo. Data length: ${e.length} characters. Maximum capacity with logo (EC level H): ~122 bytes (version 10). Logos require high error correction (H) which reduces data capacity. Consider: reducing data length, removing logo, or using multiple QR codes.`)}let t=["H","Q","M","L"];for(let o of t)try{if(D(e,y[o])<=10)return o}catch{continue}throw new Error(`Data too large for QR code version 10 at any error correction level. Data length: ${e.length} characters. Maximum capacity: ~274 bytes (version 10, EC level L). Please reduce input length or split into multiple QR codes.`)}var w=new Array(256),H=new Array(256);function at(){let e=1;for(let r=0;r<255;r++)w[r]=e,H[e]=r,e<<=1,e&256&&(e^=285);for(let r=255;r<512;r++)w[r]=w[r-255]}at();function me(e,r){return e===0||r===0?0:w[H[e]+H[r]]}function it(e){let r=[1];for(let t=0;t<e;t++){let o=r.length+1,n=new Array(o).fill(0);for(let s=0;s<r.length;s++)n[s]^=r[s],n[s+1]^=me(r[s],w[t]);r=n}return r}function de(e,r){let t=it(r),o=[...e,...new Array(r).fill(0)];for(let n=0;n<e.length;n++){let s=o[n];if(s!==0)for(let a=0;a<t.length;a++)o[n+a]^=me(t[a],s)}return o.slice(e.length)}function he(e,r,t){let o=[],n=[],[s,a,i,c]=t,u=0;for(let l=0;l<s;l++){let d=e.slice(u,u+a);o.push(d);let f=de(d,r);n.push(f),u+=a}for(let l=0;l<i;l++){let d=e.slice(u,u+c);o.push(d);let f=de(d,r);n.push(f),u+=c}return{dataBlocks:o,ecBlocks:n}}function ge(e,r){let t=[],o=Math.max(...e.map(s=>s.length));for(let s=0;s<o;s++)for(let a of e)s<a.length&&t.push(a[s]);let n=Math.max(...r.map(s=>s.length));for(let s=0;s<n;s++)for(let a of r)s<a.length&&t.push(a[s]);return t}function be(e){let r=I(e);return Array.from({length:r},()=>Array(r).fill(!1))}function pe(e){let r=I(e),t=Array.from({length:r},()=>Array(r).fill(!1));for(let n=0;n<=7;n++)for(let s=0;s<=7;s++)t[n][s]=!0;for(let n=0;n<=7;n++)for(let s=0;s<=7;s++)t[n][r-8+s]=!0;for(let n=0;n<=7;n++)for(let s=0;s<=7;s++)t[r-8+n][s]=!0;for(let n=8;n<r-8;n++)t[6][n]=!0,t[n][6]=!0;t[4*e+9][8]=!0;for(let n=0;n<6;n++)t[n][8]=!0;t[7][8]=!0,t[8][8]=!0;for(let n=r-8;n<r;n++)t[n][8]=!0;for(let n=0;n<9;n++)t[8][n]=!0;for(let n=r-8;n<r;n++)t[8][n]=!0;let o=A[e-1]||[];for(let n of o)for(let s of o)if(!(n<9&&s<9||n<9&&s>r-9||n>r-9&&s<9))for(let i=-2;i<=2;i++)for(let c=-2;c<=2;c++)t[n+i][s+c]=!0;if(e>=7){for(let n=0;n<6;n++)for(let s=r-11;s<r-8;s++)t[n][s]=!0;for(let n=r-11;n<r-8;n++)for(let s=0;s<6;s++)t[n][s]=!0}return t}function Y(e,r,t){for(let o=-1;o<=7;o++)for(let n=-1;n<=7;n++){let s=r+o,a=t+n;if(s<0||s>=e.length||a<0||a>=e.length)continue;let i=o>=0&&o<=6&&n>=0&&n<=6&&(o===0||o===6||n===0||n===6),c=o>=2&&o<=4&&n>=2&&n<=4;e[s][a]=i||c}}function ct(e,r,t){for(let o=-2;o<=2;o++)for(let n=-2;n<=2;n++){let s=o===-2||o===2||n===-2||n===2,a=o===0&&n===0;e[r+o][t+n]=s||a}}function $e(e){let r=e.length;for(let t=8;t<r-8;t++)e[6][t]=t%2===0,e[t][6]=t%2===0}function Ce(e){Y(e,0,0),Y(e,0,e.length-7),Y(e,e.length-7,0)}function Me(e,r){let t=e.length,o=A[r-1]||[];for(let n of o)for(let s of o)n<9&&s<9||n<9&&s>t-9||n>t-9&&s<9||ct(e,n,s)}function ye(e,r){e[4*r+9][8]=!0}function xe(e,r,t){let o=e.length,n=0,s=-1,a=o-1;for(let i=o-1;i>0;i-=2)for(i===6&&i--;;){for(let c=0;c<2;c++)if(!r[a][i-c]){let u=n<t.length?t[n]:!1;e[a][i-c]=u,n++}if(a+=s,a<0||o<=a){a-=s,s=-s;break}}}function X(e,r,t){let o=e.length;for(let n=0;n<o;n++)for(let s=0;s<o;s++){if(r[n][s])continue;let a=!1;switch(t){case 0:a=(n+s)%2===0;break;case 1:a=n%2===0;break;case 2:a=s%3===0;break;case 3:a=(n+s)%3===0;break;case 4:a=(Math.floor(n/2)+Math.floor(s/3))%2===0;break;case 5:a=n*s%2+n*s%3===0;break;case 6:a=(n*s%2+n*s%3)%2===0;break;case 7:a=((n+s)%2+n*s%3)%2===0;break}a&&(e[n][s]=!e[n][s])}}function ut(e){let r=e.length,t=0;for(let a=0;a<r;a++){let i=e[a][0],c=e[0][a],u=1,l=1;for(let d=1;d<r;d++)e[a][d]===i?u++:(u>=5&&(t+=3+(u-5)),i=e[a][d],u=1),e[d][a]===c?l++:(l>=5&&(t+=3+(l-5)),c=e[d][a],l=1);u>=5&&(t+=3+(u-5)),l>=5&&(t+=3+(l-5))}for(let a=0;a<r-1;a++)for(let i=0;i<r-1;i++){let c=e[a][i];e[a][i+1]===c&&e[a+1][i]===c&&e[a+1][i+1]===c&&(t+=3)}for(let a=0;a<r;a++){let i=0,c=0;for(let u=0;u<r;u++)i=i<<1&2047|(e[a][u]?1:0),u>=10&&(i===1488||i===93)&&(t+=40),c=c<<1&2047|(e[u][a]?1:0),u>=10&&(c===1488||c===93)&&(t+=40)}let o=0,n=r*r;for(let a=0;a<r;a++)for(let i=0;i<r;i++)e[a][i]&&o++;let s=Math.abs(Math.ceil(o*100/n/5)-10);return t+=s*10,t}function Se(e,r,t,o){let n=0,s=1/0;for(let a=0;a<8;a++){let i=e.map(u=>[...u]);X(i,r,a),o(i,t,a);let c=ut(i);c<s&&(s=c,n=a)}return n}function Z(e,r,t){let o=e.length,n=V[r]<<3|t,s=n<<10;for(let i=0;i<5;i++)s&1<<14-i&&(s^=1335<<4-i);let a=(n<<10|s)^21522;for(let i=0;i<15;i++){let c=(a>>14-i&1)===1;i<=5?e[8][i]=c:i===6?e[8][7]=c:i===7?e[8][8]=c:i===8?e[7][8]=c:e[5-(i-9)][8]=c,i<=6?e[o-1-i][8]=c:e[8][o-8+(i-7)]=c}}function Re(e,r){if(r<7)return;let t=e.length,o=ne[r-7];for(let n=0;n<18;n++){let s=(o>>n&1)===1,a=Math.floor(n/3),i=t-11+n%3;e[a][i]=s;let c=t-11+n%3,u=Math.floor(n/3);e[c][u]=s}}function Ie(e,r){return V[e]<<3|r}function Ee(e,r,t,o,n){let s=be(e),a=pe(e);Ce(s),$e(s),Me(s,e),ye(s,e),xe(s,a,t);let i=n?s.map(u=>[...u]):void 0,c=o??Se(s,a,r,Z);return X(s,a,c),Z(s,r,c),Re(s,e),{matrix:s,mask:c,formatInfo:n?Ie(r,c):void 0,unmaskedMatrix:i}}function K(e,r,t){return e<7&&r<7||e<7&&r>=t-7||e>=t-7&&r<7}function Oe(e){return[{x:0,y:0},{x:e-7,y:0},{x:0,y:e-7}]}function ve(e,r){let o=Math.max(.1,Math.min(.3,r));return e*o}function lt(e,r,t,o,n,s,a){let i=E[t]||E.square,c=i.renderSVG(e,r,7*a,o),u=i.renderSVG(e+a,r+a,5*a,s),l=i.renderSVG(e+2*a,r+2*a,3*a,n);return c+u+l}function ft(e,r,t,o){let n=o/2;if(e.includes("data:image/svg")||e.trim().startsWith("<svg")){let s=e;if(e.includes("data:image/svg")){let u=e.match(/data:image\/svg\+xml[^,]*,(.+)/);if(u)try{s=decodeURIComponent(u[1])}catch{return""}}let a=s.match(/viewBox=["']([^"']+)["']/),i=a?a[1]:"0 0 100 100",c=s.replace(/<\?xml[^>]*>|<svg[^>]*>|<\/svg>/gi,"");return`<g transform="translate(${r-n}, ${t-n})">
21
+ <svg width="${o}" height="${o}" viewBox="${i}">
22
+ ${c}
23
+ </svg>
24
+ </g>`}else return`<image x="${r-n}" y="${t-n}" width="${o}" height="${o}" href="${e}" preserveAspectRatio="xMidYMid meet"/>`}function dt(e,r,t,o,n){let s=e.matrixSize,a="",i=O[t]||O.classic;if(t==="classic"){a=`<path fill="${o}" d="`;for(let c=0;c<s;c++)for(let u=0;u<s;u++)if(e.modules[c][u]&&!K(c,u,s)){let l=u*r,d=c*r,f=n*r,m=(1-n)*r/2,h=l+m,g=d+m;a+=`M${h},${g}h${f}v${f}h${-f}z`}return a+='"/>',a}for(let c=0;c<s;c++)for(let u=0;u<s;u++)if(e.modules[c][u]&&!K(c,u,s)){let l=u*r,d=c*r,f=n*r,m=(1-n)*r/2,h=l+m,g=d+m,b={qrcode:e.modules,qrSize:s,row:c,col:u};a+=i.renderSVG(h,g,f,o,b)}return a}function we(e,r){let{size:t,margin:o,backgroundColor:n,eyes:s,pupils:a,dots:i}=r,c=t/e.matrixSize,u=r.border.shape==="none"?0:r.border.width,l=t+2*o+2*u,d=o+u,f=`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${l} ${l}" width="${l}" height="${l}">`;if(f+=`<rect width="${l}" height="${l}" fill="${n}"/>`,r.border.shape!=="none"&&u>0){let $=T[r.border.shape];if($){let C={borderWidth:u,borderStyle:r.border.style};f+=$.renderSVG(0,0,l,r.border.color,C)}}r.border.shape!=="none"&&u>0&&(f+=`<rect x="${d}" y="${d}" width="${t}" height="${t}" fill="${n}"/>`),f+=`<g transform="translate(${d}, ${d})">`;let m=Oe(e.matrixSize),h="";for(let $ of m)h+=lt($.x*c,$.y*c,s.shape,s.color,a.color,n,c);let g=dt(e,c,i.shape,i.color,i.scale);f+=h+g+"</g>";let b="";if(r.logo){let $=ve(e.matrixSize,r.logo.scale)*c,C=l/2;b=ft(r.logo.src,C,C,$)}return f+=b+"</svg>",f}function Pe(e,r){let{margin:t,lightChar:o,darkChar:n}=r,s="",a=e.matrixSize+t*2;for(let i=0;i<t;i++)s+=o.repeat(a)+`
25
+ `;for(let i=0;i<e.matrixSize;i++){s+=o.repeat(t);for(let c=0;c<e.matrixSize;c++)s+=e.modules[i][c]?n:o;s+=o.repeat(t)+`
26
+ `}for(let i=0;i<t;i++)s+=o.repeat(a)+`
27
+ `;return s}var B=null,Ae=!1;async function mt(){if(B)return B;if(Ae)throw new Error("PNG generation in Node.js requires @resvg/resvg-js. Install with: npm install @resvg/resvg-js");Ae=!0;try{return B=(await import("@resvg/resvg-js")).Resvg,B}catch{throw new Error("PNG generation in Node.js requires @resvg/resvg-js. Install with: npm install @resvg/resvg-js")}}async function Le(e,r){let{output:t,size:o,margin:n,border:s}=r,a=s.shape==="none"?0:s.width,i=o+2*n+2*a,c=await mt(),d=new c(e,{fitTo:{mode:"width",value:i}}).render().asPng(),f=Buffer.from(d);return t.type==="dataURL"?`data:image/png;base64,${f.toString("base64")}`:f}async function Te(e,r){let{format:t,type:o}=r.output;return t==="svg"?o==="string"?e:`data:image/svg+xml;charset=utf-8,${encodeURIComponent(e)}`:await Le(e,r)}function J(e){if(typeof e=="string")return e;switch(e.type){case"url":return ht(e.url);case"vcard":return gt(e.data);case"wifi":return bt(e.data);case"calendar":return pt(e.data);case"email":return $t(e.email,e.subject,e.body);case"sms":return Ct(e.phone,e.message);case"phone":return Mt(e.phone)}}function ht(e){return!e.startsWith("http://")&&!e.startsWith("https://")?`https://${e}`:e}function gt(e){let r=["BEGIN:VCARD","VERSION:3.0",`FN:${e.name}`];if(e.phone&&r.push(`TEL:${e.phone}`),e.email&&r.push(`EMAIL:${e.email}`),e.organization&&r.push(`ORG:${e.organization}`),e.url&&r.push(`URL:${e.url}`),e.title&&r.push(`TITLE:${e.title}`),e.note&&r.push(`NOTE:${e.note}`),e.address){let{street:t,city:o,state:n,zip:s,country:a}=e.address,i=["","",t||"",o||"",n||"",s||"",a||""];r.push(`ADR:${i.join(";")}`)}return r.push("END:VCARD"),r.join(`
28
+ `)}function bt(e){let r=e.encryption||"WPA",t=e.hidden?"H:true;":"",o=ke(e.ssid),n=ke(e.password);return`WIFI:T:${r};S:${o};P:${n};${t};`}function ke(e){return e.replace(/([\\;,":])/g,"\\$1")}function pt(e){let r=o=>(typeof o=="string"?new Date(o):o).toISOString().replace(/[-:]/g,"").split(".")[0]+"Z",t=["BEGIN:VCALENDAR","VERSION:2.0","BEGIN:VEVENT",`SUMMARY:${e.title}`,`DTSTART:${r(e.startDate)}`,`DTEND:${r(e.endDate)}`];return e.location&&t.push(`LOCATION:${e.location}`),e.description&&t.push(`DESCRIPTION:${e.description}`),t.push("END:VEVENT","END:VCALENDAR"),t.join(`
29
+ `)}function $t(e,r,t){let o=`mailto:${e}`,n=[];return r&&n.push(`subject=${encodeURIComponent(r)}`),t&&n.push(`body=${encodeURIComponent(t)}`),n.length>0&&(o+=`?${n.join("&")}`),o}function Ct(e,r){return r?`sms:${e}:${r}`:`sms:${e}`}function Mt(e){return`tel:${e}`}function yt(e,r){let t=[];for(let n of e)for(let s=7;s>=0;s--)t.push((n>>s&1)===1);let o=oe[r-1];for(let n=0;n<o;n++)t.push(!1);return t}function De(e,r){if(!e)throw new Error("QR Code input cannot be empty. Please provide text or structured content to encode.");let t=fe(e,r),o=y[t],n=D(e,o);if(n<1||n>10)throw new Error(`Input data is too large for QR code version 10. Data length: ${e.length} characters. Maximum capacity at EC level ${t}: ~${y[t][9]} bytes. Try reducing input length or removing logo for higher capacity.`);let s=le(e,n,o[n-1]),a=te[t][n-1],i=re[t][n-1],{dataBlocks:c,ecBlocks:u}=he(s,a,i),l=ge(c,u),d=yt(l,n),{matrix:f,mask:m}=Ee(n,t,d);return{version:n,matrixSize:I(n),modules:f,mask:m,errorCorrectionLevel:t}}async function Be(e,r){let t=J(e),o=ie(r),n=De(t,!!o.logo),s=we(n,o);return await Te(s,o)}function Ne(e,r){let t=J(e),o=ce(r),n=De(t,!1);return Pe(n,o)}0&&(module.exports={BorderShape,BorderStyle,DotShape,EyeFrameShape,QRValidationError,genQrImage,genQrText});
package/dist/node.mjs ADDED
@@ -0,0 +1,29 @@
1
+ var Y={L:[7,10,15,20,26,18,20,24,30,18],M:[10,16,26,18,24,16,18,22,22,26],Q:[13,22,18,26,18,24,18,22,20,24],H:[17,28,22,16,22,28,26,26,24,28]},y={L:[19,34,55,80,108,136,156,194,232,274],M:[16,28,44,64,86,108,124,154,182,216],Q:[13,22,34,48,62,76,88,110,132,154],H:[9,16,26,36,46,60,66,86,100,122]},X={L:[[1,19,0,0],[1,34,0,0],[1,55,0,0],[1,80,0,0],[1,108,0,0],[2,68,0,0],[2,78,0,0],[2,97,0,0],[2,116,0,0],[2,68,2,69]],M:[[1,16,0,0],[1,28,0,0],[1,44,0,0],[2,32,0,0],[2,43,0,0],[4,27,0,0],[4,31,0,0],[2,38,2,39],[3,36,2,37],[4,43,1,44]],Q:[[1,13,0,0],[1,22,0,0],[2,17,0,0],[2,24,0,0],[2,15,2,16],[4,19,0,0],[2,14,4,15],[4,18,2,19],[4,16,4,17],[6,19,2,20]],H:[[1,9,0,0],[1,16,0,0],[2,13,0,0],[4,9,0,0],[2,11,2,12],[4,15,0,0],[4,13,1,14],[4,14,2,15],[4,12,4,13],[6,15,2,16]]},S="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:",ke={1:[10,12,14],2:[9,11,13],4:[8,16,16]},N={L:1,M:0,Q:3,H:2},P=[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50]],Z=[31892,34236,39577,42195],K=[0,7,7,7,7,7,0,0,0,0];function R(e){return e*4+17}function A(e,r){let t=r<10?0:r<27?1:2;return ke[e][t]}var J=(t=>(t.SQUARE="square",t.SQUIRCLE="squircle",t))(J||{}),ee=(o=>(o.CLASSIC="classic",o.DOTS="dots",o.SQUARE="square",o))(ee||{}),te=(n=>(n.NONE="none",n.SQUARE="square",n.SQUIRCLE="squircle",n.CIRCLE="circle",n))(te||{}),re=(t=>(t.SOLID="solid",t.DASHED="dashed",t))(re||{});function M(e,r){let t=r/2;return e<=-t?0:e>=t?255:Math.round((e+t)/r*255)}function z(e,r,t=.01){return M(r-e,t)}function De(e,r,t,o){let n=Math.abs(e)-t+o,s=Math.abs(r)-t+o,a=Math.sqrt(Math.max(n,0)**2+Math.max(s,0)**2),i=Math.min(Math.max(n,s),0);return a+i-o}function Be(e,r){let n=r*3,s=r*2,a=n+s,i=Math.max(1,Math.round(e/a)),c=e/i,u=c*(3/5),l=c*(2/5),d=l/2;return{dashArray:`${u} ${l}`,offset:d}}function F(e,r){let t=r*3,o=r*2,n=t+o,s=Math.round(e/n);s=Math.round(s/4)*4,s=Math.max(4,s);let a=e/s,i=a*.6,c=a*.4,u=i/2;return{dashArray:`${i} ${c}`,offset:u}}function V(e,r,t,o,n){return n==="circle"?Ne(e,r,t,o):n==="squircle"?Ve(e,r,t,o):Fe(e,r,t,o)}function Ne(e,r,t,o){let s=(Math.atan2(r,e)+Math.PI)/(2*Math.PI),a=t/2-o/2,i=2*Math.PI*a,c=o*3,u=o*2,l=Math.floor(i/(c+u)),d=l%2===0?l:l-1,f=Math.max(4,d);return s*f%1<.6}function Ve(e,r,t,o){let s=t/2-o/2,a=t*q,i=Math.max(0,a-o/2),c=s-i,u=2*c,l=.5*Math.PI*i,d=4*u+4*l,f=ze(e,r,c,i,u,l,d),{dashArray:m}=F(d,o),[h,g]=m.split(" ").map(Number),b=h+g;return(f+h/2)%b<h}function ze(e,r,t,o,n,s,a){if(r<-t)if(e>t){let i=Math.atan2(r- -t,e-t)+Math.PI/2;return t+i*o}else if(e<-t){let i=Math.atan2(r- -t,e- -t)+Math.PI;return t+3*s+3*n+i*o}else return e>=0?e:a+e;else if(r>t)if(e>t){let i=Math.atan2(r-t,e-t);return t+s+n+i*o}else if(e<-t){let i=Math.atan2(r-t,e- -t)-Math.PI/2;return t+2*s+2*n+i*o}else return t+2*s+n+(t-e);else return e>t?t+s+(r- -t):e<-t?t+3*s+2*n+(t-r):e>=0?e:a+e}function Fe(e,r,t,o){let n=t/2,s=Math.abs(e),i=Math.abs(r)>=s?n+e:n+r,c=t-o,u=3,l=2,d=o*(u+l),f=Math.max(1,Math.round(c/d)),m=c/f,h=m*(u/(u+l)),b=(m-h)/2;return(i+b)%m<h}var q=.12,qe={EYE_FRAME:.90909},I={square:{renderSVG(e,r,t,o){return`<rect x="${e}" y="${r}" width="${t}" height="${t}" fill="${o}"/>`},renderPixel(e,r,t,o){let n=t/2,s=o?.pixelSize??.01,a=Math.min(n-Math.abs(e),n-Math.abs(r));return M(a,s)}},squircle:{renderSVG(e,r,t,o){let n=t/2,s=n*qe.EYE_FRAME,a=e+n,i=r+n;return`<path d="${`M${a},${i-n}
2
+ C${a+s},${i-n} ${a+n},${i-s} ${a+n},${i}
3
+ S${a+s},${i+n} ${a},${i+n}
4
+ S${a-n},${i+s} ${a-n},${i}
5
+ S${a-s},${i-n} ${a},${i-n}Z`}" fill="${o}"/>`},renderPixel(e,r,t,o){let n=t/2,s=o?.pixelSize??.01,a=4,i=Math.abs(e),c=Math.abs(r),u=i/n,l=c/n;if(i<.001&&c<.001)return 255;let d=Math.pow(u,a)+Math.pow(l,a),f=a/n*Math.sqrt(Math.pow(u,2*a-2)+Math.pow(l,2*a-2)),m=(1-d)/f;return M(m,s)}}},E={classic:{renderSVG(){return""},renderPixel(e,r,t,o){let n=t/2,s=o?.pixelSize??.01;if(t>=.99&&o&&o.qrcode&&o.row!==void 0&&o.col!==void 0){let{qrcode:i,row:c,col:u}=o,l=o.qrSize||i.length,d=u>0&&i[c][u-1],f=u<l-1&&i[c][u+1],m=c>0&&i[c-1][u],h=c<l-1&&i[c+1][u],g=d?1/0:n+e,b=f?1/0:n-e,$=m?1/0:n+r,C=h?1/0:n-r,B=Math.min(Math.min(g,b),Math.min($,C));return M(B,s)}let a=Math.min(n-Math.abs(e),n-Math.abs(r));return M(a,s)}},dots:{renderSVG(e,r,t,o){let n=e+t/2,s=r+t/2,a=t*.35;return`<circle cx="${n}" cy="${s}" r="${a}" fill="${o}"/>`},renderPixel(e,r,t,o){let n=t*.35,s=o?.pixelSize??.01,a=Math.sqrt(e*e+r*r);return z(a,n,s)}},square:{renderSVG(e,r,t,o){let n=t*.7,s=(t-n)/2,a=e+s,i=r+s;return`<rect x="${a}" y="${i}" width="${n}" height="${n}" fill="${o}"/>`},renderPixel(e,r,t,o){let s=t*.7/2,a=o?.pixelSize??.01,i=Math.min(s-Math.abs(e),s-Math.abs(r));return M(i,a)}}},L={square:{getDiagonalFactor(){return Math.sqrt(2)},renderSVG(e,r,t,o,n){let s=n?.borderWidth??1;if((n?.borderStyle??"solid")==="dashed"){let f=s/2,m=t-s,{dashArray:h,offset:g}=Be(m,s);return`<rect x="${e+f}" y="${r+f}" width="${m}" height="${m}" fill="none" stroke="${o}" stroke-width="${s}" stroke-dasharray="${h}" stroke-dashoffset="${-g}"/>`}let i=`M${e},${r}h${t}v${t}h${-t}z`,c=e+s,u=r+s,l=t-s*2,d=`M${c},${u}h${l}v${l}h${-l}z`;return`<path d="${i} ${d}" fill="${o}" fill-rule="evenodd"/>`},renderPixel(e,r,t,o){let n=o?.borderWidth??1,s=o?.borderStyle??"solid",a=o?.pixelSize??.01,i=t/2,c=i-n,u=i-Math.abs(e),l=i-Math.abs(r),d=c-Math.abs(e),f=c-Math.abs(r),m=Math.min(u,l),h=Math.min(d,f);if(m>=0&&h<=0){if(s==="dashed"&&!V(e,r,t,n,"square"))return 0;let g=M(m,a),b=255-M(h,a);return Math.min(g,b)}return 0}},squircle:{getDiagonalFactor(){return Math.pow(2,.25)},renderSVG(e,r,t,o,n){let s=n?.borderWidth??1,a=n?.borderStyle??"solid",i=t/2,c=e+i,u=r+i,l=i-s/2,d=t*q,f=Math.max(0,d-s/2),m=l-f,h=`M${c},${u-l}
6
+ H${c+m}
7
+ A${f},${f} 0 0 1 ${c+l},${u-m}
8
+ V${u+m}
9
+ A${f},${f} 0 0 1 ${c+m},${u+l}
10
+ H${c-m}
11
+ A${f},${f} 0 0 1 ${c-l},${u+m}
12
+ V${u-m}
13
+ A${f},${f} 0 0 1 ${c-m},${u-l}
14
+ Z`;if(a==="dashed"){let g=2*m,b=.5*Math.PI*f,$=4*g+4*b,{dashArray:C,offset:B}=F($,s);return`<path d="${h}" fill="none" stroke="${o}" stroke-width="${s}" stroke-dasharray="${C}" stroke-dashoffset="${B}"/>`}return`<path d="${h}" fill="none" stroke="${o}" stroke-width="${s}"/>`},renderPixel(e,r,t,o){let n=o?.borderWidth??1,s=o?.borderStyle??"solid",a=o?.pixelSize??.01,c=t/2-n/2,u=t*q,l=Math.max(0,u-n/2),d=Math.abs(De(e,r,c,l)),f=n/2-d;return f>-a?s==="dashed"&&!V(e,r,t,n,"squircle")?0:M(f,a):0}},circle:{getDiagonalFactor(){return 1},renderSVG(e,r,t,o,n){let s=n?.borderWidth??1,a=n?.borderStyle??"solid",i=e+t/2,c=r+t/2,u=t/2;if(a==="dashed"){let m=u-s/2,h=2*Math.PI*m,{dashArray:g,offset:b}=F(h,s);return`<circle cx="${i}" cy="${c}" r="${m}" fill="none" stroke="${o}" stroke-width="${s}" stroke-dasharray="${g}" stroke-dashoffset="${b}"/>`}let l=u-s,d=`M${i},${c-u}
15
+ A${u},${u} 0 1,1 ${i},${c+u}
16
+ A${u},${u} 0 1,1 ${i},${c-u}Z`,f=`M${i},${c-l}
17
+ A${l},${l} 0 1,0 ${i},${c+l}
18
+ A${l},${l} 0 1,0 ${i},${c-l}Z`;return`<path d="${d} ${f}" fill="${o}" fill-rule="evenodd"/>`},renderPixel(e,r,t,o){let n=o?.borderWidth??1,s=o?.borderStyle??"solid",a=o?.pixelSize??.01,i=t/2,c=i-n,u=Math.sqrt(e*e+r*r);if(u<=i&&u>=c){if(s==="dashed"&&!V(e,r,t,n,"circle"))return 0;let l=z(u,i,a),d=255-z(u,c,a);return Math.min(l,d)}return 0}}};var v=class extends Error{constructor(r){let t=r.map(o=>` - ${o.field}: ${o.message}`).join(`
19
+ `);super(`QR Code validation failed:
20
+ ${t}`),this.name="QRValidationError",this.errors=r}};function x(e,r,t,o,n=!1){return typeof e!="number"||!isFinite(e)?{field:r,value:e,message:"must be a finite number"}:n&&!Number.isInteger(e)?{field:r,value:e,message:"must be an integer"}:e<t?{field:r,value:e,message:`must be at least ${t}`}:o!==null&&e>o?{field:r,value:e,message:`must be at most ${o}`}:null}function O(e,r){return typeof e!="string"?{field:r,value:e,message:"must be a string"}:/^#[0-9A-Fa-f]{6}$/.test(e)?null:{field:r,value:e,message:"must be a valid hex color (e.g., #000000)"}}function _(e,r,t){if(typeof e!="string")return{field:r,value:e,message:"must be a string"};if(!(e in t)){let o=Object.keys(t).join(", ");return{field:r,value:e,message:`must be one of: ${o}`}}return null}function ne(e){let r=[];if(e.size!==void 0){let t=x(e.size,"size",21,null,!0);t&&r.push(t)}if(e.margin!==void 0){let t=x(e.margin,"margin",0,null,!0);t&&r.push(t)}if(e.backgroundColor!==void 0){let t=O(e.backgroundColor,"backgroundColor");t&&r.push(t)}if(e.eyes?.shape!==void 0){let t=_(e.eyes.shape,"eyes.shape",I);t&&r.push(t)}if(e.eyes?.color!==void 0){let t=O(e.eyes.color,"eyes.color");t&&r.push(t)}if(e.pupils?.color!==void 0){let t=O(e.pupils.color,"pupils.color");t&&r.push(t)}if(e.dots?.shape!==void 0){let t=_(e.dots.shape,"dots.shape",E);t&&r.push(t)}if(e.dots?.color!==void 0){let t=O(e.dots.color,"dots.color");t&&r.push(t)}if(e.dots?.scale!==void 0){let t=x(e.dots.scale,"dots.scale",.75,1.25,!1);t&&r.push(t)}if(e.border?.shape!==void 0&&e.border.shape!=="none"){let t=_(e.border.shape,"border.shape",L);t&&r.push(t)}if(e.border?.width!==void 0){let t=x(e.border.width,"border.width",0,null,!0);t&&r.push(t)}if(e.border?.color!==void 0){let t=O(e.border.color,"border.color");t&&r.push(t)}if(e.border?.style!==void 0&&(typeof e.border.style!="string"||e.border.style!=="solid"&&e.border.style!=="dashed")&&r.push({field:"border.style",value:e.border.style,message:'must be either "solid" or "dashed"'}),e.logo&&((!e.logo.src||typeof e.logo.src!="string")&&r.push({field:"logo.src",value:e.logo.src,message:"must be a non-empty string"}),e.logo.scale!==void 0)){let t=x(e.logo.scale,"logo.scale",.1,.3,!1);t&&r.push(t)}if(r.length>0)throw new v(r)}function oe(e){let r=[];if(e.margin!==void 0){let t=x(e.margin,"margin",0,null,!0);t&&r.push(t)}if(e.darkChar!==void 0&&typeof e.darkChar!="string"&&r.push({field:"darkChar",value:e.darkChar,message:"must be a string"}),e.lightChar!==void 0&&typeof e.lightChar!="string"&&r.push({field:"lightChar",value:e.lightChar,message:"must be a string"}),r.length>0)throw new v(r)}var p={size:300,margin:24,backgroundColor:"#ffffff",eyes:{shape:"square",color:"#000000"},pupils:{color:"#000000"},dots:{shape:"classic",color:"#000000",scale:1},logo:{scale:.2},border:{shape:"none",width:10,color:"#000000",style:"solid"},output:{format:"png",type:"buffer"}},T={margin:2,darkChar:"\u2588\u2588",lightChar:" "};function se(e){if(!e){let{logo:t,...o}=p;return o}return ne(e),{size:e.size??p.size,margin:e.margin??p.margin,backgroundColor:e.backgroundColor??p.backgroundColor,eyes:{shape:e.eyes?.shape??p.eyes.shape,color:e.eyes?.color??p.eyes.color},pupils:{color:e.pupils?.color??p.pupils.color},dots:{shape:e.dots?.shape??p.dots.shape,color:e.dots?.color??p.dots.color,scale:e.dots?.scale??p.dots.scale},logo:e.logo?{src:e.logo.src,scale:e.logo.scale??p.logo.scale}:void 0,border:{shape:e.border?.shape??p.border.shape,width:e.border?.width??p.border.width,color:e.border?.color??p.border.color,style:e.border?.style??p.border.style},output:e.output??p.output}}function ae(e){return e?(oe(e),{margin:e.margin??T.margin,darkChar:e.darkChar??T.darkChar,lightChar:e.lightChar??T.lightChar}):{...T}}function ie(e){return/^\d+$/.test(e)?1:[...e].every(r=>S.includes(r))?2:4}function _e(e){let r=[];for(let t=0;t<e.length;t+=3){let o=e.substring(t,Math.min(t+3,e.length)),n=parseInt(o,10),s=o.length===3?10:o.length===2?7:4;for(let a=s-1;a>=0;a--)r.push(n>>a&1)}return r}function Qe(e){let r=[];for(let t=0;t<e.length;t+=2)if(t+1<e.length){let o=S.indexOf(e[t])*45+S.indexOf(e[t+1]);for(let n=10;n>=0;n--)r.push(o>>n&1)}else{let o=S.indexOf(e[t]);for(let n=5;n>=0;n--)r.push(o>>n&1)}return r}function Ge(e){let r=[],t=new TextEncoder().encode(e);for(let o of t)for(let n=7;n>=0;n--)r.push(o>>n&1);return r}function Ue(e,r,t,o){let n=[];for(let a=3;a>=0;a--)n.push(r>>a&1);let s=A(r,o);for(let a=s-1;a>=0;a--)n.push(t>>a&1);return[...n,...e]}function We(e){let r=[];for(let t=0;t<e.length;t+=8){let o=0;for(let n=0;n<8&&t+n<e.length;n++)o=o<<1|e[t+n];t+8>e.length&&(o<<=8-e.length%8),r.push(o)}return r}function je(e,r){let t=[...e],o=[236,17],n=0;for(;t.length<r;)t.push(o[n]),n=1-n;return t}function ce(e,r,t){let o=ie(e),n,s;o===1?(n=_e(e),s=e.length):o===2?(n=Qe(e),s=e.length):(n=Ge(e),s=new TextEncoder().encode(e).length);let a=Ue(n,o,s,r),i=Math.min(4,t*8-a.length);for(let u=0;u<i;u++)a.push(0);for(;a.length%8!==0;)a.push(0);let c=We(a);return je(c,t)}function k(e,r){let t=ie(e),o=t===4?new TextEncoder().encode(e).length:e.length;for(let c=1;c<=10;c++){let u=A(t,c),l=t===1?Math.ceil(o/3)*10-(o%3===1?6:o%3===2?3:0):t===2?Math.floor(o/2)*11+o%2*6:o*8,d=4+u+l;if(Math.ceil(d/8)<=r[c-1])return c}let n=A(t,10),s=t===1?Math.ceil(o/3)*10-(o%3===1?6:o%3===2?3:0):t===2?Math.floor(o/2)*11+o%2*6:o*8,a=4+n+s,i=Math.ceil(a/8);throw new Error(`Input too long for QR code version 10. Required capacity: ${i} bytes, Maximum available: ${r[9]} bytes. Current data length: ${e.length} characters (${o} bytes encoded).`)}function ue(e,r){if(r)try{if(k(e,y.H)<=10)return"H"}catch{throw new Error(`Data too large for QR code with logo. Data length: ${e.length} characters. Maximum capacity with logo (EC level H): ~122 bytes (version 10). Logos require high error correction (H) which reduces data capacity. Consider: reducing data length, removing logo, or using multiple QR codes.`)}let t=["H","Q","M","L"];for(let o of t)try{if(k(e,y[o])<=10)return o}catch{continue}throw new Error(`Data too large for QR code version 10 at any error correction level. Data length: ${e.length} characters. Maximum capacity: ~274 bytes (version 10, EC level L). Please reduce input length or split into multiple QR codes.`)}var w=new Array(256),Q=new Array(256);function He(){let e=1;for(let r=0;r<255;r++)w[r]=e,Q[e]=r,e<<=1,e&256&&(e^=285);for(let r=255;r<512;r++)w[r]=w[r-255]}He();function fe(e,r){return e===0||r===0?0:w[Q[e]+Q[r]]}function Ye(e){let r=[1];for(let t=0;t<e;t++){let o=r.length+1,n=new Array(o).fill(0);for(let s=0;s<r.length;s++)n[s]^=r[s],n[s+1]^=fe(r[s],w[t]);r=n}return r}function le(e,r){let t=Ye(r),o=[...e,...new Array(r).fill(0)];for(let n=0;n<e.length;n++){let s=o[n];if(s!==0)for(let a=0;a<t.length;a++)o[n+a]^=fe(t[a],s)}return o.slice(e.length)}function de(e,r,t){let o=[],n=[],[s,a,i,c]=t,u=0;for(let l=0;l<s;l++){let d=e.slice(u,u+a);o.push(d);let f=le(d,r);n.push(f),u+=a}for(let l=0;l<i;l++){let d=e.slice(u,u+c);o.push(d);let f=le(d,r);n.push(f),u+=c}return{dataBlocks:o,ecBlocks:n}}function me(e,r){let t=[],o=Math.max(...e.map(s=>s.length));for(let s=0;s<o;s++)for(let a of e)s<a.length&&t.push(a[s]);let n=Math.max(...r.map(s=>s.length));for(let s=0;s<n;s++)for(let a of r)s<a.length&&t.push(a[s]);return t}function he(e){let r=R(e);return Array.from({length:r},()=>Array(r).fill(!1))}function ge(e){let r=R(e),t=Array.from({length:r},()=>Array(r).fill(!1));for(let n=0;n<=7;n++)for(let s=0;s<=7;s++)t[n][s]=!0;for(let n=0;n<=7;n++)for(let s=0;s<=7;s++)t[n][r-8+s]=!0;for(let n=0;n<=7;n++)for(let s=0;s<=7;s++)t[r-8+n][s]=!0;for(let n=8;n<r-8;n++)t[6][n]=!0,t[n][6]=!0;t[4*e+9][8]=!0;for(let n=0;n<6;n++)t[n][8]=!0;t[7][8]=!0,t[8][8]=!0;for(let n=r-8;n<r;n++)t[n][8]=!0;for(let n=0;n<9;n++)t[8][n]=!0;for(let n=r-8;n<r;n++)t[8][n]=!0;let o=P[e-1]||[];for(let n of o)for(let s of o)if(!(n<9&&s<9||n<9&&s>r-9||n>r-9&&s<9))for(let i=-2;i<=2;i++)for(let c=-2;c<=2;c++)t[n+i][s+c]=!0;if(e>=7){for(let n=0;n<6;n++)for(let s=r-11;s<r-8;s++)t[n][s]=!0;for(let n=r-11;n<r-8;n++)for(let s=0;s<6;s++)t[n][s]=!0}return t}function G(e,r,t){for(let o=-1;o<=7;o++)for(let n=-1;n<=7;n++){let s=r+o,a=t+n;if(s<0||s>=e.length||a<0||a>=e.length)continue;let i=o>=0&&o<=6&&n>=0&&n<=6&&(o===0||o===6||n===0||n===6),c=o>=2&&o<=4&&n>=2&&n<=4;e[s][a]=i||c}}function Xe(e,r,t){for(let o=-2;o<=2;o++)for(let n=-2;n<=2;n++){let s=o===-2||o===2||n===-2||n===2,a=o===0&&n===0;e[r+o][t+n]=s||a}}function be(e){let r=e.length;for(let t=8;t<r-8;t++)e[6][t]=t%2===0,e[t][6]=t%2===0}function pe(e){G(e,0,0),G(e,0,e.length-7),G(e,e.length-7,0)}function $e(e,r){let t=e.length,o=P[r-1]||[];for(let n of o)for(let s of o)n<9&&s<9||n<9&&s>t-9||n>t-9&&s<9||Xe(e,n,s)}function Ce(e,r){e[4*r+9][8]=!0}function Me(e,r,t){let o=e.length,n=0,s=-1,a=o-1;for(let i=o-1;i>0;i-=2)for(i===6&&i--;;){for(let c=0;c<2;c++)if(!r[a][i-c]){let u=n<t.length?t[n]:!1;e[a][i-c]=u,n++}if(a+=s,a<0||o<=a){a-=s,s=-s;break}}}function U(e,r,t){let o=e.length;for(let n=0;n<o;n++)for(let s=0;s<o;s++){if(r[n][s])continue;let a=!1;switch(t){case 0:a=(n+s)%2===0;break;case 1:a=n%2===0;break;case 2:a=s%3===0;break;case 3:a=(n+s)%3===0;break;case 4:a=(Math.floor(n/2)+Math.floor(s/3))%2===0;break;case 5:a=n*s%2+n*s%3===0;break;case 6:a=(n*s%2+n*s%3)%2===0;break;case 7:a=((n+s)%2+n*s%3)%2===0;break}a&&(e[n][s]=!e[n][s])}}function Ze(e){let r=e.length,t=0;for(let a=0;a<r;a++){let i=e[a][0],c=e[0][a],u=1,l=1;for(let d=1;d<r;d++)e[a][d]===i?u++:(u>=5&&(t+=3+(u-5)),i=e[a][d],u=1),e[d][a]===c?l++:(l>=5&&(t+=3+(l-5)),c=e[d][a],l=1);u>=5&&(t+=3+(u-5)),l>=5&&(t+=3+(l-5))}for(let a=0;a<r-1;a++)for(let i=0;i<r-1;i++){let c=e[a][i];e[a][i+1]===c&&e[a+1][i]===c&&e[a+1][i+1]===c&&(t+=3)}for(let a=0;a<r;a++){let i=0,c=0;for(let u=0;u<r;u++)i=i<<1&2047|(e[a][u]?1:0),u>=10&&(i===1488||i===93)&&(t+=40),c=c<<1&2047|(e[u][a]?1:0),u>=10&&(c===1488||c===93)&&(t+=40)}let o=0,n=r*r;for(let a=0;a<r;a++)for(let i=0;i<r;i++)e[a][i]&&o++;let s=Math.abs(Math.ceil(o*100/n/5)-10);return t+=s*10,t}function ye(e,r,t,o){let n=0,s=1/0;for(let a=0;a<8;a++){let i=e.map(u=>[...u]);U(i,r,a),o(i,t,a);let c=Ze(i);c<s&&(s=c,n=a)}return n}function W(e,r,t){let o=e.length,n=N[r]<<3|t,s=n<<10;for(let i=0;i<5;i++)s&1<<14-i&&(s^=1335<<4-i);let a=(n<<10|s)^21522;for(let i=0;i<15;i++){let c=(a>>14-i&1)===1;i<=5?e[8][i]=c:i===6?e[8][7]=c:i===7?e[8][8]=c:i===8?e[7][8]=c:e[5-(i-9)][8]=c,i<=6?e[o-1-i][8]=c:e[8][o-8+(i-7)]=c}}function xe(e,r){if(r<7)return;let t=e.length,o=Z[r-7];for(let n=0;n<18;n++){let s=(o>>n&1)===1,a=Math.floor(n/3),i=t-11+n%3;e[a][i]=s;let c=t-11+n%3,u=Math.floor(n/3);e[c][u]=s}}function Se(e,r){return N[e]<<3|r}function Re(e,r,t,o,n){let s=he(e),a=ge(e);pe(s),be(s),$e(s,e),Ce(s,e),Me(s,a,t);let i=n?s.map(u=>[...u]):void 0,c=o??ye(s,a,r,W);return U(s,a,c),W(s,r,c),xe(s,e),{matrix:s,mask:c,formatInfo:n?Se(r,c):void 0,unmaskedMatrix:i}}function j(e,r,t){return e<7&&r<7||e<7&&r>=t-7||e>=t-7&&r<7}function Ie(e){return[{x:0,y:0},{x:e-7,y:0},{x:0,y:e-7}]}function Ee(e,r){let o=Math.max(.1,Math.min(.3,r));return e*o}function Ke(e,r,t,o,n,s,a){let i=I[t]||I.square,c=i.renderSVG(e,r,7*a,o),u=i.renderSVG(e+a,r+a,5*a,s),l=i.renderSVG(e+2*a,r+2*a,3*a,n);return c+u+l}function Je(e,r,t,o){let n=o/2;if(e.includes("data:image/svg")||e.trim().startsWith("<svg")){let s=e;if(e.includes("data:image/svg")){let u=e.match(/data:image\/svg\+xml[^,]*,(.+)/);if(u)try{s=decodeURIComponent(u[1])}catch{return""}}let a=s.match(/viewBox=["']([^"']+)["']/),i=a?a[1]:"0 0 100 100",c=s.replace(/<\?xml[^>]*>|<svg[^>]*>|<\/svg>/gi,"");return`<g transform="translate(${r-n}, ${t-n})">
21
+ <svg width="${o}" height="${o}" viewBox="${i}">
22
+ ${c}
23
+ </svg>
24
+ </g>`}else return`<image x="${r-n}" y="${t-n}" width="${o}" height="${o}" href="${e}" preserveAspectRatio="xMidYMid meet"/>`}function et(e,r,t,o,n){let s=e.matrixSize,a="",i=E[t]||E.classic;if(t==="classic"){a=`<path fill="${o}" d="`;for(let c=0;c<s;c++)for(let u=0;u<s;u++)if(e.modules[c][u]&&!j(c,u,s)){let l=u*r,d=c*r,f=n*r,m=(1-n)*r/2,h=l+m,g=d+m;a+=`M${h},${g}h${f}v${f}h${-f}z`}return a+='"/>',a}for(let c=0;c<s;c++)for(let u=0;u<s;u++)if(e.modules[c][u]&&!j(c,u,s)){let l=u*r,d=c*r,f=n*r,m=(1-n)*r/2,h=l+m,g=d+m,b={qrcode:e.modules,qrSize:s,row:c,col:u};a+=i.renderSVG(h,g,f,o,b)}return a}function Oe(e,r){let{size:t,margin:o,backgroundColor:n,eyes:s,pupils:a,dots:i}=r,c=t/e.matrixSize,u=r.border.shape==="none"?0:r.border.width,l=t+2*o+2*u,d=o+u,f=`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${l} ${l}" width="${l}" height="${l}">`;if(f+=`<rect width="${l}" height="${l}" fill="${n}"/>`,r.border.shape!=="none"&&u>0){let $=L[r.border.shape];if($){let C={borderWidth:u,borderStyle:r.border.style};f+=$.renderSVG(0,0,l,r.border.color,C)}}r.border.shape!=="none"&&u>0&&(f+=`<rect x="${d}" y="${d}" width="${t}" height="${t}" fill="${n}"/>`),f+=`<g transform="translate(${d}, ${d})">`;let m=Ie(e.matrixSize),h="";for(let $ of m)h+=Ke($.x*c,$.y*c,s.shape,s.color,a.color,n,c);let g=et(e,c,i.shape,i.color,i.scale);f+=h+g+"</g>";let b="";if(r.logo){let $=Ee(e.matrixSize,r.logo.scale)*c,C=l/2;b=Je(r.logo.src,C,C,$)}return f+=b+"</svg>",f}function ve(e,r){let{margin:t,lightChar:o,darkChar:n}=r,s="",a=e.matrixSize+t*2;for(let i=0;i<t;i++)s+=o.repeat(a)+`
25
+ `;for(let i=0;i<e.matrixSize;i++){s+=o.repeat(t);for(let c=0;c<e.matrixSize;c++)s+=e.modules[i][c]?n:o;s+=o.repeat(t)+`
26
+ `}for(let i=0;i<t;i++)s+=o.repeat(a)+`
27
+ `;return s}var D=null,we=!1;async function tt(){if(D)return D;if(we)throw new Error("PNG generation in Node.js requires @resvg/resvg-js. Install with: npm install @resvg/resvg-js");we=!0;try{return D=(await import("@resvg/resvg-js")).Resvg,D}catch{throw new Error("PNG generation in Node.js requires @resvg/resvg-js. Install with: npm install @resvg/resvg-js")}}async function Pe(e,r){let{output:t,size:o,margin:n,border:s}=r,a=s.shape==="none"?0:s.width,i=o+2*n+2*a,c=await tt(),d=new c(e,{fitTo:{mode:"width",value:i}}).render().asPng(),f=Buffer.from(d);return t.type==="dataURL"?`data:image/png;base64,${f.toString("base64")}`:f}async function Ae(e,r){let{format:t,type:o}=r.output;return t==="svg"?o==="string"?e:`data:image/svg+xml;charset=utf-8,${encodeURIComponent(e)}`:await Pe(e,r)}function H(e){if(typeof e=="string")return e;switch(e.type){case"url":return rt(e.url);case"vcard":return nt(e.data);case"wifi":return ot(e.data);case"calendar":return st(e.data);case"email":return at(e.email,e.subject,e.body);case"sms":return it(e.phone,e.message);case"phone":return ct(e.phone)}}function rt(e){return!e.startsWith("http://")&&!e.startsWith("https://")?`https://${e}`:e}function nt(e){let r=["BEGIN:VCARD","VERSION:3.0",`FN:${e.name}`];if(e.phone&&r.push(`TEL:${e.phone}`),e.email&&r.push(`EMAIL:${e.email}`),e.organization&&r.push(`ORG:${e.organization}`),e.url&&r.push(`URL:${e.url}`),e.title&&r.push(`TITLE:${e.title}`),e.note&&r.push(`NOTE:${e.note}`),e.address){let{street:t,city:o,state:n,zip:s,country:a}=e.address,i=["","",t||"",o||"",n||"",s||"",a||""];r.push(`ADR:${i.join(";")}`)}return r.push("END:VCARD"),r.join(`
28
+ `)}function ot(e){let r=e.encryption||"WPA",t=e.hidden?"H:true;":"",o=Le(e.ssid),n=Le(e.password);return`WIFI:T:${r};S:${o};P:${n};${t};`}function Le(e){return e.replace(/([\\;,":])/g,"\\$1")}function st(e){let r=o=>(typeof o=="string"?new Date(o):o).toISOString().replace(/[-:]/g,"").split(".")[0]+"Z",t=["BEGIN:VCALENDAR","VERSION:2.0","BEGIN:VEVENT",`SUMMARY:${e.title}`,`DTSTART:${r(e.startDate)}`,`DTEND:${r(e.endDate)}`];return e.location&&t.push(`LOCATION:${e.location}`),e.description&&t.push(`DESCRIPTION:${e.description}`),t.push("END:VEVENT","END:VCALENDAR"),t.join(`
29
+ `)}function at(e,r,t){let o=`mailto:${e}`,n=[];return r&&n.push(`subject=${encodeURIComponent(r)}`),t&&n.push(`body=${encodeURIComponent(t)}`),n.length>0&&(o+=`?${n.join("&")}`),o}function it(e,r){return r?`sms:${e}:${r}`:`sms:${e}`}function ct(e){return`tel:${e}`}function ut(e,r){let t=[];for(let n of e)for(let s=7;s>=0;s--)t.push((n>>s&1)===1);let o=K[r-1];for(let n=0;n<o;n++)t.push(!1);return t}function Te(e,r){if(!e)throw new Error("QR Code input cannot be empty. Please provide text or structured content to encode.");let t=ue(e,r),o=y[t],n=k(e,o);if(n<1||n>10)throw new Error(`Input data is too large for QR code version 10. Data length: ${e.length} characters. Maximum capacity at EC level ${t}: ~${y[t][9]} bytes. Try reducing input length or removing logo for higher capacity.`);let s=ce(e,n,o[n-1]),a=Y[t][n-1],i=X[t][n-1],{dataBlocks:c,ecBlocks:u}=de(s,a,i),l=me(c,u),d=ut(l,n),{matrix:f,mask:m}=Re(n,t,d);return{version:n,matrixSize:R(n),modules:f,mask:m,errorCorrectionLevel:t}}async function lt(e,r){let t=H(e),o=se(r),n=Te(t,!!o.logo),s=Oe(n,o);return await Ae(s,o)}function ft(e,r){let t=H(e),o=ae(r),n=Te(t,!1);return ve(n,o)}export{te as BorderShape,re as BorderStyle,ee as DotShape,J as EyeFrameShape,v as QRValidationError,lt as genQrImage,ft as genQrText};
package/package.json ADDED
@@ -0,0 +1,104 @@
1
+ {
2
+ "name": "@tapple.io/qr-code-generator",
3
+ "version": "0.9.0",
4
+ "description": "Lightweight QR code generator with ESM and CommonJS support",
5
+ "files": [
6
+ "dist",
7
+ "README.md",
8
+ "LICENSE"
9
+ ],
10
+ "main": "./dist/node.cjs",
11
+ "module": "./dist/node.mjs",
12
+ "types": "./dist/index.d.ts",
13
+ "exports": {
14
+ ".": {
15
+ "types": "./dist/index.d.ts",
16
+ "browser": "./dist/browser.mjs",
17
+ "node": {
18
+ "import": "./dist/node.mjs",
19
+ "require": "./dist/node.cjs"
20
+ },
21
+ "default": "./dist/node.mjs"
22
+ }
23
+ },
24
+ "scripts": {
25
+ "clean": "rm -rf dist",
26
+ "build": "npm run clean && npm run build:types && npm run build:bundle-types && npm run build:browser && npm run build:node-esm && npm run build:node-cjs",
27
+ "build:types": "node scripts/build-types.mjs",
28
+ "build:bundle-types": "node scripts/bundle-types.mjs",
29
+ "build:browser": "node scripts/build-browser.mjs",
30
+ "build:node-esm": "node scripts/build-node-esm.mjs",
31
+ "build:node-cjs": "node scripts/build-node-cjs.mjs",
32
+ "demo": "npm run build && npx serve . -l 8080",
33
+ "visual-preview": "npm run build && node scripts/visual-preview.mjs",
34
+ "test": "vitest run && npm run test:dist",
35
+ "test:fast": "vitest run",
36
+ "test:unit": "vitest run test/unit",
37
+ "test:integration": "vitest run test/integration",
38
+ "test:e2e": "vitest run test/e2e",
39
+ "test:dist": "npm run test:dist:node && npm run test:dist:browser",
40
+ "test:dist:node": "npm run build && vitest run test/dist/node-*.test.ts",
41
+ "test:dist:browser": "npm run build && playwright test test/dist/browser-e2e.test.ts",
42
+ "test:watch": "vitest",
43
+ "test:ui": "vitest --ui",
44
+ "lint": "eslint src/ test/",
45
+ "lint:fix": "eslint src/ --fix",
46
+ "format": "prettier --write src/",
47
+ "format:check": "prettier --check src/",
48
+ "preversion": "npm run format && npm test && npm run lint",
49
+ "version": "npm run build && git add -A dist",
50
+ "postversion": "git push --follow-tags",
51
+ "prepublishOnly": "npm run build"
52
+ },
53
+ "sideEffects": false,
54
+ "author": {
55
+ "name": "Tapple Inc.",
56
+ "url": "https://tapple.io"
57
+ },
58
+ "license": "MIT",
59
+ "keywords": [
60
+ "qr",
61
+ "qrcode",
62
+ "qr-code",
63
+ "generator",
64
+ "svg",
65
+ "png",
66
+ "ascii",
67
+ "browser",
68
+ "universal"
69
+ ],
70
+ "repository": {
71
+ "type": "git",
72
+ "url": "https://github.com/tappleinc/qr-code-generator.git"
73
+ },
74
+ "bugs": {
75
+ "url": "https://github.com/tappleinc/qr-code-generator/issues"
76
+ },
77
+ "homepage": "https://github.com/tappleinc/qr-code-generator#readme",
78
+ "optionalDependencies": {
79
+ "@resvg/resvg-js": "^2.6.0"
80
+ },
81
+ "devDependencies": {
82
+ "@eslint/js": "^9.39.2",
83
+ "@nuintun/qrcode": "^5.0.2",
84
+ "@playwright/test": "^1.49.0",
85
+ "@types/node": "^25.0.3",
86
+ "@types/pngjs": "^6.0.5",
87
+ "@vitest/ui": "^4.0.16",
88
+ "dts-bundle-generator": "^9.5.1",
89
+ "esbuild": "^0.27.2",
90
+ "eslint": "^9.39.2",
91
+ "eslint-config-prettier": "^10.1.8",
92
+ "globals": "^16.5.0",
93
+ "jsqr": "^1.4.0",
94
+ "pngjs": "^7.0.0",
95
+ "prettier": "^3.7.4",
96
+ "tsx": "^4.19.0",
97
+ "typescript": "^5.3.0",
98
+ "typescript-eslint": "^8.51.0",
99
+ "vitest": "^4.0.16"
100
+ },
101
+ "engines": {
102
+ "node": ">=18.0.0"
103
+ }
104
+ }