solid-qr-code
Version:
Solid component to generate QR codes, based on qrcode.react
1,169 lines (1,158 loc) • 31.2 kB
JavaScript
import { insert, createComponent, effect, setAttribute, use, spread, mergeProps as mergeProps$1, template } from 'solid-js/web';
import { mergeProps, createMemo, For, createEffect, splitProps } from 'solid-js';
// src/index.tsx
// node_modules/.pnpm/scannable@1.1.0/node_modules/scannable/dist/qr/utils/bitUtils.js
function getBytes(buffer) {
const result = [];
while (result.length * 8 < buffer.length)
result.push(0);
buffer.forEach((b, i) => result[i >>> 3] |= b << 7 - (i & 7));
return result;
}
function appendBits(buffer, val, len) {
if (len < 0 || len > 31 || val >>> len != 0)
throw "Value out of range";
for (let i = len - 1; i >= 0; i--)
buffer.push(val >>> i & 1);
}
// node_modules/.pnpm/scannable@1.1.0/node_modules/scannable/dist/qr/utils/constants.js
var ECC_CODEWORDS_PER_BLOCK = Object.freeze([
// Version: (note that index 0 is for padding, and is set to an illegal value)
//0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level
[
-1,
7,
10,
15,
20,
26,
18,
20,
24,
30,
18,
20,
24,
26,
30,
22,
24,
28,
30,
28,
28,
28,
28,
30,
30,
26,
28,
30,
30,
30,
30,
30,
30,
30,
30,
30,
30,
30,
30,
30,
30
],
[
-1,
10,
16,
26,
18,
24,
16,
18,
22,
22,
26,
30,
22,
22,
24,
24,
28,
28,
26,
26,
26,
26,
28,
28,
28,
28,
28,
28,
28,
28,
28,
28,
28,
28,
28,
28,
28,
28,
28,
28,
28
],
[
-1,
13,
22,
18,
26,
18,
24,
18,
22,
20,
24,
28,
26,
24,
20,
30,
24,
28,
28,
26,
30,
28,
30,
30,
30,
30,
28,
30,
30,
30,
30,
30,
30,
30,
30,
30,
30,
30,
30,
30,
30
],
[
-1,
17,
28,
22,
16,
22,
28,
26,
26,
24,
28,
24,
28,
22,
24,
24,
30,
28,
28,
26,
28,
30,
24,
30,
30,
30,
30,
30,
30,
30,
30,
30,
30,
30,
30,
30,
30,
30,
30,
30,
30
]
// High
]);
var MIN_VERSION = 1;
var MAX_VERSION = 40;
var NUM_ERROR_CORRECTION_BLOCKS = Object.freeze([
// Version: (note that index 0 is for padding, and is set to an illegal value)
//0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level
[
-1,
1,
1,
1,
1,
1,
2,
2,
2,
2,
4,
4,
4,
4,
4,
6,
6,
6,
6,
7,
8,
8,
9,
9,
10,
12,
12,
12,
13,
14,
15,
16,
17,
18,
19,
19,
20,
21,
22,
24,
25
],
[
-1,
1,
1,
1,
2,
2,
4,
4,
4,
5,
5,
5,
8,
9,
9,
10,
10,
11,
13,
14,
16,
17,
17,
18,
20,
21,
23,
25,
26,
28,
29,
31,
33,
35,
37,
38,
40,
43,
45,
47,
49
],
[
-1,
1,
1,
2,
2,
4,
4,
6,
6,
8,
8,
8,
10,
12,
16,
12,
17,
16,
18,
21,
20,
23,
23,
25,
27,
29,
34,
34,
35,
38,
40,
43,
45,
48,
51,
53,
56,
59,
62,
65,
68
],
[
-1,
1,
1,
2,
4,
4,
4,
5,
6,
8,
8,
11,
11,
16,
16,
18,
16,
19,
21,
25,
25,
25,
34,
30,
32,
35,
37,
40,
42,
45,
48,
51,
54,
57,
60,
63,
66,
70,
74,
77,
81
]
// High
]);
// node_modules/.pnpm/scannable@1.1.0/node_modules/scannable/dist/qr/utils/errorCorrection.js
function errorCorrection(ordinal, formatBits) {
return { ordinal, formatBits };
}
var CONSTANTS = Object.freeze({
LOW: errorCorrection(0, 1),
MEDIUM: errorCorrection(1, 0),
QUARTILE: errorCorrection(2, 3),
HIGH: errorCorrection(3, 2)
});
function toErrorCorrectionLevel(level) {
return CONSTANTS[level.toUpperCase()];
}
// node_modules/.pnpm/scannable@1.1.0/node_modules/scannable/dist/qr/utils/reedSolomon.js
function multiply(x, y) {
if (x >>> 8 != 0 || y >>> 8 != 0)
throw "Byte out of range";
let z = 0;
for (let i = 7; i >= 0; i--) {
z = z << 1 ^ (z >>> 7) * 285;
z ^= (y >>> i & 1) * x;
}
if (z >>> 8 != 0)
throw "Assertion error";
return z;
}
var ReedSolomonGenerator = class {
// Coefficients of the divisor polynomial, stored from highest to lowest power, excluding the leading term which
// is always 1. For example the polynomial x^3 + 255x^2 + 8x + 93 is stored as the uint8 array {255, 8, 93}.
coefficients = [];
// Creates a Reed-Solomon ECC generator for the given degree. This could be implemented
// as a lookup table over all possible parameter values, instead of as an algorithm.
constructor(degree) {
if (degree < 1 || degree > 255)
throw new RangeError("Degree out of range (1 to 255)");
const coefs = this.coefficients;
for (let i = 0; i < degree - 1; i++)
coefs.push(0);
coefs.push(1);
let root = 1;
for (let i = 0; i < degree; i++) {
for (let j = 0; j < coefs.length; j++) {
coefs[j] = multiply(coefs[j], root);
if (j + 1 < coefs.length)
coefs[j] ^= coefs[j + 1];
}
root = multiply(root, 2);
}
}
// Computes and returns the Reed-Solomon error correction codewords for the given
// sequence of data codewords. The returned object is always a new byte array.
// This method does not alter this object's state (because it is immutable).
getRemainder(data) {
const result = [...this.coefficients].fill(0);
data.forEach((b) => {
const factor = b ^ result.shift();
result.push(0);
for (let i = 0; i < result.length; i++)
result[i] ^= multiply(this.coefficients[i], factor);
});
return result;
}
};
// node_modules/.pnpm/scannable@1.1.0/node_modules/scannable/dist/qr/utils/segmentMode.js
function segmentMode(modeBits, numBitsCharCount) {
return { modeBits, numBitsCharCount };
}
function numCharCountBits(segment, ver) {
if (1 <= ver && ver <= 9)
return segment.numBitsCharCount[0];
else if (10 <= ver && ver <= 26)
return segment.numBitsCharCount[1];
else if (27 <= ver && ver <= 40)
return segment.numBitsCharCount[2];
else
throw RangeError("Version number out of range (1-40)");
}
var CONSTANTS2 = Object.freeze({
NUMERIC: segmentMode(1, [10, 12, 14]),
ALPHANUMERIC: segmentMode(2, [9, 11, 13]),
BYTE: segmentMode(4, [8, 16, 16]),
KANJI: segmentMode(8, [8, 10, 12]),
ECI: segmentMode(7, [0, 0, 0])
});
// node_modules/.pnpm/scannable@1.1.0/node_modules/scannable/dist/qr/utils/segment.js
var NUMERIC_REGEX = /^[0-9]*$/;
var ALPHANUMERIC_REGEX = /^[A-Z0-9 $%*+./:-]*$/;
var ALPHANUMERIC_CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:";
function qrSegment(mode, numChars, bitData) {
if (numChars < 0)
throw "Invalid argument";
return { mode, numChars, bitData };
}
function makeBytes(data) {
const bb = [];
data.forEach((b) => appendBits(bb, b, 8));
return qrSegment(CONSTANTS2.BYTE, data.length, bb);
}
function makeNumeric(digits) {
if (!NUMERIC_REGEX.test(digits))
throw "String contains non-numeric characters";
const bb = [];
let i;
for (i = 0; i + 3 <= digits.length; i += 3)
appendBits(bb, parseInt(digits.substr(i, 3), 10), 10);
const rem = digits.length - i;
if (rem > 0)
appendBits(bb, parseInt(digits.substring(i), 10), rem * 3 + 1);
return qrSegment(CONSTANTS2.NUMERIC, digits.length, bb);
}
function makeAlphanumeric(text) {
if (!ALPHANUMERIC_REGEX.test(text))
throw "String contains unencodable characters in alphanumeric mode";
const bb = [];
let i;
for (i = 0; i + 2 <= text.length; i += 2) {
let temp = ALPHANUMERIC_CHARSET.indexOf(text.charAt(i)) * 45;
temp += ALPHANUMERIC_CHARSET.indexOf(text.charAt(i + 1));
appendBits(bb, temp, 11);
}
if (i < text.length)
appendBits(bb, ALPHANUMERIC_CHARSET.indexOf(text.charAt(i)), 6);
return qrSegment(CONSTANTS2.ALPHANUMERIC, text.length, bb);
}
function getTotalBits(segs, version) {
if (version < MIN_VERSION || version > MAX_VERSION)
throw "Version number out of range";
let result = 0;
for (const seg of segs) {
const ccbits = numCharCountBits(seg.mode, version);
if (seg.numChars >= 1 << ccbits)
return null;
result += 4 + ccbits + seg.bitData.length;
}
return result;
}
function toUtf8ByteArray(str) {
str = encodeURI(str);
const result = [];
for (let i = 0; i < str.length; i++) {
if (str.charAt(i) != "%")
result.push(str.charCodeAt(i));
else {
result.push(parseInt(str.substr(i + 1, 2), 16));
i += 2;
}
}
return result;
}
function makeSegments(text) {
if (text == "")
return [];
else if (NUMERIC_REGEX.test(text))
return [makeNumeric(text)];
else if (ALPHANUMERIC_REGEX.test(text))
return [makeAlphanumeric(text)];
else
return [makeBytes(toUtf8ByteArray(text))];
}
// node_modules/.pnpm/scannable@1.1.0/node_modules/scannable/dist/qr/internal.js
function getBit(x, i) {
return (x >>> i & 1) != 0;
}
function getAlignmentPatternPositions(version) {
if (version < MIN_VERSION || version > MAX_VERSION)
throw "Version number out of range";
else if (version == 1)
return [];
else {
const size = version * 4 + 17;
const numAlign = Math.floor(version / 7) + 2;
const step = version == 32 ? 26 : Math.ceil((size - 13) / (numAlign * 2 - 2)) * 2;
const result = [6];
for (let i = 0, pos = size - 7; i < numAlign - 1; i++, pos -= step)
result.splice(1, 0, pos);
return result;
}
}
function getNumRawDataModules(ver) {
if (ver < MIN_VERSION || ver > MAX_VERSION)
throw "Version number out of range";
let result = (16 * ver + 128) * ver + 64;
if (ver >= 2) {
const numAlign = Math.floor(ver / 7) + 2;
result -= (25 * numAlign - 10) * numAlign - 55;
if (ver >= 7)
result -= 18 * 2;
}
return result;
}
function getNumDataCodewords(ver, ecl) {
if (ver < MIN_VERSION || ver > MAX_VERSION)
throw "Version number out of range";
return Math.floor(getNumRawDataModules(ver) / 8) - ECC_CODEWORDS_PER_BLOCK[ecl.ordinal][ver] * NUM_ERROR_CORRECTION_BLOCKS[ecl.ordinal][ver];
}
var PENALTY_N1 = 3;
var PENALTY_N2 = 3;
var PENALTY_N3 = 40;
var PENALTY_N4 = 10;
function setFunctionModule(x, y, isBlack, modules, isFunction) {
modules[y][x] = isBlack;
isFunction[y][x] = true;
}
function drawFormatBits(mask, errorCorrectionLevel, size, modules, isFunction) {
const data = errorCorrectionLevel.formatBits << 3 | mask;
let rem = data;
for (let i = 0; i < 10; i++)
rem = rem << 1 ^ (rem >>> 9) * 1335;
const bits = (data << 10 | rem) ^ 21522;
if (bits >>> 15 != 0)
throw "Assertion error";
for (let i = 0; i <= 5; i++)
setFunctionModule(8, i, getBit(bits, i), modules, isFunction);
setFunctionModule(8, 7, getBit(bits, 6), modules, isFunction);
setFunctionModule(8, 8, getBit(bits, 7), modules, isFunction);
setFunctionModule(7, 8, getBit(bits, 8), modules, isFunction);
for (let i = 9; i < 15; i++)
setFunctionModule(14 - i, 8, getBit(bits, i), modules, isFunction);
for (let i = 0; i <= 7; i++)
setFunctionModule(size - 1 - i, 8, getBit(bits, i), modules, isFunction);
for (let i = 8; i < 15; i++)
setFunctionModule(8, size - 15 + i, getBit(bits, i), modules, isFunction);
setFunctionModule(8, size - 8, true, modules, isFunction);
}
function drawVersion(version, size, modules, isFunction) {
if (version < 7)
return;
let rem = version;
for (let i = 0; i < 12; i++)
rem = rem << 1 ^ (rem >>> 11) * 7973;
const bits = version << 12 | rem;
if (bits >>> 18 != 0)
throw "Assertion error";
for (let i = 0; i < 18; i++) {
const bt = getBit(bits, i);
const a = size - 11 + i % 3;
const b = Math.floor(i / 3);
setFunctionModule(a, b, bt, modules, isFunction);
setFunctionModule(b, a, bt, modules, isFunction);
}
}
function drawFinderPattern(x, y, size, modules, isFunction) {
for (let i = -4; i <= 4; i++) {
for (let j = -4; j <= 4; j++) {
const dist = Math.max(Math.abs(i), Math.abs(j));
const xx = x + j;
const yy = y + i;
if (0 <= xx && xx < size && 0 <= yy && yy < size)
setFunctionModule(xx, yy, dist != 2 && dist != 4, modules, isFunction);
}
}
}
function drawAlignmentPattern(x, y, modules, isFunction) {
for (let i = -2; i <= 2; i++) {
for (let j = -2; j <= 2; j++)
setFunctionModule(x + j, y + i, Math.max(Math.abs(i), Math.abs(j)) != 1, modules, isFunction);
}
}
function drawFunctionPatterns(size, version, errorCorrectionLevel, modules, isFunction) {
for (let i = 0; i < size; i++) {
setFunctionModule(6, i, i % 2 == 0, modules, isFunction);
setFunctionModule(i, 6, i % 2 == 0, modules, isFunction);
}
drawFinderPattern(3, 3, size, modules, isFunction);
drawFinderPattern(size - 4, 3, size, modules, isFunction);
drawFinderPattern(3, size - 4, size, modules, isFunction);
const alignPatPos = getAlignmentPatternPositions(version);
const numAlign = alignPatPos.length;
for (let i = 0; i < numAlign; i++) {
for (let j = 0; j < numAlign; j++) {
if (!(i == 0 && j == 0 || i == 0 && j == numAlign - 1 || i == numAlign - 1 && j == 0))
drawAlignmentPattern(alignPatPos[i], alignPatPos[j], modules, isFunction);
}
}
drawFormatBits(0, errorCorrectionLevel, size, modules, isFunction);
drawVersion(version, size, modules, isFunction);
}
function addEccAndInterleave(data, version, errorCorrectionLevel) {
if (data.length != getNumDataCodewords(version, errorCorrectionLevel))
throw "Invalid argument";
const numBlocks = NUM_ERROR_CORRECTION_BLOCKS[errorCorrectionLevel.ordinal][version];
const blockEccLen = ECC_CODEWORDS_PER_BLOCK[errorCorrectionLevel.ordinal][version];
const rawCodewords = Math.floor(getNumRawDataModules(version) / 8);
const numShortBlocks = numBlocks - rawCodewords % numBlocks;
const shortBlockLen = Math.floor(rawCodewords / numBlocks);
const blocks = [];
const rs = new ReedSolomonGenerator(blockEccLen);
for (let i = 0, k = 0; i < numBlocks; i++) {
const dat = data.slice(k, k + shortBlockLen - blockEccLen + (i < numShortBlocks ? 0 : 1));
k += dat.length;
const ecc = rs.getRemainder(dat);
if (i < numShortBlocks)
dat.push(0);
ecc.forEach((b) => dat.push(b));
blocks.push(dat);
}
const result = [];
for (let i = 0; i < blocks[0].length; i++) {
for (let j = 0; j < blocks.length; j++) {
if (i != shortBlockLen - blockEccLen || j >= numShortBlocks)
result.push(blocks[j][i]);
}
}
if (result.length != rawCodewords)
throw "Assertion error";
return result;
}
function drawCodewords(data, version, size, isFunction, modules) {
if (data.length != Math.floor(getNumRawDataModules(version) / 8))
throw "Invalid argument";
let i = 0;
for (let right = size - 1; right >= 1; right -= 2) {
if (right == 6)
right = 5;
for (let vert = 0; vert < size; vert++) {
for (let j = 0; j < 2; j++) {
const x = right - j;
const upward = (right + 1 & 2) == 0;
const y = upward ? size - 1 - vert : vert;
if (!isFunction[y][x] && i < data.length * 8) {
modules[y][x] = getBit(data[i >>> 3], 7 - (i & 7));
i++;
}
}
}
}
if (i != data.length * 8)
throw "Assertion error";
}
function applyMask(mask, size, modules, isFunction) {
if (mask < 0 || mask > 7)
throw "Mask value out of range";
for (let y = 0; y < size; y++) {
for (let x = 0; x < size; x++) {
let invert;
switch (mask) {
case 0:
invert = (x + y) % 2 == 0;
break;
case 1:
invert = y % 2 == 0;
break;
case 2:
invert = x % 3 == 0;
break;
case 3:
invert = (x + y) % 3 == 0;
break;
case 4:
invert = (Math.floor(x / 3) + Math.floor(y / 2)) % 2 == 0;
break;
case 5:
invert = x * y % 2 + x * y % 3 == 0;
break;
case 6:
invert = (x * y % 2 + x * y % 3) % 2 == 0;
break;
case 7:
invert = ((x + y) % 2 + x * y % 3) % 2 == 0;
break;
default:
throw "Assertion error";
}
if (invert && !isFunction[y][x])
modules[y][x] = !modules[y][x];
}
}
}
function getPenaltyScore(size, modules) {
let result = 0;
for (let y = 0; y < size; y++) {
for (let x = 0, runX = 0, colorX = false; x < size; x++) {
if (x == 0 || modules[y][x] != colorX) {
colorX = modules[y][x];
runX = 1;
} else {
runX++;
if (runX == 5)
result += PENALTY_N1;
else if (runX > 5)
result++;
}
}
}
for (let x = 0; x < size; x++) {
for (let y = 0, runY = 0, colorY = false; y < size; y++) {
if (y == 0 || modules[y][x] != colorY) {
colorY = modules[y][x];
runY = 1;
} else {
runY++;
if (runY == 5)
result += PENALTY_N1;
else if (runY > 5)
result++;
}
}
}
for (let y = 0; y < size - 1; y++) {
for (let x = 0; x < size - 1; x++) {
const color = modules[y][x];
if (color == modules[y][x + 1] && color == modules[y + 1][x] && color == modules[y + 1][x + 1])
result += PENALTY_N2;
}
}
for (let y = 0; y < size; y++) {
for (let x = 0, bits = 0; x < size; x++) {
bits = bits << 1 & 2047 | (modules[y][x] ? 1 : 0);
if (x >= 10 && (bits == 93 || bits == 1488))
result += PENALTY_N3;
}
}
for (let x = 0; x < size; x++) {
for (let y = 0, bits = 0; y < size; y++) {
bits = bits << 1 & 2047 | (modules[y][x] ? 1 : 0);
if (y >= 10 && (bits == 93 || bits == 1488))
result += PENALTY_N3;
}
}
let black = 0;
modules.forEach((row) => {
row.forEach((color) => {
if (color)
black++;
});
});
const total = size * size;
const k = Math.ceil(Math.abs(black * 20 - total * 10) / total) - 1;
result += k * PENALTY_N4;
return result;
}
function qrCode(datacodewords, mask, version, errorCorrectionLevel) {
if (mask < -1 || mask > 7)
throw "Mask value out of range";
if (version < MIN_VERSION || version > MAX_VERSION)
throw "Version value out of range";
const size = version * 4 + 17;
const modules = [];
const isFunction = [];
const row = [];
for (let i = 0; i < size; i++)
row.push(false);
for (let i = 0; i < size; i++) {
modules.push(row.slice());
isFunction.push(row.slice());
}
drawFunctionPatterns(size, version, errorCorrectionLevel, modules, isFunction);
const allCodewords = addEccAndInterleave(datacodewords, version, errorCorrectionLevel);
drawCodewords(allCodewords, version, size, isFunction, modules);
if (mask == -1) {
let minPenalty = Number.MAX_SAFE_INTEGER;
for (let i = 0; i < 8; i++) {
drawFormatBits(i, errorCorrectionLevel, size, modules, isFunction);
applyMask(i, size, modules, isFunction);
const penalty = getPenaltyScore(size, modules);
if (penalty < minPenalty) {
mask = i;
minPenalty = penalty;
}
applyMask(i, size, modules, isFunction);
}
}
if (mask < 0 || mask > 7)
throw "Assertion error";
drawFormatBits(mask, errorCorrectionLevel, size, modules, isFunction);
applyMask(mask, size, modules, isFunction);
return {
version,
size,
mask,
errorCorrectionLevel,
modules,
isFunction
};
}
function encodeSegments(segs, ecl, minVersion = 1, maxVersion = 40, mask = -1, boostEcl = true) {
if (!(MIN_VERSION <= minVersion && minVersion <= maxVersion && maxVersion <= MAX_VERSION) || mask < -1 || mask > 7)
throw "Invalid value";
let version;
let dataUsedBits;
for (version = minVersion; ; version++) {
const dataCapacityBits2 = getNumDataCodewords(version, ecl) * 8;
const usedBits = getTotalBits(segs, version);
if (usedBits != null && usedBits <= dataCapacityBits2) {
dataUsedBits = usedBits;
break;
}
if (version >= maxVersion)
throw `Data too long (> ${dataCapacityBits2 / 8} bytes)`;
}
[
CONSTANTS.MEDIUM,
CONSTANTS.QUARTILE,
CONSTANTS.HIGH
].forEach((newEcl) => {
if (boostEcl && dataUsedBits <= getNumDataCodewords(version, newEcl) * 8)
ecl = newEcl;
});
const bb = [];
segs.forEach((seg) => {
appendBits(bb, seg.mode.modeBits, 4);
appendBits(bb, seg.numChars, numCharCountBits(seg.mode, version));
seg.bitData.forEach((b) => bb.push(b));
});
const dataCapacityBits = getNumDataCodewords(version, ecl) * 8;
if (bb.length > dataCapacityBits)
throw "Assertion error";
appendBits(bb, 0, Math.min(4, dataCapacityBits - bb.length));
appendBits(bb, 0, (8 - bb.length % 8) % 8);
if (bb.length % 8 != 0)
throw "Assertion error";
for (let padByte = 236; bb.length < dataCapacityBits; padByte ^= 236 ^ 17)
appendBits(bb, padByte, 8);
return qrCode(getBytes(bb), mask, version, ecl);
}
function encodeText(text, ecl) {
const segs = makeSegments(text);
return encodeSegments(segs, ecl);
}
// node_modules/.pnpm/scannable@1.1.0/node_modules/scannable/dist/qr/Frame.js
var MaskType;
(function(MaskType3) {
MaskType3[MaskType3["ALTERNATING_TILES"] = 0] = "ALTERNATING_TILES";
MaskType3[MaskType3["ALTERNATING_HORIZONTAL_LINES"] = 1] = "ALTERNATING_HORIZONTAL_LINES";
MaskType3[MaskType3["ALTERNATING_VERTICAL_LINES_TWO_GAP"] = 2] = "ALTERNATING_VERTICAL_LINES_TWO_GAP";
MaskType3[MaskType3["DIAGONAL"] = 3] = "DIAGONAL";
MaskType3[MaskType3["FOUR_BY_TWO_RECTANGLE_ALTERNATING"] = 4] = "FOUR_BY_TWO_RECTANGLE_ALTERNATING";
MaskType3[MaskType3["FLOWER_IN_SQAURE"] = 5] = "FLOWER_IN_SQAURE";
MaskType3[MaskType3["DIAGONAL_SQUARE"] = 6] = "DIAGONAL_SQUARE";
MaskType3[MaskType3["ALTERNATING_PUZZLE_PIECE"] = 7] = "ALTERNATING_PUZZLE_PIECE";
})(MaskType || (MaskType = {}));
var defaultFrameOptions = Object.freeze({
level: CONSTANTS.LOW
});
function generateFrame(options) {
const level = options.level ?? defaultFrameOptions.level;
const qrCode2 = encodeText(options.value, typeof level == "string" ? toErrorCorrectionLevel(level) : level);
return {
buffer: Uint8Array.from(qrCode2.modules.map((row) => row.map((bit) => bit ? 1 : 0)).flat()),
size: qrCode2.size,
version: qrCode2.version
};
}
var _tmpl$ = /* @__PURE__ */ template(`<svg>`);
var _tmpl$2 = /* @__PURE__ */ template(`<svg><rect></svg>`, false, true);
var _tmpl$3 = /* @__PURE__ */ template(`<canvas>`);
var _tmpl$4 = /* @__PURE__ */ template(`<h1>`);
var ErrorCorrectionLevel = {
LOW: "low",
MEDIUM: "medium",
QUARTILE: "quartile",
HIGH: "high"
};
var MaskType2 = {
ALTERNATING_TILES: 0,
ALTERNATING_HORIZONTAL_LINES: 1,
ALTERNATING_VERTICAL_LINES_TWO_GAP: 2,
DIAGONAL: 3,
FOUR_BY_TWO_RECTANGLE_ALTERNATING: 4,
FLOWER_IN_SQAURE: 5,
DIAGONAL_SQUARE: 6,
ALTERNATING_PUZZLE_PIECE: 7
};
var QRCodeSVG = (_props) => {
const props = mergeProps({
...defaultFrameOptions,
backgroundColor: "white",
backgroundAlpha: 1,
foregroundColor: "black",
foregroundAlpha: 1,
width: 100,
height: 100
}, _props);
const frame = createMemo(() => generateFrame(props));
const moduleSizeWidth = createMemo(() => props.width / frame().size);
const moduleSizeHeight = createMemo(() => props.height / frame().size);
const rectangles = createMemo(() => {
let rects = [];
for (let i = 0; i < frame().size; i++) {
for (let j = 0; j < frame().size; j++) {
rects = [...rects, {
x: moduleSizeWidth() * i,
y: moduleSizeHeight() * j,
enabled: frame().buffer[j * frame().size + i] === 1
}];
}
}
return rects;
});
return (() => {
var _el$ = _tmpl$();
insert(_el$, createComponent(For, {
get each() {
return rectangles();
},
children: (rectangle) => (() => {
var _el$2 = _tmpl$2();
effect((_p$) => {
var _v$3 = moduleSizeWidth(), _v$4 = moduleSizeHeight(), _v$5 = rectangle.x, _v$6 = rectangle.y, _v$7 = rectangle.enabled ? props.foregroundColor : props.backgroundColor, _v$8 = rectangle.enabled ? props.foregroundAlpha : props.backgroundAlpha;
_v$3 !== _p$.e && setAttribute(_el$2, "width", _p$.e = _v$3);
_v$4 !== _p$.t && setAttribute(_el$2, "height", _p$.t = _v$4);
_v$5 !== _p$.a && setAttribute(_el$2, "x", _p$.a = _v$5);
_v$6 !== _p$.o && setAttribute(_el$2, "y", _p$.o = _v$6);
_v$7 !== _p$.i && ((_p$.i = _v$7) != null ? _el$2.style.setProperty("fill", _v$7) : _el$2.style.removeProperty("fill"));
_v$8 !== _p$.n && ((_p$.n = _v$8) != null ? _el$2.style.setProperty("opacity", _v$8) : _el$2.style.removeProperty("opacity"));
return _p$;
}, {
e: void 0,
t: void 0,
a: void 0,
o: void 0,
i: void 0,
n: void 0
});
return _el$2;
})()
}));
effect((_p$) => {
var _v$ = props.width, _v$2 = props.height;
_v$ !== _p$.e && setAttribute(_el$, "width", _p$.e = _v$);
_v$2 !== _p$.t && setAttribute(_el$, "height", _p$.t = _v$2);
return _p$;
}, {
e: void 0,
t: void 0
});
return _el$;
})();
};
var QRCodeCanvas = (_props) => {
const props = mergeProps({
...defaultFrameOptions,
backgroundColor: "white",
backgroundAlpha: 1,
foregroundColor: "black",
foregroundAlpha: 1,
width: 100,
height: 100,
x: 0,
y: 0
}, _props);
let ref;
const frame = createMemo(() => generateFrame(props));
const rawModuleSizeWidth = createMemo(() => props.width / frame().size);
const rawModuleSizeHeight = createMemo(() => props.height / frame().size);
const offsetX = createMemo(() => rawModuleSizeWidth() % 1 * frame().size / 2);
const offsetY = createMemo(() => rawModuleSizeHeight() % 1 * frame().size / 2);
const moduleSizeWidth = createMemo(() => Math.floor(rawModuleSizeWidth()));
const moduleSizeHeight = createMemo(() => Math.floor(rawModuleSizeHeight()));
createEffect(() => {
const context = ref.getContext("2d");
if (!context) {
return;
}
context.clearRect(0, 0, ref.width, ref.height);
for (let i = 0; i < frame().size; i++) {
for (let j = 0; j < frame().size; j++) {
if (frame().buffer[j * frame().size + i]) {
context.fillStyle = props.foregroundColor;
context.globalAlpha = props.foregroundAlpha;
context.fillRect(offsetX() + moduleSizeWidth() * i + props.x, offsetY() + moduleSizeHeight() * j + props.y, moduleSizeWidth(), moduleSizeHeight());
} else {
context.fillStyle = props.backgroundColor;
context.globalAlpha = props.backgroundAlpha;
context.fillRect(offsetX() + moduleSizeWidth() * i + props.x, offsetY() + moduleSizeHeight() * j + props.y, moduleSizeWidth(), moduleSizeHeight());
}
}
}
});
return (() => {
var _el$3 = _tmpl$3();
use((e) => ref = e, _el$3);
effect((_p$) => {
var _v$9 = props.height, _v$10 = props.width;
_v$9 !== _p$.e && setAttribute(_el$3, "height", _p$.e = _v$9);
_v$10 !== _p$.t && setAttribute(_el$3, "width", _p$.t = _v$10);
return _p$;
}, {
e: void 0,
t: void 0
});
return _el$3;
})();
};
var QRCodeText = (_props) => {
const props = mergeProps({
...defaultFrameOptions,
foregroundChar: "#",
backgroundChar: " "
}, _props);
const [, rest] = splitProps(props, ["foregroundChar", "backgroundChar", "value", "level", "maskType", "innerHTML", "style"]);
const frame = createMemo(() => generateFrame(props));
const qrText = createMemo(() => {
let str = "";
for (let i = 0; i < frame().size; i++) {
for (let j = 0; j < frame().size; j++) {
if (frame().buffer[j * frame().size + i]) {
str += props.foregroundChar;
} else {
str += props.backgroundChar;
}
}
if (i !== frame().size - 1) {
str += "\n";
}
}
str = str.replaceAll("\n", "<br/>").replaceAll(" ", " ");
return str;
});
return (() => {
var _el$4 = _tmpl$4();
spread(_el$4, mergeProps$1({
get style() {
return {
"line-height": "8px",
"letter-spacing": "0",
"font-size": "12px",
"margin-top": "2.5rem",
"margin-bottom": "2.5rem",
"font-family": "monospace",
...typeof props.style === "object" ? props.style : {}
};
},
get innerHTML() {
return qrText();
}
}, rest), false, false);
return _el$4;
})();
};
var QRCodeTwoTone = (_props) => {
const props = mergeProps({
...defaultFrameOptions,
solidCharacter: "\u2588",
solidTopCharacter: "\u2580",
solidBottomCharacter: "\u2584",
emptyCharacter: " "
}, _props);
const [, rest] = splitProps(props, ["value", "level", "maskType", "innerHTML", "style", "solidCharacter", "solidBottomCharacter", "solidTopCharacter", "emptyCharacter"]);
const qrText = createMemo(() => {
const frame = generateFrame(props);
let str = "";
for (let i = 0; i < frame.size; i += 2) {
for (let j = 0; j < frame.size; j++) {
const topExists = frame.buffer[i * frame.size + j];
const bottomExists = frame.buffer[(i + 1) * frame.size + j];
if (topExists && bottomExists) {
str += props.solidCharacter;
} else if (!topExists && bottomExists) {
str += props.solidBottomCharacter;
} else if (topExists && !bottomExists) {
str += props.solidTopCharacter;
} else {
str += props.emptyCharacter;
}
}
if (i !== frame.size - 1) {
str += "\n";
}
}
str = str.replaceAll("\n", "<br/>").replaceAll(" ", " ");
return str;
});
return (() => {
var _el$5 = _tmpl$4();
spread(_el$5, mergeProps$1({
get style() {
return {
"line-height": "12px",
"font-size": "12px",
"margin-top": "2.5rem",
"margin-bottom": "2.5rem",
"font-family": "monospace",
...typeof props.style === "object" ? props.style : {}
};
},
get innerHTML() {
return qrText();
}
}, rest), false, false);
return _el$5;
})();
};
export { ErrorCorrectionLevel, MaskType2 as MaskType, QRCodeCanvas, QRCodeSVG, QRCodeText, QRCodeTwoTone };