From 26c6d1b1721c898ca4c8e686e995ed3ebefb0106 Mon Sep 17 00:00:00 2001
From: Patrizio Bekerle <patrizio@bekerle.com>
Date: Fri, 8 May 2020 08:06:32 +0200
Subject: [PATCH] Add first draft of pdf preview (#5)

---
 package-lock.json      | 868 +++++++++++++++++++++++++++++++++++++++++
 package.json           |   2 +
 rollup.config.js       |   9 +-
 src/vpu-pdf-preview.js | 282 +++++++++++++
 vendor/file-upload     |   2 +-
 5 files changed, 1161 insertions(+), 2 deletions(-)
 create mode 100644 src/vpu-pdf-preview.js

diff --git a/package-lock.json b/package-lock.json
index 1b947d3..30a282e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -772,6 +772,23 @@
       "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
       "dev": true
     },
+    "abstract-leveldown": {
+      "version": "0.12.4",
+      "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-0.12.4.tgz",
+      "integrity": "sha1-KeGOYy5g5OIh1YECR4UqY9ey5BA=",
+      "dev": true,
+      "requires": {
+        "xtend": "~3.0.0"
+      },
+      "dependencies": {
+        "xtend": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz",
+          "integrity": "sha1-XM50B7r2Qsunvs2laBEcST9ZZlo=",
+          "dev": true
+        }
+      }
+    },
     "accepts": {
       "version": "1.3.7",
       "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
@@ -1060,6 +1077,25 @@
       "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=",
       "dev": true
     },
+    "asn1.js": {
+      "version": "4.10.1",
+      "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz",
+      "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.0.0",
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.8",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+          "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+          "dev": true
+        }
+      }
+    },
     "assertion-error": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
@@ -1145,12 +1181,53 @@
       "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==",
       "dev": true
     },
+    "bl": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/bl/-/bl-0.8.2.tgz",
+      "integrity": "sha1-yba8oI0bwuoA/Ir7Txpf0eHGbk4=",
+      "dev": true,
+      "requires": {
+        "readable-stream": "~1.0.26"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "0.0.1",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+          "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "1.0.34",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+          "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
+          "dev": true,
+          "requires": {
+            "core-util-is": "~1.0.0",
+            "inherits": "~2.0.1",
+            "isarray": "0.0.1",
+            "string_decoder": "~0.10.x"
+          }
+        },
+        "string_decoder": {
+          "version": "0.10.31",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+          "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+          "dev": true
+        }
+      }
+    },
     "blob": {
       "version": "0.0.5",
       "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz",
       "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==",
       "dev": true
     },
+    "bn.js": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.1.tgz",
+      "integrity": "sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA==",
+      "dev": true
+    },
     "body-parser": {
       "version": "1.19.0",
       "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
@@ -1205,12 +1282,113 @@
         "fill-range": "^7.0.1"
       }
     },
+    "brorand": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
+      "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
+      "dev": true
+    },
     "browser-stdout": {
       "version": "1.3.1",
       "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
       "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
       "dev": true
     },
+    "browserify-aes": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
+      "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
+      "dev": true,
+      "requires": {
+        "buffer-xor": "^1.0.3",
+        "cipher-base": "^1.0.0",
+        "create-hash": "^1.1.0",
+        "evp_bytestokey": "^1.0.3",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "browserify-cipher": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
+      "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
+      "dev": true,
+      "requires": {
+        "browserify-aes": "^1.0.4",
+        "browserify-des": "^1.0.0",
+        "evp_bytestokey": "^1.0.0"
+      }
+    },
+    "browserify-des": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz",
+      "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==",
+      "dev": true,
+      "requires": {
+        "cipher-base": "^1.0.1",
+        "des.js": "^1.0.0",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
+    "browserify-fs": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/browserify-fs/-/browserify-fs-1.0.0.tgz",
+      "integrity": "sha1-8HWqinKdTRcW0GZiDjhvzBMRqW8=",
+      "dev": true,
+      "requires": {
+        "level-filesystem": "^1.0.1",
+        "level-js": "^2.1.3",
+        "levelup": "^0.18.2"
+      }
+    },
+    "browserify-rsa": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
+      "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.1.0",
+        "randombytes": "^2.0.1"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.8",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+          "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+          "dev": true
+        }
+      }
+    },
+    "browserify-sign": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.1.0.tgz",
+      "integrity": "sha512-VYxo7cDCeYUoBZ0ZCy4UyEUCP3smyBd4DRQM5nrFS1jJjPJjX7rP3oLRpPoWfkhQfyJ0I9ZbHbKafrFD/SGlrg==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^5.1.1",
+        "browserify-rsa": "^4.0.1",
+        "create-hash": "^1.2.0",
+        "create-hmac": "^1.1.7",
+        "elliptic": "^6.5.2",
+        "inherits": "^2.0.4",
+        "parse-asn1": "^5.1.5",
+        "readable-stream": "^3.6.0"
+      },
+      "dependencies": {
+        "readable-stream": {
+          "version": "3.6.0",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+          "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+          "dev": true,
+          "requires": {
+            "inherits": "^2.0.3",
+            "string_decoder": "^1.1.1",
+            "util-deprecate": "^1.0.1"
+          }
+        }
+      }
+    },
     "buffer-crc32": {
       "version": "0.2.13",
       "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
@@ -1223,12 +1401,24 @@
       "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=",
       "dev": true
     },
