pdftest
Version:
Client-side visual testing library for PDFs
665 lines (547 loc) • 25.2 kB
JavaScript
module.exports =
/******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ({
/***/ "./src/client/compare.js":
/*!*******************************!*\
!*** ./src/client/compare.js ***!
\*******************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "compare": () => (/* binding */ compare),
/* harmony export */ "compareToSnapshot": () => (/* binding */ compareToSnapshot)
/* harmony export */ });
/* harmony import */ var pixelmatch__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pixelmatch */ "pixelmatch");
/* harmony import */ var pixelmatch__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(pixelmatch__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _util_read_pdf__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./util/read-pdf */ "./src/client/util/read-pdf.js");
/* harmony import */ var _ui__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ui */ "./src/client/ui.js");
/* harmony import */ var _shared_api__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../shared/api */ "./src/shared/api.js");
async function comparePage(pdfObjects, page, options) {
// Initialise the page match results.
let match = false;
let numDiffPixels = null;
let diffImg = null; // Get an image of the current page for both PDFs.
const [pageImg1, pageImg2, error] = await (0,_util_read_pdf__WEBPACK_IMPORTED_MODULE_1__.getPageImages)(pdfObjects, page);
if (error) {
options.verbose && console.log(`pdftest: Page ${page + 1} comparison failed with error '${error}'`);
} else {
// Create a canvas and run pixelmatch.
const diffCanvas = document.createElement('canvas');
diffImg = diffCanvas.getContext('2d').createImageData(pageImg1.width, pageImg1.height);
numDiffPixels = pixelmatch__WEBPACK_IMPORTED_MODULE_0__(pageImg1.data, pageImg2.data, diffImg.data, diffImg.width, diffImg.height, options.customDiffConfig); // Determine whether the page matches according to failureThreshold.
if (options.failureThresholdType === 'percent') {
const numPixels = pageImg1.width * pageImg1.height;
const proportionDifferent = numDiffPixels / numPixels;
match = proportionDifferent <= options.failureThreshold;
} else {
match = numDiffPixels <= options.failureThreshold;
}
} // Build results for the current page.
return {
match,
pageImg: [pageImg1, pageImg2],
diffImg,
numDiffPixels,
error
};
}
async function compare(pdf1, pdf2, options) {
// Setup default options.
options = {
failureThreshold: 0,
failureThresholdType: 'pixel',
customDiffConfig: {
threshold: 0.1
},
...options
}; // Load the PDF objects.
const pdfObjects = await (0,_util_read_pdf__WEBPACK_IMPORTED_MODULE_1__.getPdfObjects)(pdf1, pdf2); // Pre-allocate result object.
const result = {
match: true,
nPages: Math.max(pdfObjects[0].numPages, pdfObjects[1].numPages),
pageResults: [],
source: [pdf1, pdf2]
}; // Compare all pages asynchronously and wait for all to finish.
const pagePromises = [...Array(result.nPages)].map(async (_val, i) => {
result.pageResults[i] = await comparePage(pdfObjects, i, options);
result.match = result.match && result.pageResults[i].match;
});
await Promise.all(pagePromises);
return result;
}
async function compareToSnapshot(pdf, snapshotName, options) {
const snapshot = await (0,_shared_api__WEBPACK_IMPORTED_MODULE_3__.getSnapshot)(snapshotName, pdf);
const comparison = await compare(pdf, snapshot, options);
const doShowDiff = !comparison.match && options.interactive;
return doShowDiff ? await (0,_ui__WEBPACK_IMPORTED_MODULE_2__.showDiff)(comparison, snapshotName) : comparison;
}
/***/ }),
/***/ "./src/client/index.js":
/*!*****************************!*\
!*** ./src/client/index.js ***!
\*****************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "compare": () => (/* reexport safe */ _compare__WEBPACK_IMPORTED_MODULE_0__.compare),
/* harmony export */ "compareToSnapshot": () => (/* reexport safe */ _compare__WEBPACK_IMPORTED_MODULE_0__.compareToSnapshot),
/* harmony export */ "showDiff": () => (/* reexport safe */ _ui__WEBPACK_IMPORTED_MODULE_1__.showDiff),
/* harmony export */ "api": () => (/* reexport module object */ _shared_api__WEBPACK_IMPORTED_MODULE_2__)
/* harmony export */ });
/* harmony import */ var _compare__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./compare */ "./src/client/compare.js");
/* harmony import */ var _ui__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./ui */ "./src/client/ui.js");
/* harmony import */ var _shared_api__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../shared/api */ "./src/shared/api.js");
/***/ }),
/***/ "./src/client/ui.js":
/*!**************************!*\
!*** ./src/client/ui.js ***!
\**************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "showDiff": () => (/* binding */ showDiff)
/* harmony export */ });
/* harmony import */ var _shared_api__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../shared/api */ "./src/shared/api.js");
async function showDiff(comparison, snapshotName) {
// TODO:
// - fix this to show all diff pages (rather than just page 0)
// - handle comparison errors (e.g. mismatched # of pages or page sizes)
const popupWindow = window.open('', '_blank', 'width=400,height=700');
const popupDocument = popupWindow.document;
popupDocument.body.innerHTML = `
<h3>Visual change detected</h3>
<p>How would you like to treat the new PDF?</p>
<div>
<img id="diffImg" style="width: 100%; border: 1px solid black;">
</div>
<div>
<button id="ignore">Ignore (Skip)</button>
<button id="reject">Reject (Fail test)</button>
<button id="accept">Accept (Overwrite)</button>
</div>
`;
const canvas = document.createElement('canvas');
const diffImg = comparison.pageResults[0].diffImg;
canvas.width = diffImg.width;
canvas.height = diffImg.height;
canvas.getContext('2d').putImageData(diffImg, 0, 0);
const targetImg = popupDocument.body.querySelector('#diffImg');
targetImg.src = canvas.toDataURL('image/png');
return new Promise((resolve, reject) => {
const resolveAndClose = value => {
resolve({ ...comparison,
match: value
});
popupWindow.close();
};
popupWindow.addEventListener('unload', () => resolveAndClose(false));
popupDocument.querySelector('#ignore').addEventListener('click', () => resolveAndClose(true));
popupDocument.querySelector('#reject').addEventListener('click', () => resolveAndClose(false));
popupDocument.querySelector('#accept').addEventListener('click', async () => {
await (0,_shared_api__WEBPACK_IMPORTED_MODULE_0__.put)(snapshotName, comparison.source[0]);
resolveAndClose(true);
});
});
}
/***/ }),
/***/ "./src/client/util/read-pdf.js":
/*!*************************************!*\
!*** ./src/client/util/read-pdf.js ***!
\*************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "getPdfObject": () => (/* binding */ getPdfObject),
/* harmony export */ "getPdfObjects": () => (/* binding */ getPdfObjects),
/* harmony export */ "getPageImage": () => (/* binding */ getPageImage),
/* harmony export */ "getPageImages": () => (/* binding */ getPageImages)
/* harmony export */ });
/* harmony import */ var pdfjs_dist_build_pdf__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! pdfjs-dist/build/pdf */ "pdfjs-dist/build/pdf");
/* harmony import */ var pdfjs_dist_build_pdf__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(pdfjs_dist_build_pdf__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var pdfjs_dist_build_pdf_worker_entry__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! pdfjs-dist/build/pdf.worker.entry */ "pdfjs-dist/build/pdf.worker.entry");
/* harmony import */ var pdfjs_dist_build_pdf_worker_entry__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(pdfjs_dist_build_pdf_worker_entry__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var _shared_api__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../shared/api */ "./src/shared/api.js");
// 2021-01-13 In pdfjs, workerSrc should always be specified, rather than relying
// on a fallback. This solves several issues:
// - Client: DOMException: Failed to execute 'importScripts' on 'WorkerGlobalScope'.
// - Client works without this fix, but throws an exception if inspector is open.
// - Server (unverified): No "GlobalWorkerOptions.workerSrc" specified.
// - Does *not* solve the "Warning: setting up fake worker" issue
// - In fact, I believe this explicitly forces the fake worker.
// More info: https://github.com/mozilla/pdf.js/issues/10478#issuecomment-518673665
pdfjs_dist_build_pdf__WEBPACK_IMPORTED_MODULE_0__.GlobalWorkerOptions.workerSrc = pdfjs_dist_build_pdf_worker_entry__WEBPACK_IMPORTED_MODULE_1__;
function readFileAsync(file) {
// Create a promise that resolves when the file is loaded.
return new Promise((resolve, reject) => {
let reader = new FileReader();
reader.onload = () => resolve(reader.result);
reader.onerror = reject;
reader.readAsArrayBuffer(file);
});
}
async function getPdfObject(src) {
// Note: This step is also required for Blob inputs.
if (typeof File !== 'undefined' && src instanceof File) {
src = await readFileAsync(src);
} else if (typeof src === 'string') {
src = await (0,_shared_api__WEBPACK_IMPORTED_MODULE_2__.get)(src);
}
return await pdfjs_dist_build_pdf__WEBPACK_IMPORTED_MODULE_0__.getDocument(src).promise;
}
function getPdfObjects(pdf1, pdf2) {
return Promise.all([pdf1, pdf2].map(getPdfObject));
}
async function getPageImage(pdfObject, i, targetWidth) {
// Fail for invalid pages.
if (0 > i || i >= pdfObject.numPages) {
return null;
} // Get the PDF page and scale it to the target width.
const page = await pdfObject.getPage(i + 1);
const scale = targetWidth ? targetWidth / Math.floor(page.view[2]) : 1;
const viewport = page.getViewport({
scale: scale
}); // Render the PDF page to a canvas.
const canvas = document.createElement('canvas');
canvas.width = viewport.width;
canvas.height = viewport.height;
const context = canvas.getContext('2d'); // Note: page.render can take a long time (e.g. 2+ min for an 80MB PDF).
// Performance could be improved by loading pdf.js with a worker-loader - see:
// https://github.com/mozilla/pdf.js/tree/master/examples/webpack#worker-loading
await page.render({
canvasContext: context,
viewport: viewport,
intent: 'print'
}).promise; // Return the canvas' imageData with scale info attached.
const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
return Object.assign(imageData, {
scale: scale
});
}
async function getPageImages(pdfObjects, page) {
const pageImg1 = await getPageImage(pdfObjects[0], page);
const pageImg2 = await getPageImage(pdfObjects[1], page, pageImg1 && pageImg1.width);
let error; // Handle incompatible pages.
if (!pageImg1 || !pageImg2) {
error = 'missing_page';
} else if (pageImg1.width !== pageImg2.width || pageImg1.height !== pageImg2.height) {
error = 'mismatched_size';
}
return [pageImg1, pageImg2, error];
}
/***/ }),
/***/ "./src/index.js":
/*!**********************!*\
!*** ./src/index.js ***!
\**********************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "client": () => (/* reexport module object */ _client__WEBPACK_IMPORTED_MODULE_0__),
/* harmony export */ "server": () => (/* reexport module object */ _server__WEBPACK_IMPORTED_MODULE_1__)
/* harmony export */ });
/* harmony import */ var _client__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./client */ "./src/client/index.js");
/* harmony import */ var _server__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./server */ "./src/server/index.js");
/***/ }),
/***/ "./src/server/index.js":
/*!*****************************!*\
!*** ./src/server/index.js ***!
\*****************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "serve": () => (/* reexport safe */ _serve__WEBPACK_IMPORTED_MODULE_0__.default),
/* harmony export */ "api": () => (/* reexport module object */ _shared_api__WEBPACK_IMPORTED_MODULE_1__)
/* harmony export */ });
/* harmony import */ var _serve__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./serve */ "./src/server/serve.js");
/* harmony import */ var _shared_api__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../shared/api */ "./src/shared/api.js");
/***/ }),
/***/ "./src/server/serve.js":
/*!*****************************!*\
!*** ./src/server/serve.js ***!
\*****************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var express__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! express */ "express");
/* harmony import */ var express__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(express__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var cors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! cors */ "cors");
/* harmony import */ var cors__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(cors__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! path */ "path");
/* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! fs */ "fs");
/* harmony import */ var fs__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(fs__WEBPACK_IMPORTED_MODULE_3__);
function writeFile(filePath, data) {
fs__WEBPACK_IMPORTED_MODULE_3___default().mkdirSync(path__WEBPACK_IMPORTED_MODULE_2___default().dirname(filePath), {
recursive: true
});
fs__WEBPACK_IMPORTED_MODULE_3___default().writeFileSync(filePath, data);
}
function handlePostPut(root) {
return (req, res, next) => {
const requestedFile = path__WEBPACK_IMPORTED_MODULE_2___default().join(root, req.url);
switch (req.method) {
case 'POST':
if (fs__WEBPACK_IMPORTED_MODULE_3___default().existsSync(requestedFile)) {
req.method = 'GET';
break;
}
case 'PUT':
writeFile(requestedFile, req.body);
req.method = 'GET';
}
next();
};
}
function handleHandshake(req, res, next) {
if (['GET', 'HEAD'].includes(req.method) && req.url === '/') {
return res.status(200).end();
}
next();
}
function setupServer(root, options) {
const app = express__WEBPACK_IMPORTED_MODULE_0___default()();
app.use(cors__WEBPACK_IMPORTED_MODULE_1___default()());
app.use(express__WEBPACK_IMPORTED_MODULE_0___default().raw({
type: ['application/octet-stream', 'application/pdf'],
limit: options.limit || '100mb'
}));
app.use(handlePostPut(root));
app.use(handleHandshake);
app.use(express__WEBPACK_IMPORTED_MODULE_0___default().static(root));
return app;
}
function serve(port = 8000, root = '.', options = {}) {
const app = setupServer(root, options);
return new Promise((resolve, reject) => {
const server = app.listen(port, () => {
const optionsText = JSON.stringify(options) === '{}' ? '' : ` with options ${JSON.stringify(options)}`;
options.verbose && console.log(`pdftest: Serving '${root}' at http://localhost:${port}${optionsText}`);
resolve(server);
});
process.on('uncaughtException', reject);
});
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (serve);
/***/ }),
/***/ "./src/shared/api.js":
/*!***************************!*\
!*** ./src/shared/api.js ***!
\***************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "connect": () => (/* binding */ connect),
/* harmony export */ "getConnection": () => (/* binding */ getConnection),
/* harmony export */ "get": () => (/* binding */ get),
/* harmony export */ "getSnapshot": () => (/* binding */ getSnapshot),
/* harmony export */ "put": () => (/* binding */ put)
/* harmony export */ });
/* harmony import */ var cross_fetch__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! cross-fetch */ "cross-fetch");
/* harmony import */ var cross_fetch__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(cross_fetch__WEBPACK_IMPORTED_MODULE_0__);
const state = {
connection: null
};
async function connect(url, options = {}) {
state.connection = url;
await handshake();
options.verbose && console.log(`pdftest: Successfully connected to ${getConnection()}.`);
}
function getConnection() {
return state.connection;
}
function handshake() {
try {
return get('', 'text');
} catch (e) {
throw new Error(`Failed to connect to ${getConnection()}: ${e.message}`);
}
}
function verifyConnection() {
if (!getConnection()) {
throw new Error('Not connected to a server. Use api.connect(url) first.');
}
}
async function handleResponse(response, returnType) {
if (!response.ok) {
throw new Error(`Server returned a status of ${response.status}.`);
}
return await response[returnType]();
}
/**
* Get a PDF file from the server.
* @param {string} filepath Path of the target file.
* @param {string} [returnType='arrayBuffer'] One of 'arrayBuffer' or 'blob' (see fetch API).
*/
async function get(filepath, returnType = 'arrayBuffer') {
verifyConnection();
const response = await cross_fetch__WEBPACK_IMPORTED_MODULE_0___default()(`${getConnection()}/${filepath}`);
return await handleResponse(response, returnType);
}
/**
* Get a PDF file from the server, or create it with the given data if it doesn't exist.
* @param {string} filepath Path of the target file.
* @param {File} defaultValue The value to save if no snapshot exists.
* @param {string} [returnType='arrayBuffer'] One of 'arrayBuffer' or 'blob' (see fetch API).
*/
async function getSnapshot(filepath, defaultValue, returnType = 'arrayBuffer') {
verifyConnection();
const response = await cross_fetch__WEBPACK_IMPORTED_MODULE_0___default()(`${getConnection()}/${filepath}`, {
method: 'POST',
body: defaultValue,
headers: {
'Content-Type': 'application/octet-stream'
}
});
return await handleResponse(response, returnType);
}
/**
* Save a PDF file to the server and return it.
* @param {string} filepath Path of the target file.
* @param {File} data The value to save.
* @param {string} [returnType='arrayBuffer'] One of 'arrayBuffer' or 'blob' (see fetch API).
*/
async function put(filepath, data, returnType = 'arrayBuffer') {
verifyConnection();
const response = await cross_fetch__WEBPACK_IMPORTED_MODULE_0___default()(`${getConnection()}/${filepath}`, {
method: 'PUT',
body: data,
headers: {
'Content-Type': 'application/octet-stream'
}
});
return await handleResponse(response, returnType);
}
/***/ }),
/***/ "cors":
/*!***********************!*\
!*** external "cors" ***!
\***********************/
/***/ ((module) => {
module.exports = require("cors");;
/***/ }),
/***/ "cross-fetch":
/*!******************************!*\
!*** external "cross-fetch" ***!
\******************************/
/***/ ((module) => {
module.exports = require("cross-fetch");;
/***/ }),
/***/ "express":
/*!**************************!*\
!*** external "express" ***!
\**************************/
/***/ ((module) => {
module.exports = require("express");;
/***/ }),
/***/ "fs":
/*!*********************!*\
!*** external "fs" ***!
\*********************/
/***/ ((module) => {
module.exports = require("fs");;
/***/ }),
/***/ "path":
/*!***********************!*\
!*** external "path" ***!
\***********************/
/***/ ((module) => {
module.exports = require("path");;
/***/ }),
/***/ "pdfjs-dist/build/pdf":
/*!***************************************!*\
!*** external "pdfjs-dist/build/pdf" ***!
\***************************************/
/***/ ((module) => {
module.exports = require("pdfjs-dist/build/pdf");;
/***/ }),
/***/ "pdfjs-dist/build/pdf.worker.entry":
/*!****************************************************!*\
!*** external "pdfjs-dist/build/pdf.worker.entry" ***!
\****************************************************/
/***/ ((module) => {
module.exports = require("pdfjs-dist/build/pdf.worker.entry");;
/***/ }),
/***/ "pixelmatch":
/*!*****************************!*\
!*** external "pixelmatch" ***!
\*****************************/
/***/ ((module) => {
module.exports = require("pixelmatch");;
/***/ })
/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ if(__webpack_module_cache__[moduleId]) {
/******/ return __webpack_module_cache__[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/************************************************************************/
/******/ /* webpack/runtime/compat get default export */
/******/ (() => {
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = (module) => {
/******/ var getter = module && module.__esModule ?
/******/ () => (module['default']) :
/******/ () => (module);
/******/ __webpack_require__.d(getter, { a: getter });
/******/ return getter;
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/define property getters */
/******/ (() => {
/******/ // define getter functions for harmony exports
/******/ __webpack_require__.d = (exports, definition) => {
/******/ for(var key in definition) {
/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ }
/******/ }
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ (() => {
/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ })();
/******/
/******/ /* webpack/runtime/make namespace object */
/******/ (() => {
/******/ // define __esModule on exports
/******/ __webpack_require__.r = (exports) => {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/ })();
/******/
/************************************************************************/
/******/ // module exports must be returned from runtime so entry inlining is disabled
/******/ // startup
/******/ // Load entry module and return exports
/******/ return __webpack_require__("./src/index.js");
/******/ })()
;
//# sourceMappingURL=pdftest.cjs.js.map