From ae13268a5ce2fa5074773651c9215393cda21f11 Mon Sep 17 00:00:00 2001 From: Tyler Schicke Date: Wed, 6 Mar 2019 02:46:09 -0500 Subject: Fixed rendering things --- src/client/views/nodes/DocumentView.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/client/views/nodes') diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index e01e1d4cd..1f928a3d6 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -18,6 +18,7 @@ import { ImageBox } from "../nodes/ImageBox"; import { Documents } from "../../documents/Documents" import { KeyValueBox } from "./KeyValueBox" import { WebBox } from "../nodes/WebBox"; +import { PDFNode } from "../nodes/PDFNode"; import "./DocumentView.scss"; import React = require("react"); const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this? @@ -194,7 +195,7 @@ export class DocumentView extends React.Component { } @computed get mainContent() { return Date: Wed, 6 Mar 2019 03:18:26 -0500 Subject: changed to use corsProxy and another small change --- src/client/views/nodes/PDFNode.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/client/views/nodes') diff --git a/src/client/views/nodes/PDFNode.tsx b/src/client/views/nodes/PDFNode.tsx index 755994d6d..8f29e8b4d 100644 --- a/src/client/views/nodes/PDFNode.tsx +++ b/src/client/views/nodes/PDFNode.tsx @@ -417,7 +417,7 @@ export class PDFNode extends React.Component { - + { if (element.nodeName == "DIV") { element.childNodes[0].childNodes.forEach((e) => { - if (e.nodeName == "CANVAS") { + if (e instanceof HTMLCanvasElement) { this._pdfCanvas = e; - //@ts-ignore this._pdfContext = e.getContext("2d") } -- cgit v1.2.3-70-g09d2 From 6283dcc3b7889ff431941e0bcb92591ff7a64e0e Mon Sep 17 00:00:00 2001 From: laurawilsonri Date: Wed, 6 Mar 2019 10:34:04 -0500 Subject: floating tooltip rich text menu has some basic functionality --- package-lock.json | 1404 ++++++++++---------------- package.json | 12 +- src/client/util/RichTextSchema.tsx | 223 ++++ src/client/util/TooltipTextMenu.scss | 54 + src/client/util/TooltipTextMenu.tsx | 125 +++ src/client/views/nodes/DocumentView.scss | 2 +- src/client/views/nodes/FormattedTextBox.scss | 16 +- src/client/views/nodes/FormattedTextBox.tsx | 16 +- 8 files changed, 951 insertions(+), 901 deletions(-) create mode 100644 src/client/util/RichTextSchema.tsx create mode 100644 src/client/util/TooltipTextMenu.scss create mode 100644 src/client/util/TooltipTextMenu.tsx (limited to 'src/client/views/nodes') diff --git a/package-lock.json b/package-lock.json index fe90f7b96..937715315 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,16 +20,48 @@ } }, "@fortawesome/fontawesome-common-types": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.14.tgz", - "integrity": "sha512-LOcvERCI96KioXSIfOYN4IATv2ROJOyf72dYnpoWfOIkuyLp45oMej1kL03kYdzvktLCzYhykgHwiu6nkg9Xbw==" + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.15.tgz", + "integrity": "sha512-ATBRyKJw1d2ko+0DWN9+BXau0EK3I/Q6pPzPv3LhJD7r052YFAkAdfb1Bd7ZqhBsJrdse/S7jKxWUOZ61qBD4g==" + }, + "@fortawesome/fontawesome-free-solid": { + "version": "5.0.13", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free-solid/-/fontawesome-free-solid-5.0.13.tgz", + "integrity": "sha512-b+krVnqkdDt52Yfev0x0ZZgtxBQsLw00Zfa3uaVWIDzpNZVtrEXuxldUSUaN/ihgGhSNi8VpvDAdNPVgCKOSxw==", + "requires": { + "@fortawesome/fontawesome-common-types": "^0.1.7" + }, + "dependencies": { + "@fortawesome/fontawesome-common-types": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.1.7.tgz", + "integrity": "sha512-ego8jRVSHfq/iq4KRZJKQeUAdi3ZjGNrqw4oPN3fNdvTBnLCSntwVCnc37bsAJP9UB8MhrTfPnZYxkv2vpS4pg==" + } + } }, "@fortawesome/fontawesome-svg-core": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.14.tgz", - "integrity": "sha512-T1qCqkwm9PuvK53J64D1ovfrOTa1kG+SrHNj5cFst/rrskhCnbxpRdbqFIdc/thmXC0ebBX8nOUyja2/mrxe4g==", + "version": "1.2.15", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.15.tgz", + "integrity": "sha512-M/sHyl4g2VBtKYkay1Z+XImMyTVcaBPmehYtPw4HKD9zg2E7eovB7Yx98aUfZjPbroGqa+IL4/+KhWBMOGlHIQ==", "requires": { - "@fortawesome/fontawesome-common-types": "^0.2.14" + "@fortawesome/fontawesome-common-types": "^0.2.15" + } + }, + "@fortawesome/free-solid-svg-icons": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.7.2.tgz", + "integrity": "sha512-iujcXMyAvIbWM8W3jkOLpvJbR+rPpdN1QyqhZeJaLRdHPH4JmuovIAYP4vx5Sa1csZVXfRD1eDWqVZ/jGM620A==", + "requires": { + "@fortawesome/fontawesome-common-types": "^0.2.15" + } + }, + "@fortawesome/react-fontawesome": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.4.tgz", + "integrity": "sha512-GwmxQ+TK7PEdfSwvxtGnMCqrfEm0/HbRHArbUudsYiy9KzVCwndxa2KMcfyTQ8El0vROrq8gOOff09RF1oQe8g==", + "requires": { + "humps": "^2.0.1", + "prop-types": "^15.5.10" } }, "@types/anymatch": { @@ -308,6 +340,16 @@ "@types/prosemirror-model": "*" } }, + "@types/prosemirror-schema-list": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/prosemirror-schema-list/-/prosemirror-schema-list-1.0.1.tgz", + "integrity": "sha512-+iUYq+pj2wVHSThj0MjNDzkkGwq8aDQ6j0UJK8a0cNCL8v44Ftcx1noGPtBIEUJgitH960VnfBNoTWfQoQZfRA==", + "requires": { + "@types/orderedmap": "*", + "@types/prosemirror-model": "*", + "@types/prosemirror-state": "*" + } + }, "@types/prosemirror-state": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@types/prosemirror-state/-/prosemirror-state-1.2.1.tgz", @@ -3285,11 +3327,6 @@ } } }, - "font-awesome": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz", - "integrity": "sha1-j6jPBBGhoxr9B7BtKQK7n8gVoTM=" - }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -4314,6 +4351,16 @@ "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", "dev": true }, + "humps": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/humps/-/humps-2.0.1.tgz", + "integrity": "sha1-3QLqYIG9BWjcXQcxhEY5V7qe+ao=" + }, + "i": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/i/-/i-0.3.6.tgz", + "integrity": "sha1-2WyScyB28HJxG2sQ/X1PZa2O4j0=" + }, "iconv-lite": { "version": "0.4.23", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", @@ -5925,9 +5972,9 @@ "integrity": "sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg==" }, "npm": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/npm/-/npm-6.7.0.tgz", - "integrity": "sha512-OtxCLzx+pcsjMGrjZpBp214ZjxzHcAe3zLYIlaVpRYqFHff6bgggyTLf2OZPO8lfxN0RHLJnFFUU016JCzM/Ww==", + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/npm/-/npm-6.8.0.tgz", + "integrity": "sha512-xMH6V0OCSJ5ZET6yWPI3BmJSqMMCuVJSIcLx3LSH/SrratFSt6EDuCuGRFMQYty98Q1l6x/7vKmfURosoyWgrA==", "requires": { "JSONStream": "^1.3.5", "abbrev": "~1.1.1", @@ -5998,22 +6045,22 @@ "move-concurrently": "^1.0.1", "node-gyp": "^3.8.0", "nopt": "~4.0.1", - "normalize-package-data": "~2.4.0", + "normalize-package-data": "^2.5.0", "npm-audit-report": "^1.3.2", "npm-cache-filename": "~1.0.2", "npm-install-checks": "~3.0.0", "npm-lifecycle": "^2.1.0", "npm-package-arg": "^6.1.0", - "npm-packlist": "^1.2.0", + "npm-packlist": "^1.3.0", "npm-pick-manifest": "^2.2.3", "npm-profile": "*", - "npm-registry-fetch": "^3.8.0", + "npm-registry-fetch": "^3.9.0", "npm-user-validate": "~1.0.0", "npmlog": "~4.1.2", "once": "~1.4.0", "opener": "^1.5.1", "osenv": "^0.1.5", - "pacote": "^9.4.0", + "pacote": "^9.4.1", "path-is-inside": "~1.0.2", "promise-inflight": "~1.0.1", "qrcode-terminal": "^0.12.0", @@ -6023,7 +6070,7 @@ "read-cmd-shim": "~1.0.1", "read-installed": "~4.0.3", "read-package-json": "^2.0.13", - "read-package-tree": "^5.2.1", + "read-package-tree": "^5.2.2", "readable-stream": "^3.1.1", "readdir-scoped-modules": "*", "request": "^2.88.0", @@ -6055,8 +6102,7 @@ "dependencies": { "JSONStream": { "version": "1.3.5", - "resolved": false, - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "bundled": true, "requires": { "jsonparse": "^1.2.0", "through": ">=2.2.7 <3" @@ -6064,29 +6110,25 @@ }, "abbrev": { "version": "1.1.1", - "resolved": false, - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + "bundled": true }, "agent-base": { "version": "4.2.0", - "resolved": false, - "integrity": "sha512-c+R/U5X+2zz2+UCrCFv6odQzJdoqI+YecuhnAJLa1zYaMc13zPfwMwZrr91Pd1DYNo/yPRbiM4WVf9whgwFsIg==", + "bundled": true, "requires": { "es6-promisify": "^5.0.0" } }, "agentkeepalive": { "version": "3.4.1", - "resolved": false, - "integrity": "sha512-MPIwsZU9PP9kOrZpyu2042kYA8Fdt/AedQYkYXucHgF9QoD9dXVp0ypuGnHXSR0hTstBxdt85Xkh4JolYfK5wg==", + "bundled": true, "requires": { "humanize-ms": "^1.2.1" } }, "ajv": { "version": "5.5.2", - "resolved": false, - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "bundled": true, "requires": { "co": "^4.6.0", "fast-deep-equal": "^1.0.0", @@ -6096,49 +6138,41 @@ }, "ansi-align": { "version": "2.0.0", - "resolved": false, - "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", + "bundled": true, "requires": { "string-width": "^2.0.0" } }, "ansi-regex": { "version": "2.1.1", - "resolved": false, - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + "bundled": true }, "ansi-styles": { "version": "3.2.1", - "resolved": false, - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "bundled": true, "requires": { "color-convert": "^1.9.0" } }, "ansicolors": { "version": "0.3.2", - "resolved": false, - "integrity": "sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk=" + "bundled": true }, "ansistyles": { "version": "0.1.3", - "resolved": false, - "integrity": "sha1-XeYEFb2gcbs3EnhUyGT0GyMlRTk=" + "bundled": true }, "aproba": { "version": "2.0.0", - "resolved": false, - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + "bundled": true }, "archy": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=" + "bundled": true }, "are-we-there-yet": { "version": "1.1.4", - "resolved": false, - "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=", + "bundled": true, "requires": { "delegates": "^1.0.0", "readable-stream": "^2.0.6" @@ -6146,8 +6180,7 @@ "dependencies": { "readable-stream": { "version": "2.3.6", - "resolved": false, - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "bundled": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -6160,8 +6193,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": false, - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "bundled": true, "requires": { "safe-buffer": "~5.1.0" } @@ -6170,46 +6202,38 @@ }, "asap": { "version": "2.0.6", - "resolved": false, - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + "bundled": true }, "asn1": { "version": "0.2.4", - "resolved": false, - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "bundled": true, "requires": { "safer-buffer": "~2.1.0" } }, "assert-plus": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + "bundled": true }, "asynckit": { "version": "0.4.0", - "resolved": false, - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + "bundled": true }, "aws-sign2": { "version": "0.7.0", - "resolved": false, - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + "bundled": true }, "aws4": { "version": "1.8.0", - "resolved": false, - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" + "bundled": true }, "balanced-match": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "bundled": true }, "bcrypt-pbkdf": { "version": "1.0.2", - "resolved": false, - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "bundled": true, "optional": true, "requires": { "tweetnacl": "^0.14.3" @@ -6217,8 +6241,7 @@ }, "bin-links": { "version": "1.1.2", - "resolved": false, - "integrity": "sha512-8eEHVgYP03nILphilltWjeIjMbKyJo3wvp9K816pHbhP301ismzw15mxAAEVQ/USUwcP++1uNrbERbp8lOA6Fg==", + "bundled": true, "requires": { "bluebird": "^3.5.0", "cmd-shim": "^2.0.2", @@ -6229,21 +6252,18 @@ }, "block-stream": { "version": "0.0.9", - "resolved": false, - "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", + "bundled": true, "requires": { "inherits": "~2.0.0" } }, "bluebird": { "version": "3.5.3", - "resolved": false, - "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==" + "bundled": true }, "boxen": { "version": "1.3.0", - "resolved": false, - "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", + "bundled": true, "requires": { "ansi-align": "^2.0.0", "camelcase": "^4.0.0", @@ -6256,8 +6276,7 @@ }, "brace-expansion": { "version": "1.1.11", - "resolved": false, - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "bundled": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -6265,33 +6284,23 @@ }, "buffer-from": { "version": "1.0.0", - "resolved": false, - "integrity": "sha512-83apNb8KK0Se60UE1+4Ukbe3HbfELJ6UlI4ldtOGs7So4KD26orJM8hIY9lxdzP+UpItH1Yh/Y8GUvNFWFFRxA==" - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": false, - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" + "bundled": true }, "builtins": { "version": "1.0.3", - "resolved": false, - "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=" + "bundled": true }, "byline": { "version": "5.0.0", - "resolved": false, - "integrity": "sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE=" + "bundled": true }, "byte-size": { "version": "5.0.1", - "resolved": false, - "integrity": "sha512-/XuKeqWocKsYa/cBY1YbSJSWWqTi4cFgr9S6OyM7PBaPbr9zvNGwWP33vt0uqGhwDdN+y3yhbXVILEUpnwEWGw==" + "bundled": true }, "cacache": { "version": "11.3.2", - "resolved": false, - "integrity": "sha512-E0zP4EPGDOaT2chM08Als91eYnf8Z+eH1awwwVsngUmgppfM5jjJ8l3z5vO5p5w/I3LsiXawb1sW0VY65pQABg==", + "bundled": true, "requires": { "bluebird": "^3.5.3", "chownr": "^1.1.1", @@ -6311,56 +6320,47 @@ "dependencies": { "chownr": { "version": "1.1.1", - "resolved": false, - "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==" + "bundled": true }, "lru-cache": { "version": "5.1.1", - "resolved": false, - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "bundled": true, "requires": { "yallist": "^3.0.2" } }, "unique-filename": { "version": "1.1.1", - "resolved": false, - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "bundled": true, "requires": { "unique-slug": "^2.0.0" } }, "yallist": { "version": "3.0.3", - "resolved": false, - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==" + "bundled": true } } }, "call-limit": { "version": "1.1.0", - "resolved": false, - "integrity": "sha1-b9YbA/PaQqLNDsK2DwK9DnGZH+o=" + "bundled": true }, "camelcase": { "version": "4.1.0", - "resolved": false, - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" + "bundled": true }, "capture-stack-trace": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-Sm+gc5nCa7pH8LJJa00PtAjFVQ0=" + "bundled": true }, "caseless": { "version": "0.12.0", - "resolved": false, - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + "bundled": true }, "chalk": { "version": "2.4.1", - "resolved": false, - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "bundled": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -6369,31 +6369,26 @@ }, "chownr": { "version": "1.1.1", - "resolved": false, - "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==" + "bundled": true }, "ci-info": { "version": "2.0.0", - "resolved": false, - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" + "bundled": true }, "cidr-regex": { "version": "2.0.10", - "resolved": false, - "integrity": "sha512-sB3ogMQXWvreNPbJUZMRApxuRYd+KoIo4RGQ81VatjmMW6WJPo+IJZ2846FGItr9VzKo5w7DXzijPLGtSd0N3Q==", + "bundled": true, "requires": { "ip-regex": "^2.1.0" } }, "cli-boxes": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=" + "bundled": true }, "cli-columns": { "version": "3.1.2", - "resolved": false, - "integrity": "sha1-ZzLZcpee/CrkRKHwjgj6E5yWoY4=", + "bundled": true, "requires": { "string-width": "^2.0.0", "strip-ansi": "^3.0.1" @@ -6401,8 +6396,7 @@ }, "cli-table3": { "version": "0.5.1", - "resolved": false, - "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==", + "bundled": true, "requires": { "colors": "^1.1.2", "object-assign": "^4.1.0", @@ -6411,8 +6405,7 @@ }, "cliui": { "version": "4.1.0", - "resolved": false, - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "bundled": true, "requires": { "string-width": "^2.1.1", "strip-ansi": "^4.0.0", @@ -6421,13 +6414,11 @@ "dependencies": { "ansi-regex": { "version": "3.0.0", - "resolved": false, - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + "bundled": true }, "strip-ansi": { "version": "4.0.0", - "resolved": false, - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "bundled": true, "requires": { "ansi-regex": "^3.0.0" } @@ -6436,13 +6427,11 @@ }, "clone": { "version": "1.0.4", - "resolved": false, - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=" + "bundled": true }, "cmd-shim": { "version": "2.0.2", - "resolved": false, - "integrity": "sha1-b8vamUg6j9FdfTChlspp1oii79s=", + "bundled": true, "requires": { "graceful-fs": "^4.1.2", "mkdirp": "~0.5.0" @@ -6450,37 +6439,31 @@ }, "co": { "version": "4.6.0", - "resolved": false, - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + "bundled": true }, "code-point-at": { "version": "1.1.0", - "resolved": false, - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + "bundled": true }, "color-convert": { "version": "1.9.1", - "resolved": false, - "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", + "bundled": true, "requires": { "color-name": "^1.1.1" } }, "color-name": { "version": "1.1.3", - "resolved": false, - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "bundled": true }, "colors": { "version": "1.3.3", - "resolved": false, - "integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==", + "bundled": true, "optional": true }, "columnify": { "version": "1.5.4", - "resolved": false, - "integrity": "sha1-Rzfd8ce2mop8NAVweC6UfuyOeLs=", + "bundled": true, "requires": { "strip-ansi": "^3.0.0", "wcwidth": "^1.0.0" @@ -6488,21 +6471,18 @@ }, "combined-stream": { "version": "1.0.6", - "resolved": false, - "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", + "bundled": true, "requires": { "delayed-stream": "~1.0.0" } }, "concat-map": { "version": "0.0.1", - "resolved": false, - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "bundled": true }, "concat-stream": { "version": "1.6.2", - "resolved": false, - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "bundled": true, "requires": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", @@ -6512,8 +6492,7 @@ "dependencies": { "readable-stream": { "version": "2.3.6", - "resolved": false, - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "bundled": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -6526,8 +6505,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": false, - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "bundled": true, "requires": { "safe-buffer": "~5.1.0" } @@ -6536,8 +6514,7 @@ }, "config-chain": { "version": "1.1.12", - "resolved": false, - "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==", + "bundled": true, "requires": { "ini": "^1.3.4", "proto-list": "~1.2.1" @@ -6545,8 +6522,7 @@ }, "configstore": { "version": "3.1.2", - "resolved": false, - "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", + "bundled": true, "requires": { "dot-prop": "^4.1.0", "graceful-fs": "^4.1.2", @@ -6558,13 +6534,11 @@ }, "console-control-strings": { "version": "1.1.0", - "resolved": false, - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + "bundled": true }, "copy-concurrently": { "version": "1.0.5", - "resolved": false, - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "bundled": true, "requires": { "aproba": "^1.1.1", "fs-write-stream-atomic": "^1.0.8", @@ -6576,33 +6550,28 @@ "dependencies": { "aproba": { "version": "1.2.0", - "resolved": false, - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + "bundled": true }, "iferr": { "version": "0.1.5", - "resolved": false, - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=" + "bundled": true } } }, "core-util-is": { "version": "1.0.2", - "resolved": false, - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + "bundled": true }, "create-error-class": { "version": "3.0.2", - "resolved": false, - "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", + "bundled": true, "requires": { "capture-stack-trace": "^1.0.0" } }, "cross-spawn": { "version": "5.1.0", - "resolved": false, - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "bundled": true, "requires": { "lru-cache": "^4.0.1", "shebang-command": "^1.2.0", @@ -6611,89 +6580,74 @@ }, "crypto-random-string": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=" + "bundled": true }, "cyclist": { "version": "0.2.2", - "resolved": false, - "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=" + "bundled": true }, "dashdash": { "version": "1.14.1", - "resolved": false, - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "bundled": true, "requires": { "assert-plus": "^1.0.0" } }, "debug": { "version": "3.1.0", - "resolved": false, - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "bundled": true, "requires": { "ms": "2.0.0" }, "dependencies": { "ms": { "version": "2.0.0", - "resolved": false, - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "bundled": true } } }, "debuglog": { "version": "1.0.1", - "resolved": false, - "integrity": "sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=" + "bundled": true }, "decamelize": { "version": "1.2.0", - "resolved": false, - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + "bundled": true }, "decode-uri-component": { "version": "0.2.0", - "resolved": false, - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" + "bundled": true }, "deep-extend": { "version": "0.5.1", - "resolved": false, - "integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==" + "bundled": true }, "defaults": { "version": "1.0.3", - "resolved": false, - "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "bundled": true, "requires": { "clone": "^1.0.2" } }, "delayed-stream": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + "bundled": true }, "delegates": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + "bundled": true }, "detect-indent": { "version": "5.0.0", - "resolved": false, - "integrity": "sha1-OHHMCmoALow+Wzz38zYmRnXwa50=" + "bundled": true }, "detect-newline": { "version": "2.1.0", - "resolved": false, - "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=" + "bundled": true }, "dezalgo": { "version": "1.0.3", - "resolved": false, - "integrity": "sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY=", + "bundled": true, "requires": { "asap": "^2.0.0", "wrappy": "1" @@ -6701,26 +6655,22 @@ }, "dot-prop": { "version": "4.2.0", - "resolved": false, - "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", + "bundled": true, "requires": { "is-obj": "^1.0.0" } }, "dotenv": { "version": "5.0.1", - "resolved": false, - "integrity": "sha512-4As8uPrjfwb7VXC+WnLCbXK7y+Ueb2B3zgNCePYfhxS1PYeaO1YTeplffTEcbfLhvFNGLAz90VvJs9yomG7bow==" + "bundled": true }, "duplexer3": { "version": "0.1.4", - "resolved": false, - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" + "bundled": true }, "duplexify": { "version": "3.6.0", - "resolved": false, - "integrity": "sha512-fO3Di4tBKJpYTFHAxTU00BcfWMY9w24r/x21a6rZRbsD/ToUgGxsMbiGRmB7uVAXeGKXD9MwiLZa5E97EVgIRQ==", + "bundled": true, "requires": { "end-of-stream": "^1.0.0", "inherits": "^2.0.1", @@ -6730,8 +6680,7 @@ "dependencies": { "readable-stream": { "version": "2.3.6", - "resolved": false, - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "bundled": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -6744,8 +6693,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": false, - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "bundled": true, "requires": { "safe-buffer": "~5.1.0" } @@ -6754,8 +6702,7 @@ }, "ecc-jsbn": { "version": "0.1.2", - "resolved": false, - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "bundled": true, "optional": true, "requires": { "jsbn": "~0.1.0", @@ -6764,60 +6711,51 @@ }, "editor": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-YMf4e9YrzGqJT6jM1q+3gjok90I=" + "bundled": true }, "encoding": { "version": "0.1.12", - "resolved": false, - "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "bundled": true, "requires": { "iconv-lite": "~0.4.13" } }, "end-of-stream": { "version": "1.4.1", - "resolved": false, - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "bundled": true, "requires": { "once": "^1.4.0" } }, "err-code": { "version": "1.1.2", - "resolved": false, - "integrity": "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA=" + "bundled": true }, "errno": { "version": "0.1.7", - "resolved": false, - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "bundled": true, "requires": { "prr": "~1.0.1" } }, "es6-promise": { "version": "4.2.4", - "resolved": false, - "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==" + "bundled": true }, "es6-promisify": { "version": "5.0.0", - "resolved": false, - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "bundled": true, "requires": { "es6-promise": "^4.0.3" } }, "escape-string-regexp": { "version": "1.0.5", - "resolved": false, - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + "bundled": true }, "execa": { "version": "0.7.0", - "resolved": false, - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "bundled": true, "requires": { "cross-spawn": "^5.0.1", "get-stream": "^3.0.0", @@ -6830,53 +6768,44 @@ "dependencies": { "get-stream": { "version": "3.0.0", - "resolved": false, - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" + "bundled": true } } }, "extend": { "version": "3.0.2", - "resolved": false, - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + "bundled": true }, "extsprintf": { "version": "1.3.0", - "resolved": false, - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + "bundled": true }, "fast-deep-equal": { "version": "1.1.0", - "resolved": false, - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=" + "bundled": true }, "fast-json-stable-stringify": { "version": "2.0.0", - "resolved": false, - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + "bundled": true }, "figgy-pudding": { "version": "3.5.1", - "resolved": false, - "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==" + "bundled": true }, "find-npm-prefix": { "version": "1.0.2", - "resolved": false, - "integrity": "sha512-KEftzJ+H90x6pcKtdXZEPsQse8/y/UnvzRKrOSQFprnrGaFuJ62fVkP34Iu2IYuMvyauCyoLTNkJZgrrGA2wkA==" + "bundled": true }, "find-up": { "version": "2.1.0", - "resolved": false, - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "bundled": true, "requires": { "locate-path": "^2.0.0" } }, "flush-write-stream": { "version": "1.0.3", - "resolved": false, - "integrity": "sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw==", + "bundled": true, "requires": { "inherits": "^2.0.1", "readable-stream": "^2.0.4" @@ -6884,8 +6813,7 @@ "dependencies": { "readable-stream": { "version": "2.3.6", - "resolved": false, - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "bundled": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -6898,8 +6826,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": false, - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "bundled": true, "requires": { "safe-buffer": "~5.1.0" } @@ -6908,13 +6835,11 @@ }, "forever-agent": { "version": "0.6.1", - "resolved": false, - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + "bundled": true }, "form-data": { "version": "2.3.2", - "resolved": false, - "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", + "bundled": true, "requires": { "asynckit": "^0.4.0", "combined-stream": "1.0.6", @@ -6923,8 +6848,7 @@ }, "from2": { "version": "2.3.0", - "resolved": false, - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "bundled": true, "requires": { "inherits": "^2.0.1", "readable-stream": "^2.0.0" @@ -6932,8 +6856,7 @@ "dependencies": { "readable-stream": { "version": "2.3.6", - "resolved": false, - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "bundled": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -6946,8 +6869,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": false, - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "bundled": true, "requires": { "safe-buffer": "~5.1.0" } @@ -6956,16 +6878,14 @@ }, "fs-minipass": { "version": "1.2.5", - "resolved": false, - "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", + "bundled": true, "requires": { "minipass": "^2.2.1" } }, "fs-vacuum": { "version": "1.2.10", - "resolved": false, - "integrity": "sha1-t2Kb7AekAxolSP35n17PHMizHjY=", + "bundled": true, "requires": { "graceful-fs": "^4.1.2", "path-is-inside": "^1.0.1", @@ -6974,8 +6894,7 @@ }, "fs-write-stream-atomic": { "version": "1.0.10", - "resolved": false, - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "bundled": true, "requires": { "graceful-fs": "^4.1.2", "iferr": "^0.1.5", @@ -6985,13 +6904,11 @@ "dependencies": { "iferr": { "version": "0.1.5", - "resolved": false, - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=" + "bundled": true }, "readable-stream": { "version": "2.3.6", - "resolved": false, - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "bundled": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -7004,8 +6921,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": false, - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "bundled": true, "requires": { "safe-buffer": "~5.1.0" } @@ -7014,13 +6930,11 @@ }, "fs.realpath": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "bundled": true }, "fstream": { "version": "1.0.11", - "resolved": false, - "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", + "bundled": true, "requires": { "graceful-fs": "^4.1.2", "inherits": "~2.0.0", @@ -7030,8 +6944,7 @@ }, "gauge": { "version": "2.7.4", - "resolved": false, - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "bundled": true, "requires": { "aproba": "^1.0.3", "console-control-strings": "^1.0.0", @@ -7045,13 +6958,11 @@ "dependencies": { "aproba": { "version": "1.2.0", - "resolved": false, - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + "bundled": true }, "string-width": { "version": "1.0.2", - "resolved": false, - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "bundled": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -7062,13 +6973,11 @@ }, "genfun": { "version": "5.0.0", - "resolved": false, - "integrity": "sha512-KGDOARWVga7+rnB3z9Sd2Letx515owfk0hSxHGuqjANb1M+x2bGZGqHLiozPsYMdM2OubeMni/Hpwmjq6qIUhA==" + "bundled": true }, "gentle-fs": { "version": "2.0.1", - "resolved": false, - "integrity": "sha512-cEng5+3fuARewXktTEGbwsktcldA+YsnUEaXZwcK/3pjSE1X9ObnTs+/8rYf8s+RnIcQm2D5x3rwpN7Zom8Bew==", + "bundled": true, "requires": { "aproba": "^1.1.2", "fs-vacuum": "^1.2.10", @@ -7082,41 +6991,35 @@ "dependencies": { "aproba": { "version": "1.2.0", - "resolved": false, - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + "bundled": true }, "iferr": { "version": "0.1.5", - "resolved": false, - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=" + "bundled": true } } }, "get-caller-file": { "version": "1.0.2", - "resolved": false, - "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=" + "bundled": true }, "get-stream": { "version": "4.1.0", - "resolved": false, - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "bundled": true, "requires": { "pump": "^3.0.0" } }, "getpass": { "version": "0.1.7", - "resolved": false, - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "bundled": true, "requires": { "assert-plus": "^1.0.0" } }, "glob": { "version": "7.1.3", - "resolved": false, - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "bundled": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -7128,16 +7031,14 @@ }, "global-dirs": { "version": "0.1.1", - "resolved": false, - "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", + "bundled": true, "requires": { "ini": "^1.3.4" } }, "got": { "version": "6.7.1", - "resolved": false, - "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", + "bundled": true, "requires": { "create-error-class": "^3.0.0", "duplexer3": "^0.1.4", @@ -7154,25 +7055,21 @@ "dependencies": { "get-stream": { "version": "3.0.0", - "resolved": false, - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" + "bundled": true } } }, "graceful-fs": { "version": "4.1.15", - "resolved": false, - "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" + "bundled": true }, "har-schema": { "version": "2.0.0", - "resolved": false, - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + "bundled": true }, "har-validator": { "version": "5.1.0", - "resolved": false, - "integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==", + "bundled": true, "requires": { "ajv": "^5.3.0", "har-schema": "^2.0.0" @@ -7180,28 +7077,23 @@ }, "has-flag": { "version": "3.0.0", - "resolved": false, - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + "bundled": true }, "has-unicode": { "version": "2.0.1", - "resolved": false, - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + "bundled": true }, "hosted-git-info": { "version": "2.7.1", - "resolved": false, - "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==" + "bundled": true }, "http-cache-semantics": { "version": "3.8.1", - "resolved": false, - "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==" + "bundled": true }, "http-proxy-agent": { "version": "2.1.0", - "resolved": false, - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", + "bundled": true, "requires": { "agent-base": "4", "debug": "3.1.0" @@ -7209,8 +7101,7 @@ }, "http-signature": { "version": "1.2.0", - "resolved": false, - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "bundled": true, "requires": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", @@ -7219,8 +7110,7 @@ }, "https-proxy-agent": { "version": "2.2.1", - "resolved": false, - "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", + "bundled": true, "requires": { "agent-base": "^4.1.0", "debug": "^3.1.0" @@ -7228,47 +7118,40 @@ }, "humanize-ms": { "version": "1.2.1", - "resolved": false, - "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=", + "bundled": true, "requires": { "ms": "^2.0.0" } }, "iconv-lite": { "version": "0.4.23", - "resolved": false, - "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "bundled": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" } }, "iferr": { "version": "1.0.2", - "resolved": false, - "integrity": "sha512-9AfeLfji44r5TKInjhz3W9DyZI1zR1JAf2hVBMGhddAKPqBsupb89jGfbCTHIGZd6fGZl9WlHdn4AObygyMKwg==" + "bundled": true }, "ignore-walk": { "version": "3.0.1", - "resolved": false, - "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", + "bundled": true, "requires": { "minimatch": "^3.0.4" } }, "import-lazy": { "version": "2.1.0", - "resolved": false, - "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=" + "bundled": true }, "imurmurhash": { "version": "0.1.4", - "resolved": false, - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + "bundled": true }, "inflight": { "version": "1.0.6", - "resolved": false, - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "bundled": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -7276,18 +7159,15 @@ }, "inherits": { "version": "2.0.3", - "resolved": false, - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "bundled": true }, "ini": { "version": "1.3.5", - "resolved": false, - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + "bundled": true }, "init-package-json": { "version": "1.10.3", - "resolved": false, - "integrity": "sha512-zKSiXKhQveNteyhcj1CoOP8tqp1QuxPIPBl8Bid99DGLFqA1p87M6lNgfjJHSBoWJJlidGOv5rWjyYKEB3g2Jw==", + "bundled": true, "requires": { "glob": "^7.1.1", "npm-package-arg": "^4.0.0 || ^5.0.0 || ^6.0.0", @@ -7301,62 +7181,46 @@ }, "invert-kv": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" + "bundled": true }, "ip": { "version": "1.1.5", - "resolved": false, - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" + "bundled": true }, "ip-regex": { "version": "2.1.0", - "resolved": false, - "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=" - }, - "is-builtin-module": { - "version": "1.0.0", - "resolved": false, - "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", - "requires": { - "builtin-modules": "^1.0.0" - } + "bundled": true }, "is-ci": { "version": "1.1.0", - "resolved": false, - "integrity": "sha512-c7TnwxLePuqIlxHgr7xtxzycJPegNHFuIrBkwbf8hc58//+Op1CqFkyS+xnIMkwn9UsJIwc174BIjkyBmSpjKg==", + "bundled": true, "requires": { "ci-info": "^1.0.0" }, "dependencies": { "ci-info": { "version": "1.6.0", - "resolved": false, - "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==" + "bundled": true } } }, "is-cidr": { "version": "3.0.0", - "resolved": false, - "integrity": "sha512-8Xnnbjsb0x462VoYiGlhEi+drY8SFwrHiSYuzc/CEwco55vkehTaxAyIjEdpi3EMvLPPJAJi9FlzP+h+03gp0Q==", + "bundled": true, "requires": { "cidr-regex": "^2.0.10" } }, "is-fullwidth-code-point": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "bundled": true, "requires": { "number-is-nan": "^1.0.0" } }, "is-installed-globally": { "version": "0.1.0", - "resolved": false, - "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", + "bundled": true, "requires": { "global-dirs": "^0.1.0", "is-path-inside": "^1.0.0" @@ -7364,92 +7228,75 @@ }, "is-npm": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=" + "bundled": true }, "is-obj": { "version": "1.0.1", - "resolved": false, - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" + "bundled": true }, "is-path-inside": { "version": "1.0.1", - "resolved": false, - "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "bundled": true, "requires": { "path-is-inside": "^1.0.1" } }, "is-redirect": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=" + "bundled": true }, "is-retry-allowed": { "version": "1.1.0", - "resolved": false, - "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=" + "bundled": true }, "is-stream": { "version": "1.1.0", - "resolved": false, - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + "bundled": true }, "is-typedarray": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + "bundled": true }, "isarray": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "bundled": true }, "isexe": { "version": "2.0.0", - "resolved": false, - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + "bundled": true }, "isstream": { "version": "0.1.2", - "resolved": false, - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + "bundled": true }, "jsbn": { "version": "0.1.1", - "resolved": false, - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "bundled": true, "optional": true }, "json-parse-better-errors": { "version": "1.0.2", - "resolved": false, - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" + "bundled": true }, "json-schema": { "version": "0.2.3", - "resolved": false, - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + "bundled": true }, "json-schema-traverse": { "version": "0.3.1", - "resolved": false, - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" + "bundled": true }, "json-stringify-safe": { "version": "5.0.1", - "resolved": false, - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + "bundled": true }, "jsonparse": { "version": "1.3.1", - "resolved": false, - "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=" + "bundled": true }, "jsprim": { "version": "1.4.1", - "resolved": false, - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "bundled": true, "requires": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", @@ -7459,29 +7306,25 @@ }, "latest-version": { "version": "3.1.0", - "resolved": false, - "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", + "bundled": true, "requires": { "package-json": "^4.0.0" } }, "lazy-property": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-hN3Es3Bnm6i9TNz6TAa0PVcREUc=" + "bundled": true }, "lcid": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "bundled": true, "requires": { "invert-kv": "^1.0.0" } }, "libcipm": { "version": "3.0.3", - "resolved": false, - "integrity": "sha512-71V5CpTI+zFydTc5IjJ/tx8JHbXEJvmYF2zaSVW1V3X1rRnRjXqh44iuiyry1xgi3ProUQ1vX1uwFiWs00+2og==", + "bundled": true, "requires": { "bin-links": "^1.1.2", "bluebird": "^3.5.1", @@ -7502,8 +7345,7 @@ }, "libnpm": { "version": "2.0.1", - "resolved": false, - "integrity": "sha512-qTKoxyJvpBxHZQB6k0AhSLajyXq9ZE/lUsZzuHAplr2Bpv9G+k4YuYlExYdUCeVRRGqcJt8hvkPh4tBwKoV98w==", + "bundled": true, "requires": { "bin-links": "^1.1.2", "bluebird": "^3.5.3", @@ -7529,8 +7371,7 @@ }, "libnpmaccess": { "version": "3.0.1", - "resolved": false, - "integrity": "sha512-RlZ7PNarCBt+XbnP7R6PoVgOq9t+kou5rvhaInoNibhPO7eMlRfS0B8yjatgn2yaHIwWNyoJDolC/6Lc5L/IQA==", + "bundled": true, "requires": { "aproba": "^2.0.0", "get-stream": "^4.0.0", @@ -7540,15 +7381,13 @@ "dependencies": { "aproba": { "version": "2.0.0", - "resolved": false, - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + "bundled": true } } }, "libnpmconfig": { "version": "1.2.1", - "resolved": false, - "integrity": "sha512-9esX8rTQAHqarx6qeZqmGQKBNZR5OIbl/Ayr0qQDy3oXja2iFVQQI81R6GZ2a02bSNZ9p3YOGX1O6HHCb1X7kA==", + "bundled": true, "requires": { "figgy-pudding": "^3.5.1", "find-up": "^3.0.0", @@ -7557,16 +7396,14 @@ "dependencies": { "find-up": { "version": "3.0.0", - "resolved": false, - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "bundled": true, "requires": { "locate-path": "^3.0.0" } }, "locate-path": { "version": "3.0.0", - "resolved": false, - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "bundled": true, "requires": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" @@ -7574,31 +7411,27 @@ }, "p-limit": { "version": "2.1.0", - "resolved": false, - "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", + "bundled": true, "requires": { "p-try": "^2.0.0" } }, "p-locate": { "version": "3.0.0", - "resolved": false, - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "bundled": true, "requires": { "p-limit": "^2.0.0" } }, "p-try": { "version": "2.0.0", - "resolved": false, - "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==" + "bundled": true } } }, "libnpmhook": { "version": "5.0.2", - "resolved": false, - "integrity": "sha512-vLenmdFWhRfnnZiNFPNMog6CK7Ujofy2TWiM2CrpZUjBRIhHkJeDaAbJdYCT6W4lcHtyrJR8yXW8KFyq6UAp1g==", + "bundled": true, "requires": { "aproba": "^2.0.0", "figgy-pudding": "^3.4.1", @@ -7608,8 +7441,7 @@ }, "libnpmorg": { "version": "1.0.0", - "resolved": false, - "integrity": "sha512-o+4eVJBoDGMgRwh2lJY0a8pRV2c/tQM/SxlqXezjcAg26Qe9jigYVs+Xk0vvlYDWCDhP0g74J8UwWeAgsB7gGw==", + "bundled": true, "requires": { "aproba": "^2.0.0", "figgy-pudding": "^3.4.1", @@ -7619,15 +7451,13 @@ "dependencies": { "aproba": { "version": "2.0.0", - "resolved": false, - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + "bundled": true } } }, "libnpmpublish": { "version": "1.1.1", - "resolved": false, - "integrity": "sha512-nefbvJd/wY38zdt+b9SHL6171vqBrMtZ56Gsgfd0duEKb/pB8rDT4/ObUQLrHz1tOfht1flt2zM+UGaemzAG5g==", + "bundled": true, "requires": { "aproba": "^2.0.0", "figgy-pudding": "^3.5.1", @@ -7642,8 +7472,7 @@ }, "libnpmsearch": { "version": "2.0.0", - "resolved": false, - "integrity": "sha512-vd+JWbTGzOSfiOc+72MU6y7WqmBXn49egCCrIXp27iE/88bX8EpG64ST1blWQI1bSMUr9l1AKPMVsqa2tS5KWA==", + "bundled": true, "requires": { "figgy-pudding": "^3.5.1", "get-stream": "^4.0.0", @@ -7652,8 +7481,7 @@ }, "libnpmteam": { "version": "1.0.1", - "resolved": false, - "integrity": "sha512-gDdrflKFCX7TNwOMX1snWojCoDE5LoRWcfOC0C/fqF7mBq8Uz9zWAX4B2RllYETNO7pBupBaSyBDkTAC15cAMg==", + "bundled": true, "requires": { "aproba": "^2.0.0", "figgy-pudding": "^3.4.1", @@ -7663,15 +7491,13 @@ "dependencies": { "aproba": { "version": "2.0.0", - "resolved": false, - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + "bundled": true } } }, "libnpx": { "version": "10.2.0", - "resolved": false, - "integrity": "sha512-X28coei8/XRCt15cYStbLBph+KGhFra4VQhRBPuH/HHMkC5dxM8v24RVgUsvODKCrUZ0eTgiTqJp6zbl0sskQQ==", + "bundled": true, "requires": { "dotenv": "^5.0.1", "npm-package-arg": "^6.0.0", @@ -7685,8 +7511,7 @@ }, "locate-path": { "version": "2.0.0", - "resolved": false, - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "bundled": true, "requires": { "p-locate": "^2.0.0", "path-exists": "^3.0.0" @@ -7694,8 +7519,7 @@ }, "lock-verify": { "version": "2.0.2", - "resolved": false, - "integrity": "sha512-QNVwK0EGZBS4R3YQ7F1Ox8p41Po9VGl2QG/2GsuvTbkJZYSsPeWHKMbbH6iZMCHWSMww5nrJroZYnGzI4cePuw==", + "bundled": true, "requires": { "npm-package-arg": "^5.1.2 || 6", "semver": "^5.4.1" @@ -7703,21 +7527,18 @@ }, "lockfile": { "version": "1.0.4", - "resolved": false, - "integrity": "sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA==", + "bundled": true, "requires": { "signal-exit": "^3.0.2" } }, "lodash._baseindexof": { "version": "3.1.0", - "resolved": false, - "integrity": "sha1-/lK1OhxnYeQmGNZU5KJXie1hgiw=" + "bundled": true }, "lodash._baseuniq": { "version": "4.6.0", - "resolved": false, - "integrity": "sha1-DrtE5FaBSveQXGIS+iybLVG4Qeg=", + "bundled": true, "requires": { "lodash._createset": "~4.0.0", "lodash._root": "~3.0.0" @@ -7725,71 +7546,58 @@ }, "lodash._bindcallback": { "version": "3.0.1", - "resolved": false, - "integrity": "sha1-5THCdkTPi1epnhftlbNcdIeJOS4=" + "bundled": true }, "lodash._cacheindexof": { "version": "3.0.2", - "resolved": false, - "integrity": "sha1-PcaayCSY0u5ePOVgkbr9Ktx73pI=" + "bundled": true }, "lodash._createcache": { "version": "3.1.2", - "resolved": false, - "integrity": "sha1-VtagZAF2JeeevKa4AY4XRAvc8JM=", + "bundled": true, "requires": { "lodash._getnative": "^3.0.0" } }, "lodash._createset": { "version": "4.0.3", - "resolved": false, - "integrity": "sha1-D0ZZ+7CddRlPqeK4imZE02PJ/iY=" + "bundled": true }, "lodash._getnative": { "version": "3.9.1", - "resolved": false, - "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=" + "bundled": true }, "lodash._root": { "version": "3.0.1", - "resolved": false, - "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=" + "bundled": true }, "lodash.clonedeep": { "version": "4.5.0", - "resolved": false, - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" + "bundled": true }, "lodash.restparam": { "version": "3.6.1", - "resolved": false, - "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=" + "bundled": true }, "lodash.union": { "version": "4.6.0", - "resolved": false, - "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=" + "bundled": true }, "lodash.uniq": { "version": "4.5.0", - "resolved": false, - "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=" + "bundled": true }, "lodash.without": { "version": "4.4.0", - "resolved": false, - "integrity": "sha1-PNRXSgC2e643OpS3SHcmQFB7eqw=" + "bundled": true }, "lowercase-keys": { "version": "1.0.1", - "resolved": false, - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" + "bundled": true }, "lru-cache": { "version": "4.1.5", - "resolved": false, - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "bundled": true, "requires": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" @@ -7797,16 +7605,14 @@ }, "make-dir": { "version": "1.3.0", - "resolved": false, - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "bundled": true, "requires": { "pify": "^3.0.0" } }, "make-fetch-happen": { "version": "4.0.1", - "resolved": false, - "integrity": "sha512-7R5ivfy9ilRJ1EMKIOziwrns9fGeAD4bAha8EB7BIiBBLHm2KeTUGCrICFt2rbHfzheTLynv50GnNTK1zDTrcQ==", + "bundled": true, "requires": { "agentkeepalive": "^3.4.1", "cacache": "^11.0.1", @@ -7823,52 +7629,44 @@ }, "meant": { "version": "1.0.1", - "resolved": false, - "integrity": "sha512-UakVLFjKkbbUwNWJ2frVLnnAtbb7D7DsloxRd3s/gDpI8rdv8W5Hp3NaDb+POBI1fQdeussER6NB8vpcRURvlg==" + "bundled": true }, "mem": { "version": "1.1.0", - "resolved": false, - "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "bundled": true, "requires": { "mimic-fn": "^1.0.0" } }, "mime-db": { "version": "1.35.0", - "resolved": false, - "integrity": "sha512-JWT/IcCTsB0Io3AhWUMjRqucrHSPsSf2xKLaRldJVULioggvkJvggZ3VXNNSRkCddE6D+BUI4HEIZIA2OjwIvg==" + "bundled": true }, "mime-types": { "version": "2.1.19", - "resolved": false, - "integrity": "sha512-P1tKYHVSZ6uFo26mtnve4HQFE3koh1UWVkp8YUC+ESBHe945xWSoXuHHiGarDqcEZ+whpCDnlNw5LON0kLo+sw==", + "bundled": true, "requires": { "mime-db": "~1.35.0" } }, "mimic-fn": { "version": "1.2.0", - "resolved": false, - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" + "bundled": true }, "minimatch": { "version": "3.0.4", - "resolved": false, - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "bundled": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", - "resolved": false, - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + "bundled": true }, "minipass": { "version": "2.3.3", - "resolved": false, - "integrity": "sha512-/jAn9/tEX4gnpyRATxgHEOV6xbcyxgT7iUnxo9Y3+OB0zX00TgKIv/2FZCf5brBbICcwbLqVv2ImjvWWrQMSYw==", + "bundled": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -7876,23 +7674,20 @@ "dependencies": { "yallist": { "version": "3.0.2", - "resolved": false, - "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=" + "bundled": true } } }, "minizlib": { "version": "1.1.1", - "resolved": false, - "integrity": "sha512-TrfjCjk4jLhcJyGMYymBH6oTXcWjYbUAXTHDbtnWHjZC25h0cdajHuPE1zxb4DVmu8crfh+HwH/WMuyLG0nHBg==", + "bundled": true, "requires": { "minipass": "^2.2.1" } }, "mississippi": { "version": "3.0.0", - "resolved": false, - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "bundled": true, "requires": { "concat-stream": "^1.5.0", "duplexify": "^3.4.2", @@ -7908,16 +7703,14 @@ }, "mkdirp": { "version": "0.5.1", - "resolved": false, - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "bundled": true, "requires": { "minimist": "0.0.8" } }, "move-concurrently": { "version": "1.0.1", - "resolved": false, - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "bundled": true, "requires": { "aproba": "^1.1.1", "copy-concurrently": "^1.0.0", @@ -7929,25 +7722,21 @@ "dependencies": { "aproba": { "version": "1.2.0", - "resolved": false, - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + "bundled": true } } }, "ms": { "version": "2.1.1", - "resolved": false, - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + "bundled": true }, "mute-stream": { "version": "0.0.7", - "resolved": false, - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" + "bundled": true }, "node-fetch-npm": { "version": "2.0.2", - "resolved": false, - "integrity": "sha512-nJIxm1QmAj4v3nfCvEeCrYSoVwXyxLnaPBK5W1W5DGEJwjlKuC2VEUycGw5oxk+4zZahRrB84PUJJgEmhFTDFw==", + "bundled": true, "requires": { "encoding": "^0.1.11", "json-parse-better-errors": "^1.0.0", @@ -7956,8 +7745,7 @@ }, "node-gyp": { "version": "3.8.0", - "resolved": false, - "integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==", + "bundled": true, "requires": { "fstream": "^1.0.0", "glob": "^7.0.3", @@ -7975,21 +7763,18 @@ "dependencies": { "nopt": { "version": "3.0.6", - "resolved": false, - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "bundled": true, "requires": { "abbrev": "1" } }, "semver": { "version": "5.3.0", - "resolved": false, - "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" + "bundled": true }, "tar": { "version": "2.2.1", - "resolved": false, - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "bundled": true, "requires": { "block-stream": "*", "fstream": "^1.0.2", @@ -8000,55 +7785,57 @@ }, "nopt": { "version": "4.0.1", - "resolved": false, - "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", + "bundled": true, "requires": { "abbrev": "1", "osenv": "^0.1.4" } }, "normalize-package-data": { - "version": "2.4.0", - "resolved": false, - "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "version": "2.5.0", + "bundled": true, "requires": { "hosted-git-info": "^2.1.4", - "is-builtin-module": "^1.0.0", + "resolve": "^1.10.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "resolve": { + "version": "1.10.0", + "bundled": true, + "requires": { + "path-parse": "^1.0.6" + } + } } }, "npm-audit-report": { "version": "1.3.2", - "resolved": false, - "integrity": "sha512-abeqS5ONyXNaZJPGAf6TOUMNdSe1Y6cpc9MLBRn+CuUoYbfdca6AxOyXVlfIv9OgKX+cacblbG5w7A6ccwoTPw==", + "bundled": true, "requires": { "cli-table3": "^0.5.0", "console-control-strings": "^1.1.0" } }, "npm-bundled": { - "version": "1.0.5", - "resolved": false, - "integrity": "sha512-m/e6jgWu8/v5niCUKQi9qQl8QdeEduFA96xHDDzFGqly0OOjI7c+60KM/2sppfnUU9JJagf+zs+yGhqSOFj71g==" + "version": "1.0.6", + "bundled": true }, "npm-cache-filename": { "version": "1.0.2", - "resolved": false, - "integrity": "sha1-3tMGxbC/yHCp6fr4I7xfKD4FrhE=" + "bundled": true }, "npm-install-checks": { "version": "3.0.0", - "resolved": false, - "integrity": "sha1-1K7N/VGlPjcjt7L5Oy7ijjB7wNc=", + "bundled": true, "requires": { "semver": "^2.3.0 || 3.x || 4 || 5" } }, "npm-lifecycle": { "version": "2.1.0", - "resolved": false, - "integrity": "sha512-QbBfLlGBKsktwBZLj6AviHC6Q9Y3R/AY4a2PYSIRhSKSS0/CxRyD/PfxEX6tPeOCXQgMSNdwGeECacstgptc+g==", + "bundled": true, "requires": { "byline": "^5.0.0", "graceful-fs": "^4.1.11", @@ -8062,13 +7849,11 @@ }, "npm-logical-tree": { "version": "1.2.1", - "resolved": false, - "integrity": "sha512-AJI/qxDB2PWI4LG1CYN579AY1vCiNyWfkiquCsJWqntRu/WwimVrC8yXeILBFHDwxfOejxewlmnvW9XXjMlYIg==" + "bundled": true }, "npm-package-arg": { "version": "6.1.0", - "resolved": false, - "integrity": "sha512-zYbhP2k9DbJhA0Z3HKUePUgdB1x7MfIfKssC+WLPFMKTBZKpZh5m13PgexJjCq6KW7j17r0jHWcCpxEqnnncSA==", + "bundled": true, "requires": { "hosted-git-info": "^2.6.0", "osenv": "^0.1.5", @@ -8077,9 +7862,8 @@ } }, "npm-packlist": { - "version": "1.2.0", - "resolved": false, - "integrity": "sha512-7Mni4Z8Xkx0/oegoqlcao/JpPCPEMtUvsmB0q7mgvlMinykJLSRTYuFqoQLYgGY8biuxIeiHO+QNJKbCfljewQ==", + "version": "1.3.0", + "bundled": true, "requires": { "ignore-walk": "^3.0.1", "npm-bundled": "^1.0.1" @@ -8087,8 +7871,7 @@ }, "npm-pick-manifest": { "version": "2.2.3", - "resolved": false, - "integrity": "sha512-+IluBC5K201+gRU85vFlUwX3PFShZAbAgDNp2ewJdWMVSppdo/Zih0ul2Ecky/X7b51J7LrrUAP+XOmOCvYZqA==", + "bundled": true, "requires": { "figgy-pudding": "^3.5.1", "npm-package-arg": "^6.0.0", @@ -8097,8 +7880,7 @@ }, "npm-profile": { "version": "4.0.1", - "resolved": false, - "integrity": "sha512-NQ1I/1Q7YRtHZXkcuU1/IyHeLy6pd+ScKg4+DQHdfsm769TGq6HPrkbuNJVJS4zwE+0mvvmeULzQdWn2L2EsVA==", + "bundled": true, "requires": { "aproba": "^1.1.2 || 2", "figgy-pudding": "^3.4.1", @@ -8106,9 +7888,8 @@ } }, "npm-registry-fetch": { - "version": "3.8.0", - "resolved": false, - "integrity": "sha512-hrw8UMD+Nob3Kl3h8Z/YjmKamb1gf7D1ZZch2otrIXM3uFLB5vjEY6DhMlq80z/zZet6eETLbOXcuQudCB3Zpw==", + "version": "3.9.0", + "bundled": true, "requires": { "JSONStream": "^1.3.4", "bluebird": "^3.5.1", @@ -8120,21 +7901,18 @@ }, "npm-run-path": { "version": "2.0.2", - "resolved": false, - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "bundled": true, "requires": { "path-key": "^2.0.0" } }, "npm-user-validate": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-jOyg9c6gTU6TUZ73LQVXp1Ei6VE=" + "bundled": true }, "npmlog": { "version": "4.1.2", - "resolved": false, - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "bundled": true, "requires": { "are-we-there-yet": "~1.1.2", "console-control-strings": "~1.1.0", @@ -8144,41 +7922,34 @@ }, "number-is-nan": { "version": "1.0.1", - "resolved": false, - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + "bundled": true }, "oauth-sign": { "version": "0.9.0", - "resolved": false, - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + "bundled": true }, "object-assign": { "version": "4.1.1", - "resolved": false, - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + "bundled": true }, "once": { "version": "1.4.0", - "resolved": false, - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "bundled": true, "requires": { "wrappy": "1" } }, "opener": { "version": "1.5.1", - "resolved": false, - "integrity": "sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA==" + "bundled": true }, "os-homedir": { "version": "1.0.2", - "resolved": false, - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + "bundled": true }, "os-locale": { "version": "2.1.0", - "resolved": false, - "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "bundled": true, "requires": { "execa": "^0.7.0", "lcid": "^1.0.0", @@ -8187,13 +7958,11 @@ }, "os-tmpdir": { "version": "1.0.2", - "resolved": false, - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + "bundled": true }, "osenv": { "version": "0.1.5", - "resolved": false, - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "bundled": true, "requires": { "os-homedir": "^1.0.0", "os-tmpdir": "^1.0.0" @@ -8201,34 +7970,29 @@ }, "p-finally": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" + "bundled": true }, "p-limit": { "version": "1.2.0", - "resolved": false, - "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==", + "bundled": true, "requires": { "p-try": "^1.0.0" } }, "p-locate": { "version": "2.0.0", - "resolved": false, - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "bundled": true, "requires": { "p-limit": "^1.1.0" } }, "p-try": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" + "bundled": true }, "package-json": { "version": "4.0.1", - "resolved": false, - "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", + "bundled": true, "requires": { "got": "^6.7.1", "registry-auth-token": "^3.0.1", @@ -8237,9 +8001,8 @@ } }, "pacote": { - "version": "9.4.0", - "resolved": false, - "integrity": "sha512-WQ1KL/phGMkedYEQx9ODsjj7xvwLSpdFJJdEXrLyw5SILMxcTNt5DTxT2Z93fXuLFYJBlZJdnwdalrQdB/rX5w==", + "version": "9.4.1", + "bundled": true, "requires": { "bluebird": "^3.5.3", "cacache": "^11.3.2", @@ -8272,16 +8035,14 @@ "dependencies": { "lru-cache": { "version": "5.1.1", - "resolved": false, - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "bundled": true, "requires": { "yallist": "^3.0.2" } }, "minipass": { "version": "2.3.5", - "resolved": false, - "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", + "bundled": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -8289,15 +8050,13 @@ }, "yallist": { "version": "3.0.3", - "resolved": false, - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==" + "bundled": true } } }, "parallel-transform": { "version": "1.1.0", - "resolved": false, - "integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=", + "bundled": true, "requires": { "cyclist": "~0.2.2", "inherits": "^2.0.3", @@ -8306,8 +8065,7 @@ "dependencies": { "readable-stream": { "version": "2.3.6", - "resolved": false, - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "bundled": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -8320,8 +8078,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": false, - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "bundled": true, "requires": { "safe-buffer": "~5.1.0" } @@ -8330,53 +8087,47 @@ }, "path-exists": { "version": "3.0.0", - "resolved": false, - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + "bundled": true }, "path-is-absolute": { "version": "1.0.1", - "resolved": false, - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + "bundled": true }, "path-is-inside": { "version": "1.0.2", - "resolved": false, - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=" + "bundled": true }, "path-key": { "version": "2.0.1", - "resolved": false, - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + "bundled": true + }, + "path-parse": { + "version": "1.0.6", + "bundled": true }, "performance-now": { "version": "2.1.0", - "resolved": false, - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + "bundled": true }, "pify": { "version": "3.0.0", - "resolved": false, - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" + "bundled": true }, "prepend-http": { "version": "1.0.4", - "resolved": false, - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" + "bundled": true }, "process-nextick-args": { "version": "2.0.0", - "resolved": false, - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + "bundled": true }, "promise-inflight": { "version": "1.0.1", - "resolved": false, - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=" + "bundled": true }, "promise-retry": { "version": "1.1.1", - "resolved": false, - "integrity": "sha1-ZznpaOMFHaIM5kl/srUPaRHfPW0=", + "bundled": true, "requires": { "err-code": "^1.0.0", "retry": "^0.10.0" @@ -8384,51 +8135,43 @@ "dependencies": { "retry": { "version": "0.10.1", - "resolved": false, - "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=" + "bundled": true } } }, "promzard": { "version": "0.3.0", - "resolved": false, - "integrity": "sha1-JqXW7ox97kyxIggwWs+5O6OCqe4=", + "bundled": true, "requires": { "read": "1" } }, "proto-list": { "version": "1.2.4", - "resolved": false, - "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=" + "bundled": true }, "protoduck": { "version": "5.0.1", - "resolved": false, - "integrity": "sha512-WxoCeDCoCBY55BMvj4cAEjdVUFGRWed9ZxPlqTKYyw1nDDTQ4pqmnIMAGfJlg7Dx35uB/M+PHJPTmGOvaCaPTg==", + "bundled": true, "requires": { "genfun": "^5.0.0" } }, "prr": { "version": "1.0.1", - "resolved": false, - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" + "bundled": true }, "pseudomap": { "version": "1.0.2", - "resolved": false, - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + "bundled": true }, "psl": { "version": "1.1.29", - "resolved": false, - "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==" + "bundled": true }, "pump": { "version": "3.0.0", - "resolved": false, - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "bundled": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -8436,8 +8179,7 @@ }, "pumpify": { "version": "1.5.1", - "resolved": false, - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "bundled": true, "requires": { "duplexify": "^3.6.0", "inherits": "^2.0.3", @@ -8446,8 +8188,7 @@ "dependencies": { "pump": { "version": "2.0.1", - "resolved": false, - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "bundled": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -8457,23 +8198,19 @@ }, "punycode": { "version": "1.4.1", - "resolved": false, - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + "bundled": true }, "qrcode-terminal": { "version": "0.12.0", - "resolved": false, - "integrity": "sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ==" + "bundled": true }, "qs": { "version": "6.5.2", - "resolved": false, - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + "bundled": true }, "query-string": { "version": "6.2.0", - "resolved": false, - "integrity": "sha512-5wupExkIt8RYL4h/FE+WTg3JHk62e6fFPWtAZA9J5IWK1PfTfKkMS93HBUHcFpeYi9KsY5pFbh+ldvEyaz5MyA==", + "bundled": true, "requires": { "decode-uri-component": "^0.2.0", "strict-uri-encode": "^2.0.0" @@ -8481,13 +8218,11 @@ }, "qw": { "version": "1.0.1", - "resolved": false, - "integrity": "sha1-77/cdA+a0FQwRCassYNBLMi5ltQ=" + "bundled": true }, "rc": { "version": "1.2.7", - "resolved": false, - "integrity": "sha512-LdLD8xD4zzLsAT5xyushXDNscEjB7+2ulnl8+r1pnESlYtlJtVSoCMBGr30eDRJ3+2Gq89jK9P9e4tCEH1+ywA==", + "bundled": true, "requires": { "deep-extend": "^0.5.1", "ini": "~1.3.0", @@ -8497,31 +8232,27 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": false, - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + "bundled": true } } }, "read": { "version": "1.0.7", - "resolved": false, - "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", + "bundled": true, "requires": { "mute-stream": "~0.0.4" } }, "read-cmd-shim": { "version": "1.0.1", - "resolved": false, - "integrity": "sha1-LV0Vd4ajfAVdIgd8MsU/gynpHHs=", + "bundled": true, "requires": { "graceful-fs": "^4.1.2" } }, "read-installed": { "version": "4.0.3", - "resolved": false, - "integrity": "sha1-/5uLZ/GH0eTCm5/rMfayI6zRkGc=", + "bundled": true, "requires": { "debuglog": "^1.0.1", "graceful-fs": "^4.1.2", @@ -8534,8 +8265,7 @@ }, "read-package-json": { "version": "2.0.13", - "resolved": false, - "integrity": "sha512-/1dZ7TRZvGrYqE0UAfN6qQb5GYBsNcqS1C0tNK601CFOJmtHI7NIGXwetEPU/OtoFHZL3hDxm4rolFFVE9Bnmg==", + "bundled": true, "requires": { "glob": "^7.1.1", "graceful-fs": "^4.1.2", @@ -8545,9 +8275,8 @@ } }, "read-package-tree": { - "version": "5.2.1", - "resolved": false, - "integrity": "sha512-2CNoRoh95LxY47LvqrehIAfUVda2JbuFE/HaGYs42bNrGG+ojbw1h3zOcPcQ+1GQ3+rkzNndZn85u1XyZ3UsIA==", + "version": "5.2.2", + "bundled": true, "requires": { "debuglog": "^1.0.1", "dezalgo": "^1.0.0", @@ -8558,8 +8287,7 @@ }, "readable-stream": { "version": "3.1.1", - "resolved": false, - "integrity": "sha512-DkN66hPyqDhnIQ6Jcsvx9bFjhw214O4poMBcIMgPVpQvNy9a0e0Uhg5SqySyDKAmUlwt8LonTBz1ezOnM8pUdA==", + "bundled": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -8568,8 +8296,7 @@ }, "readdir-scoped-modules": { "version": "1.0.2", - "resolved": false, - "integrity": "sha1-n6+jfShr5dksuuve4DDcm19AZ0c=", + "bundled": true, "requires": { "debuglog": "^1.0.1", "dezalgo": "^1.0.0", @@ -8579,8 +8306,7 @@ }, "registry-auth-token": { "version": "3.3.2", - "resolved": false, - "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==", + "bundled": true, "requires": { "rc": "^1.1.6", "safe-buffer": "^5.0.1" @@ -8588,16 +8314,14 @@ }, "registry-url": { "version": "3.1.0", - "resolved": false, - "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", + "bundled": true, "requires": { "rc": "^1.0.1" } }, "request": { "version": "2.88.0", - "resolved": false, - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "bundled": true, "requires": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", @@ -8623,79 +8347,66 @@ }, "require-directory": { "version": "2.1.1", - "resolved": false, - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + "bundled": true }, "require-main-filename": { "version": "1.0.1", - "resolved": false, - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" + "bundled": true }, "resolve-from": { "version": "4.0.0", - "resolved": false, - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" + "bundled": true }, "retry": { "version": "0.12.0", - "resolved": false, - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=" + "bundled": true }, "rimraf": { "version": "2.6.3", - "resolved": false, - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "bundled": true, "requires": { "glob": "^7.1.3" } }, "run-queue": { "version": "1.0.3", - "resolved": false, - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "bundled": true, "requires": { "aproba": "^1.1.1" }, "dependencies": { "aproba": { "version": "1.2.0", - "resolved": false, - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + "bundled": true } } }, "safe-buffer": { "version": "5.1.2", - "resolved": false, - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "bundled": true }, "safer-buffer": { "version": "2.1.2", - "resolved": false, - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "bundled": true }, "semver": { "version": "5.6.0", - "resolved": false, - "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" + "bundled": true }, "semver-diff": { "version": "2.1.0", - "resolved": false, - "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", + "bundled": true, "requires": { "semver": "^5.0.3" } }, "set-blocking": { "version": "2.0.0", - "resolved": false, - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + "bundled": true }, "sha": { "version": "2.0.1", - "resolved": false, - "integrity": "sha1-YDCCL70smCOUn49y7WQR7lzyWq4=", + "bundled": true, "requires": { "graceful-fs": "^4.1.2", "readable-stream": "^2.0.2" @@ -8703,8 +8414,7 @@ "dependencies": { "readable-stream": { "version": "2.3.6", - "resolved": false, - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "bundled": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -8717,8 +8427,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": false, - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "bundled": true, "requires": { "safe-buffer": "~5.1.0" } @@ -8727,41 +8436,34 @@ }, "shebang-command": { "version": "1.2.0", - "resolved": false, - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "bundled": true, "requires": { "shebang-regex": "^1.0.0" } }, "shebang-regex": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + "bundled": true }, "signal-exit": { "version": "3.0.2", - "resolved": false, - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + "bundled": true }, "slash": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=" + "bundled": true }, "slide": { "version": "1.1.6", - "resolved": false, - "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=" + "bundled": true }, "smart-buffer": { "version": "4.0.1", - "resolved": false, - "integrity": "sha512-RFqinRVJVcCAL9Uh1oVqE6FZkqsyLiVOYEZ20TqIOjuX7iFVJ+zsbs4RIghnw/pTs7mZvt8ZHhvm1ZUrR4fykg==" + "bundled": true }, "socks": { "version": "2.2.0", - "resolved": false, - "integrity": "sha512-uRKV9uXQ9ytMbGm2+DilS1jB7N3AC0mmusmW5TVWjNuBZjxS8+lX38fasKVY9I4opv/bY/iqTbcpFFaTwpfwRg==", + "bundled": true, "requires": { "ip": "^1.1.5", "smart-buffer": "^4.0.1" @@ -8769,8 +8471,7 @@ }, "socks-proxy-agent": { "version": "4.0.1", - "resolved": false, - "integrity": "sha512-Kezx6/VBguXOsEe5oU3lXYyKMi4+gva72TwJ7pQY5JfqUx2nMk7NXA6z/mpNqIlfQjWYVfeuNvQjexiTaTn6Nw==", + "bundled": true, "requires": { "agent-base": "~4.2.0", "socks": "~2.2.0" @@ -8778,13 +8479,11 @@ }, "sorted-object": { "version": "2.0.1", - "resolved": false, - "integrity": "sha1-fWMfS9OnmKJK8d/8+/6DM3pd9fw=" + "bundled": true }, "sorted-union-stream": { "version": "2.1.3", - "resolved": false, - "integrity": "sha1-x3lMfgd4gAUv9xqNSi27Sppjisc=", + "bundled": true, "requires": { "from2": "^1.3.0", "stream-iterate": "^1.1.0" @@ -8792,8 +8491,7 @@ "dependencies": { "from2": { "version": "1.3.0", - "resolved": false, - "integrity": "sha1-iEE7qqX5pZfP3pIh2GmGzTwGHf0=", + "bundled": true, "requires": { "inherits": "~2.0.1", "readable-stream": "~1.1.10" @@ -8801,13 +8499,11 @@ }, "isarray": { "version": "0.0.1", - "resolved": false, - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + "bundled": true }, "readable-stream": { "version": "1.1.14", - "resolved": false, - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "bundled": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", @@ -8817,15 +8513,13 @@ }, "string_decoder": { "version": "0.10.31", - "resolved": false, - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + "bundled": true } } }, "spdx-correct": { "version": "3.0.0", - "resolved": false, - "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", + "bundled": true, "requires": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" @@ -8833,13 +8527,11 @@ }, "spdx-exceptions": { "version": "2.1.0", - "resolved": false, - "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==" + "bundled": true }, "spdx-expression-parse": { "version": "3.0.0", - "resolved": false, - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "bundled": true, "requires": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" @@ -8847,13 +8539,11 @@ }, "spdx-license-ids": { "version": "3.0.3", - "resolved": false, - "integrity": "sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g==" + "bundled": true }, "sshpk": { "version": "1.14.2", - "resolved": false, - "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=", + "bundled": true, "requires": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -8868,16 +8558,14 @@ }, "ssri": { "version": "6.0.1", - "resolved": false, - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "bundled": true, "requires": { "figgy-pudding": "^3.5.1" } }, "stream-each": { "version": "1.2.2", - "resolved": false, - "integrity": "sha512-mc1dbFhGBxvTM3bIWmAAINbqiuAk9TATcfIQC8P+/+HJefgaiTlMn2dHvkX8qlI12KeYKSQ1Ua9RrIqrn1VPoA==", + "bundled": true, "requires": { "end-of-stream": "^1.1.0", "stream-shift": "^1.0.0" @@ -8885,8 +8573,7 @@ }, "stream-iterate": { "version": "1.2.0", - "resolved": false, - "integrity": "sha1-K9fHcpbBcCpGSIuK1B95hl7s1OE=", + "bundled": true, "requires": { "readable-stream": "^2.1.5", "stream-shift": "^1.0.0" @@ -8894,8 +8581,7 @@ "dependencies": { "readable-stream": { "version": "2.3.6", - "resolved": false, - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "bundled": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -8908,8 +8594,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": false, - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "bundled": true, "requires": { "safe-buffer": "~5.1.0" } @@ -8918,18 +8603,15 @@ }, "stream-shift": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=" + "bundled": true }, "strict-uri-encode": { "version": "2.0.0", - "resolved": false, - "integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY=" + "bundled": true }, "string-width": { "version": "2.1.1", - "resolved": false, - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "bundled": true, "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" @@ -8937,18 +8619,15 @@ "dependencies": { "ansi-regex": { "version": "3.0.0", - "resolved": false, - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + "bundled": true }, "is-fullwidth-code-point": { "version": "2.0.0", - "resolved": false, - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" + "bundled": true }, "strip-ansi": { "version": "4.0.0", - "resolved": false, - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "bundled": true, "requires": { "ansi-regex": "^3.0.0" } @@ -8957,47 +8636,40 @@ }, "string_decoder": { "version": "1.2.0", - "resolved": false, - "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==", + "bundled": true, "requires": { "safe-buffer": "~5.1.0" } }, "stringify-package": { "version": "1.0.0", - "resolved": false, - "integrity": "sha512-JIQqiWmLiEozOC0b0BtxZ/AOUtdUZHCBPgqIZ2kSJJqGwgb9neo44XdTHUC4HZSGqi03hOeB7W/E8rAlKnGe9g==" + "bundled": true }, "strip-ansi": { "version": "3.0.1", - "resolved": false, - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "bundled": true, "requires": { "ansi-regex": "^2.0.0" } }, "strip-eof": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" + "bundled": true }, "strip-json-comments": { "version": "2.0.1", - "resolved": false, - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + "bundled": true }, "supports-color": { "version": "5.4.0", - "resolved": false, - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "bundled": true, "requires": { "has-flag": "^3.0.0" } }, "tar": { "version": "4.4.8", - "resolved": false, - "integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==", + "bundled": true, "requires": { "chownr": "^1.1.1", "fs-minipass": "^1.2.5", @@ -9010,13 +8682,11 @@ "dependencies": { "chownr": { "version": "1.1.1", - "resolved": false, - "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==" + "bundled": true }, "minipass": { "version": "2.3.5", - "resolved": false, - "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", + "bundled": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -9024,33 +8694,28 @@ }, "yallist": { "version": "3.0.3", - "resolved": false, - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==" + "bundled": true } } }, "term-size": { "version": "1.2.0", - "resolved": false, - "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", + "bundled": true, "requires": { "execa": "^0.7.0" } }, "text-table": { "version": "0.2.0", - "resolved": false, - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + "bundled": true }, "through": { "version": "2.3.8", - "resolved": false, - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + "bundled": true }, "through2": { "version": "2.0.3", - "resolved": false, - "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "bundled": true, "requires": { "readable-stream": "^2.1.5", "xtend": "~4.0.1" @@ -9058,8 +8723,7 @@ "dependencies": { "readable-stream": { "version": "2.3.6", - "resolved": false, - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "bundled": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -9072,8 +8736,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": false, - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "bundled": true, "requires": { "safe-buffer": "~5.1.0" } @@ -9082,18 +8745,15 @@ }, "timed-out": { "version": "4.0.1", - "resolved": false, - "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=" + "bundled": true }, "tiny-relative-date": { "version": "1.3.0", - "resolved": false, - "integrity": "sha512-MOQHpzllWxDCHHaDno30hhLfbouoYlOI8YlMNtvKe1zXbjEVhbcEovQxvZrPvtiYW630GQDoMMarCnjfyfHA+A==" + "bundled": true }, "tough-cookie": { "version": "2.4.3", - "resolved": false, - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "bundled": true, "requires": { "psl": "^1.1.24", "punycode": "^1.4.1" @@ -9101,71 +8761,60 @@ }, "tunnel-agent": { "version": "0.6.0", - "resolved": false, - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "bundled": true, "requires": { "safe-buffer": "^5.0.1" } }, "tweetnacl": { "version": "0.14.5", - "resolved": false, - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "bundled": true, "optional": true }, "typedarray": { "version": "0.0.6", - "resolved": false, - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + "bundled": true }, "uid-number": { "version": "0.0.6", - "resolved": false, - "integrity": "sha1-DqEOgDXo61uOREnwbaHHMGY7qoE=" + "bundled": true }, "umask": { "version": "1.1.0", - "resolved": false, - "integrity": "sha1-8pzr8B31F5ErtY/5xOUP3o4zMg0=" + "bundled": true }, "unique-filename": { "version": "1.1.1", - "resolved": false, - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "bundled": true, "requires": { "unique-slug": "^2.0.0" } }, "unique-slug": { "version": "2.0.0", - "resolved": false, - "integrity": "sha1-22Z258fMBimHj/GWCXx4hVrp9Ks=", + "bundled": true, "requires": { "imurmurhash": "^0.1.4" } }, "unique-string": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "bundled": true, "requires": { "crypto-random-string": "^1.0.0" } }, "unpipe": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + "bundled": true }, "unzip-response": { "version": "2.0.1", - "resolved": false, - "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=" + "bundled": true }, "update-notifier": { "version": "2.5.0", - "resolved": false, - "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", + "bundled": true, "requires": { "boxen": "^1.2.1", "chalk": "^2.0.1", @@ -9181,31 +8830,26 @@ }, "url-parse-lax": { "version": "1.0.0", - "resolved": false, - "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "bundled": true, "requires": { "prepend-http": "^1.0.1" } }, "util-deprecate": { "version": "1.0.2", - "resolved": false, - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + "bundled": true }, "util-extend": { "version": "1.0.3", - "resolved": false, - "integrity": "sha1-p8IW0mdUUWljeztu3GypEZ4v+T8=" + "bundled": true }, "uuid": { "version": "3.3.2", - "resolved": false, - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + "bundled": true }, "validate-npm-package-license": { "version": "3.0.4", - "resolved": false, - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "bundled": true, "requires": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" @@ -9213,16 +8857,14 @@ }, "validate-npm-package-name": { "version": "3.0.0", - "resolved": false, - "integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=", + "bundled": true, "requires": { "builtins": "^1.0.3" } }, "verror": { "version": "1.10.0", - "resolved": false, - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "bundled": true, "requires": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", @@ -9231,37 +8873,32 @@ }, "wcwidth": { "version": "1.0.1", - "resolved": false, - "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "bundled": true, "requires": { "defaults": "^1.0.3" } }, "which": { "version": "1.3.1", - "resolved": false, - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "bundled": true, "requires": { "isexe": "^2.0.0" } }, "which-module": { "version": "2.0.0", - "resolved": false, - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + "bundled": true }, "wide-align": { "version": "1.1.2", - "resolved": false, - "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==", + "bundled": true, "requires": { "string-width": "^1.0.2" }, "dependencies": { "string-width": { "version": "1.0.2", - "resolved": false, - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "bundled": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -9272,24 +8909,21 @@ }, "widest-line": { "version": "2.0.0", - "resolved": false, - "integrity": "sha1-AUKk6KJD+IgsAjOqDgKBqnYVInM=", + "bundled": true, "requires": { "string-width": "^2.1.1" } }, "worker-farm": { "version": "1.6.0", - "resolved": false, - "integrity": "sha512-6w+3tHbM87WnSWnENBUvA2pxJPLhQUg5LKwUQHq3r+XPhIM+Gh2R5ycbwPCyuGbNg+lPgdcnQUhuC02kJCvffQ==", + "bundled": true, "requires": { "errno": "~0.1.7" } }, "wrap-ansi": { "version": "2.1.0", - "resolved": false, - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "bundled": true, "requires": { "string-width": "^1.0.1", "strip-ansi": "^3.0.1" @@ -9297,8 +8931,7 @@ "dependencies": { "string-width": { "version": "1.0.2", - "resolved": false, - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "bundled": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -9309,13 +8942,11 @@ }, "wrappy": { "version": "1.0.2", - "resolved": false, - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "bundled": true }, "write-file-atomic": { "version": "2.4.2", - "resolved": false, - "integrity": "sha512-s0b6vB3xIVRLWywa6X9TOMA7k9zio0TMOsl9ZnDkliA/cfJlpHXAscj0gbHVJiTdIuAYpIyqS5GW91fqm6gG5g==", + "bundled": true, "requires": { "graceful-fs": "^4.1.11", "imurmurhash": "^0.1.4", @@ -9324,28 +8955,23 @@ }, "xdg-basedir": { "version": "3.0.0", - "resolved": false, - "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=" + "bundled": true }, "xtend": { "version": "4.0.1", - "resolved": false, - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" + "bundled": true }, "y18n": { "version": "4.0.0", - "resolved": false, - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" + "bundled": true }, "yallist": { "version": "2.1.2", - "resolved": false, - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + "bundled": true }, "yargs": { "version": "11.0.0", - "resolved": false, - "integrity": "sha512-Rjp+lMYQOWtgqojx1dEWorjCofi1YN7AoFvYV7b1gx/7dAAeuI4kN5SZiEvr0ZmsZTOpDRcCqrpI10L31tFkBw==", + "bundled": true, "requires": { "cliui": "^4.0.0", "decamelize": "^1.1.1", @@ -9363,15 +8989,13 @@ "dependencies": { "y18n": { "version": "3.2.1", - "resolved": false, - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" + "bundled": true } } }, "yargs-parser": { "version": "9.0.2", - "resolved": false, - "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", + "bundled": true, "requires": { "camelcase": "^4.1.0" } @@ -10430,14 +10054,6 @@ "scheduler": "^0.12.0" } }, - "react-fontawesome": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/react-fontawesome/-/react-fontawesome-1.6.1.tgz", - "integrity": "sha1-7dzhfn3HMaoJ/UoYZoimF5OhbFw=", - "requires": { - "prop-types": "^15.5.6" - } - }, "react-golden-layout": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/react-golden-layout/-/react-golden-layout-1.0.6.tgz", diff --git a/package.json b/package.json index 8568a7bef..ad1cda94e 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,10 @@ "webpack-hot-middleware": "^2.24.3" }, "dependencies": { - "@fortawesome/fontawesome-svg-core": "^1.2.14", + "@fortawesome/fontawesome-free-solid": "^5.0.13", + "@fortawesome/fontawesome-svg-core": "^1.2.15", + "@fortawesome/free-solid-svg-icons": "^5.7.2", + "@fortawesome/react-fontawesome": "^0.1.4", "@types/bcrypt-nodejs": "0.0.30", "@types/bluebird": "^3.5.25", "@types/body-parser": "^1.17.0", @@ -53,6 +56,7 @@ "@types/prosemirror-keymap": "^1.0.1", "@types/prosemirror-model": "^1.7.0", "@types/prosemirror-schema-basic": "^1.0.1", + "@types/prosemirror-schema-list": "^1.0.1", "@types/prosemirror-state": "^1.2.1", "@types/prosemirror-transform": "^1.1.0", "@types/prosemirror-view": "^1.3.0", @@ -76,6 +80,7 @@ "expressjs": "^1.0.1", "flexlayout-react": "^0.3.3", "golden-layout": "^1.5.9", + "i": "^0.3.6", "jsonwebtoken": "^8.4.0", "jsx-to-string": "^1.4.0", "lodash": "^4.17.11", @@ -87,7 +92,7 @@ "node-sass": "^4.11.0", "nodemon": "^1.18.10", "normalize.css": "^8.0.1", - "npm": "^6.7.0", + "npm": "^6.8.0", "passport": "^0.4.0", "passport-local": "^1.0.0", "prosemirror-commands": "^1.0.7", @@ -96,6 +101,7 @@ "prosemirror-keymap": "^1.0.1", "prosemirror-model": "^1.7.0", "prosemirror-schema-basic": "^1.0.0", + "prosemirror-schema-list": "^1.0.2", "prosemirror-state": "^1.2.2", "prosemirror-transform": "^1.1.3", "prosemirror-view": "^1.7.1", @@ -116,4 +122,4 @@ "url-loader": "^1.1.2", "uuid": "^3.3.2" } -} \ No newline at end of file +} diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx new file mode 100644 index 000000000..abf448c9f --- /dev/null +++ b/src/client/util/RichTextSchema.tsx @@ -0,0 +1,223 @@ +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { Schema, NodeSpec, MarkSpec, DOMOutputSpecArray } from "prosemirror-model" +import { joinUp, lift, setBlockType, toggleMark, wrapIn } from 'prosemirror-commands' +import { redo, undo } from 'prosemirror-history' +import { orderedList, bulletList, listItem } from 'prosemirror-schema-list' + +const pDOM: DOMOutputSpecArray = ["p", 0], blockquoteDOM: DOMOutputSpecArray = ["blockquote", 0], hrDOM: DOMOutputSpecArray = ["hr"], + preDOM: DOMOutputSpecArray = ["pre", ["code", 0]], brDOM: DOMOutputSpecArray = ["br"], ulDOM: DOMOutputSpecArray = ["ul", 0] + +// :: Object +// [Specs](#model.NodeSpec) for the nodes defined in this schema. +export const nodes: { [index: string]: NodeSpec } = { + // :: NodeSpec The top level document node. + doc: { + content: "block+" + }, + + // :: NodeSpec A plain paragraph textblock. Represented in the DOM + // as a `

` element. + paragraph: { + content: "inline*", + group: "block", + parseDOM: [{ tag: "p" }], + toDOM() { return pDOM } + }, + + // :: NodeSpec A blockquote (`

`) wrapping one or more blocks. + blockquote: { + content: "block+", + group: "block", + defining: true, + parseDOM: [{ tag: "blockquote" }], + toDOM() { return blockquoteDOM } + }, + + // :: NodeSpec A horizontal rule (`
`). + horizontal_rule: { + group: "block", + parseDOM: [{ tag: "hr" }], + toDOM() { return hrDOM } + }, + + // :: NodeSpec A heading textblock, with a `level` attribute that + // should hold the number 1 to 6. Parsed and serialized as `

` to + // `

` elements. + heading: { + attrs: { level: { default: 1 } }, + content: "inline*", + group: "block", + defining: true, + parseDOM: [{ tag: "h1", attrs: { level: 1 } }, + { tag: "h2", attrs: { level: 2 } }, + { tag: "h3", attrs: { level: 3 } }, + { tag: "h4", attrs: { level: 4 } }, + { tag: "h5", attrs: { level: 5 } }, + { tag: "h6", attrs: { level: 6 } }], + toDOM(node: any) { return ["h" + node.attrs.level, 0] } + }, + + // :: NodeSpec A code listing. Disallows marks or non-text inline + // nodes by default. Represented as a `
` element with a
+  // `` element inside of it.
+  code_block: {
+    content: "text*",
+    marks: "",
+    group: "block",
+    code: true,
+    defining: true,
+    parseDOM: [{ tag: "pre", preserveWhitespace: "full" }],
+    toDOM() { return preDOM }
+  },
+
+  // :: NodeSpec The text node.
+  text: {
+    group: "inline"
+  },
+
+  // :: NodeSpec An inline image (``) node. Supports `src`,
+  // `alt`, and `href` attributes. The latter two default to the empty
+  // string.
+  image: {
+    inline: true,
+    attrs: {
+      src: {},
+      alt: { default: null },
+      title: { default: null }
+    },
+    group: "inline",
+    draggable: true,
+    parseDOM: [{
+      tag: "img[src]", getAttrs(dom: any) {
+        return {
+          src: dom.getAttribute("src"),
+          title: dom.getAttribute("title"),
+          alt: dom.getAttribute("alt")
+        }
+      }
+    }],
+    toDOM(node: any) { return ["img", node.attrs] }
+  },
+
+  // :: NodeSpec A hard line break, represented in the DOM as `
`. + hard_break: { + inline: true, + group: "inline", + selectable: false, + parseDOM: [{ tag: "br" }], + toDOM() { return brDOM } + }, + + ordered_list: { + ...orderedList, + content: 'list_item+', + group: 'block' + }, + bullet_list: { + content: 'list_item+', + group: 'block', + parseDOM: [{ tag: "ul" }, { style: "list-style-type=disc;" }], + toDOM() { return ulDOM } + }, + list_item: { + ...listItem, + content: 'paragraph block*' + } +} + +const emDOM: DOMOutputSpecArray = ["em", 0]; +const strongDOM: DOMOutputSpecArray = ["strong", 0]; +const codeDOM: DOMOutputSpecArray = ["code", 0]; +const underlineDOM: DOMOutputSpecArray = ["underline", 0]; + +// :: Object [Specs](#model.MarkSpec) for the marks in the schema. +export const marks: { [index: string]: MarkSpec } = { + // :: MarkSpec A link. Has `href` and `title` attributes. `title` + // defaults to the empty string. Rendered and parsed as an `` + // element. + link: { + attrs: { + href: {}, + title: { default: null } + }, + inclusive: false, + parseDOM: [{ + tag: "a[href]", getAttrs(dom: any) { + return { href: dom.getAttribute("href"), title: dom.getAttribute("title") } + } + }], + toDOM(node: any) { return ["a", node.attrs, 0] } + }, + + // :: MarkSpec An emphasis mark. Rendered as an `` element. + // Has parse rules that also match `` and `font-style: italic`. + em: { + parseDOM: [{ tag: "i" }, { tag: "em" }, { style: "font-style=italic" }], + toDOM() { return emDOM } + }, + + // :: MarkSpec A strong mark. Rendered as ``, parse rules + // also match `` and `font-weight: bold`. + strong: { + parseDOM: [{ tag: "strong" }, + { tag: "b" }, + { style: "font-weight" }], + toDOM() { return strongDOM } + }, + + underline: { + parseDOM: [ + { tag: 'u' }, + { style: 'text-decoration=underline' } + ], + toDOM: () => ['span', { + style: 'text-decoration:underline' + }] + }, + + strikethrough: { + parseDOM: [ + { tag: 'strike' }, + { style: 'text-decoration=line-through' }, + { style: 'text-decoration-line=line-through' } + ], + toDOM: () => ['span', { + style: 'text-decoration-line:line-through' + }] + }, + + subscript: { + excludes: 'superscript', + parseDOM: [ + { tag: 'sub' }, + { style: 'vertical-align=sub' } + ], + toDOM: () => ['sub'] + }, + + superscript: { + excludes: 'subscript', + parseDOM: [ + { tag: 'sup' }, + { style: 'vertical-align=super' } + ], + toDOM: () => ['sup'] + }, + + + // :: MarkSpec Code font mark. Represented as a `` element. + code: { + parseDOM: [{ tag: "code" }], + toDOM() { return codeDOM } + } +} + +// :: Schema +// This schema rougly corresponds to the document schema used by +// [CommonMark](http://commonmark.org/), minus the list elements, +// which are defined in the [`prosemirror-schema-list`](#schema-list) +// module. +// +// To reuse elements from this schema, extend or read from its +// `spec.nodes` and `spec.marks` [properties](#model.Schema.spec). +export const schema = new Schema({ nodes, marks }) \ No newline at end of file diff --git a/src/client/util/TooltipTextMenu.scss b/src/client/util/TooltipTextMenu.scss new file mode 100644 index 000000000..fa43f5326 --- /dev/null +++ b/src/client/util/TooltipTextMenu.scss @@ -0,0 +1,54 @@ + +.tooltipMenu { + position: absolute; + z-index: 20; + background: rgb(19, 18, 18); + border: 1px solid silver; + border-radius: 4px; + padding: 2px 10px; + margin-bottom: 7px; + -webkit-transform: translateX(-50%); + transform: translateX(-50%); +} + +.tooltipMenu:before { + content: ""; + height: 0; width: 0; + position: absolute; + left: 50%; + margin-left: -5px; + bottom: -6px; + border: 5px solid transparent; + border-bottom-width: 0; + border-top-color: silver; + } + .tooltipMenu:after { + content: ""; + height: 0; width: 0; + position: absolute; + left: 50%; + margin-left: -5px; + bottom: -4.5px; + border: 5px solid transparent; + border-bottom-width: 0; + border-top-color: black; + } + + .menuicon { + display: inline-block; + border-right: 1px solid rgba(0, 0, 0, 0.2); + //color: rgb(19, 18, 18); + color: white; + line-height: 1; + padding: 0px 2px; + margin: 1px; + cursor: pointer; + text-align: center; + min-width: 10px; + } + .strong, .heading { font-weight: bold; } + .em { font-style: italic; } + .underline {text-decoration: underline} + .superscript {vertical-align:super} + .subscript { vertical-align:sub } + .strikethrough {text-decoration-line:line-through} \ No newline at end of file diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx new file mode 100644 index 000000000..3b87fe9de --- /dev/null +++ b/src/client/util/TooltipTextMenu.tsx @@ -0,0 +1,125 @@ +import { action, IReactionDisposer, reaction } from "mobx"; +import { baseKeymap } from "prosemirror-commands"; +import { history, redo, undo } from "prosemirror-history"; +import { keymap } from "prosemirror-keymap"; +const { exampleSetup } = require("prosemirror-example-setup") +import { EditorState, Transaction, } from "prosemirror-state"; +import { EditorView } from "prosemirror-view"; +import { schema } from "./RichTextSchema"; +import React = require("react") +import "./TooltipTextMenu.scss"; +const { toggleMark, setBlockType, wrapIn } = require("prosemirror-commands"); +import { library } from '@fortawesome/fontawesome-svg-core' +import { wrapInList, bulletList } from 'prosemirror-schema-list' +import { + faListUl, +} from '@fortawesome/free-solid-svg-icons'; + + + +export class TooltipTextMenu { + + private tooltip: HTMLElement; + + constructor(view: EditorView) { + this.tooltip = document.createElement("div"); + this.tooltip.className = "tooltipMenu"; + + //add the div which is the tooltip + view.dom.parentNode!.appendChild(this.tooltip); + + //add additional icons + library.add(faListUl); + + //add the buttons to the tooltip + let items = [ + { command: toggleMark(schema.marks.strong), dom: this.icon("B", "strong") }, + { command: toggleMark(schema.marks.em), dom: this.icon("i", "em") }, + { command: toggleMark(schema.marks.underline), dom: this.icon("U", "underline") }, + { command: toggleMark(schema.marks.strikethrough), dom: this.icon("S", "strikethrough") }, + { command: toggleMark(schema.marks.superscript), dom: this.icon("s", "superscript") }, + { command: toggleMark(schema.marks.subscript), dom: this.icon("s", "subscript") }, + { command: wrapInList(schema.nodes.bullet_list), dom: this.icon(":", "bullets") } + ] + items.forEach(({ dom }) => this.tooltip.appendChild(dom)); + + //pointer down handler to activate button effects + this.tooltip.addEventListener("pointerdown", e => { + e.preventDefault(); + view.focus(); + items.forEach(({ command, dom }) => { + if (dom.contains(e.srcElement)) { + command(view.state, view.dispatch, view) + } + }) + }) + + this.update(view, undefined); + } + + // Helper function to create menu icons + icon(text: string, name: string) { + let span = document.createElement("span"); + span.className = "menuicon " + name; + span.title = name; + span.textContent = text; + return span; + } + + blockActive(view: EditorView) { + const { $from, to } = view.state.selection + + return to <= $from.end() && $from.parent.hasMarkup(schema.nodes.bulletList); + } + + //this doesn't currently work but hopefully will soon + unorderedListIcon(): HTMLSpanElement { + let span = document.createElement("span"); + let icon = document.createElement("FontAwesomeIcon"); + icon.className = "menuicon fa fa-smile-o"; + span.appendChild(icon); + return span; + } + + // Create an icon for a heading at the given level + heading(level: number) { + return { + command: setBlockType(schema.nodes.heading, { level }), + dom: this.icon("H" + level, "heading") + } + } + + //updates the tooltip menu when the selection changes + update(view: EditorView, lastState: EditorState | undefined) { + let state = view.state + // Don't do anything if the document/selection didn't change + if (lastState && lastState.doc.eq(state.doc) && + lastState.selection.eq(state.selection)) return + + // Hide the tooltip if the selection is empty + if (state.selection.empty) { + this.tooltip.style.display = "none" + return + } + + // Otherwise, reposition it and update its content + this.tooltip.style.display = "" + let { from, to } = state.selection + // These are in screen coordinates + //check this - tranform + let start = view.coordsAtPos(from), end = view.coordsAtPos(to) + // The box in which the tooltip is positioned, to use as base + let box = this.tooltip.offsetParent!.getBoundingClientRect() + // Find a center-ish x position from the selection endpoints (when + // crossing lines, end may be more to the left) + let left = Math.max((start.left + end.left) / 2, start.left + 3) + this.tooltip.style.left = (left - box.left) + "px" + let width = Math.abs(start.left - end.left) / 2; + let mid = Math.min(start.left, end.left) + width; + //THIS WIDTH IS 15 * NUMBER OF ICONS + 15 + this.tooltip.style.width = 120 + "px"; + this.tooltip.style.bottom = (box.bottom - start.top) + "px"; + } + + destroy() { this.tooltip.remove() } +} \ No newline at end of file diff --git a/src/client/views/nodes/DocumentView.scss b/src/client/views/nodes/DocumentView.scss index 8e2ebd690..ab913897b 100644 --- a/src/client/views/nodes/DocumentView.scss +++ b/src/client/views/nodes/DocumentView.scss @@ -1,7 +1,7 @@ .documentView-node { position: absolute; background: #cdcdcd; - overflow: hidden; + //overflow: hidden; &.minimized { width: 30px; height: 30px; diff --git a/src/client/views/nodes/FormattedTextBox.scss b/src/client/views/nodes/FormattedTextBox.scss index 21bd43b6e..cddbef6be 100644 --- a/src/client/views/nodes/FormattedTextBox.scss +++ b/src/client/views/nodes/FormattedTextBox.scss @@ -17,4 +17,18 @@ overflow-x: hidden; color: initial; height: 100%; -} \ No newline at end of file +} + +.menuicon { + display: inline-block; + border-right: 1px solid rgba(0, 0, 0, 0.2); + color: #888; + line-height: 1; + padding: 0 7px; + margin: 1px; + cursor: pointer; + text-align: center; + min-width: 1.4em; + } + .strong, .heading { font-weight: bold; } + .em { font-style: italic; } \ No newline at end of file diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx index a92821ed6..a0f662f18 100644 --- a/src/client/views/nodes/FormattedTextBox.tsx +++ b/src/client/views/nodes/FormattedTextBox.tsx @@ -2,8 +2,7 @@ import { action, IReactionDisposer, reaction } from "mobx"; import { baseKeymap } from "prosemirror-commands"; import { history, redo, undo } from "prosemirror-history"; import { keymap } from "prosemirror-keymap"; -const { exampleSetup } = require("prosemirror-example-setup") -import { schema } from "prosemirror-schema-basic"; +import { schema } from "../../util/RichTextSchema"; import { EditorState, Transaction, } from "prosemirror-state"; import { EditorView } from "prosemirror-view"; import { Opt, FieldWaiting, FieldValue } from "../../../fields/Field"; @@ -14,6 +13,7 @@ import { RichTextField } from "../../../fields/RichTextField"; import { FieldViewProps, FieldView } from "./FieldView"; import { Plugin } from 'prosemirror-state' import { Decoration, DecorationSet } from 'prosemirror-view' +import { TooltipTextMenu } from "../../util/TooltipTextMenu" @@ -61,12 +61,15 @@ export class FormattedTextBox extends React.Component { componentDidMount() { let state: EditorState; const { doc, fieldKey } = this.props; + + // let mySchema = new Schema({ nodes, marks }) const config = { schema, plugins: [ history(), keymap({ "Mod-z": undo, "Mod-y": redo }), keymap(baseKeymap), + this.tooltipMenuPlugin() ] }; @@ -127,6 +130,15 @@ export class FormattedTextBox extends React.Component { onPointerWheel = (e: React.WheelEvent): void => { e.stopPropagation(); } + + tooltipMenuPlugin() { + return new Plugin({ + view(_editorView) { + return new TooltipTextMenu(_editorView) + } + }) + } + render() { return (
Date: Wed, 6 Mar 2019 12:30:28 -0500 Subject: fixed to work analogous to images --- src/client/documents/Documents.ts | 12 ++-- src/client/views/Main.tsx | 4 +- .../views/collections/CollectionFreeFormView.tsx | 5 +- src/client/views/nodes/ImageBox.tsx | 14 ++-- src/client/views/nodes/PDFNode.tsx | 79 ++++++++++++---------- 5 files changed, 65 insertions(+), 49 deletions(-) (limited to 'src/client/views/nodes') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 94e1cb8dd..d2183c90f 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -40,8 +40,9 @@ export namespace Documents { let webProto: Document; let collProto: Document; let kvpProto: Document; + let pdfProto: Document; const textProtoId = "textProto"; - const pdfProtoId = "textProto"; + const pdfProtoId = "pdfProto"; const imageProtoId = "imageProto"; const webProtoId = "webProto"; const collProtoId = "collectionProto"; @@ -96,9 +97,12 @@ export namespace Documents { { x: 0, y: 0, width: 300, height: 150, layoutKeys: [KeyStore.Data] }); } function GetPdfPrototype(): Document { - return textProto ? textProto : - textProto = setupPrototypeOptions(pdfProtoId, "PDF_PROTO", PDFNode.LayoutString(), - { x: 0, y: 0, width: 300, height: 150, layoutKeys: [KeyStore.Data] }); + if (!pdfProto) { + pdfProto = setupPrototypeOptions(pdfProtoId, "PDF_PROTO", CollectionView.LayoutString("AnnotationsKey"), + { x: 0, y: 0, nativeWidth: 300, nativeHeight: 300, width: 300, layoutKeys: [KeyStore.Data, KeyStore.Annotations] }); + pdfProto.SetText(KeyStore.BackgroundLayout, PDFNode.LayoutString()); + } + return pdfProto; } function GetWebPrototype(): Document { return webProto ? webProto : diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index bbf315052..abacb258e 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -51,7 +51,7 @@ Documents.initProtos(mainDocId, (res?: Document) => { } let imgurl = "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg"; - let pdfurl = "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg" + let pdfurl = "http://www.adobe.com/support/products/enterprise/knowledgecenter/media/c4611_sample_explain.pdf" let weburl = "https://cs.brown.edu/courses/cs166/"; let clearDatabase = action(() => Utils.Emit(Server.Socket, MessageStore.DeleteAll, {})) let addTextNode = action(() => Documents.TextDocument({ width: 200, height: 200, title: "a text note" })) @@ -66,7 +66,7 @@ Documents.initProtos(mainDocId, (res?: Document) => { ); let imgRef = React.createRef(); - let pdfRef = React.createRef(); + let pdfRef = React.createRef(); let webRef = React.createRef(); let textRef = React.createRef(); let schemaRef = React.createRef(); diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx index 1a7349201..285d515cd 100644 --- a/src/client/views/collections/CollectionFreeFormView.tsx +++ b/src/client/views/collections/CollectionFreeFormView.tsx @@ -15,6 +15,7 @@ import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocum import { DocumentView } from "../nodes/DocumentView"; import { FormattedTextBox } from "../nodes/FormattedTextBox"; import { ImageBox } from "../nodes/ImageBox"; +import { PDFNode } from "../nodes/PDFNode"; import { WebBox } from "../nodes/WebBox"; import { KeyValueBox } from "../nodes/KeyValueBox" import "./CollectionFreeFormView.scss"; @@ -246,7 +247,7 @@ export class CollectionFreeFormView extends CollectionViewBase { get backgroundView() { return !this.backgroundLayout ? (null) : ( { diff --git a/src/client/views/nodes/PDFNode.tsx b/src/client/views/nodes/PDFNode.tsx index 8f29e8b4d..4749ed101 100644 --- a/src/client/views/nodes/PDFNode.tsx +++ b/src/client/views/nodes/PDFNode.tsx @@ -1,17 +1,17 @@ +import { action, observable } from 'mobx'; +import { observer } from "mobx-react"; +import Measure from "react-measure"; import 'react-image-lightbox/style.css'; -import "./ImageBox.scss"; -import React = require("react") -import { observer } from "mobx-react" -import { observable, action } from 'mobx'; -import 'react-pdf/dist/Page/AnnotationLayer.css' //@ts-ignore -import { Document, Page, PDFPageProxy, PageAnnotation } from "react-pdf"; +import { Document, Page } from "react-pdf"; +import 'react-pdf/dist/Page/AnnotationLayer.css'; import { Utils } from '../../../Utils'; -import { Sticky } from './Sticky'; //you should look at sticky and annotation, because they are used here import { Annotation } from './Annotation'; -import { ObjectPositionProperty } from 'csstype'; -import { keydownHandler } from 'prosemirror-keymap'; -import { FieldViewProps, FieldView } from './FieldView'; +import { FieldView, FieldViewProps } from './FieldView'; +import "./ImageBox.scss"; +import { Sticky } from './Sticky'; //you should look at sticky and annotation, because they are used here +import React = require("react") +import { KeyStore } from '../../../fields/KeyStore'; /** ALSO LOOK AT: Annotation.tsx, Sticky.tsx * This method renders PDF and puts all kinds of functionalities such as annotation, highlighting, @@ -390,6 +390,11 @@ export class PDFNode extends React.Component { } + @action + setScaling = (r: any) => { + this.props.doc.SetNumber(KeyStore.NativeWidth, r.entry.width); + this.props.doc.SetNumber(KeyStore.NativeHeight, r.entry.height); + } render() { return (
{ - { - if (this._mainDiv.current) { - this._mainDiv.current.childNodes.forEach((element) => { - if (element.nodeName == "DIV") { - element.childNodes[0].childNodes.forEach((e) => { - - if (e instanceof HTMLCanvasElement) { - this._pdfCanvas = e; - this._pdfContext = e.getContext("2d") - - } - - }) + + {({ measureRef }) => +
+ { + if (this._mainDiv.current) { + this._mainDiv.current.childNodes.forEach((element) => { + if (element.nodeName == "DIV") { + element.childNodes[0].childNodes.forEach((e) => { + + if (e instanceof HTMLCanvasElement) { + this._pdfCanvas = e; + this._pdfContext = e.getContext("2d") + + } + + }) + } + }) + } + this.numPage = page.transport.numPages + if (this.perPage.length == 0) { //Makes sure it only runs once + this.perPage = [...Array(this.numPage)] + } } - }) - } - this.numPage = page.transport.numPages - if (this.perPage.length == 0) { //Makes sure it only runs once - this.perPage = [...Array(this.numPage)] - } - } + } + /> +
} - /> +
); -- cgit v1.2.3-70-g09d2 From d724a248442184415d4591fedebe1060b3e12278 Mon Sep 17 00:00:00 2001 From: bob Date: Wed, 6 Mar 2019 12:40:17 -0500 Subject: from last --- src/client/views/nodes/PDFNode.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/client/views/nodes') diff --git a/src/client/views/nodes/PDFNode.tsx b/src/client/views/nodes/PDFNode.tsx index 4749ed101..16afdccd8 100644 --- a/src/client/views/nodes/PDFNode.tsx +++ b/src/client/views/nodes/PDFNode.tsx @@ -397,7 +397,7 @@ export class PDFNode extends React.Component { } render() { return ( -
@@ -425,7 +425,7 @@ export class PDFNode extends React.Component { {({ measureRef }) => -
+
Date: Wed, 6 Mar 2019 17:59:15 -0500 Subject: fixed render size of pdfs & changed note backrounds contextually. --- src/client/documents/Documents.ts | 2 +- .../views/collections/CollectionFreeFormView.scss | 28 +++++- .../views/collections/CollectionFreeFormView.tsx | 6 +- src/client/views/collections/CollectionView.tsx | 2 +- src/client/views/nodes/FormattedTextBox.scss | 8 +- src/client/views/nodes/PDFNode.scss | 9 ++ src/client/views/nodes/PDFNode.tsx | 109 ++++++++++++--------- 7 files changed, 111 insertions(+), 53 deletions(-) create mode 100644 src/client/views/nodes/PDFNode.scss (limited to 'src/client/views/nodes') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index d2183c90f..47b8ea844 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -99,7 +99,7 @@ export namespace Documents { function GetPdfPrototype(): Document { if (!pdfProto) { pdfProto = setupPrototypeOptions(pdfProtoId, "PDF_PROTO", CollectionView.LayoutString("AnnotationsKey"), - { x: 0, y: 0, nativeWidth: 300, nativeHeight: 300, width: 300, layoutKeys: [KeyStore.Data, KeyStore.Annotations] }); + { x: 0, y: 0, nativeWidth: 600, width: 300, layoutKeys: [KeyStore.Data, KeyStore.Annotations] }); pdfProto.SetText(KeyStore.BackgroundLayout, PDFNode.LayoutString()); } return pdfProto; diff --git a/src/client/views/collections/CollectionFreeFormView.scss b/src/client/views/collections/CollectionFreeFormView.scss index f432e8cc3..fb9394d59 100644 --- a/src/client/views/collections/CollectionFreeFormView.scss +++ b/src/client/views/collections/CollectionFreeFormView.scss @@ -1,9 +1,35 @@ .collectionfreeformview-container { + .collectionfreeformview > .jsx-parser{ + position:absolute; + height: 100%; + } + + border-style: solid; + box-sizing: border-box; + position: relative; + top: 0; + left: 0; + width: 100%; + height: 100%; + overflow: hidden; + .collectionfreeformview { + position: absolute; + top: 0; + left: 0; + width:100%; + height: 100%; + } +} +.collectionfreeformview-overlay { + .collectionfreeformview > .jsx-parser{ position:absolute; height: 100%; } + .formattedTextBox-cont { + background:yellow; + } border-style: solid; box-sizing: border-box; @@ -18,7 +44,7 @@ top: 0; left: 0; width:100%; - height: 100% + height: 100%; } } diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx index 285d515cd..be5784b32 100644 --- a/src/client/views/collections/CollectionFreeFormView.tsx +++ b/src/client/views/collections/CollectionFreeFormView.tsx @@ -67,8 +67,8 @@ export class CollectionFreeFormView extends CollectionViewBase { @action onPointerDown = (e: React.PointerEvent): void => { - if ((e.button === 2 && this.props.active()) || - !e.defaultPrevented) { + if (((e.button === 2 && this.props.active()) || + !e.defaultPrevented) && (!this.isAnnotationOverlay || this.zoomScaling != 1 || e.button == 0)) { document.removeEventListener("pointermove", this.onPointerMove); document.addEventListener("pointermove", this.onPointerMove); document.removeEventListener("pointerup", this.onPointerUp); @@ -292,7 +292,7 @@ export class CollectionFreeFormView extends CollectionViewBase { const pany: number = -this.props.Document.GetNumber(KeyStore.PanY, 0); return ( -
{ subView =
break; } - return (
+ return (
{subView}
) } diff --git a/src/client/views/nodes/FormattedTextBox.scss b/src/client/views/nodes/FormattedTextBox.scss index 21bd43b6e..3e21f34de 100644 --- a/src/client/views/nodes/FormattedTextBox.scss +++ b/src/client/views/nodes/FormattedTextBox.scss @@ -11,8 +11,12 @@ .formattedTextBox-cont { background: white; padding: 1; - border: black; - border-width: 10; + border-width: 1px; + border-radius: 2px; + border-color:black; + box-sizing: border-box; + background: white; + border-style:solid; overflow-y: scroll; overflow-x: hidden; color: initial; diff --git a/src/client/views/nodes/PDFNode.scss b/src/client/views/nodes/PDFNode.scss new file mode 100644 index 000000000..f4935cba9 --- /dev/null +++ b/src/client/views/nodes/PDFNode.scss @@ -0,0 +1,9 @@ +.react-pdf__Page { + transform-origin: left top; + //transform: scale(0.2, 0.2); + position: absolute; +} +.pdfButton-Tray { + position:absolute; + z-index: 25; +} \ No newline at end of file diff --git a/src/client/views/nodes/PDFNode.tsx b/src/client/views/nodes/PDFNode.tsx index 16afdccd8..b80283065 100644 --- a/src/client/views/nodes/PDFNode.tsx +++ b/src/client/views/nodes/PDFNode.tsx @@ -12,6 +12,9 @@ import "./ImageBox.scss"; import { Sticky } from './Sticky'; //you should look at sticky and annotation, because they are used here import React = require("react") import { KeyStore } from '../../../fields/KeyStore'; +import "./PDFNode.scss"; +import { PDFField } from '../../../fields/PDFField'; +import { FieldWaiting } from '../../../fields/Field'; /** ALSO LOOK AT: Annotation.tsx, Sticky.tsx * This method renders PDF and puts all kinds of functionalities such as annotation, highlighting, @@ -392,10 +395,21 @@ export class PDFNode extends React.Component { @action setScaling = (r: any) => { - this.props.doc.SetNumber(KeyStore.NativeWidth, r.entry.width); - this.props.doc.SetNumber(KeyStore.NativeHeight, r.entry.height); + // bcz: the nativeHeight should really be set when the document is imported. + // also, the native dimensions could be different for different pages of the PDF + // so this design is flawed. + var nativeWidth = this.props.doc.GetNumber(KeyStore.NativeWidth, 0); + if (!this.props.doc.GetNumber(KeyStore.NativeHeight, 0)) { + this.props.doc.SetNumber(KeyStore.NativeHeight, nativeWidth * r.entry.height / r.entry.width); + } } render() { + const renderHeight = 2400; + let xf = this.props.doc.GetNumber(KeyStore.NativeHeight, 0) / renderHeight; + var pdfUrl = this.props.doc.GetT(this.props.fieldKey, PDFField); + if (!pdfUrl || pdfUrl == FieldWaiting) { + return (null); + } return (
{ return element })} - - - - - - - - - - - - - {({ measureRef }) => -
- { - if (this._mainDiv.current) { - this._mainDiv.current.childNodes.forEach((element) => { - if (element.nodeName == "DIV") { - element.childNodes[0].childNodes.forEach((e) => { - - if (e instanceof HTMLCanvasElement) { - this._pdfCanvas = e; - this._pdfContext = e.getContext("2d") - - } - - }) - } - }) - } - this.numPage = page.transport.numPages - if (this.perPage.length == 0) { //Makes sure it only runs once - this.perPage = [...Array(this.numPage)] +
+ + + + + + + + + +
+ +
+ + + {({ measureRef }) => +
+ { + if (this._mainDiv.current) { + this._mainDiv.current.childNodes.forEach((element) => { + if (element.nodeName == "DIV") { + element.childNodes[0].childNodes.forEach((e) => { + + if (e instanceof HTMLCanvasElement) { + this._pdfCanvas = e; + this._pdfContext = e.getContext("2d") + + } + + }) + } + }) + } + this.numPage = page.transport.numPages + if (this.perPage.length == 0) { //Makes sure it only runs once + this.perPage = [...Array(this.numPage)] + } } } - } - /> -
- } -
-
-
+ /> +
+ } +
+
+
+
); } -- cgit v1.2.3-70-g09d2 From c0f6d5b4ef67a60b4bd52b98e5bda29746765969 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Thu, 7 Mar 2019 00:02:57 -0500 Subject: added image caching for pdfs --- package-lock.json | 33 ++++++++++++------------------- package.json | 3 ++- src/client/util/DragManager.ts | 18 ++++++++++++++--- src/client/views/nodes/PDFNode.tsx | 40 +++++++++++++++++++++++++++++++++++--- src/fields/KeyStore.ts | 1 + 5 files changed, 67 insertions(+), 28 deletions(-) (limited to 'src/client/views/nodes') diff --git a/package-lock.json b/package-lock.json index 4c26734f6..b8f18acbc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3412,14 +3412,12 @@ "balanced-match": { "version": "1.0.0", "resolved": false, - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "optional": true + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "brace-expansion": { "version": "1.1.11", "resolved": false, "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3434,20 +3432,17 @@ "code-point-at": { "version": "1.1.0", "resolved": false, - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "optional": true + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" }, "concat-map": { "version": "0.0.1", "resolved": false, - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "optional": true + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "console-control-strings": { "version": "1.1.0", "resolved": false, - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "optional": true + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" }, "core-util-is": { "version": "1.0.2", @@ -3564,8 +3559,7 @@ "inherits": { "version": "2.0.3", "resolved": false, - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "optional": true + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, "ini": { "version": "1.3.5", @@ -3577,7 +3571,6 @@ "version": "1.0.0", "resolved": false, "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -3592,7 +3585,6 @@ "version": "3.0.4", "resolved": false, "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -3600,14 +3592,12 @@ "minimist": { "version": "0.0.8", "resolved": false, - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "optional": true + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" }, "minipass": { "version": "2.3.5", "resolved": false, "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -3626,7 +3616,6 @@ "version": "0.5.1", "resolved": false, "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "optional": true, "requires": { "minimist": "0.0.8" } @@ -3707,8 +3696,7 @@ "number-is-nan": { "version": "1.0.1", "resolved": false, - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "optional": true + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" }, "object-assign": { "version": "4.1.1", @@ -3720,7 +3708,6 @@ "version": "1.4.0", "resolved": false, "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "optional": true, "requires": { "wrappy": "1" } @@ -3842,7 +3829,6 @@ "version": "1.0.2", "resolved": false, "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -4332,6 +4318,11 @@ "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=", "dev": true }, + "html-to-image": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/html-to-image/-/html-to-image-0.1.0.tgz", + "integrity": "sha512-/VLH+jjGQgLDs+BlVDVAzI1rdghYfFWFcPmFHChiD3UHMmckyDuvJpH3N3lli0elJkWfyv/EKrWNXTxm3mg4oQ==" + }, "http-deceiver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", diff --git a/package.json b/package.json index 7112d3672..271acfd0b 100644 --- a/package.json +++ b/package.json @@ -67,8 +67,8 @@ "@types/socket.io-client": "^1.4.32", "@types/typescript": "^2.0.0", "@types/uuid": "^3.4.4", - "babel-runtime": "^6.26.0", "@types/webpack": "^4.4.24", + "babel-runtime": "^6.26.0", "bcrypt-nodejs": "0.0.3", "bluebird": "^3.5.3", "body-parser": "^1.18.3", @@ -80,6 +80,7 @@ "expressjs": "^1.0.1", "flexlayout-react": "^0.3.3", "golden-layout": "^1.5.9", + "html-to-image": "^0.1.0", "i": "^0.3.6", "jsonwebtoken": "^8.4.0", "jsx-to-string": "^1.4.0", diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 60910a40b..63f5616a9 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -3,6 +3,8 @@ import { CollectionDockingView } from "../views/collections/CollectionDockingVie import { Document } from "../../fields/Document" import { action } from "mobx"; import { DocumentView } from "../views/nodes/DocumentView"; +import { ImageField } from "../../fields/ImageField"; +import { KeyStore } from "../../fields/KeyStore"; export function setupDrag(_reference: React.RefObject, docFunc: () => Document) { let onRowMove = action((e: PointerEvent): void => { @@ -105,7 +107,19 @@ export namespace DragManager { const scaleX = rect.width / w, scaleY = rect.height / h; let x = rect.left, y = rect.top; // const offsetX = e.x - rect.left, offsetY = e.y - rect.top; - let dragElement = ele.cloneNode(true) as HTMLElement; + + // bcz: PDFs don't show up if you clone them -- presumably because they contain a canvas. + // however, PDF's have a thumbnail field that contains an image of the current page. + // so we use this image instead of the cloned element if it's present. + const docView: DocumentView = dragData["documentView"]; + const doc: Document = docView ? docView.props.Document : dragData["document"]; + let thumbnail = doc.GetT(KeyStore.Thumbnail, ImageField); + let img = thumbnail ? new Image() : null; + if (thumbnail) { + img!.src = thumbnail.toString(); + } + let dragElement = img ? img : ele.cloneNode(true) as HTMLElement; + dragElement.style.opacity = "0.7"; dragElement.style.position = "absolute"; dragElement.style.bottom = ""; @@ -140,8 +154,6 @@ export namespace DragManager { y += e.movementY; if (e.shiftKey) { abortDrag(); - const docView: DocumentView = dragData["documentView"]; - const doc: Document = docView ? docView.props.Document : dragData["document"]; CollectionDockingView.Instance.StartOtherDrag(doc, { pageX: e.pageX, pageY: e.pageY, preventDefault: () => { }, button: 0 }); } dragElement.style.transform = `translate(${x}px, ${y}px) scale(${scaleX}, ${scaleY})`; diff --git a/src/client/views/nodes/PDFNode.tsx b/src/client/views/nodes/PDFNode.tsx index b80283065..0390d5e0d 100644 --- a/src/client/views/nodes/PDFNode.tsx +++ b/src/client/views/nodes/PDFNode.tsx @@ -1,4 +1,4 @@ -import { action, observable } from 'mobx'; +import { action, observable, _interceptReads } from 'mobx'; import { observer } from "mobx-react"; import Measure from "react-measure"; import 'react-image-lightbox/style.css'; @@ -15,6 +15,9 @@ import { KeyStore } from '../../../fields/KeyStore'; import "./PDFNode.scss"; import { PDFField } from '../../../fields/PDFField'; import { FieldWaiting } from '../../../fields/Field'; +import { ImageField } from '../../../fields/ImageField'; +import * as htmlToImage from "html-to-image"; +import { url } from 'inspector'; /** ALSO LOOK AT: Annotation.tsx, Sticky.tsx * This method renders PDF and puts all kinds of functionalities such as annotation, highlighting, @@ -94,6 +97,7 @@ export class PDFNode extends React.Component { if (this.perPage[this.page - 1]) { this.pageInfo = this.perPage[this.page - 1]; } + this.saveThumbnail(); } } @@ -110,6 +114,7 @@ export class PDFNode extends React.Component { if (this.perPage[this.page - 1]) { this.pageInfo = this.perPage[this.page - 1]; } + this.saveThumbnail(); } } @@ -288,7 +293,6 @@ export class PDFNode extends React.Component { */ @action onPointerUp = (e: React.PointerEvent) => { - if (this._highlightToolOn) { this.highlight("rgba(76, 175, 80, 0.3)"); //highlights to this default color. this._highlightToolOn = false; @@ -314,7 +318,7 @@ export class PDFNode extends React.Component { } this._toolOn = false; } - + this._interactive = true; } /** @@ -392,7 +396,22 @@ export class PDFNode extends React.Component { } + @observable _interactive: boolean = false; + @action + saveThumbnail = () => { + setTimeout(() => { + var me = this; + htmlToImage.toPng(this._mainDiv.current!, + { width: me.props.doc.GetNumber(KeyStore.NativeWidth, 0), height: me.props.doc.GetNumber(KeyStore.NativeHeight, 0), quality: 0.5 }) + .then(function (dataUrl: string) { + me.props.doc.SetData(KeyStore.Thumbnail, new URL(dataUrl), ImageField); + }) + .catch(function (error: any) { + console.error('oops, something went wrong!', error); + }); + }, 1000); + } @action setScaling = (r: any) => { // bcz: the nativeHeight should really be set when the document is imported. @@ -402,8 +421,23 @@ export class PDFNode extends React.Component { if (!this.props.doc.GetNumber(KeyStore.NativeHeight, 0)) { this.props.doc.SetNumber(KeyStore.NativeHeight, nativeWidth * r.entry.height / r.entry.width); } + if (!this.props.doc.GetT(KeyStore.Thumbnail, ImageField)) { + this.saveThumbnail(); + } } render() { + let field = this.props.doc.Get(KeyStore.Thumbnail); + if (!this._interactive && field) { + let path = field == FieldWaiting ? "https://image.flaticon.com/icons/svg/66/66163.svg" : + field instanceof ImageField ? field.Data.href : "http://cs.brown.edu/people/bcz/prairie.jpg"; + return ( +
+ +
); + } const renderHeight = 2400; let xf = this.props.doc.GetNumber(KeyStore.NativeHeight, 0) / renderHeight; var pdfUrl = this.props.doc.GetT(this.props.fieldKey, PDFField); diff --git a/src/fields/KeyStore.ts b/src/fields/KeyStore.ts index a3b39735d..1327bd9f4 100644 --- a/src/fields/KeyStore.ts +++ b/src/fields/KeyStore.ts @@ -26,4 +26,5 @@ export namespace KeyStore { export const Caption = new Key("Caption"); export const ActiveFrame = new Key("ActiveFrame"); export const DocumentText = new Key("DocumentText"); + export const Thumbnail = new Key("Thumbnail"); } -- cgit v1.2.3-70-g09d2 From 20599dce380b63af37433614d74778fb4f3e20b6 Mon Sep 17 00:00:00 2001 From: Bob Zeleznik Date: Thu, 7 Mar 2019 01:45:20 -0500 Subject: cleaned up PDF render and fixed dragging to show annotations. --- src/client/util/DragManager.ts | 34 ++++----- src/client/views/nodes/PDFNode.tsx | 144 ++++++++++++++++++------------------- 2 files changed, 87 insertions(+), 91 deletions(-) (limited to 'src/client/views/nodes') diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index 63f5616a9..a7af399e2 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -108,18 +108,7 @@ export namespace DragManager { let x = rect.left, y = rect.top; // const offsetX = e.x - rect.left, offsetY = e.y - rect.top; - // bcz: PDFs don't show up if you clone them -- presumably because they contain a canvas. - // however, PDF's have a thumbnail field that contains an image of the current page. - // so we use this image instead of the cloned element if it's present. - const docView: DocumentView = dragData["documentView"]; - const doc: Document = docView ? docView.props.Document : dragData["document"]; - let thumbnail = doc.GetT(KeyStore.Thumbnail, ImageField); - let img = thumbnail ? new Image() : null; - if (thumbnail) { - img!.src = thumbnail.toString(); - } - let dragElement = img ? img : ele.cloneNode(true) as HTMLElement; - + let dragElement = ele.cloneNode(true) as HTMLElement; dragElement.style.opacity = "0.7"; dragElement.style.position = "absolute"; dragElement.style.bottom = ""; @@ -129,10 +118,23 @@ export namespace DragManager { dragElement.style.transform = `translate(${x}px, ${y}px) scale(${scaleX}, ${scaleY})`; dragElement.style.width = `${rect.width / scaleX}px`; dragElement.style.height = `${rect.height / scaleY}px`; - // It seems like the above code should be able to just be this: - // dragElement.style.transform = `translate(${x}px, ${y}px)`; - // dragElement.style.width = `${rect.width}px`; - // dragElement.style.height = `${rect.height}px`; + + // bcz: PDFs don't show up if you clone them because they contain a canvas. + // however, PDF's have a thumbnail field that contains an image of their canvas. + // So we replace the pdf's canvas with the image thumbnail + const docView: DocumentView = dragData["documentView"]; + const doc: Document = docView ? docView.props.Document : dragData["document"]; + var pdfNode = dragElement.getElementsByClassName("pdfNode-cont")[0] as HTMLElement; + let thumbnail = doc.GetT(KeyStore.Thumbnail, ImageField); + if (pdfNode && pdfNode.childElementCount && thumbnail) { + let img = new Image(); + img!.src = thumbnail.toString(); + img!.style.position = "absolute"; + img!.style.width = `${rect.width / scaleX}px`; + img!.style.height = `${rect.height / scaleY}px`; + pdfNode.replaceChild(img!, pdfNode.children[0]) + } + dragDiv.appendChild(dragElement); let hideSource = false; diff --git a/src/client/views/nodes/PDFNode.tsx b/src/client/views/nodes/PDFNode.tsx index 0390d5e0d..b6829f086 100644 --- a/src/client/views/nodes/PDFNode.tsx +++ b/src/client/views/nodes/PDFNode.tsx @@ -412,6 +412,29 @@ export class PDFNode extends React.Component { }); }, 1000); } + + onLoaded = (page: any) => { + if (this._mainDiv.current) { + this._mainDiv.current.childNodes.forEach((element) => { + if (element.nodeName == "DIV") { + element.childNodes[0].childNodes.forEach((e) => { + + if (e instanceof HTMLCanvasElement) { + this._pdfCanvas = e; + this._pdfContext = e.getContext("2d") + + } + + }) + } + }) + } + this.numPage = page.transport.numPages + if (this.perPage.length == 0) { //Makes sure it only runs once + this.perPage = [...Array(this.numPage)] + } + } + @action setScaling = (r: any) => { // bcz: the nativeHeight should really be set when the document is imported. @@ -425,90 +448,61 @@ export class PDFNode extends React.Component { this.saveThumbnail(); } } - render() { - let field = this.props.doc.Get(KeyStore.Thumbnail); - if (!this._interactive && field) { - let path = field == FieldWaiting ? "https://image.flaticon.com/icons/svg/66/66163.svg" : - field instanceof ImageField ? field.Data.href : "http://cs.brown.edu/people/bcz/prairie.jpg"; - return ( -
- -
); + makeUIButtons() { + return ( +
+ + + + + + + + + +
); + } + makePdfRenderer() { + let proxy = this.makeImageProxyRenderer(); + let pdfUrl = this.props.doc.GetT(this.props.fieldKey, PDFField); + if ((!this._interactive && proxy) || !pdfUrl || pdfUrl == FieldWaiting) { + return proxy; } const renderHeight = 2400; let xf = this.props.doc.GetNumber(KeyStore.NativeHeight, 0) / renderHeight; - var pdfUrl = this.props.doc.GetT(this.props.fieldKey, PDFField); - if (!pdfUrl || pdfUrl == FieldWaiting) { - return (null); + return [ + this.pageInfo.area.filter(() => this.pageInfo.area).map((element: any) => element), + this.currAnno.map((element: any) => element), + this.makeUIButtons(), +
+ + + {({ measureRef }) => +
+ +
+ } +
+
+
+ ]; + } + makeImageProxyRenderer() { + let field = this.props.doc.Get(KeyStore.Thumbnail); + if (field) { + let path = field == FieldWaiting ? "https://image.flaticon.com/icons/svg/66/66163.svg" : + field instanceof ImageField ? field.Data.href : "http://cs.brown.edu/people/bcz/prairie.jpg"; + return ; } + return (null); + } + render() { return (
- - {this.pageInfo.area.filter(() => { - return this.pageInfo.area - }).map((element: any) => { - return element - }) - } - {this.currAnno.map((element: any) => { - return element - })} - -
- - - - - - - - - -
- -
- - - {({ measureRef }) => -
- { - if (this._mainDiv.current) { - this._mainDiv.current.childNodes.forEach((element) => { - if (element.nodeName == "DIV") { - element.childNodes[0].childNodes.forEach((e) => { - - if (e instanceof HTMLCanvasElement) { - this._pdfCanvas = e; - this._pdfContext = e.getContext("2d") - - } - - }) - } - }) - } - this.numPage = page.transport.numPages - if (this.perPage.length == 0) { //Makes sure it only runs once - this.perPage = [...Array(this.numPage)] - } - } - } - /> -
- } -
-
-
+ {this.makePdfRenderer()}
); } -- cgit v1.2.3-70-g09d2 From 22d7f22a60a17373a6e453e09cc616f651c11a9e Mon Sep 17 00:00:00 2001 From: bob Date: Thu, 7 Mar 2019 14:37:25 -0500 Subject: fixed flicker when activating a PDF --- .../views/collections/CollectionDockingView.tsx | 2 +- .../views/collections/CollectionFreeFormView.scss | 1 + src/client/views/nodes/KeyValueBox.tsx | 23 +--- src/client/views/nodes/PDFNode.scss | 10 +- src/client/views/nodes/PDFNode.tsx | 151 +++++++++++---------- src/fields/ListField.ts | 1 + 6 files changed, 91 insertions(+), 97 deletions(-) (limited to 'src/client/views/nodes') diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx index c51fba908..f01c538e6 100644 --- a/src/client/views/collections/CollectionDockingView.tsx +++ b/src/client/views/collections/CollectionDockingView.tsx @@ -35,6 +35,7 @@ export class CollectionDockingView extends React.Component(); private _fullScreen: any = null; + private _flush: boolean = false; constructor(props: SubCollectionViewProps) { super(props); @@ -164,7 +165,6 @@ export class CollectionDockingView extends React.Component { if (this._flush) { diff --git a/src/client/views/collections/CollectionFreeFormView.scss b/src/client/views/collections/CollectionFreeFormView.scss index fb9394d59..f496517f5 100644 --- a/src/client/views/collections/CollectionFreeFormView.scss +++ b/src/client/views/collections/CollectionFreeFormView.scss @@ -3,6 +3,7 @@ .collectionfreeformview > .jsx-parser{ position:absolute; height: 100%; + width: 100%; } border-style: solid; diff --git a/src/client/views/nodes/KeyValueBox.tsx b/src/client/views/nodes/KeyValueBox.tsx index e8ebd50be..ac8c949a9 100644 --- a/src/client/views/nodes/KeyValueBox.tsx +++ b/src/client/views/nodes/KeyValueBox.tsx @@ -1,37 +1,18 @@ -import { IReactionDisposer } from 'mobx'; import { observer } from "mobx-react"; -import { EditorView } from 'prosemirror-view'; import 'react-image-lightbox/style.css'; // This only needs to be imported once in your app import { Document } from '../../../fields/Document'; -import { Opt, FieldWaiting } from '../../../fields/Field'; +import { FieldWaiting } from '../../../fields/Field'; import { KeyStore } from '../../../fields/KeyStore'; import { FieldView, FieldViewProps } from './FieldView'; -import { KeyValuePair } from "./KeyValuePair"; import "./KeyValueBox.scss"; +import { KeyValuePair } from "./KeyValuePair"; import React = require("react") @observer export class KeyValueBox extends React.Component { public static LayoutString(fieldStr: string = "DataKey") { return FieldView.LayoutString(KeyValueBox, fieldStr) } - private _ref: React.RefObject; - private _editorView: Opt; - private _reactionDisposer: Opt; - - - constructor(props: FieldViewProps) { - super(props); - - this._ref = React.createRef(); - } - - - - shouldComponentUpdate() { - return false; - } - onPointerDown = (e: React.PointerEvent): void => { if (e.buttons === 1 && this.props.isSelected()) { diff --git a/src/client/views/nodes/PDFNode.scss b/src/client/views/nodes/PDFNode.scss index f4935cba9..18ebca952 100644 --- a/src/client/views/nodes/PDFNode.scss +++ b/src/client/views/nodes/PDFNode.scss @@ -1,9 +1,15 @@ .react-pdf__Page { transform-origin: left top; - //transform: scale(0.2, 0.2); position: absolute; } -.pdfButton-Tray { +.react-pdf__Document { + position: absolute; +} +.pdfNode-buttonTray { position:absolute; z-index: 25; +} +.pdfNode-contentContainer { + position: absolute; + transform-origin: "left top"; } \ No newline at end of file diff --git a/src/client/views/nodes/PDFNode.tsx b/src/client/views/nodes/PDFNode.tsx index b6829f086..648bd3e62 100644 --- a/src/client/views/nodes/PDFNode.tsx +++ b/src/client/views/nodes/PDFNode.tsx @@ -1,4 +1,4 @@ -import { action, observable, _interceptReads } from 'mobx'; +import { action, observable, _interceptReads, computed } from 'mobx'; import { observer } from "mobx-react"; import Measure from "react-measure"; import 'react-image-lightbox/style.css'; @@ -76,26 +76,29 @@ export class PDFNode extends React.Component { private _highlightTool = React.createRef(); //highlighter button reference private _highlightToolOn: boolean = false; + private _pdfCanvas: any; - @observable perPage: Object[] = []; //stores pageInfo - @observable pageInfo: any = { area: [], divs: [], anno: [] }; //divs is array of objects linked to anno + @observable private _perPageInfo: Object[] = []; //stores pageInfo + @observable private _pageInfo: any = { area: [], divs: [], anno: [] }; //divs is array of objects linked to anno - @observable private page: number = 1; //default is the first page. - @observable private numPage: number = 1; //default number of pages - private _pdfCanvas: any; + @observable private _currAnno: any = [] + @observable private _page: number = 1; //default is the first page. + @observable private _numPages: number = 1; //default number of pages + @observable private _interactive: boolean = false; + @observable private _loaded: boolean = false; /** * for pagination backwards */ @action onPageBack = () => { - if (this.page > 1) { - this.page -= 1; - this.currAnno = []; - this.perPage[this.page] = this.pageInfo - this.pageInfo = { area: [], divs: [], anno: [] }; //resets the object to default - if (this.perPage[this.page - 1]) { - this.pageInfo = this.perPage[this.page - 1]; + if (this._page > 1) { + this._page -= 1; + this._currAnno = []; + this._perPageInfo[this._page] = this._pageInfo + this._pageInfo = { area: [], divs: [], anno: [] }; //resets the object to default + if (this._perPageInfo[this._page - 1]) { + this._pageInfo = this._perPageInfo[this._page - 1]; } this.saveThumbnail(); } @@ -106,13 +109,13 @@ export class PDFNode extends React.Component { */ @action onPageForward = () => { - if (this.page < this.numPage) { - this.page += 1; - this.currAnno = []; - this.perPage[this.page - 2] = this.pageInfo; - this.pageInfo = { area: [], divs: [], anno: [] }; //resets the object to default - if (this.perPage[this.page - 1]) { - this.pageInfo = this.perPage[this.page - 1]; + if (this._page < this._numPages) { + this._page += 1; + this._currAnno = []; + this._perPageInfo[this._page - 2] = this._pageInfo; + this._pageInfo = { area: [], divs: [], anno: [] }; //resets the object to default + if (this._perPageInfo[this._page - 1]) { + this._pageInfo = this._perPageInfo[this._page - 1]; } this.saveThumbnail(); } @@ -196,7 +199,7 @@ export class PDFNode extends React.Component { } } } - this.pageInfo.divs.push(obj); + this._pageInfo.divs.push(obj); } document.designMode = "off"; @@ -224,27 +227,26 @@ export class PDFNode extends React.Component { /** * when the cursor enters the highlight, it pops out annotation. ONLY WORKS FOR SINGLE DIV LINES */ - @observable private currAnno: any = [] @action onEnter = (e: any) => { let span: HTMLSpanElement = e.toElement; let index: any; - this.pageInfo.divs.forEach((obj: any) => { + this._pageInfo.divs.forEach((obj: any) => { obj.spans.forEach((element: any) => { if (element == span) { if (!index) { - index = this.pageInfo.divs.indexOf(obj); + index = this._pageInfo.divs.indexOf(obj); } } }) }) - if (this.pageInfo.anno.length >= index + 1) { - if (this.currAnno.length == 0) { - this.currAnno.push(this.pageInfo.anno[index]); + if (this._pageInfo.anno.length >= index + 1) { + if (this._currAnno.length == 0) { + this._currAnno.push(this._pageInfo.anno[index]); } } else { - if (this.currAnno.length == 0) { //if there are no current annotation + if (this._currAnno.length == 0) { //if there are no current annotation let div = span.offsetParent; //@ts-ignore let divX = div.style.left @@ -253,9 +255,9 @@ export class PDFNode extends React.Component { //slicing "px" from the end divX = divX.slice(0, divX.length - 2); //gets X of the DIV element (parent of Span) divY = divY.slice(0, divY.length - 2); //gets Y of the DIV element (parent of Span) - let annotation = - this.pageInfo.anno.push(annotation); - this.currAnno.push(annotation); + let annotation = + this._pageInfo.anno.push(annotation); + this._currAnno.push(annotation); } } @@ -314,7 +316,7 @@ export class PDFNode extends React.Component { if (this._mainDiv.current) { let sticky = - this.pageInfo.area.push(sticky); + this._pageInfo.area.push(sticky); } this._toolOn = false; } @@ -384,19 +386,7 @@ export class PDFNode extends React.Component { } - /** - * renders whole lot of shets, including pdf, stickies, and annotations. - */ - - reHighlight = () => { - let div = document.getElementsByClassName("react-pdf__Page__textContent"); - if (div) { - - } - - } - @observable _interactive: boolean = false; @action saveThumbnail = () => { @@ -413,6 +403,7 @@ export class PDFNode extends React.Component { }, 1000); } + @action onLoaded = (page: any) => { if (this._mainDiv.current) { this._mainDiv.current.childNodes.forEach((element) => { @@ -429,10 +420,11 @@ export class PDFNode extends React.Component { } }) } - this.numPage = page.transport.numPages - if (this.perPage.length == 0) { //Makes sure it only runs once - this.perPage = [...Array(this.numPage)] + this._numPages = page.transport.numPages + if (this._perPageInfo.length == 0) { //Makes sure it only runs once + this._perPageInfo = [...Array(this._numPages)] } + this._loaded = true; } @action @@ -448,9 +440,11 @@ export class PDFNode extends React.Component { this.saveThumbnail(); } } - makeUIButtons() { + + @computed + get uIButtons() { return ( -
+
@@ -462,32 +456,45 @@ export class PDFNode extends React.Component {
); } - makePdfRenderer() { - let proxy = this.makeImageProxyRenderer(); + + @computed + get pdfContent() { + const renderHeight = 2400; + let pdfUrl = this.props.doc.GetT(this.props.fieldKey, PDFField); + let xf = this.props.doc.GetNumber(KeyStore.NativeHeight, 0) / renderHeight; + return
+ + + {({ measureRef }) => +
+ +
+ } +
+
+
; + } + + @computed + get pdfRenderer() { + let proxy = this._loaded ? (null) : this.imageProxyRenderer; let pdfUrl = this.props.doc.GetT(this.props.fieldKey, PDFField); if ((!this._interactive && proxy) || !pdfUrl || pdfUrl == FieldWaiting) { return proxy; } - const renderHeight = 2400; - let xf = this.props.doc.GetNumber(KeyStore.NativeHeight, 0) / renderHeight; return [ - this.pageInfo.area.filter(() => this.pageInfo.area).map((element: any) => element), - this.currAnno.map((element: any) => element), - this.makeUIButtons(), -
- - - {({ measureRef }) => -
- -
- } -
-
-
+ this._pageInfo.area.filter(() => this._pageInfo.area).map((element: any) => element), + this._currAnno.map((element: any) => element), + this.uIButtons, +
+ {this.pdfContent} + {proxy} +
]; } - makeImageProxyRenderer() { + + @computed + get imageProxyRenderer() { let field = this.props.doc.Get(KeyStore.Thumbnail); if (field) { let path = field == FieldWaiting ? "https://image.flaticon.com/icons/svg/66/66163.svg" : @@ -496,13 +503,11 @@ export class PDFNode extends React.Component { } return (null); } + render() { return ( -
- {this.makePdfRenderer()} +
+ {this.pdfRenderer}
); } diff --git a/src/fields/ListField.ts b/src/fields/ListField.ts index 700600804..a71325a65 100644 --- a/src/fields/ListField.ts +++ b/src/fields/ListField.ts @@ -40,6 +40,7 @@ export class ListField extends BasicField { this.observeDisposer() } this.data = observable(value); + this.updateProxies(); this.observeList(); } -- cgit v1.2.3-70-g09d2 From 4796d17b089824df4455788c564414526c08eaa4 Mon Sep 17 00:00:00 2001 From: bob Date: Fri, 8 Mar 2019 09:21:18 -0500 Subject: merged with master --- src/client/documents/Documents.ts | 5 +- src/client/util/DragManager.ts | 6 +- .../views/collections/CollectionFreeFormView.tsx | 16 +- src/client/views/nodes/DocumentView.tsx | 4 +- src/client/views/nodes/PDFBox.scss | 15 + src/client/views/nodes/PDFBox.tsx | 515 +++++++++++++++++++++ src/client/views/nodes/PDFNode.scss | 15 - src/client/views/nodes/PDFNode.tsx | 515 --------------------- 8 files changed, 544 insertions(+), 547 deletions(-) create mode 100644 src/client/views/nodes/PDFBox.scss create mode 100644 src/client/views/nodes/PDFBox.tsx delete mode 100644 src/client/views/nodes/PDFNode.scss delete mode 100644 src/client/views/nodes/PDFNode.tsx (limited to 'src/client/views/nodes') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 47b8ea844..f73823603 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -14,9 +14,8 @@ import { HtmlField } from "../../fields/HtmlField"; import { Key } from "../../fields/Key" import { Field } from "../../fields/Field"; import { KeyValueBox } from "../views/nodes/KeyValueBox" -import { KVPField } from "../../fields/KVPField"; import { PDFField } from "../../fields/PDFField"; -import { PDFNode } from "../views/nodes/PDFNode"; +import { PDFBox } from "../views/nodes/PDFBox"; export interface DocumentOptions { x?: number; @@ -100,7 +99,7 @@ export namespace Documents { if (!pdfProto) { pdfProto = setupPrototypeOptions(pdfProtoId, "PDF_PROTO", CollectionView.LayoutString("AnnotationsKey"), { x: 0, y: 0, nativeWidth: 600, width: 300, layoutKeys: [KeyStore.Data, KeyStore.Annotations] }); - pdfProto.SetText(KeyStore.BackgroundLayout, PDFNode.LayoutString()); + pdfProto.SetText(KeyStore.BackgroundLayout, PDFBox.LayoutString()); } return pdfProto; } diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts index a7af399e2..513a6ac9e 100644 --- a/src/client/util/DragManager.ts +++ b/src/client/util/DragManager.ts @@ -124,15 +124,15 @@ export namespace DragManager { // So we replace the pdf's canvas with the image thumbnail const docView: DocumentView = dragData["documentView"]; const doc: Document = docView ? docView.props.Document : dragData["document"]; - var pdfNode = dragElement.getElementsByClassName("pdfNode-cont")[0] as HTMLElement; + var pdfBox = dragElement.getElementsByClassName("pdfBox-cont")[0] as HTMLElement; let thumbnail = doc.GetT(KeyStore.Thumbnail, ImageField); - if (pdfNode && pdfNode.childElementCount && thumbnail) { + if (pdfBox && pdfBox.childElementCount && thumbnail) { let img = new Image(); img!.src = thumbnail.toString(); img!.style.position = "absolute"; img!.style.width = `${rect.width / scaleX}px`; img!.style.height = `${rect.height / scaleY}px`; - pdfNode.replaceChild(img!, pdfNode.children[0]) + pdfBox.replaceChild(img!, pdfBox.children[0]) } dragDiv.appendChild(dragElement); diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx index 86d9a10e3..74e70ef33 100644 --- a/src/client/views/collections/CollectionFreeFormView.tsx +++ b/src/client/views/collections/CollectionFreeFormView.tsx @@ -1,30 +1,28 @@ -import { observable, action, computed } from "mobx"; +import { action, computed, observable } from "mobx"; import { observer } from "mobx-react"; import { Document } from "../../../fields/Document"; import { FieldWaiting } from "../../../fields/Field"; import { KeyStore } from "../../../fields/KeyStore"; import { ListField } from "../../../fields/ListField"; import { TextField } from "../../../fields/TextField"; +import { Documents } from "../../documents/Documents"; import { DragManager } from "../../util/DragManager"; import { Transform } from "../../util/Transform"; import { undoBatch } from "../../util/UndoManager"; import { CollectionDockingView } from "../collections/CollectionDockingView"; import { CollectionSchemaView } from "../collections/CollectionSchemaView"; import { CollectionView } from "../collections/CollectionView"; +import { InkingCanvas } from "../InkingCanvas"; import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView"; import { DocumentView } from "../nodes/DocumentView"; import { FormattedTextBox } from "../nodes/FormattedTextBox"; import { ImageBox } from "../nodes/ImageBox"; -import { PDFNode } from "../nodes/PDFNode"; +import { KeyValueBox } from "../nodes/KeyValueBox"; +import { PDFBox } from "../nodes/PDFBox"; import { WebBox } from "../nodes/WebBox"; -import { KeyValueBox } from "../nodes/KeyValueBox" import "./CollectionFreeFormView.scss"; import { COLLECTION_BORDER_WIDTH } from "./CollectionView"; import { CollectionViewBase } from "./CollectionViewBase"; -import { Documents } from "../../documents/Documents"; -import { InkingCanvas } from "../InkingCanvas"; -import { InkingControl } from "../InkingControl"; -import { InkTool } from "../../../fields/InkField"; import React = require("react"); const JsxParser = require('react-jsx-parser').default;//TODO Why does this need to be imported like this? @@ -250,7 +248,7 @@ export class CollectionFreeFormView extends CollectionViewBase { get backgroundView() { return !this.backgroundLayout ? (null) : ( { } @computed get mainContent() { return { + public static LayoutString() { return FieldView.LayoutString(PDFBox); } + + private _mainDiv = React.createRef() + private _pdf = React.createRef(); + + //very useful for keeping track of X and y position throughout the PDF Canvas + private initX: number = 0; + private initY: number = 0; + + //checks if tool is on + private _toolOn: boolean = false; //checks if tool is on + private _pdfContext: any = null; //gets pdf context + private bool: Boolean = false; //general boolean debounce + private currSpan: any;//keeps track of current span (for highlighting) + + private _currTool: any; //keeps track of current tool button reference + private _drawToolOn: boolean = false; //boolean that keeps track of the drawing tool + private _drawTool = React.createRef()//drawing tool button reference + + private _colorTool = React.createRef(); //color button reference + private _currColor: string = "black"; //current color that user selected (for ink/pen) + + private _highlightTool = React.createRef(); //highlighter button reference + private _highlightToolOn: boolean = false; + private _pdfCanvas: any; + + @observable private _perPageInfo: Object[] = []; //stores pageInfo + @observable private _pageInfo: any = { area: [], divs: [], anno: [] }; //divs is array of objects linked to anno + + @observable private _currAnno: any = [] + @observable private _page: number = 1; //default is the first page. + @observable private _numPages: number = 1; //default number of pages + @observable private _interactive: boolean = false; + @observable private _loaded: boolean = false; + + /** + * for pagination backwards + */ + @action + onPageBack = () => { + if (this._page > 1) { + this._page -= 1; + this._currAnno = []; + this._perPageInfo[this._page] = this._pageInfo + this._pageInfo = { area: [], divs: [], anno: [] }; //resets the object to default + if (this._perPageInfo[this._page - 1]) { + this._pageInfo = this._perPageInfo[this._page - 1]; + } + this.saveThumbnail(); + } + } + + /** + * for pagination forwards + */ + @action + onPageForward = () => { + if (this._page < this._numPages) { + this._page += 1; + this._currAnno = []; + this._perPageInfo[this._page - 2] = this._pageInfo; + this._pageInfo = { area: [], divs: [], anno: [] }; //resets the object to default + if (this._perPageInfo[this._page - 1]) { + this._pageInfo = this._perPageInfo[this._page - 1]; + } + this.saveThumbnail(); + } + } + + /** + * selection tool used for area highlighting (stickies). Kinda temporary + */ + selectionTool = () => { + this._toolOn = true; + } + /** + * when user draws on the canvas. When mouse pointer is down + */ + drawDown = (e: PointerEvent) => { + this.initX = e.offsetX; + this.initY = e.offsetY; + this._pdfContext.beginPath(); + this._pdfContext.lineTo(this.initX, this.initY); + this._pdfContext.strokeStyle = this._currColor; + this._pdfCanvas.addEventListener("pointermove", this.drawMove); + this._pdfCanvas.addEventListener("pointerup", this.drawUp); + + } + //when user drags + drawMove = (e: PointerEvent): void => { + //x and y mouse movement + let x = this.initX += e.movementX, + y = this.initY += e.movementY; + //connects the point + this._pdfContext.lineTo(x, y); + this._pdfContext.stroke(); + } + + drawUp = (e: PointerEvent) => { + this._pdfContext.closePath(); + this._pdfCanvas.removeEventListener("pointermove", this.drawMove); + this._pdfCanvas.removeEventListener("pointerdown", this.drawDown); + this._pdfCanvas.addEventListener("pointerdown", this.drawDown); + } + + + /** + * highlighting helper function + */ + makeEditableAndHighlight = (colour: string) => { + var range, sel = window.getSelection(); + if (sel.rangeCount && sel.getRangeAt) { + range = sel.getRangeAt(0); + } + document.designMode = "on"; + if (!document.execCommand("HiliteColor", false, colour)) { + document.execCommand("HiliteColor", false, colour); + } + + if (range) { + sel.removeAllRanges(); + sel.addRange(range); + + let obj: Object = { parentDivs: [], spans: [] }; + //@ts-ignore + if (range.commonAncestorContainer.className == 'react-pdf__Page__textContent') { //multiline highlighting case + obj = this.highlightNodes(range.commonAncestorContainer.childNodes) + } else { //single line highlighting case + let parentDiv = range.commonAncestorContainer.parentElement + if (parentDiv) { + if (parentDiv.className == 'react-pdf__Page__textContent') { //when highlight is overwritten + obj = this.highlightNodes(parentDiv.childNodes) + } else { + parentDiv.childNodes.forEach((child) => { + if (child.nodeName == 'SPAN') { + //@ts-ignore + obj.parentDivs.push(parentDiv) + //@ts-ignore + child.id = "highlighted" + //@ts-ignore + obj.spans.push(child) + child.addEventListener("mouseover", this.onEnter); //adds mouseover annotation handler + } + }) + } + } + } + this._pageInfo.divs.push(obj); + + } + document.designMode = "off"; + } + + highlightNodes = (nodes: NodeListOf) => { + let temp = { parentDivs: [], spans: [] } + nodes.forEach((div) => { + div.childNodes.forEach((child) => { + if (child.nodeName == 'SPAN') { + //@ts-ignore + temp.parentDivs.push(div) + //@ts-ignore + child.id = "highlighted" + //@ts-ignore + temp.spans.push(child) + child.addEventListener("mouseover", this.onEnter); //adds mouseover annotation handler + } + }) + + }) + return temp; + } + + /** + * when the cursor enters the highlight, it pops out annotation. ONLY WORKS FOR SINGLE DIV LINES + */ + @action + onEnter = (e: any) => { + let span: HTMLSpanElement = e.toElement; + let index: any; + this._pageInfo.divs.forEach((obj: any) => { + obj.spans.forEach((element: any) => { + if (element == span) { + if (!index) { + index = this._pageInfo.divs.indexOf(obj); + } + } + }) + }) + + if (this._pageInfo.anno.length >= index + 1) { + if (this._currAnno.length == 0) { + this._currAnno.push(this._pageInfo.anno[index]); + } + } else { + if (this._currAnno.length == 0) { //if there are no current annotation + let div = span.offsetParent; + //@ts-ignore + let divX = div.style.left + //@ts-ignore + let divY = div.style.top + //slicing "px" from the end + divX = divX.slice(0, divX.length - 2); //gets X of the DIV element (parent of Span) + divY = divY.slice(0, divY.length - 2); //gets Y of the DIV element (parent of Span) + let annotation = + this._pageInfo.anno.push(annotation); + this._currAnno.push(annotation); + } + } + + } + + /** + * highlight function for highlighting actual text. This works fine. + */ + highlight = (color: string) => { + if (window.getSelection()) { + try { + if (!document.execCommand("hiliteColor", false, color)) { + this.makeEditableAndHighlight(color); + } + } catch (ex) { + this.makeEditableAndHighlight(color) + } + } + } + + /** + * controls the area highlighting (stickies) Kinda temporary + */ + onPointerDown = (e: React.PointerEvent) => { + if (this._toolOn) { + let mouse = e.nativeEvent; + this.initX = mouse.offsetX; + this.initY = mouse.offsetY; + + } + } + + /** + * controls area highlighting and partially highlighting. Kinda temporary + */ + @action + onPointerUp = (e: React.PointerEvent) => { + if (this._highlightToolOn) { + this.highlight("rgba(76, 175, 80, 0.3)"); //highlights to this default color. + this._highlightToolOn = false; + } + if (this._toolOn) { + let mouse = e.nativeEvent; + let finalX = mouse.offsetX; + let finalY = mouse.offsetY; + let width = Math.abs(finalX - this.initX); //width + let height = Math.abs(finalY - this.initY); //height + + //these two if statements are bidirectional dragging. You can drag from any point to another point and generate sticky + if (finalX < this.initX) { + this.initX = finalX; + } + if (finalY < this.initY) { + this.initY = finalY; + } + + if (this._mainDiv.current) { + let sticky = + this._pageInfo.area.push(sticky); + } + this._toolOn = false; + } + this._interactive = true; + } + + /** + * starts drawing the line when user presses down. + */ + onDraw = () => { + if (this._currTool != null) { + this._currTool.style.backgroundColor = "grey"; + } + + if (this._drawTool.current) { + this._currTool = this._drawTool.current; + if (this._drawToolOn) { + this._drawToolOn = false; + this._pdfCanvas.removeEventListener("pointerdown", this.drawDown); + this._pdfCanvas.removeEventListener("pointerup", this.drawUp); + this._pdfCanvas.removeEventListener("pointermove", this.drawMove); + this._drawTool.current.style.backgroundColor = "grey"; + } else { + this._drawToolOn = true; + this._pdfCanvas.addEventListener("pointerdown", this.drawDown); + this._drawTool.current.style.backgroundColor = "cyan"; + } + } + } + + + /** + * for changing color (for ink/pen) + */ + onColorChange = (e: React.PointerEvent) => { + if (e.currentTarget.innerHTML == "Red") { + this._currColor = "red"; + } else if (e.currentTarget.innerHTML == "Blue") { + this._currColor = "blue"; + } else if (e.currentTarget.innerHTML == "Green") { + this._currColor = "green"; + } else if (e.currentTarget.innerHTML == "Black") { + this._currColor = "black"; + } + + } + + + /** + * For highlighting (text drag highlighting) + */ + onHighlight = () => { + this._drawToolOn = false; + if (this._currTool != null) { + this._currTool.style.backgroundColor = "grey"; + } + if (this._highlightTool.current) { + this._currTool = this._drawTool.current; + if (this._highlightToolOn) { + this._highlightToolOn = false; + this._highlightTool.current.style.backgroundColor = "grey"; + } else { + this._highlightToolOn = true; + this._highlightTool.current.style.backgroundColor = "orange"; + } + } + } + + + + + @action + saveThumbnail = () => { + setTimeout(() => { + var me = this; + htmlToImage.toPng(this._mainDiv.current!, + { width: me.props.doc.GetNumber(KeyStore.NativeWidth, 0), height: me.props.doc.GetNumber(KeyStore.NativeHeight, 0), quality: 0.5 }) + .then(function (dataUrl: string) { + me.props.doc.SetData(KeyStore.Thumbnail, new URL(dataUrl), ImageField); + }) + .catch(function (error: any) { + console.error('oops, something went wrong!', error); + }); + }, 1000); + } + + @action + onLoaded = (page: any) => { + if (this._mainDiv.current) { + this._mainDiv.current.childNodes.forEach((element) => { + if (element.nodeName == "DIV") { + element.childNodes[0].childNodes.forEach((e) => { + + if (e instanceof HTMLCanvasElement) { + this._pdfCanvas = e; + this._pdfContext = e.getContext("2d") + + } + + }) + } + }) + } + this._numPages = page._transport.numPages; + if (this._perPageInfo.length == 0) { //Makes sure it only runs once + this._perPageInfo = [...Array(this._numPages)] + } + this._loaded = true; + } + + @action + setScaling = (r: any) => { + // bcz: the nativeHeight should really be set when the document is imported. + // also, the native dimensions could be different for different pages of the PDF + // so this design is flawed. + var nativeWidth = this.props.doc.GetNumber(KeyStore.NativeWidth, 0); + if (!this.props.doc.GetNumber(KeyStore.NativeHeight, 0)) { + this.props.doc.SetNumber(KeyStore.NativeHeight, nativeWidth * r.entry.height / r.entry.width); + } + if (!this.props.doc.GetT(KeyStore.Thumbnail, ImageField)) { + this.saveThumbnail(); + } + } + + @computed + get uIButtons() { + return ( +
+ + + + + + + + + +
); + } + + @computed + get pdfContent() { + const renderHeight = 2400; + let pdfUrl = this.props.doc.GetT(this.props.fieldKey, PDFField); + let xf = this.props.doc.GetNumber(KeyStore.NativeHeight, 0) / renderHeight; + return
+ + + {({ measureRef }) => +
+ +
+ } +
+
+
; + } + + @computed + get pdfRenderer() { + let proxy = this._loaded ? (null) : this.imageProxyRenderer; + let pdfUrl = this.props.doc.GetT(this.props.fieldKey, PDFField); + if ((!this._interactive && proxy) || !pdfUrl || pdfUrl == FieldWaiting) { + return proxy; + } + return [ + this._pageInfo.area.filter(() => this._pageInfo.area).map((element: any) => element), + this._currAnno.map((element: any) => element), + this.uIButtons, +
+ {this.pdfContent} + {proxy} +
+ ]; + } + + @computed + get imageProxyRenderer() { + let field = this.props.doc.Get(KeyStore.Thumbnail); + if (field) { + let path = field == FieldWaiting ? "https://image.flaticon.com/icons/svg/66/66163.svg" : + field instanceof ImageField ? field.Data.href : "http://cs.brown.edu/people/bcz/prairie.jpg"; + return ; + } + return (null); + } + + render() { + return ( +
+ {this.pdfRenderer} +
+ ); + } + +} \ No newline at end of file diff --git a/src/client/views/nodes/PDFNode.scss b/src/client/views/nodes/PDFNode.scss deleted file mode 100644 index 18ebca952..000000000 --- a/src/client/views/nodes/PDFNode.scss +++ /dev/null @@ -1,15 +0,0 @@ -.react-pdf__Page { - transform-origin: left top; - position: absolute; -} -.react-pdf__Document { - position: absolute; -} -.pdfNode-buttonTray { - position:absolute; - z-index: 25; -} -.pdfNode-contentContainer { - position: absolute; - transform-origin: "left top"; -} \ No newline at end of file diff --git a/src/client/views/nodes/PDFNode.tsx b/src/client/views/nodes/PDFNode.tsx deleted file mode 100644 index 648bd3e62..000000000 --- a/src/client/views/nodes/PDFNode.tsx +++ /dev/null @@ -1,515 +0,0 @@ -import { action, observable, _interceptReads, computed } from 'mobx'; -import { observer } from "mobx-react"; -import Measure from "react-measure"; -import 'react-image-lightbox/style.css'; -//@ts-ignore -import { Document, Page } from "react-pdf"; -import 'react-pdf/dist/Page/AnnotationLayer.css'; -import { Utils } from '../../../Utils'; -import { Annotation } from './Annotation'; -import { FieldView, FieldViewProps } from './FieldView'; -import "./ImageBox.scss"; -import { Sticky } from './Sticky'; //you should look at sticky and annotation, because they are used here -import React = require("react") -import { KeyStore } from '../../../fields/KeyStore'; -import "./PDFNode.scss"; -import { PDFField } from '../../../fields/PDFField'; -import { FieldWaiting } from '../../../fields/Field'; -import { ImageField } from '../../../fields/ImageField'; -import * as htmlToImage from "html-to-image"; -import { url } from 'inspector'; - -/** ALSO LOOK AT: Annotation.tsx, Sticky.tsx - * This method renders PDF and puts all kinds of functionalities such as annotation, highlighting, - * area selection (I call it stickies), embedded ink node for directly annotating using a pen or - * mouse, and pagination. - * - * - * HOW TO USE: - * AREA selection: - * 1) Click on Area button. - * 2) click on any part of the PDF, and drag to get desired sized area shape - * 3) You can write on the area (hence the reason why it's called sticky) - * 4) to make another area, you need to click on area button AGAIN. - * - * HIGHLIGHT: (Buggy. No multiline/multidiv text highlighting for now...) - * 1) just click and drag on a text - * 2) click highlight - * 3) for annotation, just pull your cursor over to that text - * 4) another method: click on highlight first and then drag on your desired text - * 5) To make another highlight, you need to reclick on the button - * - * Draw: - * 1) click draw and select color. then just draw like there's no tomorrow. - * 2) once you finish drawing your masterpiece, just reclick on the draw button to end your drawing session. - * - * Pagination: - * 1) click on arrows. You'll notice that stickies will stay in those page. But... highlights won't. - * 2) to test this out, make few area/stickies and then click on next page then come back. You'll see that they are all saved. - * - * - * written by: Andrew Kim - */ -@observer -export class PDFNode extends React.Component { - public static LayoutString() { return FieldView.LayoutString(PDFNode); } - - private _mainDiv = React.createRef() - private _pdf = React.createRef(); - - //very useful for keeping track of X and y position throughout the PDF Canvas - private initX: number = 0; - private initY: number = 0; - - //checks if tool is on - private _toolOn: boolean = false; //checks if tool is on - private _pdfContext: any = null; //gets pdf context - private bool: Boolean = false; //general boolean debounce - private currSpan: any;//keeps track of current span (for highlighting) - - private _currTool: any; //keeps track of current tool button reference - private _drawToolOn: boolean = false; //boolean that keeps track of the drawing tool - private _drawTool = React.createRef()//drawing tool button reference - - private _colorTool = React.createRef(); //color button reference - private _currColor: string = "black"; //current color that user selected (for ink/pen) - - private _highlightTool = React.createRef(); //highlighter button reference - private _highlightToolOn: boolean = false; - private _pdfCanvas: any; - - @observable private _perPageInfo: Object[] = []; //stores pageInfo - @observable private _pageInfo: any = { area: [], divs: [], anno: [] }; //divs is array of objects linked to anno - - @observable private _currAnno: any = [] - @observable private _page: number = 1; //default is the first page. - @observable private _numPages: number = 1; //default number of pages - @observable private _interactive: boolean = false; - @observable private _loaded: boolean = false; - - /** - * for pagination backwards - */ - @action - onPageBack = () => { - if (this._page > 1) { - this._page -= 1; - this._currAnno = []; - this._perPageInfo[this._page] = this._pageInfo - this._pageInfo = { area: [], divs: [], anno: [] }; //resets the object to default - if (this._perPageInfo[this._page - 1]) { - this._pageInfo = this._perPageInfo[this._page - 1]; - } - this.saveThumbnail(); - } - } - - /** - * for pagination forwards - */ - @action - onPageForward = () => { - if (this._page < this._numPages) { - this._page += 1; - this._currAnno = []; - this._perPageInfo[this._page - 2] = this._pageInfo; - this._pageInfo = { area: [], divs: [], anno: [] }; //resets the object to default - if (this._perPageInfo[this._page - 1]) { - this._pageInfo = this._perPageInfo[this._page - 1]; - } - this.saveThumbnail(); - } - } - - /** - * selection tool used for area highlighting (stickies). Kinda temporary - */ - selectionTool = () => { - this._toolOn = true; - } - /** - * when user draws on the canvas. When mouse pointer is down - */ - drawDown = (e: PointerEvent) => { - this.initX = e.offsetX; - this.initY = e.offsetY; - this._pdfContext.beginPath(); - this._pdfContext.lineTo(this.initX, this.initY); - this._pdfContext.strokeStyle = this._currColor; - this._pdfCanvas.addEventListener("pointermove", this.drawMove); - this._pdfCanvas.addEventListener("pointerup", this.drawUp); - - } - //when user drags - drawMove = (e: PointerEvent): void => { - //x and y mouse movement - let x = this.initX += e.movementX, - y = this.initY += e.movementY; - //connects the point - this._pdfContext.lineTo(x, y); - this._pdfContext.stroke(); - } - - drawUp = (e: PointerEvent) => { - this._pdfContext.closePath(); - this._pdfCanvas.removeEventListener("pointermove", this.drawMove); - this._pdfCanvas.removeEventListener("pointerdown", this.drawDown); - this._pdfCanvas.addEventListener("pointerdown", this.drawDown); - } - - - /** - * highlighting helper function - */ - makeEditableAndHighlight = (colour: string) => { - var range, sel = window.getSelection(); - if (sel.rangeCount && sel.getRangeAt) { - range = sel.getRangeAt(0); - } - document.designMode = "on"; - if (!document.execCommand("HiliteColor", false, colour)) { - document.execCommand("HiliteColor", false, colour); - } - - if (range) { - sel.removeAllRanges(); - sel.addRange(range); - - let obj: Object = { parentDivs: [], spans: [] }; - //@ts-ignore - if (range.commonAncestorContainer.className == 'react-pdf__Page__textContent') { //multiline highlighting case - obj = this.highlightNodes(range.commonAncestorContainer.childNodes) - } else { //single line highlighting case - let parentDiv = range.commonAncestorContainer.parentElement - if (parentDiv) { - if (parentDiv.className == 'react-pdf__Page__textContent') { //when highlight is overwritten - obj = this.highlightNodes(parentDiv.childNodes) - } else { - parentDiv.childNodes.forEach((child) => { - if (child.nodeName == 'SPAN') { - //@ts-ignore - obj.parentDivs.push(parentDiv) - //@ts-ignore - child.id = "highlighted" - //@ts-ignore - obj.spans.push(child) - child.addEventListener("mouseover", this.onEnter); //adds mouseover annotation handler - } - }) - } - } - } - this._pageInfo.divs.push(obj); - - } - document.designMode = "off"; - } - - highlightNodes = (nodes: NodeListOf) => { - let temp = { parentDivs: [], spans: [] } - nodes.forEach((div) => { - div.childNodes.forEach((child) => { - if (child.nodeName == 'SPAN') { - //@ts-ignore - temp.parentDivs.push(div) - //@ts-ignore - child.id = "highlighted" - //@ts-ignore - temp.spans.push(child) - child.addEventListener("mouseover", this.onEnter); //adds mouseover annotation handler - } - }) - - }) - return temp; - } - - /** - * when the cursor enters the highlight, it pops out annotation. ONLY WORKS FOR SINGLE DIV LINES - */ - @action - onEnter = (e: any) => { - let span: HTMLSpanElement = e.toElement; - let index: any; - this._pageInfo.divs.forEach((obj: any) => { - obj.spans.forEach((element: any) => { - if (element == span) { - if (!index) { - index = this._pageInfo.divs.indexOf(obj); - } - } - }) - }) - - if (this._pageInfo.anno.length >= index + 1) { - if (this._currAnno.length == 0) { - this._currAnno.push(this._pageInfo.anno[index]); - } - } else { - if (this._currAnno.length == 0) { //if there are no current annotation - let div = span.offsetParent; - //@ts-ignore - let divX = div.style.left - //@ts-ignore - let divY = div.style.top - //slicing "px" from the end - divX = divX.slice(0, divX.length - 2); //gets X of the DIV element (parent of Span) - divY = divY.slice(0, divY.length - 2); //gets Y of the DIV element (parent of Span) - let annotation = - this._pageInfo.anno.push(annotation); - this._currAnno.push(annotation); - } - } - - } - - /** - * highlight function for highlighting actual text. This works fine. - */ - highlight = (color: string) => { - if (window.getSelection()) { - try { - if (!document.execCommand("hiliteColor", false, color)) { - this.makeEditableAndHighlight(color); - } - } catch (ex) { - this.makeEditableAndHighlight(color) - } - } - } - - /** - * controls the area highlighting (stickies) Kinda temporary - */ - onPointerDown = (e: React.PointerEvent) => { - if (this._toolOn) { - let mouse = e.nativeEvent; - this.initX = mouse.offsetX; - this.initY = mouse.offsetY; - - } - } - - /** - * controls area highlighting and partially highlighting. Kinda temporary - */ - @action - onPointerUp = (e: React.PointerEvent) => { - if (this._highlightToolOn) { - this.highlight("rgba(76, 175, 80, 0.3)"); //highlights to this default color. - this._highlightToolOn = false; - } - if (this._toolOn) { - let mouse = e.nativeEvent; - let finalX = mouse.offsetX; - let finalY = mouse.offsetY; - let width = Math.abs(finalX - this.initX); //width - let height = Math.abs(finalY - this.initY); //height - - //these two if statements are bidirectional dragging. You can drag from any point to another point and generate sticky - if (finalX < this.initX) { - this.initX = finalX; - } - if (finalY < this.initY) { - this.initY = finalY; - } - - if (this._mainDiv.current) { - let sticky = - this._pageInfo.area.push(sticky); - } - this._toolOn = false; - } - this._interactive = true; - } - - /** - * starts drawing the line when user presses down. - */ - onDraw = () => { - if (this._currTool != null) { - this._currTool.style.backgroundColor = "grey"; - } - - if (this._drawTool.current) { - this._currTool = this._drawTool.current; - if (this._drawToolOn) { - this._drawToolOn = false; - this._pdfCanvas.removeEventListener("pointerdown", this.drawDown); - this._pdfCanvas.removeEventListener("pointerup", this.drawUp); - this._pdfCanvas.removeEventListener("pointermove", this.drawMove); - this._drawTool.current.style.backgroundColor = "grey"; - } else { - this._drawToolOn = true; - this._pdfCanvas.addEventListener("pointerdown", this.drawDown); - this._drawTool.current.style.backgroundColor = "cyan"; - } - } - } - - - /** - * for changing color (for ink/pen) - */ - onColorChange = (e: React.PointerEvent) => { - if (e.currentTarget.innerHTML == "Red") { - this._currColor = "red"; - } else if (e.currentTarget.innerHTML == "Blue") { - this._currColor = "blue"; - } else if (e.currentTarget.innerHTML == "Green") { - this._currColor = "green"; - } else if (e.currentTarget.innerHTML == "Black") { - this._currColor = "black"; - } - - } - - - /** - * For highlighting (text drag highlighting) - */ - onHighlight = () => { - this._drawToolOn = false; - if (this._currTool != null) { - this._currTool.style.backgroundColor = "grey"; - } - if (this._highlightTool.current) { - this._currTool = this._drawTool.current; - if (this._highlightToolOn) { - this._highlightToolOn = false; - this._highlightTool.current.style.backgroundColor = "grey"; - } else { - this._highlightToolOn = true; - this._highlightTool.current.style.backgroundColor = "orange"; - } - } - } - - - - - @action - saveThumbnail = () => { - setTimeout(() => { - var me = this; - htmlToImage.toPng(this._mainDiv.current!, - { width: me.props.doc.GetNumber(KeyStore.NativeWidth, 0), height: me.props.doc.GetNumber(KeyStore.NativeHeight, 0), quality: 0.5 }) - .then(function (dataUrl: string) { - me.props.doc.SetData(KeyStore.Thumbnail, new URL(dataUrl), ImageField); - }) - .catch(function (error: any) { - console.error('oops, something went wrong!', error); - }); - }, 1000); - } - - @action - onLoaded = (page: any) => { - if (this._mainDiv.current) { - this._mainDiv.current.childNodes.forEach((element) => { - if (element.nodeName == "DIV") { - element.childNodes[0].childNodes.forEach((e) => { - - if (e instanceof HTMLCanvasElement) { - this._pdfCanvas = e; - this._pdfContext = e.getContext("2d") - - } - - }) - } - }) - } - this._numPages = page.transport.numPages - if (this._perPageInfo.length == 0) { //Makes sure it only runs once - this._perPageInfo = [...Array(this._numPages)] - } - this._loaded = true; - } - - @action - setScaling = (r: any) => { - // bcz: the nativeHeight should really be set when the document is imported. - // also, the native dimensions could be different for different pages of the PDF - // so this design is flawed. - var nativeWidth = this.props.doc.GetNumber(KeyStore.NativeWidth, 0); - if (!this.props.doc.GetNumber(KeyStore.NativeHeight, 0)) { - this.props.doc.SetNumber(KeyStore.NativeHeight, nativeWidth * r.entry.height / r.entry.width); - } - if (!this.props.doc.GetT(KeyStore.Thumbnail, ImageField)) { - this.saveThumbnail(); - } - } - - @computed - get uIButtons() { - return ( -
- - - - - - - - - -
); - } - - @computed - get pdfContent() { - const renderHeight = 2400; - let pdfUrl = this.props.doc.GetT(this.props.fieldKey, PDFField); - let xf = this.props.doc.GetNumber(KeyStore.NativeHeight, 0) / renderHeight; - return
- - - {({ measureRef }) => -
- -
- } -
-
-
; - } - - @computed - get pdfRenderer() { - let proxy = this._loaded ? (null) : this.imageProxyRenderer; - let pdfUrl = this.props.doc.GetT(this.props.fieldKey, PDFField); - if ((!this._interactive && proxy) || !pdfUrl || pdfUrl == FieldWaiting) { - return proxy; - } - return [ - this._pageInfo.area.filter(() => this._pageInfo.area).map((element: any) => element), - this._currAnno.map((element: any) => element), - this.uIButtons, -
- {this.pdfContent} - {proxy} -
- ]; - } - - @computed - get imageProxyRenderer() { - let field = this.props.doc.Get(KeyStore.Thumbnail); - if (field) { - let path = field == FieldWaiting ? "https://image.flaticon.com/icons/svg/66/66163.svg" : - field instanceof ImageField ? field.Data.href : "http://cs.brown.edu/people/bcz/prairie.jpg"; - return ; - } - return (null); - } - - render() { - return ( -
- {this.pdfRenderer} -
- ); - } - -} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From c4eff83d814b1f9b94b7fc75ca06e8f0474de20d Mon Sep 17 00:00:00 2001 From: bob Date: Fri, 8 Mar 2019 11:44:28 -0500 Subject: working version of pdfs with annotations. --- src/client/documents/Documents.ts | 4 +- src/client/views/InkingCanvas.tsx | 17 ++-- .../views/collections/CollectionFreeFormView.scss | 2 +- .../views/collections/CollectionFreeFormView.tsx | 32 +++---- src/client/views/collections/CollectionPDFView.tsx | 74 +++++++++++++++++ src/client/views/collections/CollectionView.tsx | 78 ++++++++++------- src/client/views/nodes/DocumentView.tsx | 3 +- src/client/views/nodes/PDFBox.tsx | 97 ++++++++-------------- src/fields/InkField.ts | 1 + src/fields/KeyStore.ts | 3 + 10 files changed, 193 insertions(+), 118 deletions(-) create mode 100644 src/client/views/collections/CollectionPDFView.tsx (limited to 'src/client/views/nodes') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index f73823603..fb1c3d867 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -16,6 +16,7 @@ import { Field } from "../../fields/Field"; import { KeyValueBox } from "../views/nodes/KeyValueBox" import { PDFField } from "../../fields/PDFField"; import { PDFBox } from "../views/nodes/PDFBox"; +import { CollectionPDFView } from "../views/collections/CollectionPDFView"; export interface DocumentOptions { x?: number; @@ -97,8 +98,9 @@ export namespace Documents { } function GetPdfPrototype(): Document { if (!pdfProto) { - pdfProto = setupPrototypeOptions(pdfProtoId, "PDF_PROTO", CollectionView.LayoutString("AnnotationsKey"), + pdfProto = setupPrototypeOptions(pdfProtoId, "PDF_PROTO", CollectionPDFView.LayoutString("AnnotationsKey"), { x: 0, y: 0, nativeWidth: 600, width: 300, layoutKeys: [KeyStore.Data, KeyStore.Annotations] }); + pdfProto.SetNumber(KeyStore.Page, 1); pdfProto.SetText(KeyStore.BackgroundLayout, PDFBox.LayoutString()); } return pdfProto; diff --git a/src/client/views/InkingCanvas.tsx b/src/client/views/InkingCanvas.tsx index baf1567b7..14a779837 100644 --- a/src/client/views/InkingCanvas.tsx +++ b/src/client/views/InkingCanvas.tsx @@ -66,7 +66,8 @@ export class InkingCanvas extends React.Component { pathData: [point], color: InkingControl.Instance.selectedColor, width: InkingControl.Instance.selectedWidth, - tool: InkingControl.Instance.selectedTool + tool: InkingControl.Instance.selectedTool, + page: this.props.Document.GetNumber(KeyStore.CurPage, 0) }); this.inkData = data; this._isDrawing = true; @@ -137,15 +138,17 @@ export class InkingCanvas extends React.Component { // parse data from server let paths: Array = [] + let curPage = this.props.Document.GetNumber(KeyStore.CurPage, 0) Array.from(lines).map(item => { let id = item[0]; let strokeData = item[1]; - paths.push() + if (strokeData.page == 0 || strokeData.page == curPage) + paths.push() }) return ( diff --git a/src/client/views/collections/CollectionFreeFormView.scss b/src/client/views/collections/CollectionFreeFormView.scss index f496517f5..b059163ed 100644 --- a/src/client/views/collections/CollectionFreeFormView.scss +++ b/src/client/views/collections/CollectionFreeFormView.scss @@ -34,7 +34,7 @@ border-style: solid; box-sizing: border-box; - position: relative; + position: absolute; top: 0; left: 0; width: 100%; diff --git a/src/client/views/collections/CollectionFreeFormView.tsx b/src/client/views/collections/CollectionFreeFormView.tsx index 74e70ef33..782313e55 100644 --- a/src/client/views/collections/CollectionFreeFormView.tsx +++ b/src/client/views/collections/CollectionFreeFormView.tsx @@ -12,6 +12,7 @@ import { undoBatch } from "../../util/UndoManager"; import { CollectionDockingView } from "../collections/CollectionDockingView"; import { CollectionSchemaView } from "../collections/CollectionSchemaView"; import { CollectionView } from "../collections/CollectionView"; +import { CollectionPDFView } from "../collections/CollectionPDFView"; import { InkingCanvas } from "../InkingCanvas"; import { CollectionFreeFormDocumentView } from "../nodes/CollectionFreeFormDocumentView"; import { DocumentView } from "../nodes/DocumentView"; @@ -224,21 +225,24 @@ export class CollectionFreeFormView extends CollectionViewBase { @computed get views() { + var curPage = this.props.Document.GetNumber(KeyStore.CurPage, 1); const lvalue = this.props.Document.GetT>(this.props.fieldKey, ListField); if (lvalue && lvalue != FieldWaiting) { return lvalue.Data.map(doc => { - return (); + var page = doc.GetNumber(KeyStore.Page, 0); + return (page != curPage && page != 0) ? (null) : + (); }) } return null; @@ -248,7 +252,7 @@ export class CollectionFreeFormView extends CollectionViewBase { get backgroundView() { return !this.backgroundLayout ? (null) : ( { + + public static LayoutString(fieldKey: string = "DataKey") { + return `<${CollectionPDFView.name} Document={Document} + ScreenToLocalTransform={ScreenToLocalTransform} fieldKey={${fieldKey}} panelWidth={PanelWidth} panelHeight={PanelHeight} isSelected={isSelected} select={select} bindings={bindings} + isTopMost={isTopMost} SelectOnLoad={selectOnLoad} BackgroundView={BackgroundView} focus={focus}/>`; + } + + @action onPageBack = () => this.curPage > 1 ? this.props.Document.SetNumber(KeyStore.CurPage, this.curPage - 1) : 0; + @action onPageForward = () => this.curPage < this.numPages ? this.props.Document.SetNumber(KeyStore.CurPage, this.curPage + 1) : 0; + + @computed private get curPage() { return this.props.Document.GetNumber(KeyStore.CurPage, 0); } + @computed private get numPages() { return this.props.Document.GetNumber(KeyStore.NumPages, 0); } + @computed private get uIButtons() { + return ( +
+ + +
); + } + + // CollectionView API starts here... + + public active: () => boolean = () => CollectionView.Active(this); + + @action + addDocument = (doc: Document): void => { + doc.SetNumber(KeyStore.Page, this.curPage); + CollectionView.AddDocument(this.props, doc); + } + + @action removeDocument = (doc: Document): boolean => { + return CollectionView.RemoveDocument(this.props, doc); + } + + specificContextMenu = (e: React.MouseEvent): void => { + if (!e.isPropagationStopped) { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7 + ContextMenu.Instance.addItem({ description: "PDFOptions", event: () => { } }) + } + } + + get collectionViewType(): CollectionViewType { return CollectionViewType.Freeform; } + + + @computed + get subView(): any { return CollectionView.SubView(this); } + + render() { + return (
+ {this.subView} + {this.props.isSelected() ? this.uIButtons : (null)} +
) + } +} \ No newline at end of file diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 8d175ee35..504538e85 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -1,4 +1,4 @@ -import { action } from "mobx"; +import { action, computed } from "mobx"; import { observer } from "mobx-react"; import { Document } from "../../../fields/Document"; import { ListField } from "../../../fields/ListField"; @@ -28,32 +28,42 @@ export const COLLECTION_BORDER_WIDTH = 2; export class CollectionView extends React.Component { public static LayoutString(fieldKey: string = "DataKey") { - return ``; } - public active = () => { - var isSelected = this.props.isSelected(); - var childSelected = SelectionManager.SelectedDocuments().some(view => view.props.ContainingCollectionView == this); - var topMost = this.props.isTopMost; + + public active: () => boolean = () => CollectionView.Active(this); + + public static Active(self: CollectionView): boolean { + var isSelected = self.props.isSelected(); + var childSelected = SelectionManager.SelectedDocuments().some(view => view.props.ContainingCollectionView == self); + var topMost = self.props.isTopMost; return isSelected || childSelected || topMost; } - @action + addDocument = (doc: Document): void => { - if (this.props.Document.Get(this.props.fieldKey) instanceof Field) { + CollectionView.AddDocument(this.props, doc); + } + removeDocument = (doc: Document): boolean => { + return CollectionView.RemoveDocument(this.props, doc); + } + + @action + public static AddDocument(props: CollectionViewProps, doc: Document) { + if (props.Document.Get(props.fieldKey) instanceof Field) { //TODO This won't create the field if it doesn't already exist - const value = this.props.Document.GetData(this.props.fieldKey, ListField, new Array()) + const value = props.Document.GetData(props.fieldKey, ListField, new Array()) value.push(doc); } else { - this.props.Document.SetData(this.props.fieldKey, [doc], ListField); + props.Document.SetData(props.fieldKey, [doc], ListField); } } - @action - removeDocument = (doc: Document): boolean => { + public static RemoveDocument(props: CollectionViewProps, doc: Document): boolean { //TODO This won't create the field if it doesn't already exist - const value = this.props.Document.GetData(this.props.fieldKey, ListField, new Array()) + const value = props.Document.GetData(props.fieldKey, ListField, new Array()) let index = -1; for (let i = 0; i < value.length; i++) { if (value[i].Id == doc.Id) { @@ -98,36 +108,40 @@ export class CollectionView extends React.Component { } } - render() { - let viewType = this.collectionViewType; - let subView: JSX.Element; + @computed + get subView() { return CollectionView.SubView(this); } + + public static SubView(self: CollectionView) { + let viewType = self.collectionViewType; + let subView = (null); switch (viewType) { case CollectionViewType.Freeform: - subView = () + subView = () break; case CollectionViewType.Schema: - subView = () + subView = () break; case CollectionViewType.Docking: - subView = () + subView = () break; case CollectionViewType.Tree: - subView = () - break; - default: - subView =
+ subView = () break; } + return subView; + } + + render() { return (
- {subView} + {this.subView}
) } } \ No newline at end of file diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index 20526c256..41e93df35 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -12,6 +12,7 @@ import { CollectionDockingView } from "../collections/CollectionDockingView"; import { CollectionFreeFormView } from "../collections/CollectionFreeFormView"; import { CollectionSchemaView } from "../collections/CollectionSchemaView"; import { CollectionView, CollectionViewType } from "../collections/CollectionView"; +import { CollectionPDFView } from "../collections/CollectionPDFView"; import { ContextMenu } from "../ContextMenu"; import { FormattedTextBox } from "../nodes/FormattedTextBox"; import { ImageBox } from "../nodes/ImageBox"; @@ -195,7 +196,7 @@ export class DocumentView extends React.Component { } @computed get mainContent() { return { //very useful for keeping track of X and y position throughout the PDF Canvas private initX: number = 0; private initY: number = 0; + private initPage: boolean = false; //checks if tool is on private _toolOn: boolean = false; //checks if tool is on @@ -77,47 +77,36 @@ export class PDFBox extends React.Component { private _highlightTool = React.createRef(); //highlighter button reference private _highlightToolOn: boolean = false; private _pdfCanvas: any; + private _reactionDisposer: Opt; @observable private _perPageInfo: Object[] = []; //stores pageInfo @observable private _pageInfo: any = { area: [], divs: [], anno: [] }; //divs is array of objects linked to anno @observable private _currAnno: any = [] - @observable private _page: number = 1; //default is the first page. - @observable private _numPages: number = 1; //default number of pages @observable private _interactive: boolean = false; @observable private _loaded: boolean = false; - /** - * for pagination backwards - */ - @action - onPageBack = () => { - if (this._page > 1) { - this._page -= 1; - this._currAnno = []; - this._perPageInfo[this._page] = this._pageInfo - this._pageInfo = { area: [], divs: [], anno: [] }; //resets the object to default - if (this._perPageInfo[this._page - 1]) { - this._pageInfo = this._perPageInfo[this._page - 1]; - } - this.saveThumbnail(); - } + @computed private get curPage() { return this.props.doc.GetNumber(KeyStore.CurPage, 0); } + + componentDidMount() { + this._reactionDisposer = reaction( + () => this.curPage, + () => { + if (this.curPage && this.initPage) { + this.saveThumbnail(); + this._interactive = true; + } else { + if (this.curPage) + this.initPage = true; + } + }, + { fireImmediately: true }); + } - /** - * for pagination forwards - */ - @action - onPageForward = () => { - if (this._page < this._numPages) { - this._page += 1; - this._currAnno = []; - this._perPageInfo[this._page - 2] = this._pageInfo; - this._pageInfo = { area: [], divs: [], anno: [] }; //resets the object to default - if (this._perPageInfo[this._page - 1]) { - this._pageInfo = this._perPageInfo[this._page - 1]; - } - this.saveThumbnail(); + componentWillUnmount() { + if (this._reactionDisposer) { + this._reactionDisposer(); } } @@ -386,8 +375,6 @@ export class PDFBox extends React.Component { } - - @action saveThumbnail = () => { setTimeout(() => { @@ -420,9 +407,11 @@ export class PDFBox extends React.Component { } }) } - this._numPages = page._transport.numPages; + + // bcz: the number of pages should really be set when the document is imported. + this.props.doc.SetNumber(KeyStore.NumPages, page._transport.numPages); if (this._perPageInfo.length == 0) { //Makes sure it only runs once - this._perPageInfo = [...Array(this._numPages)] + this._perPageInfo = [...Array(page._transport.numPages)] } this._loaded = true; } @@ -441,24 +430,9 @@ export class PDFBox extends React.Component { } } - @computed - get uIButtons() { - return ( -
- - - - - - - - - -
); - } - @computed get pdfContent() { + const page = this.curPage; const renderHeight = 2400; let pdfUrl = this.props.doc.GetT(this.props.fieldKey, PDFField); let xf = this.props.doc.GetNumber(KeyStore.NativeHeight, 0) / renderHeight; @@ -467,7 +441,7 @@ export class PDFBox extends React.Component { {({ measureRef }) =>
- +
}
@@ -485,7 +459,6 @@ export class PDFBox extends React.Component { return [ this._pageInfo.area.filter(() => this._pageInfo.area).map((element: any) => element), this._currAnno.map((element: any) => element), - this.uIButtons,
{this.pdfContent} {proxy} diff --git a/src/fields/InkField.ts b/src/fields/InkField.ts index a475e2aae..1108a04a5 100644 --- a/src/fields/InkField.ts +++ b/src/fields/InkField.ts @@ -13,6 +13,7 @@ export interface StrokeData { color: string; width: string; tool: InkTool; + page: number; } export type StrokeMap = Map; diff --git a/src/fields/KeyStore.ts b/src/fields/KeyStore.ts index 259d1acaf..f67257093 100644 --- a/src/fields/KeyStore.ts +++ b/src/fields/KeyStore.ts @@ -4,6 +4,7 @@ export namespace KeyStore { export const Prototype = new Key("Prototype"); export const X = new Key("X"); export const Y = new Key("Y"); + export const Page = new Key("Page"); export const Title = new Key("Title"); export const Author = new Key("Author"); export const PanX = new Key("PanX"); @@ -27,5 +28,7 @@ export namespace KeyStore { export const ActiveFrame = new Key("ActiveFrame"); export const DocumentText = new Key("DocumentText"); export const Thumbnail = new Key("Thumbnail"); + export const CurPage = new Key("CurPage"); + export const NumPages = new Key("NumPages"); export const Ink = new Key("Ink"); } -- cgit v1.2.3-70-g09d2 From d3e66a67406447682c59045a0130d884fe1045a6 Mon Sep 17 00:00:00 2001 From: bob Date: Fri, 8 Mar 2019 13:03:57 -0500 Subject: bug fixes and hack to make context menu appear again --- src/client/documents/Documents.ts | 2 +- src/client/views/collections/CollectionPDFView.tsx | 35 ++++----------- src/client/views/collections/CollectionView.tsx | 52 +++++----------------- src/client/views/nodes/PDFBox.tsx | 4 +- 4 files changed, 24 insertions(+), 69 deletions(-) (limited to 'src/client/views/nodes') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index fb1c3d867..fc210e9a2 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -100,7 +100,7 @@ export namespace Documents { if (!pdfProto) { pdfProto = setupPrototypeOptions(pdfProtoId, "PDF_PROTO", CollectionPDFView.LayoutString("AnnotationsKey"), { x: 0, y: 0, nativeWidth: 600, width: 300, layoutKeys: [KeyStore.Data, KeyStore.Annotations] }); - pdfProto.SetNumber(KeyStore.Page, 1); + pdfProto.SetNumber(KeyStore.CurPage, 1); pdfProto.SetText(KeyStore.BackgroundLayout, PDFBox.LayoutString()); } return pdfProto; diff --git a/src/client/views/collections/CollectionPDFView.tsx b/src/client/views/collections/CollectionPDFView.tsx index 90da43921..7fd9f0f11 100644 --- a/src/client/views/collections/CollectionPDFView.tsx +++ b/src/client/views/collections/CollectionPDFView.tsx @@ -1,20 +1,11 @@ import { action, computed } from "mobx"; import { observer } from "mobx-react"; import { Document } from "../../../fields/Document"; -import { ListField } from "../../../fields/ListField"; -import { SelectionManager } from "../../util/SelectionManager"; -import { ContextMenu } from "../ContextMenu"; -import React = require("react"); import { KeyStore } from "../../../fields/KeyStore"; -import { NumberField } from "../../../fields/NumberField"; -import { CollectionFreeFormView } from "./CollectionFreeFormView"; -import { CollectionDockingView } from "./CollectionDockingView"; -import { CollectionSchemaView } from "./CollectionSchemaView"; +import { ContextMenu } from "../ContextMenu"; +import { CollectionView, CollectionViewType } from "./CollectionView"; import { CollectionViewProps } from "./CollectionViewBase"; -import { CollectionTreeView } from "./CollectionTreeView"; -import { Field } from "../../../fields/Field"; -import { CollectionViewType, CollectionView } from "./CollectionView"; -import { JSXElement } from "babel-types"; +import React = require("react"); @observer @@ -39,30 +30,20 @@ export class CollectionPDFView extends React.Component {
); } - // CollectionView API starts here... + // "inherited" CollectionView API starts here... public active: () => boolean = () => CollectionView.Active(this); - @action - addDocument = (doc: Document): void => { - doc.SetNumber(KeyStore.Page, this.curPage); - CollectionView.AddDocument(this.props, doc); - } - - @action removeDocument = (doc: Document): boolean => { - return CollectionView.RemoveDocument(this.props, doc); - } + addDocument = (doc: Document): void => { CollectionView.AddDocument(this.props, doc); } + removeDocument = (doc: Document): boolean => { return CollectionView.RemoveDocument(this.props, doc); } specificContextMenu = (e: React.MouseEvent): void => { - if (!e.isPropagationStopped) { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7 - ContextMenu.Instance.addItem({ description: "PDFOptions", event: () => { } }) + if (!e.isPropagationStopped() && this.props.Document.Id != "mainDoc") { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7 + ContextMenu.Instance.addItem({ description: "PDFOptions", event: () => { } }); } } get collectionViewType(): CollectionViewType { return CollectionViewType.Freeform; } - - - @computed get subView(): any { return CollectionView.SubView(this); } render() { diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 504538e85..49df04163 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -34,6 +34,9 @@ export class CollectionView extends React.Component { } public active: () => boolean = () => CollectionView.Active(this); + addDocument = (doc: Document): void => { CollectionView.AddDocument(this.props, doc); } + removeDocument = (doc: Document): boolean => { return CollectionView.RemoveDocument(this.props, doc); } + get subView() { return CollectionView.SubView(this); } public static Active(self: CollectionView): boolean { var isSelected = self.props.isSelected(); @@ -42,15 +45,9 @@ export class CollectionView extends React.Component { return isSelected || childSelected || topMost; } - addDocument = (doc: Document): void => { - CollectionView.AddDocument(this.props, doc); - } - removeDocument = (doc: Document): boolean => { - return CollectionView.RemoveDocument(this.props, doc); - } - @action public static AddDocument(props: CollectionViewProps, doc: Document) { + doc.SetNumber(KeyStore.Page, props.Document.GetNumber(KeyStore.CurPage, 0)); if (props.Document.Get(props.fieldKey) instanceof Field) { //TODO This won't create the field if it doesn't already exist const value = props.Document.GetData(props.fieldKey, ListField, new Array()) @@ -94,13 +91,8 @@ export class CollectionView extends React.Component { } } - set collectionViewType(type: CollectionViewType) { - let Document = this.props.Document; - Document.SetData(KeyStore.ViewType, type, NumberField); - } - specificContextMenu = (e: React.MouseEvent): void => { - if (!e.isPropagationStopped) { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7 + if (!e.isPropagationStopped() && this.props.Document.Id != "mainDoc") { // need to test this because GoldenLayout causes a parallel hierarchy in the React DOM for its children and the main document view7 ContextMenu.Instance.addItem({ description: "Freeform", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Freeform) }) ContextMenu.Instance.addItem({ description: "Schema", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Schema) }) ContextMenu.Instance.addItem({ description: "Treeview", event: () => this.props.Document.SetNumber(KeyStore.ViewType, CollectionViewType.Tree) }) @@ -108,35 +100,15 @@ export class CollectionView extends React.Component { } } - @computed - get subView() { return CollectionView.SubView(this); } - public static SubView(self: CollectionView) { - let viewType = self.collectionViewType; - let subView = (null); - switch (viewType) { - case CollectionViewType.Freeform: - subView = () - break; - case CollectionViewType.Schema: - subView = () - break; - case CollectionViewType.Docking: - subView = () - break; - case CollectionViewType.Tree: - subView = () - break; + let subProps = { ...self.props, addDocument: self.addDocument, removeDocument: self.removeDocument, active: self.active, CollectionView: self } + switch (self.collectionViewType) { + case CollectionViewType.Freeform: return () + case CollectionViewType.Schema: return () + case CollectionViewType.Docking: return () + case CollectionViewType.Tree: return () } - return subView; + return (null); } render() { diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index fb3e24659..70a70c7c8 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -432,7 +432,9 @@ export class PDFBox extends React.Component { @computed get pdfContent() { - const page = this.curPage; + let page = this.curPage; + if (page == 0) + page = 1; const renderHeight = 2400; let pdfUrl = this.props.doc.GetT(this.props.fieldKey, PDFField); let xf = this.props.doc.GetNumber(KeyStore.NativeHeight, 0) / renderHeight; -- cgit v1.2.3-70-g09d2 From b9cfa458a6535e7ee0ff8b81398afa1e123cf458 Mon Sep 17 00:00:00 2001 From: Andrew Kim Date: Sat, 9 Mar 2019 18:21:06 -0500 Subject: added audio and video nodes --- src/client/documents/Documents.ts | 35 ++++++++++++++++++++ src/client/views/Main.tsx | 11 ++++++- src/client/views/collections/CollectionView.tsx | 2 ++ src/client/views/nodes/AudioBox.scss | 4 +++ src/client/views/nodes/AudioBox.tsx | 44 +++++++++++++++++++++++++ src/client/views/nodes/DocumentView.tsx | 4 ++- src/client/views/nodes/FieldView.tsx | 11 +++++++ src/client/views/nodes/VideoBox.scss | 4 +++ src/client/views/nodes/VideoBox.tsx | 43 ++++++++++++++++++++++++ src/fields/AudioField.ts | 31 +++++++++++++++++ src/fields/VideoField.ts | 30 +++++++++++++++++ src/server/Message.ts | 2 +- src/server/ServerUtil.ts | 6 ++++ 13 files changed, 224 insertions(+), 3 deletions(-) create mode 100644 src/client/views/nodes/AudioBox.scss create mode 100644 src/client/views/nodes/AudioBox.tsx create mode 100644 src/client/views/nodes/VideoBox.scss create mode 100644 src/client/views/nodes/VideoBox.tsx create mode 100644 src/fields/AudioField.ts create mode 100644 src/fields/VideoField.ts (limited to 'src/client/views/nodes') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 1d24ff7d2..f81ad3188 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -15,6 +15,10 @@ import { Key } from "../../fields/Key" import { Field } from "../../fields/Field"; import { KeyValueBox } from "../views/nodes/KeyValueBox" import { KVPField } from "../../fields/KVPField"; +import { VideoField } from "../../fields/VideoField" +import { VideoBox } from "../views/nodes/VideoBox"; +import { AudioField } from "../../fields/AudioField"; +import { AudioBox } from "../views/nodes/AudioBox"; export interface DocumentOptions { x?: number; @@ -38,11 +42,15 @@ export namespace Documents { let webProto: Document; let collProto: Document; let kvpProto: Document; + let videoProto: Document; + let audioProto: Document; const textProtoId = "textProto"; const imageProtoId = "imageProto"; const webProtoId = "webProto"; const collProtoId = "collectionProto"; const kvpProtoId = "kvpProto"; + const videoProtoId = "videoProto" + const audioProtoId = "audioProto"; export function initProtos(mainDocId: string, callback: (mainDoc?: Document) => void) { Server.GetFields([collProtoId, textProtoId, imageProtoId, mainDocId], (fields) => { @@ -108,6 +116,17 @@ export namespace Documents { kvpProto = setupPrototypeOptions(kvpProtoId, "KVP_PROTO", KeyValueBox.LayoutString(), { x: 0, y: 0, width: 300, height: 150, layoutKeys: [KeyStore.Data] }) } + function GetVideoPrototype(): Document { + return videoProto ? videoProto : + videoProto = setupPrototypeOptions(videoProtoId, "VIDEO_PROTO", VideoBox.LayoutString(), + { x: 0, y: 0, width: 300, height: 150, layoutKeys: [KeyStore.Data] }) + } + function GetAudioPrototype(): Document { + return audioProto ? audioProto : + audioProto = setupPrototypeOptions(audioProtoId, "AUDIO_PROTO", AudioBox.LayoutString(), + { x: 0, y: 0, width: 300, height: 150, layoutKeys: [KeyStore.Data] }) + } + export function ImageDocument(url: string, options: DocumentOptions = {}) { let doc = SetInstanceOptions(GetImagePrototype(), { ...options, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] }, @@ -117,6 +136,22 @@ export namespace Documents { doc.SetText(KeyStore.OverlayLayout, FixedCaption()); return doc; } + export function VideoDocument(url: string, options: DocumentOptions = {}){ + let doc = SetInstanceOptions(GetVideoPrototype(), { ...options, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] }, + new URL(url), VideoField); + doc.SetText(KeyStore.Caption, "my caption..."); + doc.SetText(KeyStore.BackgroundLayout, EmbeddedCaption()); + doc.SetText(KeyStore.OverlayLayout, FixedCaption()); + return doc; + } + export function AudioDocument(url: string, options: DocumentOptions = {}){ + let doc = SetInstanceOptions(GetAudioPrototype(), { ...options, layoutKeys: [KeyStore.Data, KeyStore.Annotations, KeyStore.Caption] }, + new URL(url), AudioField); + doc.SetText(KeyStore.Caption, "my caption..."); + doc.SetText(KeyStore.BackgroundLayout, EmbeddedCaption()); + doc.SetText(KeyStore.OverlayLayout, FixedCaption()); + return doc; + } export function TextDocument(options: DocumentOptions = {}) { return SetInstanceOptions(GetTextPrototype(), options, "", TextField); } diff --git a/src/client/views/Main.tsx b/src/client/views/Main.tsx index d845fa7a3..a52047631 100644 --- a/src/client/views/Main.tsx +++ b/src/client/views/Main.tsx @@ -52,13 +52,16 @@ Documents.initProtos(mainDocId, (res?: Document) => { let imgurl = "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3a/Cat03.jpg/1200px-Cat03.jpg"; let weburl = "https://cs.brown.edu/courses/cs166/"; + let audiourl = "http://techslides.com/demos/samples/sample.mp3"; + let videourl = "http://techslides.com/demos/sample-videos/small.mp4"; let clearDatabase = action(() => Utils.Emit(Server.Socket, MessageStore.DeleteAll, {})) let addTextNode = action(() => Documents.TextDocument({ width: 200, height: 200, title: "a text note" })) let addColNode = action(() => Documents.FreeformDocument([], { width: 200, height: 200, title: "a freeform collection" })); let addSchemaNode = action(() => Documents.SchemaDocument([Documents.TextDocument()], { width: 200, height: 200, title: "a schema collection" })); + let addVideoNode = action(() => Documents.VideoDocument(videourl, {width: 200, height:200, title: "video node"})); let addImageNode = action(() => Documents.ImageDocument(imgurl, { width: 200, height: 200, title: "an image of a cat" })); let addWebNode = action(() => Documents.WebDocument(weburl, { width: 200, height: 200, title: "a sample web page" })); - + let addAudioNode = action(() => Documents.AudioDocument(audiourl,{ width: 200, height: 200, title: "audio node" } )) let addClick = (creator: () => Document) => action(() => mainfreeform.GetList(KeyStore.Data, []).push(creator()) ); @@ -67,6 +70,8 @@ Documents.initProtos(mainDocId, (res?: Document) => { let webRef = React.createRef(); let textRef = React.createRef(); let schemaRef = React.createRef(); + let videoRef = React.createRef(); + let audioRef = React.createRef(); let colRef = React.createRef(); ReactDOM.render(( @@ -94,6 +99,10 @@ Documents.initProtos(mainDocId, (res?: Document) => {
+
+
+
+
), diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx index 31824763d..454d547ef 100644 --- a/src/client/views/collections/CollectionView.tsx +++ b/src/client/views/collections/CollectionView.tsx @@ -19,6 +19,8 @@ export enum CollectionViewType { Freeform, Schema, Docking, + Video, + Audio, Tree } diff --git a/src/client/views/nodes/AudioBox.scss b/src/client/views/nodes/AudioBox.scss new file mode 100644 index 000000000..704cdc31c --- /dev/null +++ b/src/client/views/nodes/AudioBox.scss @@ -0,0 +1,4 @@ +.audiobox-cont{ + height: 100%; + width: 100%; +} \ No newline at end of file diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx new file mode 100644 index 000000000..f7d89843d --- /dev/null +++ b/src/client/views/nodes/AudioBox.tsx @@ -0,0 +1,44 @@ +import React = require("react") +import { FieldViewProps, FieldView } from './FieldView'; +import { FieldWaiting } from '../../../fields/Field'; +import { observer } from "mobx-react" +import { ContextMenu } from "../../views/ContextMenu"; +import { observable, action } from 'mobx'; +import { KeyStore } from '../../../fields/KeyStore'; +import { AudioField } from "../../../fields/AudioField"; +import "./AudioBox.scss" +import { NumberField } from "../../../fields/NumberField"; + +@observer +export class AudioBox extends React.Component { + + public static LayoutString() { return FieldView.LayoutString(AudioBox) } + + constructor(props: FieldViewProps) { + super(props); + } + + + + componentDidMount() { + } + + componentWillUnmount() { + } + + + render() { + let field = this.props.doc.Get(this.props.fieldKey) + let path = field == FieldWaiting ? "http://techslides.com/demos/samples/sample.mp3": + field instanceof AudioField ? field.Data.href : "http://techslides.com/demos/samples/sample.mp3"; + + return ( +
+ +
+ ) + } +} \ No newline at end of file diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx index e01e1d4cd..b22435f1a 100644 --- a/src/client/views/nodes/DocumentView.tsx +++ b/src/client/views/nodes/DocumentView.tsx @@ -15,6 +15,8 @@ import { CollectionView, CollectionViewType } from "../collections/CollectionVie import { ContextMenu } from "../ContextMenu"; import { FormattedTextBox } from "../nodes/FormattedTextBox"; import { ImageBox } from "../nodes/ImageBox"; +import { VideoBox } from "../nodes/VideoBox"; +import { AudioBox } from "../nodes/AudioBox"; import { Documents } from "../../documents/Documents" import { KeyValueBox } from "./KeyValueBox" import { WebBox } from "../nodes/WebBox"; @@ -194,7 +196,7 @@ export class DocumentView extends React.Component { } @computed get mainContent() { return { } else if (field instanceof WebField) { return + } + else if (field instanceof VideoField){ + return + } + else if (field instanceof AudioField){ + return } // bcz: this belongs here, but it doesn't render well so taking it out for now // else if (field instanceof HtmlField) { diff --git a/src/client/views/nodes/VideoBox.scss b/src/client/views/nodes/VideoBox.scss new file mode 100644 index 000000000..7306450d9 --- /dev/null +++ b/src/client/views/nodes/VideoBox.scss @@ -0,0 +1,4 @@ +.videobox-cont{ + width: 100%; + height: 100%; +} \ No newline at end of file diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx new file mode 100644 index 000000000..22ff5c5ad --- /dev/null +++ b/src/client/views/nodes/VideoBox.tsx @@ -0,0 +1,43 @@ +import React = require("react") +import { FieldViewProps, FieldView } from './FieldView'; +import { FieldWaiting } from '../../../fields/Field'; +import { observer } from "mobx-react" +import { VideoField } from '../../../fields/VideoField'; +import "./VideoBox.scss" +import { ContextMenu } from "../../views/ContextMenu"; +import { observable, action } from 'mobx'; +import { KeyStore } from '../../../fields/KeyStore'; + +@observer +export class VideoBox extends React.Component { + + public static LayoutString() { return FieldView.LayoutString(VideoBox) } + + constructor(props: FieldViewProps) { + super(props); + } + + + + componentDidMount() { + } + + componentWillUnmount() { + } + + + render() { + let field = this.props.doc.Get(this.props.fieldKey) + let path = field == FieldWaiting ? "http://techslides.com/demos/sample-videos/small.mp4": + field instanceof VideoField ? field.Data.href : "http://techslides.com/demos/sample-videos/small.mp4"; + + return ( +
+ +
+ ) + } +} \ No newline at end of file diff --git a/src/fields/AudioField.ts b/src/fields/AudioField.ts new file mode 100644 index 000000000..aefcc15c1 --- /dev/null +++ b/src/fields/AudioField.ts @@ -0,0 +1,31 @@ +import { BasicField } from "./BasicField"; +import { Field, FieldId } from "./Field"; +import { Types } from "../server/Message"; + +export class AudioField extends BasicField { + constructor(data: URL | undefined = undefined, id?: FieldId, save: boolean = true) { + super(data == undefined ? new URL("http://techslides.com/demos/samples/sample.mp3") : data, save, id); + } + + toString(): string { + return this.Data.href; + } + + + ToScriptString(): string { + return `new AudioField("${this.Data}")`; + } + + Copy(): Field { + return new AudioField(this.Data); + } + + ToJson(): { type: Types, data: URL, _id: string } { + return { + type: Types.Audio, + data: this.Data, + _id: this.Id + } + } + +} \ No newline at end of file diff --git a/src/fields/VideoField.ts b/src/fields/VideoField.ts new file mode 100644 index 000000000..5f4ae19bf --- /dev/null +++ b/src/fields/VideoField.ts @@ -0,0 +1,30 @@ +import { BasicField } from "./BasicField"; +import { Field, FieldId } from "./Field"; +import { Types } from "../server/Message"; + +export class VideoField extends BasicField { + constructor(data: URL | undefined = undefined, id?: FieldId, save: boolean = true) { + super(data == undefined ? new URL("http://techslides.com/demos/sample-videos/small.mp4") : data, save, id); + } + + toString(): string { + return this.Data.href; + } + + ToScriptString(): string { + return `new VideoField("${this.Data}")`; + } + + Copy(): Field { + return new VideoField(this.Data); + } + + ToJson(): { type: Types, data: URL, _id: string } { + return { + type: Types.Video, + data: this.Data, + _id: this.Id + } + } + +} \ No newline at end of file diff --git a/src/server/Message.ts b/src/server/Message.ts index 148e6e723..f85f56dd2 100644 --- a/src/server/Message.ts +++ b/src/server/Message.ts @@ -45,7 +45,7 @@ export class GetFieldArgs { } export enum Types { - Number, List, Key, Image, Web, Document, Text, RichText, DocumentReference, Html + Number, List, Key, Image, Web, Document, Text, RichText, DocumentReference, Html, Video, Audio } export class DocumentTransfer implements Transferable { diff --git a/src/server/ServerUtil.ts b/src/server/ServerUtil.ts index a53fb5d2b..2e681fece 100644 --- a/src/server/ServerUtil.ts +++ b/src/server/ServerUtil.ts @@ -11,6 +11,8 @@ import { Types } from './Message'; import { Utils } from '../Utils'; import { HtmlField } from '../fields/HtmlField'; import { WebField } from '../fields/WebField'; +import { AudioField } from '../fields/AudioField'; +import { VideoField } from '../fields/VideoField'; export class ServerUtils { public static FromJson(json: any): Field { @@ -41,6 +43,10 @@ export class ServerUtils { return new ImageField(new URL(data), id, false) case Types.List: return ListField.FromJson(id, data) + case Types.Audio: + return new AudioField(new URL(data), id, false) + case Types.Video: + return new VideoField(new URL(data), id, false) case Types.Document: let doc: Document = new Document(id, false) let fields: [string, string][] = data as [string, string][] -- cgit v1.2.3-70-g09d2