+    "buffer-es6": {
+      "version": "4.9.3",
+      "resolved": "https://registry.npmjs.org/buffer-es6/-/buffer-es6-4.9.3.tgz",
+      "integrity": "sha1-8mNHuC33b9N+GLy1KIxJcM/VxAQ=",
+      "dev": true
+    },
     "buffer-from": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
       "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
       "dev": true
     },
+    "buffer-xor": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
+      "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
+      "dev": true
+    },
     "builtin-modules": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.1.0.tgz",
@@ -1312,6 +1502,16 @@
         "readdirp": "~3.4.0"
       }
     },
+    "cipher-base": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
+      "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
     "cli-cursor": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
@@ -1531,6 +1731,51 @@
       "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
       "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
     },
+    "create-ecdh": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz",
+      "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.1.0",
+        "elliptic": "^6.0.0"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.8",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+          "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+          "dev": true
+        }
+      }
+    },
+    "create-hash": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
+      "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
+      "dev": true,
+      "requires": {
+        "cipher-base": "^1.0.1",
+        "inherits": "^2.0.1",
+        "md5.js": "^1.3.4",
+        "ripemd160": "^2.0.1",
+        "sha.js": "^2.4.0"
+      }
+    },
+    "create-hmac": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
+      "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
+      "dev": true,
+      "requires": {
+        "cipher-base": "^1.0.3",
+        "create-hash": "^1.1.0",
+        "inherits": "^2.0.1",
+        "ripemd160": "^2.0.0",
+        "safe-buffer": "^5.0.1",
+        "sha.js": "^2.4.8"
+      }
+    },
     "cross-spawn": {
       "version": "6.0.5",
       "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
@@ -1544,6 +1789,25 @@
         "which": "^1.2.9"
       }
     },
+    "crypto-browserify": {
+      "version": "3.12.0",
+      "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
+      "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
+      "dev": true,
+      "requires": {
+        "browserify-cipher": "^1.0.0",
+        "browserify-sign": "^4.0.0",
+        "create-ecdh": "^4.0.0",
+        "create-hash": "^1.1.0",
+        "create-hmac": "^1.1.0",
+        "diffie-hellman": "^5.0.0",
+        "inherits": "^2.0.1",
+        "pbkdf2": "^3.0.3",
+        "public-encrypt": "^4.0.0",
+        "randombytes": "^2.0.0",
+        "randomfill": "^1.0.3"
+      }
+    },
     "custom-event": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz",
@@ -1598,6 +1862,15 @@
       "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
       "dev": true
     },
+    "deferred-leveldown": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-0.2.0.tgz",
+      "integrity": "sha1-LO8fER4cV4cNi7uK8mUOWHzS9bQ=",
+      "dev": true,
+      "requires": {
+        "abstract-leveldown": "~0.12.1"
+      }
+    },
     "define-properties": {
       "version": "1.1.3",
       "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
@@ -1660,6 +1933,16 @@
       "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
       "dev": true
     },
+    "des.js": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz",
+      "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0"
+      }
+    },
     "dezalgo": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.3.tgz",
@@ -1682,6 +1965,25 @@
       "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
       "dev": true
     },
+    "diffie-hellman": {
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
+      "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.1.0",
+        "miller-rabin": "^4.0.0",
+        "randombytes": "^2.0.0"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.8",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+          "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+          "dev": true
+        }
+      }
+    },
     "dir-glob": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
@@ -1754,6 +2056,29 @@
       "integrity": "sha512-cuIMtJwxvzumSAkqaaoGY/L6Fc/t6YvoP9/VIaK0V/CyqKLEQ8sqODmYfy/cjXEdZ9+OOL8TecbJu+1RsofGDw==",
       "dev": true
     },
+    "elliptic": {
+      "version": "6.5.2",
+      "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz",
+      "integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.4.0",
+        "brorand": "^1.0.1",
+        "hash.js": "^1.0.0",
+        "hmac-drbg": "^1.0.0",
+        "inherits": "^2.0.1",
+        "minimalistic-assert": "^1.0.0",
+        "minimalistic-crypto-utils": "^1.0.0"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.8",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+          "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+          "dev": true
+        }
+      }
+    },
     "emoji-regex": {
       "version": "8.0.0",
       "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
@@ -1879,6 +2204,15 @@
       "integrity": "sha512-z00WIrQhtOMUnjdTG0O4f6hMG64EVccVDBy2WwgjcF8S4UB1exGYuc2OFwmdQmsJwLQVEIHWHPCz/omXXgAZHw==",
       "dev": true
     },
+    "errno": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
+      "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==",
+      "dev": true,
+      "requires": {
+        "prr": "~1.0.1"
+      }
+    },
     "es-abstract": {
       "version": "1.17.5",
       "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz",
@@ -2103,6 +2437,16 @@
       "integrity": "sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg==",
       "dev": true
     },
+    "evp_bytestokey": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
+      "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
+      "dev": true,
+      "requires": {
+        "md5.js": "^1.3.4",
+        "safe-buffer": "^5.1.1"
+      }
+    },
     "extend": {
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
@@ -2346,6 +2690,12 @@
         }
       }
     },
