Browse Source

Refactor core apis

develop
Jerome Wu 6 years ago
parent
commit
142f4dd92d
  1. 27
      examples/node/recognize.js
  2. 856
      package-lock.json
  3. 27
      src/common/createJob.js
  4. 57
      src/common/createScheduler.js
  5. 7
      src/common/createTesseract.js
  6. 129
      src/common/createWorker.js
  7. 1
      src/common/env.js
  8. 1
      src/common/options.js
  9. 87
      src/common/utils.js
  10. 299
      src/common/workerUtils.js
  11. 6
      src/index.js
  12. 30
      src/node/index.js

27
examples/node/recognize.js

@ -1,23 +1,22 @@ @@ -1,23 +1,22 @@
#!/usr/bin/env node
const path = require('path');
const { TesseractWorker } = require('../../');
const { createScheduler, createWorker, createJob, OEM } = require('../../');
const [,, imagePath] = process.argv;
const image = path.resolve(__dirname, (imagePath || '../../tests/assets/images/cosmic.png'));
const tessWorker = new TesseractWorker();
console.log(`Recognizing ${image}`);
tessWorker.recognize(image)
.progress((info) => {
console.log(info);
})
.then((data) => {
console.log(data.text);
})
.catch((err) => {
console.log('Error\n', err);
})
.finally(() => {
process.exit();
(async () => {
const scheduler = createScheduler();
const worker = createWorker();
await worker.load();
await worker.loadLanguage('osd');
await worker.initialize('osd', {
tessedit_ocr_engine_mode: OEM.OSD_ONLY,
});
scheduler.addWorker(worker);
const data = await scheduler.addJob(createJob('detect', { image }));
console.log(data);
scheduler.terminate();
})();

856
package-lock.json generated

@ -214,22 +214,22 @@ @@ -214,22 +214,22 @@
}
},
"@babel/parser": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.4.tgz",
"integrity": "sha512-5pCS4mOsL+ANsFZGdvNLybx4wtqAZJ0MJjMHxvzI3bvIsz6sQvzW8XX92EYIkiPtIvcfG3Aj+Ir5VNyjnZhP7w==",
"version": "7.4.5",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.5.tgz",
"integrity": "sha512-9mUqkL1FF5T7f0WDFfAoDdiMVPWsdD1gZYzSnaXsxUCUqzuch/8of9G3VUSNiZmMBoRxT3neyVsqeiL/ZPcjew==",
"dev": true
},
"@babel/traverse": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.4.tgz",
"integrity": "sha512-Gw6qqkw/e6AGzlyj9KnkabJX7VcubqPtkUQVAwkc0wUMldr3A/hezNB3Rc5eIvId95iSGkGIOe5hh1kMKf951A==",
"version": "7.4.5",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.5.tgz",
"integrity": "sha512-Vc+qjynwkjRmIFGxy0KYoPj4FdVDxLej89kMHFsWScq999uX+pwcX4v9mWRjW0KcAYTPAuVQl2LKP1wEVLsp+A==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
"@babel/generator": "^7.4.4",
"@babel/helper-function-name": "^7.1.0",
"@babel/helper-split-export-declaration": "^7.4.4",
"@babel/parser": "^7.4.4",
"@babel/parser": "^7.4.5",
"@babel/types": "^7.4.4",
"debug": "^4.1.0",
"globals": "^11.1.0",
@ -376,848 +376,6 @@ @@ -376,848 +376,6 @@
"@babel/types": "^7.0.0"
}
},
"@babel/helper-module-transforms": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.4.4.tgz",
"integrity": "sha512-3Z1yp8TVQf+B4ynN7WoHPKS8EkdTbgAEy0nU0rs/1Kw4pDgmvYH3rz3aI11KgxKCba2cn7N+tqzV1mY2HMN96w==",
"dev": true,
"requires": {
"@babel/helper-module-imports": "^7.0.0",
"@babel/helper-simple-access": "^7.1.0",
"@babel/helper-split-export-declaration": "^7.4.4",
"@babel/template": "^7.4.4",
"@babel/types": "^7.4.4",
"lodash": "^4.17.11"
},
"dependencies": {
"@babel/helper-split-export-declaration": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz",
"integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==",
"dev": true,
"requires": {
"@babel/types": "^7.4.4"
}
},
"@babel/parser": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.4.tgz",
"integrity": "sha512-5pCS4mOsL+ANsFZGdvNLybx4wtqAZJ0MJjMHxvzI3bvIsz6sQvzW8XX92EYIkiPtIvcfG3Aj+Ir5VNyjnZhP7w==",
"dev": true
},
"@babel/template": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz",
"integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
"@babel/parser": "^7.4.4",
"@babel/types": "^7.4.4"
}
},
"@babel/types": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz",
"integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==",
"dev": true,
"requires": {
"esutils": "^2.0.2",
"lodash": "^4.17.11",
"to-fast-properties": "^2.0.0"
}
},
"lodash": {
"version": "4.17.11",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
"dev": true
}
}
},
"@babel/helper-optimise-call-expression": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz",
"integrity": "sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g==",
"dev": true,
"requires": {
"@babel/types": "^7.0.0"
}
},
"@babel/helper-plugin-utils": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz",
"integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==",
"dev": true
},
"@babel/helper-regex": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.4.4.tgz",
"integrity": "sha512-Y5nuB/kESmR3tKjU8Nkn1wMGEx1tjJX076HBMeL3XLQCu6vA/YRzuTW0bbb+qRnXvQGn+d6Rx953yffl8vEy7Q==",
"dev": true,
"requires": {
"lodash": "^4.17.11"
},
"dependencies": {
"lodash": {
"version": "4.17.11",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
"dev": true
}
}
},
"@babel/helper-remap-async-to-generator": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz",
"integrity": "sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg==",
"dev": true,
"requires": {
"@babel/helper-annotate-as-pure": "^7.0.0",
"@babel/helper-wrap-function": "^7.1.0",
"@babel/template": "^7.1.0",
"@babel/traverse": "^7.1.0",
"@babel/types": "^7.0.0"
}
},
"@babel/helper-replace-supers": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.4.4.tgz",
"integrity": "sha512-04xGEnd+s01nY1l15EuMS1rfKktNF+1CkKmHoErDppjAAZL+IUBZpzT748x262HF7fibaQPhbvWUl5HeSt1EXg==",
"dev": true,
"requires": {
"@babel/helper-member-expression-to-functions": "^7.0.0",
"@babel/helper-optimise-call-expression": "^7.0.0",
"@babel/traverse": "^7.4.4",
"@babel/types": "^7.4.4"
},
"dependencies": {
"@babel/generator": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.4.tgz",
"integrity": "sha512-53UOLK6TVNqKxf7RUh8NE851EHRxOOeVXKbK2bivdb+iziMyk03Sr4eaE9OELCbyZAAafAKPDwF2TPUES5QbxQ==",
"dev": true,
"requires": {
"@babel/types": "^7.4.4",
"jsesc": "^2.5.1",
"lodash": "^4.17.11",
"source-map": "^0.5.0",
"trim-right": "^1.0.1"
}
},
"@babel/helper-split-export-declaration": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz",
"integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==",
"dev": true,
"requires": {
"@babel/types": "^7.4.4"
}
},
"@babel/parser": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.4.tgz",
"integrity": "sha512-5pCS4mOsL+ANsFZGdvNLybx4wtqAZJ0MJjMHxvzI3bvIsz6sQvzW8XX92EYIkiPtIvcfG3Aj+Ir5VNyjnZhP7w==",
"dev": true
},
"@babel/traverse": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.4.tgz",
"integrity": "sha512-Gw6qqkw/e6AGzlyj9KnkabJX7VcubqPtkUQVAwkc0wUMldr3A/hezNB3Rc5eIvId95iSGkGIOe5hh1kMKf951A==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
"@babel/generator": "^7.4.4",
"@babel/helper-function-name": "^7.1.0",
"@babel/helper-split-export-declaration": "^7.4.4",
"@babel/parser": "^7.4.4",
"@babel/types": "^7.4.4",
"debug": "^4.1.0",
"globals": "^11.1.0",
"lodash": "^4.17.11"
}
},
"@babel/types": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz",
"integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==",
"dev": true,
"requires": {
"esutils": "^2.0.2",
"lodash": "^4.17.11",
"to-fast-properties": "^2.0.0"
}
},
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"dev": true,
"requires": {
"ms": "^2.1.1"
}
},
"lodash": {
"version": "4.17.11",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
"dev": true
},
"ms": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
"dev": true
}
}
},
"@babel/helper-simple-access": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz",
"integrity": "sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w==",
"dev": true,
"requires": {
"@babel/template": "^7.1.0",
"@babel/types": "^7.0.0"
}
},
"@babel/helper-split-export-declaration": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz",
"integrity": "sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==",
"dev": true,
"requires": {
"@babel/types": "^7.0.0"
}
},
"@babel/helper-wrap-function": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz",
"integrity": "sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ==",
"dev": true,
"requires": {
"@babel/helper-function-name": "^7.1.0",
"@babel/template": "^7.1.0",
"@babel/traverse": "^7.1.0",
"@babel/types": "^7.2.0"
},
"dependencies": {
"@babel/types": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz",
"integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==",
"dev": true,
"requires": {
"esutils": "^2.0.2",
"lodash": "^4.17.11",
"to-fast-properties": "^2.0.0"
}
},
"lodash": {
"version": "4.17.11",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
"dev": true
}
}
},
"@babel/helpers": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.4.4.tgz",
"integrity": "sha512-igczbR/0SeuPR8RFfC7tGrbdTbFL3QTvH6D+Z6zNxnTe//GyqmtHmDkzrqDmyZ3eSwPqB/LhyKoU5DXsp+Vp2A==",
"dev": true,
"requires": {
"@babel/template": "^7.4.4",
"@babel/traverse": "^7.4.4",
"@babel/types": "^7.4.4"
},
"dependencies": {
"@babel/generator": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.4.tgz",
"integrity": "sha512-53UOLK6TVNqKxf7RUh8NE851EHRxOOeVXKbK2bivdb+iziMyk03Sr4eaE9OELCbyZAAafAKPDwF2TPUES5QbxQ==",
"dev": true,
"requires": {
"@babel/types": "^7.4.4",
"jsesc": "^2.5.1",
"lodash": "^4.17.11",
"source-map": "^0.5.0",
"trim-right": "^1.0.1"
}
},
"@babel/helper-split-export-declaration": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz",
"integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==",
"dev": true,
"requires": {
"@babel/types": "^7.4.4"
}
},
"@babel/parser": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.4.tgz",
"integrity": "sha512-5pCS4mOsL+ANsFZGdvNLybx4wtqAZJ0MJjMHxvzI3bvIsz6sQvzW8XX92EYIkiPtIvcfG3Aj+Ir5VNyjnZhP7w==",
"dev": true
},
"@babel/template": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz",
"integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
"@babel/parser": "^7.4.4",
"@babel/types": "^7.4.4"
}
},
"@babel/traverse": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.4.tgz",
"integrity": "sha512-Gw6qqkw/e6AGzlyj9KnkabJX7VcubqPtkUQVAwkc0wUMldr3A/hezNB3Rc5eIvId95iSGkGIOe5hh1kMKf951A==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
"@babel/generator": "^7.4.4",
"@babel/helper-function-name": "^7.1.0",
"@babel/helper-split-export-declaration": "^7.4.4",
"@babel/parser": "^7.4.4",
"@babel/types": "^7.4.4",
"debug": "^4.1.0",
"globals": "^11.1.0",
"lodash": "^4.17.11"
}
},
"@babel/types": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz",
"integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==",
"dev": true,
"requires": {
"esutils": "^2.0.2",
"lodash": "^4.17.11",
"to-fast-properties": "^2.0.0"
}
},
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"dev": true,
"requires": {
"ms": "^2.1.1"
}
},
"lodash": {
"version": "4.17.11",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
"dev": true
},
"ms": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
"dev": true
}
}
},
"@babel/highlight": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz",
"integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==",
"dev": true,
"requires": {
"chalk": "^2.0.0",
"esutils": "^2.0.2",
"js-tokens": "^4.0.0"
},
"dependencies": {
"ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dev": true,
"requires": {
"color-convert": "^1.9.0"
}
},
"chalk": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
"integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
"dev": true,
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
}
},
"js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
"dev": true
},
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
"requires": {
"has-flag": "^3.0.0"
}
}
}
},
"@babel/parser": {
"version": "7.1.6",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.1.6.tgz",
"integrity": "sha512-dWP6LJm9nKT6ALaa+bnL247GHHMWir3vSlZ2+IHgHgktZQx0L3Uvq2uAWcuzIe+fujRsYWBW2q622C5UvGK9iQ==",
"dev": true
},
"@babel/plugin-proposal-async-generator-functions": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz",
"integrity": "sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.0.0",
"@babel/helper-remap-async-to-generator": "^7.1.0",
"@babel/plugin-syntax-async-generators": "^7.2.0"
}
},
"@babel/plugin-proposal-json-strings": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz",
"integrity": "sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.0.0",
"@babel/plugin-syntax-json-strings": "^7.2.0"
}
},
"@babel/plugin-proposal-object-rest-spread": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.4.4.tgz",
"integrity": "sha512-dMBG6cSPBbHeEBdFXeQ2QLc5gUpg4Vkaz8octD4aoW/ISO+jBOcsuxYL7bsb5WSu8RLP6boxrBIALEHgoHtO9g==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.0.0",
"@babel/plugin-syntax-object-rest-spread": "^7.2.0"
}
},
"@babel/plugin-proposal-optional-catch-binding": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz",
"integrity": "sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.0.0",
"@babel/plugin-syntax-optional-catch-binding": "^7.2.0"
}
},
"@babel/plugin-proposal-unicode-property-regex": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.4.4.tgz",
"integrity": "sha512-j1NwnOqMG9mFUOH58JTFsA/+ZYzQLUZ/drqWUqxCYLGeu2JFZL8YrNC9hBxKmWtAuOCHPcRpgv7fhap09Fb4kA==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.0.0",
"@babel/helper-regex": "^7.4.4",
"regexpu-core": "^4.5.4"
}
},
"@babel/plugin-syntax-async-generators": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz",
"integrity": "sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-syntax-json-strings": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz",
"integrity": "sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-syntax-object-rest-spread": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz",
"integrity": "sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-syntax-optional-catch-binding": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz",
"integrity": "sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-transform-arrow-functions": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz",
"integrity": "sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-transform-async-to-generator": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.4.4.tgz",
"integrity": "sha512-YiqW2Li8TXmzgbXw+STsSqPBPFnGviiaSp6CYOq55X8GQ2SGVLrXB6pNid8HkqkZAzOH6knbai3snhP7v0fNwA==",
"dev": true,
"requires": {
"@babel/helper-module-imports": "^7.0.0",
"@babel/helper-plugin-utils": "^7.0.0",
"@babel/helper-remap-async-to-generator": "^7.1.0"
}
},
"@babel/plugin-transform-block-scoped-functions": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz",
"integrity": "sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-transform-block-scoping": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.4.4.tgz",
"integrity": "sha512-jkTUyWZcTrwxu5DD4rWz6rDB5Cjdmgz6z7M7RLXOJyCUkFBawssDGcGh8M/0FTSB87avyJI1HsTwUXp9nKA1PA==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.0.0",
"lodash": "^4.17.11"
},
"dependencies": {
"lodash": {
"version": "4.17.11",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
"dev": true
}
}
},
"@babel/plugin-transform-classes": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.4.4.tgz",
"integrity": "sha512-/e44eFLImEGIpL9qPxSRat13I5QNRgBLu2hOQJCF7VLy/otSM/sypV1+XaIw5+502RX/+6YaSAPmldk+nhHDPw==",
"dev": true,
"requires": {
"@babel/helper-annotate-as-pure": "^7.0.0",
"@babel/helper-define-map": "^7.4.4",
"@babel/helper-function-name": "^7.1.0",
"@babel/helper-optimise-call-expression": "^7.0.0",
"@babel/helper-plugin-utils": "^7.0.0",
"@babel/helper-replace-supers": "^7.4.4",
"@babel/helper-split-export-declaration": "^7.4.4",
"globals": "^11.1.0"
},
"dependencies": {
"@babel/helper-split-export-declaration": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz",
"integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==",
"dev": true,
"requires": {
"@babel/types": "^7.4.4"
}
},
"@babel/types": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz",
"integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==",
"dev": true,
"requires": {
"esutils": "^2.0.2",
"lodash": "^4.17.11",
"to-fast-properties": "^2.0.0"
}
},
"lodash": {
"version": "4.17.11",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
"dev": true
}
}
},
"@babel/plugin-transform-computed-properties": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz",
"integrity": "sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-transform-destructuring": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.4.4.tgz",
"integrity": "sha512-/aOx+nW0w8eHiEHm+BTERB2oJn5D127iye/SUQl7NjHy0lf+j7h4MKMMSOwdazGq9OxgiNADncE+SRJkCxjZpQ==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-transform-dotall-regex": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.4.4.tgz",
"integrity": "sha512-P05YEhRc2h53lZDjRPk/OektxCVevFzZs2Gfjd545Wde3k+yFDbXORgl2e0xpbq8mLcKJ7Idss4fAg0zORN/zg==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.0.0",
"@babel/helper-regex": "^7.4.4",
"regexpu-core": "^4.5.4"
}
},
"@babel/plugin-transform-duplicate-keys": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.2.0.tgz",
"integrity": "sha512-q+yuxW4DsTjNceUiTzK0L+AfQ0zD9rWaTLiUqHA8p0gxx7lu1EylenfzjeIWNkPy6e/0VG/Wjw9uf9LueQwLOw==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-transform-exponentiation-operator": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz",
"integrity": "sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A==",
"dev": true,
"requires": {
"@babel/helper-builder-binary-assignment-operator-visitor": "^7.1.0",
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/helper-annotate-as-pure": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz",
"integrity": "sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q==",
"dev": true,
"requires": {
"@babel/types": "^7.0.0"
}
},
"@babel/helper-builder-binary-assignment-operator-visitor": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz",
"integrity": "sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w==",
"dev": true,
"requires": {
"@babel/helper-explode-assignable-expression": "^7.1.0",
"@babel/types": "^7.0.0"
}
},
"@babel/helper-call-delegate": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.4.4.tgz",
"integrity": "sha512-l79boDFJ8S1c5hvQvG+rc+wHw6IuH7YldmRKsYtpbawsxURu/paVy57FZMomGK22/JckepaikOkY0MoAmdyOlQ==",
"dev": true,
"requires": {
"@babel/helper-hoist-variables": "^7.4.4",
"@babel/traverse": "^7.4.4",
"@babel/types": "^7.4.4"
},
"dependencies": {
"@babel/generator": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.4.tgz",
"integrity": "sha512-53UOLK6TVNqKxf7RUh8NE851EHRxOOeVXKbK2bivdb+iziMyk03Sr4eaE9OELCbyZAAafAKPDwF2TPUES5QbxQ==",
"dev": true,
"requires": {
"@babel/types": "^7.4.4",
"jsesc": "^2.5.1",
"lodash": "^4.17.11",
"source-map": "^0.5.0",
"trim-right": "^1.0.1"
}
},
"@babel/helper-split-export-declaration": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz",
"integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==",
"dev": true,
"requires": {
"@babel/types": "^7.4.4"
}
},
"@babel/parser": {
"version": "7.4.5",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.5.tgz",
"integrity": "sha512-9mUqkL1FF5T7f0WDFfAoDdiMVPWsdD1gZYzSnaXsxUCUqzuch/8of9G3VUSNiZmMBoRxT3neyVsqeiL/ZPcjew==",
"dev": true
},
"@babel/traverse": {
"version": "7.4.5",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.5.tgz",
"integrity": "sha512-Vc+qjynwkjRmIFGxy0KYoPj4FdVDxLej89kMHFsWScq999uX+pwcX4v9mWRjW0KcAYTPAuVQl2LKP1wEVLsp+A==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
"@babel/generator": "^7.4.4",
"@babel/helper-function-name": "^7.1.0",
"@babel/helper-split-export-declaration": "^7.4.4",
"@babel/parser": "^7.4.5",
"@babel/types": "^7.4.4",
"debug": "^4.1.0",
"globals": "^11.1.0",
"lodash": "^4.17.11"
}
},
"@babel/types": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz",
"integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==",
"dev": true,
"requires": {
"esutils": "^2.0.2",
"lodash": "^4.17.11",
"to-fast-properties": "^2.0.0"
}
},
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"dev": true,
"requires": {
"ms": "^2.1.1"
}
},
"lodash": {
"version": "4.17.11",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
"dev": true
},
"ms": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
"dev": true
}
}
},
"@babel/helper-define-map": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.4.4.tgz",
"integrity": "sha512-IX3Ln8gLhZpSuqHJSnTNBWGDE9kdkTEWl21A/K7PQ00tseBwbqCHTvNLHSBd9M0R5rER4h5Rsvj9vw0R5SieBg==",
"dev": true,
"requires": {
"@babel/helper-function-name": "^7.1.0",
"@babel/types": "^7.4.4",
"lodash": "^4.17.11"
},
"dependencies": {
"@babel/types": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz",
"integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==",
"dev": true,
"requires": {
"esutils": "^2.0.2",
"lodash": "^4.17.11",
"to-fast-properties": "^2.0.0"
}
},
"lodash": {
"version": "4.17.11",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
"dev": true
}
}
},
"@babel/helper-explode-assignable-expression": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz",
"integrity": "sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA==",
"dev": true,
"requires": {
"@babel/traverse": "^7.1.0",
"@babel/types": "^7.0.0"
}
},
"@babel/helper-function-name": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz",
"integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==",
"dev": true,
"requires": {
"@babel/helper-call-delegate": "^7.4.4",
"@babel/helper-get-function-arity": "^7.0.0",
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/plugin-transform-property-literals": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.2.0.tgz",
"integrity": "sha512-9q7Dbk4RhgcLp8ebduOpCbtjh7C0itoLYHXd9ueASKAG/is5PQtMR5VJGka9NKqGhYEGn5ITahd4h9QeBMylWQ==",
"dev": true,
"requires": {
"@babel/helper-plugin-utils": "^7.0.0"
}
},
"@babel/helper-hoist-variables": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.4.4.tgz",
"integrity": "sha512-VYk2/H/BnYbZDDg39hr3t2kKyifAm1W6zHRfhx8jGjIHpQEBv9dry7oQ2f3+J703TLu69nYdxsovl0XYfcnK4w==",
"dev": true,
"requires": {
"@babel/types": "^7.4.4"
},
"dependencies": {
"@babel/types": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz",
"integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==",
"dev": true,
"requires": {
"esutils": "^2.0.2",
"lodash": "^4.17.11",
"to-fast-properties": "^2.0.0"
}
},
"lodash": {
"version": "4.17.11",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
"dev": true
}
}
},
"@babel/helper-member-expression-to-functions": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz",
"integrity": "sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg==",
"dev": true,
"requires": {
"regenerator-transform": "^0.13.4"
}
},
"@babel/helper-module-imports": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz",
"integrity": "sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A==",
"dev": true,
"requires": {
"@babel/types": "^7.0.0"
}
},
"@babel/helper-module-transforms": {
"version": "7.4.4",
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.4.4.tgz",

27
src/common/createJob.js

@ -0,0 +1,27 @@ @@ -0,0 +1,27 @@
const { sendPacket } = require('../node');
let jobCounter = 0;
module.exports = (
action,
payload,
) => {
jobCounter += 1;
const id = `Job-${jobCounter}-${Math.random().toString(16).slice(3, 8)}`;
const start = (worker) => {
console.log(`[${worker.id}]: Start ${id}, action=${action}`);
sendPacket(worker, {
workerId: worker.id,
jobId: id,
action,
payload,
});
};
return {
id,
action,
start,
};
};

57
src/common/createScheduler.js

@ -0,0 +1,57 @@ @@ -0,0 +1,57 @@
module.exports = () => {
const workers = {};
const runningJobs = {};
let jobQueue = [];
const dequeue = () => {
if (jobQueue.length !== 0) {
const wIds = Object.keys(workers);
for (let i = 0; i < wIds.length; i += 1) {
if (typeof runningJobs[wIds[i]] === 'undefined') {
jobQueue[0](workers[wIds[i]]);
break;
}
}
}
};
const queue = job => (
new Promise((resolve, reject) => {
jobQueue.push((w) => {
const { action } = job;
jobQueue.shift();
w.setResolve(action, (data) => {
delete runningJobs[w.id];
dequeue();
resolve(data);
});
w.setReject(action, reject);
runningJobs[w.id] = job;
job.start(w);
});
dequeue();
})
);
const addWorker = (w) => {
workers[w.id] = w;
return w.id;
};
const addJob = job => (
queue(job)
);
const terminate = () => {
Object.keys(workers).forEach((id) => {
workers[id].terminate();
});
jobQueue = [];
};
return {
addWorker,
addJob,
terminate,
};
};

7
src/common/createTesseract.js

@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
module.exports = (options = {}, nWorkers = 1) => {
return {
init: () => {},
loadLanguauge: () => {},
recognize: () => {},
};
};

129
src/common/createWorker.js

@ -0,0 +1,129 @@ @@ -0,0 +1,129 @@
const { isBrowser } = require('./env');
const resolveURL = isBrowser ? require('resolve-url') : s => s; // eslint-disable-line
const circularize = require('./circularize');
const createJob = require('./createJob');
const { defaultParams } = require('./options');
const {
defaultOptions,
spawnWorker,
terminateWorker,
setOnMessage,
} = require('../node');
let workerCounter = 0;
const resolvePaths = (options) => {
const opts = { ...options };
['corePath', 'workerPath', 'langPath'].forEach((key) => {
if (typeof options[key] !== 'undefined') {
opts[key] = resolveURL(opts[key]);
}
});
return opts;
};
module.exports = (options = {}) => {
workerCounter += 1;
const id = `Worker-${workerCounter}-${Math.random().toString(16).slice(3, 8)}`;
const opts = resolvePaths({
...defaultOptions,
...options,
});
const { logger } = opts;
const resolves = {};
const rejects = {};
let worker = spawnWorker(opts);
const setResolve = (action, res) => {
resolves[action] = res;
};
const setReject = (action, rej) => {
rejects[action] = rej;
};
const load = () => (
new Promise((resolve, reject) => {
const job = createJob(
'load',
opts,
);
setResolve('load', resolve);
setReject('load', reject);
job.start({ worker, id });
})
);
const loadLanguage = (langs = 'eng') => (
new Promise((resolve, reject) => {
const job = createJob(
'load-language',
{
langs,
options: opts,
},
);
setResolve('load-language', resolve);
setReject('load-language', reject);
job.start({ worker, id });
})
);
const initialize = (langs = 'eng', params = {}) => (
new Promise((resolve, reject) => {
const job = createJob(
'initialize',
{
langs,
params: {
...defaultParams,
...params,
},
},
);
setResolve('initialize', resolve);
setReject('initialize', reject);
job.start({ worker, id });
})
);
const terminate = () => {
if (worker !== null) {
terminateWorker({ worker });
worker = null;
}
};
setOnMessage(worker, (packet) => {
const { status, action, data } = packet;
if (status === 'resolve') {
if (action === 'load') {
resolves.load(data);
} else if (action === 'initialize') {
resolves.initialize({ id });
} else if (action === 'load-language') {
resolves['load-language'](data);
} else if (action === 'recognize') {
resolves.recognize(circularize(data));
} else if (action === 'detect') {
resolves.detect(data);
}
} else if (status === 'reject') {
rejects[action](data);
throw Error(data);
} else if (status === 'progress') {
logger(data);
}
});
return {
id,
worker,
setResolve,
setReject,
load,
loadLanguage,
initialize,
terminate,
};
};

1
src/common/env.js

@ -0,0 +1 @@ @@ -0,0 +1 @@
exports.isBrowser = (typeof window !== 'undefined') && (typeof window.document !== 'undefined');

1
src/common/options.js

@ -12,6 +12,7 @@ module.exports = { @@ -12,6 +12,7 @@ module.exports = {
* Use BlobURL for worker script by default
*/
workerBlobURL: true,
logger: () => {},
},
/*
* default params for recognize()

87
src/common/utils.js

@ -0,0 +1,87 @@ @@ -0,0 +1,87 @@
const { readImage } = require('tesseract.js-utils');
/**
* setImage
*
* @name setImage
* @function set image in tesseract for recognition
* @access public
* @param {array} image - binary array in array format
* @returns {number} - an emscripten pointer of the image
*/
exports.setImage = (TessModule, api, image, params) => {
const {
tessjs_image_rectangle_left: left,
tessjs_image_rectangle_top: top,
tessjs_image_rectangle_width: width,
tessjs_image_rectangle_height: height,
} = params;
const {
w, h, bytesPerPixel, data, pix,
} = readImage(TessModule, Array.from(image));
/*
* As some image format (ex. bmp) is not supported natiely by tesseract,
* sometimes it will not return pix directly, but data and bytesPerPixel
* for another SetImage usage.
*
*/
if (data === null) {
api.SetImage(pix);
} else {
api.SetImage(data, w, h, bytesPerPixel, w * bytesPerPixel);
}
api.SetRectangle(
(left < 0) ? 0 : left,
(top < 0) ? 0 : top,
(width < 0) ? w : width,
(height < 0) ? h : height,
);
return data === null ? pix : data;
};
exports.getLangsStr = langs => (
typeof langs === 'string'
? langs
: langs.map(lang => (typeof lang === 'string' ? lang : lang.data)).join('+')
);
/**
* handleOutput
*
* @name handleOutput
* @function handle file output
* @access private
* @param {object} customParams - an object of params
*/
exports.getFiles = (TessModule, api, adapter, params) => {
let files = {};
const {
tessjs_create_pdf,
tessjs_textonly_pdf,
tessjs_pdf_name,
tessjs_pdf_title,
tessjs_pdf_auto_download,
tessjs_pdf_bin,
} = params;
if (tessjs_create_pdf === '1') {
const pdfRenderer = new TessModule.TessPDFRenderer(tessjs_pdf_name, '/', tessjs_textonly_pdf === '1');
pdfRenderer.BeginDocument(tessjs_pdf_title);
pdfRenderer.AddImage(api);
pdfRenderer.EndDocument();
TessModule._free(pdfRenderer);
const data = TessModule.FS.readFile(`/${tessjs_pdf_name}.pdf`);
if (tessjs_pdf_bin) {
files = { pdf: data, ...files };
}
if (tessjs_pdf_auto_download) {
adapter.writeFile(`${tessjs_pdf_name}.pdf`, data, 'application/pdf');
}
}
return files;
};

299
src/common/workerUtils.js

@ -7,13 +7,12 @@ @@ -7,13 +7,12 @@
* @author Guillermo Webster <gui@mit.edu>
* @author Jerome Wu <jeromewus@gmail.com>
*/
const { readImage, loadLang } = require('tesseract.js-utils');
const { loadLang } = require('tesseract.js-utils');
const pdfTTF = require('./pdf-ttf');
const dump = require('./dump');
const { defaultParams } = require('./options');
const { OEM, PSM } = require('./types');
const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined';
const { isBrowser } = require('./env');
const { setImage, getLangsStr, getFiles } = require('./utils');
/*
* Tesseract Module returned by TesseractCore.
@ -25,117 +24,8 @@ let TessModule; @@ -25,117 +24,8 @@ let TessModule;
let api;
let latestJob;
let adapter = {};
let curParams = {};
/**
* setImage
*
* @name setImage
* @function set image in tesseract for recognition
* @access public
* @param {array} image - binary array in array format
* @returns {number} - an emscripten pointer of the image
*/
const setImage = (image, params) => {
const {
tessjs_image_rectangle_left: left,
tessjs_image_rectangle_top: top,
tessjs_image_rectangle_width: width,
tessjs_image_rectangle_height: height,
} = params;
const {
w, h, bytesPerPixel, data, pix,
} = readImage(TessModule, Array.from(image));
/*
* As some image format (ex. bmp) is not supported natiely by tesseract,
* sometimes it will not return pix directly, but data and bytesPerPixel
* for another SetImage usage.
*
*/
if (data === null) {
api.SetImage(pix);
} else {
api.SetImage(data, w, h, bytesPerPixel, w * bytesPerPixel);
}
api.SetRectangle(
(left < 0) ? 0 : left,
(top < 0) ? 0 : top,
(width < 0) ? w : width,
(height < 0) ? h : height,
);
return data === null ? pix : data;
};
const getLangsStr = langs => (
typeof langs === 'string'
? langs
: langs.map(lang => (typeof lang === 'string' ? lang : lang.data)).join('+')
);
/**
* handleParams
*
* @name handleParams
* @function hanlde params from users
* @access private
* @param {string} langs - lang string for Init()
* @param {object} customParams - an object of params
*/
const handleParams = (langs, iParams) => {
const {
tessedit_ocr_engine_mode,
...params
} = iParams;
api.Init(null, getLangsStr(langs), tessedit_ocr_engine_mode);
Object.keys(params).forEach((key) => {
if (!key.startsWith('tessjs')) {
api.SetVariable(key, params[key]);
}
});
};
/**
* handleOutput
*
* @name handleOutput
* @function handle file output
* @access private
* @param {object} customParams - an object of params
*/
const handleOutput = (customParams) => {
let files = {};
const {
tessjs_create_pdf,
tessjs_textonly_pdf,
tessjs_pdf_name,
tessjs_pdf_title,
tessjs_pdf_auto_download,
tessjs_pdf_bin,
} = {
...defaultParams,
...customParams,
};
if (tessjs_create_pdf === '1') {
const pdfRenderer = new TessModule.TessPDFRenderer(tessjs_pdf_name, '/', tessjs_textonly_pdf === '1');
pdfRenderer.BeginDocument(tessjs_pdf_title);
pdfRenderer.AddImage(api);
pdfRenderer.EndDocument();
TessModule._free(pdfRenderer);
const data = TessModule.FS.readFile(`/${tessjs_pdf_name}.pdf`);
if (tessjs_pdf_bin) {
files = { pdf: data, ...files };
}
if (tessjs_pdf_auto_download) {
adapter.writeFile(`${tessjs_pdf_name}.pdf`, data, 'application/pdf');
}
}
return files;
};
/**
* handleInit
@ -148,26 +38,32 @@ const handleOutput = (customParams) => { @@ -148,26 +38,32 @@ const handleOutput = (customParams) => {
* @param {object} res - job instance
* @returns {Promise} A Promise for callback
*/
const handleInit = ({ corePath }, res) => {
const load = ({ workerId, jobId, payload: { corePath } }, res) => {
if (!TessModule) {
const Core = adapter.getCore(corePath, res);
res.progress({ status: 'initializing tesseract', progress: 0 });
res.progress({ workerId, status: 'initializing tesseract', progress: 0 });
return Core({
Core({
TesseractProgress(percent) {
latestJob.progress({ status: 'recognizing text', progress: Math.max(0, (percent - 30) / 70) });
latestJob.progress({
workerId,
jobId,
status: 'recognizing text',
progress: Math.max(0, (percent - 30) / 70),
});
},
})
.then((tessModule) => {
TessModule = tessModule;
TessModule.FS.writeFile('/pdf.ttf', adapter.b64toU8Array(pdfTTF));
api = new TessModule.TessBaseAPI();
res.progress({ status: 'initialized tesseract', progress: 1 });
res.progress({ workerId, status: 'initialized tesseract', progress: 1 });
res.resolve({ loaded: true });
});
} else {
res.resolve({ loaded: true });
}
return Promise.resolve();
};
/**
@ -182,12 +78,57 @@ const handleInit = ({ corePath }, res) => { @@ -182,12 +78,57 @@ const handleInit = ({ corePath }, res) => {
* @param {object} res - job instance
* @returns {Promise} A Promise for callback
*/
const loadLanguage = ({ langs, options }, res) => {
res.progress({ status: 'loading language traineddata', progress: 0 });
return loadLang({ langs, TessModule, ...options }).then((...args) => {
res.progress({ status: 'loaded language traineddata', progress: 1 });
return args;
const loadLanguage = ({ workerId, payload: { langs, options } }, res) => {
res.progress({ workerId, status: 'loading language traineddata', progress: 0 });
loadLang({ langs, TessModule, ...options }).then(() => {
res.progress({ workerId, status: 'loaded language traineddata', progress: 1 });
res.resolve(langs);
}).catch((e) => {
if (isBrowser && e instanceof DOMException) {
/*
* For some reason google chrome throw DOMException in loadLang,
* while other browser is OK, for now we ignore this exception
* and hopefully to find the root cause one day.
*/
} else {
res.reject(e.toString());
}
});
};
const initialize = ({
workerId,
jobId,
payload: { langs, params },
}, res) => {
let { tessedit_ocr_engine_mode: oem } = params;
let l = langs;
res.progress({
workerId, jobId, status: 'initializing api', progress: 0,
});
if ([
PSM.OSD_ONLY,
PSM.AUTO_OSD,
PSM.RAW_LINE,
].includes(params.tessedit_pageseg_mode)) {
l = (typeof l === 'string') ? `${l}+osd` : [...l, 'osd'];
// oem = OEM.TESSERACT_ONLY;
}
api.Init(null, getLangsStr(l), oem);
Object.keys(params).forEach((key) => {
if (!key.startsWith('tessjs')) {
api.SetVariable(key, params[key]);
}
});
curParams = {
tessedit_ocr_engine_mode: oem,
...params,
};
res.progress({
workerId, jobId, status: 'initialized api', progress: 1,
});
res.resolve();
};
/**
@ -203,66 +144,18 @@ const loadLanguage = ({ langs, options }, res) => { @@ -203,66 +144,18 @@ const loadLanguage = ({ langs, options }, res) => {
* @param {object} req.params - parameters for tesseract
* @param {object} res - job instance
*/
const handleRecognize = ({
image, langs: iLangs, options, params: customParams,
}, res) => {
const params = {
...defaultParams,
...customParams,
};
const { tessedit_pageseg_mode } = params;
let langs = iLangs;
/*
* When PSM === OSD_ONLY or AUTO_OSD or RAW_LINE
* osd.traineddata must be included and
* OEM must be TESSERACT_ONLY (LSTM doesn't support OSD)
*/
if ([
PSM.OSD_ONLY,
PSM.AUTO_OSD,
PSM.RAW_LINE,
].includes(tessedit_pageseg_mode)) {
langs = (typeof iLangs === 'string')
? `${iLangs}+osd`
: [...iLangs, 'osd'];
params.tessedit_ocr_engine_mode = OEM.TESSERACT_ONLY;
}
return handleInit(options, res)
.then(() => (
loadLanguage({ langs, params, options }, res)
.catch((e) => {
if (isBrowser && e instanceof DOMException) {
/*
* For some reason google chrome throw DOMException in loadLang,
* while other browser is OK, for now we ignore this exception
* and hopefully to find the root cause one day.
*/
} else {
throw e;
}
})
.then(() => {
const recognize = ({ payload: { image } }, res) => {
try {
const progressUpdate = (progress) => {
res.progress({ status: 'initializing api', progress });
};
progressUpdate(0);
handleParams(langs, params);
progressUpdate(0.5);
const ptr = setImage(image, params);
progressUpdate(1);
const ptr = setImage(TessModule, api, image, curParams);
api.Recognize(null);
const files = handleOutput(params);
const result = dump(TessModule, api, params);
api.End();
res.resolve({
files: getFiles(TessModule, api, adapter, curParams),
...dump(TessModule, api, curParams),
});
TessModule._free(ptr);
res.resolve({ files, ...result });
} catch (err) {
res.reject({ err });
res.reject(err.toString());
}
})
));
};
/**
@ -277,21 +170,9 @@ const handleRecognize = ({ @@ -277,21 +170,9 @@ const handleRecognize = ({
* @param {object} req.options - other options for loadLang function
* @param {object} res - job instance
*/
const handleDetect = ({
image, langs, options, params: customParams,
}, res) => (
handleInit(options, res)
.then(() => (
loadLanguage({ langs, options }, res)
.then(() => {
api.Init(null, getLangsStr(langs), OEM.TESSERACT_ONLY);
api.SetPageSegMode(PSM.OSD_ONLY);
const params = {
...defaultParams,
...customParams,
};
const ptr = setImage(image, params);
const detect = ({ payload: { image } }, res) => {
try {
const ptr = setImage(TessModule, api, image, curParams);
const results = new TessModule.OSResults();
if (!api.DetectOS(results)) {
@ -303,7 +184,6 @@ const handleDetect = ({ @@ -303,7 +184,6 @@ const handleDetect = ({
const oid = best.orientation_id;
const sid = best.script_id;
api.End();
TessModule._free(ptr);
res.resolve({
@ -314,9 +194,10 @@ const handleDetect = ({ @@ -314,9 +194,10 @@ const handleDetect = ({
orientation_confidence: best.oconfidence,
});
}
})
))
);
} catch (err) {
res.reject(err.toString());
}
};
/**
* dispatchHandlers
@ -330,12 +211,11 @@ const handleDetect = ({ @@ -330,12 +211,11 @@ const handleDetect = ({
* @param {object} data.payload - data for the job
* @param {function} send - trigger job to work
*/
exports.dispatchHandlers = ({ jobId, action, payload }, send) => {
exports.dispatchHandlers = (packet, send) => {
const res = (status, data) => {
send({
jobId,
...packet,
status,
action,
data,
});
};
@ -346,10 +226,17 @@ exports.dispatchHandlers = ({ jobId, action, payload }, send) => { @@ -346,10 +226,17 @@ exports.dispatchHandlers = ({ jobId, action, payload }, send) => {
latestJob = res;
try {
if (action === 'recognize') {
handleRecognize(payload, res);
const { action } = packet;
if (action === 'load') {
load(packet, res);
} else if (action === 'load-language') {
loadLanguage(packet, res);
} else if (action === 'initialize') {
initialize(packet, res);
} else if (action === 'recognize') {
recognize(packet, res);
} else if (action === 'detect') {
handleDetect(payload, res);
detect(packet, res);
}
} catch (err) {
/** Prepare exception to travel through postMessage */

6
src/index.js

@ -9,6 +9,9 @@ @@ -9,6 +9,9 @@
*/
const utils = require('tesseract.js-utils');
const TesseractWorker = require('./common/TesseractWorker');
const createScheduler = require('./common/createScheduler');
const createWorker = require('./common/createWorker');
const createJob = require('./common/createJob');
const types = require('./common/types');
module.exports = {
@ -18,4 +21,7 @@ module.exports = { @@ -18,4 +21,7 @@ module.exports = {
utils,
/** Check ./common/types for more details */
...types,
createScheduler,
createWorker,
createJob,
};

30
src/node/index.js

@ -67,12 +67,12 @@ exports.defaultOptions = { @@ -67,12 +67,12 @@ exports.defaultOptions = {
* @param {object} options
* @param {string} options.workerPath - worker script path
*/
exports.spawnWorker = (instance, { workerPath }) => {
const cp = fork(workerPath);
cp.on('message', (packet) => {
instance.recv(packet);
});
return cp;
exports.spawnWorker = ({ workerPath }) => (
fork(workerPath)
);
exports.setOnMessage = (worker, handler) => {
worker.on('message', handler);
};
/**
@ -83,8 +83,8 @@ exports.spawnWorker = (instance, { workerPath }) => { @@ -83,8 +83,8 @@ exports.spawnWorker = (instance, { workerPath }) => {
* @access public
* @param {object} instance TesseractWorker instance
*/
exports.terminateWorker = (instance) => {
instance.worker.kill();
exports.terminateWorker = ({ worker }) => {
worker.kill();
};
/**
@ -96,12 +96,16 @@ exports.terminateWorker = (instance) => { @@ -96,12 +96,16 @@ exports.terminateWorker = (instance) => {
* @param {object} instance TesseractWorker instance
* @param {object} iPacket data for worker
*/
exports.sendPacket = (instance, iPacket) => {
const packet = { ...iPacket };
loadImage(packet.payload.image)
exports.sendPacket = ({ worker }, packet) => {
const p = { ...packet };
if (['recognize', 'detect'].includes(p.action)) {
loadImage(p.payload.image)
.then(buf => new Uint8Array(buf))
.then((img) => {
packet.payload.image = Array.from(img);
instance.worker.send(packet);
p.payload.image = Array.from(img);
worker.send(p);
});
} else {
worker.send(p);
}
};

Loading…
Cancel
Save