aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTyler Schicke <tschicke@gmail.com>2020-01-11 14:10:59 -0800
committerTyler Schicke <tschicke@gmail.com>2020-01-11 14:10:59 -0800
commitf24fcf4df595542d47ec9b98e173979656db68bd (patch)
treedaf32c16ac99add88460980a6f19925806eb51da
parenta2f423fa31e649805e7dd087037a5fe262c44a4a (diff)
parent54a241ff71abc07a5dbdebce1b614f1024a767e6 (diff)
Merge branch 'master' of github.com:browngraphicslab/Dash-Web into no_db
-rw-r--r--package-lock.json1297
-rw-r--r--package.json6
-rw-r--r--src/client/util/DropConverter.ts8
-rw-r--r--src/client/views/CollectionMulticolumnView.tsx44
-rw-r--r--src/client/views/TemplateMenu.tsx2
-rw-r--r--src/client/views/collections/CollectionSchemaView.tsx2
-rw-r--r--src/client/views/collections/CollectionStackingView.tsx4
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx17
-rw-r--r--src/client/views/collections/CollectionViewChromes.tsx6
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx13
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx21
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx11
-rw-r--r--src/client/views/nodes/ContentFittingDocumentView.tsx2
-rw-r--r--src/client/views/nodes/DocumentBox.tsx2
-rw-r--r--src/client/views/nodes/FormattedTextBoxComment.tsx1
-rw-r--r--src/client/views/presentationview/PresElementBox.tsx1
-rw-r--r--src/client/views/search/SearchItem.tsx2
-rw-r--r--src/new_fields/Doc.ts8
-rw-r--r--src/server/ActionUtilities.ts24
-rw-r--r--src/server/ApiManagers/SessionManager.ts38
-rw-r--r--src/server/DashSession.ts139
-rw-r--r--src/server/DashSession/DashSessionAgent.ts221
-rw-r--r--src/server/DashSession/templates/crash_instructions.txt14
-rw-r--r--src/server/DashSession/templates/remote_debug_instructions.txt (renamed from src/server/remote_debug_instructions.txt)0
-rw-r--r--src/server/RouteManager.ts4
-rw-r--r--src/server/index.ts12
-rw-r--r--src/server/session/README.txt11
-rw-r--r--src/server/session/agents/applied_session_agent.ts58
-rw-r--r--src/server/session/agents/monitor.ts302
-rw-r--r--src/server/session/agents/process_message_router.ts46
-rw-r--r--src/server/session/agents/promisified_ipc_manager.ts97
-rw-r--r--src/server/session/agents/server_worker.ts160
-rw-r--r--src/server/session/utilities/repl.ts (renamed from src/server/repl.ts)2
-rw-r--r--src/server/session/utilities/session_config.ts (renamed from src/server/Session/session_config_schema.ts)62
-rw-r--r--src/server/session/utilities/utilities.ts31
35 files changed, 1600 insertions, 1068 deletions
diff --git a/package-lock.json b/package-lock.json
index 08e409ac6..1200dc26c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8820,9 +8820,9 @@
"integrity": "sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg=="
},
"npm": {
- "version": "6.13.4",
- "resolved": "https://registry.npmjs.org/npm/-/npm-6.13.4.tgz",
- "integrity": "sha512-vTcUL4SCg3AzwInWTbqg1OIaOXlzKSS8Mb8kc5avwrJpcvevDA5J9BhYSuei+fNs3pwOp4lzA5x2FVDXACvoXA==",
+ "version": "6.13.6",
+ "resolved": "https://registry.npmjs.org/npm/-/npm-6.13.6.tgz",
+ "integrity": "sha512-NomC08kv7HIl1FOyLOe9Hp89kYsOsvx52huVIJ7i8hFW8Xp65lDwe/8wTIrh9q9SaQhA8hTrfXPh3BEL3TmMpw==",
"requires": {
"JSONStream": "^1.3.5",
"abbrev": "~1.1.1",
@@ -8909,7 +8909,7 @@
"once": "~1.4.0",
"opener": "^1.5.1",
"osenv": "^0.1.5",
- "pacote": "^9.5.11",
+ "pacote": "^9.5.12",
"path-is-inside": "~1.0.2",
"promise-inflight": "~1.0.1",
"qrcode-terminal": "^0.12.0",
@@ -8951,8 +8951,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"
@@ -8960,29 +8959,25 @@
},
"abbrev": {
"version": "1.1.1",
- "resolved": false,
- "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
+ "bundled": true
},
"agent-base": {
"version": "4.3.0",
- "resolved": false,
- "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==",
+ "bundled": true,
"requires": {
"es6-promisify": "^5.0.0"
}
},
"agentkeepalive": {
"version": "3.5.2",
- "resolved": false,
- "integrity": "sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ==",
+ "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",
@@ -8992,49 +8987,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"
@@ -9042,8 +9029,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",
@@ -9056,8 +9042,7 @@
},
"string_decoder": {
"version": "1.1.1",
- "resolved": false,
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "bundled": true,
"requires": {
"safe-buffer": "~5.1.0"
}
@@ -9066,46 +9051,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"
@@ -9113,8 +9090,7 @@
},
"bin-links": {
"version": "1.1.6",
- "resolved": false,
- "integrity": "sha512-b5rV3uVyrlrJWLI3mawUUf5t2f9mCEQm/TqT5zNj6DPYhYDZaNp0AYaYd/CVASkSEklayNDLliZHVdo2J3niPw==",
+ "bundled": true,
"requires": {
"bluebird": "^3.5.3",
"cmd-shim": "^3.0.0",
@@ -9126,13 +9102,11 @@
},
"bluebird": {
"version": "3.5.5",
- "resolved": false,
- "integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w=="
+ "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",
@@ -9145,8 +9119,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"
@@ -9154,28 +9127,23 @@
},
"buffer-from": {
"version": "1.0.0",
- "resolved": false,
- "integrity": "sha512-83apNb8KK0Se60UE1+4Ukbe3HbfELJ6UlI4ldtOGs7So4KD26orJM8hIY9lxdzP+UpItH1Yh/Y8GUvNFWFFRxA=="
+ "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": "12.0.3",
- "resolved": false,
- "integrity": "sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==",
+ "bundled": true,
"requires": {
"bluebird": "^3.5.5",
"chownr": "^1.1.1",
@@ -9196,28 +9164,23 @@
},
"call-limit": {
"version": "1.1.1",
- "resolved": false,
- "integrity": "sha512-5twvci5b9eRBw2wCfPtN0GmlR2/gadZqyFpPhOK6CvMFoFgA+USnZ6Jpu1lhG9h85pQ3Ouil3PfXWRD4EUaRiQ=="
+ "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",
@@ -9226,31 +9189,26 @@
},
"chownr": {
"version": "1.1.3",
- "resolved": false,
- "integrity": "sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw=="
+ "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"
@@ -9258,8 +9216,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",
@@ -9268,8 +9225,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",
@@ -9278,13 +9234,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"
}
@@ -9293,13 +9247,11 @@
},
"clone": {
"version": "1.0.4",
- "resolved": false,
- "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4="
+ "bundled": true
},
"cmd-shim": {
"version": "3.0.3",
- "resolved": false,
- "integrity": "sha512-DtGg+0xiFhQIntSBRzL2fRQBnmtAVwXIDo4Qq46HPpObYquxMaZS4sb82U9nH91qJrlosC1wa9gwr0QyL/HypA==",
+ "bundled": true,
"requires": {
"graceful-fs": "^4.1.2",
"mkdirp": "~0.5.0"
@@ -9307,37 +9259,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"
@@ -9345,21 +9291,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",
@@ -9369,8 +9312,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",
@@ -9383,8 +9325,7 @@
},
"string_decoder": {
"version": "1.1.1",
- "resolved": false,
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "bundled": true,
"requires": {
"safe-buffer": "~5.1.0"
}
@@ -9393,8 +9334,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"
@@ -9402,8 +9342,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",
@@ -9415,13 +9354,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",
@@ -9433,33 +9370,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",
@@ -9468,8 +9400,7 @@
"dependencies": {
"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"
@@ -9477,104 +9408,87 @@
},
"yallist": {
"version": "2.1.2",
- "resolved": false,
- "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
+ "bundled": true
}
}
},
"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"
}
},
"define-properties": {
"version": "1.1.3",
- "resolved": false,
- "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+ "bundled": true,
"requires": {
"object-keys": "^1.0.12"
}
},
"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"
@@ -9582,26 +9496,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",
@@ -9611,8 +9521,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",
@@ -9625,8 +9534,7 @@
},
"string_decoder": {
"version": "1.1.1",
- "resolved": false,
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "bundled": true,
"requires": {
"safe-buffer": "~5.1.0"
}
@@ -9635,8 +9543,7 @@
},
"ecc-jsbn": {
"version": "0.1.2",
- "resolved": false,
- "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
+ "bundled": true,
"optional": true,
"requires": {
"jsbn": "~0.1.0",
@@ -9645,47 +9552,40 @@
},
"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"
}
},
"env-paths": {
"version": "1.0.0",
- "resolved": false,
- "integrity": "sha1-QWgTO0K7BcOKNbGuQ5fIKYqzaeA="
+ "bundled": true
},
"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"
}
},
"es-abstract": {
"version": "1.12.0",
- "resolved": false,
- "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==",
+ "bundled": true,
"requires": {
"es-to-primitive": "^1.1.1",
"function-bind": "^1.1.1",
@@ -9696,8 +9596,7 @@
},
"es-to-primitive": {
"version": "1.2.0",
- "resolved": false,
- "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==",
+ "bundled": true,
"requires": {
"is-callable": "^1.1.4",
"is-date-object": "^1.0.1",
@@ -9706,26 +9605,22 @@
},
"es6-promise": {
"version": "4.2.8",
- "resolved": false,
- "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w=="
+ "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",
@@ -9738,53 +9633,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"
@@ -9792,8 +9678,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",
@@ -9806,8 +9691,7 @@
},
"string_decoder": {
"version": "1.1.1",
- "resolved": false,
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "bundled": true,
"requires": {
"safe-buffer": "~5.1.0"
}
@@ -9816,13 +9700,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",
@@ -9831,8 +9713,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"
@@ -9840,8 +9721,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",
@@ -9854,8 +9734,7 @@
},
"string_decoder": {
"version": "1.1.1",
- "resolved": false,
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "bundled": true,
"requires": {
"safe-buffer": "~5.1.0"
}
@@ -9864,16 +9743,14 @@
},
"fs-minipass": {
"version": "1.2.7",
- "resolved": false,
- "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==",
+ "bundled": true,
"requires": {
"minipass": "^2.6.0"
},
"dependencies": {
"minipass": {
"version": "2.9.0",
- "resolved": false,
- "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==",
+ "bundled": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@@ -9883,8 +9760,7 @@
},
"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",
@@ -9893,8 +9769,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",
@@ -9904,13 +9779,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",
@@ -9923,8 +9796,7 @@
},
"string_decoder": {
"version": "1.1.1",
- "resolved": false,
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "bundled": true,
"requires": {
"safe-buffer": "~5.1.0"
}
@@ -9933,18 +9805,15 @@
},
"fs.realpath": {
"version": "1.0.0",
- "resolved": false,
- "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+ "bundled": true
},
"function-bind": {
"version": "1.1.1",
- "resolved": false,
- "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+ "bundled": true
},
"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",
@@ -9958,13 +9827,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",
@@ -9975,13 +9842,11 @@
},
"genfun": {
"version": "5.0.0",
- "resolved": false,
- "integrity": "sha512-KGDOARWVga7+rnB3z9Sd2Letx515owfk0hSxHGuqjANb1M+x2bGZGqHLiozPsYMdM2OubeMni/Hpwmjq6qIUhA=="
+ "bundled": true
},
"gentle-fs": {
"version": "2.3.0",
- "resolved": false,
- "integrity": "sha512-3k2CgAmPxuz7S6nKK+AqFE2AdM1QuwqKLPKzIET3VRwK++3q96MsNFobScDjlCrq97ZJ8y5R725MOlm6ffUCjg==",
+ "bundled": true,
"requires": {
"aproba": "^1.1.2",
"chownr": "^1.1.2",
@@ -9998,41 +9863,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.4",
- "resolved": false,
- "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
+ "bundled": true,
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
@@ -10044,16 +9903,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",
@@ -10070,25 +9927,21 @@
"dependencies": {
"get-stream": {
"version": "3.0.0",
- "resolved": false,
- "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ="
+ "bundled": true
}
}
},
"graceful-fs": {
"version": "4.2.3",
- "resolved": false,
- "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ=="
+ "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"
@@ -10096,41 +9949,34 @@
},
"has": {
"version": "1.0.3",
- "resolved": false,
- "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "bundled": true,
"requires": {
"function-bind": "^1.1.1"
}
},
"has-flag": {
"version": "3.0.0",
- "resolved": false,
- "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
+ "bundled": true
},
"has-symbols": {
"version": "1.0.0",
- "resolved": false,
- "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q="
+ "bundled": true
},
"has-unicode": {
"version": "2.0.1",
- "resolved": false,
- "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
+ "bundled": true
},
"hosted-git-info": {
"version": "2.8.5",
- "resolved": false,
- "integrity": "sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg=="
+ "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"
@@ -10138,8 +9984,7 @@
},
"http-signature": {
"version": "1.2.0",
- "resolved": false,
- "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+ "bundled": true,
"requires": {
"assert-plus": "^1.0.0",
"jsprim": "^1.2.2",
@@ -10148,8 +9993,7 @@
},
"https-proxy-agent": {
"version": "2.2.4",
- "resolved": false,
- "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==",
+ "bundled": true,
"requires": {
"agent-base": "^4.3.0",
"debug": "^3.1.0"
@@ -10157,52 +10001,44 @@
},
"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.3",
- "resolved": false,
- "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==",
+ "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
},
"infer-owner": {
"version": "1.0.4",
- "resolved": false,
- "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A=="
+ "bundled": true
},
"inflight": {
"version": "1.0.6",
- "resolved": false,
- "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "bundled": true,
"requires": {
"once": "^1.3.0",
"wrappy": "1"
@@ -10210,18 +10046,15 @@
},
"inherits": {
"version": "2.0.4",
- "resolved": false,
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+ "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",
@@ -10235,64 +10068,54 @@
},
"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="
+ "bundled": true
},
"is-callable": {
"version": "1.1.4",
- "resolved": false,
- "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA=="
+ "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-date-object": {
"version": "1.0.1",
- "resolved": false,
- "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY="
+ "bundled": true
},
"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"
@@ -10300,108 +10123,89 @@
},
"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-regex": {
"version": "1.0.4",
- "resolved": false,
- "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
+ "bundled": true,
"requires": {
"has": "^1.0.1"
}
},
"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-symbol": {
"version": "1.0.2",
- "resolved": false,
- "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==",
+ "bundled": true,
"requires": {
"has-symbols": "^1.0.0"
}
},
"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",
@@ -10411,29 +10215,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": "4.0.7",
- "resolved": false,
- "integrity": "sha512-fTq33otU3PNXxxCTCYCYe7V96o59v/o7bvtspmbORXpgFk+wcWrGf5x6tBgui5gCed/45/wtPomBsZBYm5KbIw==",
+ "bundled": true,
"requires": {
"bin-links": "^1.1.2",
"bluebird": "^3.5.1",
@@ -10454,8 +10254,7 @@
},
"libnpm": {
"version": "3.0.1",
- "resolved": false,
- "integrity": "sha512-d7jU5ZcMiTfBqTUJVZ3xid44fE5ERBm9vBnmhp2ECD2Ls+FNXWxHSkO7gtvrnbLO78gwPdNPz1HpsF3W4rjkBQ==",
+ "bundled": true,
"requires": {
"bin-links": "^1.1.2",
"bluebird": "^3.5.3",
@@ -10481,8 +10280,7 @@
},
"libnpmaccess": {
"version": "3.0.2",
- "resolved": false,
- "integrity": "sha512-01512AK7MqByrI2mfC7h5j8N9V4I7MHJuk9buo8Gv+5QgThpOgpjB7sQBDDkeZqRteFb1QM/6YNdHfG7cDvfAQ==",
+ "bundled": true,
"requires": {
"aproba": "^2.0.0",
"get-stream": "^4.0.0",
@@ -10492,8 +10290,7 @@
},
"libnpmconfig": {
"version": "1.2.1",
- "resolved": false,
- "integrity": "sha512-9esX8rTQAHqarx6qeZqmGQKBNZR5OIbl/Ayr0qQDy3oXja2iFVQQI81R6GZ2a02bSNZ9p3YOGX1O6HHCb1X7kA==",
+ "bundled": true,
"requires": {
"figgy-pudding": "^3.5.1",
"find-up": "^3.0.0",
@@ -10502,16 +10299,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"
@@ -10519,31 +10314,27 @@
},
"p-limit": {
"version": "2.2.0",
- "resolved": false,
- "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==",
+ "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.2.0",
- "resolved": false,
- "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
+ "bundled": true
}
}
},
"libnpmhook": {
"version": "5.0.3",
- "resolved": false,
- "integrity": "sha512-UdNLMuefVZra/wbnBXECZPefHMGsVDTq5zaM/LgKNE9Keyl5YXQTnGAzEo+nFOpdRqTWI9LYi4ApqF9uVCCtuA==",
+ "bundled": true,
"requires": {
"aproba": "^2.0.0",
"figgy-pudding": "^3.4.1",
@@ -10553,8 +10344,7 @@
},
"libnpmorg": {
"version": "1.0.1",
- "resolved": false,
- "integrity": "sha512-0sRUXLh+PLBgZmARvthhYXQAWn0fOsa6T5l3JSe2n9vKG/lCVK4nuG7pDsa7uMq+uTt2epdPK+a2g6btcY11Ww==",
+ "bundled": true,
"requires": {
"aproba": "^2.0.0",
"figgy-pudding": "^3.4.1",
@@ -10564,8 +10354,7 @@
},
"libnpmpublish": {
"version": "1.1.2",
- "resolved": false,
- "integrity": "sha512-2yIwaXrhTTcF7bkJKIKmaCV9wZOALf/gsTDxVSu/Gu/6wiG3fA8ce8YKstiWKTxSFNC0R7isPUb6tXTVFZHt2g==",
+ "bundled": true,
"requires": {
"aproba": "^2.0.0",
"figgy-pudding": "^3.5.1",
@@ -10580,8 +10369,7 @@
},
"libnpmsearch": {
"version": "2.0.2",
- "resolved": false,
- "integrity": "sha512-VTBbV55Q6fRzTdzziYCr64+f8AopQ1YZ+BdPOv16UegIEaE8C0Kch01wo4s3kRTFV64P121WZJwgmBwrq68zYg==",
+ "bundled": true,
"requires": {
"figgy-pudding": "^3.5.1",
"get-stream": "^4.0.0",
@@ -10590,8 +10378,7 @@
},
"libnpmteam": {
"version": "1.0.2",
- "resolved": false,
- "integrity": "sha512-p420vM28Us04NAcg1rzgGW63LMM6rwe+6rtZpfDxCcXxM0zUTLl7nPFEnRF3JfFBF5skF/yuZDUthTsHgde8QA==",
+ "bundled": true,
"requires": {
"aproba": "^2.0.0",
"figgy-pudding": "^3.4.1",
@@ -10601,8 +10388,7 @@
},
"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",
@@ -10616,8 +10402,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"
@@ -10625,8 +10410,7 @@
},
"lock-verify": {
"version": "2.1.0",
- "resolved": false,
- "integrity": "sha512-vcLpxnGvrqisKvLQ2C2v0/u7LVly17ak2YSgoK4PrdsYBXQIax19vhKiLfvKNFx7FRrpTnitrpzF/uuCMuorIg==",
+ "bundled": true,
"requires": {
"npm-package-arg": "^6.1.0",
"semver": "^5.4.1"
@@ -10634,21 +10418,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"
@@ -10656,87 +10437,72 @@
},
"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": "5.1.1",
- "resolved": false,
- "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "bundled": true,
"requires": {
"yallist": "^3.0.2"
}
},
"make-dir": {
"version": "1.3.0",
- "resolved": false,
- "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==",
+ "bundled": true,
"requires": {
"pify": "^3.0.0"
}
},
"make-fetch-happen": {
"version": "5.0.2",
- "resolved": false,
- "integrity": "sha512-07JHC0r1ykIoruKO8ifMXu+xEU8qOXDFETylktdug6vJDACnP+HKevOu3PXyNPzFyTSlz8vrBYlBO1JZRe8Cag==",
+ "bundled": true,
"requires": {
"agentkeepalive": "^3.4.1",
"cacache": "^12.0.0",
@@ -10753,60 +10519,51 @@
},
"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
},
"minizlib": {
"version": "1.3.3",
- "resolved": false,
- "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==",
+ "bundled": true,
"requires": {
"minipass": "^2.9.0"
},
"dependencies": {
"minipass": {
"version": "2.9.0",
- "resolved": false,
- "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==",
+ "bundled": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@@ -10816,8 +10573,7 @@
},
"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",
@@ -10833,16 +10589,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",
@@ -10854,25 +10608,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",
@@ -10881,8 +10631,7 @@
},
"node-gyp": {
"version": "5.0.5",
- "resolved": false,
- "integrity": "sha512-WABl9s4/mqQdZneZHVWVG4TVr6QQJZUC6PAx47ITSk9lreZ1n+7Z9mMAIbA3vnO4J9W20P7LhCxtzfWsAD/KDw==",
+ "bundled": true,
"requires": {
"env-paths": "^1.0.0",
"glob": "^7.0.3",
@@ -10899,23 +10648,20 @@
"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
}
}
},
"nopt": {
"version": "4.0.1",
- "resolved": false,
- "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=",
+ "bundled": true,
"requires": {
"abbrev": "1",
"osenv": "^0.1.4"
@@ -10923,8 +10669,7 @@
},
"normalize-package-data": {
"version": "2.5.0",
- "resolved": false,
- "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+ "bundled": true,
"requires": {
"hosted-git-info": "^2.1.4",
"resolve": "^1.10.0",
@@ -10934,8 +10679,7 @@
"dependencies": {
"resolve": {
"version": "1.10.0",
- "resolved": false,
- "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==",
+ "bundled": true,
"requires": {
"path-parse": "^1.0.6"
}
@@ -10944,8 +10688,7 @@
},
"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"
@@ -10953,29 +10696,25 @@
},
"npm-bundled": {
"version": "1.1.1",
- "resolved": false,
- "integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==",
+ "bundled": true,
"requires": {
"npm-normalize-package-bin": "^1.0.1"
}
},
"npm-cache-filename": {
"version": "1.0.2",
- "resolved": false,
- "integrity": "sha1-3tMGxbC/yHCp6fr4I7xfKD4FrhE="
+ "bundled": true
},
"npm-install-checks": {
"version": "3.0.2",
- "resolved": false,
- "integrity": "sha512-E4kzkyZDIWoin6uT5howP8VDvkM+E8IQDcHAycaAxMbwkqhIg5eEYALnXOl3Hq9MrkdQB/2/g1xwBINXdKSRkg==",
+ "bundled": true,
"requires": {
"semver": "^2.3.0 || 3.x || 4 || 5"
}
},
"npm-lifecycle": {
"version": "3.1.4",
- "resolved": false,
- "integrity": "sha512-tgs1PaucZwkxECGKhC/stbEgFyc3TGh2TJcg2CDr6jbvQRdteHNhmMeljRzpe4wgFAXQADoy1cSqqi7mtiAa5A==",
+ "bundled": true,
"requires": {
"byline": "^5.0.0",
"graceful-fs": "^4.1.15",
@@ -10989,18 +10728,15 @@
},
"npm-logical-tree": {
"version": "1.2.1",
- "resolved": false,
- "integrity": "sha512-AJI/qxDB2PWI4LG1CYN579AY1vCiNyWfkiquCsJWqntRu/WwimVrC8yXeILBFHDwxfOejxewlmnvW9XXjMlYIg=="
+ "bundled": true
},
"npm-normalize-package-bin": {
"version": "1.0.1",
- "resolved": false,
- "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA=="
+ "bundled": true
},
"npm-package-arg": {
"version": "6.1.1",
- "resolved": false,
- "integrity": "sha512-qBpssaL3IOZWi5vEKUKW0cO7kzLeT+EQO9W8RsLOZf76KF9E/K9+wH0C7t06HXPpaH8WH5xF1MExLuCwbTqRUg==",
+ "bundled": true,
"requires": {
"hosted-git-info": "^2.7.1",
"osenv": "^0.1.5",
@@ -11010,8 +10746,7 @@
},
"npm-packlist": {
"version": "1.4.7",
- "resolved": false,
- "integrity": "sha512-vAj7dIkp5NhieaGZxBJB8fF4R0078rqsmhJcAfXZ6O7JJhjhPK96n5Ry1oZcfLXgfun0GWTZPOxaEyqv8GBykQ==",
+ "bundled": true,
"requires": {
"ignore-walk": "^3.0.1",
"npm-bundled": "^1.0.1"
@@ -11019,8 +10754,7 @@
},
"npm-pick-manifest": {
"version": "3.0.2",
- "resolved": false,
- "integrity": "sha512-wNprTNg+X5nf+tDi+hbjdHhM4bX+mKqv6XmPh7B5eG+QY9VARfQPfCEH013H5GqfNj6ee8Ij2fg8yk0mzps1Vw==",
+ "bundled": true,
"requires": {
"figgy-pudding": "^3.5.1",
"npm-package-arg": "^6.0.0",
@@ -11029,8 +10763,7 @@
},
"npm-profile": {
"version": "4.0.2",
- "resolved": false,
- "integrity": "sha512-VRsC04pvRH+9cF+PoVh2nTmJjiG21yu59IHpsBpkxk+jaGAV8lxx96G4SDc0jOHAkfWLXbc6kIph3dGAuRnotQ==",
+ "bundled": true,
"requires": {
"aproba": "^1.1.2 || 2",
"figgy-pudding": "^3.4.1",
@@ -11039,8 +10772,7 @@
},
"npm-registry-fetch": {
"version": "4.0.2",
- "resolved": false,
- "integrity": "sha512-Z0IFtPEozNdeZRPh3aHHxdG+ZRpzcbQaJLthsm3VhNf6DScicTFRHZzK82u8RsJUsUHkX+QH/zcB/5pmd20H4A==",
+ "bundled": true,
"requires": {
"JSONStream": "^1.3.4",
"bluebird": "^3.5.1",
@@ -11053,28 +10785,24 @@
"dependencies": {
"safe-buffer": {
"version": "5.2.0",
- "resolved": false,
- "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg=="
+ "bundled": true
}
}
},
"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",
@@ -11084,28 +10812,23 @@
},
"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
},
"object-keys": {
"version": "1.0.12",
- "resolved": false,
- "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag=="
+ "bundled": true
},
"object.getownpropertydescriptors": {
"version": "2.0.3",
- "resolved": false,
- "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=",
+ "bundled": true,
"requires": {
"define-properties": "^1.1.2",
"es-abstract": "^1.5.1"
@@ -11113,26 +10836,22 @@
},
"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",
@@ -11141,13 +10860,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"
@@ -11155,34 +10872,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",
@@ -11191,9 +10903,8 @@
}
},
"pacote": {
- "version": "9.5.11",
- "resolved": false,
- "integrity": "sha512-DMDPvFKCjCg6zMS4IfzZyvT57O/bX8XGG00eEoy4K/S4Wj+qiN8KbnmKpsTvfS6OL9r5TAicxMKWbj1yV2Yh4g==",
+ "version": "9.5.12",
+ "bundled": true,
"requires": {
"bluebird": "^3.5.3",
"cacache": "^12.0.2",
@@ -11229,8 +10940,7 @@
"dependencies": {
"minipass": {
"version": "2.9.0",
- "resolved": false,
- "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==",
+ "bundled": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@@ -11240,8 +10950,7 @@
},
"parallel-transform": {
"version": "1.1.0",
- "resolved": false,
- "integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=",
+ "bundled": true,
"requires": {
"cyclist": "~0.2.2",
"inherits": "^2.0.3",
@@ -11250,8 +10959,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",
@@ -11264,8 +10972,7 @@
},
"string_decoder": {
"version": "1.1.1",
- "resolved": false,
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "bundled": true,
"requires": {
"safe-buffer": "~5.1.0"
}
@@ -11274,58 +10981,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",
- "resolved": false,
- "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw=="
+ "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"
@@ -11333,51 +11029,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"
@@ -11385,8 +11073,7 @@
},
"pumpify": {
"version": "1.5.1",
- "resolved": false,
- "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==",
+ "bundled": true,
"requires": {
"duplexify": "^3.6.0",
"inherits": "^2.0.3",
@@ -11395,8 +11082,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"
@@ -11406,23 +11092,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.8.2",
- "resolved": false,
- "integrity": "sha512-J3Qi8XZJXh93t2FiKyd/7Ec6GNifsjKXUsVFkSBj/kjLsDylWhnCz4NT1bkPcKotttPW+QbKGqqPH8OoI2pdqw==",
+ "bundled": true,
"requires": {
"decode-uri-component": "^0.2.0",
"split-on-first": "^1.0.0",
@@ -11431,13 +11113,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",
@@ -11447,31 +11127,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.5",
- "resolved": false,
- "integrity": "sha512-v5yCqQ/7okKoZZkBQUAfTsQ3sVJtXdNfbPnI5cceppoxEVLYA3k+VtV2omkeo8MS94JCy4fSiUwlRBAwCVRPUA==",
+ "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",
@@ -11484,8 +11160,7 @@
},
"read-package-json": {
"version": "2.1.1",
- "resolved": false,
- "integrity": "sha512-dAiqGtVc/q5doFz6096CcnXhpYk0ZN8dEKVkGLU0CsASt8SrgF6SF7OTKAYubfvFhWaqofl+Y8HK19GR8jwW+A==",
+ "bundled": true,
"requires": {
"glob": "^7.1.1",
"graceful-fs": "^4.1.2",
@@ -11496,8 +11171,7 @@
},
"read-package-tree": {
"version": "5.3.1",
- "resolved": false,
- "integrity": "sha512-mLUDsD5JVtlZxjSlPPx1RETkNjjvQYuweKwNVt1Sn8kP5Jh44pvYuUHCp6xSVDZWbNxVxG5lyZJ921aJH61sTw==",
+ "bundled": true,
"requires": {
"read-package-json": "^2.0.0",
"readdir-scoped-modules": "^1.0.0",
@@ -11506,8 +11180,7 @@
},
"readable-stream": {
"version": "3.4.0",
- "resolved": false,
- "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==",
+ "bundled": true,
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
@@ -11516,8 +11189,7 @@
},
"readdir-scoped-modules": {
"version": "1.1.0",
- "resolved": false,
- "integrity": "sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw==",
+ "bundled": true,
"requires": {
"debuglog": "^1.0.1",
"dezalgo": "^1.0.0",
@@ -11527,8 +11199,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"
@@ -11536,16 +11207,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",
@@ -11571,115 +11240,96 @@
},
"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.7.1",
- "resolved": false,
- "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
+ "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": "3.0.0",
- "resolved": false,
- "integrity": "sha512-DOYnM37cNsLNSGIG/zZWch5CKIRNoLdYUQTQlcgkRkoYIUwDYjqDyye16YcDZg/OPdcbUgTKMjc4SY6TB7ZAPw==",
+ "bundled": true,
"requires": {
"graceful-fs": "^4.1.2"
}
},
"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
},
"slide": {
"version": "1.1.6",
- "resolved": false,
- "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc="
+ "bundled": true
},
"smart-buffer": {
"version": "4.1.0",
- "resolved": false,
- "integrity": "sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw=="
+ "bundled": true
},
"socks": {
"version": "2.3.3",
- "resolved": false,
- "integrity": "sha512-o5t52PCNtVdiOvzMry7wU4aOqYWL0PeCXRWBEiJow4/i/wr+wpsJQ9awEu1EonLIqsfGd5qSgDdxEOvCdmBEpA==",
+ "bundled": true,
"requires": {
"ip": "1.1.5",
"smart-buffer": "^4.1.0"
@@ -11687,8 +11337,7 @@
},
"socks-proxy-agent": {
"version": "4.0.2",
- "resolved": false,
- "integrity": "sha512-NT6syHhI9LmuEMSK6Kd2V7gNv5KFZoLE7V5udWmn0de+3Mkj3UMA/AJPLyeNUVmElCurSHtUdM3ETpR3z770Wg==",
+ "bundled": true,
"requires": {
"agent-base": "~4.2.1",
"socks": "~2.3.2"
@@ -11696,8 +11345,7 @@
"dependencies": {
"agent-base": {
"version": "4.2.1",
- "resolved": false,
- "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==",
+ "bundled": true,
"requires": {
"es6-promisify": "^5.0.0"
}
@@ -11706,13 +11354,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"
@@ -11720,8 +11366,7 @@
"dependencies": {
"from2": {
"version": "1.3.0",
- "resolved": false,
- "integrity": "sha1-iEE7qqX5pZfP3pIh2GmGzTwGHf0=",
+ "bundled": true,
"requires": {
"inherits": "~2.0.1",
"readable-stream": "~1.1.10"
@@ -11729,13 +11374,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",
@@ -11745,15 +11388,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"
@@ -11761,13 +11402,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"
@@ -11775,18 +11414,15 @@
},
"spdx-license-ids": {
"version": "3.0.3",
- "resolved": false,
- "integrity": "sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g=="
+ "bundled": true
},
"split-on-first": {
"version": "1.1.0",
- "resolved": false,
- "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw=="
+ "bundled": true
},
"sshpk": {
"version": "1.14.2",
- "resolved": false,
- "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=",
+ "bundled": true,
"requires": {
"asn1": "~0.2.3",
"assert-plus": "^1.0.0",
@@ -11801,16 +11437,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"
@@ -11818,8 +11452,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"
@@ -11827,8 +11460,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",
@@ -11841,8 +11473,7 @@
},
"string_decoder": {
"version": "1.1.1",
- "resolved": false,
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "bundled": true,
"requires": {
"safe-buffer": "~5.1.0"
}
@@ -11851,18 +11482,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"
@@ -11870,18 +11498,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"
}
@@ -11890,47 +11515,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.1",
- "resolved": false,
- "integrity": "sha512-sa4DUQsYciMP1xhKWGuFM04fB0LG/9DlluZoSVywUMRNvzid6XucHK0/90xGxRoHrAaROrcHK1aPKaijCtSrhg=="
+ "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.13",
- "resolved": false,
- "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==",
+ "bundled": true,
"requires": {
"chownr": "^1.1.1",
"fs-minipass": "^1.2.5",
@@ -11943,8 +11561,7 @@
"dependencies": {
"minipass": {
"version": "2.9.0",
- "resolved": false,
- "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==",
+ "bundled": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@@ -11954,26 +11571,22 @@
},
"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"
@@ -11981,8 +11594,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",
@@ -11995,8 +11607,7 @@
},
"string_decoder": {
"version": "1.1.1",
- "resolved": false,
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "bundled": true,
"requires": {
"safe-buffer": "~5.1.0"
}
@@ -12005,18 +11616,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"
@@ -12024,71 +11632,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",
@@ -12104,39 +11701,33 @@
},
"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
},
"util-promisify": {
"version": "2.1.0",
- "resolved": false,
- "integrity": "sha1-PCI2R2xNMsX/PEcAKt18E7moKlM=",
+ "bundled": true,
"requires": {
"object.getownpropertydescriptors": "^2.0.3"
}
},
"uuid": {
"version": "3.3.3",
- "resolved": false,
- "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ=="
+ "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"
@@ -12144,16 +11735,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",
@@ -12162,37 +11751,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",
@@ -12203,24 +11787,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.7.0",
- "resolved": false,
- "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==",
+ "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"
@@ -12228,8 +11809,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",
@@ -12240,13 +11820,11 @@
},
"wrappy": {
"version": "1.0.2",
- "resolved": false,
- "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+ "bundled": true
},
"write-file-atomic": {
"version": "2.4.3",
- "resolved": false,
- "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==",
+ "bundled": true,
"requires": {
"graceful-fs": "^4.1.11",
"imurmurhash": "^0.1.4",
@@ -12255,28 +11833,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": "3.0.3",
- "resolved": false,
- "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A=="
+ "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",
@@ -12294,15 +11867,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"
}
diff --git a/package.json b/package.json
index b2dc699cf..0a6cada2b 100644
--- a/package.json
+++ b/package.json
@@ -176,9 +176,9 @@
"nodemailer": "^5.1.1",
"nodemon": "^1.19.4",
"normalize.css": "^8.0.1",
- "npm": "^6.13.4",
- "p-limit": "^2.2.2",
- "passport": "^0.4.1",
+ "npm": "^6.13.6",
+ "p-limit": "^2.2.0",
+ "passport": "^0.4.0",
"passport-google-oauth20": "^2.0.0",
"passport-local": "^1.0.0",
"pdf-parse": "^1.1.1",
diff --git a/src/client/util/DropConverter.ts b/src/client/util/DropConverter.ts
index 9e036d6c2..da0ad7efe 100644
--- a/src/client/util/DropConverter.ts
+++ b/src/client/util/DropConverter.ts
@@ -14,13 +14,13 @@ function makeTemplate(doc: Doc): boolean {
const fieldKey = layout.replace("fieldKey={'", "").replace(/'}$/, "");
const docs = DocListCast(layoutDoc[fieldKey]);
let any = false;
- docs.map(d => {
+ docs.forEach(d => {
if (!StrCast(d.title).startsWith("-")) {
any = true;
- return Doc.MakeMetadataFieldTemplate(d, Doc.GetProto(layoutDoc));
+ Doc.MakeMetadataFieldTemplate(d, Doc.GetProto(layoutDoc));
+ } else if (d.type === DocumentType.COL) {
+ any = makeTemplate(d) || any;
}
- if (d.type === DocumentType.COL) return makeTemplate(d);
- return false;
});
return any;
}
diff --git a/src/client/views/CollectionMulticolumnView.tsx b/src/client/views/CollectionMulticolumnView.tsx
new file mode 100644
index 000000000..94e86c048
--- /dev/null
+++ b/src/client/views/CollectionMulticolumnView.tsx
@@ -0,0 +1,44 @@
+import { observer } from 'mobx-react';
+import { makeInterface } from '../../new_fields/Schema';
+import { documentSchema } from '../../new_fields/documentSchemas';
+import { CollectionSubView, SubCollectionViewProps } from './collections/CollectionSubView';
+import { DragManager } from '../util/DragManager';
+import * as React from "react";
+import { Doc } from '../../new_fields/Doc';
+import { NumCast } from '../../new_fields/Types';
+
+type MulticolumnDocument = makeInterface<[typeof documentSchema]>;
+const MulticolumnDocument = makeInterface(documentSchema);
+
+@observer
+export default class CollectionMulticolumnView extends CollectionSubView(MulticolumnDocument) {
+
+ constructor(props: Readonly<SubCollectionViewProps>) {
+ super(props);
+ const { Document } = this.props;
+ Document.multicolumnData = new Doc();
+ }
+
+ private _dropDisposer?: DragManager.DragDropDisposer;
+ protected createDropTarget = (ele: HTMLDivElement) => { //used for stacking and masonry view
+ this._dropDisposer && this._dropDisposer();
+ if (ele) {
+ this._dropDisposer = DragManager.MakeDropTarget(ele, this.drop.bind(this));
+ }
+ }
+
+ public isCurrent(doc: Doc) { return !doc.isMinimized && (Math.abs(NumCast(doc.displayTimecode, -1) - NumCast(this.Document.currentTimecode, -1)) < 1.5 || NumCast(doc.displayTimecode, -1) === -1); }
+
+ render() {
+ return (
+ <div className={"collectionMulticolumnView_outer"}>
+ <div className={"collectionMulticolumnView_contents"}>
+ {this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).map(({ layout, data }) => {
+
+ })}
+ </div>
+ </div>
+ );
+ }
+
+} \ No newline at end of file
diff --git a/src/client/views/TemplateMenu.tsx b/src/client/views/TemplateMenu.tsx
index 10419ddb7..e56395ca1 100644
--- a/src/client/views/TemplateMenu.tsx
+++ b/src/client/views/TemplateMenu.tsx
@@ -146,7 +146,7 @@ export class TemplateMenu extends React.Component<TemplateMenuProps> {
templateMenu.push(<OtherToggle key={"custom"} name={"Custom"} checked={StrCast(this.props.docs[0].Document.layoutKey, "layout") !== "layout"} toggle={this.toggleCustom} />);
templateMenu.push(<OtherToggle key={"chrome"} name={"Chrome"} checked={layout.chromeStatus !== "disabled"} toggle={this.toggleChrome} />);
return (
- <Flyout anchorPoint={anchorPoints.RIGHT_TOP}
+ <Flyout anchorPoint={anchorPoints.LEFT_TOP}
content={<ul className="template-list" ref={this._dragRef} style={{ display: this._hidden ? "none" : "block" }}>
{templateMenu}
{<button onClick={this.clearTemplates}>Restore Defaults</button>}
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index bb706e528..b466d9511 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -157,8 +157,6 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
whenActiveChanged={this.props.whenActiveChanged}
addDocTab={this.props.addDocTab}
pinToPres={this.props.pinToPres}
- setPreviewScript={this.setPreviewScript}
- previewScript={this.previewScript}
/>
</div>;
}
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index e71e11b48..c1e36272c 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -187,9 +187,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
active={this.props.active}
whenActiveChanged={this.props.whenActiveChanged}
addDocTab={this.props.addDocTab}
- pinToPres={this.props.pinToPres}
- setPreviewScript={emptyFunction}
- previewScript={undefined}>
+ pinToPres={this.props.pinToPres}>
</ContentFittingDocumentView>;
}
getDocHeight(d?: Doc) {
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index 2b13d87ee..79fc477ab 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -8,7 +8,7 @@ import { Id } from '../../../new_fields/FieldSymbols';
import { List } from '../../../new_fields/List';
import { Document, listSpec } from '../../../new_fields/Schema';
import { ComputedField, ScriptField } from '../../../new_fields/ScriptField';
-import { BoolCast, Cast, NumCast, StrCast } from '../../../new_fields/Types';
+import { BoolCast, Cast, NumCast, StrCast, ScriptCast } from '../../../new_fields/Types';
import { emptyFunction, Utils, returnFalse, emptyPath } from '../../../Utils';
import { Docs, DocUtils } from '../../documents/Documents';
import { DocumentType } from "../../documents/DocumentTypes";
@@ -359,15 +359,24 @@ class TreeView extends React.Component<TreeViewProps> {
active={this.props.active}
whenActiveChanged={emptyFunction}
addDocTab={this.props.addDocTab}
- pinToPres={this.props.pinToPres}
- setPreviewScript={emptyFunction} />
+ pinToPres={this.props.pinToPres} />
</div>;
}
}
+ @action
+ bulletClick = (e: React.MouseEvent) => {
+ if (this.props.document.onClick) {
+ ScriptCast(this.props.document.onClick).script.run({ this: this.props.document.isTemplateField && this.props.dataDoc ? this.props.dataDoc : this.props.document }, console.log);
+ } else {
+ this.treeViewOpen = !this.treeViewOpen;
+ }
+ e.stopPropagation();
+ }
+
@computed
get renderBullet() {
- return <div className="bullet" title="view inline" onClick={action((e: React.MouseEvent) => { this.treeViewOpen = !this.treeViewOpen; e.stopPropagation(); })} style={{ color: StrCast(this.props.document.color, "black"), opacity: 0.4 }}>
+ return <div className="bullet" title="view inline" onClick={this.bulletClick} style={{ color: StrCast(this.props.document.color, "black"), opacity: 0.4 }}>
{<FontAwesomeIcon icon={!this.treeViewOpen ? (this.childDocs ? "caret-square-right" : "caret-right") : (this.childDocs ? "caret-square-down" : "caret-down")} />}
</div>;
}
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index a870b6043..184504e5a 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -217,7 +217,11 @@ export class CollectionViewBaseChrome extends React.Component<CollectionViewChro
`(${keyRestrictionScript}) ${dateRestrictionScript.length ? "&&" : ""} ${dateRestrictionScript}` :
"true";
- this.props.CollectionView.props.Document.viewSpecScript = ScriptField.MakeFunction(fullScript, { doc: Doc.name });
+ const docFilter = StrCast(this.props.CollectionView.props.Document.docFilter);
+ const finalScript = docFilter && !fullScript.startsWith("(())") ? `${fullScript} ${docFilter ? "&&" : ""} (${docFilter})` :
+ docFilter ? docFilter : fullScript;
+
+ this.props.CollectionView.props.Document.viewSpecScript = ScriptField.MakeFunction(finalScript, { doc: Doc.name });
}
@action
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
index 012115b1f..a965a6cc9 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormLayoutEngines.tsx
@@ -44,7 +44,7 @@ function toLabel(target: FieldResult<Field>) {
return String(target);
}
-export function computePivotLayout(poolData: ObservableMap<string, any>, pivotDoc: Doc, childDocs: Doc[], childPairs: { layout: Doc, data?: Doc }[], viewDefsToJSX: (views: any) => ViewDefResult[]) {
+export function computePivotLayout(poolData: ObservableMap<string, any>, pivotDoc: Doc, childDocs: Doc[], childPairs: { layout: Doc, data?: Doc }[], panelDim: number[], viewDefsToJSX: (views: any) => ViewDefResult[]) {
const pivotAxisWidth = NumCast(pivotDoc.pivotWidth, 200);
const pivotColumnGroups = new Map<FieldResult<Field>, Doc[]>();
@@ -57,9 +57,14 @@ export function computePivotLayout(poolData: ObservableMap<string, any>, pivotDo
}
const minSize = Array.from(pivotColumnGroups.entries()).reduce((min, pair) => Math.min(min, pair[1].length), Infinity);
- const numCols = NumCast(pivotDoc.pivotNumColumns, Math.ceil(Math.sqrt(minSize)));
+ let numCols = NumCast(pivotDoc.pivotNumColumns, Math.ceil(Math.sqrt(minSize)));
const docMap = new Map<Doc, ViewDefBounds>();
const groupNames: PivotData[] = [];
+ if (panelDim[0] < 2500) numCols = Math.min(5, numCols);
+ if (panelDim[0] < 2000) numCols = Math.min(4, numCols);
+ if (panelDim[0] < 1400) numCols = Math.min(3, numCols);
+ if (panelDim[0] < 1000) numCols = Math.min(2, numCols);
+ if (panelDim[0] < 600) numCols = 1;
const expander = 1.05;
const gap = .15;
@@ -85,14 +90,14 @@ export function computePivotLayout(poolData: ObservableMap<string, any>, pivotDo
wid = layoutDoc.nativeHeight ? (NumCast(layoutDoc.nativeWidth) / NumCast(layoutDoc.nativeHeight)) * pivotAxisWidth : pivotAxisWidth;
}
docMap.set(doc, {
- x: x + xCount * pivotAxisWidth * expander + (pivotAxisWidth - wid) / 2,
+ x: x + xCount * pivotAxisWidth * expander + (pivotAxisWidth - wid) / 2 + (val.length < numCols ? (numCols - val.length) * pivotAxisWidth / 2 : 0),
y: -y,
width: wid,
height: hgt
});
xCount++;
if (xCount >= numCols) {
- xCount = (pivotAxisWidth - wid) / 2;
+ xCount = 0;
y += pivotAxisWidth * expander;
}
}
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index eb5a074bb..936c4413f 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -772,7 +772,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
doPivotLayout(poolData: ObservableMap<string, any>) {
return computePivotLayout(poolData, this.props.Document, this.childDocs,
- this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)), this.viewDefsToJSX);
+ this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)), [this.props.PanelWidth(), this.props.PanelHeight()], this.viewDefsToJSX);
}
doFreeformLayout(poolData: ObservableMap<string, any>) {
@@ -987,6 +987,11 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
</CollectionFreeFormViewPannableContents>
</MarqueeView>;
}
+ @computed get contentScaling() {
+ let hscale = this.nativeHeight ? this.props.PanelHeight() / this.nativeHeight : 1;
+ let wscale = this.nativeWidth ? this.props.PanelWidth() / this.nativeWidth : 1;
+ return wscale < hscale ? wscale : hscale;
+ }
render() {
TraceMobx();
// update the actual dimensions of the collection so that they can inquired (e.g., by a minimap)
@@ -998,9 +1003,17 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
// otherwise, they are stored in fieldKey. All annotations to this document are stored in the extension document
if (!this.extensionDoc) return (null);
// let lodarea = this.Document[WidthSym]() * this.Document[HeightSym]() / this.props.ScreenToLocalTransform().Scale / this.props.ScreenToLocalTransform().Scale;
- return <div className={"collectionfreeformview-container"} ref={this.createDropTarget} onWheel={this.onPointerWheel}//pointerEvents: SelectionManager.GetIsDragging() ? "all" : undefined,
- style={{ pointerEvents: SelectionManager.GetIsDragging() ? "all" : undefined, height: this.isAnnotationOverlay ? (this.props.Document.scrollHeight ? this.Document.scrollHeight : "100%") : this.props.PanelHeight() }}
- onPointerDown={this.onPointerDown} onPointerMove={this.onCursorMove} onDrop={this.onDrop.bind(this)} onContextMenu={this.onContextMenu} onTouchStart={this.onTouchStart}>
+ return <div className={"collectionfreeformview-container"}
+ ref={this.createDropTarget}
+ onWheel={this.onPointerWheel}//pointerEvents: SelectionManager.GetIsDragging() ? "all" : undefined,
+ onPointerDown={this.onPointerDown} onPointerMove={this.onCursorMove} onDrop={this.onDrop.bind(this)} onContextMenu={this.onContextMenu} onTouchStart={this.onTouchStart}
+ style={{
+ pointerEvents: SelectionManager.GetIsDragging() ? "all" : undefined,
+ transform: this.contentScaling ? `scale(${this.contentScaling})` : "",
+ transformOrigin: this.contentScaling ? "left top" : "",
+ width: this.contentScaling ? `${100 / this.contentScaling}%` : "",
+ height: this.contentScaling ? `${100 / this.contentScaling}%` : this.isAnnotationOverlay ? (this.props.Document.scrollHeight ? this.Document.scrollHeight : "100%") : this.props.PanelHeight()
+ }}>
{!this.Document.LODdisable && !this.props.active() && !this.props.isAnnotationOverlay && !this.props.annotationsKey && this.props.renderDepth > 0 ? // && this.props.CollectionView && lodarea < NumCast(this.Document.LODarea, 100000) ?
this.placeholder : this.marqueeView}
<CollectionFreeFormOverlayView elements={this.elementFunc} />
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index 7973c31c6..f79496ab7 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -103,6 +103,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
height: this.height,
zIndex: this.Document.zIndex || 0,
}} >
+
<DocumentView {...this.props}
dragDivName={"collectionFreeFormDocumentView-container"}
ContentScaling={this.contentScaling}
@@ -111,6 +112,16 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
PanelWidth={this.finalPanelWidth}
PanelHeight={this.finalPanelHeight}
/>
+ {/* <ContentFittingDocumentView {...this.props}
+ //dragDivName={"collectionFreeFormDocumentView-container"}
+ //ContentScaling={this.contentScaling}
+ getTransform={this.getTransform}
+ active={returnFalse}
+ focus={(doc: Doc) => this.props.focus(doc, false)}
+ // backgroundColor={this.clusterColorFunc}
+ PanelWidth={this.finalPanelWidth}
+ PanelHeight={this.finalPanelHeight}
+ /> */}
</div>;
}
}
diff --git a/src/client/views/nodes/ContentFittingDocumentView.tsx b/src/client/views/nodes/ContentFittingDocumentView.tsx
index 2f8142a44..bbec66233 100644
--- a/src/client/views/nodes/ContentFittingDocumentView.tsx
+++ b/src/client/views/nodes/ContentFittingDocumentView.tsx
@@ -39,8 +39,6 @@ interface ContentFittingDocumentViewProps {
addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => boolean;
pinToPres: (document: Doc) => void;
dontRegisterView?: boolean;
- setPreviewScript: (script: string) => void;
- previewScript?: string;
}
@observer
diff --git a/src/client/views/nodes/DocumentBox.tsx b/src/client/views/nodes/DocumentBox.tsx
index 94755afec..863ea748b 100644
--- a/src/client/views/nodes/DocumentBox.tsx
+++ b/src/client/views/nodes/DocumentBox.tsx
@@ -106,8 +106,6 @@ export class DocumentBox extends DocComponent<FieldViewProps, DocBoxSchema>(DocB
focus={this.props.focus}
active={this.props.active}
whenActiveChanged={this.props.whenActiveChanged}
- setPreviewScript={emptyFunction}
- previewScript={undefined}
/>}
</div>;
}
diff --git a/src/client/views/nodes/FormattedTextBoxComment.tsx b/src/client/views/nodes/FormattedTextBoxComment.tsx
index 5fd5d4ce1..f7a530790 100644
--- a/src/client/views/nodes/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/FormattedTextBoxComment.tsx
@@ -183,7 +183,6 @@ export class FormattedTextBoxComment {
moveDocument={returnFalse}
getTransform={Transform.Identity}
active={returnFalse}
- setPreviewScript={returnEmptyString}
addDocument={returnFalse}
removeDocument={returnFalse}
ruleProvider={undefined}
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index 37c837414..c02042380 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -180,7 +180,6 @@ export class PresElementBox extends DocComponent<FieldViewProps, PresDocument>(P
pinToPres={returnFalse}
PanelWidth={() => this.props.PanelWidth() - 20}
PanelHeight={() => 100}
- setPreviewScript={emptyFunction}
getTransform={Transform.Identity}
active={this.props.active}
moveDocument={this.props.moveDocument!}
diff --git a/src/client/views/search/SearchItem.tsx b/src/client/views/search/SearchItem.tsx
index 32ba5d19d..88a4d4c50 100644
--- a/src/client/views/search/SearchItem.tsx
+++ b/src/client/views/search/SearchItem.tsx
@@ -172,8 +172,6 @@ export class SearchItem extends React.Component<SearchItemProps> {
moveDocument={returnFalse}
active={returnFalse}
whenActiveChanged={returnFalse}
- setPreviewScript={emptyFunction}
- previewScript={undefined}
/>
</div>;
return docview;
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index 8e0b28606..8117453e7 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -10,7 +10,7 @@ import { ObjectField } from "./ObjectField";
import { PrefetchProxy, ProxyField } from "./Proxy";
import { FieldId, RefField } from "./RefField";
import { listSpec } from "./Schema";
-import { ComputedField } from "./ScriptField";
+import { ComputedField, ScriptField } from "./ScriptField";
import { BoolCast, Cast, FieldValue, NumCast, PromiseValue, StrCast, ToConstructor } from "./Types";
import { deleteProperty, getField, getter, makeEditable, makeReadOnly, setter, updateFunction } from "./util";
import { intersectRect } from "../Utils";
@@ -760,4 +760,10 @@ Scripting.addGlobal(function selectDoc(doc: any) { Doc.UserDoc().SelectedDocs =
Scripting.addGlobal(function selectedDocs(container: Doc, excludeCollections: boolean, prevValue: any) {
const docs = DocListCast(Doc.UserDoc().SelectedDocs).filter(d => !Doc.AreProtosEqual(d, container) && !d.annotationOn && d.type !== DocumentType.DOCUMENT && d.type !== DocumentType.KVP && (!excludeCollections || !Cast(d.data, listSpec(Doc), null)));
return docs.length ? new List(docs) : prevValue;
+});
+Scripting.addGlobal(function setDocFilter(container: Doc, key: string, value: any, type: string, contains: boolean = true) {
+ const scriptText = `${contains ? "" : "!"}(((doc.${key} && (doc.${key} as ${type})${type === "string" ? ".includes" : "<="}(${value}))) ||
+ ((doc.data_ext && doc.data_ext.${key}) && (doc.data_ext.${key} as ${type})${type === "string" ? ".includes" : "<="}(${value}))))`;
+ container.docFilter = scriptText;
+ container.viewSpecScript = ScriptField.MakeFunction(scriptText, { doc: Doc.name });
}); \ No newline at end of file
diff --git a/src/server/ActionUtilities.ts b/src/server/ActionUtilities.ts
index f0bfbc525..60f66c878 100644
--- a/src/server/ActionUtilities.ts
+++ b/src/server/ActionUtilities.ts
@@ -119,16 +119,24 @@ export namespace Email {
}
});
+ export interface DispatchOptions<T extends string | string[]> {
+ to: T;
+ subject: string;
+ content: string;
+ attachments?: Mail.Attachment | Mail.Attachment[];
+ }
+
export interface DispatchFailure {
recipient: string;
error: Error;
}
- export async function dispatchAll(recipients: string[], subject: string, content: string) {
+ export async function dispatchAll({ to, subject, content, attachments }: DispatchOptions<string[]>) {
const failures: DispatchFailure[] = [];
- await Promise.all(recipients.map(async (recipient: string) => {
+ await Promise.all(to.map(async recipient => {
let error: Error | null;
- if ((error = await Email.dispatch(recipient, subject, content)) !== null) {
+ const resolved = attachments ? "length" in attachments ? attachments : [attachments] : undefined;
+ if ((error = await Email.dispatch({ to: recipient, subject, content, attachments: resolved })) !== null) {
failures.push({
recipient,
error
@@ -138,17 +146,15 @@ export namespace Email {
return failures.length ? failures : undefined;
}
- export async function dispatch(recipient: string, subject: string, content: string, attachments?: Mail.Attachment[]): Promise<Error | null> {
+ export async function dispatch({ to, subject, content, attachments }: DispatchOptions<string>): Promise<Error | null> {
const mailOptions = {
- to: recipient,
+ to,
from: 'brownptcdash@gmail.com',
subject,
- text: `Hello ${recipient.split("@")[0]},\n\n${content}`,
+ text: `Hello ${to.split("@")[0]},\n\n${content}`,
attachments
} as MailOptions;
- return new Promise<Error | null>(resolve => {
- smtpTransport.sendMail(mailOptions, resolve);
- });
+ return new Promise<Error | null>(resolve => smtpTransport.sendMail(mailOptions, resolve));
}
} \ No newline at end of file
diff --git a/src/server/ApiManagers/SessionManager.ts b/src/server/ApiManagers/SessionManager.ts
index 0290b578c..d989d8d1b 100644
--- a/src/server/ApiManagers/SessionManager.ts
+++ b/src/server/ApiManagers/SessionManager.ts
@@ -2,24 +2,25 @@ import ApiManager, { Registration } from "./ApiManager";
import { Method, _permission_denied, AuthorizedCore, SecureHandler } from "../RouteManager";
import RouteSubscriber from "../RouteSubscriber";
import { sessionAgent } from "..";
+import { DashSessionAgent } from "../DashSession/DashSessionAgent";
const permissionError = "You are not authorized!";
export default class SessionManager extends ApiManager {
- private secureSubscriber = (root: string, ...params: string[]) => new RouteSubscriber(root).add("password", ...params);
+ private secureSubscriber = (root: string, ...params: string[]) => new RouteSubscriber(root).add("sessionKey", ...params);
private authorizedAction = (handler: SecureHandler) => {
return (core: AuthorizedCore) => {
const { req, res, isRelease } = core;
- const { password } = req.params;
+ const { sessionKey } = req.params;
if (!isRelease) {
return res.send("This can be run only on the release server.");
}
- if (password !== process.env.session_key) {
+ if (sessionKey !== process.env.session_key) {
return _permission_denied(res, permissionError);
}
- handler(core);
+ return handler(core);
};
}
@@ -27,14 +28,21 @@ export default class SessionManager extends ApiManager {
register({
method: Method.GET,
- subscription: this.secureSubscriber("debug", "mode", "recipient"),
- secureHandler: this.authorizedAction(({ req, res }) => {
+ subscription: this.secureSubscriber("debug", "mode?", "recipient?"),
+ secureHandler: this.authorizedAction(async ({ req, res }) => {
const { mode, recipient } = req.params;
- if (["passive", "active"].includes(mode)) {
- sessionAgent.serverWorker.sendMonitorAction("debug", { mode, recipient });
- res.send(`Your request was successful: the server is ${mode === "active" ? "creating and compressing a new" : "retrieving and compressing the most recent"} back up. It will be sent to ${recipient}.`);
- } else {
+ if (mode && !["passive", "active"].includes(mode)) {
res.send(`Your request failed. '${mode}' is not a valid mode: please choose either 'active' or 'passive'`);
+ } else {
+ const response = await sessionAgent.serverWorker.emitToMonitorPromise("debug", {
+ mode: mode || "active",
+ recipient: recipient || DashSessionAgent.notificationRecipient
+ });
+ if (response instanceof Error) {
+ res.send(response);
+ } else {
+ res.send(`Your request was successful: the server ${mode === "active" ? "created and compressed a new" : "retrieved and compressed the most recent"} back up. It was sent to ${recipient}.`);
+ }
}
})
});
@@ -42,9 +50,13 @@ export default class SessionManager extends ApiManager {
register({
method: Method.GET,
subscription: this.secureSubscriber("backup"),
- secureHandler: this.authorizedAction(({ res }) => {
- sessionAgent.serverWorker.sendMonitorAction("backup");
- res.send(`Your request was successful: the server is creating a new back up.`);
+ secureHandler: this.authorizedAction(async ({ res }) => {
+ const response = await sessionAgent.serverWorker.emitToMonitor("backup");
+ if (response instanceof Error) {
+ res.send(response);
+ } else {
+ res.send("Your request was successful: the server successfully created a new back up.");
+ }
})
});
diff --git a/src/server/DashSession.ts b/src/server/DashSession.ts
deleted file mode 100644
index 56610874e..000000000
--- a/src/server/DashSession.ts
+++ /dev/null
@@ -1,139 +0,0 @@
-import { Session } from "./Session/session";
-import { Email, pathFromRoot } from "./ActionUtilities";
-import { red, yellow, green, cyan } from "colors";
-import { get } from "request-promise";
-import { Utils } from "../Utils";
-import { WebSocket } from "./Websocket/Websocket";
-import { MessageStore } from "./Message";
-import { launchServer, onWindows } from ".";
-import { existsSync, mkdirSync, readdirSync, statSync, createWriteStream, readFileSync } from "fs";
-import * as Archiver from "archiver";
-import { resolve } from "path";
-
-/**
- * If we're the monitor (master) thread, we should launch the monitor logic for the session.
- * Otherwise, we must be on a worker thread that was spawned *by* the monitor (master) thread, and thus
- * our job should be to run the server.
- */
-export class DashSessionAgent extends Session.AppliedSessionAgent {
-
- private readonly notificationRecipients = ["samuel_wilkins@brown.edu"];
- private readonly signature = "-Dash Server Session Manager";
- private readonly releaseDesktop = pathFromRoot("../../Desktop");
-
- protected async launchMonitor() {
- const monitor = Session.Monitor.Create(this.notifiers);
- monitor.addReplCommand("pull", [], () => monitor.exec("git pull"));
- monitor.addReplCommand("solr", [/start|stop|index/], this.executeSolrCommand);
- monitor.addReplCommand("backup", [], this.backup);
- monitor.addReplCommand("debug", [/active|passive/, /\S+\@\S+/], async ([mode, recipient]) => this.dispatchZippedDebugBackup(mode, recipient));
- monitor.addServerMessageListener("backup", this.backup);
- monitor.addServerMessageListener("debug", ({ args: { mode, recipient } }) => this.dispatchZippedDebugBackup(mode, recipient));
- return monitor;
- }
-
- protected async launchServerWorker() {
- const worker = Session.ServerWorker.Create(launchServer); // server initialization delegated to worker
- worker.addExitHandler(this.notifyClient);
- return worker;
- }
-
- private readonly notifiers: Session.Monitor.NotifierHooks = {
- key: async key => {
- // this sends a pseudorandomly generated guid to the configuration's recipients, allowing them alone
- // to kill the server via the /kill/:key route
- const content = `The key for this session (started @ ${new Date().toUTCString()}) is ${key}.\n\n${this.signature}`;
- const failures = await Email.dispatchAll(this.notificationRecipients, "Dash Release Session Admin Authentication Key", content);
- if (failures) {
- failures.map(({ recipient, error: { message } }) => this.sessionMonitor.mainLog(red(`dispatch failure @ ${recipient} (${yellow(message)})`)));
- return false;
- }
- return true;
- },
- crash: async ({ name, message, stack }) => {
- const body = [
- "You, as a Dash Administrator, are being notified of a server crash event. Here's what we know:",
- `name:\n${name}`,
- `message:\n${message}`,
- `stack:\n${stack}`,
- "The server is already restarting itself, but if you're concerned, use the Remote Desktop Connection to monitor progress.",
- ].join("\n\n");
- const content = `${body}\n\n${this.signature}`;
- const failures = await Email.dispatchAll(this.notificationRecipients, "Dash Web Server Crash", content);
- if (failures) {
- failures.map(({ recipient, error: { message } }) => this.sessionMonitor.mainLog(red(`dispatch failure @ ${recipient} (${yellow(message)})`)));
- return false;
- }
- return true;
- }
- };
-
- private executeSolrCommand = async (args: string[]) => {
- const { exec, mainLog } = this.sessionMonitor;
- const action = args[0];
- if (action === "index") {
- exec("npx ts-node ./updateSearch.ts", { cwd: pathFromRoot("./src/server") });
- } else {
- const command = `${onWindows ? "solr.cmd" : "solr"} ${args[0] === "start" ? "start" : "stop -p 8983"}`;
- await exec(command, { cwd: "./solr-8.3.1/bin" });
- try {
- await get("http://localhost:8983");
- mainLog(green("successfully connected to 8983 after running solr initialization"));
- } catch {
- mainLog(red("unable to connect at 8983 after running solr initialization"));
- }
- }
- }
-
- private notifyClient: Session.ExitHandler = reason => {
- const { _socket } = WebSocket;
- if (_socket) {
- const message = typeof reason === "boolean" ? (reason ? "exit" : "temporary") : "crash";
- Utils.Emit(_socket, MessageStore.ConnectionTerminated, message);
- }
- }
-
- private backup = async () => this.sessionMonitor.exec("backup.bat", { cwd: this.releaseDesktop });
-
- private async dispatchZippedDebugBackup(mode: string, recipient: string) {
- const { mainLog } = this.sessionMonitor;
- try {
- if (mode === "active") {
- await this.backup();
- }
- mainLog("backup complete");
- const backupsDirectory = `${this.releaseDesktop}/backups`;
- const compressedDirectory = `${this.releaseDesktop}/compressed`;
- if (!existsSync(compressedDirectory)) {
- mkdirSync(compressedDirectory);
- }
- const target = readdirSync(backupsDirectory).map(filename => ({
- modifiedTime: statSync(`${backupsDirectory}/${filename}`).mtimeMs,
- filename
- })).sort((a, b) => b.modifiedTime - a.modifiedTime)[0].filename;
- mainLog(`targeting ${target}...`);
- const zipName = `${target}.zip`;
- const zipPath = `${compressedDirectory}/${zipName}`;
- const output = createWriteStream(zipPath);
- const zip = Archiver('zip');
- zip.pipe(output);
- zip.directory(`${backupsDirectory}/${target}/Dash`, false);
- await zip.finalize();
- mainLog(`zip finalized with size ${statSync(zipPath).size} bytes, saved to ${zipPath}`);
- let instructions = readFileSync(resolve(__dirname, "./remote_debug_instructions.txt"), { encoding: "utf8" });
- instructions = instructions.replace(/__zipname__/, zipName).replace(/__target__/, target).replace(/__signature__/, this.signature);
- const error = await Email.dispatch(recipient, `Compressed backup of ${target}...`, instructions, [
- {
- filename: zipName,
- path: zipPath
- }
- ]);
- mainLog(`${error === null ? green("successfully dispatched") : red("failed to dispatch")} ${zipName} to ${cyan(recipient)}`);
- error && mainLog(red(error.message));
- } catch (error) {
- mainLog(red("unable to dispatch zipped backup..."));
- mainLog(red(error.message));
- }
- }
-
-} \ No newline at end of file
diff --git a/src/server/DashSession/DashSessionAgent.ts b/src/server/DashSession/DashSessionAgent.ts
new file mode 100644
index 000000000..fe7cdae88
--- /dev/null
+++ b/src/server/DashSession/DashSessionAgent.ts
@@ -0,0 +1,221 @@
+import { Email, pathFromRoot } from "../ActionUtilities";
+import { red, yellow, green, cyan } from "colors";
+import { get } from "request-promise";
+import { Utils } from "../../Utils";
+import { WebSocket } from "../Websocket/Websocket";
+import { MessageStore } from "../Message";
+import { launchServer, onWindows } from "..";
+import { existsSync, mkdirSync, readdirSync, statSync, createWriteStream, readFileSync } from "fs";
+import * as Archiver from "archiver";
+import { resolve } from "path";
+import { AppliedSessionAgent, ExitHandler } from "../session/agents/applied_session_agent";
+import { Monitor } from "../session/agents/monitor";
+import { ServerWorker } from "../session/agents/server_worker";
+import { MessageHandler } from "../session/agents/promisified_ipc_manager";
+
+/**
+ * If we're the monitor (master) thread, we should launch the monitor logic for the session.
+ * Otherwise, we must be on a worker thread that was spawned *by* the monitor (master) thread, and thus
+ * our job should be to run the server.
+ */
+export class DashSessionAgent extends AppliedSessionAgent {
+
+ private readonly signature = "-Dash Server Session Manager";
+ private readonly releaseDesktop = pathFromRoot("../../Desktop");
+
+ /**
+ * The core method invoked when the single master thread is initialized.
+ * Installs event hooks, repl commands and additional IPC listeners.
+ */
+ protected async initializeMonitor(monitor: Monitor, sessionKey: string) {
+ await this.dispatchSessionPassword(sessionKey);
+ monitor.addReplCommand("pull", [], () => monitor.exec("git pull"));
+ monitor.addReplCommand("solr", [/start|stop|index/], this.executeSolrCommand);
+ monitor.addReplCommand("backup", [], this.backup);
+ monitor.addReplCommand("debug", [/active|passive/, /\S+\@\S+/], async ([mode, recipient]) => this.dispatchZippedDebugBackup(mode, recipient));
+ monitor.on("backup", this.backup);
+ monitor.on("debug", ({ mode, recipient }) => this.dispatchZippedDebugBackup(mode, recipient));
+ monitor.coreHooks.onCrashDetected(this.dispatchCrashReport);
+ }
+
+ /**
+ * The core method invoked when a server worker thread is initialized.
+ * Installs logic to be executed when the server worker dies.
+ */
+ protected async initializeServerWorker() {
+ const worker = ServerWorker.Create(launchServer); // server initialization delegated to worker
+ worker.addExitHandler(this.notifyClient);
+ return worker;
+ }
+
+ /**
+ * Prepares the body of the email with instructions on restoring the transmitted remote database backup locally.
+ */
+ private _remoteDebugInstructions: string | undefined;
+ private generateDebugInstructions = (zipName: string, target: string) => {
+ if (!this._remoteDebugInstructions) {
+ this._remoteDebugInstructions = readFileSync(resolve(__dirname, "./templates/remote_debug_instructions.txt"), { encoding: "utf8" });
+ }
+ return this._remoteDebugInstructions
+ .replace(/__zipname__/, zipName)
+ .replace(/__target__/, target)
+ .replace(/__signature__/, this.signature);
+ }
+
+ /**
+ * Prepares the body of the email with information regarding a crash event.
+ */
+ private _crashInstructions: string | undefined;
+ private generateCrashInstructions({ name, message, stack }: Error) {
+ if (!this._crashInstructions) {
+ this._crashInstructions = readFileSync(resolve(__dirname, "./templates/crash_instructions.txt"), { encoding: "utf8" });
+ }
+ return this._crashInstructions
+ .replace(/__name__/, name || "[no error name found]")
+ .replace(/__message__/, message || "[no error message found]")
+ .replace(/__stack__/, stack || "[no error stack found]")
+ .replace(/__signature__/, this.signature);
+ }
+
+ /**
+ * This sends a pseudorandomly generated guid to the configuration's recipients, allowing them alone
+ * to kill the server via the /kill/:key route.
+ */
+ private dispatchSessionPassword = async (sessionKey: string) => {
+ const { mainLog } = this.sessionMonitor;
+ const { notificationRecipient } = DashSessionAgent;
+ mainLog(green("dispatching session key..."));
+ const error = await Email.dispatch({
+ to: notificationRecipient,
+ subject: "Dash Release Session Admin Authentication Key",
+ content: `Here's the key for this session (started @ ${new Date().toUTCString()}):\n\n${sessionKey}.\n\n${this.signature}`
+ });
+ if (error) {
+ this.sessionMonitor.mainLog(red(`dispatch failure @ ${notificationRecipient} (${yellow(error.message)})`));
+ mainLog(red("distribution of session key experienced errors"));
+ } else {
+ mainLog(green("successfully distributed session key to recipients"));
+ }
+ }
+
+ /**
+ * This sends an email with the generated crash report.
+ */
+ private dispatchCrashReport: MessageHandler<{ error: Error }> = async ({ error: crashCause }) => {
+ const { mainLog } = this.sessionMonitor;
+ const { notificationRecipient } = DashSessionAgent;
+ const error = await Email.dispatch({
+ to: notificationRecipient,
+ subject: "Dash Web Server Crash",
+ content: this.generateCrashInstructions(crashCause)
+ });
+ if (error) {
+ this.sessionMonitor.mainLog(red(`dispatch failure @ ${notificationRecipient} ${yellow(`(${error.message})`)}`));
+ mainLog(red("distribution of crash notification experienced errors"));
+ } else {
+ mainLog(green("successfully distributed crash notification to recipients"));
+ }
+ }
+
+ /**
+ * Logic for interfacing with Solr. Either starts it,
+ * stops it, or rebuilds its indicies.
+ */
+ private executeSolrCommand = async (args: string[]) => {
+ const { exec, mainLog } = this.sessionMonitor;
+ const action = args[0];
+ if (action === "index") {
+ exec("npx ts-node ./updateSearch.ts", { cwd: pathFromRoot("./src/server") });
+ } else {
+ const command = `${onWindows ? "solr.cmd" : "solr"} ${args[0] === "start" ? "start" : "stop -p 8983"}`;
+ await exec(command, { cwd: "./solr-8.3.1/bin" });
+ try {
+ await get("http://localhost:8983");
+ mainLog(green("successfully connected to 8983 after running solr initialization"));
+ } catch {
+ mainLog(red("unable to connect at 8983 after running solr initialization"));
+ }
+ }
+ }
+
+ /**
+ * Broadcast to all clients that their connection
+ * is no longer valid, and explain why / what to expect.
+ */
+ private notifyClient: ExitHandler = reason => {
+ const { _socket } = WebSocket;
+ if (_socket) {
+ const message = typeof reason === "boolean" ? (reason ? "exit" : "temporary") : "crash";
+ Utils.Emit(_socket, MessageStore.ConnectionTerminated, message);
+ }
+ }
+
+ /**
+ * Performs a backup of the database, saved to the desktop subdirectory.
+ * This should work as is only on our specific release server.
+ */
+ private backup = async () => this.sessionMonitor.exec("backup.bat", { cwd: this.releaseDesktop });
+
+ /**
+ * Compress either a brand new backup or the most recent backup and send it
+ * as an attachment to an email, dispatched to the requested recipient.
+ * @param mode specifies whether or not to make a new backup before exporting
+ * @param to the recipient of the email
+ */
+ private async dispatchZippedDebugBackup(mode: string, to: string) {
+ const { mainLog } = this.sessionMonitor;
+ try {
+ // if desired, complete an immediate backup to send
+ if (mode === "active") {
+ await this.backup();
+ mainLog("backup complete");
+ }
+
+ // ensure the directory for compressed backups exists
+ const backupsDirectory = `${this.releaseDesktop}/backups`;
+ const compressedDirectory = `${this.releaseDesktop}/compressed`;
+ if (!existsSync(compressedDirectory)) {
+ mkdirSync(compressedDirectory);
+ }
+
+ // sort all backups by their modified time, and choose the most recent one
+ const target = readdirSync(backupsDirectory).map(filename => ({
+ modifiedTime: statSync(`${backupsDirectory}/${filename}`).mtimeMs,
+ filename
+ })).sort((a, b) => b.modifiedTime - a.modifiedTime)[0].filename;
+ mainLog(`targeting ${target}...`);
+
+ // create a zip file and to it, write the contents of the backup directory
+ const zipName = `${target}.zip`;
+ const zipPath = `${compressedDirectory}/${zipName}`;
+ const output = createWriteStream(zipPath);
+ const zip = Archiver('zip');
+ zip.pipe(output);
+ zip.directory(`${backupsDirectory}/${target}/Dash`, false);
+ await zip.finalize();
+ mainLog(`zip finalized with size ${statSync(zipPath).size} bytes, saved to ${zipPath}`);
+
+ // dispatch the email to the recipient, containing the finalized zip file
+ const error = await Email.dispatch({
+ to,
+ subject: `Remote debug: compressed backup of ${target}...`,
+ content: this.generateDebugInstructions(zipName, target),
+ attachments: [{ filename: zipName, path: zipPath }]
+ });
+
+ // indicate success or failure
+ mainLog(`${error === null ? green("successfully dispatched") : red("failed to dispatch")} ${zipName} to ${cyan(to)}`);
+ error && mainLog(red(error.message));
+ } catch (error) {
+ mainLog(red("unable to dispatch zipped backup..."));
+ mainLog(red(error.message));
+ }
+ }
+
+}
+
+export namespace DashSessionAgent {
+
+ export const notificationRecipient = "brownptcdash@gmail.com";
+
+} \ No newline at end of file
diff --git a/src/server/DashSession/templates/crash_instructions.txt b/src/server/DashSession/templates/crash_instructions.txt
new file mode 100644
index 000000000..65417919d
--- /dev/null
+++ b/src/server/DashSession/templates/crash_instructions.txt
@@ -0,0 +1,14 @@
+You, as a Dash Administrator, are being notified of a server crash event. Here's what we know:
+
+name:
+__name__
+
+message:
+__message__
+
+stack:
+__stack__
+
+The server is already restarting itself, but if you're concerned, use the Remote Desktop Connection to monitor progress.
+
+__signature__ \ No newline at end of file
diff --git a/src/server/remote_debug_instructions.txt b/src/server/DashSession/templates/remote_debug_instructions.txt
index c279c460a..c279c460a 100644
--- a/src/server/remote_debug_instructions.txt
+++ b/src/server/DashSession/templates/remote_debug_instructions.txt
diff --git a/src/server/RouteManager.ts b/src/server/RouteManager.ts
index 35d5131a4..a7ee405a7 100644
--- a/src/server/RouteManager.ts
+++ b/src/server/RouteManager.ts
@@ -68,7 +68,7 @@ export default class RouteManager {
console.log('please remove all duplicate routes before continuing');
}
if (malformedCount) {
- console.log(`please ensure all routes adhere to ^\/$|^\/[A-Za-z]+(\/\:[A-Za-z]+)*$`);
+ console.log(`please ensure all routes adhere to ^\/$|^\/[A-Za-z]+(\/\:[A-Za-z?]+)*$`);
}
process.exit(1);
} else {
@@ -131,7 +131,7 @@ export default class RouteManager {
} else {
route = subscriber.build;
}
- if (!/^\/$|^\/[A-Za-z]+(\/\:[A-Za-z]+)*$/g.test(route)) {
+ if (!/^\/$|^\/[A-Za-z]+(\/\:[A-Za-z?]+)*$/g.test(route)) {
this.failedRegistrations.push({
reason: RegistrationError.Malformed,
route
diff --git a/src/server/index.ts b/src/server/index.ts
index 2c8f32130..ef8ed9700 100644
--- a/src/server/index.ts
+++ b/src/server/index.ts
@@ -9,7 +9,7 @@ import initializeServer from './server_Initialization';
import RouteManager, { Method, _success, _permission_denied, _error, _invalid, PublicHandler } from './RouteManager';
import * as qs from 'query-string';
import UtilManager from './ApiManagers/UtilManager';
-import { SearchManager, SolrManager } from './ApiManagers/SearchManager';
+import { SearchManager } from './ApiManagers/SearchManager';
import UserManager from './ApiManagers/UserManager';
import { WebSocket } from './Websocket/Websocket';
import DownloadManager from './ApiManagers/DownloadManager';
@@ -17,17 +17,17 @@ import { GoogleCredentialsLoader } from './credentials/CredentialsLoader';
import DeleteManager from "./ApiManagers/DeleteManager";
import PDFManager from "./ApiManagers/PDFManager";
import UploadManager from "./ApiManagers/UploadManager";
-import { log_execution, Email } from "./ActionUtilities";
+import { log_execution } from "./ActionUtilities";
import GeneralGoogleManager from "./ApiManagers/GeneralGoogleManager";
import GooglePhotosManager from "./ApiManagers/GooglePhotosManager";
import { Logger } from "./ProcessFactory";
-import { yellow, red } from "colors";
-import { Session } from "./Session/session";
-import { DashSessionAgent } from "./DashSession";
+import { yellow } from "colors";
+import { DashSessionAgent } from "./DashSession/DashSessionAgent";
import SessionManager from "./ApiManagers/SessionManager";
+import { AppliedSessionAgent } from "./session/agents/applied_session_agent";
export const onWindows = process.platform === "win32";
-export let sessionAgent: Session.AppliedSessionAgent;
+export let sessionAgent: AppliedSessionAgent;
export const publicDirectory = path.resolve(__dirname, "public");
export const filesDirectory = path.resolve(publicDirectory, "files");
diff --git a/src/server/session/README.txt b/src/server/session/README.txt
new file mode 100644
index 000000000..ac7d3d4e7
--- /dev/null
+++ b/src/server/session/README.txt
@@ -0,0 +1,11 @@
+/**
+ * These abstractions rely on NodeJS's cluster module, which allows a parent (master) process to share
+ * code with its children (workers). A simple `isMaster` flag indicates who is trying to access
+ * the code, and thus determines the functionality that actually gets invoked (checked by the caller, not internally).
+ *
+ * Think of the master thread as a factory, and the workers as the helpers that actually run the server.
+ *
+ * So, when we run `npm start`, given the appropriate check, initializeMaster() is called in the parent process
+ * This will spawn off its own child process (by default, mirrors the execution path of its parent),
+ * in which initializeWorker() is invoked.
+ */ \ No newline at end of file
diff --git a/src/server/session/agents/applied_session_agent.ts b/src/server/session/agents/applied_session_agent.ts
new file mode 100644
index 000000000..48226dab6
--- /dev/null
+++ b/src/server/session/agents/applied_session_agent.ts
@@ -0,0 +1,58 @@
+import { isMaster } from "cluster";
+import { Monitor } from "./monitor";
+import { ServerWorker } from "./server_worker";
+import { Utils } from "../../../Utils";
+
+export type ExitHandler = (reason: Error | boolean) => void | Promise<void>;
+
+export abstract class AppliedSessionAgent {
+
+ // the following two methods allow the developer to create a custom
+ // session and use the built in customization options for each thread
+ protected abstract async initializeMonitor(monitor: Monitor, key: string): Promise<void>;
+ protected abstract async initializeServerWorker(): Promise<ServerWorker>;
+
+ private launched = false;
+
+ public killSession = (reason: string, graceful = true, errorCode = 0) => {
+ const target = isMaster ? this.sessionMonitor : this.serverWorker;
+ target.killSession(reason, graceful, errorCode);
+ }
+
+ private sessionMonitorRef: Monitor | undefined;
+ public get sessionMonitor(): Monitor {
+ if (!isMaster) {
+ this.serverWorker.emitToMonitor("kill", {
+ graceful: false,
+ reason: "Cannot access the session monitor directly from the server worker thread.",
+ errorCode: 1
+ });
+ throw new Error();
+ }
+ return this.sessionMonitorRef!;
+ }
+
+ private serverWorkerRef: ServerWorker | undefined;
+ public get serverWorker(): ServerWorker {
+ if (isMaster) {
+ throw new Error("Cannot access the server worker directly from the session monitor thread");
+ }
+ return this.serverWorkerRef!;
+ }
+
+ public async launch(): Promise<void> {
+ if (!this.launched) {
+ this.launched = true;
+ if (isMaster) {
+ const sessionKey = Utils.GenerateGuid();
+ await this.initializeMonitor(this.sessionMonitorRef = Monitor.Create(sessionKey), sessionKey);
+ this.sessionMonitorRef.finalize();
+ } else {
+ this.serverWorkerRef = await this.initializeServerWorker();
+ }
+ } else {
+ throw new Error("Cannot launch a session thread more than once per process.");
+ }
+ }
+
+} \ No newline at end of file
diff --git a/src/server/session/agents/monitor.ts b/src/server/session/agents/monitor.ts
new file mode 100644
index 000000000..5ea950b2b
--- /dev/null
+++ b/src/server/session/agents/monitor.ts
@@ -0,0 +1,302 @@
+import { ExitHandler } from "./applied_session_agent";
+import { Configuration, configurationSchema, defaultConfig, Identifiers, colorMapping } from "../utilities/session_config";
+import Repl, { ReplAction } from "../utilities/repl";
+import { isWorker, setupMaster, on, Worker, fork } from "cluster";
+import { IPC_Promisify, MessageHandler } from "./promisified_ipc_manager";
+import { red, cyan, white, yellow, blue } from "colors";
+import { exec, ExecOptions } from "child_process";
+import { validate, ValidationError } from "jsonschema";
+import { Utilities } from "../utilities/utilities";
+import { readFileSync } from "fs";
+import ProcessMessageRouter from "./process_message_router";
+import { ServerWorker } from "./server_worker";
+
+/**
+ * Validates and reads the configuration file, accordingly builds a child process factory
+ * and spawns off an initial process that will respawn as predecessors die.
+ */
+export class Monitor extends ProcessMessageRouter {
+ private static count = 0;
+ private finalized = false;
+ private exitHandlers: ExitHandler[] = [];
+ private readonly config: Configuration;
+ private activeWorker: Worker | undefined;
+ private key: string | undefined;
+ private repl: Repl;
+
+ public static Create(sessionKey: string) {
+ if (isWorker) {
+ ServerWorker.IPCManager.emit("kill", {
+ reason: "cannot create a monitor on the worker process.",
+ graceful: false,
+ errorCode: 1
+ });
+ process.exit(1);
+ } else if (++Monitor.count > 1) {
+ console.error(red("cannot create more than one monitor."));
+ process.exit(1);
+ } else {
+ return new Monitor(sessionKey);
+ }
+ }
+
+ private constructor(sessionKey: string) {
+ super();
+ this.config = this.loadAndValidateConfiguration();
+ this.initialize(sessionKey);
+ this.repl = this.initializeRepl();
+ }
+
+ private initialize = (sessionKey: string) => {
+ console.log(this.timestamp(), cyan("initializing session..."));
+ this.key = sessionKey;
+
+ // determines whether or not we see the compilation / initialization / runtime output of each child server process
+ const output = this.config.showServerOutput ? "inherit" : "ignore";
+ setupMaster({ stdio: ["ignore", output, output, "ipc"] });
+
+ // handle exceptions in the master thread - there shouldn't be many of these
+ // the IPC (inter process communication) channel closed exception can't seem
+ // to be caught in a try catch, and is inconsequential, so it is ignored
+ process.on("uncaughtException", ({ message, stack }): void => {
+ if (message !== "Channel closed") {
+ this.mainLog(red(message));
+ if (stack) {
+ this.mainLog(`uncaught exception\n${red(stack)}`);
+ }
+ }
+ });
+
+ // a helpful cluster event called on the master thread each time a child process exits
+ on("exit", ({ process: { pid } }, code, signal) => {
+ const prompt = `server worker with process id ${pid} has exited with code ${code}${signal === null ? "" : `, having encountered signal ${signal}`}.`;
+ this.mainLog(cyan(prompt));
+ // to make this a robust, continuous session, every time a child process dies, we immediately spawn a new one
+ this.spawn();
+ });
+ }
+
+ public finalize = (): void => {
+ if (this.finalized) {
+ throw new Error("Session monitor is already finalized");
+ }
+ this.finalized = true;
+ this.spawn();
+ }
+
+ public readonly coreHooks = Object.freeze({
+ onCrashDetected: (listener: MessageHandler<{ error: Error }>) => this.on(Monitor.IntrinsicEvents.CrashDetected, listener),
+ onServerRunning: (listener: MessageHandler<{ isFirstTime: boolean }>) => this.on(Monitor.IntrinsicEvents.ServerRunning, listener)
+ });
+
+ /**
+ * Kill this session and its active child
+ * server process, either gracefully (may wait
+ * indefinitely, but at least allows active networking
+ * requests to complete) or immediately.
+ */
+ public killSession = async (reason: string, graceful = true, errorCode = 0) => {
+ this.mainLog(cyan(`exiting session ${graceful ? "clean" : "immediate"}ly`));
+ this.mainLog(`session exit reason: ${(red(reason))}`);
+ await this.executeExitHandlers(true);
+ this.killActiveWorker(graceful, true);
+ process.exit(errorCode);
+ }
+
+ /**
+ * Execute the list of functions registered to be called
+ * whenever the process exits.
+ */
+ public addExitHandler = (handler: ExitHandler) => this.exitHandlers.push(handler);
+
+ /**
+ * Extend the default repl by adding in custom commands
+ * that can invoke application logic external to this module
+ */
+ public addReplCommand = (basename: string, argPatterns: (RegExp | string)[], action: ReplAction) => {
+ this.repl.registerCommand(basename, argPatterns, action);
+ }
+
+ public exec = (command: string, options?: ExecOptions) => {
+ return new Promise<void>(resolve => {
+ exec(command, { ...options, encoding: "utf8" }, (error, stdout, stderr) => {
+ if (error) {
+ this.execLog(red(`unable to execute ${white(command)}`));
+ error.message.split("\n").forEach(line => line.length && this.execLog(red(`(error) ${line}`)));
+ } else {
+ let outLines: string[], errorLines: string[];
+ if ((outLines = stdout.split("\n").filter(line => line.length)).length) {
+ outLines.forEach(line => line.length && this.execLog(cyan(`(stdout) ${line}`)));
+ }
+ if ((errorLines = stderr.split("\n").filter(line => line.length)).length) {
+ errorLines.forEach(line => line.length && this.execLog(yellow(`(stderr) ${line}`)));
+ }
+ }
+ resolve();
+ });
+ });
+ }
+
+ /**
+ * Generates a blue UTC string associated with the time
+ * of invocation.
+ */
+ private timestamp = () => blue(`[${new Date().toUTCString()}]`);
+
+ /**
+ * A formatted, identified and timestamped log in color
+ */
+ public mainLog = (...optionalParams: any[]) => {
+ console.log(this.timestamp(), this.config.identifiers.master.text, ...optionalParams);
+ }
+
+ /**
+ * A formatted, identified and timestamped log in color for non-
+ */
+ private execLog = (...optionalParams: any[]) => {
+ console.log(this.timestamp(), this.config.identifiers.exec.text, ...optionalParams);
+ }
+
+ /**
+ * Reads in configuration .json file only once, in the master thread
+ * and pass down any variables the pertinent to the child processes as environment variables.
+ */
+ private loadAndValidateConfiguration = (): Configuration => {
+ let config: Configuration;
+ try {
+ console.log(this.timestamp(), cyan("validating configuration..."));
+ config = JSON.parse(readFileSync('./session.config.json', 'utf8'));
+ const options = {
+ throwError: true,
+ allowUnknownAttributes: false
+ };
+ // ensure all necessary and no excess information is specified by the configuration file
+ validate(config, configurationSchema, options);
+ config = Utilities.preciseAssign({}, defaultConfig, config);
+ } catch (error) {
+ if (error instanceof ValidationError) {
+ console.log(red("\nSession configuration failed."));
+ console.log("The given session.config.json configuration file is invalid.");
+ console.log(`${error.instance}: ${error.stack}`);
+ process.exit(0);
+ } else if (error.code === "ENOENT" && error.path === "./session.config.json") {
+ console.log(cyan("Loading default session parameters..."));
+ console.log("Consider including a session.config.json configuration file in your project root for customization.");
+ config = Utilities.preciseAssign({}, defaultConfig);
+ } else {
+ console.log(red("\nSession configuration failed."));
+ console.log("The following unknown error occurred during configuration.");
+ console.log(error.stack);
+ process.exit(0);
+ }
+ } finally {
+ const { identifiers } = config!;
+ Object.keys(identifiers).forEach(key => {
+ const resolved = key as keyof Identifiers;
+ const { text, color } = identifiers[resolved];
+ identifiers[resolved].text = (colorMapping.get(color) || white)(`${text}:`);
+ });
+ return config!;
+ }
+ }
+
+ /**
+ * Builds the repl that allows the following commands to be typed into stdin of the master thread.
+ */
+ private initializeRepl = (): Repl => {
+ const repl = new Repl({ identifier: () => `${this.timestamp()} ${this.config.identifiers.master.text}` });
+ const boolean = /true|false/;
+ const number = /\d+/;
+ const letters = /[a-zA-Z]+/;
+ repl.registerCommand("exit", [/clean|force/], args => this.killSession("manual exit requested by repl", args[0] === "clean", 0));
+ repl.registerCommand("restart", [/clean|force/], args => this.killActiveWorker(args[0] === "clean"));
+ repl.registerCommand("set", [letters, "port", number, boolean], args => this.setPort(args[0], Number(args[2]), args[3] === "true"));
+ repl.registerCommand("set", [/polling/, number, boolean], args => {
+ const newPollingIntervalSeconds = Math.floor(Number(args[1]));
+ if (newPollingIntervalSeconds < 0) {
+ this.mainLog(red("the polling interval must be a non-negative integer"));
+ } else {
+ if (newPollingIntervalSeconds !== this.config.polling.intervalSeconds) {
+ this.config.polling.intervalSeconds = newPollingIntervalSeconds;
+ if (args[2] === "true") {
+ Monitor.IPCManager.emit("updatePollingInterval", { newPollingIntervalSeconds });
+ }
+ }
+ }
+ });
+ return repl;
+ }
+
+ private executeExitHandlers = async (reason: Error | boolean) => Promise.all(this.exitHandlers.map(handler => handler(reason)));
+
+ /**
+ * Attempts to kill the active worker gracefully, unless otherwise specified.
+ */
+ private killActiveWorker = (graceful = true, isSessionEnd = false): void => {
+ if (this.activeWorker && !this.activeWorker.isDead()) {
+ if (graceful) {
+ Monitor.IPCManager.emit("manualExit", { isSessionEnd });
+ } else {
+ this.activeWorker.process.kill();
+ }
+ }
+ }
+
+ /**
+ * Allows the caller to set the port at which the target (be it the server,
+ * the websocket, some other custom port) is listening. If an immediate restart
+ * is specified, this monitor will kill the active child and re-launch the server
+ * at the port. Otherwise, the updated port won't be used until / unless the child
+ * dies on its own and triggers a restart.
+ */
+ private setPort = (port: "server" | "socket" | string, value: number, immediateRestart: boolean): void => {
+ if (value > 1023 && value < 65536) {
+ this.config.ports[port] = value;
+ if (immediateRestart) {
+ this.killActiveWorker();
+ }
+ } else {
+ this.mainLog(red(`${port} is an invalid port number`));
+ }
+ }
+
+ /**
+ * Kills the current active worker and proceeds to spawn a new worker,
+ * feeding in configuration information as environment variables.
+ */
+ private spawn = (): void => {
+ const {
+ polling: {
+ route,
+ failureTolerance,
+ intervalSeconds
+ },
+ ports
+ } = this.config;
+ this.killActiveWorker();
+ this.activeWorker = fork({
+ pollingRoute: route,
+ pollingFailureTolerance: failureTolerance,
+ serverPort: ports.server,
+ socketPort: ports.socket,
+ pollingIntervalSeconds: intervalSeconds,
+ session_key: this.key
+ });
+ Monitor.IPCManager = IPC_Promisify(this.activeWorker, this.route);
+ this.mainLog(cyan(`spawned new server worker with process id ${this.activeWorker?.process.pid}`));
+
+ this.on("kill", ({ reason, graceful, errorCode }) => this.killSession(reason, graceful, errorCode), true);
+ this.on("lifecycle", ({ event }) => console.log(this.timestamp(), `${this.config.identifiers.worker.text} lifecycle phase (${event})`), true);
+ }
+
+}
+
+export namespace Monitor {
+
+ export enum IntrinsicEvents {
+ KeyGenerated = "key_generated",
+ CrashDetected = "crash_detected",
+ ServerRunning = "server_running"
+ }
+
+} \ No newline at end of file
diff --git a/src/server/session/agents/process_message_router.ts b/src/server/session/agents/process_message_router.ts
new file mode 100644
index 000000000..d359e97c3
--- /dev/null
+++ b/src/server/session/agents/process_message_router.ts
@@ -0,0 +1,46 @@
+import { MessageHandler, PromisifiedIPCManager } from "./promisified_ipc_manager";
+
+export default abstract class ProcessMessageRouter {
+
+ protected static IPCManager: PromisifiedIPCManager;
+ private onMessage: { [name: string]: MessageHandler[] | undefined } = {};
+
+ /**
+ * Add a listener at this message. When the monitor process
+ * receives a message, it will invoke all registered functions.
+ */
+ public on = (name: string, handler: MessageHandler, exclusive = false) => {
+ const handlers = this.onMessage[name];
+ if (exclusive || !handlers) {
+ this.onMessage[name] = [handler];
+ } else {
+ handlers.push(handler);
+ }
+ }
+
+ /**
+ * Unregister a given listener at this message.
+ */
+ public off = (name: string, handler: MessageHandler) => {
+ const handlers = this.onMessage[name];
+ if (handlers) {
+ const index = handlers.indexOf(handler);
+ if (index > -1) {
+ handlers.splice(index, 1);
+ }
+ }
+ }
+
+ /**
+ * Unregister all listeners at this message.
+ */
+ public clearMessageListeners = (...names: string[]) => names.map(name => this.onMessage[name] = undefined);
+
+ protected route: MessageHandler = async ({ name, args }) => {
+ const handlers = this.onMessage[name];
+ if (handlers) {
+ await Promise.all(handlers.map(handler => handler(args)));
+ }
+ }
+
+} \ No newline at end of file
diff --git a/src/server/session/agents/promisified_ipc_manager.ts b/src/server/session/agents/promisified_ipc_manager.ts
new file mode 100644
index 000000000..216e9be44
--- /dev/null
+++ b/src/server/session/agents/promisified_ipc_manager.ts
@@ -0,0 +1,97 @@
+import { Utils } from "../../../Utils";
+import { isMaster } from "cluster";
+
+/**
+ * Convenience constructor
+ * @param target the process / worker to which to attach the specialized listeners
+ */
+export function IPC_Promisify(target: IPCTarget, router: Router) {
+ return new PromisifiedIPCManager(target, router);
+}
+
+/**
+ * Essentially, a node process or node cluster worker
+ */
+export type IPCTarget = NodeJS.EventEmitter & { send?: Function };
+
+/**
+ * Some external code that maps the name of incoming messages to registered handlers, if any
+ * when this returns, the message is assumed to have been handled in its entirety by the process, so
+ * await any asynchronous code inside this router.
+ */
+export type Router = (message: Message) => void | Promise<void>;
+
+/**
+ * Specifies a general message format for this API
+ */
+export type Message<T = any> = { name: string; args: T; };
+export type MessageHandler<T = any> = (args: T) => any | Promise<any>;
+
+/**
+ * When a message is emitted, it
+ */
+type InternalMessage = Message & { metadata: any };
+type InternalMessageHandler = (message: InternalMessage) => any | Promise<any>;
+
+/**
+ * This is a wrapper utility class that allows the caller process
+ * to emit an event and return a promise that resolves when it and all
+ * other processes listening to its emission of this event have completed.
+ */
+export class PromisifiedIPCManager {
+ private readonly target: IPCTarget;
+
+ constructor(target: IPCTarget, router: Router) {
+ this.target = target;
+ this.target.addListener("message", this.internalHandler(router));
+ }
+
+ /**
+ * A convenience wrapper around the standard process emission.
+ * Does not wait for a response.
+ */
+ public emit = async (name: string, args?: any) => this.target.send?.({ name, args });
+
+ /**
+ * This routine uniquely identifies each message, then adds a general
+ * message listener that waits for a response with the same id before resolving
+ * the promise.
+ */
+ public emitPromise = async (name: string, args?: any) => {
+ return new Promise(resolve => {
+ const messageId = Utils.GenerateGuid();
+ const responseHandler: InternalMessageHandler = ({ metadata: { id, isResponse }, args, name }) => {
+ if (isResponse && id === messageId) {
+ this.target.removeListener("message", responseHandler);
+ resolve(args?.error as Error | undefined);
+ }
+ };
+ this.target.addListener("message", responseHandler);
+ const message = { name, args, metadata: { id: messageId } };
+ this.target.send?.(message);
+ });
+ }
+
+ /**
+ * This routine receives a uniquely identified message. If the message is itself a response,
+ * it is ignored to avoid infinite mutual responses. Otherwise, the routine awaits its completion using whatever
+ * router the caller has installed, and then sends a response containing the original message id,
+ * which will ultimately invoke the responseHandler of the original emission and resolve the
+ * sender's promise.
+ */
+ private internalHandler = (router: Router) => async ({ name, args, metadata }: InternalMessage) => {
+ if (name && (!metadata || !metadata.isResponse)) {
+ let error: Error | undefined;
+ try {
+ await router({ name, args });
+ } catch (e) {
+ error = e;
+ }
+ if (metadata && this.target.send) {
+ metadata.isResponse = true;
+ this.target.send({ name, args: { error }, metadata });
+ }
+ }
+ }
+
+} \ No newline at end of file
diff --git a/src/server/session/agents/server_worker.ts b/src/server/session/agents/server_worker.ts
new file mode 100644
index 000000000..705307030
--- /dev/null
+++ b/src/server/session/agents/server_worker.ts
@@ -0,0 +1,160 @@
+import { ExitHandler } from "./applied_session_agent";
+import { isMaster } from "cluster";
+import { PromisifiedIPCManager } from "./promisified_ipc_manager";
+import ProcessMessageRouter from "./process_message_router";
+import { red, green, white, yellow } from "colors";
+import { get } from "request-promise";
+import { Monitor } from "./monitor";
+
+/**
+ * Effectively, each worker repairs the connection to the server by reintroducing a consistent state
+ * if its predecessor has died. It itself also polls the server heartbeat, and exits with a notification
+ * email if the server encounters an uncaught exception or if the server cannot be reached.
+ */
+export class ServerWorker extends ProcessMessageRouter {
+ private static count = 0;
+ private shouldServerBeResponsive = false;
+ private exitHandlers: ExitHandler[] = [];
+ private pollingFailureCount = 0;
+ private pollingIntervalSeconds: number;
+ private pollingFailureTolerance: number;
+ private pollTarget: string;
+ private serverPort: number;
+ private isInitialized = false;
+
+ public static Create(work: Function) {
+ if (isMaster) {
+ console.error(red("cannot create a worker on the monitor process."));
+ process.exit(1);
+ } else if (++ServerWorker.count > 1) {
+ ServerWorker.IPCManager.emit("kill", {
+ reason: "cannot create more than one worker on a given worker process.",
+ graceful: false,
+ errorCode: 1
+ });
+ process.exit(1);
+ } else {
+ return new ServerWorker(work);
+ }
+ }
+
+ /**
+ * Allows developers to invoke application specific logic
+ * by hooking into the exiting of the server process.
+ */
+ public addExitHandler = (handler: ExitHandler) => this.exitHandlers.push(handler);
+
+ /**
+ * Kill the session monitor (parent process) from this
+ * server worker (child process). This will also kill
+ * this process (child process).
+ */
+ public killSession = (reason: string, graceful = true, errorCode = 0) => this.emitToMonitor("kill", { reason, graceful, errorCode });
+
+ /**
+ * A convenience wrapper to tell the session monitor (parent process)
+ * to carry out the action with the specified message and arguments.
+ */
+ public emitToMonitor = (name: string, args?: any) => ServerWorker.IPCManager.emit(name, args);
+
+ public emitToMonitorPromise = (name: string, args?: any) => ServerWorker.IPCManager.emitPromise(name, args);
+
+ private constructor(work: Function) {
+ super();
+ ServerWorker.IPCManager = new PromisifiedIPCManager(process, this.route);
+ this.lifecycleNotification(green(`initializing process... ${white(`[${process.execPath} ${process.execArgv.join(" ")}]`)}`));
+
+ const { pollingRoute, serverPort, pollingIntervalSeconds, pollingFailureTolerance } = process.env;
+ this.serverPort = Number(serverPort);
+ this.pollingIntervalSeconds = Number(pollingIntervalSeconds);
+ this.pollingFailureTolerance = Number(pollingFailureTolerance);
+ this.pollTarget = `http://localhost:${serverPort}${pollingRoute}`;
+
+ this.configureProcess();
+ work();
+ this.pollServer();
+ }
+
+ /**
+ * Set up message and uncaught exception handlers for this
+ * server process.
+ */
+ private configureProcess = () => {
+ // updates the local values of variables to the those sent from master
+ this.on("updatePollingInterval", ({ newPollingIntervalSeconds }) => this.pollingIntervalSeconds = newPollingIntervalSeconds);
+ this.on("manualExit", async ({ isSessionEnd }) => {
+ await this.executeExitHandlers(isSessionEnd);
+ process.exit(0);
+ });
+
+ // one reason to exit, as the process might be in an inconsistent state after such an exception
+ process.on('uncaughtException', this.proactiveUnplannedExit);
+ process.on('unhandledRejection', reason => {
+ const appropriateError = reason instanceof Error ? reason : new Error(`unhandled rejection: ${reason}`);
+ this.proactiveUnplannedExit(appropriateError);
+ });
+ }
+
+ /**
+ * Execute the list of functions registered to be called
+ * whenever the process exits.
+ */
+ private executeExitHandlers = async (reason: Error | boolean) => Promise.all(this.exitHandlers.map(handler => handler(reason)));
+
+ /**
+ * Notify master thread (which will log update in the console) of initialization via IPC.
+ */
+ public lifecycleNotification = (event: string) => ServerWorker.IPCManager.emit("lifecycle", { event });
+
+ /**
+ * Called whenever the process has a reason to terminate, either through an uncaught exception
+ * in the process (potentially inconsistent state) or the server cannot be reached.
+ */
+ private proactiveUnplannedExit = async (error: Error): Promise<void> => {
+ this.shouldServerBeResponsive = false;
+ // communicates via IPC to the master thread that it should dispatch a crash notification email
+ this.emitToMonitor(Monitor.IntrinsicEvents.CrashDetected, { error });
+ await this.executeExitHandlers(error);
+ // notify master thread (which will log update in the console) of crash event via IPC
+ this.lifecycleNotification(red(`crash event detected @ ${new Date().toUTCString()}`));
+ this.lifecycleNotification(red(error.message));
+ process.exit(1);
+ }
+
+ /**
+ * This monitors the health of the server by submitting a get request to whatever port / route specified
+ * by the configuration every n seconds, where n is also given by the configuration.
+ */
+ private pollServer = async (): Promise<void> => {
+ await new Promise<void>(resolve => {
+ setTimeout(async () => {
+ try {
+ await get(this.pollTarget);
+ if (!this.shouldServerBeResponsive) {
+ // notify monitor thread that the server is up and running
+ this.lifecycleNotification(green(`listening on ${this.serverPort}...`));
+ this.emitToMonitor(Monitor.IntrinsicEvents.ServerRunning, { isFirstTime: !this.isInitialized });
+ this.isInitialized = true;
+ }
+ this.shouldServerBeResponsive = true;
+ } catch (error) {
+ // if we expect the server to be unavailable, i.e. during compilation,
+ // the listening variable is false, activeExit will return early and the child
+ // process will continue
+ if (this.shouldServerBeResponsive) {
+ if (++this.pollingFailureCount > this.pollingFailureTolerance) {
+ this.proactiveUnplannedExit(error);
+ } else {
+ this.lifecycleNotification(yellow(`the server has encountered ${this.pollingFailureCount} of ${this.pollingFailureTolerance} tolerable failures`));
+ }
+ }
+ } finally {
+ resolve();
+ }
+ }, 1000 * this.pollingIntervalSeconds);
+ });
+ // controlled, asynchronous infinite recursion achieves a persistent poll that does not submit a new request until the previous has completed
+ this.pollServer();
+ }
+
+} \ No newline at end of file
diff --git a/src/server/repl.ts b/src/server/session/utilities/repl.ts
index ad55b6aaa..643141286 100644
--- a/src/server/repl.ts
+++ b/src/server/session/utilities/repl.ts
@@ -54,7 +54,7 @@ export default class Repl {
}
}
- private success = (command: string) => `${this.resolvedIdentifier()} completed execution of ${white(command)}`;
+ private success = (command: string) => `${this.resolvedIdentifier()} completed local execution of ${white(command)}`;
public registerCommand = (basename: string, argPatterns: (RegExp | string)[], action: ReplAction) => {
const existing = this.commandMap.get(basename);
diff --git a/src/server/Session/session_config_schema.ts b/src/server/session/utilities/session_config.ts
index e32cf8c6a..b0e65dde4 100644
--- a/src/server/Session/session_config_schema.ts
+++ b/src/server/session/utilities/session_config.ts
@@ -1,4 +1,5 @@
import { Schema } from "jsonschema";
+import { yellow, red, cyan, green, blue, magenta, Color, grey, gray, white, black } from "colors";
const colorPattern = /black|red|green|yellow|blue|magenta|cyan|white|gray|grey/;
@@ -64,4 +65,65 @@ export const configurationSchema: Schema = {
}
},
}
+};
+
+type ColorLabel = "yellow" | "red" | "cyan" | "green" | "blue" | "magenta" | "grey" | "gray" | "white" | "black";
+
+export const colorMapping: Map<ColorLabel, Color> = new Map([
+ ["yellow", yellow],
+ ["red", red],
+ ["cyan", cyan],
+ ["green", green],
+ ["blue", blue],
+ ["magenta", magenta],
+ ["grey", grey],
+ ["gray", gray],
+ ["white", white],
+ ["black", black]
+]);
+
+interface Identifier {
+ text: string;
+ color: ColorLabel;
+}
+
+export interface Identifiers {
+ master: Identifier;
+ worker: Identifier;
+ exec: Identifier;
+}
+
+export interface Configuration {
+ showServerOutput: boolean;
+ identifiers: Identifiers;
+ ports: { [description: string]: number };
+ polling: {
+ route: string;
+ intervalSeconds: number;
+ failureTolerance: number;
+ };
+}
+
+export const defaultConfig: Configuration = {
+ showServerOutput: false,
+ identifiers: {
+ master: {
+ text: "__monitor__",
+ color: "yellow"
+ },
+ worker: {
+ text: "__server__",
+ color: "magenta"
+ },
+ exec: {
+ text: "__exec__",
+ color: "green"
+ }
+ },
+ ports: { server: 3000 },
+ polling: {
+ route: "/",
+ intervalSeconds: 30,
+ failureTolerance: 0
+ }
}; \ No newline at end of file
diff --git a/src/server/session/utilities/utilities.ts b/src/server/session/utilities/utilities.ts
new file mode 100644
index 000000000..ac8a6590a
--- /dev/null
+++ b/src/server/session/utilities/utilities.ts
@@ -0,0 +1,31 @@
+export namespace Utilities {
+
+ /**
+ * At any arbitrary layer of nesting within the configuration objects, any single value that
+ * is not specified by the configuration is given the default counterpart. If, within an object,
+ * one peer is given by configuration and two are not, the one is preserved while the two are given
+ * the default value.
+ * @returns the composition of all of the assigned objects, much like Object.assign(), but with more
+ * granularity in the overwriting of nested objects
+ */
+ export function preciseAssign(target: any, ...sources: any[]): any {
+ for (const source of sources) {
+ preciseAssignHelper(target, source);
+ }
+ return target;
+ }
+
+ export function preciseAssignHelper(target: any, source: any) {
+ Array.from(new Set([...Object.keys(target), ...Object.keys(source)])).map(property => {
+ let targetValue: any, sourceValue: any;
+ if (sourceValue = source[property]) {
+ if (typeof sourceValue === "object" && typeof (targetValue = target[property]) === "object") {
+ preciseAssignHelper(targetValue, sourceValue);
+ } else {
+ target[property] = sourceValue;
+ }
+ }
+ });
+ }
+
+} \ No newline at end of file