+    "foreach": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
+      "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=",
+      "dev": true
+    },
     "fs-extra": {
       "version": "7.0.1",
       "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
@@ -2404,6 +2754,41 @@
       "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
       "dev": true
     },
+    "fwd-stream": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/fwd-stream/-/fwd-stream-1.0.4.tgz",
+      "integrity": "sha1-7Sgcq+1G/uz5Ie4y3ExQs3KsfPo=",
+      "dev": true,
+      "requires": {
+        "readable-stream": "~1.0.26-4"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "0.0.1",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+          "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "1.0.34",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+          "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
+          "dev": true,
+          "requires": {
+            "core-util-is": "~1.0.0",
+            "inherits": "~2.0.1",
+            "isarray": "0.0.1",
+            "string_decoder": "~0.10.x"
+          }
+        },
+        "string_decoder": {
+          "version": "0.10.31",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+          "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+          "dev": true
+        }
+      }
+    },
     "gensync": {
       "version": "1.0.0-beta.1",
       "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz",
@@ -2591,12 +2976,63 @@
       "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==",
       "dev": true
     },
+    "hash-base": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz",
+      "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.4",
+        "readable-stream": "^3.6.0",
+        "safe-buffer": "^5.2.0"
+      },
+      "dependencies": {
+        "readable-stream": {
+          "version": "3.6.0",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+          "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+          "dev": true,
+          "requires": {
+            "inherits": "^2.0.3",
+            "string_decoder": "^1.1.1",
+            "util-deprecate": "^1.0.1"
+          }
+        },
+        "safe-buffer": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
+          "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==",
+          "dev": true
+        }
+      }
+    },
+    "hash.js": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz",
+      "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.3",
+        "minimalistic-assert": "^1.0.1"
+      }
+    },
     "he": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
       "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
       "dev": true
     },
+    "hmac-drbg": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
+      "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
+      "dev": true,
+      "requires": {
+        "hash.js": "^1.0.3",
+        "minimalistic-assert": "^1.0.0",
+        "minimalistic-crypto-utils": "^1.0.1"
+      }
+    },
     "hosted-git-info": {
       "version": "2.8.8",
       "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
@@ -2690,6 +3126,12 @@
         "safer-buffer": ">= 2.1.2 < 3"
       }
     },
+    "idb-wrapper": {
+      "version": "1.7.2",
+      "resolved": "https://registry.npmjs.org/idb-wrapper/-/idb-wrapper-1.7.2.tgz",
+      "integrity": "sha512-zfNREywMuf0NzDo9mVsL0yegjsirJxHpKHvWcyRozIqQy89g0a3U+oBPOCN4cc0oCiOuYgZHimzaW/R46G1Mpg==",
+      "dev": true
+    },
     "ignore": {
       "version": "4.0.6",
       "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
@@ -2820,6 +3262,12 @@
         }
       }
     },
+    "is": {
+      "version": "0.2.7",
+      "resolved": "https://registry.npmjs.org/is/-/is-0.2.7.tgz",
+      "integrity": "sha1-OzSixI81mXLzUEKEkZOucmS2NWI=",
+      "dev": true
+    },
     "is-absolute": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz",
@@ -2896,6 +3344,12 @@
       "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
       "dev": true
     },
+    "is-object": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/is-object/-/is-object-0.1.2.tgz",
+      "integrity": "sha1-AO+8CIFsM8/ErIJR0TLhDcZQmNc=",
+      "dev": true
+    },
     "is-path-cwd": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz",
@@ -3015,6 +3469,12 @@
       "integrity": "sha512-ORrEy+SNVqUhrCaal4hA4fBzhggQQ+BaLntyPOdoEiwlKZW9BZiJXjg3RMiruE4tPEI3pyVPpySHQF/dKWperg==",
       "dev": true
     },
+    "isbuffer": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/isbuffer/-/isbuffer-0.0.0.tgz",
+      "integrity": "sha1-OMFG2d9Si4v5sHAcPUPPEt8/w5s=",
+      "dev": true
+    },
     "isexe": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
@@ -3239,6 +3699,232 @@
         "flush-write-stream": "^1.0.2"
       }
     },
