label-studio
Version:
Data Labeling Tool that is backend agnostic and can be embedded into your applications
1,445 lines (1,411 loc) • 257 kB
JavaScript
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["jsQR"] = factory();
else
root["jsQR"] = factory();
})(typeof self !== 'undefined' ? self : this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 3);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var BitMatrix = /** @class */ (function () {
function BitMatrix(data, width) {
this.width = width;
this.height = data.length / width;
this.data = data;
}
BitMatrix.createEmpty = function (width, height) {
return new BitMatrix(new Uint8ClampedArray(width * height), width);
};
BitMatrix.prototype.get = function (x, y) {
if (x < 0 || x >= this.width || y < 0 || y >= this.height) {
return false;
}
return !!this.data[y * this.width + x];
};
BitMatrix.prototype.set = function (x, y, v) {
this.data[y * this.width + x] = v ? 1 : 0;
};
BitMatrix.prototype.setRegion = function (left, top, width, height, v) {
for (var y = top; y < top + height; y++) {
for (var x = left; x < left + width; x++) {
this.set(x, y, !!v);
}
}
};
return BitMatrix;
}());
exports.BitMatrix = BitMatrix;
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var GenericGFPoly_1 = __webpack_require__(2);
function addOrSubtractGF(a, b) {
return a ^ b; // tslint:disable-line:no-bitwise
}
exports.addOrSubtractGF = addOrSubtractGF;
var GenericGF = /** @class */ (function () {
function GenericGF(primitive, size, genBase) {
this.primitive = primitive;
this.size = size;
this.generatorBase = genBase;
this.expTable = new Array(this.size);
this.logTable = new Array(this.size);
var x = 1;
for (var i = 0; i < this.size; i++) {
this.expTable[i] = x;
x = x * 2;
if (x >= this.size) {
x = (x ^ this.primitive) & (this.size - 1); // tslint:disable-line:no-bitwise
}
}
for (var i = 0; i < this.size - 1; i++) {
this.logTable[this.expTable[i]] = i;
}
this.zero = new GenericGFPoly_1.default(this, Uint8ClampedArray.from([0]));
this.one = new GenericGFPoly_1.default(this, Uint8ClampedArray.from([1]));
}
GenericGF.prototype.multiply = function (a, b) {
if (a === 0 || b === 0) {
return 0;
}
return this.expTable[(this.logTable[a] + this.logTable[b]) % (this.size - 1)];
};
GenericGF.prototype.inverse = function (a) {
if (a === 0) {
throw new Error("Can't invert 0");
}
return this.expTable[this.size - this.logTable[a] - 1];
};
GenericGF.prototype.buildMonomial = function (degree, coefficient) {
if (degree < 0) {
throw new Error("Invalid monomial degree less than 0");
}
if (coefficient === 0) {
return this.zero;
}
var coefficients = new Uint8ClampedArray(degree + 1);
coefficients[0] = coefficient;
return new GenericGFPoly_1.default(this, coefficients);
};
GenericGF.prototype.log = function (a) {
if (a === 0) {
throw new Error("Can't take log(0)");
}
return this.logTable[a];
};
GenericGF.prototype.exp = function (a) {
return this.expTable[a];
};
return GenericGF;
}());
exports.default = GenericGF;
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var GenericGF_1 = __webpack_require__(1);
var GenericGFPoly = /** @class */ (function () {
function GenericGFPoly(field, coefficients) {
if (coefficients.length === 0) {
throw new Error("No coefficients.");
}
this.field = field;
var coefficientsLength = coefficients.length;
if (coefficientsLength > 1 && coefficients[0] === 0) {
// Leading term must be non-zero for anything except the constant polynomial "0"
var firstNonZero = 1;
while (firstNonZero < coefficientsLength && coefficients[firstNonZero] === 0) {
firstNonZero++;
}
if (firstNonZero === coefficientsLength) {
this.coefficients = field.zero.coefficients;
}
else {
this.coefficients = new Uint8ClampedArray(coefficientsLength - firstNonZero);
for (var i = 0; i < this.coefficients.length; i++) {
this.coefficients[i] = coefficients[firstNonZero + i];
}
}
}
else {
this.coefficients = coefficients;
}
}
GenericGFPoly.prototype.degree = function () {
return this.coefficients.length - 1;
};
GenericGFPoly.prototype.isZero = function () {
return this.coefficients[0] === 0;
};
GenericGFPoly.prototype.getCoefficient = function (degree) {
return this.coefficients[this.coefficients.length - 1 - degree];
};
GenericGFPoly.prototype.addOrSubtract = function (other) {
var _a;
if (this.isZero()) {
return other;
}
if (other.isZero()) {
return this;
}
var smallerCoefficients = this.coefficients;
var largerCoefficients = other.coefficients;
if (smallerCoefficients.length > largerCoefficients.length) {
_a = [largerCoefficients, smallerCoefficients], smallerCoefficients = _a[0], largerCoefficients = _a[1];
}
var sumDiff = new Uint8ClampedArray(largerCoefficients.length);
var lengthDiff = largerCoefficients.length - smallerCoefficients.length;
for (var i = 0; i < lengthDiff; i++) {
sumDiff[i] = largerCoefficients[i];
}
for (var i = lengthDiff; i < largerCoefficients.length; i++) {
sumDiff[i] = GenericGF_1.addOrSubtractGF(smallerCoefficients[i - lengthDiff], largerCoefficients[i]);
}
return new GenericGFPoly(this.field, sumDiff);
};
GenericGFPoly.prototype.multiply = function (scalar) {
if (scalar === 0) {
return this.field.zero;
}
if (scalar === 1) {
return this;
}
var size = this.coefficients.length;
var product = new Uint8ClampedArray(size);
for (var i = 0; i < size; i++) {
product[i] = this.field.multiply(this.coefficients[i], scalar);
}
return new GenericGFPoly(this.field, product);
};
GenericGFPoly.prototype.multiplyPoly = function (other) {
if (this.isZero() || other.isZero()) {
return this.field.zero;
}
var aCoefficients = this.coefficients;
var aLength = aCoefficients.length;
var bCoefficients = other.coefficients;
var bLength = bCoefficients.length;
var product = new Uint8ClampedArray(aLength + bLength - 1);
for (var i = 0; i < aLength; i++) {
var aCoeff = aCoefficients[i];
for (var j = 0; j < bLength; j++) {
product[i + j] = GenericGF_1.addOrSubtractGF(product[i + j], this.field.multiply(aCoeff, bCoefficients[j]));
}
}
return new GenericGFPoly(this.field, product);
};
GenericGFPoly.prototype.multiplyByMonomial = function (degree, coefficient) {
if (degree < 0) {
throw new Error("Invalid degree less than 0");
}
if (coefficient === 0) {
return this.field.zero;
}
var size = this.coefficients.length;
var product = new Uint8ClampedArray(size + degree);
for (var i = 0; i < size; i++) {
product[i] = this.field.multiply(this.coefficients[i], coefficient);
}
return new GenericGFPoly(this.field, product);
};
GenericGFPoly.prototype.evaluateAt = function (a) {
var result = 0;
if (a === 0) {
// Just return the x^0 coefficient
return this.getCoefficient(0);
}
var size = this.coefficients.length;
if (a === 1) {
// Just the sum of the coefficients
this.coefficients.forEach(function (coefficient) {
result = GenericGF_1.addOrSubtractGF(result, coefficient);
});
return result;
}
result = this.coefficients[0];
for (var i = 1; i < size; i++) {
result = GenericGF_1.addOrSubtractGF(this.field.multiply(a, result), this.coefficients[i]);
}
return result;
};
return GenericGFPoly;
}());
exports.default = GenericGFPoly;
/***/ }),
/* 3 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var binarizer_1 = __webpack_require__(4);
var decoder_1 = __webpack_require__(5);
var extractor_1 = __webpack_require__(11);
var locator_1 = __webpack_require__(12);
function scan(matrix) {
var locations = locator_1.locate(matrix);
if (!locations) {
return null;
}
for (var _i = 0, locations_1 = locations; _i < locations_1.length; _i++) {
var location_1 = locations_1[_i];
var extracted = extractor_1.extract(matrix, location_1);
var decoded = decoder_1.decode(extracted.matrix);
if (decoded) {
return {
binaryData: decoded.bytes,
data: decoded.text,
chunks: decoded.chunks,
location: {
topRightCorner: extracted.mappingFunction(location_1.dimension, 0),
topLeftCorner: extracted.mappingFunction(0, 0),
bottomRightCorner: extracted.mappingFunction(location_1.dimension, location_1.dimension),
bottomLeftCorner: extracted.mappingFunction(0, location_1.dimension),
topRightFinderPattern: location_1.topRight,
topLeftFinderPattern: location_1.topLeft,
bottomLeftFinderPattern: location_1.bottomLeft,
bottomRightAlignmentPattern: location_1.alignmentPattern,
},
};
}
}
return null;
}
var defaultOptions = {
inversionAttempts: "attemptBoth",
};
function jsQR(data, width, height, providedOptions) {
if (providedOptions === void 0) { providedOptions = {}; }
var options = defaultOptions;
Object.keys(options || {}).forEach(function (opt) {
options[opt] = providedOptions[opt] || options[opt];
});
var shouldInvert = options.inversionAttempts === "attemptBoth" || options.inversionAttempts === "invertFirst";
var tryInvertedFirst = options.inversionAttempts === "onlyInvert" || options.inversionAttempts === "invertFirst";
var _a = binarizer_1.binarize(data, width, height, shouldInvert), binarized = _a.binarized, inverted = _a.inverted;
var result = scan(tryInvertedFirst ? inverted : binarized);
if (!result && (options.inversionAttempts === "attemptBoth" || options.inversionAttempts === "invertFirst")) {
result = scan(tryInvertedFirst ? binarized : inverted);
}
return result;
}
jsQR.default = jsQR;
exports.default = jsQR;
/***/ }),
/* 4 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var BitMatrix_1 = __webpack_require__(0);
var REGION_SIZE = 8;
var MIN_DYNAMIC_RANGE = 24;
function numBetween(value, min, max) {
return value < min ? min : value > max ? max : value;
}
// Like BitMatrix but accepts arbitry Uint8 values
var Matrix = /** @class */ (function () {
function Matrix(width, height) {
this.width = width;
this.data = new Uint8ClampedArray(width * height);
}
Matrix.prototype.get = function (x, y) {
return this.data[y * this.width + x];
};
Matrix.prototype.set = function (x, y, value) {
this.data[y * this.width + x] = value;
};
return Matrix;
}());
function binarize(data, width, height, returnInverted) {
if (data.length !== width * height * 4) {
throw new Error("Malformed data passed to binarizer.");
}
// Convert image to greyscale
var greyscalePixels = new Matrix(width, height);
for (var x = 0; x < width; x++) {
for (var y = 0; y < height; y++) {
var r = data[((y * width + x) * 4) + 0];
var g = data[((y * width + x) * 4) + 1];
var b = data[((y * width + x) * 4) + 2];
greyscalePixels.set(x, y, 0.2126 * r + 0.7152 * g + 0.0722 * b);
}
}
var horizontalRegionCount = Math.ceil(width / REGION_SIZE);
var verticalRegionCount = Math.ceil(height / REGION_SIZE);
var blackPoints = new Matrix(horizontalRegionCount, verticalRegionCount);
for (var verticalRegion = 0; verticalRegion < verticalRegionCount; verticalRegion++) {
for (var hortizontalRegion = 0; hortizontalRegion < horizontalRegionCount; hortizontalRegion++) {
var sum = 0;
var min = Infinity;
var max = 0;
for (var y = 0; y < REGION_SIZE; y++) {
for (var x = 0; x < REGION_SIZE; x++) {
var pixelLumosity = greyscalePixels.get(hortizontalRegion * REGION_SIZE + x, verticalRegion * REGION_SIZE + y);
sum += pixelLumosity;
min = Math.min(min, pixelLumosity);
max = Math.max(max, pixelLumosity);
}
}
var average = sum / (Math.pow(REGION_SIZE, 2));
if (max - min <= MIN_DYNAMIC_RANGE) {
// If variation within the block is low, assume this is a block with only light or only
// dark pixels. In that case we do not want to use the average, as it would divide this
// low contrast area into black and white pixels, essentially creating data out of noise.
//
// Default the blackpoint for these blocks to be half the min - effectively white them out
average = min / 2;
if (verticalRegion > 0 && hortizontalRegion > 0) {
// Correct the "white background" assumption for blocks that have neighbors by comparing
// the pixels in this block to the previously calculated black points. This is based on
// the fact that dark barcode symbology is always surrounded by some amount of light
// background for which reasonable black point estimates were made. The bp estimated at
// the boundaries is used for the interior.
// The (min < bp) is arbitrary but works better than other heuristics that were tried.
var averageNeighborBlackPoint = (blackPoints.get(hortizontalRegion, verticalRegion - 1) +
(2 * blackPoints.get(hortizontalRegion - 1, verticalRegion)) +
blackPoints.get(hortizontalRegion - 1, verticalRegion - 1)) / 4;
if (min < averageNeighborBlackPoint) {
average = averageNeighborBlackPoint;
}
}
}
blackPoints.set(hortizontalRegion, verticalRegion, average);
}
}
var binarized = BitMatrix_1.BitMatrix.createEmpty(width, height);
var inverted = null;
if (returnInverted) {
inverted = BitMatrix_1.BitMatrix.createEmpty(width, height);
}
for (var verticalRegion = 0; verticalRegion < verticalRegionCount; verticalRegion++) {
for (var hortizontalRegion = 0; hortizontalRegion < horizontalRegionCount; hortizontalRegion++) {
var left = numBetween(hortizontalRegion, 2, horizontalRegionCount - 3);
var top_1 = numBetween(verticalRegion, 2, verticalRegionCount - 3);
var sum = 0;
for (var xRegion = -2; xRegion <= 2; xRegion++) {
for (var yRegion = -2; yRegion <= 2; yRegion++) {
sum += blackPoints.get(left + xRegion, top_1 + yRegion);
}
}
var threshold = sum / 25;
for (var xRegion = 0; xRegion < REGION_SIZE; xRegion++) {
for (var yRegion = 0; yRegion < REGION_SIZE; yRegion++) {
var x = hortizontalRegion * REGION_SIZE + xRegion;
var y = verticalRegion * REGION_SIZE + yRegion;
var lum = greyscalePixels.get(x, y);
binarized.set(x, y, lum <= threshold);
if (returnInverted) {
inverted.set(x, y, !(lum <= threshold));
}
}
}
}
}
if (returnInverted) {
return { binarized: binarized, inverted: inverted };
}
return { binarized: binarized };
}
exports.binarize = binarize;
/***/ }),
/* 5 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var BitMatrix_1 = __webpack_require__(0);
var decodeData_1 = __webpack_require__(6);
var reedsolomon_1 = __webpack_require__(9);
var version_1 = __webpack_require__(10);
// tslint:disable:no-bitwise
function numBitsDiffering(x, y) {
var z = x ^ y;
var bitCount = 0;
while (z) {
bitCount++;
z &= z - 1;
}
return bitCount;
}
function pushBit(bit, byte) {
return (byte << 1) | bit;
}
// tslint:enable:no-bitwise
var FORMAT_INFO_TABLE = [
{ bits: 0x5412, formatInfo: { errorCorrectionLevel: 1, dataMask: 0 } },
{ bits: 0x5125, formatInfo: { errorCorrectionLevel: 1, dataMask: 1 } },
{ bits: 0x5E7C, formatInfo: { errorCorrectionLevel: 1, dataMask: 2 } },
{ bits: 0x5B4B, formatInfo: { errorCorrectionLevel: 1, dataMask: 3 } },
{ bits: 0x45F9, formatInfo: { errorCorrectionLevel: 1, dataMask: 4 } },
{ bits: 0x40CE, formatInfo: { errorCorrectionLevel: 1, dataMask: 5 } },
{ bits: 0x4F97, formatInfo: { errorCorrectionLevel: 1, dataMask: 6 } },
{ bits: 0x4AA0, formatInfo: { errorCorrectionLevel: 1, dataMask: 7 } },
{ bits: 0x77C4, formatInfo: { errorCorrectionLevel: 0, dataMask: 0 } },
{ bits: 0x72F3, formatInfo: { errorCorrectionLevel: 0, dataMask: 1 } },
{ bits: 0x7DAA, formatInfo: { errorCorrectionLevel: 0, dataMask: 2 } },
{ bits: 0x789D, formatInfo: { errorCorrectionLevel: 0, dataMask: 3 } },
{ bits: 0x662F, formatInfo: { errorCorrectionLevel: 0, dataMask: 4 } },
{ bits: 0x6318, formatInfo: { errorCorrectionLevel: 0, dataMask: 5 } },
{ bits: 0x6C41, formatInfo: { errorCorrectionLevel: 0, dataMask: 6 } },
{ bits: 0x6976, formatInfo: { errorCorrectionLevel: 0, dataMask: 7 } },
{ bits: 0x1689, formatInfo: { errorCorrectionLevel: 3, dataMask: 0 } },
{ bits: 0x13BE, formatInfo: { errorCorrectionLevel: 3, dataMask: 1 } },
{ bits: 0x1CE7, formatInfo: { errorCorrectionLevel: 3, dataMask: 2 } },
{ bits: 0x19D0, formatInfo: { errorCorrectionLevel: 3, dataMask: 3 } },
{ bits: 0x0762, formatInfo: { errorCorrectionLevel: 3, dataMask: 4 } },
{ bits: 0x0255, formatInfo: { errorCorrectionLevel: 3, dataMask: 5 } },
{ bits: 0x0D0C, formatInfo: { errorCorrectionLevel: 3, dataMask: 6 } },
{ bits: 0x083B, formatInfo: { errorCorrectionLevel: 3, dataMask: 7 } },
{ bits: 0x355F, formatInfo: { errorCorrectionLevel: 2, dataMask: 0 } },
{ bits: 0x3068, formatInfo: { errorCorrectionLevel: 2, dataMask: 1 } },
{ bits: 0x3F31, formatInfo: { errorCorrectionLevel: 2, dataMask: 2 } },
{ bits: 0x3A06, formatInfo: { errorCorrectionLevel: 2, dataMask: 3 } },
{ bits: 0x24B4, formatInfo: { errorCorrectionLevel: 2, dataMask: 4 } },
{ bits: 0x2183, formatInfo: { errorCorrectionLevel: 2, dataMask: 5 } },
{ bits: 0x2EDA, formatInfo: { errorCorrectionLevel: 2, dataMask: 6 } },
{ bits: 0x2BED, formatInfo: { errorCorrectionLevel: 2, dataMask: 7 } },
];
var DATA_MASKS = [
function (p) { return ((p.y + p.x) % 2) === 0; },
function (p) { return (p.y % 2) === 0; },
function (p) { return p.x % 3 === 0; },
function (p) { return (p.y + p.x) % 3 === 0; },
function (p) { return (Math.floor(p.y / 2) + Math.floor(p.x / 3)) % 2 === 0; },
function (p) { return ((p.x * p.y) % 2) + ((p.x * p.y) % 3) === 0; },
function (p) { return ((((p.y * p.x) % 2) + (p.y * p.x) % 3) % 2) === 0; },
function (p) { return ((((p.y + p.x) % 2) + (p.y * p.x) % 3) % 2) === 0; },
];
function buildFunctionPatternMask(version) {
var dimension = 17 + 4 * version.versionNumber;
var matrix = BitMatrix_1.BitMatrix.createEmpty(dimension, dimension);
matrix.setRegion(0, 0, 9, 9, true); // Top left finder pattern + separator + format
matrix.setRegion(dimension - 8, 0, 8, 9, true); // Top right finder pattern + separator + format
matrix.setRegion(0, dimension - 8, 9, 8, true); // Bottom left finder pattern + separator + format
// Alignment patterns
for (var _i = 0, _a = version.alignmentPatternCenters; _i < _a.length; _i++) {
var x = _a[_i];
for (var _b = 0, _c = version.alignmentPatternCenters; _b < _c.length; _b++) {
var y = _c[_b];
if (!(x === 6 && y === 6 || x === 6 && y === dimension - 7 || x === dimension - 7 && y === 6)) {
matrix.setRegion(x - 2, y - 2, 5, 5, true);
}
}
}
matrix.setRegion(6, 9, 1, dimension - 17, true); // Vertical timing pattern
matrix.setRegion(9, 6, dimension - 17, 1, true); // Horizontal timing pattern
if (version.versionNumber > 6) {
matrix.setRegion(dimension - 11, 0, 3, 6, true); // Version info, top right
matrix.setRegion(0, dimension - 11, 6, 3, true); // Version info, bottom left
}
return matrix;
}
function readCodewords(matrix, version, formatInfo) {
var dataMask = DATA_MASKS[formatInfo.dataMask];
var dimension = matrix.height;
var functionPatternMask = buildFunctionPatternMask(version);
var codewords = [];
var currentByte = 0;
var bitsRead = 0;
// Read columns in pairs, from right to left
var readingUp = true;
for (var columnIndex = dimension - 1; columnIndex > 0; columnIndex -= 2) {
if (columnIndex === 6) { // Skip whole column with vertical alignment pattern;
columnIndex--;
}
for (var i = 0; i < dimension; i++) {
var y = readingUp ? dimension - 1 - i : i;
for (var columnOffset = 0; columnOffset < 2; columnOffset++) {
var x = columnIndex - columnOffset;
if (!functionPatternMask.get(x, y)) {
bitsRead++;
var bit = matrix.get(x, y);
if (dataMask({ y: y, x: x })) {
bit = !bit;
}
currentByte = pushBit(bit, currentByte);
if (bitsRead === 8) { // Whole bytes
codewords.push(currentByte);
bitsRead = 0;
currentByte = 0;
}
}
}
}
readingUp = !readingUp;
}
return codewords;
}
function readVersion(matrix) {
var dimension = matrix.height;
var provisionalVersion = Math.floor((dimension - 17) / 4);
if (provisionalVersion <= 6) { // 6 and under dont have version info in the QR code
return version_1.VERSIONS[provisionalVersion - 1];
}
var topRightVersionBits = 0;
for (var y = 5; y >= 0; y--) {
for (var x = dimension - 9; x >= dimension - 11; x--) {
topRightVersionBits = pushBit(matrix.get(x, y), topRightVersionBits);
}
}
var bottomLeftVersionBits = 0;
for (var x = 5; x >= 0; x--) {
for (var y = dimension - 9; y >= dimension - 11; y--) {
bottomLeftVersionBits = pushBit(matrix.get(x, y), bottomLeftVersionBits);
}
}
var bestDifference = Infinity;
var bestVersion;
for (var _i = 0, VERSIONS_1 = version_1.VERSIONS; _i < VERSIONS_1.length; _i++) {
var version = VERSIONS_1[_i];
if (version.infoBits === topRightVersionBits || version.infoBits === bottomLeftVersionBits) {
return version;
}
var difference = numBitsDiffering(topRightVersionBits, version.infoBits);
if (difference < bestDifference) {
bestVersion = version;
bestDifference = difference;
}
difference = numBitsDiffering(bottomLeftVersionBits, version.infoBits);
if (difference < bestDifference) {
bestVersion = version;
bestDifference = difference;
}
}
// We can tolerate up to 3 bits of error since no two version info codewords will
// differ in less than 8 bits.
if (bestDifference <= 3) {
return bestVersion;
}
}
function readFormatInformation(matrix) {
var topLeftFormatInfoBits = 0;
for (var x = 0; x <= 8; x++) {
if (x !== 6) { // Skip timing pattern bit
topLeftFormatInfoBits = pushBit(matrix.get(x, 8), topLeftFormatInfoBits);
}
}
for (var y = 7; y >= 0; y--) {
if (y !== 6) { // Skip timing pattern bit
topLeftFormatInfoBits = pushBit(matrix.get(8, y), topLeftFormatInfoBits);
}
}
var dimension = matrix.height;
var topRightBottomRightFormatInfoBits = 0;
for (var y = dimension - 1; y >= dimension - 7; y--) { // bottom left
topRightBottomRightFormatInfoBits = pushBit(matrix.get(8, y), topRightBottomRightFormatInfoBits);
}
for (var x = dimension - 8; x < dimension; x++) { // top right
topRightBottomRightFormatInfoBits = pushBit(matrix.get(x, 8), topRightBottomRightFormatInfoBits);
}
var bestDifference = Infinity;
var bestFormatInfo = null;
for (var _i = 0, FORMAT_INFO_TABLE_1 = FORMAT_INFO_TABLE; _i < FORMAT_INFO_TABLE_1.length; _i++) {
var _a = FORMAT_INFO_TABLE_1[_i], bits = _a.bits, formatInfo = _a.formatInfo;
if (bits === topLeftFormatInfoBits || bits === topRightBottomRightFormatInfoBits) {
return formatInfo;
}
var difference = numBitsDiffering(topLeftFormatInfoBits, bits);
if (difference < bestDifference) {
bestFormatInfo = formatInfo;
bestDifference = difference;
}
if (topLeftFormatInfoBits !== topRightBottomRightFormatInfoBits) { // also try the other option
difference = numBitsDiffering(topRightBottomRightFormatInfoBits, bits);
if (difference < bestDifference) {
bestFormatInfo = formatInfo;
bestDifference = difference;
}
}
}
// Hamming distance of the 32 masked codes is 7, by construction, so <= 3 bits differing means we found a match
if (bestDifference <= 3) {
return bestFormatInfo;
}
return null;
}
function getDataBlocks(codewords, version, ecLevel) {
var ecInfo = version.errorCorrectionLevels[ecLevel];
var dataBlocks = [];
var totalCodewords = 0;
ecInfo.ecBlocks.forEach(function (block) {
for (var i = 0; i < block.numBlocks; i++) {
dataBlocks.push({ numDataCodewords: block.dataCodewordsPerBlock, codewords: [] });
totalCodewords += block.dataCodewordsPerBlock + ecInfo.ecCodewordsPerBlock;
}
});
// In some cases the QR code will be malformed enough that we pull off more or less than we should.
// If we pull off less there's nothing we can do.
// If we pull off more we can safely truncate
if (codewords.length < totalCodewords) {
return null;
}
codewords = codewords.slice(0, totalCodewords);
var shortBlockSize = ecInfo.ecBlocks[0].dataCodewordsPerBlock;
// Pull codewords to fill the blocks up to the minimum size
for (var i = 0; i < shortBlockSize; i++) {
for (var _i = 0, dataBlocks_1 = dataBlocks; _i < dataBlocks_1.length; _i++) {
var dataBlock = dataBlocks_1[_i];
dataBlock.codewords.push(codewords.shift());
}
}
// If there are any large blocks, pull codewords to fill the last element of those
if (ecInfo.ecBlocks.length > 1) {
var smallBlockCount = ecInfo.ecBlocks[0].numBlocks;
var largeBlockCount = ecInfo.ecBlocks[1].numBlocks;
for (var i = 0; i < largeBlockCount; i++) {
dataBlocks[smallBlockCount + i].codewords.push(codewords.shift());
}
}
// Add the rest of the codewords to the blocks. These are the error correction codewords.
while (codewords.length > 0) {
for (var _a = 0, dataBlocks_2 = dataBlocks; _a < dataBlocks_2.length; _a++) {
var dataBlock = dataBlocks_2[_a];
dataBlock.codewords.push(codewords.shift());
}
}
return dataBlocks;
}
function decodeMatrix(matrix) {
var version = readVersion(matrix);
if (!version) {
return null;
}
var formatInfo = readFormatInformation(matrix);
if (!formatInfo) {
return null;
}
var codewords = readCodewords(matrix, version, formatInfo);
var dataBlocks = getDataBlocks(codewords, version, formatInfo.errorCorrectionLevel);
if (!dataBlocks) {
return null;
}
// Count total number of data bytes
var totalBytes = dataBlocks.reduce(function (a, b) { return a + b.numDataCodewords; }, 0);
var resultBytes = new Uint8ClampedArray(totalBytes);
var resultIndex = 0;
for (var _i = 0, dataBlocks_3 = dataBlocks; _i < dataBlocks_3.length; _i++) {
var dataBlock = dataBlocks_3[_i];
var correctedBytes = reedsolomon_1.decode(dataBlock.codewords, dataBlock.codewords.length - dataBlock.numDataCodewords);
if (!correctedBytes) {
return null;
}
for (var i = 0; i < dataBlock.numDataCodewords; i++) {
resultBytes[resultIndex++] = correctedBytes[i];
}
}
try {
return decodeData_1.decode(resultBytes, version.versionNumber);
}
catch (_a) {
return null;
}
}
function decode(matrix) {
if (matrix == null) {
return null;
}
var result = decodeMatrix(matrix);
if (result) {
return result;
}
// Decoding didn't work, try mirroring the QR across the topLeft -> bottomRight line.
for (var x = 0; x < matrix.width; x++) {
for (var y = x + 1; y < matrix.height; y++) {
if (matrix.get(x, y) !== matrix.get(y, x)) {
matrix.set(x, y, !matrix.get(x, y));
matrix.set(y, x, !matrix.get(y, x));
}
}
}
return decodeMatrix(matrix);
}
exports.decode = decode;
/***/ }),
/* 6 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
// tslint:disable:no-bitwise
var BitStream_1 = __webpack_require__(7);
var shiftJISTable_1 = __webpack_require__(8);
var Mode;
(function (Mode) {
Mode["Numeric"] = "numeric";
Mode["Alphanumeric"] = "alphanumeric";
Mode["Byte"] = "byte";
Mode["Kanji"] = "kanji";
Mode["ECI"] = "eci";
})(Mode = exports.Mode || (exports.Mode = {}));
var ModeByte;
(function (ModeByte) {
ModeByte[ModeByte["Terminator"] = 0] = "Terminator";
ModeByte[ModeByte["Numeric"] = 1] = "Numeric";
ModeByte[ModeByte["Alphanumeric"] = 2] = "Alphanumeric";
ModeByte[ModeByte["Byte"] = 4] = "Byte";
ModeByte[ModeByte["Kanji"] = 8] = "Kanji";
ModeByte[ModeByte["ECI"] = 7] = "ECI";
// StructuredAppend = 0x3,
// FNC1FirstPosition = 0x5,
// FNC1SecondPosition = 0x9,
})(ModeByte || (ModeByte = {}));
function decodeNumeric(stream, size) {
var bytes = [];
var text = "";
var characterCountSize = [10, 12, 14][size];
var length = stream.readBits(characterCountSize);
// Read digits in groups of 3
while (length >= 3) {
var num = stream.readBits(10);
if (num >= 1000) {
throw new Error("Invalid numeric value above 999");
}
var a = Math.floor(num / 100);
var b = Math.floor(num / 10) % 10;
var c = num % 10;
bytes.push(48 + a, 48 + b, 48 + c);
text += a.toString() + b.toString() + c.toString();
length -= 3;
}
// If the number of digits aren't a multiple of 3, the remaining digits are special cased.
if (length === 2) {
var num = stream.readBits(7);
if (num >= 100) {
throw new Error("Invalid numeric value above 99");
}
var a = Math.floor(num / 10);
var b = num % 10;
bytes.push(48 + a, 48 + b);
text += a.toString() + b.toString();
}
else if (length === 1) {
var num = stream.readBits(4);
if (num >= 10) {
throw new Error("Invalid numeric value above 9");
}
bytes.push(48 + num);
text += num.toString();
}
return { bytes: bytes, text: text };
}
var AlphanumericCharacterCodes = [
"0", "1", "2", "3", "4", "5", "6", "7", "8",
"9", "A", "B", "C", "D", "E", "F", "G", "H",
"I", "J", "K", "L", "M", "N", "O", "P", "Q",
"R", "S", "T", "U", "V", "W", "X", "Y", "Z",
" ", "$", "%", "*", "+", "-", ".", "/", ":",
];
function decodeAlphanumeric(stream, size) {
var bytes = [];
var text = "";
var characterCountSize = [9, 11, 13][size];
var length = stream.readBits(characterCountSize);
while (length >= 2) {
var v = stream.readBits(11);
var a = Math.floor(v / 45);
var b = v % 45;
bytes.push(AlphanumericCharacterCodes[a].charCodeAt(0), AlphanumericCharacterCodes[b].charCodeAt(0));
text += AlphanumericCharacterCodes[a] + AlphanumericCharacterCodes[b];
length -= 2;
}
if (length === 1) {
var a = stream.readBits(6);
bytes.push(AlphanumericCharacterCodes[a].charCodeAt(0));
text += AlphanumericCharacterCodes[a];
}
return { bytes: bytes, text: text };
}
function decodeByte(stream, size) {
var bytes = [];
var text = "";
var characterCountSize = [8, 16, 16][size];
var length = stream.readBits(characterCountSize);
for (var i = 0; i < length; i++) {
var b = stream.readBits(8);
bytes.push(b);
}
try {
text += decodeURIComponent(bytes.map(function (b) { return "%" + ("0" + b.toString(16)).substr(-2); }).join(""));
}
catch (_a) {
// failed to decode
}
return { bytes: bytes, text: text };
}
function decodeKanji(stream, size) {
var bytes = [];
var text = "";
var characterCountSize = [8, 10, 12][size];
var length = stream.readBits(characterCountSize);
for (var i = 0; i < length; i++) {
var k = stream.readBits(13);
var c = (Math.floor(k / 0xC0) << 8) | (k % 0xC0);
if (c < 0x1F00) {
c += 0x8140;
}
else {
c += 0xC140;
}
bytes.push(c >> 8, c & 0xFF);
text += String.fromCharCode(shiftJISTable_1.shiftJISTable[c]);
}
return { bytes: bytes, text: text };
}
function decode(data, version) {
var _a, _b, _c, _d;
var stream = new BitStream_1.BitStream(data);
// There are 3 'sizes' based on the version. 1-9 is small (0), 10-26 is medium (1) and 27-40 is large (2).
var size = version <= 9 ? 0 : version <= 26 ? 1 : 2;
var result = {
text: "",
bytes: [],
chunks: [],
};
while (stream.available() >= 4) {
var mode = stream.readBits(4);
if (mode === ModeByte.Terminator) {
return result;
}
else if (mode === ModeByte.ECI) {
if (stream.readBits(1) === 0) {
result.chunks.push({
type: Mode.ECI,
assignmentNumber: stream.readBits(7),
});
}
else if (stream.readBits(1) === 0) {
result.chunks.push({
type: Mode.ECI,
assignmentNumber: stream.readBits(14),
});
}
else if (stream.readBits(1) === 0) {
result.chunks.push({
type: Mode.ECI,
assignmentNumber: stream.readBits(21),
});
}
else {
// ECI data seems corrupted
result.chunks.push({
type: Mode.ECI,
assignmentNumber: -1,
});
}
}
else if (mode === ModeByte.Numeric) {
var numericResult = decodeNumeric(stream, size);
result.text += numericResult.text;
(_a = result.bytes).push.apply(_a, numericResult.bytes);
result.chunks.push({
type: Mode.Numeric,
text: numericResult.text,
});
}
else if (mode === ModeByte.Alphanumeric) {
var alphanumericResult = decodeAlphanumeric(stream, size);
result.text += alphanumericResult.text;
(_b = result.bytes).push.apply(_b, alphanumericResult.bytes);
result.chunks.push({
type: Mode.Alphanumeric,
text: alphanumericResult.text,
});
}
else if (mode === ModeByte.Byte) {
var byteResult = decodeByte(stream, size);
result.text += byteResult.text;
(_c = result.bytes).push.apply(_c, byteResult.bytes);
result.chunks.push({
type: Mode.Byte,
bytes: byteResult.bytes,
text: byteResult.text,
});
}
else if (mode === ModeByte.Kanji) {
var kanjiResult = decodeKanji(stream, size);
result.text += kanjiResult.text;
(_d = result.bytes).push.apply(_d, kanjiResult.bytes);
result.chunks.push({
type: Mode.Kanji,
bytes: kanjiResult.bytes,
text: kanjiResult.text,
});
}
}
// If there is no data left, or the remaining bits are all 0, then that counts as a termination marker
if (stream.available() === 0 || stream.readBits(stream.available()) === 0) {
return result;
}
}
exports.decode = decode;
/***/ }),
/* 7 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
// tslint:disable:no-bitwise
Object.defineProperty(exports, "__esModule", { value: true });
var BitStream = /** @class */ (function () {
function BitStream(bytes) {
this.byteOffset = 0;
this.bitOffset = 0;
this.bytes = bytes;
}
BitStream.prototype.readBits = function (numBits) {
if (numBits < 1 || numBits > 32 || numBits > this.available()) {
throw new Error("Cannot read " + numBits.toString() + " bits");
}
var result = 0;
// First, read remainder from current byte
if (this.bitOffset > 0) {
var bitsLeft = 8 - this.bitOffset;
var toRead = numBits < bitsLeft ? numBits : bitsLeft;
var bitsToNotRead = bitsLeft - toRead;
var mask = (0xFF >> (8 - toRead)) << bitsToNotRead;
result = (this.bytes[this.byteOffset] & mask) >> bitsToNotRead;
numBits -= toRead;
this.bitOffset += toRead;
if (this.bitOffset === 8) {
this.bitOffset = 0;
this.byteOffset++;
}
}
// Next read whole bytes
if (numBits > 0) {
while (numBits >= 8) {
result = (result << 8) | (this.bytes[this.byteOffset] & 0xFF);
this.byteOffset++;
numBits -= 8;
}
// Finally read a partial byte
if (numBits > 0) {
var bitsToNotRead = 8 - numBits;
var mask = (0xFF >> bitsToNotRead) << bitsToNotRead;
result = (result << numBits) | ((this.bytes[this.byteOffset] & mask) >> bitsToNotRead);
this.bitOffset += numBits;
}
}
return result;
};
BitStream.prototype.available = function () {
return 8 * (this.bytes.length - this.byteOffset) - this.bitOffset;
};
return BitStream;
}());
exports.BitStream = BitStream;
/***/ }),
/* 8 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.shiftJISTable = {
0x20: 0x0020,
0x21: 0x0021,
0x22: 0x0022,
0x23: 0x0023,
0x24: 0x0024,
0x25: 0x0025,
0x26: 0x0026,
0x27: 0x0027,
0x28: 0x0028,
0x29: 0x0029,
0x2A: 0x002A,
0x2B: 0x002B,
0x2C: 0x002C,
0x2D: 0x002D,
0x2E: 0x002E,
0x2F: 0x002F,
0x30: 0x0030,
0x31: 0x0031,
0x32: 0x0032,
0x33: 0x0033,
0x34: 0x0034,
0x35: 0x0035,
0x36: 0x0036,
0x37: 0x0037,
0x38: 0x0038,
0x39: 0x0039,
0x3A: 0x003A,
0x3B: 0x003B,
0x3C: 0x003C,
0x3D: 0x003D,
0x3E: 0x003E,
0x3F: 0x003F,
0x40: 0x0040,
0x41: 0x0041,
0x42: 0x0042,
0x43: 0x0043,
0x44: 0x0044,
0x45: 0x0045,
0x46: 0x0046,
0x47: 0x0047,
0x48: 0x0048,
0x49: 0x0049,
0x4A: 0x004A,
0x4B: 0x004B,
0x4C: 0x004C,
0x4D: 0x004D,
0x4E: 0x004E,
0x4F: 0x004F,
0x50: 0x0050,
0x51: 0x0051,
0x52: 0x0052,
0x53: 0x0053,
0x54: 0x0054,
0x55: 0x0055,
0x56: 0x0056,
0x57: 0x0057,
0x58: 0x0058,
0x59: 0x0059,
0x5A: 0x005A,
0x5B: 0x005B,
0x5C: 0x00A5,
0x5D: 0x005D,
0x5E: 0x005E,
0x5F: 0x005F,
0x60: 0x0060,
0x61: 0x0061,
0x62: 0x0062,
0x63: 0x0063,
0x64: 0x0064,
0x65: 0x0065,
0x66: 0x0066,
0x67: 0x0067,
0x68: 0x0068,
0x69: 0x0069,
0x6A: 0x006A,
0x6B: 0x006B,
0x6C: 0x006C,
0x6D: 0x006D,
0x6E: 0x006E,
0x6F: 0x006F,
0x70: 0x0070,
0x71: 0x0071,
0x72: 0x0072,
0x73: 0x0073,
0x74: 0x0074,
0x75: 0x0075,
0x76: 0x0076,
0x77: 0x0077,
0x78: 0x0078,
0x79: 0x0079,
0x7A: 0x007A,
0x7B: 0x007B,
0x7C: 0x007C,
0x7D: 0x007D,
0x7E: 0x203E,
0x8140: 0x3000,
0x8141: 0x3001,
0x8142: 0x3002,
0x8143: 0xFF0C,
0x8144: 0xFF0E,
0x8145: 0x30FB,
0x8146: 0xFF1A,
0x8147: 0xFF1B,
0x8148: 0xFF1F,
0x8149: 0xFF01,
0x814A: 0x309B,
0x814B: 0x309C,
0x814C: 0x00B4,
0x814D: 0xFF40,
0x814E: 0x00A8,
0x814F: 0xFF3E,
0x8150: 0xFFE3,
0x8151: 0xFF3F,
0x8152: 0x30FD,
0x8153: 0x30FE,
0x8154: 0x309D,
0x8155: 0x309E,
0x8156: 0x3003,
0x8157: 0x4EDD,
0x8158: 0x3005,
0x8159: 0x3006,
0x815A: 0x3007,
0x815B: 0x30FC,
0x815C: 0x2015,
0x815D: 0x2010,
0x815E: 0xFF0F,
0x815F: 0x005C,
0x8160: 0x301C,
0x8161: 0x2016,
0x8162: 0xFF5C,
0x8163: 0x2026,
0x8164: 0x2025,
0x8165: 0x2018,
0x8166: 0x2019,
0x8167: 0x201C,
0x8168: 0x201D,
0x8169: 0xFF08,
0x816A: 0xFF09,
0x816B: 0x3014,
0x816C: 0x3015,
0x816D: 0xFF3B,
0x816E: 0xFF3D,
0x816F: 0xFF5B,
0x8170: 0xFF5D,
0x8171: 0x3008,
0x8172: 0x3009,
0x8173: 0x300A,
0x8174: 0x300B,
0x8175: 0x300C,
0x8176: 0x300D,
0x8177: 0x300E,
0x8178: 0x300F,
0x8179: 0x3010,
0x817A: 0x3011,
0x817B: 0xFF0B,
0x817C: 0x2212,
0x817D: 0x00B1,
0x817E: 0x00D7,
0x8180: 0x00F7,
0x8181: 0xFF1D,
0x8182: 0x2260,
0x8183: 0xFF1C,
0x8184: 0xFF1E,
0x8185: 0x2266,
0x8186: 0x2267,
0x8187: 0x221E,
0x8188: 0x2234,
0x8189: 0x2642,
0x818A: 0x2640,
0x818B: 0x00B0,
0x818C: 0x2032,
0x818D: 0x2033,
0x818E: 0x2103,
0x818F: 0xFFE5,
0x8190: 0xFF04,
0x8191: 0x00A2,
0x8192: 0x00A3,
0x8193: 0xFF05,
0x8194: 0xFF03,
0x8195: 0xFF06,
0x8196: 0xFF0A,
0x8197: 0xFF20,
0x8198: 0x00A7,
0x8199: 0x2606,
0x819A: 0x2605,
0x819B: 0x25CB,
0x819C: 0x25CF,
0x819D: 0x25CE,
0x819E: 0x25C7,
0x819F: 0x25C6,
0x81A0: 0x25A1,
0x81A1: 0x25A0,
0x81A2: 0x25B3,
0x81A3: 0x25B2,
0x81A4: 0x25BD,
0x81A5: 0x25BC,
0x81A6: 0x203B,
0x81A7: 0x3012,
0x81A8: 0x2192,
0x81A9: 0x2190,
0x81AA: 0x2191,
0x81AB: 0x2193,
0x81AC: 0x3013,
0x81B8: 0x2208,
0x81B9: 0x220B,
0x81BA: 0x2286,
0x81BB: 0x2287,
0x81BC: 0x2282,
0x81BD: 0x2283,
0x81BE: 0x222A,
0x81BF: 0x2229,
0x81C8: 0x2227,
0x81C9: 0x2228,
0x81CA: 0x00AC,
0x81CB: 0x21D2,
0x81CC: 0x21D4,
0x81CD: 0x2200,
0x81CE: 0x2203,
0x81DA: 0x2220,
0x81DB: 0x22A5,
0x81DC: 0x2312,
0x81DD: 0x2202,
0x81DE: 0x2207,
0x81DF: 0x2261,
0x81E0: 0x2252,
0x81E1: 0x226A,
0x81E2: 0x226B,
0x81E3: 0x221A,
0x81E4: 0x223D,
0x81E5: 0x221D,
0x81E6: 0x2235,
0x81E7: 0x222B,
0x81E8: 0x222C,
0x81F0: 0x212B,
0x81F1: 0x2030,
0x81F2: 0x266F,
0x81F3: 0x266D,
0x81F4: 0x266A,
0x81F5: 0x2020,
0x81F6: 0x2021,
0x81F7: 0x00B6,
0x81FC: 0x25EF,
0x824F: 0xFF10,
0x8250: 0xFF11,
0x8251: 0xFF12,
0x8252: 0xFF13,
0x8253: 0xFF14,
0x8254: 0xFF15,
0x8255: 0xFF16,
0x8256: 0xFF17,
0x8257: 0xFF18,
0x8258: 0xFF19,
0x8260: 0xFF21,
0x8261: 0xFF22,
0x8262: 0xFF23,
0x8263: 0xFF24,
0x8264: 0xFF25,
0x8265: 0xFF26,
0x8266: 0xFF27,
0x8267: 0xFF28,
0x8268: 0xFF29,
0x8269: 0xFF2A,
0x826A: 0xFF2B,
0x826B: 0xFF2C,
0x826C: 0xFF2D,
0x826D: 0xFF2E,
0x826E: 0xFF2F,
0x826F: 0xFF30,
0x8270: 0xFF31,
0x8271: 0xFF32,
0x8272: 0xFF33,
0x8273: 0xFF34,
0x8274: 0xFF35,
0x8275: 0xFF36,
0x8276: 0xFF37,
0x8277: 0xFF38,
0x8278: 0xFF39,
0x8279: 0xFF3A,
0x8281: 0xFF41,
0x8282: 0xFF42,
0x8283: 0xFF43,
0x8284: 0xFF44,
0x8285: 0xFF45,
0x8286: 0xFF46,
0x8287: 0xFF47,
0x8288: 0xFF48,
0x8289: 0xFF49,
0x828A: 0xFF4A,
0x828B: 0xFF4B,
0x828C: 0xFF4C,
0x828D: 0xFF4D,
0x828E: 0xFF4E,
0x828F: 0xFF4F,
0x8290: 0xFF50,
0x8291: 0xFF51,
0x8292: 0xFF52,
0x8293: 0xFF53,
0x8294: 0xFF54,
0x8295: 0xFF55,
0x8296: 0xFF56,
0x8297: 0xFF57,
0x8298: 0xFF58,
0x8299: 0xFF59,
0x829A: 0xFF5A,
0x829F: 0x3041,
0x82A0: 0x3042,
0x82A1: 0x3043,
0x82A2: 0x3044,
0x82A3: 0x3045,
0x82A4: 0x3046,
0x82A5: 0x3047,
0x82A6: 0x3048,
0x82A7: 0x3049,
0x82A8: 0x304A,
0x82A9: 0x304B,
0x82AA: 0x304C,
0x82AB: 0x304D,
0x82AC: 0x304E,
0x82AD: 0x304F,
0x82AE: 0x3050,
0x82AF: 0x3051,
0x82B0: 0x3052,
0x82B1: 0x3053,
0x82B2: 0x3054,
0x82B3: 0x3055,
0x82B4: 0x3056,
0x82B5: 0x3057,
0x82B6: 0x3058,
0x82B7: 0x3059,
0x82B8: 0x305A,
0x82B9: 0x305B,
0x82BA: 0x305C,
0x82BB: 0x305D,
0x82BC: 0x305E,
0x82BD: 0x305F,
0x82BE: 0x3060,
0x82BF: 0x3061,
0x82C0: 0x3062,
0x82C1: 0x3063,
0x82C2: 0x3064,
0x82C3: 0x30