├── .prettierignore
├── .eslintrc.yml
├── run
├── .eslintrc.yml
├── listInstalledFonts.js
├── testOCR.js
├── fontAnalysis.js
├── testMRZ.js
├── createFontFingerprint.js
└── testRotation.js
├── demo
├── id1.jpg
├── id2.jpg
├── id3.jpg
├── id4.jpg
├── id5.jpg
├── id6.jpg
├── iwona.png
├── ocrb.png
├── test.odt
├── dejavusans.png
├── driving_CH.jpg
├── passport1.jpg
├── passport2.jpg
├── passport3.jpg
├── passport4.jpg
├── passport5.jpg
├── passport6.jpg
├── passport7.jpg
├── passport8.jpg
└── passport9.jpg
├── .gitignore
├── .travis.yml
├── src
├── util
│ ├── byteArrayToBinary.js
│ ├── loadFontData.js
│ ├── setFingerprintDataOnRoi.js
│ ├── saveFontData.js
│ ├── getFontDataFilename.js
│ ├── loadAllFontData.js
│ ├── getInstalledRegularFonts.js
│ ├── bestMatch.js
│ ├── symbolClasses.js
│ ├── appendFingerprints.js
│ ├── groupRoisPerLine.js
│ ├── tanimotoSimilarity.js
│ ├── generateSymbolImage.js
│ ├── ambiguitySolver.js
│ ├── doOcrOnLines.js
│ └── getLinesFromImage.js
├── index.js
├── runOCR.js
├── runFontAnalysis.js
├── getRotation.js
└── createFontFingerprint.js
├── History.md
├── LICENSE
├── README.md
└── package.json
/.prettierignore:
--------------------------------------------------------------------------------
1 | package*.json
--------------------------------------------------------------------------------
/.eslintrc.yml:
--------------------------------------------------------------------------------
1 | extends: cheminfo
2 |
--------------------------------------------------------------------------------
/run/.eslintrc.yml:
--------------------------------------------------------------------------------
1 | rules:
2 | no-console: off
3 |
--------------------------------------------------------------------------------
/demo/id1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/image-js/ocr-tools/HEAD/demo/id1.jpg
--------------------------------------------------------------------------------
/demo/id2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/image-js/ocr-tools/HEAD/demo/id2.jpg
--------------------------------------------------------------------------------
/demo/id3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/image-js/ocr-tools/HEAD/demo/id3.jpg
--------------------------------------------------------------------------------
/demo/id4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/image-js/ocr-tools/HEAD/demo/id4.jpg
--------------------------------------------------------------------------------
/demo/id5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/image-js/ocr-tools/HEAD/demo/id5.jpg
--------------------------------------------------------------------------------
/demo/id6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/image-js/ocr-tools/HEAD/demo/id6.jpg
--------------------------------------------------------------------------------
/demo/iwona.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/image-js/ocr-tools/HEAD/demo/iwona.png
--------------------------------------------------------------------------------
/demo/ocrb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/image-js/ocr-tools/HEAD/demo/ocrb.png
--------------------------------------------------------------------------------
/demo/test.odt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/image-js/ocr-tools/HEAD/demo/test.odt
--------------------------------------------------------------------------------
/demo/dejavusans.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/image-js/ocr-tools/HEAD/demo/dejavusans.png
--------------------------------------------------------------------------------
/demo/driving_CH.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/image-js/ocr-tools/HEAD/demo/driving_CH.jpg
--------------------------------------------------------------------------------
/demo/passport1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/image-js/ocr-tools/HEAD/demo/passport1.jpg
--------------------------------------------------------------------------------
/demo/passport2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/image-js/ocr-tools/HEAD/demo/passport2.jpg
--------------------------------------------------------------------------------
/demo/passport3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/image-js/ocr-tools/HEAD/demo/passport3.jpg
--------------------------------------------------------------------------------
/demo/passport4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/image-js/ocr-tools/HEAD/demo/passport4.jpg
--------------------------------------------------------------------------------
/demo/passport5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/image-js/ocr-tools/HEAD/demo/passport5.jpg
--------------------------------------------------------------------------------
/demo/passport6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/image-js/ocr-tools/HEAD/demo/passport6.jpg
--------------------------------------------------------------------------------
/demo/passport7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/image-js/ocr-tools/HEAD/demo/passport7.jpg
--------------------------------------------------------------------------------
/demo/passport8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/image-js/ocr-tools/HEAD/demo/passport8.jpg
--------------------------------------------------------------------------------
/demo/passport9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/image-js/ocr-tools/HEAD/demo/passport9.jpg
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .idea
3 | logs
4 | *.log
5 | npm-debug.log*
6 | coverage
7 | /png
8 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - 10
4 | - 8
5 | script: "npm run test-travis "
6 | after_script: "npm install coveralls@2 && cat ./coverage/lcov.info | coveralls"
7 |
--------------------------------------------------------------------------------
/run/listInstalledFonts.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var getInstalledRegularFonts = require('../src/util/getInstalledRegularFonts');
4 |
5 |
6 | var names = getInstalledRegularFonts();
7 |
8 |
9 | names = names.filter((a) => a.toLowerCase().indexOf('ocr') >= 0);
10 |
11 | console.log(names);
12 |
13 |
--------------------------------------------------------------------------------
/src/util/byteArrayToBinary.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const zero = '0'.repeat(10);
4 | module.exports = function byteArrayToBinary(array) {
5 | const result = [];
6 | for (const element of array) {
7 | const binary = element.toString(2);
8 | result.push(zero.substring(0, 8 - binary.length) + binary);
9 | }
10 | return result.join('');
11 | };
12 |
--------------------------------------------------------------------------------
/src/util/loadFontData.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const fs = require('fs');
4 | const { join } = require('path');
5 |
6 | var getFontDataFilename = require('./getFontDataFilename');
7 |
8 | module.exports = function loadFontData(options = {}) {
9 | var file = getFontDataFilename(options);
10 | return JSON.parse(fs.readFileSync(join(file.folder, file.name)));
11 | };
12 |
--------------------------------------------------------------------------------
/src/util/setFingerprintDataOnRoi.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function (lines, options) {
4 | for (let line of lines) {
5 | for (let roi of line.rois) {
6 | var small = roi.getMask().scale({
7 | width: options.width,
8 | height: options.height
9 | });
10 | roi.data = Array.from(small.data);
11 | }
12 | }
13 | };
14 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = {
4 | getLinesFromImage: require('./util/getLinesFromImage'),
5 | doOcrOnLines: require('./util/doOcrOnLines'),
6 | groupRoisPerLine: require('./util/groupRoisPerLine'),
7 | runFontAnalysis: require('./runFontAnalysis'),
8 | loadAllFontData: require('./util/loadAllFontData'),
9 | loadFontData: require('./util/loadFontData'),
10 | generateSymbolImage: require('./util/generateSymbolImage')
11 | };
12 |
--------------------------------------------------------------------------------
/src/runOCR.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const getLinesFromImage = require('./util/getLinesFromImage');
4 | const doOcrOnLines = require('./util/doOcrOnLines');
5 | const setFingerprintDataOnRoi = require('./util/setFingerprintDataOnRoi');
6 |
7 | module.exports = function runOCR(image, fontFingerprint, options = {}) {
8 | const lines = getLinesFromImage(image, options);
9 | setFingerprintDataOnRoi(lines, options.fingerprintOptions);
10 | return doOcrOnLines(lines, fontFingerprint, options.fingerprintOptions);
11 | };
12 |
--------------------------------------------------------------------------------
/src/util/saveFontData.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 |
4 | const fs = require('fs');
5 |
6 | const mkdirp = require('mkdirp');
7 |
8 | const getFingerprintName = require('./getFontDataFilename');
9 |
10 | module.exports = function saveFingerprint(fingerprint, options = {}) {
11 | const file = getFingerprintName(options);
12 | mkdirp.sync(file.folder);
13 |
14 | fs.writeFileSync(
15 | file.folder + file.name,
16 | JSON.stringify({
17 | font: options.fontName,
18 | fingerprint
19 | })
20 | );
21 | };
22 |
--------------------------------------------------------------------------------
/src/util/getFontDataFilename.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const { join } = require('path');
4 |
5 | module.exports = function getFingerprintsName(options = {}) {
6 | var {
7 | width = 8,
8 | height = 8,
9 | category = '',
10 | fontName = 'helvetica',
11 | baseDir = 'fontFingerprint'
12 | } = options;
13 |
14 | fontName = fontName.toLowerCase().replace(/[^a-zA-Z0-9]/g, '_');
15 | fontName = fontName.replace(/_?regular$/, '');
16 |
17 | const kind = `${width}x${height}`;
18 | return {
19 | folder: join(baseDir, kind, category),
20 | name: `${fontName}.json`
21 | };
22 | };
23 |
--------------------------------------------------------------------------------
/src/util/loadAllFontData.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const fs = require('fs');
4 | const { join } = require('path');
5 |
6 | var getFontDataFilename = require('./getFontDataFilename');
7 |
8 | module.exports = function loadAllFontData(options = {}) {
9 | var fingerprints = [];
10 |
11 | var folder = getFontDataFilename(options).folder;
12 |
13 | var dir = fs.readdirSync(folder);
14 |
15 | for (var file of dir) {
16 | var fontData = JSON.parse(fs.readFileSync(join(folder, file)));
17 | fontData.filneme = folder + file;
18 | fingerprints.push(fontData);
19 | }
20 |
21 | return fingerprints;
22 | };
23 |
--------------------------------------------------------------------------------
/src/util/getInstalledRegularFonts.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // eslint-disable-next-line
4 | const fontManager = require('font-manager');
5 |
6 | module.exports = function getInstalledRegularFonts() {
7 | const fonts = fontManager.getAvailableFontsSync();
8 | const regular = fonts.filter((a) => a.style === 'Regular');
9 |
10 | let names = regular.map((a) => a.postscriptName);
11 | // this is not really enough ... and we get rid of the font that contains some Bold, Italic or other
12 | names = names.filter(function (a) {
13 | return !a
14 | .toLowerCase()
15 | .match(/(condensed|light|bold|extra|black|narrow|medium)/);
16 | });
17 |
18 | return names.sort();
19 | };
20 |
--------------------------------------------------------------------------------
/src/util/bestMatch.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const tanimotoSimilarity = require('./tanimotoSimilarity');
4 |
5 | module.exports = function bestMatch(targetFingerprint, fontData) {
6 | const bestMatch = {
7 | similarity: 0
8 | };
9 |
10 | for (const symbolFingerprint of fontData.fingerprint) {
11 | for (const fingerprint of symbolFingerprint.fingerprints) {
12 | const similarity = tanimotoSimilarity(fingerprint, targetFingerprint);
13 | if (similarity >= bestMatch.similarity) {
14 | bestMatch.similarity = similarity;
15 | bestMatch.fingerprintOptions = fingerprint;
16 | bestMatch.symbol = symbolFingerprint.symbol;
17 | }
18 | }
19 | }
20 | return bestMatch;
21 | };
22 |
--------------------------------------------------------------------------------
/src/util/symbolClasses.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const LETTERS_NUMBERS = { symbols: [], label: 'lettersNumbers' };
4 | const NUMBERS = { symbols: [], label: 'numbers' };
5 | const MRZ = { symbols: [], label: 'numbers' };
6 |
7 | for (let i = '0'.charCodeAt(0); i <= '9'.charCodeAt(0); i++) {
8 | LETTERS_NUMBERS.symbols.push(i);
9 | NUMBERS.symbols.push(i);
10 | MRZ.symbols.push(i);
11 | }
12 | for (let i = 'A'.charCodeAt(0); i <= 'Z'.charCodeAt(0); i++) {
13 | LETTERS_NUMBERS.symbols.push(i);
14 | MRZ.symbols.push(i);
15 | }
16 | for (let i = 'a'.charCodeAt(0); i <= 'z'.charCodeAt(0); i++) {
17 | LETTERS_NUMBERS.symbols.push(i);
18 | }
19 |
20 | MRZ.symbols.push('<'.charCodeAt(0));
21 |
22 | module.exports = {
23 | LETTERS_NUMBERS,
24 | NUMBERS,
25 | MRZ
26 | };
27 |
--------------------------------------------------------------------------------
/src/util/appendFingerprints.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const tanimotoSimilarity = require('./tanimotoSimilarity');
4 |
5 | module.exports = function appendFingerprints(lines, options = {}) {
6 | const {
7 | maxSimilarity = 1 // over this value we don't add the fingerprintOptions
8 | } = options;
9 | for (const line of lines.lines) {
10 | if (!line.fingerprints) line.fingerprints = [];
11 | for (const roi of line.rois) {
12 | let isNew = true;
13 | for (const fingerprint of line.fingerprints) {
14 | if (tanimotoSimilarity(fingerprint, roi.data) >= maxSimilarity) {
15 | isNew = false;
16 | break;
17 | }
18 | }
19 | if (isNew) {
20 | line.fingerprints.push(roi.data);
21 | }
22 | }
23 | }
24 | };
25 |
--------------------------------------------------------------------------------
/src/runFontAnalysis.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const doOcrOnLines = require('./util/doOcrOnLines');
4 | const getLinesFromImage = require('./util/getLinesFromImage');
5 | const setFingerprintDataOnRoi = require('./util/setFingerprintDataOnRoi');
6 |
7 | module.exports = function runFontAnalysis(image, allFontData, options = {}) {
8 | const lines = getLinesFromImage(image, options).lines;
9 | setFingerprintDataOnRoi(lines, options.fingerprintOptions);
10 | var fingerprintOptions = Object.assign({}, options.fingerprintOptions, {
11 | minSimilarity: 0.9
12 | });
13 |
14 | const results = [];
15 | for (const fontData of allFontData) {
16 | var result = doOcrOnLines(lines, fontData, fingerprintOptions);
17 | result.fontName = fontData.font;
18 | results.push(result);
19 | }
20 |
21 | return results.sort((a, b) => b.totalSimilarity - a.totalSimilarity);
22 | };
23 |
--------------------------------------------------------------------------------
/History.md:
--------------------------------------------------------------------------------
1 |
2 | # [0.2.0](https://github.com/cheminfo-js/ocr/compare/v0.1.1...v0.2.0) (2018-07-26)
3 |
4 |
5 |
6 |
7 | ## [0.1.1](https://github.com/cheminfo-js/ocr/compare/v0.1.0...v0.1.1) (2018-05-23)
8 |
9 |
10 | ### Bug Fixes
11 |
12 | * install missing eslint plugin ([4780696](https://github.com/cheminfo-js/ocr/commit/4780696))
13 |
14 |
15 |
16 |
17 | # [0.1.0](https://github.com/cheminfo-js/ocr/compare/v0.0.5...v0.1.0) (2018-04-13)
18 |
19 |
20 |
21 |
22 | ## [0.0.5](https://github.com/cheminfo-js/ocr/compare/v0.0.4...v0.0.5) (2018-03-20)
23 |
24 |
25 |
26 |
27 | ## [0.0.4](https://github.com/cheminfo-js/ocr/compare/v0.0.3...v0.0.4) (2018-03-15)
28 |
29 |
30 |
31 |
32 | ## [0.0.3](https://github.com/cheminfo-js/ocr/compare/v0.0.2...v0.0.3) (2018-01-29)
33 |
34 |
35 |
36 |
37 | ## 0.0.2 (2017-01-19)
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/src/getRotation.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const runOCR = require('./runOCR');
4 |
5 | module.exports = function getRotation(image, fontFingerprint, options = {}) {
6 | var similarities = [];
7 | var result = runOCR(image, fontFingerprint, options);
8 | similarities.push({
9 | rotation: 0,
10 | similarity: result.totalSimilarity
11 | });
12 | for (var rotation = 90; rotation < 360; rotation += 90) {
13 | var rotated = image.rotate(rotation);
14 | result = runOCR(rotated, fontFingerprint, options);
15 | similarities.push({
16 | rotation: rotation,
17 | similarity: result.totalSimilarity
18 | });
19 | }
20 | similarities.sort(function (a, b) {
21 | return b.similarity - a.similarity;
22 | });
23 | return {
24 | rotation: similarities[0].rotation,
25 | reliability:
26 | (similarities[0].similarity - similarities[1].similarity) /
27 | similarities[0].similarity *
28 | 100,
29 | similarities
30 | };
31 | };
32 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 image-js
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.
22 |
--------------------------------------------------------------------------------
/src/util/groupRoisPerLine.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // we will sort the rois per line
4 | // we need to regroup per line
5 | module.exports = function groupRoisPerLine(rois, options = {}) {
6 | let { allowedShift } = options;
7 | rois = rois.slice();
8 |
9 | if (!allowedShift) {
10 | // we take the average height / 5
11 | let total = 0;
12 | rois.forEach((a) => (total += a.height));
13 | allowedShift = Math.round(total / rois.length / 2);
14 | }
15 |
16 | rois.sort(function (a, b) {
17 | return a.minX - b.minX;
18 | });
19 |
20 | const lines = [];
21 | for (const roi of rois) {
22 | const x = roi.minX;
23 | const y = roi.minY;
24 | // is there a close line ?
25 | let currentLine;
26 | for (const line of lines) {
27 | if (Math.abs(line.y - y) <= allowedShift) {
28 | currentLine = line;
29 | break;
30 | }
31 | }
32 | if (!currentLine) {
33 | currentLine = { rois: [] };
34 | lines.push(currentLine);
35 | }
36 | currentLine.y = y;
37 | currentLine.x = x;
38 | currentLine.rois.push(roi);
39 | }
40 | lines.sort((a, b) => a.y - b.y);
41 |
42 | return lines;
43 | };
44 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ocr-tools
2 |
3 | [![NPM version][npm-imageoptions]][npm-url]
4 | [![build status][travis-imageoptions]][travis-url]
5 | [![Test coverage][coveralls-imageoptions]][coveralls-url]
6 | [![David deps][david-imageoptions]][david-url]
7 | [![npm download][download-imageoptions]][download-url]
8 |
9 | Various tools for OCR
10 |
11 | ## Installation
12 |
13 | `$ npm install ocr-tools`
14 |
15 | ## [API Documentation](https://image-js.github.io/ocr-tools/)
16 |
17 | ## Example
18 |
19 | ```js
20 | const ocr = require('ocr-tools');
21 | ```
22 |
23 | ## License
24 |
25 | [MIT](./LICENSE)
26 |
27 | [npm-imageoptions]: https://img.shields.io/npm/v/ocr-tools.svg?style=flat-square
28 | [npm-url]: https://npmjs.org/package/ocr-tools
29 | [travis-imageoptions]: https://img.shields.io/travis/image-js/ocr-tools/master.svg?style=flat-square
30 | [travis-url]: https://travis-ci.org/image-js/ocr-tools
31 | [coveralls-imageoptions]: https://img.shields.io/coveralls/image-js/ocr-tools.svg?style=flat-square
32 | [coveralls-url]: https://coveralls.io/github/image-js/ocr-tools
33 | [david-imageoptions]: https://img.shields.io/david/image-js/ocr-tools.svg?style=flat-square
34 | [david-url]: https://david-dm.org/image-js/ocr-tools
35 | [download-imageoptions]: https://img.shields.io/npm/dm/ocr-tools.svg?style=flat-square
36 | [download-url]: https://npmjs.org/package/ocr-tools
37 |
--------------------------------------------------------------------------------
/run/testOCR.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 |
4 | const runOCR = require('../src/runOCR');
5 |
6 | const Image = require('image-js').default;
7 |
8 | const loadFontFingerprint = require('../src/util/loadFontData');
9 | const symbols = require('../src/util/symbolClasses').MRZ; // SYMBOLS MRZ NUMBERS
10 |
11 | var options = {
12 | roiOptions: {
13 | minSurface: 30,
14 | positive: true,
15 | negative: false,
16 | greyThreshold: 0.5
17 | },
18 | fingerprintOptions: {
19 | height: 12,
20 | width: 12,
21 | minSimilarity: 0.7,
22 | fontName: 'ocrb',
23 | category: symbols.label
24 | },
25 | };
26 |
27 |
28 | var fontFingerprint = loadFontFingerprint(options.fingerprintOptions);
29 |
30 |
31 | Image.load('demo/ocrb.png').then(function (image) {
32 | var result = runOCR(image, fontFingerprint, options);
33 | console.log(result);
34 |
35 | for (var line of result.lines) {
36 | console.log(line.text, line.similarity, ' Found:', line.found, ' Not found:', line.notFound);
37 | }
38 | console.log('Total similarity', result.totalSimilarity);
39 | console.log('Total found', result.totalFound);
40 | console.log('Total not found', result.totalNotFound);
41 |
42 | // for the first line we just show the roiOptions
43 | // for (var roi of result.lines[1].rois) {
44 | // console.log(JSON.stringify(roiOptions));
45 | // }
46 | });
47 |
--------------------------------------------------------------------------------
/src/util/tanimotoSimilarity.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const bitsSetTable256 = [
4 | 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
5 | 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
6 | 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
7 | 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
8 | 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
9 | 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
10 | 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
11 | 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
12 | 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
13 | 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
14 | 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
15 | 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
16 | 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
17 | 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
18 | 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
19 | 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
20 | ];
21 |
22 | // in our case we have 2 arrays of bytes
23 | module.exports = function tanimotoSimilarity(a, b) {
24 | if (a.length !== b.length) {
25 | throw Error(`tanimotoSimilarity: not same length: ${a}, ${b}`);
26 | }
27 | let totalAnd = 0;
28 | let totalOr = 0;
29 | for (let i = 0; i < a.length; i++) {
30 | totalAnd += bitsSetTable256[a[i] & b[i]];
31 | totalOr += bitsSetTable256[a[i] | b[i]];
32 | }
33 | return totalAnd / totalOr;
34 | };
35 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ocr-tools",
3 | "version": "0.2.0",
4 | "description": "Various tools for OCR",
5 | "main": "./src/index.js",
6 | "files": [
7 | "src"
8 | ],
9 | "scripts": {
10 | "eslint": "eslint src run",
11 | "eslint-fix": "npm run eslint -- --fix",
12 | "test": "npm run test-only && npm run eslint",
13 | "test-cov": "npm run test-only -- --coverage",
14 | "test-travis": "npm run test-cov && npm run eslint",
15 | "test-only": "echo 'No test for now...'"
16 | },
17 | "repository": {
18 | "type": "git",
19 | "url": "https://github.com/cheminfo-js/ocr-tools.git"
20 | },
21 | "keywords": [
22 | "ocr",
23 | "image",
24 | "optical",
25 | "character",
26 | "recognition"
27 | ],
28 | "license": "MIT",
29 | "bugs": {
30 | "url": "https://github.com/cheminfo-js/ocr-tools/issues"
31 | },
32 | "homepage": "https://github.com/cheminfo-js/ocr-tools#readme",
33 | "optionalDependencies": {
34 | "font-manager": "^0.2.2"
35 | },
36 | "devDependencies": {
37 | "eslint": "^4.16.0",
38 | "eslint-config-cheminfo": "^1.14.1",
39 | "eslint-plugin-import": "^2.12.0",
40 | "eslint-plugin-jest": "^21.7.0",
41 | "image-js": "^0.21.0",
42 | "jest": "^22.1.4"
43 | },
44 | "dependencies": {
45 | "mkdirp": "^0.5.1",
46 | "ml-array-mean": "^1.0.1",
47 | "ml-array-median": "^1.0.1",
48 | "ml-distance": "^2.1.1",
49 | "ml-kmeans": "^4.0.0"
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/util/generateSymbolImage.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const IJS = require('image-js').Image;
4 |
5 | const SYMBOLS = require('./symbolClasses').MRZ;
6 |
7 | function generateSymbolImage(options = {}) {
8 | let {
9 | fontSize = 24,
10 | fontName = 'Helvetica',
11 | numberPerLine = 11,
12 | allowedRotation = 2,
13 | backgroundColor = 255,
14 | symbols = SYMBOLS.symbols
15 | } = options;
16 |
17 | const grid = Math.floor(fontSize * 1.2);
18 | fontName = `${fontSize}px ${fontName}`;
19 |
20 | // default RGBA 8bits
21 | const image = new IJS(
22 | (numberPerLine + 2) * grid,
23 | (symbols.length + 2) * grid
24 | );
25 |
26 | // the imageOptions is now white
27 | const data = image.data;
28 | for (let i = 0; i < data.length; i++) {
29 | if (i % 4 === 3) continue;
30 | data[i] = backgroundColor;
31 | }
32 |
33 | const rotate = [];
34 | const paintOptions = {
35 | font: fontName,
36 | color: 'black',
37 | rotate: rotate
38 | };
39 |
40 | const labels = [];
41 | const positions = [];
42 |
43 | for (let y = 0; y < symbols.length; y++) {
44 | const text = String.fromCharCode(symbols[y]);
45 | for (let x = 0; x < numberPerLine; x++) {
46 | const position = [x * grid + grid, y * grid + grid];
47 | positions.push(position);
48 | labels.push(text);
49 | rotate.push(
50 | 2 * allowedRotation * x / (numberPerLine - 1) - allowedRotation
51 | );
52 | }
53 | }
54 | image.paintLabels(labels, positions, paintOptions);
55 | return { image, chars: labels };
56 | }
57 |
58 | module.exports = generateSymbolImage;
59 |
--------------------------------------------------------------------------------
/run/fontAnalysis.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var IJS = require('image-js').Image;
4 |
5 | var loadFingerprints = require('../src/util/loadAllFontData');
6 | var runFontAnalysis = require('../src/runFontAnalysis');
7 | var symbols = require('../src/util/symbolClasses').MRZ; // SYMBOLS MRZ NUMBERS
8 |
9 | var options = {
10 | roiOptions: {
11 | minSurface: 30,
12 | positive: true,
13 | negative: false,
14 | greyThreshold: 0.5
15 | },
16 | fingerprintOptions: {
17 | height: 12,
18 | width: 12,
19 | category: symbols.label,
20 | maxSimilarity: 0.7 // we store all the different fontFingerprint
21 | },
22 | imageOptions: {
23 | symbols: symbols.symbols,
24 | fontSize: 48, // font size we use at the beginning
25 | allowedRotation: 5, // we may rotate the font
26 | numberPerLine: 11, // better to have a odd number
27 | fontName: ''
28 | }
29 | };
30 |
31 | var allFontFingerprints = loadFingerprints(options.fingerprintOptions);
32 |
33 | console.log('Analysing', allFontFingerprints.length, 'different fonts');
34 |
35 | IJS.load('demo/test.png').then(function (image) {
36 | var results = runFontAnalysis(image, allFontFingerprints, options);
37 |
38 | results = results.slice(0, 5);
39 |
40 | for (var result of results) {
41 | console.log(
42 | '----------',
43 | result.fontName,
44 | '--',
45 | 'Total similarity: ',
46 | result.totalSimilarity / result.totalFound,
47 | '-',
48 | 'Total found: ',
49 | result.totalFound,
50 | '-',
51 | 'Total not found: ',
52 | result.totalNotFound
53 | );
54 | }
55 | });
56 |
--------------------------------------------------------------------------------
/run/testMRZ.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // eslint-disable-next-line
4 | const runMRZ = require('../src/runMRZ');
5 |
6 | const IJS = require('image-js').default;
7 |
8 | const loadFontFingerprint = require('../src/util/loadFontData');
9 | const symbols = require('../src/util/symbolClasses').MRZ; // SYMBOLS MRZ NUMBERS
10 |
11 | var options = {
12 | roiOptions: {
13 | minSurface: 20,
14 | positive: true,
15 | negative: false,
16 | maxWidth: 50,
17 | greyThreshold: 0.5,
18 | level: true // we recalculate the greyThreshold based
19 | // on min / max values of the grey image
20 | },
21 | fingerprintOptions: {
22 | height: 12,
23 | width: 12,
24 | minSimilarity: 0.7,
25 | fontName: 'ocrb',
26 | category: symbols.label
27 | }
28 | };
29 |
30 | var fontFingerprint = loadFontFingerprint(options.fingerprintOptions);
31 | IJS.load('../output/image.png').then(function (image) {
32 | console.log('Image size: ', image.width, image.height);
33 | console.time('full OCR process');
34 |
35 | var result = runMRZ(image, fontFingerprint, options).ocrResult;
36 |
37 | console.timeEnd('full OCR process');
38 |
39 | for (var line of result.lines) {
40 | console.log(
41 | line.text,
42 | line.similarity,
43 | ' Found:',
44 | line.found,
45 | ' Not found:',
46 | line.notFound
47 | );
48 | }
49 | console.log('Total similarity', result.totalSimilarity);
50 | console.log('Total found', result.totalFound);
51 | console.log('Total not found', result.totalNotFound);
52 |
53 | // for the first line we just show the roiOptions
54 | for (var roi of result.lines[1].rois) {
55 | console.log(JSON.stringify(roi));
56 | }
57 | });
58 |
--------------------------------------------------------------------------------
/src/util/ambiguitySolver.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const kmeans = require('ml-kmeans');
4 |
5 | const variablesForClust = ['height'];
6 | // if you want to add a new ambiguity to solver just add a new string to the array to be analysed
7 | const IS_LETTER = {
8 | 0: 'O'
9 | };
10 |
11 | const IS_NUMBER = {
12 | O: '0'
13 | };
14 |
15 | function ambiguitySolver(report) {
16 | var positions = new Array(report.length);
17 | var dataset = [];
18 | for (let i = 0; i < report.length; ++i) {
19 | positions[i] = [];
20 | var text = report[i].text;
21 | for (let j = 0; j < text.length; ++j) {
22 | var letter = text[j];
23 | const datasetElement = [];
24 | if (letter === '<') {
25 | continue;
26 | }
27 |
28 | variablesForClust.forEach((elem) =>
29 | datasetElement.push(report[i].rois[j][elem])
30 | );
31 | dataset.push(datasetElement);
32 | }
33 | }
34 |
35 | var { centroids, clusters } = kmeans(dataset, 2);
36 |
37 | var isNumber = centroids[0].centroid[0] < centroids[1].centroid[0] ? 1 : 0;
38 | var k = 0;
39 | for (let i = 0; i < report.length; ++i) {
40 | text = report[i].text;
41 | var toReplace = '';
42 | for (let j = 0; j < text.length; ++j) {
43 | letter = text[j];
44 | if (letter === '<') {
45 | toReplace += letter;
46 | continue;
47 | }
48 |
49 | var prediction = clusters[k];
50 | k++;
51 | var replace =
52 | isNumber === prediction ? IS_NUMBER[letter] : IS_LETTER[letter];
53 | toReplace += replace !== undefined ? replace : letter;
54 | }
55 | report[i].text = toReplace;
56 | }
57 |
58 | return report;
59 | }
60 |
61 | module.exports = ambiguitySolver;
62 |
--------------------------------------------------------------------------------
/src/createFontFingerprint.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-console */
2 | 'use strict';
3 |
4 | const generateSymbolImage = require('../src/util/generateSymbolImage');
5 | const appendFingerprints = require('../src/util/appendFingerprints');
6 | const setFingerprintDataOnRoi = require('../src/util/setFingerprintDataOnRoi');
7 |
8 | const getLinesFromImage = require('./util/getLinesFromImage');
9 |
10 | module.exports = function createFontFingerprint(options = {}) {
11 | const { image } = generateSymbolImage(options.imageOptions);
12 | image.save(
13 | `png/${options.imageOptions.fontName}_${
14 | options.roiOptions.greyThreshold
15 | }.jpg`
16 | );
17 | const lines = getLinesFromImage(image, options);
18 | setFingerprintDataOnRoi(lines, options.fingerprintOptions);
19 | const symbols = options.imageOptions.symbols;
20 |
21 | let valid = true;
22 | // we have the lines in the correct order, it should match directly the font
23 | for (let i = 0; i < lines.length; i++) {
24 | const line = lines[i];
25 | line.symbol = String.fromCharCode(symbols[i]);
26 | if (line.rois.length !== options.imageOptions.numberPerLine) {
27 | console.log(
28 | `Number of symbol on the line not correct for: ${line.symbol}`
29 | );
30 | valid = false;
31 | }
32 | }
33 | if (lines.lines.length !== symbols.length) {
34 | console.log('Number of lines not correct: ', lines.length, symbols.length);
35 | valid = false;
36 | }
37 |
38 | appendFingerprints(lines, {
39 | maxSimilarity: options.fingerprintOptions.maxSimilarity
40 | });
41 |
42 | const results = lines.lines.map(function (line) {
43 | return {
44 | symbol: line.symbol,
45 | fingerprints: line.fingerprints
46 | };
47 | });
48 |
49 | return {
50 | valid,
51 | results,
52 | fontName: options.imageOptions.fontName
53 | };
54 | };
55 |
--------------------------------------------------------------------------------
/src/util/doOcrOnLines.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const bestMatch = require('./bestMatch');
4 | const ambiguitySolver = require('./ambiguitySolver');
5 |
6 | module.exports = function doOcrOnLines(lines, fontData, options = {}) {
7 | var {
8 | minSimilarity = 0.8,
9 | maxNotFound = Number.MIN_SAFE_INTEGER,
10 | ambiguity = false
11 | } = options;
12 |
13 | // we try to analyse each line
14 | var totalSimilarity = 0;
15 | var totalFound = 0;
16 | var totalNotFound = 0;
17 | for (var line of lines) {
18 | line.text = '';
19 | line.similarity = 0;
20 | line.found = 0;
21 | line.notFound = 0;
22 | var rois = line.rois;
23 | for (var roi of rois) {
24 | // TODO: get roi.mask() for matrix
25 | var roiData = roi.data;
26 | var match = bestMatch(roiData, fontData);
27 | if (match.similarity > minSimilarity) {
28 | line.text += match.symbol;
29 | line.similarity += match.similarity;
30 | line.found++;
31 | } else {
32 | line.text += '?';
33 | line.notFound++;
34 | }
35 | }
36 | totalSimilarity += line.similarity;
37 | totalFound += line.found;
38 | totalNotFound += line.notFound;
39 | }
40 |
41 | const report = [];
42 | for (const line of lines) {
43 | if (line.notFound < maxNotFound) {
44 | const rois = [];
45 | for (const roi of line.rois) {
46 | rois.push({
47 | meanX: roi.meanX,
48 | meanY: roi.meanY,
49 | width: roi.width,
50 | height: roi.height
51 | });
52 | }
53 | report.push({
54 | text: line.text,
55 | found: line.found,
56 | notFound: line.notFound,
57 | similarity: line.similarity,
58 | rois: rois
59 | });
60 | }
61 | }
62 |
63 | if (ambiguity) {
64 | ambiguitySolver(report);
65 | }
66 |
67 | return {
68 | lines: report,
69 | totalSimilarity,
70 | totalFound,
71 | totalNotFound
72 | };
73 | };
74 |
--------------------------------------------------------------------------------
/run/createFontFingerprint.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const tanimotoSimilarity = require('../src/util/tanimotoSimilarity');
4 | var createFontFingerprint = require('../src/createFontFingerprint');
5 | var symbols = require('../src/util/symbolClasses').MRZ; // SYMBOLS MRZ NUMBERS
6 | var saveFingerprint = require('../src/util/saveFontData');
7 | var getInstalledRegularFonts = require('../src/util/getInstalledRegularFonts');
8 |
9 | var fonts = getInstalledRegularFonts(); // .filter(elem => elem === 'OCRB-Regular');
10 |
11 | // fonts=fonts.filter(a=>a.toLowerCase().indexOf('ocr')>=0).slice(0,3);
12 | // fonts=fonts.slice(0,1);
13 |
14 | var greyThresholds = [0.3, 0.5, 0.7];
15 |
16 | var options = {
17 | roiOptions: {
18 | minSurface: 30,
19 | positive: true,
20 | negative: false,
21 | greyThreshold: 0.5
22 | },
23 | fingerprintOptions: {
24 | height: 64,
25 | width: 45,
26 | category: symbols.label,
27 | maxSimilarity: 0.95 // we store all the different fontFingerprint
28 | },
29 | imageOptions: {
30 | symbols: symbols.symbols,
31 | fontSize: 48, // font size we use at the beginning
32 | allowedRotation: 5, // we may rotate the font
33 | numberPerLine: 11, // better to have a odd number
34 | fontName: ''
35 | }
36 | };
37 |
38 | for (var font of fonts) {
39 | console.log('-----------------> Processing:', font);
40 |
41 | options.imageOptions.fontName = font;
42 |
43 | var fontFingerprintPerThreshold = [];
44 | for (var greyThreshold of greyThresholds) {
45 | console.log('Grey threshold', greyThreshold);
46 | options.roiOptions.greyThreshold = greyThreshold;
47 | var fontFingerprint = createFontFingerprint(options);
48 | if (fontFingerprint.valid) {
49 | fontFingerprintPerThreshold.push(fontFingerprint);
50 | }
51 | }
52 |
53 | fontFingerprint = joinFontFingerprints(fontFingerprintPerThreshold, {
54 | maxSimilarity: options.fingerprintOptions.maxSimilarity
55 | });
56 | if (fontFingerprint.length > 0) {
57 | saveFingerprint(fontFingerprint, options.fingerprintOptions);
58 | }
59 | }
60 |
61 | /*
62 | We have an array of fontFingerprint and we flatten it
63 | */
64 | function joinFontFingerprints(allFingerprints, options = {}) {
65 | const { maxSimilarity } = options;
66 | var symbols = {};
67 | for (var oneFingerprint of allFingerprints) {
68 | var results = oneFingerprint.results;
69 | for (var result of results) {
70 | // result is composed of a symbol and the related fontFingerprint
71 | if (!symbols[result.symbol]) {
72 | symbols[result.symbol] = [];
73 | }
74 | for (const newFingerprint of result.fingerprints) {
75 | var isNew = true;
76 | for (const existingFingerprint of symbols[result.symbol]) {
77 | if (
78 | tanimotoSimilarity(existingFingerprint, newFingerprint) >=
79 | maxSimilarity
80 | ) {
81 | isNew = false;
82 | break;
83 | }
84 | }
85 | if (isNew) {
86 | symbols[result.symbol].push(newFingerprint);
87 | }
88 | }
89 | }
90 | }
91 | var toReturn = [];
92 | for (var symbol of Object.keys(symbols)) {
93 | toReturn.push({
94 | symbol: symbol,
95 | fingerprints: symbols[symbol]
96 | });
97 | }
98 |
99 | return toReturn;
100 | }
101 |
--------------------------------------------------------------------------------
/src/util/getLinesFromImage.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const Image = require('image-js').Image;
4 | const mean = require('ml-array-mean');
5 | const median = require('ml-array-median');
6 |
7 | var groupRoisPerLine = require('./groupRoisPerLine');
8 |
9 | module.exports = function getLinesFromImage(image, roiOptions = {}) {
10 | var grey = image.grey({ allowGrey: true });
11 |
12 | // we should allow to make a level without making a level ...
13 | let maskOptions = {
14 | invert: true
15 | };
16 | if (roiOptions.algorithm) {
17 | maskOptions.algorithm = roiOptions.algorithm;
18 | } else if (roiOptions.greyThreshold) {
19 | let greyThreshold = roiOptions.greyThreshold;
20 | if (roiOptions.level) {
21 | // we simulate the level by changing the threshold
22 | greyThreshold =
23 | (grey.min[0] + (grey.max[0] - grey.min[0]) * greyThreshold) /
24 | grey.maxValue;
25 | }
26 | maskOptions.threshold = greyThreshold;
27 | } else {
28 | throw new Error('no algorithm or greyThreshold provided to apply.');
29 | }
30 |
31 | var mask = grey.mask(maskOptions);
32 | var manager = image.getRoiManager();
33 | manager.fromMask(mask);
34 | var rois = manager.getRois(roiOptions);
35 | rois = filterRois(rois);
36 |
37 | if (rois.length < 60) {
38 | mask = getMask(grey, maskOptions);
39 | manager = image.getRoiManager();
40 | manager.fromMask(mask);
41 | rois = manager.getRois(roiOptions);
42 | rois = filterRois(rois);
43 | }
44 |
45 | var averageSurface = mean(rois.map((elem) => elem.surface));
46 |
47 | var painted = manager.paint(roiOptions);
48 |
49 | rois.forEach(function (roi) {
50 | // draw bounding boxes
51 | var mask = roi.getMask();
52 | var mbr = mask.minimalBoundingRectangle();
53 | roi.mbr = mbr;
54 | roi.mbrWidth = getDistance(mbr[0], mbr[1]);
55 | roi.mbrHeight = getDistance(mbr[1], mbr[2]);
56 | roi.mbrSurface = roi.mbrWidth * roi.mbrHeight;
57 | roi.fillingFactor = roi.surface / roi.mbrSurface;
58 |
59 | mbr = mbr.map((point) => [
60 | point[0] + mask.position[0],
61 | point[1] + mask.position[1]
62 | ]);
63 | painted.paintPolyline(mbr, { color: [255, 0, 0] });
64 | });
65 |
66 | return {
67 | lines: groupRoisPerLine(rois, roiOptions),
68 | painted,
69 | mask,
70 | averageSurface
71 | };
72 | };
73 |
74 | function getDistance(p1, p2) {
75 | return Math.sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2);
76 | }
77 |
78 | function getMask(image, maskOptions) {
79 | let mask = new Image(image.width, image.height, { kind: 'BINARY' });
80 | const partsY = 1;
81 | const partsX = 30;
82 | const h = Math.floor(image.height / partsY);
83 | const w = Math.floor(image.width / partsX);
84 | for (let i = 0; i < partsX; i++) {
85 | for (let j = 0; j < partsY; j++) {
86 | let x = i * w;
87 | let y = j * h;
88 | let width = w;
89 | let height = h;
90 | if (i === partsX - 1) {
91 | width += image.width % partsX;
92 | }
93 | if (j === partsY - 1) {
94 | height += image.height % partsY;
95 | }
96 | const params = {
97 | x,
98 | y,
99 | width,
100 | height
101 | };
102 | const imagePart = image.crop(params).mask(maskOptions);
103 | mask.insert(imagePart, { inPlace: true, x: x, y: y });
104 | }
105 | }
106 | return mask;
107 | }
108 |
109 | function filterRois(rois) {
110 | rois = rois.filter((roi) => roi.width !== 1 || roi.height !== 1);
111 | var medianSurface = median(rois.map((elem) => elem.surface));
112 | rois = rois.filter(
113 | (roi) => roi.surface * 3 > medianSurface && roi.surface / 3 < medianSurface
114 | );
115 |
116 | return rois;
117 | }
118 |
--------------------------------------------------------------------------------
/run/testRotation.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const FS = require('fs');
4 |
5 | const IJS = require('image-js');
6 |
7 | const getRotation = require('../src/getRotation');
8 | const runOCR = require('../src/runOCR');
9 |
10 |
11 | const fontFingerprint = { font: 'OcrB-Regular', fingerprint: [{ symbol: '0', fingerprints: [[63, 199, 14, 96, 110, 6, 224, 62, 3, 96, 54, 3, 96, 54, 3, 48, 225, 252], [63, 135, 28, 224, 108, 6, 192, 108, 6, 192, 124, 7, 96, 118, 6, 112, 227, 252], [63, 135, 156, 96, 110, 6, 192, 108, 7, 224, 62, 3, 96, 118, 6, 63, 225, 248], [31, 135, 254, 96, 102, 6, 224, 54, 3, 96, 54, 3, 96, 54, 7, 56, 225, 252], [63, 199, 14, 224, 108, 3, 192, 60, 3, 192, 60, 3, 224, 54, 7, 112, 227, 252], [63, 135, 14, 96, 110, 6, 224, 124, 7, 192, 124, 7, 224, 102, 6, 112, 227, 252], [31, 135, 158, 96, 102, 3, 96, 62, 3, 224, 62, 3, 96, 118, 6, 127, 225, 248], [31, 135, 254, 96, 126, 3, 192, 60, 3, 192, 60, 3, 192, 126, 6, 120, 227, 252], [63, 199, 14, 96, 102, 7, 224, 124, 7, 192, 124, 6, 192, 110, 6, 112, 227, 248], [31, 199, 14, 96, 118, 3, 96, 62, 3, 224, 60, 7, 192, 110, 6, 112, 227, 252], [31, 131, 190, 112, 54, 3, 96, 54, 3, 224, 62, 7, 224, 102, 6, 125, 225, 248], [63, 143, 28, 192, 236, 6, 192, 108, 6, 192, 108, 7, 224, 118, 6, 113, 227, 252], [63, 135, 156, 224, 108, 6, 192, 108, 7, 192, 126, 7, 224, 118, 6, 127, 225, 248], [63, 135, 254, 224, 110, 6, 224, 126, 7, 224, 126, 7, 96, 118, 7, 127, 225, 252], [31, 135, 254, 96, 110, 7, 224, 126, 3, 224, 54, 3, 96, 118, 7, 127, 225, 252], [63, 199, 14, 224, 110, 6, 192, 108, 7, 192, 124, 7, 224, 110, 6, 113, 227, 252], [63, 199, 158, 96, 110, 7, 224, 126, 7, 224, 126, 7, 224, 118, 6, 127, 225, 248], [31, 199, 254, 96, 102, 7, 224, 62, 3, 224, 62, 7, 224, 118, 6, 127, 225, 248], [31, 135, 254, 96, 110, 6, 224, 108, 7, 192, 108, 6, 192, 110, 14, 127, 227, 248], [31, 135, 254, 96, 102, 7, 224, 126, 7, 192, 124, 7, 192, 110, 6, 112, 227, 248], [31, 199, 158, 96, 118, 3, 224, 62, 7, 224, 126, 7, 224, 110, 6, 127, 225, 248], [31, 135, 254, 96, 110, 7, 224, 124, 6, 192, 108, 6, 192, 108, 14, 127, 195, 248], [63, 135, 252, 224, 236, 6, 192, 108, 6, 192, 126, 7, 224, 118, 6, 127, 225, 248], [63, 143, 252, 224, 238, 6, 192, 108, 7, 224, 126, 7, 224, 118, 7, 127, 225, 248], [63, 135, 252, 224, 238, 6, 192, 108, 6, 192, 124, 7, 224, 110, 6, 127, 227, 248], [63, 199, 254, 96, 126, 7, 224, 126, 7, 224, 126, 7, 224, 118, 6, 127, 227, 252], [63, 135, 254, 224, 110, 6, 224, 124, 7, 192, 124, 6, 224, 110, 14, 127, 227, 248], [31, 135, 254, 96, 110, 7, 224, 126, 7, 224, 126, 7, 224, 110, 14, 127, 225, 248], [63, 199, 254, 112, 118, 7, 224, 126, 7, 224, 126, 7, 224, 110, 14, 127, 227, 248], [63, 135, 254, 96, 110, 7, 224, 124, 7, 192, 108, 6, 192, 238, 14, 255, 195, 248]] }, { symbol: '1', fingerprints: [[7, 193, 252, 121, 198, 28, 1, 224, 14, 0, 224, 14, 0, 224, 15, 0, 112, 7], [3, 193, 252, 125, 238, 14, 0, 224, 14, 0, 224, 14, 0, 240, 15, 0, 112, 7], [3, 224, 254, 60, 231, 14, 0, 224, 14, 0, 240, 15, 0, 112, 7, 0, 112, 7], [1, 225, 255, 126, 254, 15, 0, 240, 7, 0, 112, 7, 0, 112, 7, 0, 112, 7], [3, 241, 255, 124, 118, 7, 0, 112, 7, 0, 112, 7, 0, 112, 7, 0, 112, 7], [3, 241, 255, 252, 254, 15, 0, 224, 14, 0, 224, 14, 0, 224, 14, 0, 224, 14], [1, 241, 255, 126, 118, 7, 0, 112, 7, 0, 240, 15, 0, 224, 14, 0, 224, 14], [3, 241, 255, 248, 240, 14, 0, 224, 14, 0, 224, 14, 1, 224, 28, 1, 192, 28], [3, 241, 255, 252, 112, 7, 0, 240, 14, 0, 224, 14, 0, 224, 30, 1, 192, 28], [3, 241, 255, 252, 244, 14, 0, 224, 30, 1, 224, 28, 1, 192, 28, 3, 128, 56], [1, 241, 255, 252, 118, 15, 0, 224, 14, 1, 224, 28, 1, 192, 28, 3, 128, 56], [3, 192, 252, 127, 207, 30, 1, 224, 30, 1, 224, 14, 0, 240, 15, 0, 240, 7], [3, 193, 254, 125, 238, 30, 0, 224, 14, 0, 224, 15, 0, 240, 15, 0, 240, 7], [3, 225, 254, 124, 239, 14, 0, 240, 15, 0, 240, 15, 0, 240, 15, 0, 112, 7], [3, 225, 255, 126, 254, 15, 0, 240, 15, 0, 240, 15, 0, 112, 7, 0, 112, 7], [1, 240, 255, 63, 127, 7, 0, 112, 7, 0, 112, 7, 0, 112, 7, 0, 112, 7], [3, 241, 255, 252, 254, 15, 0, 240, 15, 0, 240, 15, 0, 240, 14, 0, 224, 14], [1, 241, 255, 126, 126, 7, 0, 240, 15, 0, 240, 15, 0, 240, 15, 0, 224, 14], [1, 240, 255, 126, 247, 15, 0, 224, 14, 0, 224, 30, 1, 224, 30, 1, 224, 28], [3, 227, 254, 252, 228, 30, 1, 224, 30, 1, 192, 28, 3, 192, 60, 3, 192, 60], [3, 241, 255, 124, 242, 14, 0, 224, 30, 1, 224, 28, 3, 192, 60, 3, 192, 60], [3, 225, 255, 252, 228, 30, 1, 224, 28, 3, 192, 60, 3, 192, 60, 3, 192, 56], [3, 224, 254, 127, 231, 30, 1, 224, 31, 0, 240, 15, 0, 240, 15, 0, 240, 15], [3, 225, 254, 125, 255, 15, 0, 240, 15, 0, 240, 15, 0, 240, 15, 0, 240, 7], [3, 240, 255, 62, 247, 143, 0, 240, 15, 0, 240, 15, 0, 240, 15, 0, 240, 7], [3, 224, 255, 127, 255, 31, 1, 240, 31, 1, 240, 31, 1, 240, 15, 0, 240, 14], [3, 241, 255, 124, 247, 15, 0, 240, 15, 0, 240, 15, 0, 240, 15, 0, 240, 14], [3, 225, 255, 253, 238, 30, 1, 224, 30, 1, 224, 30, 1, 224, 30, 1, 224, 28], [3, 240, 255, 126, 247, 15, 0, 240, 31, 1, 224, 30, 1, 224, 30, 1, 224, 28], [3, 225, 255, 127, 239, 30, 1, 224, 30, 1, 224, 60, 3, 192, 60, 3, 192, 60], [3, 241, 255, 252, 246, 15, 1, 224, 30, 1, 224, 30, 3, 192, 60, 3, 192, 60], [3, 241, 255, 253, 238, 30, 1, 224, 60, 3, 192, 60, 3, 192, 60, 3, 192, 56]] }, { symbol: '2', fingerprints: [[63, 143, 28, 0, 96, 6, 0, 192, 56, 7, 1, 192, 56, 3, 0, 51, 243, 254], [63, 143, 28, 0, 224, 14, 1, 192, 56, 15, 1, 192, 48, 3, 0, 113, 231, 254], [63, 143, 28, 0, 96, 6, 0, 224, 56, 15, 1, 192, 48, 6, 0, 96, 103, 254], [63, 143, 252, 0, 96, 6, 0, 224, 60, 15, 129, 224, 48, 6, 0, 96, 7, 255], [127, 206, 30, 0, 96, 6, 0, 224, 124, 15, 3, 192, 96, 6, 0, 127, 231, 254], [63, 207, 30, 0, 112, 7, 0, 224, 60, 15, 131, 192, 112, 6, 0, 96, 7, 255], [63, 207, 30, 0, 48, 3, 0, 224, 60, 15, 131, 192, 112, 12, 0, 192, 15, 255], [63, 143, 190, 0, 96, 7, 0, 96, 60, 31, 3, 128, 96, 12, 0, 255, 207, 254], [127, 198, 14, 0, 48, 3, 0, 224, 60, 15, 131, 192, 96, 12, 0, 255, 15, 254], [63, 199, 30, 0, 48, 3, 0, 112, 60, 15, 131, 192, 96, 14, 0, 248, 15, 254], [63, 135, 30, 0, 112, 3, 0, 96, 60, 31, 3, 128, 96, 12, 0, 255, 131, 254], [31, 15, 252, 192, 192, 14, 0, 192, 56, 15, 1, 192, 48, 7, 0, 127, 231, 254], [63, 143, 28, 0, 224, 14, 1, 192, 56, 15, 1, 192, 48, 7, 0, 119, 231, 254], [63, 143, 188, 0, 224, 6, 0, 224, 60, 15, 1, 192, 48, 7, 0, 127, 243, 254], [63, 143, 252, 0, 96, 6, 0, 224, 60, 15, 3, 192, 112, 6, 0, 127, 231, 254], [31, 143, 254, 64, 96, 6, 0, 224, 28, 15, 3, 192, 112, 6, 0, 127, 231, 255], [127, 207, 30, 0, 112, 7, 0, 224, 60, 15, 131, 192, 112, 6, 0, 255, 231, 255], [63, 207, 190, 0, 112, 3, 0, 112, 60, 7, 131, 192, 112, 6, 0, 96, 7, 255], [63, 143, 254, 0, 112, 7, 0, 96, 60, 31, 7, 128, 96, 12, 0, 255, 239, 254], [63, 143, 254, 0, 112, 3, 0, 112, 62, 31, 131, 192, 96, 14, 0, 255, 207, 254], [63, 135, 30, 0, 96, 7, 0, 224, 124, 31, 7, 128, 96, 14, 0, 255, 195, 254], [63, 135, 158, 0, 112, 7, 0, 96, 60, 31, 3, 128, 96, 14, 0, 255, 199, 254], [63, 15, 252, 192, 192, 14, 1, 192, 56, 30, 3, 128, 112, 7, 0, 127, 243, 248], [31, 15, 252, 192, 224, 14, 0, 224, 60, 15, 3, 192, 48, 7, 0, 127, 247, 254], [63, 143, 252, 64, 224, 6, 0, 224, 60, 15, 3, 192, 48, 7, 0, 127, 247, 254], [63, 143, 254, 64, 112, 7, 0, 112, 62, 15, 131, 192, 112, 6, 0, 255, 239, 255], [63, 143, 254, 0, 96, 6, 0, 224, 124, 31, 3, 128, 112, 6, 0, 255, 231, 254], [63, 135, 254, 0, 112, 7, 0, 224, 60, 31, 3, 192, 112, 6, 0, 255, 231, 254], [31, 135, 254, 0, 112, 7, 0, 112, 30, 15, 131, 192, 112, 6, 0, 255, 199, 254], [31, 135, 254, 0, 96, 7, 0, 96, 30, 31, 3, 192, 112, 6, 0, 255, 231, 254], [63, 199, 254, 0, 112, 7, 0, 240, 60, 15, 3, 192, 112, 6, 0, 255, 199, 254]] }, { symbol: '3', fingerprints: [[255, 207, 220, 3, 128, 112, 15, 0, 252, 0, 224, 3, 0, 48, 7, 33, 231, 248], [255, 207, 252, 3, 128, 112, 14, 0, 252, 0, 224, 6, 0, 96, 6, 65, 199, 248], [127, 207, 252, 3, 128, 112, 14, 0, 252, 0, 224, 7, 0, 112, 6, 127, 195, 240], [127, 224, 14, 3, 128, 112, 15, 0, 252, 0, 224, 7, 0, 48, 6, 115, 199, 240], [255, 224, 14, 1, 192, 112, 15, 0, 252, 0, 224, 7, 0, 48, 7, 97, 231, 248], [127, 231, 254, 1, 192, 120, 15, 0, 252, 0, 224, 3, 0, 48, 7, 97, 231, 248], [127, 231, 254, 1, 192, 56, 14, 0, 252, 1, 224, 6, 0, 112, 6, 97, 231, 248], [127, 224, 14, 1, 192, 112, 15, 0, 124, 0, 224, 6, 0, 112, 6, 255, 195, 240], [127, 240, 31, 1, 192, 56, 15, 0, 124, 0, 224, 7, 0, 48, 6, 243, 227, 248], [127, 240, 127, 0, 224, 56, 15, 0, 252, 0, 224, 7, 0, 48, 7, 225, 231, 248], [127, 224, 255, 0, 224, 56, 14, 0, 252, 1, 192, 6, 0, 96, 6, 225, 199, 248], [31, 207, 252, 1, 192, 112, 14, 0, 252, 0, 224, 7, 0, 48, 7, 33, 231, 248], [255, 207, 252, 3, 128, 112, 14, 1, 252, 0, 224, 7, 0, 112, 14, 127, 199, 240], [127, 231, 254, 1, 192, 120, 14, 0, 252, 0, 224, 7, 0, 112, 6, 127, 231, 248], [255, 231, 254, 1, 192, 112, 31, 0, 252, 0, 224, 7, 0, 48, 7, 247, 231, 248], [127, 231, 254, 1, 192, 112, 14, 0, 252, 1, 224, 6, 0, 112, 6, 227, 231, 248], [127, 231, 254, 1, 224, 56, 15, 0, 252, 0, 224, 7, 0, 112, 6, 255, 231, 248], [127, 240, 63, 1, 224, 56, 15, 0, 252, 0, 224, 7, 0, 112, 6, 255, 231, 248], [127, 225, 255, 1, 224, 56, 15, 0, 252, 0, 224, 6, 0, 96, 14, 255, 195, 240], [63, 207, 254, 1, 192, 112, 14, 1, 252, 0, 112, 3, 0, 112, 7, 127, 227, 240], [255, 239, 254, 3, 192, 112, 14, 1, 252, 0, 224, 7, 0, 112, 6, 127, 231, 248], [255, 231, 254, 3, 128, 112, 31, 1, 252, 1, 224, 6, 0, 96, 14, 255, 199, 248], [255, 231, 254, 3, 192, 112, 14, 0, 252, 0, 224, 7, 0, 112, 14, 255, 199, 240], [127, 227, 255, 0, 224, 60, 15, 0, 252, 0, 224, 7, 0, 112, 7, 255, 231, 248], [127, 199, 255, 1, 224, 60, 15, 0, 248, 1, 224, 6, 0, 96, 14, 255, 199, 248]] }, { symbol: '4', fingerprints: [[12, 0, 192, 28, 1, 128, 48, 3, 24, 113, 134, 24, 255, 246, 24, 1, 192, 8], [6, 0, 192, 12, 1, 128, 56, 3, 24, 113, 134, 24, 255, 247, 152, 1, 192, 12], [6, 0, 224, 28, 1, 128, 48, 7, 24, 97, 142, 24, 255, 255, 252, 1, 192, 12], [6, 0, 224, 28, 1, 128, 48, 7, 24, 97, 142, 28, 255, 240, 28, 0, 192, 12], [7, 0, 224, 12, 1, 128, 56, 3, 8, 113, 198, 28, 255, 240, 12, 0, 192, 12], [6, 0, 96, 12, 1, 192, 24, 3, 24, 113, 134, 24, 255, 240, 24, 1, 128, 24], [3, 0, 96, 14, 1, 192, 24, 3, 8, 113, 134, 24, 255, 240, 24, 1, 128, 24], [7, 0, 224, 14, 1, 128, 56, 7, 8, 97, 206, 24, 255, 240, 24, 1, 128, 24], [3, 0, 112, 14, 1, 192, 56, 3, 12, 112, 206, 28, 255, 240, 28, 1, 128, 24], [3, 0, 112, 14, 1, 192, 24, 3, 12, 96, 206, 12, 255, 240, 24, 1, 128, 24], [1, 128, 112, 7, 0, 224, 24, 3, 8, 112, 206, 12, 255, 240, 28, 1, 128, 24], [14, 0, 192, 28, 1, 128, 56, 3, 24, 113, 134, 24, 255, 247, 156, 1, 192, 12], [6, 0, 224, 12, 1, 192, 56, 3, 24, 113, 134, 24, 255, 247, 252, 1, 192, 28], [6, 0, 224, 28, 1, 128, 56, 3, 24, 97, 206, 28, 255, 240, 28, 1, 192, 12], [6, 0, 224, 12, 1, 192, 56, 3, 24, 113, 142, 24, 255, 240, 24, 1, 128, 24], [3, 0, 96, 14, 1, 192, 24, 3, 152, 113, 142, 24, 255, 240, 24, 1, 128, 24], [3, 0, 112, 14, 0, 192, 24, 3, 136, 113, 198, 28, 255, 240, 28, 1, 128, 24], [3, 128, 112, 14, 1, 224, 24, 3, 12, 112, 206, 28, 255, 240, 28, 1, 128, 24], [3, 0, 112, 14, 0, 192, 24, 3, 136, 113, 206, 24, 255, 240, 24, 1, 128, 24], [12, 0, 192, 28, 1, 128, 56, 3, 24, 113, 142, 24, 255, 247, 220, 1, 192, 28], [14, 0, 224, 28, 1, 128, 56, 3, 24, 113, 134, 24, 255, 247, 252, 1, 192, 28], [6, 0, 224, 12, 1, 192, 56, 3, 24, 113, 198, 30, 255, 240, 28, 1, 192, 12], [6, 0, 224, 28, 1, 128, 56, 7, 24, 113, 142, 24, 255, 240, 24, 1, 128, 24], [7, 0, 112, 14, 1, 192, 24, 3, 152, 113, 206, 28, 255, 240, 24, 1, 128, 24], [3, 0, 112, 14, 1, 192, 56, 3, 152, 97, 143, 248, 255, 240, 24, 3, 128, 24], [3, 0, 112, 14, 1, 192, 56, 3, 24, 113, 143, 152, 255, 240, 24, 1, 128, 24], [3, 0, 112, 14, 0, 192, 28, 3, 136, 113, 207, 24, 255, 240, 30, 1, 128, 24]] }, { symbol: '5', fingerprints: [[255, 239, 128, 192, 12, 0, 255, 128, 30, 0, 96, 7, 0, 112, 14, 63, 199, 128], [255, 239, 224, 224, 14, 0, 255, 128, 30, 0, 112, 7, 0, 112, 14, 31, 207, 192], [127, 239, 252, 224, 14, 0, 255, 132, 62, 0, 112, 7, 0, 112, 14, 31, 207, 192], [127, 230, 0, 96, 14, 0, 255, 192, 14, 0, 112, 7, 0, 112, 15, 15, 239, 224], [127, 231, 0, 96, 6, 0, 127, 128, 30, 0, 224, 7, 0, 112, 14, 7, 207, 224], [127, 231, 254, 112, 7, 0, 127, 128, 30, 0, 224, 3, 0, 112, 14, 7, 239, 240], [63, 247, 0, 112, 7, 0, 127, 128, 30, 0, 112, 3, 0, 112, 14, 3, 239, 240], [63, 227, 0, 112, 7, 0, 127, 128, 30, 0, 96, 6, 0, 96, 14, 127, 199, 192], [63, 243, 142, 48, 3, 0, 127, 128, 30, 0, 96, 6, 0, 96, 14, 127, 199, 224], [63, 227, 126, 48, 3, 0, 63, 128, 28, 0, 224, 6, 0, 96, 14, 15, 199, 240], [31, 227, 255, 48, 3, 0, 63, 128, 28, 0, 224, 6, 0, 96, 14, 7, 199, 240], [63, 207, 252, 224, 14, 0, 255, 7, 254, 0, 112, 7, 0, 112, 30, 63, 199, 192], [127, 239, 248, 224, 14, 0, 255, 196, 30, 0, 112, 7, 0, 112, 14, 63, 199, 224], [127, 239, 252, 224, 14, 0, 255, 134, 62, 0, 112, 7, 0, 112, 15, 63, 239, 192], [127, 231, 254, 224, 14, 0, 255, 7, 254, 0, 224, 7, 0, 96, 14, 31, 207, 224], [127, 231, 224, 112, 6, 0, 127, 192, 30, 0, 224, 7, 0, 112, 14, 15, 207, 224], [63, 247, 255, 112, 7, 0, 127, 128, 30, 0, 112, 3, 0, 112, 14, 127, 207, 224], [63, 243, 2, 112, 7, 0, 127, 192, 30, 0, 96, 6, 0, 96, 30, 127, 207, 224], [63, 243, 191, 48, 7, 0, 127, 192, 30, 0, 96, 7, 0, 96, 14, 127, 207, 224], [63, 227, 255, 48, 3, 0, 63, 128, 28, 0, 224, 6, 0, 96, 14, 127, 207, 240], [127, 239, 252, 224, 14, 0, 255, 15, 254, 0, 240, 7, 0, 112, 30, 127, 199, 224], [127, 239, 252, 224, 14, 0, 255, 199, 62, 0, 112, 7, 0, 112, 14, 127, 231, 224], [255, 239, 252, 224, 14, 0, 255, 135, 254, 0, 224, 15, 0, 224, 30, 127, 207, 224], [127, 239, 254, 224, 14, 0, 255, 135, 254, 0, 224, 7, 0, 240, 14, 63, 207, 224], [127, 231, 252, 112, 7, 0, 255, 192, 30, 0, 240, 7, 0, 240, 30, 255, 207, 128], [127, 247, 254, 112, 7, 0, 127, 192, 30, 0, 112, 7, 0, 112, 30, 127, 207, 192], [127, 247, 255, 112, 7, 0, 127, 194, 62, 0, 112, 7, 0, 112, 14, 127, 239, 224], [63, 231, 255, 112, 7, 0, 127, 130, 126, 0, 96, 7, 0, 96, 30, 127, 207, 224], [63, 227, 254, 48, 7, 0, 127, 128, 30, 0, 224, 6, 0, 224, 14, 127, 207, 240], [63, 227, 254, 56, 3, 0, 63, 128, 60, 0, 224, 14, 0, 224, 12, 127, 207, 240]] }, { symbol: '6', fingerprints: [[3, 0, 96, 28, 3, 128, 48, 7, 252, 112, 238, 6, 192, 118, 6, 121, 225, 248], [3, 0, 96, 28, 3, 128, 63, 7, 254, 112, 238, 7, 224, 54, 7, 112, 225, 248], [3, 0, 240, 28, 3, 128, 127, 7, 254, 224, 108, 3, 192, 62, 6, 127, 225, 248], [1, 128, 112, 14, 3, 128, 55, 7, 254, 224, 108, 3, 192, 62, 7, 121, 225, 248], [3, 0, 112, 28, 3, 128, 63, 7, 252, 96, 236, 6, 192, 102, 6, 113, 225, 248], [3, 128, 112, 14, 1, 128, 63, 7, 252, 112, 238, 7, 192, 118, 6, 112, 225, 248], [1, 128, 112, 14, 1, 192, 63, 7, 252, 96, 110, 3, 224, 54, 6, 63, 225, 248], [1, 128, 112, 30, 3, 128, 127, 135, 254, 224, 108, 3, 192, 62, 6, 121, 225, 248], [1, 192, 120, 14, 1, 128, 63, 135, 254, 96, 108, 3, 192, 62, 7, 112, 225, 248], [0, 192, 56, 15, 1, 192, 63, 7, 254, 112, 110, 3, 192, 62, 7, 112, 225, 252], [1, 192, 120, 14, 1, 192, 63, 135, 158, 96, 108, 7, 192, 118, 6, 127, 193, 248], [3, 0, 224, 28, 3, 128, 54, 7, 252, 240, 238, 7, 224, 118, 6, 121, 225, 248], [3, 0, 112, 14, 1, 192, 56, 7, 252, 96, 110, 7, 224, 118, 6, 63, 225, 248], [3, 0, 112, 14, 1, 128, 63, 7, 254, 112, 126, 3, 224, 54, 7, 63, 225, 248], [3, 0, 112, 28, 3, 128, 127, 7, 252, 224, 236, 6, 192, 110, 6, 127, 193, 248], [3, 0, 112, 14, 1, 192, 62, 7, 252, 240, 238, 7, 192, 126, 6, 121, 225, 248], [3, 128, 112, 14, 1, 192, 63, 135, 254, 224, 110, 7, 224, 118, 6, 63, 193, 248], [1, 128, 56, 14, 1, 192, 63, 7, 254, 112, 110, 7, 224, 54, 7, 63, 225, 248], [1, 192, 120, 14, 3, 192, 63, 135, 254, 224, 124, 3, 192, 62, 7, 121, 225, 252], [1, 128, 120, 14, 1, 192, 63, 7, 252, 224, 108, 7, 192, 126, 6, 127, 193, 240], [1, 192, 56, 15, 1, 192, 63, 7, 252, 96, 110, 7, 224, 118, 6, 127, 225, 248], [3, 0, 224, 28, 3, 128, 127, 7, 252, 224, 110, 7, 224, 118, 6, 127, 225, 248], [3, 0, 112, 14, 1, 192, 58, 7, 252, 224, 126, 7, 224, 118, 7, 127, 225, 248], [7, 0, 224, 28, 3, 128, 127, 7, 252, 224, 236, 6, 192, 110, 14, 127, 193, 248], [3, 0, 112, 30, 3, 128, 127, 7, 252, 224, 238, 7, 192, 126, 6, 127, 225, 248], [3, 0, 112, 14, 1, 192, 62, 7, 252, 224, 110, 7, 224, 126, 14, 127, 193, 240], [1, 128, 120, 14, 1, 192, 62, 7, 252, 224, 110, 7, 224, 118, 6, 127, 225, 248], [1, 128, 120, 14, 1, 192, 63, 135, 254, 112, 126, 7, 224, 118, 7, 127, 225, 248], [1, 128, 112, 14, 3, 192, 63, 7, 252, 224, 236, 6, 192, 110, 14, 127, 195, 248], [1, 128, 120, 14, 1, 192, 63, 135, 254, 224, 238, 7, 224, 126, 14, 127, 193, 248]] }, { symbol: '7', fingerprints: [[127, 247, 199, 0, 224, 28, 3, 128, 48, 7, 0, 96, 14, 0, 192, 14, 0, 96], [127, 255, 243, 0, 96, 12, 1, 128, 112, 7, 0, 224, 14, 0, 224, 14, 0, 224], [255, 255, 255, 0, 96, 28, 3, 128, 112, 14, 0, 224, 12, 0, 192, 12, 0, 192], [255, 240, 3, 0, 96, 28, 3, 128, 112, 6, 0, 224, 12, 0, 192, 12, 0, 192], [255, 240, 7, 0, 224, 28, 3, 128, 112, 14, 0, 192, 24, 1, 128, 24, 1, 128], [255, 231, 254, 0, 224, 28, 3, 128, 96, 14, 0, 192, 28, 1, 128, 24, 1, 128], [255, 247, 255, 0, 96, 28, 3, 128, 112, 14, 1, 192, 24, 1, 128, 24, 1, 128], [255, 240, 6, 0, 224, 28, 3, 0, 96, 14, 1, 192, 24, 1, 128, 24, 1, 128], [255, 240, 31, 0, 96, 28, 7, 128, 224, 14, 1, 128, 24, 3, 128, 48, 3, 0], [255, 224, 255, 0, 96, 28, 7, 128, 224, 28, 1, 128, 48, 3, 0, 48, 3, 0], [255, 225, 255, 0, 112, 28, 7, 128, 240, 14, 1, 128, 56, 3, 0, 48, 3, 0], [31, 255, 255, 0, 96, 12, 1, 128, 48, 7, 0, 96, 14, 0, 224, 14, 0, 224], [127, 247, 255, 0, 96, 28, 3, 128, 112, 6, 0, 224, 12, 0, 192, 12, 0, 192], [127, 239, 255, 0, 224, 28, 3, 128, 112, 14, 0, 192, 12, 1, 192, 28, 0, 192], [255, 247, 247, 0, 224, 28, 7, 128, 112, 14, 0, 224, 28, 1, 128, 24, 1, 128], [255, 247, 255, 0, 224, 28, 3, 128, 112, 14, 0, 192, 28, 1, 128, 24, 1, 128], [255, 240, 127, 0, 96, 28, 7, 128, 240, 14, 1, 128, 24, 3, 128, 48, 3, 0], [255, 225, 255, 0, 224, 28, 3, 128, 224, 14, 1, 192, 24, 3, 128, 56, 3, 0], [63, 255, 255, 0, 96, 14, 3, 192, 56, 6, 0, 224, 14, 0, 224, 14, 0, 96], [63, 239, 255, 0, 224, 28, 3, 128, 112, 6, 0, 224, 12, 0, 192, 12, 0, 192], [255, 247, 255, 0, 224, 28, 3, 128, 112, 6, 0, 224, 12, 1, 192, 28, 0, 192], [255, 239, 254, 0, 224, 28, 7, 128, 224, 12, 1, 192, 24, 1, 128, 24, 1, 128], [255, 239, 255, 0, 224, 28, 3, 128, 240, 12, 1, 192, 56, 3, 128, 56, 3, 0], [127, 135, 255, 0, 112, 30, 3, 128, 112, 14, 1, 192, 24, 3, 128, 56, 3, 0], [255, 231, 255, 0, 224, 28, 7, 128, 224, 28, 3, 128, 56, 3, 0, 48, 3, 0]] }, { symbol: '8', fingerprints: [[63, 135, 28, 224, 198, 28, 63, 129, 248, 59, 198, 6, 224, 126, 7, 113, 227, 248], [31, 135, 156, 96, 198, 12, 63, 129, 248, 63, 199, 6, 96, 54, 7, 112, 227, 252], [63, 135, 252, 224, 230, 12, 127, 129, 248, 121, 238, 7, 192, 60, 7, 127, 225, 248], [31, 135, 252, 96, 102, 14, 59, 193, 248, 121, 238, 7, 192, 62, 3, 121, 225, 248], [63, 135, 28, 96, 231, 12, 63, 129, 248, 59, 198, 6, 192, 110, 6, 113, 227, 248], [31, 135, 156, 96, 103, 14, 63, 193, 248, 63, 198, 6, 224, 126, 7, 112, 227, 252], [31, 131, 254, 96, 99, 14, 63, 193, 248, 57, 230, 6, 224, 54, 7, 127, 225, 248], [15, 131, 254, 48, 99, 6, 29, 192, 248, 57, 198, 6, 224, 54, 7, 121, 225, 248], [31, 195, 142, 96, 99, 6, 31, 193, 248, 121, 206, 6, 192, 60, 3, 112, 227, 252], [31, 195, 142, 48, 51, 7, 31, 225, 248, 61, 198, 6, 192, 60, 3, 112, 227, 252], [15, 195, 254, 48, 51, 7, 31, 225, 248, 121, 238, 7, 192, 62, 3, 127, 225, 252], [63, 135, 188, 96, 198, 28, 63, 129, 248, 121, 230, 7, 224, 54, 7, 127, 225, 248], [31, 135, 252, 96, 231, 12, 63, 193, 248, 57, 230, 7, 224, 54, 7, 127, 225, 248], [31, 7, 252, 96, 198, 12, 123, 129, 240, 123, 206, 6, 192, 126, 6, 127, 227, 248], [63, 135, 28, 96, 231, 12, 63, 129, 248, 59, 198, 14, 224, 126, 7, 121, 227, 248], [31, 135, 190, 96, 103, 14, 63, 193, 248, 121, 238, 6, 224, 126, 7, 127, 225, 248], [31, 131, 254, 112, 103, 14, 63, 193, 248, 121, 230, 7, 224, 126, 7, 127, 225, 248], [15, 131, 254, 112, 99, 6, 61, 192, 248, 61, 230, 7, 224, 62, 7, 127, 225, 252], [31, 195, 142, 48, 115, 134, 31, 193, 248, 61, 231, 7, 224, 54, 7, 120, 225, 252], [31, 131, 158, 112, 99, 14, 31, 193, 248, 121, 206, 6, 192, 126, 6, 127, 225, 248], [31, 131, 254, 48, 115, 6, 31, 225, 248, 121, 206, 6, 192, 126, 6, 127, 225, 248], [31, 7, 252, 224, 206, 28, 123, 129, 248, 121, 238, 7, 224, 126, 7, 127, 225, 248], [63, 135, 252, 224, 230, 28, 63, 129, 248, 121, 230, 7, 224, 126, 7, 127, 225, 248], [63, 7, 252, 224, 206, 28, 127, 129, 248, 123, 206, 14, 192, 126, 6, 127, 227, 248], [31, 7, 252, 224, 198, 12, 127, 193, 248, 123, 206, 14, 224, 126, 7, 127, 227, 248], [31, 135, 252, 96, 230, 14, 63, 193, 248, 121, 238, 7, 224, 126, 7, 127, 225, 248], [31, 131, 254, 112, 99, 6, 63, 225, 248, 125, 231, 7, 224, 126, 7, 127, 225, 252], [31, 195, 254, 112, 99, 14, 31, 193, 248, 121, 238, 6, 192, 126, 6, 127, 225, 248], [31, 195, 254, 48, 115, 135, 31, 225, 248, 121, 206, 14, 224, 126, 7, 127, 225, 248]] }, { symbol: '9', fingerprints: [[31, 7, 252, 96, 108, 7, 192, 118, 6, 127, 224, 252, 1, 192, 56, 7, 0, 192], [31, 135, 142, 96, 110, 3, 96, 55, 14, 63, 224, 254, 1, 192, 56, 7, 0, 224], [31, 135, 142, 224, 124, 3, 192, 54, 7, 63, 224, 110, 1, 192, 120, 14, 0, 192], [31, 135, 158, 96, 110, 3, 224, 118, 6, 63, 224, 124, 1, 128, 112, 14, 0, 192], [31, 135, 254, 224, 124, 3, 192, 62, 7, 127, 224, 252, 1, 192, 112, 14, 1, 128], [31, 135, 14, 96, 108, 7, 224, 119, 14, 127, 224, 252, 1, 128, 112, 14, 1, 192], [31, 135, 30, 224, 124, 3, 192, 54, 6, 127, 225, 252, 1, 128, 112, 14, 1, 128], [31, 135, 156, 96, 108, 6, 192, 102, 14, 63, 224, 252, 3, 128, 112, 28, 1, 128], [31, 131, 254, 96, 110, 3, 224, 54, 6, 63, 224, 252, 3, 128, 112, 28, 1, 128], [31, 135, 14, 224, 124, 3, 192, 54, 6, 127, 225, 252, 3, 128, 112, 30, 3, 128], [31, 135, 158, 96, 108, 3, 224, 118, 6, 127, 225, 252, 3, 128, 112, 28, 3, 128], [31, 135, 252, 96, 110, 7, 224, 118, 6, 127, 225, 252, 1, 192, 56, 7, 0, 224], [15, 131, 254, 96, 110, 7, 224, 54, 7, 63, 224, 12, 1, 192, 56, 14, 0, 192], [31, 135, 158, 224, 108, 7, 224, 118, 14, 63, 224, 252, 3, 128, 112, 14, 0, 192], [31, 135, 254, 96, 110, 7, 224, 119, 7, 63, 224, 252, 1, 128, 112, 14, 0, 192], [31, 135, 252, 224, 108, 6, 192, 110, 14, 127, 225, 252, 3, 128, 112, 14, 1, 192], [31, 135, 252, 96, 110, 7, 224, 118, 6, 127, 225, 252, 3, 128, 112, 14, 1, 192], [31, 135, 158, 96, 126, 3, 224, 119, 7, 63, 224, 124, 3, 128, 112, 14, 1, 128], [31, 135, 254, 224, 110, 7, 224, 118, 14, 127, 224, 252, 3, 128, 112, 28, 1, 128], [31, 131, 254, 96, 110, 7, 224, 118, 7, 63, 224, 252, 3, 128, 112, 30, 1, 128], [31, 7, 252, 224, 108, 6, 192, 126, 6, 127, 225, 252, 3, 128, 240, 28, 3, 128], [31, 135, 158, 96, 110, 7, 224, 119, 14, 127, 225, 252, 3, 128, 112, 28, 3, 128], [31, 135, 254, 224, 110, 7, 224, 126, 15, 63, 224, 28, 3, 128, 112, 14, 0, 192], [31, 131, 254, 112, 126, 7, 224, 118, 7, 63, 224, 124, 1, 192, 120, 14, 0, 192], [63, 135, 254, 224, 110, 7, 224, 127, 14, 127, 224, 252, 3, 128, 112, 14, 0, 192], [31, 135, 254, 96, 126, 7, 224, 119, 15, 63, 224, 252, 3, 192, 112, 14, 0, 192], [31, 135, 252, 224, 236, 7, 224, 126, 14, 127, 225, 252, 3, 128, 112, 14, 1, 192], [31, 7, 252, 224, 236, 6, 192, 126, 14, 127, 224, 252, 3, 128, 240, 28, 1, 128], [31, 135, 254, 96, 126, 7, 224, 119, 7, 127, 224, 252, 3, 128, 112, 30, 1, 128], [31, 7, 252, 224, 238, 7, 192, 126, 14, 127, 225, 252, 3, 128, 240, 28, 3, 128], [31, 135, 254, 224, 126, 7, 224, 119, 14, 63, 224, 252, 7, 128, 240, 60, 3, 0]] }, { symbol: 'A', fingerprints: [[30, 1, 224, 63, 3, 48, 49, 131, 24, 48, 199, 252, 96, 102, 6, 96, 52, 0], [30, 1, 240, 31, 3, 184, 49, 131, 28, 48, 199, 252, 96, 102, 6, 96, 52, 2], [30, 1, 224, 59, 3, 184, 49, 135, 28, 97, 199, 252, 96, 110, 6, 192, 124, 3], [30, 1, 240, 27, 3, 184, 57, 131, 28, 113, 199, 252, 112, 110, 6, 192, 124, 3], [14, 1, 240, 31, 129, 184, 57, 131, 28, 49, 199, 254, 127, 230, 6, 192, 124, 3], [15, 1, 248, 31, 129, 152, 57, 195, 156, 48, 199, 254, 127, 230, 6, 192, 60, 3], [15, 0, 248, 31, 129, 216, 57, 195, 140, 48, 199, 254, 96, 102, 6, 192, 60, 3], [7, 128, 248, 13, 129, 220, 25, 195, 140, 56, 199, 254, 96, 230, 6, 192, 60, 3], [7, 128, 120, 13, 193, 220, 29, 195, 140, 56, 103, 254, 96, 102, 6, 192, 48, 3], [7, 128, 124, 15, 193, 220, 28, 195, 142, 56, 99, 254, 96, 102, 7, 192, 52, 3], [3, 128, 124, 7, 192, 204, 28, 193, 134, 56, 99, 254, 96, 102, 7, 192, 52, 3], [30, 1, 224, 63, 3, 112, 51, 131, 24, 112, 199, 252, 96, 102, 6, 224, 124, 0], [30, 1, 240, 31, 3, 184, 49, 131, 24, 48, 199, 252, 96, 102, 6, 96, 126, 2], [31, 1, 240, 31, 1, 184, 57, 131, 28, 48, 199, 254, 112, 102, 6, 96, 126, 3], [15, 1, 240, 27, 129, 152, 57, 131, 12, 48, 195, 254, 127, 230, 6, 96, 126, 3], [15, 0, 240, 31, 129, 152, 25, 195, 140, 48, 195, 254, 127, 230, 6, 96, 126, 3], [15, 0, 240, 15, 129, 216, 25, 131, 156, 56, 195, 252, 112, 230, 6, 96, 102, 6], [7, 0, 248, 13, 129, 216, 25, 193, 140, 56, 195, 252, 119, 230, 6, 96, 102, 7], [7, 0, 248, 13, 128, 216, 29, 193, 140, 56, 195, 254, 112, 102, 6, 96, 100, 6], [7, 128, 248, 15, 129, 220, 24, 195, 140, 48, 199, 254, 96, 230, 6, 224, 108, 6], [7, 128, 248, 15, 193, 220, 24, 195, 140, 56, 231, 254, 96, 110, 6, 192, 96, 2], [30, 3, 240, 63, 3, 240, 51, 131, 24, 113, 199, 254, 96, 230, 6, 224, 126, 2], [30, 1, 224, 63, 3, 176, 59, 131, 24, 113, 199, 252, 112, 230, 14, 224, 110, 2], [30, 1, 240, 31, 3, 176, 59, 131, 24, 49, 199, 252, 124, 230, 14, 224, 110, 6], [14, 1, 240, 31, 1, 184, 59, 131, 24, 49, 199, 252, 127, 230, 14, 96, 110, 6], [15, 1, 240, 31, 1, 184, 57, 131, 156, 49, 199, 252, 112, 230, 14, 224, 102, 2], [7, 0, 240, 15, 129, 216, 25, 131, 156, 56, 195, 252, 119, 231, 6, 96, 110, 7], [7, 0, 248, 13, 129, 216, 29, 195, 156, 56, 195, 254, 112, 230, 6, 224, 116, 6], [7, 128, 248, 15, 128, 216, 29, 193, 140, 56, 195, 254, 112, 231, 6, 224, 100, 7], [7, 128, 120, 15, 192, 252, 28, 193, 140, 60, 227, 254, 112, 103, 6, 224, 112, 6]] }, { symbol: 'B', fingerprints: [[255, 143, 142, 192, 108, 6, 224, 231, 254, 120, 246, 3, 96, 54, 7, 127, 231, 224], [255, 143, 220, 192, 108, 6, 192, 239, 252, 253, 238, 7, 96, 54, 14, 127, 231, 240], [255, 143, 254, 192, 108, 6, 192, 239, 252, 255, 230, 3, 96, 54, 6, 127, 231, 248], [255, 206, 14, 224, 110, 6, 225, 231, 252, 96, 230, 3, 96, 54, 7, 127, 231, 248], [255, 140, 30, 192, 108, 6, 192, 239, 252, 224, 236, 6, 192, 124, 6, 255, 207, 248], [255, 142, 30, 192, 108, 6, 192, 239, 252, 227, 236, 7, 192, 124, 6, 255, 239, 248], [127, 135, 254, 96, 102, 7, 96, 111, 254, 255, 238, 7, 224, 62, 7, 255, 239, 252], [127, 135, 254, 96, 102, 3, 96, 103, 254, 127, 230, 7, 96, 62, 7, 255, 239, 252], [127, 134, 62, 96, 102, 7, 224, 111, 254, 195, 236, 6, 192, 108, 6, 255, 207, 248], [127, 134, 126, 96, 118, 3, 96, 119, 254, 239, 236, 6, 192, 108, 6, 255, 239, 252], [255, 207, 222, 192, 110, 6, 225, 239, 254, 124, 246, 3, 96, 54, 15, 127, 231, 240], [255, 143, 254, 192, 236, 6, 193, 239, 252, 255, 238, 7, 224, 118, 14, 127, 231, 240], [255, 143, 254, 192, 108, 6, 224, 239, 252, 255, 238, 7, 224, 54, 7, 127, 231, 248], [255, 140, 30, 192, 236, 6, 195, 207, 252, 192, 236, 6, 192, 124, 14, 255, 207, 248], [255, 142, 62, 192, 108, 6, 193, 239, 252, 241, 236, 7, 192, 126, 6, 255, 207, 248], [255, 143, 254, 224, 110, 6, 224, 239, 252, 255, 238, 7, 224, 126, 7, 255, 239, 252], [127, 7, 254, 96, 230, 7, 224, 127, 254, 255, 204, 6, 192, 124, 6, 255, 239, 252], [126, 7, 254, 96, 230, 3, 96, 127, 254, 255, 206, 6, 192, 124, 6, 249, 239, 252], [255, 207, 254, 224, 110, 6, 225, 239, 254, 255, 246, 3, 96, 54, 15, 127, 231, 240], [255, 143, 254, 192, 236, 6, 193, 239, 254, 255, 238, 7, 224, 126, 15, 255, 231, 248], [255, 143, 252, 192, 236, 6, 192, 239, 252, 255, 236, 7, 224, 126, 14, 255, 239, 248], [255, 143, 254, 192, 108, 6, 225, 239, 252, 255, 238, 7, 224, 126, 6, 255, 239, 248], [255, 143, 254, 224, 238, 7, 224, 111, 252, 255, 236, 6, 192, 124, 14, 255, 239, 248]] }, { symbol: 'C', fingerprints: [[31, 135, 222, 112, 238, 0, 224, 14, 0, 224, 14, 0, 96, 7, 7, 60, 240, 252], [31, 135, 254, 112, 230, 0, 224, 14, 0, 224, 6, 0, 112, 7, 7, 60, 113, 254], [31, 199, 142, 112, 102, 0, 224, 14, 0, 96, 6, 0, 112, 3, 135, 31, 240, 252], [31, 199, 142, 112, 110, 0, 224, 14, 0, 224, 14, 0, 96, 7, 135, 60, 241, 252], [31, 195, 255, 112, 118, 0, 224, 14, 0, 224, 14, 0, 96, 7, 7, 60, 113, 254], [15, 131, 254, 112, 102, 0, 96, 14, 0, 224, 6, 0, 112, 7, 6, 63, 224, 248], [31, 231, 143, 112, 126, 0, 224, 14, 0, 224, 14, 0, 224, 7, 7, 125, 225, 252], [31, 227, 207, 120, 118, 0, 224, 14, 0, 224, 14, 0, 224, 7, 7, 120, 225, 252], [15, 195, 254, 112, 119, 0, 224, 14, 0, 224, 14, 0, 96, 7, 6, 120, 225, 252], [15, 227, 199, 112, 119, 0, 96, 14, 0, 224, 14, 0, 96, 7, 6, 63, 224, 248], [31, 195, 206, 112, 118, 0, 224, 14, 0, 224, 14, 0, 224, 7, 14, 121, 225, 248], [31, 135, 254, 112, 110, 0, 224, 14, 0, 224, 14, 0, 112, 7, 7, 63, 240, 252], [15, 131, 254, 112, 103, 0, 224, 14, 0, 224, 6, 0, 112, 7, 7, 63, 240, 252], [31, 199, 223, 112, 126, 0, 224, 14, 0, 224, 14, 0, 224, 7, 135, 127, 241, 254], [31, 135, 254, 112, 110, 0, 224, 14, 0, 224, 14, 0, 96, 7, 7, 124, 225, 252], [15, 131, 254, 112, 103, 0, 224, 14, 0, 224, 14, 0, 112, 7, 7, 63, 224, 248], [31, 227, 207, 112, 119, 0, 96, 14, 0, 224, 6, 0, 112, 7, 7, 63, 224, 252], [31, 199, 222, 112, 126, 0, 224, 14, 0, 224, 14, 0, 224, 7, 14, 125, 225, 248], [15, 195, 255, 112, 119, 0, 224, 14, 0, 224, 14, 0, 96, 7, 6, 63, 224, 248], [15, 195, 254, 112, 103, 0, 96, 14, 0, 224, 14, 0, 96, 7, 14, 63, 225, 248], [15, 195, 239, 56, 119, 0, 112, 14, 0, 224, 14, 0, 96, 7, 14, 63, 225, 248], [31, 199, 254, 112, 231, 0, 224, 14, 0, 112, 7, 0, 112, 35, 135, 63, 224, 124], [15, 131, 254, 112, 231, 0, 224, 14, 0, 224, 15, 0, 112, 7, 6, 63, 224, 252], [31, 195, 254, 112, 231, 0, 224, 14, 0, 224, 7, 0, 112, 7, 135, 63, 224, 252], [15, 195, 255, 112, 119, 0, 240, 14, 0, 224, 14, 0, 112, 7, 7, 63, 241, 252], [15, 195, 255, 120, 119, 0, 112, 15, 0, 240, 7, 0, 112, 7, 14, 63, 225, 252], [15, 195, 255, 112, 119, 0, 224, 14, 0, 224, 14, 0, 240, 7, 14, 127, 225, 248], [15, 195, 255, 120, 119, 0, 112, 14, 0, 224, 14, 0, 112, 7, 14, 127, 225, 252]] }, { symbol: 'D', fingerprints: [[252, 15, 248, 193, 206, 14, 96, 118, 3, 96, 55, 3, 112, 103, 30, 127, 135, 224], [254, 15, 248, 97, 230, 14, 96, 118, 3, 112, 55, 3, 112, 119, 30, 127, 199, 240], [254, 15, 240, 193, 206, 14, 224, 102, 7, 96, 118, 6, 96, 230, 30, 127, 135, 224], [254, 14, 120, 97, 198, 14, 96, 118, 3, 96, 54, 7, 96, 230, 28, 127, 7, 224], [254, 14, 248, 227, 206, 14, 224, 126, 7, 224, 126, 7, 224, 110, 30, 255, 143, 224], [254, 14, 248, 225, 206, 14, 224, 110, 6, 224, 110, 6, 224, 238, 28, 255, 15, 224], [124, 7, 248, 97, 198, 14, 96, 102, 7, 96, 118, 6, 96, 230, 28, 255, 143, 224], [124, 7, 248, 113, 198, 14, 96, 102, 3, 96, 54, 7, 96, 102, 30, 127, 143, 224], [126, 7, 248, 113, 199, 14, 112, 119, 3, 96, 54, 3, 96, 102, 14, 127, 199, 240], [62, 7, 248, 97, 198, 6, 96, 102, 6, 96, 118, 6, 96, 102, 30, 127, 135, 240], [62, 3, 248, 49, 199, 6, 96, 102, 7, 96, 54, 6, 96, 102, 28, 127, 143, 224], [254, 7, 248, 99, 198, 14, 96, 118, 7, 112, 55, 7, 112, 115, 30, 63, 131, 240], [252, 15, 248, 227, 198, 14, 96, 102, 7, 96, 118, 6, 96, 230, 60, 127, 135, 192], [254, 14, 248, 225, 206, 14, 224, 110, 7, 224, 118, 6, 96, 231, 60, 127, 7, 224], [254, 14, 248, 225, 206, 14, 96, 118, 7, 96, 118, 7, 112, 231, 30, 127, 135, 224], [254, 15, 248, 227, 206, 14, 224, 238, 7, 224, 126, 6, 224, 238, 28, 255, 15, 224], [126, 7, 248, 99, 198, 14, 96, 102, 7, 224, 126, 7, 224, 238, 30, 255, 143, 224], [126, 7, 248, 115, 199, 14, 112, 119, 7, 96, 54, 7, 96, 238, 30, 255, 143, 240], [126, 7, 248, 115, 199, 14, 112, 119, 3, 112, 55, 7, 96, 118, 30, 255, 207, 240], [126, 7, 248, 113, 198, 14, 96, 102, 7, 96, 118, 6, 96, 102, 60, 255, 143, 224], [62, 3, 248, 113, 199, 6, 112, 118, 7, 96, 118, 7, 96, 102, 30, 255, 143, 224], [254, 7, 248, 99, 198, 14, 96, 103, 6, 112, 119, 6, 112, 231, 60, 63, 131, 224], [252, 15, 248, 227, 206, 30, 96, 102, 7, 96, 118, 7, 96, 231, 60, 127, 135, 224], [252, 7, 248, 99, 198, 14, 96, 102, 7, 96, 118, 7, 112, 103, 60, 127, 135, 224], [254, 15, 252, 225, 206, 14, 224, 126, 7, 112, 119, 7, 112, 231, 30, 127, 135, 224], [254, 7, 248, 99, 198, 14, 96, 102, 7, 96, 118, 6, 96, 230, 60, 127, 135, 224], [126, 7, 248, 243, 206, 14, 224, 254, 7, 224, 126, 7, 224, 238, 30, 255, 143, 240], [126, 7, 248, 115, 199, 14, 112, 119, 7, 112, 126, 7, 224, 254, 30, 255, 207, 240], [124, 7, 248, 99, 198, 30, 96, 102, 7, 96, 118, 6, 224, 238, 60, 255, 143, 224], [124, 7, 248, 115, 199, 14, 96, 102, 7, 96, 118, 7, 96, 238, 60, 255, 207, 224], [60, 7, 248, 115, 199, 14, 112, 119, 7, 96, 118, 7, 96, 102, 30, 255, 207, 224]] }, { symbol: 'E', fingerprints: [[63, 207, 248, 192, 12, 0, 224, 7, 252, 127, 134, 0, 96, 6, 0, 103, 247, 254], [255, 207, 128, 224, 6, 0, 96, 7, 252, 120, 6, 0, 96, 6, 0, 127, 247, 255], [255, 239, 224, 192, 12, 0, 224, 15, 252, 127, 6, 0, 96, 6, 0, 127, 247, 255], [255, 239, 252, 224, 6, 0, 96, 7, 252, 127, 198, 0, 96, 6, 0, 127, 247, 254], [255, 236, 0, 192, 12, 0, 192, 15, 254, 224, 12, 0, 192, 12, 0, 255, 255, 255], [255, 238, 0, 224, 14, 0, 224, 15, 254, 224, 14, 0, 224, 14, 0, 255, 255, 255], [127, 247, 254, 96, 6, 0, 96, 7, 254, 127, 198, 0, 96, 14, 0, 255, 255, 255], [127, 231, 254, 96, 6, 0, 96, 7, 252, 127, 198, 0, 96, 6, 0, 255, 239, 254], [127, 246, 6, 96, 6, 0, 96, 7, 254, 96, 70, 0, 96, 6, 0, 255, 239, 254], [127, 231, 62, 96, 6, 0, 96, 7, 252, 103, 198, 0, 96, 6, 0, 127, 207, 254], [63, 227, 127, 112, 7, 0, 96, 7, 252, 111, 198, 0, 96, 6, 0, 127, 131, 254], [127, 199, 252, 96, 6, 0, 96, 7, 252, 127, 199, 0, 112, 7, 0, 63, 243, 254], [255, 239, 224, 224, 6, 0, 96, 7, 252, 126, 6, 0, 96, 6, 0, 127, 247, 252], [255, 231, 248, 96, 6, 0, 96, 7, 252, 127, 134, 0, 96, 6, 0, 127, 247, 254], [255, 239, 254, 224, 14, 0, 224, 7, 252, 127, 198, 0, 96, 6, 0, 127, 247, 255], [255, 255, 254, 224, 14, 0, 224, 15, 254, 255, 206, 0, 224, 14, 0, 255, 255, 255], [127, 247, 255, 96, 6, 0, 224, 15, 254, 255, 238, 0, 224, 14, 0, 255, 255, 255], [127, 231, 255, 96, 6, 0, 96, 7, 254, 127, 230, 0, 96, 14, 0, 255, 207, 254], [127, 231, 126, 112, 6, 0, 96, 7, 252, 111, 198, 0, 96, 14, 0, 255, 231, 254], [63, 231, 255, 112, 7, 0, 96, 7, 252, 127, 198, 0, 96, 6, 0, 255, 199, 254], [127, 207, 252, 96, 6, 0, 96, 7, 252, 126, 7, 0, 112, 7, 0, 63, 243, 248], [255, 239, 254, 224, 6, 0, 96, 7, 254, 127, 230, 0, 96, 6, 0, 127, 247, 255], [127, 231, 255, 96, 6, 0, 96, 7, 254, 255, 206, 0, 224, 14, 0, 255, 239, 254], [127, 231, 255, 112, 7, 0, 96, 7, 252, 127, 198, 0, 224, 14, 0, 255, 239, 254], [63, 7, 255, 112, 7, 0, 112, 7, 252, 127, 198, 0, 96, 14, 0, 255, 207, 254]] }, { symbol: 'F', fingerprints: [[127, 239, 254, 224, 15, 0, 112, 7, 254, 112, 7, 0, 112, 7, 0, 112, 3, 0], [255, 247, 192, 112, 7, 0, 112, 7, 254, 124, 7, 0, 112, 7, 0, 112, 3, 0], [255, 255, 240, 224, 15, 0, 240, 7, 254, 127, 7, 0, 112, 7, 0, 112, 7, 0], [255, 247, 254, 112, 7, 0, 112, 7, 254, 127, 199, 0, 112, 7, 0, 112, 7, 0], [255, 254, 0, 224, 14, 0, 224, 15, 254, 240, 15, 0, 240, 15, 0, 240, 7, 0], [255, 255, 0, 240, 15, 0, 240, 15, 254, 240, 15, 0, 240, 15, 0, 240, 7, 0], [255, 239, 254, 224, 14, 0, 224, 15, 252, 255, 206, 0, 224, 14, 0, 224, 12, 0], [127, 255, 255, 240, 15, 0, 224, 15, 254, 255, 206, 0, 224, 14, 0, 224, 14, 0], [127, 246, 6, 96, 6, 0, 224, 15, 252, 225, 142, 0, 224, 14, 0, 224, 14, 0], [127, 247, 127, 96, 6, 0, 96, 7, 252, 231, 206, 0, 224, 14, 0, 224, 14, 0], [127, 231, 254, 112, 7, 0, 96, 7, 248, 127, 142, 0, 224, 14, 0, 224, 14, 0], [255, 255, 254, 240, 15, 0, 240, 7, 254, 124, 7, 0, 112, 7, 0, 120, 7, 0], [255, 255, 240, 240, 7, 0, 112, 7, 254, 127, 7, 0, 112, 7, 128, 120, 7, 128], [255, 255, 252, 240, 15, 0, 240, 15, 254, 255, 199, 0, 112, 7, 0, 112, 7, 0], [255, 255, 254, 240, 15, 0, 112, 7, 254, 127, 231, 0, 112, 7, 0, 112, 7, 0], [255, 255, 254, 240, 15, 0, 240, 15, 254, 255, 207, 0, 240, 15, 0, 240, 7, 0], [127, 247, 254, 96, 6, 0, 96, 7, 254, 127, 206, 0, 224, 14, 0, 224, 6, 0], [127, 247, 255, 112, 7, 0, 112, 7, 254, 127, 230, 0, 96, 14, 0, 224, 6, 0], [127, 231, 255, 112, 7, 0, 112, 7, 252, 127, 199, 0, 96, 6, 0, 224, 6, 0], [63, 227, 255, 112, 7, 0, 112, 7, 252, 127, 199, 0, 112, 6, 0, 96, 6, 0], [127, 247, 254, 112, 7, 0, 112, 7, 254, 127, 7, 128, 120, 7, 128, 56, 3, 128], [255, 255, 255, 240, 15, 0, 112, 7, 254, 127, 199, 0, 120, 7, 128, 120, 7, 128], [255, 247, 254, 112, 7, 0, 112, 7, 254, 127, 199, 128, 120, 7, 128, 120, 7, 128], [255, 239, 254, 224, 14, 0, 224, 15, 254, 127, 199, 0, 112, 7, 0, 112, 7, 0], [127, 231, 254, 112, 7, 0, 112, 7, 252, 127, 207, 0, 224, 14, 0, 224, 14, 0]] }, { symbol: 'G', fingerprints: [[31, 131, 222, 112, 78, 0, 192, 12, 30, 199, 238, 7, 96, 55, 3, 56, 113, 254], [15, 131, 252, 112, 70, 0, 224, 14, 6, 231, 230, 6, 96, 103, 6, 56, 97, 254], [31, 199, 142, 96, 78, 0, 192, 12, 126, 199, 236, 6, 96, 103, 6, 63, 241, 252], [31, 195, 142, 112, 78, 0, 192, 12, 62, 199, 238, 6, 96, 103, 7, 56, 241, 252], [15, 195, 238, 112, 102, 0, 224, 14, 2, 231, 238, 7, 96, 119, 7, 56, 113, 254], [31, 195, 254, 96, 46, 0, 192, 12, 0, 199, 252, 3, 224, 54, 3, 63, 241, 252], [31, 195, 135, 112, 46, 0, 192, 12, 63, 195, 252, 3, 96, 55, 3, 61, 241, 254], [31, 195, 207, 112, 54, 0, 224, 12, 0, 195, 254, 3, 96, 55, 3, 56, 113, 254], [15, 195, 254, 112, 102, 0, 96, 14, 0, 231, 254, 6, 96, 103, 6, 56, 97, 254], [31, 231, 135, 112, 62, 0, 192, 12, 62, 199, 252, 7, 224, 102, 6, 127, 225, 252], [31, 195, 199, 112, 54, 0, 224, 12, 48, 199, 252, 7, 224, 118, 6, 124, 225, 254], [31, 135, 252, 112, 206, 0, 224, 12, 62, 231, 238, 6, 96, 103, 6, 56, 241, 252], [15, 131, 252, 112, 6, 0, 224, 14, 30, 231, 230, 6, 96, 103, 6, 63, 240, 252], [15, 131, 254, 112, 70, 0, 96, 14, 2, 103, 230, 6, 112, 103, 7, 63, 240, 252], [31, 199, 142, 112, 110, 0, 224, 12, 62, 199, 238, 7, 96, 119, 7, 61, 241, 254], [31, 195, 254, 112, 102, 0, 224, 14, 30, 231, 254, 7, 96, 119, 7, 56, 241, 254], [15, 195, 254, 112, 38, 0, 96, 14, 0, 231, 246, 7, 96, 119, 7, 63, 240, 252], [31, 231, 207, 112, 46, 0, 224, 12, 63, 199, 254, 3, 224, 119, 7, 127, 241, 254], [31, 195, 254, 112, 102, 0, 224, 14, 62, 231, 238, 6, 224, 103, 6, 120, 225, 254], [15, 195, 254, 112, 38, 0, 96, 14, 0, 231, 254, 7, 96, 103, 6, 63, 224, 252], [15, 195, 255, 112, 55, 0, 96, 6, 0, 231, 254, 7, 96, 119, 6, 63, 224, 252], [31, 195, 206, 112, 118, 0, 224, 12, 120, 199, 236, 6, 224, 102, 6, 127, 225, 252], [31, 135, 252, 96, 14, 0, 224, 14, 62, 231, 238, 6, 112, 103, 7, 63, 240, 252], [31, 131, 252, 112, 78, 0, 224, 14, 62, 231, 238, 6, 112, 119, 7, 63, 240, 252], [15, 131, 254, 112, 70, 0, 224, 14, 14, 231, 230, 7, 112, 119, 7, 63, 240, 252], [31, 199, 254, 112, 110, 0, 224, 14, 127, 231, 254, 7, 224, 119, 7, 63, 241, 254], [31, 195, 254, 112, 46, 0, 224, 14, 63, 231, 254, 7, 96, 119, 7, 63, 240, 252], [15, 195, 254, 112, 38, 0, 224, 14, 31, 231, 254, 7, 96, 119, 7, 63, 240, 254], [15, 195, 255, 112, 39, 0, 96, 14, 0, 231, 246, 7, 96, 119, 7, 63, 241, 254], [31, 195, 254, 112, 110, 0, 224, 14, 126, 231, 254, 7, 224, 103, 6, 127, 225, 254], [15, 195, 255, 112, 38, 0, 224, 14, 56, 231, 254, 7, 96, 119, 6, 63, 224, 252], [15, 131, 254, 120, 119, 0, 96, 6, 0, 231, 238, 6, 96, 103, 6, 63, 225, 254]] }, { symbol: 'H', fingerprints: [[64, 108, 6, 192, 110, 6, 96, 103, 254, 126, 102, 6, 96, 118, 3, 96, 50, 0], [64, 110, 6, 96, 102, 6, 96, 103, 254, 127, 102, 7, 96, 54, 3, 96, 50, 2], [192, 108, 6, 192, 110, 6, 224, 103, 255, 127, 246, 3, 96, 54, 3, 96, 54, 3], [64, 110, 6, 96, 118, 7, 96, 119, 255, 127, 246, 3, 96, 54, 3, 96, 54, 3], [192, 60, 3, 192, 60, 3, 192, 63, 255, 255, 254, 3, 224, 62, 3, 224, 54, 3], [96, 62, 3, 224, 62, 3, 224, 63, 255, 255, 254, 3, 224, 62, 3, 224, 54, 3], [192, 60, 3, 192, 60, 3, 192, 63, 255, 255, 252, 7, 192, 124, 7, 192, 108, 6], [96, 62, 3, 224, 62, 3, 192, 63, 255, 255, 252, 3, 192, 124, 7, 192, 124, 6], [96, 38, 3, 96, 54, 7, 224, 111, 254, 255, 236, 6, 192, 108, 6, 192, 108, 6], [96, 38, 3, 96, 54, 3, 96, 55, 255, 239, 236, 6, 192, 108, 6, 192, 100, 6], [96, 6, 3, 96, 118, 6, 96, 103, 254, 127, 238, 6, 192, 108, 6, 192, 236, 12], [64, 236, 14, 224, 110, 6, 224, 103, 254, 127, 102, 7, 96, 118, 7, 112, 55, 2], [64, 110, 6, 224, 102, 6, 96, 103, 254, 127, 246, 7, 96, 118, 7, 112, 55, 3], [64, 108, 6, 224, 110, 6, 224, 127, 255, 255, 246, 7, 96, 118, 3, 96, 54, 3], [96, 110, 6, 224, 110, 6, 96, 103, 254, 127, 230, 6, 96, 102, 6, 96, 102, 6], [192, 108, 6, 192, 110, 6, 224, 111, 254, 255, 238, 6, 224, 110, 7, 224, 126, 6], [64, 110, 7, 224, 126, 7, 224, 127, 255, 255, 254, 7, 224, 126, 7, 224, 126, 7], [96, 54, 7, 96, 118, 7, 96, 119, 255, 127, 254, 7, 224, 126, 7, 224, 118, 6], [96, 102, 7, 96, 118, 6, 96, 103, 254, 127, 230, 6, 96, 110, 6, 224, 102, 6], [96, 54, 7, 96, 118, 7, 96, 119, 255, 111, 230, 6, 96, 102, 6, 224, 100, 6], [48, 39, 7, 112, 103, 6, 96, 103, 254, 127, 230, 6, 96, 102, 14, 224, 228, 14], [48, 3, 7, 112, 119, 7, 112, 103, 254, 127, 230, 6, 96, 102, 6, 96, 228, 14], [0, 204, 12, 224, 238, 14, 224, 239, 254, 127, 230, 6, 96, 103, 6, 112, 119, 2], [64, 206, 14, 224, 238, 14, 96, 231, 254, 127, 230, 6, 96, 103, 6, 112, 119, 6], [192, 238, 14, 224, 238, 6, 224, 111, 254, 255, 238, 6, 96, 102, 6, 96, 118, 6], [224, 110, 6, 224, 110, 6, 224, 111, 254, 127, 230, 6, 96, 118, 7, 96, 118, 6], [192, 110, 6, 224, 110, 6, 224, 111, 255, 255, 254, 7, 224, 126, 7, 224, 118, 6], [96, 54, 7, 96, 126, 7, 224, 127, 255, 255, 254, 7, 224, 126, 7, 224, 126, 7], [96, 118, 7, 96, 118, 7, 96, 119, 254, 127, 238, 6, 224, 110, 6, 224, 110, 6], [112, 55, 7, 96, 118, 7, 96, 119, 255, 127, 246, 6, 224, 110, 6, 224, 100, 6], [112, 39, 7, 112, 119, 6, 112, 103, 254, 127, 230, 6, 96, 238, 14, 224, 228, 14], [48, 39, 7, 112, 119, 7, 112, 119, 254, 127, 230, 6, 96, 238, 14, 224, 224, 12]] }, { symbol: 'I', fingerprints: [[255, 199, 192, 12, 0, 224, 14, 0, 224, 14, 0, 240, 15, 0, 112, 127, 247, 254], [255, 207, 224, 14, 0, 224, 14, 0, 224, 14, 0, 96, 6, 0, 96, 127, 247, 255], [127, 199, 240, 14, 0, 224, 14, 0, 224, 6, 0, 96, 6, 0, 96, 127, 247, 255], [255, 239, 252, 14, 0, 224, 14, 0, 224, 14, 0, 224, 14, 0, 224, 127, 239, 255], [255, 224, 224, 14, 0, 224, 14, 0, 224, 14, 0, 224, 14, 0, 224, 255, 255, 255], [127, 224, 240, 15, 0, 240, 15, 0, 240, 15, 0, 240, 15, 0, 240, 255, 255, 255], [127, 227, 254, 7, 0, 112, 7, 0, 112, 7, 0, 112, 7, 0, 240, 255, 239, 255], [127, 240, 112, 7, 0, 112, 7, 0, 96, 6, 0, 96, 6, 0, 96, 255, 239, 254], [63, 240, 126, 7, 0, 112, 7, 0, 112, 7, 0, 96, 6, 0, 96, 255, 239, 254], [63, 224, 254, 3, 0, 112, 7, 0, 112, 7, 0, 240, 14, 0, 224, 255, 199, 254], [127, 143, 248, 12, 0, 224, 14, 0, 224, 14, 0, 240, 15, 0, 112, 15, 247, 254], [127, 199, 240, 14, 0, 224, 14, 0, 240, 15, 0, 240, 15, 0, 112, 127, 247, 255], [255, 231, 248, 14, 0, 224, 14, 0, 224, 14, 0, 96, 6, 0, 96, 127, 247, 254], [255, 224, 240, 14, 0, 224, 14, 0, 224, 15, 0, 240, 15, 0, 240, 255, 255, 255], [127, 231, 254, 15, 0, 240, 15, 0, 240, 15, 0, 240, 15, 0, 240, 255, 255, 255], [63, 225, 255, 7, 0, 112, 7, 0, 112, 15, 0, 240, 15, 0, 224, 255, 199, 254], [127, 207, 248, 14, 0, 224, 14, 0, 224, 15, 0, 240, 15, 0, 240, 31, 247, 255], [255, 239, 252, 14, 0, 224, 14, 0, 224, 14, 0, 224, 15, 0, 112, 127, 247, 254], [127, 231, 254, 14, 0, 224, 14, 0, 224, 14, 0, 112, 7, 0, 112, 127, 247, 255], [127, 231, 254, 15, 0, 112, 7, 0, 112, 7, 0, 112, 7, 0, 112, 127, 247, 255], [127, 231, 254, 7, 0, 112, 7, 0, 112, 15, 0, 224, 14, 0, 224, 255, 239, 254], [127, 227, 255, 7, 0, 112, 7, 0, 112, 7, 0, 112, 14, 0, 224, 255, 239, 254], [127, 225, 254, 7, 0, 240, 15, 0, 240, 15, 0, 240, 15, 0, 224, 255, 231, 254]] }, { symbol: 'J', fingerprints: [[1, 192, 30, 1, 224, 14, 0, 224, 14, 0, 240, 7, 96, 127, 7, 112, 243, 252], [0, 224, 14, 0, 224, 14, 0, 240, 7, 0, 112, 7, 224, 119, 7, 127, 241, 252], [1, 192, 30, 1, 224, 14, 0, 224, 14, 0, 224, 14, 192, 254, 14, 241, 227, 252], [0, 224, 14, 0, 224, 14, 0, 224, 14, 0, 224, 15, 224, 254, 15, 241, 227, 252], [0, 224, 15, 0, 240, 15, 0, 240, 15, 0, 240, 7, 224, 126, 15, 113, 227, 252], [0, 112, 7, 0, 112, 7, 0, 112, 7, 0, 112, 7, 224, 127, 15, 127, 225, 248], [0, 224, 14, 0, 224, 14, 0, 224, 14, 0, 224, 14, 224, 239, 14, 127, 225, 248], [0, 112, 7, 0, 112, 7, 0, 240, 15, 0, 240, 14, 224, 239, 14, 121, 227, 248], [0, 96, 6, 0, 96, 6, 0, 96, 6, 0, 224, 14, 224, 230, 14, 127, 195, 248], [0, 112, 7, 0, 240, 15, 0, 224, 14, 0, 224, 14, 224, 238, 14, 127, 231, 248], [0, 96, 6, 0, 96, 6, 0, 224, 14, 0, 224, 14, 225, 238, 28, 127, 195, 240], [1, 192, 30, 1, 224, 30, 0, 224, 15, 0, 240, 7, 224, 127, 7, 127, 241, 252], [0, 224, 14, 0, 224, 14, 0, 224, 14, 0, 224, 14, 240, 255, 15, 127, 225, 248], [0, 224, 14, 0, 224, 14, 0, 224, 14, 0, 224, 15, 240, 247, 15, 127, 225, 252], [0, 224, 14, 0, 224, 14, 0, 240, 15, 0, 240, 15, 112, 247, 15, 121, 225, 252], [0, 224, 15, 0, 240, 15, 0, 240, 15, 0, 240, 15, 224, 255, 15, 127, 225, 248], [0, 240, 15, 0, 240, 15, 0, 240, 14, 0, 224, 14, 224, 239, 14, 127, 227, 248], [0, 112, 7, 0, 240, 15, 0, 240, 15, 0, 240, 15, 240, 255, 14, 127, 227, 252], [0, 96, 7, 0, 112, 6, 0, 96, 14, 0, 224, 14, 224, 238, 14, 121, 227, 248], [0, 112, 7, 0, 112, 7, 0, 112, 6, 0, 100, 14, 224, 230, 30, 127, 225, 248], [0, 112, 7, 0, 96, 14, 0, 224, 14, 0, 224, 14, 224, 230, 14, 127, 193, 240], [1, 192, 30, 1, 224, 30, 0, 224, 14, 0, 224, 14, 240, 255, 15, 127, 225, 248], [0, 240, 15, 0, 240, 15, 0, 240, 15, 0, 240, 15, 240, 247, 15, 127, 225, 252], [0, 112, 15, 0, 240, 15, 0, 240, 15, 0, 240, 15, 224, 255, 15, 127, 243, 252], [0, 112, 7, 0, 112, 7, 0, 224, 14, 0, 230, 14, 224, 238, 30, 127, 225, 248], [0, 112, 7, 0, 112, 7, 0, 112, 15, 0, 230, 14, 224, 239, 30, 127, 225, 248], [0, 112, 7, 0, 112, 14, 0, 224, 14, 0, 230, 14, 224, 239, 30, 127, 193, 248]] }, { symbol: 'K', fingerprints: [[128, 204, 24, 199, 12, 96, 220, 15, 128, 252, 6, 240, 99, 134, 30, 96, 118, 0], [64, 204, 28, 195, 12, 112, 236, 7, 128, 124, 6, 240, 99, 134, 28, 96, 118, 0], [192, 204, 56, 195, 12, 224, 220, 15, 0, 248, 12, 224, 227, 142, 28, 96, 230, 2], [192, 204, 28, 195, 140, 96, 220, 15, 128, 248, 14, 224, 231, 134, 28, 96, 230, 2], [64, 110, 28, 227, 142, 112, 252, 15, 128, 120, 6, 224, 103, 6, 28, 96, 230, 7], [192, 108, 28, 195, 140, 240, 220, 15, 128, 248, 12, 224, 199, 12, 28, 192, 236, 7], [96, 38, 14, 97, 198, 112, 254, 15, 128, 248, 12, 224, 199, 140, 28, 192, 236, 7], [96, 38, 14, 97, 198, 120, 126, 7, 128, 124, 14, 240, 195, 140, 28, 192, 228, 2], [96, 6, 7, 97, 198, 120, 110, 7, 128, 124, 6, 240, 227, 140, 28, 192, 228, 7], [32, 6, 7, 97, 198, 56, 110, 7, 128, 124, 6, 224, 227, 14, 56, 192, 196, 6], [192, 204, 24, 199, 12, 224, 220, 15, 128, 252, 6, 240, 99, 198, 30, 96, 118, 0], [128, 204, 56, 199, 12, 224, 220, 15, 128, 248, 12, 224, 231, 142, 28, 224, 230, 2], [192, 204, 28, 199, 12, 112, 220, 15, 128, 252, 14, 224, 231, 142, 60, 224, 230, 2], [192, 204, 28, 195, 140, 224, 252, 15, 128, 252, 14, 224, 231, 142, 28, 224, 230, 7], [192, 110, 28, 227, 142, 112, 252, 15, 128, 252, 14, 224, 231, 142, 28, 96, 230, 7], [192, 108, 30, 195, 204, 112, 222, 15, 128, 248, 13, 224, 199, 12, 28, 192, 236, 7], [224, 110, 30, 227, 206, 240, 254, 15, 128, 252, 12, 224, 199, 140, 28, 192, 236, 7], [96, 102, 14, 225, 206, 112, 254, 15, 128, 252, 14, 224, 231, 140, 28, 192, 236, 7], [96, 54, 14, 97, 198, 120, 126, 15, 128, 252, 14, 240, 227, 142, 28, 192, 228, 3], [96, 38, 14, 99, 198, 120, 110, 7, 128, 124, 14, 224, 227, 142, 56, 192, 228, 6], [112, 7, 7, 97, 198, 120, 126, 7, 128, 124, 6, 224, 231, 14, 28, 192, 224, 6], [0, 204, 28, 195, 140, 224, 252, 15, 128, 252, 14, 224, 231, 134, 30, 96, 118, 0], [192, 204, 28, 227, 142, 112, 254, 15, 128, 252, 6, 240, 99, 134, 30, 96, 118, 3], [192, 236, 28, 227, 142, 240, 252, 15, 128, 252, 14, 224, 231, 142, 28, 224, 238, 7], [224, 238, 28, 227, 142, 112, 254, 15, 128, 252, 14, 240, 227, 142, 28, 224, 246, 2], [96, 110, 30, 227, 142, 112, 254, 15, 128, 252, 14, 240, 227, 142, 28, 224, 230, 7], [96, 102, 14, 99, 198, 120, 110, 7, 192, 124, 6, 240, 99, 134, 28, 224, 230, 7], [96, 126, 14, 227, 206, 120, 254, 15, 128, 254, 14, 240, 227, 142, 28, 224, 228, 3], [96, 54, 15, 99, 198, 120, 254, 15, 128, 254, 14, 240, 231, 142, 28, 224, 236, 7], [96, 38, 15, 99, 198, 120, 126, 7, 128, 252, 14, 224, 231, 142, 56, 225, 236, 6], [112, 39, 15, 113, 198, 120, 126, 7, 128, 124, 14, 224, 231, 142, 28, 224, 224, 6]] }, { symbol: 'L', fingerprints: [[192, 12, 0, 192, 14, 0, 96, 6, 0, 96, 6, 0, 96, 6, 0, 127, 247, 254], [192, 14, 0, 96, 6, 0, 96, 6, 0, 96, 6, 0, 96, 6, 0, 127, 247, 255], [192, 12, 0, 192, 12, 0, 224, 14, 0, 96, 6, 0, 96, 6, 0, 127, 247, 255], [64, 14, 0, 224, 6, 0, 96, 6, 0, 96, 6, 0, 96, 6, 0, 127, 231, 254], [192, 12, 0, 192, 12, 0, 192, 12, 0, 192, 12, 0, 192, 14, 0, 255, 239, 254], [224, 14, 0, 224, 14, 0, 224, 14, 0, 224, 14, 0, 224, 14, 0, 255, 239, 255], [96, 6, 0, 96, 6, 0, 96, 6, 0, 96, 6, 0, 96, 14, 0, 255, 239, 255], [96, 6, 0, 96, 6, 0, 96, 6, 0, 96, 6, 0, 96, 6, 0, 127, 15, 255], [48, 7, 0, 96, 6, 0, 96, 6, 0, 96, 6, 0, 96, 6, 0, 120, 15, 255], [48, 3, 0, 48, 7, 0, 96, 6, 0, 96, 6, 0, 96, 6, 0, 127, 195, 255], [192, 12, 0, 192, 12, 0, 192, 12, 0, 224, 14, 0, 224, 6, 6, 127, 247, 224], [192, 12, 0, 192, 12, 0, 192, 14, 0, 224, 14, 0, 96, 6, 0, 127, 247, 248], [192, 12, 0, 192, 14, 0, 224, 14, 0, 224, 6, 0, 96, 6, 0, 127, 231, 254], [192, 14, 0, 224, 14, 0, 224, 6, 0, 96, 6, 0, 96, 6, 0, 127, 231, 254], [192, 12, 0, 192, 12, 0, 192, 14, 0, 224, 14, 0, 224, 14, 0, 255, 239, 255], [96, 6, 0, 96, 6, 0, 96, 14, 0, 224, 14, 0, 224, 14, 0, 255, 239, 255], [112, 7, 0, 112, 6, 0, 96, 6, 0, 96, 6, 0, 96, 6, 0, 255, 227, 255], [48, 3, 0, 112, 7, 0, 112, 6, 0, 96, 6, 0, 96, 6, 0, 255, 231, 255], [192, 14, 0, 224, 14, 0, 224, 14, 0, 96, 6, 0, 96, 6, 14, 127, 247, 248], [192, 12, 0, 192, 12, 0, 224, 14, 0, 224, 14, 0, 224, 6, 0, 127, 247, 254], [192, 14, 0, 224, 14, 0, 224, 14, 0, 224, 14, 0, 224, 6, 0, 127, 247, 254], [224, 14, 0, 224, 14, 0, 224, 14, 0, 224, 6, 0, 96, 6, 0, 127, 247, 254], [96, 14, 0, 96, 6, 0, 96, 6, 0, 96, 6, 0, 96, 6, 0, 127, 231, 255], [112, 7, 0, 112, 7, 0, 96, 6, 0, 96, 6, 0, 96, 14, 0, 255, 231, 255], [48, 7, 0, 112, 7, 0, 112, 7, 0, 96, 6, 0, 96, 14, 0, 255, 239, 255]] }, { symbol: 'M', fingerprints: [[225, 239, 30, 243, 111, 182, 219, 108, 246, 206, 108, 103, 224, 62, 3, 96, 54, 0], [225, 239, 30, 249, 237, 182, 223, 108, 246, 206, 126, 99, 224, 54, 3, 96, 54, 2], [225, 239, 30, 243, 109, 182, 223, 108, 230, 206, 108, 102, 192, 108, 6, 192, 124, 2], [241, 239, 30, 241, 237, 182, 223, 108, 246, 206, 108, 102, 192, 108, 7, 192, 124, 2], [240, 239, 30, 249, 237, 190, 223, 108, 246, 206, 108, 103, 192, 124, 7, 192, 124, 3], [240, 255, 159, 217, 253, 191, 207, 124, 247, 206, 124, 103, 192, 124, 7, 192, 124, 3], [112, 247, 143, 121, 247, 219, 239, 62, 243, 231, 62, 99, 224, 60, 3, 192, 52, 3], [240, 239, 159, 249, 253, 191, 223, 108, 246, 206, 108, 102, 192, 108, 6, 192, 108, 6], [112, 247, 143, 249, 255, 155, 207, 60, 247, 206, 108, 102, 192, 108, 6, 192, 96, 6], [120, 103, 143, 121, 247, 219, 239, 190, 243, 207, 124, 103, 192, 108, 6, 192, 104, 6], [120, 7, 143, 124, 246, 219, 109, 182, 243, 231, 60, 103, 192, 108, 6, 192, 108, 6], [241, 239, 62, 251, 109, 182, 255, 110, 246, 102, 118, 103, 96, 54, 3, 96, 54, 0], [225, 239, 30, 251, 237, 190, 223, 108, 247, 239, 126, 103, 224, 62, 3, 96, 54, 3], [113, 239, 30, 249, 253, 191, 223, 126, 247, 239, 126, 99, 224, 54, 3, 96, 54, 3], [241, 239, 30, 251, 237, 182, 223, 108, 246, 206, 108, 230, 192, 124, 7, 192, 124, 3], [241, 239, 30, 249, 237, 191, 223, 124, 247, 207, 124, 103, 192, 124, 7, 224, 124, 7], [240, 255, 159, 249, 255, 159, 255, 126, 247, 239, 126, 103, 224, 126, 7, 224, 126, 7], [120, 255, 159, 249, 255, 219, 239, 190, 243, 239, 62, 103, 224, 126, 7, 224, 124, 3], [120, 255, 159, 249, 255, 223, 239, 252, 247, 206, 124, 103, 192, 108, 6, 192, 108, 6], [120, 119, 143, 121, 247, 219, 239, 190, 247, 239, 124, 103, 192, 124, 6, 192, 108, 6], [120, 103, 143, 124, 246, 219, 111, 190, 243, 239, 62, 103, 192, 124, 6, 192, 96, 6], [1, 239, 62, 251, 239, 182, 255, 110, 247, 239, 118, 103, 96, 118, 7, 96, 54, 2], [241, 239, 30, 251, 239, 190, 223, 126, 247, 239, 126, 103, 224, 126, 3, 224, 54, 3], [241, 239, 31, 249, 255, 191, 255, 254, 247, 239, 126, 103, 224, 62, 3, 224, 54, 3], [225, 239, 30, 251, 239, 190, 223, 109, 246, 206, 124, 231, 192, 126, 7, 224, 126, 7], [241, 239, 159, 251, 253, 191, 223, 124, 247, 239, 126, 103, 224, 126, 7, 224, 124, 2], [240, 239, 159, 249, 255, 191, 223, 124, 247, 207, 124, 231, 192, 108, 6, 192, 108, 6], [248, 255, 159, 249, 255, 223, 255, 254, 247, 207, 124, 103, 192, 124, 6, 192, 108, 6], [120, 247, 143, 253, 255, 219, 239, 254, 247, 239, 126, 103, 192, 124, 7, 192, 108, 6], [120, 231, 159, 125, 246, 255, 239, 126, 247, 238, 110, 102, 192, 108, 6, 192, 224, 6]] }, { symbol: 'N', fingerprints: [[192, 206, 14, 240, 111, 134, 220, 108, 230, 231, 102, 54, 97, 230, 31, 96, 246, 0], [96, 111, 6, 240, 111, 134, 252, 110, 230, 103, 102, 54, 97, 246, 31, 96, 246, 6], [224, 111, 6, 248, 103, 134, 108, 102, 102, 103, 102, 63, 97, 246, 15, 96, 246, 6], [224, 111, 6, 240, 109, 134, 220, 108, 231, 199, 126, 63, 225, 246, 15, 96, 246, 7], [96, 47, 7, 240, 127, 135, 238, 62, 227, 231, 54, 59, 97, 246, 15, 96, 246, 7], [224, 63, 3, 248, 61, 195, 204, 60, 227, 199, 60, 59, 195, 188, 31, 192, 252, 7], [224, 47, 7, 248, 125, 135, 204, 108, 230, 199, 108, 118, 193, 236, 30, 192, 236, 6], [112, 55, 3, 120, 55, 131, 238, 62, 231, 231, 124, 55, 193, 236, 30, 192, 236, 14], [112, 39, 7, 120, 103, 198, 108, 102, 102, 230, 110, 54, 195, 236, 30, 193, 228, 14], [112, 39, 131, 120, 55, 195, 108, 118, 102, 103, 110, 54, 227, 236, 30, 193, 228, 14], [112, 7, 7, 120, 103, 134, 236, 108, 198, 198, 108, 118, 195, 236, 62, 193, 200, 28], [192, 238, 14, 240, 239, 134, 220, 110, 230, 231, 110, 62, 97, 246, 31, 96, 246, 6], [224, 111, 6, 248, 111, 134, 252, 110, 230, 231, 102, 63, 97, 246, 31, 96, 246, 6], [96, 111, 6, 248, 111, 134, 252, 102, 230, 103, 118, 63, 97, 246, 31, 96, 246, 7], [224, 111, 6, 240, 111, 135, 220, 126, 231, 231, 126, 63, 225, 254, 15, 224, 246, 7], [224, 127, 7, 248, 127, 135, 238, 126, 231, 231, 126, 63, 225, 254, 15, 224, 246, 7], [224, 63, 3, 248, 63, 131, 220, 60, 227, 199, 60, 59, 193, 252, 31, 192, 252, 7], [224, 127, 7, 248, 127, 135, 238, 124, 231, 199, 124, 119, 193, 236, 30, 192, 236, 14], [112, 55, 3, 248, 63, 199, 238, 126, 231, 231, 126, 119, 225, 252, 31, 192, 236, 14], [112, 39, 135, 120, 119, 199, 108, 110, 230, 231, 110, 54, 227, 238, 30, 193, 228, 14], [112, 39, 131, 120, 119, 199, 108, 118, 103, 103, 110, 54, 227, 238, 30, 193, 228, 14], [112, 7, 7, 120, 119, 134, 236, 110, 230, 198, 108, 118, 195, 236, 62, 193, 236, 28], [0, 206, 14, 240, 239, 142, 252, 110, 230, 230, 110, 118, 227, 246, 31, 96, 246, 6], [224, 239, 14, 248, 111, 134, 252, 110, 230, 231, 126, 63, 97, 246, 31, 96, 246, 7], [112, 111, 7, 248, 119, 199, 110, 118, 103, 103, 118, 63, 97, 246, 15, 96, 246, 7], [112, 111, 7, 248, 127, 199, 236, 126, 231, 231, 126, 63, 227, 254, 31, 224, 246, 14], [112, 39, 135, 120, 119, 199, 108, 118, 231, 103, 118, 63, 227, 254, 31, 224, 246, 14], [112, 47, 7, 248, 111, 198, 236, 110, 230, 230, 110, 118, 227, 238, 30, 193, 236, 14], [112, 55, 135, 120, 119, 199, 236, 126, 230, 231, 110, 54, 227, 238, 30, 225, 236, 14], [112, 47, 7, 248, 111, 134, 252, 110, 230, 198, 236, 126, 195, 236, 62, 193, 236, 28], [112, 39, 135, 120, 127, 199, 236, 110, 230, 230, 108, 126, 195, 236, 62, 193, 224, 12]] }, { symbol: 'O', fingerprints: [[31, 3, 252, 112, 198, 6, 192, 124, 3, 192, 62, 3, 96, 119, 6, 56, 225, 248], [15, 3, 252, 96, 230, 6, 224, 124, 3, 224, 54, 3, 96, 119, 6, 63, 192, 248], [31, 131, 156, 112, 230, 6, 96, 110, 7, 96, 118, 7, 96, 99, 14, 63, 192, 248], [31, 131, 156, 112, 230, 6, 192, 124, 3, 192, 60, 7, 96, 103, 14, 57, 193, 248], [31, 131, 252, 112, 230, 6, 224, 60, 3, 192, 62, 3, 96, 119, 14, 57, 193, 248], [15, 3, 252, 112, 230, 6, 96, 110, 6, 224, 102, 6, 96, 103, 14, 63, 192, 240], [15, 131, 252, 48, 230, 7, 96, 60, 3, 192, 62, 3, 96, 103, 14, 57, 193, 248], [15, 1, 252, 48, 230, 6, 96, 102, 7, 224, 118, 6, 96, 103, 12, 63, 192, 240], [31, 131, 156, 112, 102, 6, 192, 60, 3, 192, 60, 6, 224, 102, 12, 123, 193, 240], [31, 3, 252, 112, 198, 14, 224, 110, 6, 224, 118, 6, 96, 103, 14, 63, 192, 240], [15, 3, 252, 112, 230, 14, 96, 110, 7, 224, 118, 7, 96, 103, 14, 63, 192, 248], [31, 131, 188, 112, 238, 6, 192, 124, 7, 192, 62, 7, 96, 103, 14, 57, 193, 248], [31, 131, 252, 112, 230, 6, 224, 126, 3, 224, 62, 3, 96, 119, 14, 57, 225, 248], [15, 3, 252, 112, 231, 6, 96, 118, 7, 224, 118, 7, 96, 103, 14, 63, 192, 240], [31, 131, 220, 112, 230, 7, 224, 124, 3, 192, 62, 7, 224, 103, 14, 59, 193, 248], [15, 131, 252, 112, 230, 6, 224, 110, 7, 224, 126, 6, 96, 103, 12, 59, 193, 240], [15, 131, 252, 112, 231, 6, 96, 126, 7, 224, 126, 6, 96, 231, 14, 63, 193, 240], [15, 131, 222, 48, 231, 7, 96, 118, 7, 224, 118, 7, 96, 103, 12, 63, 193, 240], [31, 7, 252, 96, 206, 14, 224, 108, 6, 224, 126, 6, 96, 231, 14, 63, 192, 240], [31, 3, 252, 112, 230, 14, 224, 110, 7, 224, 126, 7, 112, 103, 14, 63, 192, 248], [31, 131, 252, 112, 230, 6, 96, 126, 7, 224, 118, 7, 112, 115, 142, 63, 192, 248], [31, 3, 252, 112, 230, 14, 224, 110, 7, 224, 126, 6, 96, 231, 14, 63, 192, 240], [15, 3, 252, 112, 230, 6, 224, 126, 7, 224, 126, 7, 96, 103, 14, 63, 192, 240], [15, 131, 252, 112, 231, 6, 96, 126, 7, 224, 118, 7, 96, 103, 14, 63, 193, 248], [31, 131, 252, 112, 230, 14, 224, 110, 6, 224, 110, 6, 224, 231, 28, 127, 193, 240], [15, 129, 252, 56, 231, 7, 96, 126, 7, 224, 126, 7, 96, 103, 14, 63, 193, 240]] }, { symbol: 'P', fingerprints: [[255, 207, 14, 192, 110, 7, 96, 103, 252, 127, 134, 0, 96, 6, 0, 96, 6, 0], [255, 207, 158, 96, 118, 3, 96, 119, 254, 127, 134, 0, 96, 6, 0, 96, 6, 0], [255, 207, 254, 192, 124, 3, 224, 119, 254, 127, 198, 0, 96, 6, 0, 96, 6, 0], [255, 206, 14, 96, 118, 3, 96, 103, 254, 127, 134, 0, 96, 6, 0, 96, 6, 0], [255, 204, 30, 192, 124, 3, 192, 127, 254, 255, 140, 0, 224, 14, 0, 224, 14, 0], [255, 142, 30, 224, 110, 7, 224, 110, 30, 255, 142, 0, 224, 14, 0, 224, 6, 0], [127, 135, 254, 96, 118, 3, 96, 118, 14, 127, 198, 0, 96, 6, 0, 224, 6, 0], [255, 143, 254, 224, 124, 3, 192, 63, 254, 255, 204, 0, 192, 12, 0, 192, 12, 0], [127, 7, 254, 96, 102, 3, 224, 127, 254, 255, 204, 0, 192, 12, 0, 192, 12, 0], [127, 134, 62, 96, 118, 3, 96, 119, 142, 255, 204, 0, 192, 12, 0, 192, 12, 0], [127, 134, 126, 96, 102, 7, 96, 102, 14, 127, 206, 0, 192, 12, 0, 192, 12, 0], [255, 199, 222, 96, 118, 7, 96, 103, 254, 127, 135, 0, 112, 3, 0, 48, 3, 0], [255, 207, 254, 224, 118, 3, 96, 119, 254, 127, 198, 0, 96, 6, 0, 112, 7, 0], [255, 143, 254, 224, 110, 7, 224, 111, 254, 255, 198, 0, 96, 6, 0, 96, 6, 0], [255, 206, 14, 224, 126, 7, 96, 119, 254, 127, 134, 0, 96, 6, 0, 96, 6, 0], [255, 206, 30, 192, 124, 3, 224, 127, 254, 255, 206, 0, 224, 14, 0, 224, 14, 0], [255, 207, 254, 224, 110, 7, 224, 111, 254, 255, 206, 0, 224, 14, 0, 224, 14, 0], [127, 135, 254, 96, 118, 3, 96, 119, 254, 255, 206, 0, 224, 14, 0, 224, 6, 0], [127, 135, 254, 96, 230, 7, 96, 103, 254, 127, 198, 0, 96, 14, 0, 224, 6, 0], [127, 7, 254, 112, 246, 3, 96, 119, 254, 127, 230, 0, 96, 6, 0, 224, 6, 0], [127, 135, 254, 96, 102, 7, 96, 103, 14, 255, 206, 0, 224, 12, 0, 192, 12, 0], [255, 199, 254, 96, 102, 7, 96, 119, 254, 127, 198, 0, 112, 7, 0, 112, 7, 0], [255, 199, 254, 96, 102, 7, 96, 231, 252, 127, 134, 0, 96, 6, 0, 96, 6, 0], [127, 135, 254, 96, 230, 7, 96, 119, 254, 127, 206, 0, 224, 14, 0, 224, 14, 0], [127, 7, 252, 96, 230, 7, 224, 111, 254, 255, 206, 0, 224, 12, 0, 192, 12, 0], [127, 7, 254, 97, 230, 7, 96, 127, 222, 255, 238, 112, 224, 14, 0, 192, 12, 0]] }, { symbol: 'Q', fingerprints: [[30, 7, 248, 97, 204, 12, 192, 204, 14, 198, 110, 126, 99, 199, 28, 63, 240, 227], [63, 7, 56, 225, 140, 12, 192, 204, 12, 206, 204, 124, 227, 199, 60, 63, 96, 6], [63, 7, 56, 225, 204, 12, 192, 204, 12, 206, 204, 124, 227, 199, 28, 63, 224, 199], [31, 7, 56, 97, 204, 12, 192, 236, 14, 198, 236, 124, 99, 195, 188, 63, 224, 2], [31, 3, 184, 97, 206, 12, 192, 108, 6, 198, 110, 126, 99, 195, 188, 63, 224, 7], [31, 3, 248, 113, 198, 14, 224, 108, 6, 198, 102, 118, 99, 195, 28, 63, 224, 7], [31, 131, 156, 112, 198, 6, 96, 110, 6, 102, 102, 118, 113, 195, 252, 31, 224, 3], [31, 131, 156, 96, 238, 6, 192, 108, 6, 198, 108, 118, 97, 231, 188, 63, 224, 7], [31, 131, 252, 96, 102, 6, 224, 108, 6, 198, 110, 126, 97, 199, 156, 31, 224, 3], [15, 131, 252, 112, 102, 6, 96, 126, 7, 230, 102, 118, 97, 231, 28, 31, 224, 3], [31, 131, 142, 48, 102, 7, 96, 54, 3, 230, 118, 118, 97, 227, 252, 31, 224, 7], [30, 7, 248, 97, 206, 12, 192, 236, 14, 198, 238, 126, 99, 231, 28, 63, 240, 247], [62, 7, 248, 225, 140, 28, 192, 204, 12, 204, 204, 252, 227, 199, 60, 63, 224, 199], [63, 7, 248, 97, 206, 12, 192, 236, 14, 206, 238, 126, 99, 199, 252, 63, 224, 3], [31, 7, 248, 113, 206, 14, 192, 236, 6, 198, 110, 126, 99, 199, 188, 63, 224, 7], [31, 3, 252, 112, 198, 14, 224, 110, 6, 230, 102, 126, 113, 199, 156, 31, 224, 3], [15, 3, 252, 112, 198, 14, 96, 110, 6, 230, 102, 126, 115, 199, 156, 31, 224, 7], [31, 135, 156, 112, 238, 6, 192, 108, 6, 206, 110, 118, 99, 231, 252, 63, 224, 7], [31, 131, 252, 96, 230, 6, 224, 108, 6, 231, 110, 126, 97, 231, 188, 31, 224, 3], [15, 131, 252, 112, 102, 6, 224, 126, 7, 231, 110, 126, 97, 231, 156, 31, 224, 7], [31, 131, 158, 112, 102, 7, 96, 126, 7, 231, 118, 62, 113, 227, 252, 31, 224, 3], [63, 7, 248, 97, 206, 12, 192, 236, 14, 198, 238, 126, 99, 199, 190, 63, 240, 67], [31, 7, 248, 113, 206, 14, 224, 238, 14, 230, 238, 126, 99, 231, 190, 63, 240, 227], [30, 7, 248, 225, 206, 12, 192, 236, 14, 206, 238, 126, 227, 199, 60, 63, 224, 2], [31, 7, 252, 113, 206, 14, 224, 236, 14, 230, 238, 126, 99, 199, 252, 63, 224, 71], [31, 3, 252, 112, 206, 14, 224, 238, 6, 230, 110, 126, 115, 199, 188, 31, 224, 3], [31, 3, 252, 112, 230, 14, 224, 110, 6, 230, 110, 126, 115, 231, 156, 31, 224, 7], [31, 131, 252, 112, 230, 6, 96, 110, 6, 231, 102, 62, 113, 227, 254, 31, 240, 3], [31, 131, 252, 112, 230, 6, 224, 126, 7, 239, 110, 126, 113, 231, 252, 31, 224, 7], [31, 131, 252, 112, 230, 6, 224, 126, 7, 231, 126, 126, 113, 231, 156, 63, 224, 7], [15, 131, 254, 112, 102, 7, 224, 126, 7, 231, 126, 126, 113, 227, 254, 31, 224, 3]] }, { symbol: 'R', fingerprints: [[255, 143, 28, 96, 230, 6, 96, 231, 252, 127, 134, 24, 96, 199, 6, 48, 115, 0], [255, 143, 254, 192, 110, 6, 96, 103, 252, 127, 134, 56, 97, 198, 6, 96, 118, 2], [255, 143, 254, 96, 102, 6, 96, 103, 252, 127, 134, 56, 97, 198, 6, 96, 118, 3], [255, 204, 30, 192, 108, 7, 224, 239, 254, 255, 6, 56, 97, 198, 14, 96, 118, 3], [255, 206, 30, 96, 118, 3, 96, 119, 254, 127, 134, 56, 97, 198, 14, 96, 118, 3], [255, 142, 62, 192, 236, 6, 192, 238, 62, 255, 140, 112, 193, 140, 28, 192, 236, 7], [255, 143, 254, 224, 238, 3, 224, 111, 254, 255, 204, 112, 193, 204, 14, 192, 236, 2], [127, 7, 254, 96, 246, 3, 96, 119, 254, 255, 206, 48, 225, 204, 14, 192, 236, 7], [127, 134, 30, 96, 102, 7, 96, 103, 252, 127, 134, 56, 225, 140, 28, 192, 228, 6], [127, 134, 62, 96, 118, 3, 96, 119, 254, 127, 198, 56, 225, 142, 28, 192, 228, 6], [63, 135, 126, 96, 118, 3, 96, 119, 254, 127, 198, 56, 97, 142, 28, 192, 228, 6], [255, 143, 252, 224, 198, 14, 96, 199, 248, 127, 6, 56, 113, 199, 14, 112, 99, 2], [255, 143, 252, 224, 238, 14, 224, 231, 252, 127, 134, 120, 97, 198, 14, 96, 102, 2], [255, 142, 30, 224, 110, 6, 224, 239, 252, 255, 142, 56, 227, 198, 30, 96, 102, 6], [255, 142, 62, 224, 110, 6, 224, 239, 254, 255, 134, 56, 99, 198, 30, 96, 102, 7], [255, 143, 254, 192, 236, 7, 192, 239, 254, 255, 140, 120, 193, 204, 14, 192, 236, 2], [255, 143, 254, 224, 254, 7, 224, 127, 254, 255, 206, 120, 225, 206, 14, 192, 236, 7], [127, 135, 254, 96, 246, 3, 224, 127, 254, 255, 206, 120, 225, 206, 14, 224, 236, 7], [127, 135, 254, 96, 102, 7, 96, 119, 254, 255, 142, 56, 227, 206, 28, 224, 228, 6], [127, 135, 254, 96, 118, 3, 96, 119, 254, 127, 134, 56, 225, 206, 28, 224, 224, 6], [255, 135, 252, 96, 230, 14, 96, 231, 252, 127, 135, 56, 113, 199, 14, 112, 99, 2], [255, 135, 252, 96, 230, 6, 96, 231, 252, 127, 198, 120, 97, 198, 14, 96, 230, 7], [255, 207, 254, 224, 110, 6, 224, 239, 252, 255, 142, 56, 225, 206, 14, 224, 102, 2], [255, 207, 254, 224, 238, 7, 224, 239, 254, 255, 206, 120, 225, 206, 30, 224, 236, 7], [127, 135, 254, 224, 110, 7, 224, 111, 254, 255, 142, 56, 227, 206, 28, 224, 228, 6], [127, 7, 252, 112, 231, 7, 96, 103, 254, 127, 206, 112, 227, 142, 28, 224, 192, 6]] }, { symbol: 'S', fingerprints: [[63, 135, 158, 224, 236, 0, 240, 3, 240, 7, 192, 15, 0, 55, 3, 112, 227, 252], [31, 135, 254, 224, 110, 0, 112, 3, 240, 3, 224, 7, 64, 55, 3, 127, 225, 248], [63, 135, 30, 192, 236, 0, 120, 3, 240, 7, 192, 14, 64, 126, 6, 121, 227, 248], [63, 135, 30, 224, 236, 0, 120, 3, 240, 7, 192, 14, 64, 54, 6, 113, 227, 252], [31, 135, 190, 224, 110, 0, 240, 3, 240, 15, 192, 14, 0, 126, 7, 240, 227, 248], [31, 135, 254, 224, 126, 0, 112, 3, 240, 3, 224, 7, 192, 126, 7, 127, 225, 248], [31, 199, 15, 224, 126, 0, 120, 1, 248, 3, 224, 15, 192, 126, 7, 127, 225, 248], [31, 199, 143, 112, 118, 0, 120, 1, 248, 7, 192, 15, 96, 126, 7, 112, 225, 248], [31, 199, 222, 112, 119, 0, 120, 1, 240, 7, 192, 14, 64, 126, 6, 112, 227, 252], [15, 195, 254, 112, 119, 2, 120, 1, 240, 7, 192, 14, 64, 126, 6, 112, 227, 252], [31, 195, 142, 112, 118, 0, 60, 1, 240, 3, 192, 14, 64, 102, 6, 123, 227, 248], [63, 135, 254, 192, 236, 0, 240, 3, 240, 3, 224, 7, 96, 55, 7, 127, 225, 248], [31, 135, 252, 224, 110, 0, 112, 3, 240, 7, 192, 6, 96, 118, 6, 127, 225, 248], [63, 199, 158, 224, 238, 0, 120, 3, 240, 7, 192, 14, 64, 126, 7, 121, 227, 252], [63, 199, 254, 112, 238, 0, 120, 3, 240, 7, 192, 14, 64, 126, 7, 121, 227, 252], [31, 199, 143, 224, 126, 0, 124, 1, 248, 7, 224, 15, 224, 126, 7, 127, 227, 248], [63, 199, 158, 112, 118, 0, 120, 1, 240, 7, 192, 14, 192, 126, 14, 121, 227, 252], [31, 131, 254, 96, 118, 2, 120, 1, 224, 7, 192, 14, 192, 110, 6, 127, 227, 248], [31, 195, 158, 112, 119, 0, 60, 1, 248, 7, 192, 14, 192, 110, 6, 127, 227, 248], [31, 135, 252, 224, 206, 0, 112, 3, 248, 7, 224, 6, 96, 119, 6, 63, 225, 248], [63, 135, 254, 224, 238, 0, 240, 3, 240, 7, 224, 6, 96, 118, 7, 127, 225, 248], [31, 135, 254, 224, 110, 0, 112, 3, 240, 7, 224, 15, 96, 118, 7, 127, 227, 252], [63, 199, 254, 224, 238, 0, 120, 3, 248, 15, 224, 15, 64, 127, 15, 127, 227, 252], [63, 199, 254, 224, 110, 0, 120, 3, 240, 7, 224, 15, 224, 127, 7, 127, 225, 248], [31, 135, 254, 96, 102, 0, 120, 3, 240, 7, 192, 14, 96, 126, 6, 127, 227, 248], [63, 199, 254, 112, 127, 0, 120, 3, 240, 7, 192, 14, 192, 126, 14, 255, 227, 252], [31, 199, 255, 112, 119, 2, 120, 3, 240, 7, 224, 15, 192, 126, 15, 127, 227, 248], [31, 135, 254, 96, 118, 2, 120, 3, 240, 7, 192, 14, 224, 110, 6, 127, 227, 248], [31, 131, 254, 112, 119, 3, 120, 1, 240, 7, 192, 30, 224, 110, 6, 127, 227, 248]] }, { symbol: 'T', fingerprints: [[31, 255, 254, 6, 0, 96, 7, 0, 112, 7, 0, 112, 7, 0, 48, 3, 0, 48], [127, 247, 224, 6, 0, 96, 6, 0, 96, 7, 0, 112, 3, 0, 48, 3, 0, 48], [255, 255, 240, 6, 0, 96, 6, 0, 112, 7, 0, 112, 7, 0, 112, 7, 0, 48], [127, 231, 254, 6, 0, 96, 6, 0, 96, 6, 0, 96, 6, 0, 96, 6, 0, 96], [255, 240, 96, 6, 0, 96, 6, 0, 96, 6, 0, 96, 6, 0, 96, 6, 0, 96], [255, 247, 254, 6, 0, 96, 6, 0, 96, 6, 0, 224, 14, 0, 224, 14, 0, 96], [255, 231, 254, 6, 0, 96, 6, 0, 96, 6, 0, 96, 6, 0, 224, 14, 0, 64], [255, 240, 102, 6, 0, 224, 14, 0, 224, 14, 0, 224, 14, 0, 224, 14, 0, 224], [255, 224, 126, 6, 0, 96, 6, 0, 224, 14, 0, 192, 12, 0, 192, 12, 0, 192], [255, 224, 255, 14, 0, 224, 14, 0, 224, 14, 0, 224, 12, 0, 192, 12, 0, 128], [63, 255, 254, 6, 0, 112, 7, 0, 48, 3, 0, 48, 3, 0, 48, 3, 0, 48], [63, 239, 254, 6, 0, 96, 6, 0, 112, 7, 0, 112, 7, 0, 48, 3, 0, 48], [127, 247, 252, 6, 0, 112, 7, 0, 112, 7, 0, 112, 3, 0, 48, 3, 0, 48], [127, 255, 254, 6, 0, 96, 6, 0, 96, 6, 0, 96, 6, 0, 112, 7, 0, 96], [127, 240, 112, 6, 0, 96, 6, 0, 96, 7, 0, 112, 7, 0, 112, 7, 0, 112], [255, 231, 255, 6, 0, 96, 6, 0, 96, 6, 0, 96, 14, 0, 224, 14, 0, 224], [255, 239, 255, 14, 0, 224, 14, 0, 224, 14, 0, 224, 14, 0, 224, 14, 0, 224], [255, 135, 255, 6, 0, 96, 14, 0, 224, 14, 0, 224, 12, 0, 192, 12, 0, 192], [255, 225, 255, 14, 0, 224, 14, 0, 224, 14, 0, 224, 12, 0, 192, 28, 1, 192], [127, 255, 254, 7, 0, 112, 7, 0, 112, 7, 0, 48, 3, 0, 48, 3, 128, 56], [127, 255, 254, 6, 0, 96, 6, 0, 112, 7, 0, 112, 7, 0, 112, 3, 0, 48], [255, 239, 254, 6, 0, 96, 6, 0, 96, 6, 0, 96, 6, 0, 112, 7, 0, 112], [255, 255, 254, 6, 0, 96, 6, 0, 96, 6, 0, 112, 7, 0, 112, 7, 0, 112], [255, 239, 254, 14, 0, 224, 6, 0, 96, 6, 0, 96, 6, 0, 96, 6, 0, 96], [255, 247, 255, 6, 0, 96, 6, 0, 224, 14, 0, 224, 14, 0, 224, 14, 0, 224], [255, 239, 254, 14, 0, 224, 14, 0, 224, 14, 0, 224, 12, 0, 192, 12, 0, 192], [255, 199, 255, 6, 0, 224, 14, 0, 224, 14, 0, 224, 14, 0, 192, 12, 0, 192], [255, 15, 255, 14, 0, 224, 14, 0, 192, 12, 0, 192, 12, 1, 192, 28, 1, 192]] }, { symbol: 'U', fingerprints: [[64, 110, 6, 224, 102, 6, 96, 102, 6, 96, 118, 3, 96, 55, 7, 56, 225, 252], [64, 108, 6, 192, 108, 6, 224, 118, 3, 96, 54, 3, 96, 54, 7, 63, 225, 248], [64, 110, 7, 224, 118, 3, 96, 54, 3, 96, 54, 3, 96, 55, 7, 57, 225, 252], [192, 108, 6, 192, 108, 6, 192, 108, 6, 224, 110, 7, 96, 118, 6, 113, 225, 248], [64, 110, 7, 224, 126, 7, 224, 118, 7, 96, 118, 3, 96, 54, 6, 112, 227, 252], [192, 60, 3, 192, 60, 3, 192, 60, 3, 192, 60, 3, 192, 54, 6, 127, 225, 248], [224, 62, 3, 224, 60, 3, 192, 60, 3, 192, 60, 3, 192, 54, 7, 125, 225, 252], [96, 54, 3, 96, 54, 3, 96, 126, 7, 224, 126, 6, 192, 102, 6, 113, 227, 248], [96, 54, 3, 96, 54, 3, 96, 54, 3, 96, 62, 7, 224, 102, 6, 112, 227, 252], [96, 38, 3, 96, 62, 7, 192, 108, 6, 192, 108, 6, 192, 108, 6, 127, 193, 248], [96, 6, 3, 96, 54, 3, 96, 62, 7, 192, 108, 6, 192, 108, 6, 121, 195, 248], [64, 110, 6, 224, 102, 6, 96, 102, 7, 96, 118, 3, 112, 55, 7, 63, 224, 248], [64, 108, 6, 192, 110, 7, 224, 126, 7, 96, 54, 3, 96, 54, 7, 63, 225, 248], [64, 110, 6, 224, 110, 6, 96, 102, 6, 96, 102, 7, 96, 118, 6, 63, 225, 248], [192, 108, 6, 192, 108, 6, 224, 110, 7, 224, 126, 7, 224, 118, 6, 121, 227, 252], [192, 110, 7, 224, 126, 7, 224, 126, 7, 224, 126, 7, 96, 118, 7, 112, 227, 252], [224, 126, 7, 224, 126, 7, 224, 126, 6, 224, 110, 6, 224, 110, 6, 127, 227, 248], [96, 54, 3, 96, 126, 7, 224, 126, 7, 224, 126, 7, 224, 110, 6, 121, 227, 248], [96, 38, 7, 96, 118, 6, 96, 102, 6, 224, 110, 6, 224, 102, 14, 113, 195, 248], [96, 38, 3, 96, 118, 7, 96, 118, 6, 96, 110, 6, 224, 102, 14, 127, 193, 248], [96, 6, 7, 96, 102, 6, 224, 110, 6, 224, 108, 6, 192, 238, 14, 127, 195, 248], [0, 110, 6, 224, 110, 6, 96, 118, 7, 96, 118, 7, 112, 119, 7, 63, 224, 248], [192, 236, 14, 224, 110, 6, 224, 110, 6, 224, 102, 7, 96, 118, 6, 127, 225, 248], [64, 110, 6, 224, 110, 6, 224, 110, 6, 96, 118, 7, 96, 119, 7, 127, 225, 248], [96, 110, 6, 96, 102, 7, 96, 118, 7, 96, 118, 7, 96, 119, 7, 127, 225, 252], [224, 126, 7, 224, 126, 7, 224, 126, 7, 224, 126, 7, 224, 118, 7, 127, 225, 248], [96, 62, 7, 224, 126, 7, 224, 126, 7, 224, 126, 7, 96, 118, 7, 127, 225, 252], [224, 46, 7, 224, 126, 7, 224, 126, 7, 224, 126, 7, 224, 110, 6, 127, 227, 248], [96, 62, 7, 224, 126, 7, 224, 126, 7, 224, 126, 7, 224, 126, 6, 127, 227, 252], [96, 102, 7, 96, 118, 7, 224, 110, 6, 224, 110, 6, 224, 110, 14, 127, 193, 248], [96, 54, 7, 96, 118, 7, 96, 118, 7, 224, 110, 6, 224, 110, 14, 127, 193, 248], [96, 38, 7, 96, 126, 6, 224, 110, 6, 224, 108, 14, 192, 238, 14, 127, 195, 248]] }, { symbol: 'V', fingerprints: [[64, 60, 6, 96, 102, 6, 48, 99, 14, 24, 193, 140, 12, 192, 252, 7, 128, 120], [64, 62, 3, 96, 118, 6, 48, 99, 134, 24, 225, 140, 12, 192, 236, 7, 128, 120], [192, 62, 6, 96, 102, 6, 48, 99, 12, 56, 193, 140, 29, 128, 248, 15, 128, 120], [192, 54, 6, 96, 103, 6, 48, 195, 12, 24, 193, 152, 29, 128, 216, 15, 128, 112], [192, 60, 7, 96, 102, 6, 112, 227, 12, 48, 193, 156, 25, 129, 216, 15, 128, 240], [192, 54, 6, 96, 103, 14, 48, 195, 12, 57, 193, 152, 25, 129, 240, 15, 0, 240], [192, 62, 7, 96, 102, 6, 112, 195, 12, 48, 195, 152, 25, 129, 176, 31, 0, 240], [192, 38, 6, 96, 102, 14, 48, 195, 28, 49, 131, 152, 27, 1, 176, 31, 0, 224], [192, 62, 7, 96, 102, 6, 96, 195, 12, 49, 195, 24, 59, 129, 240, 31, 1, 224], [192, 38, 6, 96, 102, 14, 112, 195, 28, 49, 131, 24, 59, 1, 240, 30, 1, 224], [192, 12, 3, 96, 102, 6, 96, 198, 12, 49, 131, 56, 55, 3, 112, 30, 1, 224], [64, 54, 7, 96, 103, 6, 48, 97, 142, 24, 193, 204, 12, 192, 124, 7, 128, 120], [64, 126, 6, 96, 103, 6, 48, 227, 140, 24, 193, 220, 13, 128, 248, 7, 128, 120], [64, 54, 7, 96, 103, 6, 48, 99, 142, 24, 193, 204, 13, 192, 248, 7, 128, 120], [192, 126, 6, 96, 103, 14, 48, 195, 140, 56, 193, 156, 29, 128, 216, 15, 128, 112], [192, 62, 7, 224, 102, 6, 112, 227, 12, 48, 195, 156, 25, 129, 216, 15, 128, 240], [192, 62, 6, 96, 102, 14, 48, 195, 12, 57, 193, 152, 25, 129, 248, 15, 0, 240], [192, 62, 7, 96, 102, 6, 112, 227, 12, 49, 195, 152, 25, 129, 248, 31, 0, 240], [224, 54, 6, 96, 102, 14, 112, 195, 28, 49, 131, 152, 27, 129, 176, 31, 0, 224], [192, 46, 7, 96, 102, 14, 112, 195, 28, 49, 131, 56, 59, 1, 240, 30, 1, 224], [192, 14, 7, 224, 102, 6, 96, 199, 28, 113, 131, 56, 55, 3, 112, 62, 1, 224], [0, 62, 7, 96, 119, 6, 56, 227, 142, 24, 225, 204, 14, 192, 252, 7, 128, 56], [64, 126, 6, 96, 103, 14, 48, 227, 140, 24, 193, 220, 13, 192, 248, 15, 128, 120], [64, 62, 7, 112, 103, 6, 48, 227, 142, 24, 193, 220, 13, 192, 248, 7, 128, 120], [64, 62, 7, 96, 103, 14, 112, 227, 12, 57, 193, 156, 29, 128, 216, 15, 128, 112], [192, 110, 6, 224, 230, 14, 112, 195, 28, 57, 195, 152, 27, 129, 248, 15, 0, 240], [192, 62, 7, 96, 103, 14, 112, 227, 12, 57, 193, 152, 31, 129, 248, 15, 0, 240], [192, 110, 6, 224, 230, 14, 112, 199, 28, 49, 131, 184, 27, 129, 176, 31, 0, 224], [192, 46, 7, 96, 102, 14, 112, 195, 28, 49, 195, 152, 27, 129, 176, 31, 0, 224], [192, 110, 6, 224, 230, 14, 113, 199, 28, 49, 131, 56, 59, 3, 240, 30, 1, 224], [224, 46, 7, 96, 102, 14, 112, 199, 28, 49, 131, 184, 59, 1, 240, 30, 1, 224], [192, 46, 7, 224, 230, 14, 97, 199, 28, 115, 131, 48, 55, 3, 240, 62, 1, 192]] }, { symbol: 'W', fingerprints: [[64, 60, 3, 192, 62, 3, 96, 54, 115, 103, 183, 251, 63, 243, 207, 60, 241, 128], [64, 108, 7, 224, 118, 7, 96, 54, 115, 103, 119, 255, 61, 227, 222, 60, 225, 134], [192, 60, 3, 192, 60, 3, 224, 54, 115, 111, 54, 251, 125, 243, 206, 56, 227, 134], [192, 44, 7, 224, 118, 7, 96, 118, 118, 103, 102, 246, 125, 227, 222, 57, 227, 140], [192, 60, 3, 192, 60, 3, 192, 62, 243, 111, 118, 246, 125, 231, 158, 121, 227, 14], [192, 60, 7, 224, 126, 6, 230, 102, 102, 111, 102, 246, 127, 231, 158, 57, 195, 156], [192, 60, 3, 192, 60, 3, 192, 124, 230, 239, 103, 246, 123, 231, 158, 113, 199, 12], [192, 44, 7, 192, 108, 6, 192, 110, 230, 238, 102, 246, 123, 199, 188, 113, 199, 28], [96, 54, 3, 96, 54, 7, 224, 102, 102, 110, 102, 246, 123, 231, 188, 121, 199, 28], [192, 44, 7, 192, 108, 6, 192, 108, 230, 206, 109, 236, 251, 199, 60, 115, 198, 24], [96, 6, 3, 224, 126, 7, 192, 108, 230, 238, 111, 254, 123, 199, 188, 115, 198, 24], [192, 108, 6, 192, 110, 7, 224, 118, 119, 111, 119, 255, 61, 227, 222, 60, 225, 132], [64, 126, 7, 224, 126, 7, 96, 118, 119, 103, 119, 255, 61, 243, 222, 60, 225, 134], [64, 62, 3, 96, 54, 3, 96, 54, 115, 119, 55, 255, 61, 243, 223, 60, 225, 142], [192, 126, 7, 224, 126, 7, 96, 118, 119, 111, 102, 246, 125, 227, 222, 57, 227, 142], [96, 62, 3, 96, 54, 3, 96, 118, 119, 103, 119, 255, 125, 227, 222, 57, 227, 142], [192, 46, 7, 224, 126, 7, 224, 110, 102, 111, 102, 246, 127, 231, 158, 121, 227, 156], [96, 62, 3, 96, 118, 7, 102, 118, 119, 111, 102, 246, 127, 231, 158, 121, 227, 28], [224, 62, 7, 224, 126, 6, 224, 110, 230, 238, 103, 254, 123, 231, 188, 123, 199, 28], [96, 62, 3, 224, 126, 7, 224, 126, 230, 111, 103, 246, 123, 231, 188, 113, 195, 28], [192, 46, 7, 224, 124, 6, 192, 108, 230, 238, 239, 254, 251, 207, 188, 115, 198, 56], [96, 14, 3, 224, 126, 7, 224, 110, 230, 238, 111, 254, 251, 199, 188, 115, 198, 56], [0, 108, 7, 224, 126, 7, 224, 118, 119, 111, 119, 255, 127, 243, 222, 60, 225, 134], [192, 108, 7, 224, 126, 7, 224, 126, 103, 111, 102, 246, 127, 231, 222, 57, 227, 142], [64, 110, 7, 224, 126, 7, 224, 118, 119, 111, 119, 254, 127, 231, 222, 61, 227, 142], [192, 108, 7, 224, 110, 6, 224, 110, 230, 239, 103, 246, 127, 231, 190, 121, 195, 12], [192, 126, 7, 224, 126, 7, 224, 126, 230, 111, 102, 246, 127, 231, 190, 121, 227, 28], [192, 108, 7, 192, 108, 6, 192, 110, 230, 238, 239, 254, 123, 231, 188, 123, 199, 28], [192, 46, 7, 224, 126, 7, 224, 110, 230, 239, 111, 254, 123, 231, 190, 123, 199, 28], [192, 108, 7, 192, 108, 6, 192, 108, 238, 222, 239, 252, 255, 207, 188, 243, 198, 56], [224, 46, 7, 224, 126, 6, 224, 110, 230, 254, 239, 254, 255, 207, 188, 115, 198, 56], [192, 44, 7, 192, 108, 6, 192, 236, 238, 222, 237, 236, 255, 207, 124, 247, 142, 56]] }, { symbol: 'X', fingerprints: [[64, 206, 28, 113, 131, 184, 31, 0, 224, 15, 1, 248, 25, 195, 142, 48, 102, 0], [64, 198, 12, 49, 131, 152, 31, 0, 224, 15, 1, 248, 25, 195, 140, 48, 102, 2], [192, 102, 12, 113, 195, 152, 31, 0, 224, 15, 1, 184, 57, 195, 14, 112, 102, 2], [64, 102, 12, 112, 195, 152, 31, 0, 240, 15, 1, 248, 25, 195, 14, 112, 102, 2], [192, 102, 14, 113, 195, 152, 31, 128, 224, 15, 1, 248, 57, 199, 14, 96, 108, 3], [224, 102, 14, 57, 195, 152, 31, 128, 240, 15, 1, 248, 57, 199, 14, 96, 108, 7], [96, 55, 6, 56, 225, 156, 31, 128, 112, 15, 1, 248, 57, 199, 14, 96, 100, 3], [96, 39, 6, 48, 225, 156, 15, 128, 240, 15, 1, 248, 57, 135, 12, 96, 236, 6], [96, 51, 6, 56, 225, 156, 15, 128, 240, 15, 1, 152, 49, 199, 12, 96, 100, 6], [48, 35, 6, 24, 193, 156, 15, 128, 240, 15, 1, 240, 57, 135, 28, 96, 196, 6], [48, 3, 7, 24, 225, 204, 15, 128, 112, 15, 1, 240, 57, 131, 28, 96, 196, 6], [192, 206, 28, 113, 131, 184, 31, 0, 224, 15, 1, 248, 25, 195, 142, 48, 118, 2], [64, 206, 12, 113, 131, 184, 31, 0, 240, 15, 1, 248, 25, 195, 142, 48, 102, 2], [64, 110, 12, 113, 195, 24, 31, 128, 240, 15, 1, 248, 57, 195, 12, 112, 102, 2], [192, 102, 14, 113, 195, 152, 31, 128, 240, 15, 1, 248, 57, 195, 14, 112, 102, 3], [192, 110, 14, 113, 195, 188, 31, 128, 224, 15, 1, 248, 57, 199, 14, 96, 108, 7], [64, 38, 6, 57, 195, 156, 31, 128, 240, 31, 1, 248, 57, 199, 14, 96, 108, 3], [96, 103, 6, 48, 225, 156, 31, 128, 240, 15, 1, 248, 57, 199, 12, 96, 236, 6], [96, 51, 7, 56, 225, 156, 15, 128, 240, 15, 1, 152, 57, 199, 12, 224, 228, 6], [112, 35, 6, 24, 193, 220, 15, 128, 240, 15, 1, 248, 57, 135, 28, 224, 196, 6], [48, 3, 135, 24, 225, 220, 15, 128, 112, 15, 1, 248, 57, 135, 28, 224, 192, 6], [0, 206, 28, 113, 131, 184, 31, 0, 224, 15, 1, 248, 25, 195, 142, 112, 118, 2], [64, 238, 28, 113, 195, 184, 31, 0, 240, 15, 1, 248, 25, 195, 142, 112, 118, 2], [64, 102, 14, 49, 195, 152, 31, 128, 240, 15, 1, 248, 25, 195, 142, 48, 102, 3], [64, 110, 14, 113, 195, 152, 31, 128, 240, 15, 1, 248, 57, 195, 14, 112, 118, 2], [96, 103, 14, 57, 195, 156, 31, 128, 240, 15, 129, 216, 57, 195, 14, 112, 118, 2], [224, 118, 6, 121, 227, 156, 31, 128, 240, 31, 129, 248, 57, 199, 158, 224, 124, 3], [96, 55, 7, 56, 227, 156, 31, 128, 248, 15, 129, 248, 57, 199, 158, 224, 108, 7], [96, 39, 7, 56, 225, 156, 31, 128, 240, 15, 1, 248, 57, 199, 12, 224, 228, 6], [112, 35, 7, 56, 225, 220, 15, 128, 240, 15, 1, 248, 57, 135, 28, 224, 196, 14]] }, { symbol: 'Y', fingerprints: [[64, 62, 14, 112, 227, 156, 29, 192, 240, 7, 0, 112, 7, 0, 48, 3, 0, 48], [64, 54, 7, 112, 227, 140, 31, 192, 248, 7, 0, 112, 3, 0, 48, 3, 0, 48], [192, 55, 14, 112, 227, 156, 31, 128, 240, 7, 0, 112, 7, 0, 112, 7, 0, 48], [64, 55, 6, 112, 227, 156, 15, 192, 240, 7, 0, 112, 7, 0, 112, 7, 0, 112], [192, 54, 14, 112, 227, 156, 31, 128, 240, 7, 0, 96, 6, 0, 96, 6, 0, 96], [224, 118, 6, 48, 195, 156, 31, 128, 240, 6, 0, 96, 6, 0, 96, 6, 0, 96], [192, 55, 14, 112, 227, 156, 31, 128, 240, 14, 0, 224, 14, 0, 224, 14, 0, 96], [224, 38, 6, 112, 227, 156, 31, 128, 224, 6, 0, 96, 6, 0, 224, 14, 0, 64], [192, 54, 7, 112, 227, 156, 59, 128, 240, 14, 0, 224, 14, 0, 224, 14, 0, 224], [64, 38, 6, 112, 227, 156, 27, 129, 224, 14, 0, 192, 12, 0, 192, 12, 1, 192], [192, 6, 7, 112, 227, 28, 59, 129, 240, 14, 0, 224, 12, 0, 192, 12, 0, 128], [64, 118, 6, 120, 227, 220, 31, 192, 120, 7, 128, 56, 3, 128, 56, 3, 128, 56], [64, 110, 6, 112, 227, 156, 31, 128, 248, 7, 0, 112, 7, 0, 48, 3, 0, 56], [64, 62, 14, 112, 227, 156, 29, 192, 240, 7, 0, 112, 7, 0, 112, 7, 0, 112], [192, 118, 6, 112, 227, 156, 31, 128, 240, 6, 0, 96, 6, 0, 112, 7, 0, 96], [192, 63, 14, 112, 227, 156, 31, 128, 240, 15, 0, 112, 7, 0, 112, 7, 0, 112], [192, 38, 6, 112, 227, 156, 31, 128, 240, 6, 0, 96, 6, 0, 96, 6, 0, 96], [224, 54, 6, 112, 227, 156, 31, 129, 240, 14, 0, 96, 14, 0, 224, 14, 0, 224], [224, 38, 6, 113, 227, 156, 31, 129, 240, 14, 0, 224, 12, 0, 192, 28, 0, 192], [192, 14, 7, 112, 227, 156, 59, 129, 240, 14, 0, 224, 12, 0, 192, 28, 1, 192], [0, 62, 7, 120, 227, 158, 29, 192, 248, 7, 128, 56, 3, 128, 56, 3, 128, 56], [64, 126, 6, 121, 227, 156, 31, 128, 248, 7, 0, 112, 7, 0, 112, 3, 128, 48], [64, 54, 7, 120, 227, 156, 31, 192, 248, 7, 0, 112, 7, 0, 56, 3, 128, 56], [64, 110, 6, 113, 227, 156, 31, 129, 248, 7, 0, 112, 7, 0, 112, 7, 0, 112], [96, 55, 7, 120, 227, 220, 31, 192, 248, 7, 0, 112, 7, 0, 112, 7, 0, 112], [192, 118, 6, 121, 227, 156, 31, 129, 240, 6, 0, 96, 6, 0, 96, 6, 0, 96], [96, 55, 7, 56, 227, 156, 31, 192, 248, 6, 0, 96, 6, 0, 96, 6, 0, 96], [192, 46, 7, 113, 227, 156, 63, 129, 240, 14, 0, 224, 14, 0, 224, 14, 0, 224], [192, 63, 15, 112, 227, 156, 63, 129, 240, 14, 0, 224, 14, 0, 224, 14, 0, 224], [224, 38, 7, 121, 227, 156, 63, 129, 240, 14, 0, 224, 30, 1, 192, 28, 1, 192], [192, 47, 7, 112, 231, 156, 63, 129, 240, 14, 0, 224, 14, 1, 192, 28, 1, 192]] }, { symbol: 'Z', fingerprints: [[255, 199, 24, 1, 128, 112, 7, 0, 224, 14, 1, 192, 24, 3, 128, 63, 247, 254], [255, 207, 156, 3, 128, 56, 6, 0, 96, 12, 1, 192, 56, 3, 128, 127, 247, 255], [127, 199, 252, 1, 192, 56, 7, 0, 96, 14, 1, 192, 24, 3, 128, 127, 247, 255], [255, 224, 28, 1, 192, 48, 7, 0, 224, 12, 3, 128, 56, 7, 0, 127, 247, 255], [255, 224, 28, 1, 192, 56, 7, 0, 96, 14, 1, 128, 56, 7, 0, 127, 247, 255], [255, 224, 14, 1, 192, 56, 7, 0, 240, 28, 1, 192, 56, 7, 0, 255, 255, 255], [255, 231, 254, 0, 224, 56, 7, 0, 240, 14, 1, 192, 56, 7, 0, 255, 255, 255], [127, 231, 254, 0, 224, 28, 3, 128, 240, 14, 1, 192, 56, 7, 0, 255, 239, 255], [127, 240, 15, 0, 224, 28, 3, 128, 112, 14, 1, 192, 56, 7, 0, 255, 255, 255], [127, 240, 30, 0, 224, 28, 7, 0, 112, 14, 3, 128, 56, 7, 0, 255, 239, 254], [127, 224, 127, 0, 224, 28, 3, 128, 112, 14, 1, 192, 56, 7, 0, 255, 195, 254], [127, 207, 252, 1, 128, 56, 7, 0, 224, 14, 1, 192, 24, 3, 128, 63, 247, 254], [255, 207, 252, 1, 192, 56, 7, 0, 96, 14, 1, 192, 56, 3, 128, 127, 247, 254], [255, 224, 30, 1, 192, 56, 7, 0, 240, 14, 3, 192, 56, 7, 0, 255, 255, 255], [127, 231, 252, 1, 192, 56, 7, 0, 96, 28, 1, 192, 56, 7, 0, 127, 239, 254], [127, 231, 254, 1, 192, 56, 7, 128, 96, 14, 1, 192, 56, 7, 128, 127, 239, 255], [127, 227, 254, 1, 192, 60, 3, 128, 96, 14, 1, 192, 56, 7, 0, 127, 231, 254], [127, 227, 254, 0, 224, 28, 3, 128, 112, 14, 1, 192, 56, 7, 0, 127, 199, 255], [63, 240, 126, 0, 224, 28, 3, 128, 112, 14, 1, 192, 56, 7, 128, 127, 231, 255], [63, 240, 255, 0, 224, 28, 3, 128, 112, 14, 1, 192, 56, 7, 0, 127, 231, 254], [127, 207, 252, 3, 128, 120, 7, 0, 224, 14, 1, 192, 56, 3, 128, 127, 247, 248], [255, 207, 252, 3, 128, 120, 7, 0, 224, 30, 1, 192, 56, 7, 0, 127, 231, 254], [127, 199, 252, 1, 192, 56, 7, 0, 224, 14, 1, 192, 56, 3, 0, 127, 231, 254], [255, 207, 252, 1, 192, 56, 7, 0, 224, 30, 1, 192, 56, 7, 0, 127, 239, 254], [255, 231, 252, 1, 192, 56, 7, 0, 96, 30, 3, 192, 56, 7, 128, 255, 239, 255], [127, 231, 254, 1, 192, 56, 7, 128, 224, 30, 1, 192, 56, 7, 0, 255, 231, 254], [127, 231, 254, 1, 224, 60, 3, 128, 112, 14, 1, 192, 56, 7, 0, 127, 231, 255], [63, 227, 255, 0, 224, 28, 3, 128, 120, 14, 1, 192, 56, 7, 128, 255, 231, 255], [63, 225, 254, 0, 224, 28, 7, 128, 240, 14, 1, 192, 56, 7, 0, 255, 231, 254]] }, { symbol: '<', fingerprints: [[0, 96, 30, 7, 128, 240, 28, 7, 128, 224, 7, 192, 30, 0, 120, 1, 240, 7], [0, 224, 30, 3, 128, 224, 28, 7, 128, 240, 7, 128, 30, 0, 60, 1, 224, 7], [0, 96, 14, 3, 128, 240, 28, 7, 0, 240, 3, 192, 15, 0, 124, 0, 240, 3], [0, 112, 30, 7, 193, 240, 60, 7, 0, 240, 3, 192, 31, 0, 60, 0, 240, 7], [0, 96, 30, 3, 192, 224, 60, 7, 128, 240, 3, 192, 30, 0, 60, 1, 224, 7], [0, 96, 14, 7, 128, 240, 28, 7, 0, 240, 1, 192, 15, 0, 56, 0, 224, 7], [0, 112, 30, 7, 193, 240, 56, 15, 0, 112, 3, 192, 31, 0, 60, 0, 224, 7], [0, 112, 30, 7, 129, 224, 60, 14, 0, 112, 1, 192, 15, 0, 56, 0, 224, 6], [0, 112, 30, 7, 193, 224, 120, 15, 0, 120, 1, 192, 15, 0, 60, 1, 224, 6], [0, 112, 30, 7, 193, 224, 120, 15, 0, 112, 3, 192, 14, 0, 120, 1, 192, 14], [0, 112, 30, 7, 131, 224, 120, 14, 0, 56, 1, 192, 15, 0, 56, 1, 224, 14], [0, 224, 30, 3, 128, 224, 60, 7, 128, 240, 7, 192, 30, 0, 124, 1, 240, 7], [0, 224, 30, 7, 128, 224, 60, 15, 0, 224, 7, 192, 31, 0, 120, 1, 224, 6], [0, 96, 30, 7, 128, 240, 60, 15, 0, 224, 7, 192, 31, 0, 120, 1, 224, 7], [0, 96, 30, 7, 128, 240, 60, 15, 0, 240, 3, 224, 15, 0, 124, 0, 240, 6], [0, 112, 15, 7, 128, 240, 60, 15, 0, 240, 3, 224, 15, 0, 120, 0, 224, 7], [0, 112, 30, 3, 193, 240, 60, 7, 128, 120, 3, 192, 15, 0, 60, 1, 224, 7], [0, 112, 30, 7, 129, 240, 60, 15, 0, 112, 1, 224, 15, 0, 120, 1, 224, 6], [0, 48, 15, 7, 192, 240, 60, 15, 0, 112, 1, 224, 15, 0, 120, 1, 224, 6], [0, 112, 30, 15, 129, 224, 124, 14, 0, 120, 1, 224, 15, 0, 120, 1, 224, 6], [0, 112, 15, 7, 193, 240, 124, 14, 0, 120, 1, 192, 15, 0, 120, 1, 224, 14], [0, 224, 30, 7, 128, 240, 30, 7, 128, 240, 7, 192, 31, 0, 252, 1, 240, 7], [0, 224, 30, 7, 128, 240, 60, 7, 128, 224, 15, 128, 62, 0, 248, 3, 224, 15], [0, 224, 30, 7, 129, 240, 60, 15, 0, 240, 7, 192, 31, 0, 120, 1, 240, 7], [0, 96, 30, 7, 128, 240, 62, 15, 128, 240, 7, 192, 31, 0, 120, 1, 224, 7], [0, 240, 30, 7, 129, 240, 60, 15, 0, 240, 3, 224, 15, 0, 124, 0, 240, 7], [0, 112, 31, 7, 192, 240, 62, 15, 0, 240, 3, 224, 15, 0, 124, 1, 240, 7], [0, 96, 31, 7, 192, 240, 124, 15, 0, 248, 3, 192, 15, 0, 124, 1, 224, 6], [0, 112, 31, 7, 129, 240, 60, 15, 0, 248, 3, 224, 15, 0, 120, 1, 224, 6], [0, 96, 30, 7, 129, 240, 124, 15, 0, 240, 3, 192, 30, 0, 120, 1, 224, 14], [0, 112, 31, 15, 131, 224, 124, 14, 0, 120, 1, 224, 15, 0, 120, 1, 224, 14], [0, 112, 31, 7, 193, 240, 124, 15, 0, 120, 1, 224, 15, 0, 120, 1, 224, 14]] }] };
12 |
13 |
14 | var dir = 'demo/';
15 | var files = FS.readdirSync(dir);
16 |
17 | (async function () {
18 | for (let file of files) {
19 | if (file.match(/(passport)/)) {
20 | let image = await IJS.load(dir + file);
21 | image = image.level();
22 |
23 | var smallImage = image;
24 | if (image.width > 1000 || image.height > 1000) {
25 | if (image.width > image.height) {
26 | smallImage = image.scale({ width: 1000 });
27 | } else {
28 | smallImage = image.scale({ height: 1000 });
29 | }
30 | }
31 |
32 |
33 | let options = {
34 | roiOptions: {
35 | minWidth: Math.min(smallImage.width, smallImage.height) / 100,
36 | minHeight: Math.min(smallImage.width, smallImage.height) / 100,
37 | positive: true,
38 | negative: false,
39 | greyThreshold: 0.5
40 | },
41 | fingerprintOptions: {
42 | height: 12,
43 | width: 12,
44 | minSimilarity: 0.7
45 | }
46 | };
47 |
48 | var result = getRotation(smallImage, fontFingerprint, options);
49 | console.log(file, ' - Rotation: ', result.rotation, ' Reliability: ', result.reliability);
50 |
51 | // we rotate
52 |
53 | image = image.rotate(result.rotation);
54 |
55 |
56 | options = {
57 | roiOptions: {
58 | minWidth: Math.min(image.width, image.height) / 100,
59 | minHeight: Math.min(image.width, image.height) / 100,
60 | positive: true,
61 | negative: false,
62 | greyThreshold: 0.5
63 | },
64 | fingerprintOptions: {
65 | height: 12,
66 | width: 12,
67 | minSimilarity: 0.5
68 | }
69 | };
70 |
71 |
72 | result = runOCR(image, fontFingerprint, options).lines;
73 | if (result.length > 2) {
74 | result = result.slice(result.length - 3, result.length);
75 | }
76 | var mzr = result.map((a) => a.text);
77 |
78 | console.log(mzr.join('\r\n'));
79 | }
80 | }
81 | })();
82 |
83 |
--------------------------------------------------------------------------------