+    "level-blobs": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/level-blobs/-/level-blobs-0.1.7.tgz",
+      "integrity": "sha1-mrm5e7mfHtv594o0M+Ie1WOGva8=",
+      "dev": true,
+      "requires": {
+        "level-peek": "1.0.6",
+        "once": "^1.3.0",
+        "readable-stream": "^1.0.26-4"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "0.0.1",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+          "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "1.1.14",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+          "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
+          "dev": true,
+          "requires": {
+            "core-util-is": "~1.0.0",
+            "inherits": "~2.0.1",
+            "isarray": "0.0.1",
+            "string_decoder": "~0.10.x"
+          }
+        },
+        "string_decoder": {
+          "version": "0.10.31",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+          "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+          "dev": true
+        }
+      }
+    },
+    "level-filesystem": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/level-filesystem/-/level-filesystem-1.2.0.tgz",
+      "integrity": "sha1-oArKmRnEpN+v3KaoEI0iWq3/Y7M=",
+      "dev": true,
+      "requires": {
+        "concat-stream": "^1.4.4",
+        "errno": "^0.1.1",
+        "fwd-stream": "^1.0.4",
+        "level-blobs": "^0.1.7",
+        "level-peek": "^1.0.6",
+        "level-sublevel": "^5.2.0",
+        "octal": "^1.0.0",
+        "once": "^1.3.0",
+        "xtend": "^2.2.0"
+      },
+      "dependencies": {
+        "xtend": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.2.0.tgz",
+          "integrity": "sha1-7vax8ZjByN6vrYsXZaBNrUoBxak=",
+          "dev": true
+        }
+      }
+    },
+    "level-fix-range": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/level-fix-range/-/level-fix-range-1.0.2.tgz",
+      "integrity": "sha1-vxW5Fa422EcMgh6IPd95zRZCCCg=",
+      "dev": true
+    },
+    "level-hooks": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/level-hooks/-/level-hooks-4.5.0.tgz",
+      "integrity": "sha1-G5rmGSKTDzMF0aYfxNg8gQLA3ZM=",
+      "dev": true,
+      "requires": {
+        "string-range": "~1.2"
+      }
+    },
+    "level-js": {
+      "version": "2.2.4",
+      "resolved": "https://registry.npmjs.org/level-js/-/level-js-2.2.4.tgz",
+      "integrity": "sha1-vAVfQYBjXUSJtWHJSG+jcOjBFpc=",
+      "dev": true,
+      "requires": {
+        "abstract-leveldown": "~0.12.0",
+        "idb-wrapper": "^1.5.0",
+        "isbuffer": "~0.0.0",
+        "ltgt": "^2.1.2",
+        "typedarray-to-buffer": "~1.0.0",
+        "xtend": "~2.1.2"
+      },
+      "dependencies": {
+        "object-keys": {
+          "version": "0.4.0",
+          "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
+          "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=",
+          "dev": true
+        },
+        "xtend": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
+          "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=",
+          "dev": true,
+          "requires": {
+            "object-keys": "~0.4.0"
+          }
+        }
+      }
+    },
+    "level-peek": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/level-peek/-/level-peek-1.0.6.tgz",
+      "integrity": "sha1-vsUccqgu5GTTNkNMfIdsP8vM538=",
+      "dev": true,
+      "requires": {
+        "level-fix-range": "~1.0.2"
+      }
+    },
+    "level-sublevel": {
+      "version": "5.2.3",
+      "resolved": "https://registry.npmjs.org/level-sublevel/-/level-sublevel-5.2.3.tgz",
+      "integrity": "sha1-dEwSxy0ucr543eO5tc2E1iGRQTo=",
+      "dev": true,
+      "requires": {
+        "level-fix-range": "2.0",
+        "level-hooks": ">=4.4.0 <5",
+        "string-range": "~1.2.1",
+        "xtend": "~2.0.4"
+      },
+      "dependencies": {
+        "clone": {
+          "version": "0.1.19",
+          "resolved": "https://registry.npmjs.org/clone/-/clone-0.1.19.tgz",
+          "integrity": "sha1-YT+2hjmyaklKxTJT4Vsaa9iK2oU=",
+          "dev": true
+        },
+        "level-fix-range": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/level-fix-range/-/level-fix-range-2.0.0.tgz",
+          "integrity": "sha1-xBfWIVlEIVGhnZojZ4aPFyTC1Ug=",
+          "dev": true,
+          "requires": {
+            "clone": "~0.1.9"
+          }
+        },
+        "object-keys": {
+          "version": "0.2.0",
+          "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.2.0.tgz",
+          "integrity": "sha1-zd7AKZiwkb5CvxA1rjLknxy26mc=",
+          "dev": true,
+          "requires": {
+            "foreach": "~2.0.1",
+            "indexof": "~0.0.1",
+            "is": "~0.2.6"
+          }
+        },
+        "xtend": {
+          "version": "2.0.6",
+          "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.0.6.tgz",
+          "integrity": "sha1-XqZXptukRwacLlnFihE4ywxebO4=",
+          "dev": true,
+          "requires": {
+            "is-object": "~0.1.2",
+            "object-keys": "~0.2.0"
+          }
+        }
+      }
+    },
+    "levelup": {
+      "version": "0.18.6",
+      "resolved": "https://registry.npmjs.org/levelup/-/levelup-0.18.6.tgz",
+      "integrity": "sha1-5qAcsIlhbI7MApHCqb0/DETj5es=",
+      "dev": true,
+      "requires": {
+        "bl": "~0.8.1",
+        "deferred-leveldown": "~0.2.0",
+        "errno": "~0.1.1",
+        "prr": "~0.0.0",
+        "readable-stream": "~1.0.26",
+        "semver": "~2.3.1",
+        "xtend": "~3.0.0"
+      },
+      "dependencies": {
+        "isarray": {
+          "version": "0.0.1",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+          "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+          "dev": true
+        },
+        "prr": {
+          "version": "0.0.0",
+          "resolved": "https://registry.npmjs.org/prr/-/prr-0.0.0.tgz",
+          "integrity": "sha1-GoS4WQgyVQFBGFPQCB7j+obikmo=",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "1.0.34",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+          "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
+          "dev": true,
+          "requires": {
+            "core-util-is": "~1.0.0",
+            "inherits": "~2.0.1",
+            "isarray": "0.0.1",
+            "string_decoder": "~0.10.x"
+          }
+        },
+        "semver": {
+          "version": "2.3.2",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-2.3.2.tgz",
+          "integrity": "sha1-uYSPJdbPNjMwc+ye+IVtQvEjPlI=",
+          "dev": true
+        },
+        "string_decoder": {
+          "version": "0.10.31",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+          "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+          "dev": true
+        },
+        "xtend": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz",
+          "integrity": "sha1-XM50B7r2Qsunvs2laBEcST9ZZlo=",
+          "dev": true
+        }
+      }
+    },
     "levn": {
       "version": "0.3.0",
       "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
@@ -3336,6 +4022,12 @@
         "streamroller": "^1.0.6"
       }
     },
+    "ltgt": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz",
+      "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=",
+      "dev": true
+    },
     "magic-string": {
       "version": "0.25.7",
       "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
@@ -3367,6 +4059,17 @@
       "resolved": "https://registry.npmjs.org/material-design-icons-svg/-/material-design-icons-svg-3.0.0.tgz",
       "integrity": "sha512-MbHjWXGzHLPZX9qiICq3CLp0zkxaKm1uzNnrwsmThoCf5J70Lq8zSMKJMxG6uLAZB4b6evvBXrdf3C34RoRfaA=="
     },
+    "md5.js": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
+      "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
+      "dev": true,
+      "requires": {
+        "hash-base": "^3.0.0",
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      }
+    },
     "media-typer": {
       "version": "0.3.0",
       "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
@@ -3395,6 +4098,24 @@
         "picomatch": "^2.0.5"
       }
     },
+    "miller-rabin": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
+      "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.0.0",
+        "brorand": "^1.0.1"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.8",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+          "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+          "dev": true
+        }
+      }
+    },
     "mime": {
       "version": "2.4.4",
       "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz",
@@ -3422,6 +4143,18 @@
       "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
       "dev": true
     },
+    "minimalistic-assert": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
+      "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
+      "dev": true
+    },
+    "minimalistic-crypto-utils": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
+      "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=",
+      "dev": true
+    },
     "minimatch": {
       "version": "3.0.4",
       "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
@@ -3814,6 +4547,12 @@
         "es-abstract": "^1.17.0-next.1"
       }
     },
+    "octal": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/octal/-/octal-1.0.0.tgz",
+      "integrity": "sha1-Y+cWKmjvvrniE1iNWOmJ0eXEUws=",
+      "dev": true
+    },
     "on-finished": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
@@ -3936,6 +4675,20 @@
         "callsites": "^3.0.0"
       }
     },
+    "parse-asn1": {
+      "version": "5.1.5",
+      "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz",
+      "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==",
+      "dev": true,
+      "requires": {
+        "asn1.js": "^4.0.0",
+        "browserify-aes": "^1.0.0",
+        "create-hash": "^1.1.0",
+        "evp_bytestokey": "^1.0.0",
+        "pbkdf2": "^3.0.3",
+        "safe-buffer": "^5.1.1"
+      }
+    },
     "parse5": {
       "version": "5.1.1",
       "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz",
@@ -4019,6 +4772,24 @@
       "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=",
       "dev": true
     },
+    "pbkdf2": {
+      "version": "3.0.17",
+      "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz",
+      "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==",
+      "dev": true,
+      "requires": {
+        "create-hash": "^1.1.2",
+        "create-hmac": "^1.1.4",
+        "ripemd160": "^2.0.1",
+        "safe-buffer": "^5.0.1",
+        "sha.js": "^2.4.8"
+      }
+    },
+    "pdfjs-dist": {
+      "version": "2.4.456",
+      "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-2.4.456.tgz",
+      "integrity": "sha512-yckJEHq3F48hcp6wStEpbN9McOj328Ib09UrBlGAKxvN2k+qYPN5iq6TH6jD1C0pso7zTep+g/CKsYgdrQd5QA=="
+    },
     "pend": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
@@ -4058,6 +4829,12 @@
       "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
       "dev": true
     },
+    "process-es6": {
+      "version": "0.11.6",
+      "resolved": "https://registry.npmjs.org/process-es6/-/process-es6-0.11.6.tgz",
+      "integrity": "sha1-xrs4n5qVH4K9TrFpYAEFvS/5x3g=",
+      "dev": true
+    },
     "process-nextick-args": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
@@ -4075,6 +4852,34 @@
       "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
       "dev": true
     },
+    "prr": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
+      "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=",
+      "dev": true
+    },
+    "public-encrypt": {
+      "version": "4.0.3",
+      "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz",
+      "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==",
+      "dev": true,
+      "requires": {
+        "bn.js": "^4.1.0",
+        "browserify-rsa": "^4.0.0",
+        "create-hash": "^1.1.0",
+        "parse-asn1": "^5.0.0",
+        "randombytes": "^2.0.1",
+        "safe-buffer": "^5.1.2"
+      },
+      "dependencies": {
+        "bn.js": {
+          "version": "4.11.8",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+          "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==",
+          "dev": true
+        }
+      }
+    },
     "pump": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
@@ -4143,6 +4948,25 @@
       "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
       "dev": true
     },
+    "randombytes": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
+      "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "^5.1.0"
+      }
+    },
+    "randomfill": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
+      "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
+      "dev": true,
+      "requires": {
+        "randombytes": "^2.0.5",
+        "safe-buffer": "^5.1.0"
+      }
+    },
     "range-parser": {
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
@@ -4411,6 +5235,16 @@
         "glob": "^7.1.3"
       }
     },
+    "ripemd160": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
+      "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
+      "dev": true,
+      "requires": {
+        "hash-base": "^3.0.0",
+        "inherits": "^2.0.1"
+      }
+    },
     "rollup": {
       "version": "2.7.5",
       "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.7.5.tgz",
@@ -4501,6 +5335,18 @@
         }
       }
     },
+    "rollup-plugin-node-builtins": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/rollup-plugin-node-builtins/-/rollup-plugin-node-builtins-2.1.2.tgz",
+      "integrity": "sha1-JKH+1KQyV7a2Q3HYq8bOGrFFl+k=",
+      "dev": true,
+      "requires": {
+        "browserify-fs": "^1.0.0",
+        "buffer-es6": "^4.9.2",
+        "crypto-browserify": "^3.11.0",
+        "process-es6": "^0.11.2"
+      }
+    },
     "rollup-plugin-serve": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/rollup-plugin-serve/-/rollup-plugin-serve-1.0.1.tgz",
@@ -4614,6 +5460,16 @@
       "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==",
       "dev": true
     },
+    "sha.js": {
+      "version": "2.4.11",
+      "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
+      "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "safe-buffer": "^5.0.1"
+      }
+    },
     "shallow-clone": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
@@ -4931,6 +5787,12 @@
         }
       }
     },
+    "string-range": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/string-range/-/string-range-1.2.2.tgz",
+      "integrity": "sha1-qJPtNH5yKZvIO++78qaSqNI51d0=",
+      "dev": true
+    },
     "string-width": {
       "version": "4.2.0",
       "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
@@ -5255,6 +6117,12 @@
       "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
       "dev": true
     },
+    "typedarray-to-buffer": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-1.0.4.tgz",
+      "integrity": "sha1-m7i6DoQfs/TPH+fCRenz+opf6Zw=",
+      "dev": true
+    },
     "ua-parser-js": {
       "version": "0.7.21",
       "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.21.tgz",
diff --git a/package.json b/package.json
index 58ea6ce..d8b89f7 100644
--- a/package.json
+++ b/package.json
@@ -35,6 +35,7 @@
     "rollup-plugin-copy": "^3.3.0",
     "rollup-plugin-delete": "^1.2.0",
     "rollup-plugin-emit-ejs": "^3.0.0",
+    "rollup-plugin-node-builtins": "^2.1.2",
     "rollup-plugin-serve": "^1.0.1",
     "rollup-plugin-terser": "^5.2.0",
     "selfsigned": "^1.10.7"
@@ -46,6 +47,7 @@
     "jszip": "^3.4.0",
     "lit-element": "^2.3.1",
     "lit-html": "^1.2.1",
+    "pdfjs-dist": "^2.4.456",
     "source-sans-pro": "^2.45.0",
     "universal-router": "^9.0.1",
     "vpu-app-shell": "file:./vendor/app-shell",
diff --git a/rollup.config.js b/rollup.config.js
index 63eeed7..a754af8 100644
--- a/rollup.config.js
+++ b/rollup.config.js
@@ -3,6 +3,7 @@ import fs from 'fs';
 import url from 'url';
 import glob from 'glob';
 import resolve from '@rollup/plugin-node-resolve';
+import builtins from "rollup-plugin-node-builtins";
 import commonjs from '@rollup/plugin-commonjs';
 import copy from 'rollup-plugin-copy';
 import {terser} from "rollup-plugin-terser";
@@ -167,6 +168,7 @@ export default {
       format: 'esm',
       sourcemap: true
     },
+    // external: ['zlib', 'http', 'fs', 'https', 'url'],
     manualChunks: useManualChunks ? getManualChunks(pkg) : false,
     onwarn: function (warning, warn) {
         // ignore "suggestions" warning re "use strict"
@@ -218,8 +220,11 @@ export default {
           customResolveOptions: {
             // ignore node_modules from vendored packages
             moduleDirectory: path.join(process.cwd(), 'node_modules')
-          }
+          },
+          browser: true,
+          preferBuiltins: true
         }),
+        builtins(),
         commonjs({
             include: 'node_modules/**',
             namedExports: {
@@ -247,6 +252,8 @@ export default {
                 {src: 'assets/*.css', dest: 'dist/local/' + pkg.name},
                 {src: 'assets/*.ico', dest: 'dist/local/' + pkg.name},
                 {src: 'assets/*.svg', dest: 'dist/local/' + pkg.name},
+                // {src: 'assets/pdfjs/*.js', dest: 'dist/local/' + pkg.name + '/pdfjs'},
+                {src: 'node_modules/pdfjs-dist/build/pdf.worker.min.js', dest: 'dist/local/' + pkg.name + '/pdfjs'},
                 {src: 'node_modules/source-sans-pro/WOFF2/OTF/*', dest: 'dist/local/' + pkg.name + '/fonts'},
                 {src: 'node_modules/vpu-common/src/spinner.js', dest: 'dist/local/' + pkg.name, rename: 'spinner.js'},
                 {src: 'node_modules/vpu-common/misc/browser-check.js', dest: 'dist/local/' + pkg.name, rename: 'browser-check.js'},
diff --git a/src/vpu-pdf-preview.js b/src/vpu-pdf-preview.js
new file mode 100644
index 0000000..7ebc73b
--- /dev/null
+++ b/src/vpu-pdf-preview.js
@@ -0,0 +1,282 @@
+import {createI18nInstance} from './i18n.js';
+import {css, html} from 'lit-element';
+import {ScopedElementsMixin} from '@open-wc/scoped-elements';
+import VPULitElement from 'vpu-common/vpu-lit-element';
+import * as commonUtils from "vpu-common/utils";
+// import * as commonStyles from 'vpu-common/styles';
+
+// import './pdfjs/pdf';
+import pdfjs from 'pdfjs-dist';
+
+
+//import '../assets/pdfjs/pdf';
+// import pdfjsLib from './pdfjs/pdf';
+// import pdfjs from '../assets/pdfjs/pdf';
+// import zlib;
+
+// import pdfjsLib from 'pdfjs-dist';
+// import pdfjs from '../node_modules/pdfjs-dist/lib/pdf';
+// import pdfjs from '../node_modules/pdfjs-dist/build/pdf';
+
+const i18n = createI18nInstance();
+
+
+/**
+ * PdfPreview web component
+ */
+export class PdfPreview extends ScopedElementsMixin(VPULitElement) {
+    constructor() {
+        super();
+        this.lang = 'de';
+        this._PDF_DOC = null;
+        this._CURRENT_PAGE = 0;
+        this._TOTAL_PAGES = 0;
+        this._PAGE_RENDERING_IN_PROGRESS = 0;
+        this._CANVAS = null;
+    }
+
+    static get scopedElements() {
+        return {
+            // 'vpu-icon': Icon,
+        };
+    }
+
+    /**
+     * See: https://lit-element.polymer-project.org/guide/properties#initialize
+     */
+    static get properties() {
+        return {
+            lang: { type: String },
+        };
+    }
+
+
+    update(changedProperties) {
+        changedProperties.forEach((oldValue, propName) => {
+            switch (propName) {
+                case "lang":
+                    i18n.changeLanguage(this.lang);
+                    break;
+            }
+        });
+
+        super.update(changedProperties);
+    }
+
+    connectedCallback() {
+        super.connectedCallback();
+        const that = this;
+
+        // commonUtils.initAssetBaseURL('vpu-person-select-src');
+        // const select2CSS = commonUtils.getAssetURL(select2CSSPath);
+
+        // TODO: use commonUtils.getAssetURL to get correct path
+        pdfjs.GlobalWorkerOptions.workerSrc =
+            "/dist/local/vpu-signature/pdfjs/pdf.worker.min.js";
+
+        this.updateComplete.then(() => {
+            that._CANVAS = that._('#pdf-canvas');
+
+            this._('#upload-pdf-input').addEventListener('change', function() {
+                const url = URL.createObjectURL(Array.from(this.files)[0]);
+                // that.showPDF(url);
+                that.showPDF(this.files[0]);
+            });
+
+            // click on the "Previous" page button
+            this._("#pdf-prev").addEventListener('click', function() {
+                if(that._CURRENT_PAGE !== 1)
+                    that.showPage(--that._CURRENT_PAGE);
+            });
+
+            // click on the "Next" page button
+            this._("#pdf-next").addEventListener('click', function() {
+                if(that._CURRENT_PAGE !== that._TOTAL_PAGES)
+                    that.showPage(++that._CURRENT_PAGE);
+            });
+
+            // click on the "First" page button
+            this._("#pdf-first").addEventListener('click', function() {
+                that.showPage(1);
+            });
+
+            // click on the "Last" page button
+            this._("#pdf-last").addEventListener('click', function() {
+                that.showPage(that._TOTAL_PAGES);
+            });
+
+            // change on page input
+            this._("#pdf-page-no").addEventListener('input', function() {
+                const page_no = parseInt(that._("#pdf-page-no").value);
+                console.log('page_no = ', page_no);
+                if (page_no > 0 && page_no <= that._TOTAL_PAGES) {
+                    that.showPage(page_no);
+                }
+            });
+
+        });
+    }
+
+    // initialize and load the PDF
+    async showPDF(file) {
+        let reader = new FileReader();
+
+        reader.onload = async () => {
+            const data = reader.result;
+            this._("#pdf-loader").style.display = 'block';
+
+            // try {
+            //     await pdfjs.getDocument({data: pdf_url}).then((pdf) => {
+            //         console.log(pdf);
+            //         this._PDF_DOC = pdf;
+            //
+            //         // total pages in pdf
+            //         this._TOTAL_PAGES = this._PDF_DOC.numPages;
+            //
+            //         // Hide the pdf loader and show pdf container
+            //         this._("#pdf-loader").style.display = 'none';
+            //         this._("#pdf-contents").style.display = 'block';
+            //         this._("#pdf-total-pages").innerHTML = this._TOTAL_PAGES;
+            //
+            //         // show the first page
+            //         this.showPage(1);
+            //     });
+            // }
+            // catch(error) {
+            //     alert(error.message);
+            // }
+
+            // get handle of pdf document
+            try {
+                // console.log(data);
+                // this._PDF_DOC = await pdfjsLib.getDocument({ url: pdf_url });
+                // this._PDF_DOC = await pdfjs.pdfjsLib.getDocument({ url: pdf_url });
+                this._PDF_DOC = await pdfjs.getDocument({data: data}).promise;
+                // this._PDF_DOC = await pdfjs.getDocument({ url: pdf_url });
+            } catch (error) {
+                alert(error);
+            }
+
+            // total pages in pdf
+            this._TOTAL_PAGES = this._PDF_DOC.numPages;
+
+            // Hide the pdf loader and show pdf container
+            this._("#pdf-loader").style.display = 'none';
+            this._("#pdf-contents").style.display = 'block';
+            this._("#pdf-total-pages").innerHTML = this._TOTAL_PAGES;
+
+            // show the first page
+            this.showPage(1);
+        };
+
+        reader.readAsBinaryString(file);
+    }
+
+    // load and render specific page of the PDF
+    async showPage(page_no) {
+        const that = this;
+        this._PAGE_RENDERING_IN_PROGRESS = 1;
+        this._CURRENT_PAGE = page_no;
+
+        // disable Previous & Next buttons while page is being loaded
+        this._("#pdf-next").disabled = true;
+        this._("#pdf-prev").disabled = true;
+
+        // while page is being rendered hide the canvas and show a loading message
+        this._("#pdf-canvas").style.display = 'none';
+        this._("#page-loader").style.display = 'block';
+
+        // update current page
+        this._("#pdf-current-page").innerHTML = page_no;
+        this._("#pdf-page-no").value = page_no;
+
+        console.log(page_no);
+        // get handle of page
+
+        try {
+            this._PDF_DOC.getPage(page_no).then(async (page) => {
+                // you can now use *page* here
+                console.log("page");
+                console.log(page);
+
+                // original width of the pdf page at scale 1
+                var pdf_original_width = page.getViewport({ scale: 1 }).width;
+
+                // as the canvas is of a fixed width we need to adjust the scale of the viewport where page is rendered
+                var scale_required = this._CANVAS.width / pdf_original_width;
+
+                // get viewport to render the page at required scale
+                var viewport = page.getViewport({ scale: scale_required });
+
+                // set canvas height same as viewport height
+                this._CANVAS.height = viewport.height;
+
+                // setting page loader height for smooth experience
+                this._("#page-loader").style.height =  this._CANVAS.height + 'px';
+                this._("#page-loader").style.lineHeight = this._CANVAS.height + 'px';
+
+                // page is rendered on <canvas> element
+                const render_context = {
+                    canvasContext: this._CANVAS.getContext('2d'),
+                    viewport: viewport
+                };
+
+                // render the page contents in the canvas
+                try {
+                    page.render(render_context).promise.then(() => {
+                        console.log('Page rendered');
+                        that._PAGE_RENDERING_IN_PROGRESS = 0;
+
+                        // re-enable Previous & Next buttons
+                        that._("#pdf-next").disabled = false;
+                        that._("#pdf-prev").disabled = false;
+
+                        // show the canvas and hide the page loader
+                        that._("#pdf-canvas").style.display = 'block';
+                        that._("#page-loader").style.display = 'none';
+                    });
+                }
+                catch(error) {
+                    alert(error.message);
+                }
+            });
+        }
+        catch(error) {
+            alert(error.message);
+        }
+    }
+
+    static get styles() {
+        // language=css
+        return css`
+            
+        `;
+    }
+
+    render() {
+        return html`
+            <form>
+                <input type="file" name="pdf" id="upload-pdf-input">
+            </form>
+            <div id="pdf-main-container">
+                <div id="pdf-loader">Loading document ...</div>
+                <div id="pdf-contents">
+                    <div id="pdf-meta">
+                        <div id="pdf-buttons">
+                            <button id="pdf-first">First</button>
+                            <button id="pdf-prev">Previous</button>
+                            <input type="number" id="pdf-page-no">
+                            <button id="pdf-next">Next</button>
+                            <button id="pdf-last">Last</button>
+                        </div>
+                        <div id="page-count-container">Page <div id="pdf-current-page"></div> of <div id="pdf-total-pages"></div></div>
+                    </div>
+                    <canvas id="pdf-canvas" width="400"></canvas>
+                    <div id="page-loader">Loading page ...</div>
+                </div>
+            </div>
+        `;
+    }
+}
+
+commonUtils.defineCustomElement('vpu-pdf-preview', PdfPreview);
diff --git a/vendor/file-upload b/vendor/file-upload
index df74ef2..87decfd 160000
--- a/vendor/file-upload
+++ b/vendor/file-upload
@@ -1 +1 @@
-Subproject commit df74ef234eac20ab9ec2d6a03f54a746f357d675
+Subproject commit 87decfdaf136064dddff4ed357d37e68cd192733
-- 
GitLab