From e177cbd042b2c04a1a3ef84da1c808183b898bd7 Mon Sep 17 00:00:00 2001 From: Scott Lamb Date: Mon, 4 May 2020 23:06:12 -0700 Subject: [PATCH 1/6] improve mobile-friendliness (#68) nav div changes: * make it togglable (on all devices) by hamburger button * on narrow devices, make it closed by default and be at the top rather than on the left open zoomed by default trim some arguably less important columns on narrow displays, and reduce some horizontal padding always show videos full-screen on narrow displays --- ui-src/NVRApplication.js | 14 +++++++++-- ui-src/assets/index.css | 37 ++++++++++++++++++++++------- ui-src/assets/index.html | 34 ++++++++++++++------------ ui-src/lib/views/RecordingsView.js | 4 ++-- ui-src/lib/views/VideoDialogView.js | 23 ++++++++++++++---- 5 files changed, 81 insertions(+), 31 deletions(-) diff --git a/ui-src/NVRApplication.js b/ui-src/NVRApplication.js index ca92ee3..14a40df 100644 --- a/ui-src/NVRApplication.js +++ b/ui-src/NVRApplication.js @@ -143,9 +143,14 @@ function onSelectVideo(nvrSettingsView, camera, streamType, range, recording) { ); const videoTitle = camera.shortName + ', ' + formattedStart + ' to ' + formattedEnd; + const maxWidth = window.innerWidth / 2; + let width = recording.videoSampleEntryWidth; + while (width > maxWidth) { + width /= 2; + } new VideoDialogView() .attach($('body')) - .play(videoTitle, recording.videoSampleEntryWidth / 4, url); + .play(videoTitle, width, url); } /** @@ -220,7 +225,7 @@ function updateSession(session) { return; } sessionBar.append($('').text(session.username)); - const logout = $('logout'); + const logout = $('logout'); logout.click(() => { api .logout(session.csrf) @@ -377,6 +382,11 @@ export default class NVRApplication { * Start the application. */ start() { + let nav = $('#nav'); + + $('#toggle-nav').click(() => { + nav.toggle('slide'); + }); loginDialog = $('#login').dialog({ autoOpen: false, modal: true, diff --git a/ui-src/assets/index.css b/ui-src/assets/index.css index 1165ea2..96852a7 100644 --- a/ui-src/assets/index.css +++ b/ui-src/assets/index.css @@ -1,12 +1,24 @@ body { font-family: Arial, Helvetica, sans-serif; } +#top { + width: 100%; + padding-bottom: 2ex; +} +#toggle-nav { + font-size: 1.25em; + cursor: pointer; +} #nav { float: left; + margin: 0 0.5em 0.5ex 0; } #session { float: right; } +#logout { + cursor: pointer; +} #datetime .ui-datepicker { width: 100%; @@ -14,17 +26,15 @@ body { #videos { display: inline-block; - padding-top: 0.5em; - padding-left: 1em; - padding-right: 1em; } #videos tbody:after { content: ""; display: block; height: 3ex; } -table.videos { +table#videos { border-collapse: collapse; + /*border-spacing: 0.5em 0.5ex;*/ } tbody tr.name { font-size: 110%; @@ -47,8 +57,8 @@ tr.r td { tr.r th, tr.r td { border: 0; - padding: 0.5ex 1.5em; text-align: right; + padding: 0.5ex 1.5em; } fieldset { @@ -62,9 +72,6 @@ fieldset legend { #from, #to { padding-right: 0.75em; } -#st { - width: 100%; -} #range { padding: 0.5em 0; @@ -78,3 +85,17 @@ video { width: 100%; height: 100%; } + +@media only screen and (max-width: 768px) { + #nav { + float: none; + display: none; + } + .resolution, .frameRate, .size { + display: none; + } + tr.r th, + tr.r td { + padding: 0.5ex 0.5em; + } +} diff --git a/ui-src/assets/index.html b/ui-src/assets/index.html index fa1ac44..ef0b63a 100644 --- a/ui-src/assets/index.html +++ b/ui-src/assets/index.html @@ -3,9 +3,12 @@ Moonfire NVR + -
+
+ +
- -
-
-
-
- - - - - - - - - - - - - -
-

-
-
-
- - diff --git a/ui-src/favicon.ico b/ui-src/favicon.ico deleted file mode 100644 index 08e133d1b6ab9268209042340ae5fa884ce54051..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15086 zcmdU03vgUj8NR#OY+n0FHpwQXg{G7~>?3Vx=_4&kp{0}-+N6|+f+JQCbmU=$qM$Z~ z@(`-15m5$3RJ8a45fL9ipj1T>Xtym&r4z<>#(^0?hGFPT$?^OCbI;wok9+sg4GcT; z=Wg!3=bZ2S=bZn&mKCt7tl6_ITsy37lPqhVWmz2^_WzBRwIBByapm(%LY8$SUYLq^ z(8Rg`#QX9&PG2hdH`%u<2I>ZF0Br+34|)Z32&8P{ci!VOzQcFfCRRx-#rB19t3cC0 zSA&K?uY%qM8N7wAe3xz5mVL0Vs$$14_dSde1a*OK2OR*7fC^zP^qhULFZRj4gXQA$ zYlnW@L7PDbL4`1t`<#7qjCMaPr94Al0ZP- z7Tm3;|3x(}{I;q+`V1AUZBal>dK0t}6b2Rj0bcT**xw#C?BsP{N;NP4y^7BIqN;A0 zs{&QE2DkhAHh^;uMXv)ebI*(p-}_Ulb@e|~Q}0i(M=nrRk@3n31l@S^edjuGFBSX% zcQ0sk_B-}U^C`bowc}Q(U^t!+r{BGU0N?930pO;Ld=gZ6-KY!ql%-mQAqxbV*^+nuMwy-=~^RyjygY*fp}h_Ndt0 zTU4MrmbWeOC;Rt$SuxD9#uDftqRsO=N;E;E`jQ(syXTu*fqD~ z{5`GLgZ=gVP}Oy;bK5!6Z;AMc+4y|9bA}z**!^8qGj_Qrzr1i~--jJ3XN0_OUGiNk7*%ME%%u@DsD~SMiH^?{Y3`$E_^KhV-0wnrA=N>rmu8A~UW8jz-UZxpxEA5y+8cD!$-bB1c3A0B8ai{j1Cx1d!HH`Dck(MK0f<5?HT8^CZ zkZSnQr79Gi=(#70!R~&CK4mz$(BYY!^YlDSOi!N^u@7L^z(%B)lWsG^;phaEPux0WV6>d2JzIml&ZwP+CjrM+WVyPbXgVt%H8_*`)I=>)} zU|pN4JN6^+&nZWqPs`rCo4OKJd zlBU*~~+5+@)hpMakZ! zkiCQ0w@=G@P|r5?{1`ItY{=f$qSu3GAb!FvX74->Jr~Ei&<7~Zf3fEwI4FCMJr_8N zk-d~7H{)E;hJ)<`Ju9)oN$U&BJno`g8B!9b=vNtwa-lZSv z$X?34&TGU6Hue~KPdiv_RxSG(YjFH`dkrcRKXGL5qdKmc=v3Ud#E_pLdmA8oCtrlU zbic@TNA@CK5^kL*aZ&p7c6@*_o{ad3jlZ(-E5td;Q~Khuxi5@+ed z5*u~P-p20l=)KmLVr-2uww(BtJ%>?Zc9 zIyRHG;TYS@8$Tp|e(<~(Gz#%sdmfa%&A%2Ex%wXGPj_!`JL{#M&O37B{ApyReZw3+kojx( zEHMY#8K!=Kd#Vz-8ume*I;!;pS@ZZn)^E7yV7`NI?`!>xQo}V0+QXrDEDIS~OAT8V zJytbjS&V+F0WF#F75`Y)2(Ozg>oBjqmW5_$XjyOY3a?_A*P8Toi2tKPCi^-nqj4YszQ`|{XQ_>S=wfOde&m!qO{_rR~+F%s+A zyaROw3yQ&jF_(e%fxPDAe_w3!UGQ7sFV4JL@)CCa$Ucm}%nt*`hNDhjz zbBT54)_)K~UOr&laiFI_{`1TG9AhI7&6qXgvlzpVp2G8SZa!d4>K*R2GR9_`l=yK{ z^Ws0Y#7*JXZtb{AIdz2?w}@Do4>tIuj9K`Nuk+uX$n9Lo{5Q{3H+g_7=gzb0J$LbW zkvn6q-^rW1-uD@wISA$o12#IOPm>hcsXgKfqF1wYn3&uGalcIklIVpRu zd-0!n^QI+;cOo~c<1_FT)AQt*9GmhoQ?3a6(dq1c&72Cw^4$ zY0EKlFXZsT<`d({brX1Y@6~5l?@QV(*nc`V&wV2~K|}6cT?A;&tFDt?`Fx5W$!(0naUK zKTs#Yu_*&G>&)7DjgMn36}07E*RTmd{x(}q|dI-HSFNpQ|E~e#>;THfIJoy++hku)cya6!mlal56+++TSh=NA7+{p|fE`Cl#!A>epl{7-{{S70Cx`qY${74^T>8*!xu0t)el zO^7}8zJq8BViNITgcpVoY9I|j(HgP}e9U{i4%zL8(HHw<-yDNuaZHZQI0eHJ9Uv!8 zQNUvd4{AUwLHB_eZ>0Vr@jLFNR<@tBA5oUv51x+!4T4?=W!poP542NWhkhJHo$(lV z4|dxJ^R`1@tifVUGHa8o>W_l%2|S4Q(g)fwZ@_U~W4df(j0-;43-QsP>itlUFSS0b`N4X^*4T5v zk%GElC(=G5?{n9WzgJm&x74NacOSa0uMhoPC$?pE({%bYueGh)&$fB?kFiTwgS<_2 zK6SjdRZ&+rpMKfXgYD=3SMo&YgL^;!{?&YzT5;AbhN8!E|2#P6{Qu=U13u?Ra#pWH x*AK?#Y{_VA&Jr*bIKR7Awyk?HtmktUAAG{{{yV%{B-~T diff --git a/ui-src/favicon.svg b/ui-src/favicon.svg new file mode 100644 index 0000000..927f5d4 --- /dev/null +++ b/ui-src/favicon.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ui-src/assets/index.css b/ui-src/index.css similarity index 100% rename from ui-src/assets/index.css rename to ui-src/index.css diff --git a/ui-src/index.html b/ui-src/index.html new file mode 100644 index 0000000..c63ebef --- /dev/null +++ b/ui-src/index.html @@ -0,0 +1,110 @@ + + + Moonfire NVR + + + +
+ +
+ + +
+
+
+
+ + + + + + + + + + + + + +
+

+
+
+
diff --git a/ui-src/index.js b/ui-src/index.js index 9eab9ff..d24a320 100644 --- a/ui-src/index.js +++ b/ui-src/index.js @@ -33,7 +33,6 @@ import NVRApplication from './NVRApplication'; import $ from 'jquery'; -import './favicon.ico'; // On document load, start application $(function() { diff --git a/ui-src/lib/MoonfireAPI.js b/ui-src/lib/MoonfireAPI.js index 774a6c6..f7924b5 100644 --- a/ui-src/lib/MoonfireAPI.js +++ b/ui-src/lib/MoonfireAPI.js @@ -146,16 +146,14 @@ export default class MoonfireAPI { * Start a new AJAX request with the specified URL. * * @param {String} url URL to use - * @param {String} cacheOk True if cached results are OK * @return {Request} jQuery request type */ - request(url, cacheOk = false) { + request(url) { return $.ajax(url, { dataType: 'json', headers: { Accept: 'application/json', }, - cache: cacheOk, }); } diff --git a/webpack/base.config.js b/webpack/base.config.js index f3ff49c..4f98b57 100644 --- a/webpack/base.config.js +++ b/webpack/base.config.js @@ -1,7 +1,7 @@ // vim: set et sw=2 ts=2: // // This file is part of Moonfire NVR, a security camera network video recorder. -// Copyright (C) 2018 The Moonfire NVR Authors +// Copyright (C) 2018-2020 The Moonfire NVR Authors // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by @@ -32,6 +32,7 @@ const path = require('path'); const webpack = require('webpack'); +const FaviconsWebpackPlugin = require('favicons-webpack-plugin') const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { @@ -39,7 +40,7 @@ module.exports = { nvr: './ui-src/index.js', }, output: { - filename: '[name].bundle.js', + filename: '[name].[chunkhash].js', path: path.resolve('./ui-dist/'), publicPath: '/', }, @@ -63,15 +64,11 @@ module.exports = { }, { test: /\.png$/, - use: ['file-loader'], - }, - { - test: /\.ico$/, use: [ { loader: 'file-loader', options: { - name: '[name].[ext]', + name: '[name].[contenthash].[ext]', }, }, ], @@ -86,9 +83,7 @@ module.exports = { plugins: [ new webpack.IgnorePlugin(/\.\/locale$/), new HtmlWebpackPlugin({ - title: 'Moonfire NVR', - filename: 'index.html', - template: './ui-src/assets/index.html', + template: './ui-src/index.html', }), new webpack.NormalModuleReplacementPlugin( /node_modules\/moment\/moment\.js$/, @@ -98,5 +93,16 @@ module.exports = { /node_modules\/moment-timezone\/index\.js$/, './builds/moment-timezone-with-data-2012-2022.min.js' ), + new FaviconsWebpackPlugin({ + logo: './ui-src/favicon.svg', + mode: 'webapp', + devMode: 'light', + prefix: 'favicons-[hash]/', + favicons: { + coast: false, + windows: false, + yandex: false, + }, + }), ], }; diff --git a/webpack/dev.config.js b/webpack/dev.config.js index da4af7e..e6ac419 100644 --- a/webpack/dev.config.js +++ b/webpack/dev.config.js @@ -44,6 +44,9 @@ module.exports = merge(baseConfig, { minimize: false, namedChunks: true, }, + output: { + filename: '[name].[hash].js', + }, devServer: { inline: true, port: process.env.MOONFIRE_DEV_PORT || 3000, diff --git a/yarn.lock b/yarn.lock index 1db1716..7157365 100644 --- a/yarn.lock +++ b/yarn.lock @@ -703,6 +703,13 @@ "@babel/types" "^7.4.4" esutils "^2.0.2" +"@babel/runtime@^7.7.2": + version "7.10.1" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.10.1.tgz#b6eb75cac279588d3100baecd1b9894ea2840822" + integrity sha512-nQbbCbQc9u/rpg1XCxoMYQTbSMVZjCDxErQ1ClCn9Pvcmv1lGads19ep0a2VsEiIJeHqjZley6EQGEC3Yo1xMA== + dependencies: + regenerator-runtime "^0.13.4" + "@babel/runtime@^7.8.4": version "7.9.6" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.9.6.tgz#a9102eb5cadedf3f31d08a9ecf294af7827ea29f" @@ -743,6 +750,325 @@ lodash "^4.17.13" to-fast-properties "^2.0.0" +"@jimp/bmp@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/bmp/-/bmp-0.9.8.tgz#5933ab8fb359889bec380b0f7802163374933624" + integrity sha512-CZYQPEC3iUBMuaGWrtIG+GKNl93q/PkdudrCKJR/B96dfNngsmoosEm3LuFgJHEcJIfvnJkNqKw74l+zEiqCbg== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.8" + bmp-js "^0.1.0" + core-js "^3.4.1" + +"@jimp/core@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/core/-/core-0.9.8.tgz#b2b74263a80559c0ee244e0f2d1052b36a358b85" + integrity sha512-N4GCjcXb0QwR5GBABDK2xQ3cKyaF7LlCYeJEG9mV7G/ynBoRqJe4JA6YKU9Ww9imGkci/4A594nQo8tUIqdcBw== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.8" + any-base "^1.1.0" + buffer "^5.2.0" + core-js "^3.4.1" + exif-parser "^0.1.12" + file-type "^9.0.0" + load-bmfont "^1.3.1" + mkdirp "^0.5.1" + phin "^2.9.1" + pixelmatch "^4.0.2" + tinycolor2 "^1.4.1" + +"@jimp/custom@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/custom/-/custom-0.9.8.tgz#1e9d904b1b05aa22b00b899baba2be7c0704a5d1" + integrity sha512-1UpJjI7fhX02BWLJ/KEqPwkHH60eNkCNeD6hEd+IZdTwLXfZCfFiM5BVlpgiZYZJSsVoRiAL4ne2Q5mCiKPKyw== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/core" "^0.9.8" + core-js "^3.4.1" + +"@jimp/gif@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/gif/-/gif-0.9.8.tgz#513aff511634c338d1ab33a7bba1ba3412220b5b" + integrity sha512-LEbfpcO1sBJIQCJHchZjNlyNxzPjZQQ4X32klpQHZJG58n9FvL7Uuh1rpkrJRbqv3cU3P0ENNtTrsBDxsYwcfA== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.8" + core-js "^3.4.1" + omggif "^1.0.9" + +"@jimp/jpeg@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/jpeg/-/jpeg-0.9.8.tgz#8c086f69d0e8c46e43a7db9725576edc30925cb1" + integrity sha512-5u29SUzbZ32ZMmOaz3gO0hXatwSCnsvEAXRCKZoPPgbsPoyFAiZKVxjfLzjkeQF6awkvJ8hZni5chM15SNMg+g== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.8" + core-js "^3.4.1" + jpeg-js "^0.3.4" + +"@jimp/plugin-blit@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-blit/-/plugin-blit-0.9.8.tgz#916bf6f261e6a91dbecca0ca866b8d9cba563753" + integrity sha512-6xTDomxJybhBcby1IUVaPydZFhxf+V0DRgfDlVK81kR9kSCoshJpzWqDuWrMqjNEPspPE7jRQwHMs0FdU7mVwQ== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.8" + core-js "^3.4.1" + +"@jimp/plugin-blur@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-blur/-/plugin-blur-0.9.8.tgz#00055d54b90532b7951dae377b3e40352c187f07" + integrity sha512-dqbxuNFBRbmt35iIRacdgma7nlXklmPThsKcGWNTDmqb/hniK5IC+0xSPzBV4qMI2fLGP39LWHqqDZ0xDz14dA== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.8" + core-js "^3.4.1" + +"@jimp/plugin-circle@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-circle/-/plugin-circle-0.9.8.tgz#5de8735f32f931d9160d0f5211e9aab6413a1d4b" + integrity sha512-+UStXUPCzPqzTixLC8eVqcFcEa6TS+BEM/6/hyM11TDb9sbiMGeUtgpwZP/euR5H5gfpAQDA1Ppzqhh5fuMDlw== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.8" + core-js "^3.4.1" + +"@jimp/plugin-color@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-color/-/plugin-color-0.9.8.tgz#3c633f22955a4f5013025e9e9e78a267ac4c3a88" + integrity sha512-SDHxOQsJHpt75hk6+sSlCPc2B3UJlXosFW+iLZ11xX1Qr0IdDtbfYlIoPmjKQFIDUNzqLSue/z7sKQ1OMZr/QA== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.8" + core-js "^3.4.1" + tinycolor2 "^1.4.1" + +"@jimp/plugin-contain@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-contain/-/plugin-contain-0.9.8.tgz#f892fb7fc87134a47b37281f0ff17d608f3e51af" + integrity sha512-oK52CPt7efozuLYCML7qOmpFeDt3zpU8qq8UZlnjsDs15reU6L8EiUbwYpJvzoEnEOh1ZqamB8F/gymViEO5og== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.8" + core-js "^3.4.1" + +"@jimp/plugin-cover@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-cover/-/plugin-cover-0.9.8.tgz#37474b19027ac0155100b71ca17266aab19e50fc" + integrity sha512-nnamtHzMrNd5j5HRSPd1VzpZ8v9YYtUJPtvCdHOOiIjqG72jxJ2kTBlsS3oG5XS64h/2MJwpl/fmmMs1Tj1CmQ== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.8" + core-js "^3.4.1" + +"@jimp/plugin-crop@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-crop/-/plugin-crop-0.9.8.tgz#2308696597a8bcb528d09eeebbbadb22248e7c1c" + integrity sha512-Nv/6AIp4aJmbSIH2uiIqm+kSoShKM8eaX2fyrUTj811kio0hwD3f/vIxrWebvAqwDZjAFIAmMufFoFCVg6caoQ== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.8" + core-js "^3.4.1" + +"@jimp/plugin-displace@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-displace/-/plugin-displace-0.9.8.tgz#00331047039cb2d0d9d5f7c3d8ce542e07eea791" + integrity sha512-0OgPjkOVa2xdbqI8P6gBKX/UK36RbaYVrFyXL8Jy9oNF69+LYWyTskuCu9YbGxzlCVjY/JFqQOvrKDbxgMYAKA== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.8" + core-js "^3.4.1" + +"@jimp/plugin-dither@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-dither/-/plugin-dither-0.9.8.tgz#9cca12997f2917f27d5681275b32affdb3083450" + integrity sha512-jGM/4ByniZJnmV2fv8hKwyyydXZe/YzvgBcnB8XxzCq8kVR3Imcn+qnd2PEPZzIPKOTH4Cig/zo9Vk9Bs+m5FQ== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.8" + core-js "^3.4.1" + +"@jimp/plugin-fisheye@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-fisheye/-/plugin-fisheye-0.9.8.tgz#e3f5f616ec06a9ef99aa268446f0096eac863437" + integrity sha512-VnsalrD05f4pxG1msjnkwIFi5QveOqRm4y7VkoZKNX+iqs4TvRnH5+HpBnfdMzX/RXBi+Lf/kpTtuZgbOu/QWw== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.8" + core-js "^3.4.1" + +"@jimp/plugin-flip@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-flip/-/plugin-flip-0.9.8.tgz#c00559a8543a684c7cff4d1128b7152e598fbb1c" + integrity sha512-XbiZ4OfHD6woc0f6Sk7XxB6a7IyMjTRQ4pNU7APjaNxsl3L6qZC8qfCQphWVe3DHx7f3y7jEiPMvNnqRDP1xgA== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.8" + core-js "^3.4.1" + +"@jimp/plugin-gaussian@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-gaussian/-/plugin-gaussian-0.9.8.tgz#d1666167ce1b947b65db5093bb9a00d319bcfe4d" + integrity sha512-ZBl5RA6+4XAD+mtqLfiG7u+qd8W5yqq3RBNca8eFqUSVo1v+eB2tzeLel0CWfVC/z6cw93Awm/nVnm6/CL2Oew== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.8" + core-js "^3.4.1" + +"@jimp/plugin-invert@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-invert/-/plugin-invert-0.9.8.tgz#41d6e87faf01a5d8fe7554e322d2aad25f596ab1" + integrity sha512-ESploqCoF6qUv5IWhVLaO5fEcrYZEsAWPFflh6ROiD2mmFKQxfeK+vHnk3IDLHtUwWTkAZQNbk89BVq7xvaNpQ== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.8" + core-js "^3.4.1" + +"@jimp/plugin-mask@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-mask/-/plugin-mask-0.9.8.tgz#fe92132db1a2b9f7718226bc3c37794dd148ce36" + integrity sha512-zSvEisTV4iGsBReitEdnQuGJq9/1xB5mPATadYZmIlp8r5HpD72HQb0WdEtb51/pu9Odt8KAxUf0ASg/PRVUiQ== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.8" + core-js "^3.4.1" + +"@jimp/plugin-normalize@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-normalize/-/plugin-normalize-0.9.8.tgz#05646aa15b6a789c4ba447edcad77c83c1d51f16" + integrity sha512-dPFBfwTa67K1tRw1leCidQT25R3ozrTUUOpO4jcGFHqXvBTWaR8sML1qxdfOBWs164mE5YpfdTvu6MM/junvCg== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.8" + core-js "^3.4.1" + +"@jimp/plugin-print@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-print/-/plugin-print-0.9.8.tgz#808f723176d0a57186d7558290c7e53a7a8bf812" + integrity sha512-nLLPv1/faehRsOjecXXUb6kzhRcZzImO55XuFZ0c90ZyoiHm4UFREwO5sKxHGvpLXS6RnkhvSav4+IWD2qGbEQ== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.8" + core-js "^3.4.1" + load-bmfont "^1.4.0" + +"@jimp/plugin-resize@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-resize/-/plugin-resize-0.9.8.tgz#eef750b77f1cc06e8bcf9b390860c95c489dcc02" + integrity sha512-L80NZ+HKsiKFyeDc6AfneC4+5XACrdL2vnyAVfAAsb3pmamgT/jDInWvvGhyI0Y76vx2w6XikplzEznW/QQvWg== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.8" + core-js "^3.4.1" + +"@jimp/plugin-rotate@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-rotate/-/plugin-rotate-0.9.8.tgz#5eba01f75a397777c6782b7999c9ac6c7ed8a411" + integrity sha512-bpqzQheISYnBXKyU1lIj46uR7mRs0UhgEREWK70HnvFJSlRshdcoNMIrKamyrJeFdJrkYPSfR/a6D0d5zsWf1Q== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.8" + core-js "^3.4.1" + +"@jimp/plugin-scale@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-scale/-/plugin-scale-0.9.8.tgz#c875d5e0b377b15b8b398ee402f45e3fc43fea40" + integrity sha512-QU3ZS4Lre8nN66U9dKCOC4FNfaOh/QJFYUmQPKpPS924oYbtnm4OlmsdfpK2hVMSVVyVOis8M+xpA1rDBnIp7w== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.8" + core-js "^3.4.1" + +"@jimp/plugin-shadow@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-shadow/-/plugin-shadow-0.9.8.tgz#ca2d18afa29a1027b77b3e1fb2ce7d4e073a7170" + integrity sha512-t/pE+QS3r1ZUxGIQNmwWDI3c5+/hLU+gxXD+C3EEC47/qk3gTBHpj/xDdGQBoObdT/HRjR048vC2BgBfzjj2hg== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.8" + core-js "^3.4.1" + +"@jimp/plugin-threshold@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/plugin-threshold/-/plugin-threshold-0.9.8.tgz#2d1dde0791f70b2ff2d0b915cab8d40b0e446594" + integrity sha512-WWmC3lnIwOTPvkKu55w4DUY8Ehlzf3nU98bY0QtIzkqxkAOZU5m+lvgC/JxO5FyGiA57j9FLMIf0LsWkjARj7g== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.8" + core-js "^3.4.1" + +"@jimp/plugins@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/plugins/-/plugins-0.9.8.tgz#5279dfe22d0d27633f4201ab36103e587b32eb85" + integrity sha512-tD+cxS9SuEZaQ1hhAkNKw9TkUAqfoBAhdWPBrEZDr/GvGPrvJR4pYmmpSYhc5IZmMbXfQayHTTGqjj8D18bToA== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/plugin-blit" "^0.9.8" + "@jimp/plugin-blur" "^0.9.8" + "@jimp/plugin-circle" "^0.9.8" + "@jimp/plugin-color" "^0.9.8" + "@jimp/plugin-contain" "^0.9.8" + "@jimp/plugin-cover" "^0.9.8" + "@jimp/plugin-crop" "^0.9.8" + "@jimp/plugin-displace" "^0.9.8" + "@jimp/plugin-dither" "^0.9.8" + "@jimp/plugin-fisheye" "^0.9.8" + "@jimp/plugin-flip" "^0.9.8" + "@jimp/plugin-gaussian" "^0.9.8" + "@jimp/plugin-invert" "^0.9.8" + "@jimp/plugin-mask" "^0.9.8" + "@jimp/plugin-normalize" "^0.9.8" + "@jimp/plugin-print" "^0.9.8" + "@jimp/plugin-resize" "^0.9.8" + "@jimp/plugin-rotate" "^0.9.8" + "@jimp/plugin-scale" "^0.9.8" + "@jimp/plugin-shadow" "^0.9.8" + "@jimp/plugin-threshold" "^0.9.8" + core-js "^3.4.1" + timm "^1.6.1" + +"@jimp/png@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/png/-/png-0.9.8.tgz#f88dacc9b9da1c2ea8e91026a9530d0fb45c4409" + integrity sha512-9CqR8d40zQCDhbnXHqcwkAMnvlV0vk9xSyE6LHjkYHS7x18Unsz5txQdsaEkEcXxCrOQSoWyITfLezlrWXRJAA== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/utils" "^0.9.8" + core-js "^3.4.1" + pngjs "^3.3.3" + +"@jimp/tiff@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/tiff/-/tiff-0.9.8.tgz#91dc3eab2f222e23414f139e917f3407caa73560" + integrity sha512-eMxcpJivJqMByn2dZxUHLeh6qvVs5J/52kBF3TFa3C922OJ97D9l1C1h0WKUCBqFMWzMYapQQ4vwnLgpJ5tkow== + dependencies: + "@babel/runtime" "^7.7.2" + core-js "^3.4.1" + utif "^2.0.1" + +"@jimp/types@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/types/-/types-0.9.8.tgz#46980a4a7bfcadf2f0484d187c32b4e7d6d61b8e" + integrity sha512-H5y/uqt0lqJ/ZN8pWqFG+pv8jPAppMKkTMByuC8YBIjWSsornwv44hjiWl93sbYhduLZY8ubz/CbX9jH2X6EwA== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/bmp" "^0.9.8" + "@jimp/gif" "^0.9.8" + "@jimp/jpeg" "^0.9.8" + "@jimp/png" "^0.9.8" + "@jimp/tiff" "^0.9.8" + core-js "^3.4.1" + timm "^1.6.1" + +"@jimp/utils@^0.9.8": + version "0.9.8" + resolved "https://registry.yarnpkg.com/@jimp/utils/-/utils-0.9.8.tgz#6a6f47158ec6b424f03df0f55f0baff5b4b5e096" + integrity sha512-UK0Fu0eevQlpRXq5ff4o/71HJlpX9wJMddJjMYg9vUqCCl8ZnumRAljfShHFhGyO+Vc9IzN6dd8Y5JZZTp1KOw== + dependencies: + "@babel/runtime" "^7.7.2" + core-js "^3.4.1" + "@types/anymatch@*": version "1.3.1" resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" @@ -758,6 +1084,13 @@ resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== +"@types/favicons@5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@types/favicons/-/favicons-5.5.0.tgz#c1cb3d2a14955eedf479f3cc51948630c56e3a64" + integrity sha512-s76OlRaBfqtGu2ZBobnZv2NETfqsQUVfKKlOkKNGo4ArBsqiblodKsnQ3j29hCCgmpQacEfLxealV96za+tzVQ== + dependencies: + "@types/node" "*" + "@types/glob@^7.1.1": version "7.1.1" resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575" @@ -772,6 +1105,11 @@ resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-5.1.0.tgz#551a4589b6ee2cc9c1dff08056128aec29b94880" integrity sha512-iYCgjm1dGPRuo12+BStjd1HiVQqhlRhWDOQigNxn023HcjnhsiFz9pc6CzJj4HwDCSQca9bxTL4PxJDbkdm3PA== +"@types/json-schema@^7.0.4": + version "7.0.4" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339" + integrity sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA== + "@types/minimatch@*": version "3.0.3" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" @@ -1016,7 +1354,7 @@ ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da" integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ== -ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.0: +ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.0, ajv@^6.12.2, ajv@^6.5.5: version "6.12.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.2.tgz#c629c5eced17baf314437918d2da88c99d5958cd" integrity sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ== @@ -1048,6 +1386,11 @@ ansi-regex@^2.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + ansi-regex@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" @@ -1073,6 +1416,11 @@ ansi-styles@^4.1.0: "@types/color-name" "^1.1.1" color-convert "^2.0.1" +any-base@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/any-base/-/any-base-1.1.0.tgz#ae101a62bc08a597b4c9ab5b7089d456630549fe" + integrity sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg== + anymatch@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" @@ -1081,11 +1429,19 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" -aproba@^1.1.1: +aproba@^1.0.3, aproba@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -1135,6 +1491,11 @@ array-unique@^0.3.2: resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= +arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= + asn1.js@^4.0.0: version "4.10.1" resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" @@ -1144,6 +1505,18 @@ asn1.js@^4.0.0: inherits "^2.0.1" minimalistic-assert "^1.0.0" +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + assert@^1.1.1: version "1.5.0" resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" @@ -1179,11 +1552,31 @@ async@^2.6.2: dependencies: lodash "^4.17.14" +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + atob@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== +author-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/author-regex/-/author-regex-1.0.0.tgz#d08885be6b9bbf9439fe087c76287245f0a81450" + integrity sha1-0IiFvmubv5Q5/gh8dihyRfCoFFA= + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.8.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.10.0.tgz#a17b3a8ea811060e74d47d306122400ad4497ae2" + integrity sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA== + babel-loader@^8.0.6: version "8.1.0" resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.1.0.tgz#c611d5112bd5209abe8b9fa84c3e4da25275f1c3" @@ -1238,11 +1631,23 @@ batch@0.6.1: resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" integrity sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY= +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + dependencies: + tweetnacl "^0.14.3" + big.js@^5.2.2: version "5.2.2" resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== +bignumber.js@^2.1.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-2.4.0.tgz#838a992da9f9d737e0f4b2db0be62bb09dd0c5e8" + integrity sha1-g4qZLan51zfg9LLbC+YrsJ3Qxeg= + binary-extensions@^1.0.0: version "1.13.1" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" @@ -1255,11 +1660,35 @@ bindings@^1.5.0: dependencies: file-uri-to-path "1.0.0" +bl@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/bl/-/bl-4.0.2.tgz#52b71e9088515d0606d9dd9cc7aa48dc1f98e73a" + integrity sha512-j4OH8f6Qg2bGuWfRiltT2HYGx0e1QcBTrK9KAHNMwMZdQnDZFk0ZSYIpADjYCB3U12nicC5tVJwSIhwOWjb4RQ== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" + bluebird@^3.5.5: version "3.7.2" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== +bmp-js@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/bmp-js/-/bmp-js-0.0.1.tgz#5ad0147099d13a9f38aa7b99af1d6e78666ed37f" + integrity sha1-WtAUcJnROp84qnuZrx1ueGZu038= + +bmp-js@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/bmp-js/-/bmp-js-0.0.3.tgz#64113e9c7cf1202b376ed607bf30626ebe57b18a" + integrity sha1-ZBE+nHzxICs3btYHvzBibr5XsYo= + +bmp-js@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/bmp-js/-/bmp-js-0.1.0.tgz#e05a63f796a6c1ff25f4771ec7adadc148c07233" + integrity sha1-4Fpj95amwf8l9Hcex62twUjAcjM= + bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.4.0: version "4.11.8" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" @@ -1402,6 +1831,29 @@ browserslist@^4.11.1, browserslist@^4.8.5: node-releases "^1.1.53" pkg-up "^2.0.0" +buffer-alloc-unsafe@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" + integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== + +buffer-alloc@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" + integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== + dependencies: + buffer-alloc-unsafe "^1.1.0" + buffer-fill "^1.0.0" + +buffer-equal@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-0.0.1.tgz#91bc74b11ea405bc916bc6aa908faafa5b4aac4b" + integrity sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs= + +buffer-fill@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" + integrity sha1-+PeLdniYiO858gXNY39o5wISKyw= + buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" @@ -1412,6 +1864,11 @@ buffer-indexof@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g== +buffer-json@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/buffer-json/-/buffer-json-2.0.0.tgz#f73e13b1e42f196fe2fd67d001c7d7107edd7c23" + integrity sha512-+jjPFVqyfF1esi9fvfUs3NqM0pH1ziZ36VP4hmA/y/Ssfo/5w5xHKfTw9BwQjoJ1w/oVtpLomqwUHKdefGyuHw== + buffer-xor@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" @@ -1426,6 +1883,14 @@ buffer@^4.3.0: ieee754 "^1.1.4" isarray "^1.0.0" +buffer@^5.2.0, buffer@^5.5.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.6.0.tgz#a31749dc7d81d84db08abf937b6b8c4033f62786" + integrity sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + builtin-status-codes@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" @@ -1501,6 +1966,18 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" +cache-loader@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cache-loader/-/cache-loader-4.1.0.tgz#9948cae353aec0a1fcb1eafda2300816ec85387e" + integrity sha512-ftOayxve0PwKzBF/GLsZNC9fJBXl8lkZE3TOsjkboHfVHVkL39iUEs1FO07A33mizmci5Dudt38UZrrYXDtbhw== + dependencies: + buffer-json "^2.0.0" + find-cache-dir "^3.0.0" + loader-utils "^1.2.3" + mkdirp "^0.5.1" + neo-async "^2.6.1" + schema-utils "^2.0.0" + callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -1524,6 +2001,11 @@ caniuse-lite@^1.0.30001043: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001054.tgz#7e82fc42d927980b0ce1426c4813df12381e1a75" integrity sha512-jiKlTI6Ur8Kjfj8z0muGrV6FscpRvefcQVPSuMuXnvRCfExU7zlVLNjmOz1TnurWgUrAY7MMmjyy+uTgIl1XHw== +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + chalk@2.4.2, chalk@^2.0.0, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -1573,7 +2055,7 @@ chokidar@^2.1.8: optionalDependencies: fsevents "^1.2.7" -chownr@^1.1.1, chownr@^1.1.2: +chownr@^1.1.1, chownr@^1.1.2, chownr@^1.1.3: version "1.1.4" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== @@ -1644,6 +2126,35 @@ cliui@^5.0.0: strip-ansi "^5.2.0" wrap-ansi "^5.1.0" +clone-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" + integrity sha1-4+JbIHrE5wGvch4staFnksrD3Fg= + +clone-stats@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" + integrity sha1-s3gt/4u1R04Yuba/D9/ngvh3doA= + +clone@^2.1.1, clone@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18= + +cloneable-readable@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.1.3.tgz#120a00cb053bfb63a222e709f9683ea2e11d8cec" + integrity sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ== + dependencies: + inherits "^2.0.1" + process-nextick-args "^2.0.0" + readable-stream "^2.3.5" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + collection-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" @@ -1652,7 +2163,7 @@ collection-visit@^1.0.0: map-visit "^1.0.0" object-visit "^1.0.0" -color-convert@^1.9.0: +color-convert@^1.9.0, color-convert@^1.9.1: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== @@ -1671,11 +2182,39 @@ color-name@1.1.3: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= -color-name@~1.1.4: +color-name@^1.0.0, color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +color-string@^1.5.2: + version "1.5.3" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc" + integrity sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw== + dependencies: + color-name "^1.0.0" + simple-swizzle "^0.2.2" + +color@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/color/-/color-3.1.2.tgz#68148e7f85d41ad7649c5fa8c8106f098d229e10" + integrity sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg== + dependencies: + color-convert "^1.9.1" + color-string "^1.5.2" + +colors@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== + +combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -1753,6 +2292,11 @@ console-browserify@^1.1.0: resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + constants-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" @@ -1812,7 +2356,12 @@ core-js-compat@^3.6.2: browserslist "^4.8.5" semver "7.0.0" -core-util-is@~1.0.0: +core-js@^3.4.1, core-js@^3.4.5: + version "3.6.5" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.5.tgz#7395dc273af37fb2e50e9bd3d9fe841285231d1a" + integrity sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA== + +core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= @@ -1929,6 +2478,13 @@ cyclist@^1.0.1: resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + debug@2.6.9, debug@^2.2.0, debug@^2.3.3: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -1960,6 +2516,13 @@ decode-uri-component@^0.2.0: resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= +decompress-response@^4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-4.2.1.tgz#414023cc7a302da25ce2ec82d0d5238ccafd8986" + integrity sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw== + dependencies: + mimic-response "^2.0.0" + deep-equal@^1.0.1: version "1.1.1" resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" @@ -1972,6 +2535,11 @@ deep-equal@^1.0.1: object-keys "^1.1.1" regexp.prototype.flags "^1.2.0" +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + deep-is@^0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" @@ -2027,6 +2595,16 @@ del@^4.1.1: pify "^4.0.1" rimraf "^2.6.3" +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" @@ -2050,6 +2628,11 @@ detect-file@^1.0.0: resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" integrity sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc= +detect-libc@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= + detect-node@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" @@ -2106,6 +2689,11 @@ dom-serializer@0, dom-serializer@^0.2.1: domelementtype "^2.0.1" entities "^2.0.0" +dom-walk@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84" + integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w== + domain-browser@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" @@ -2178,6 +2766,14 @@ duplexify@^3.4.2, duplexify@^3.6.0: readable-stream "^2.0.0" stream-shift "^1.0.0" +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -2226,7 +2822,7 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= -end-of-stream@^1.0.0, end-of-stream@^1.1.0: +end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== @@ -2294,6 +2890,11 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" +es6-promise@^3.0.2: + version "3.3.1" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.3.1.tgz#a08cdde84ccdbf34d027a1451bc91d4bcd28a613" + integrity sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM= + escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -2465,6 +3066,11 @@ execa@^1.0.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +exif-parser@^0.1.12, exif-parser@^0.1.9: + version "0.1.12" + resolved "https://registry.yarnpkg.com/exif-parser/-/exif-parser-0.1.12.tgz#58a9d2d72c02c1f6f02a0ef4a9166272b7760922" + integrity sha1-WKnS1ywCwfbwKg70qRZicrd2CSI= + expand-brackets@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" @@ -2478,6 +3084,11 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" +expand-template@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" + integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== + expand-tilde@^2.0.0, expand-tilde@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" @@ -2536,6 +3147,11 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: assign-symbols "^1.0.0" is-extendable "^1.0.1" +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + external-editor@^3.0.3: version "3.1.0" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" @@ -2559,6 +3175,16 @@ extglob@^2.0.4: snapdragon "^0.8.1" to-regex "^3.0.1" +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + fast-deep-equal@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" @@ -2574,6 +3200,44 @@ fast-levenshtein@^2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= +favicons-webpack-plugin@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/favicons-webpack-plugin/-/favicons-webpack-plugin-3.0.1.tgz#49220046add28ba24351960ee48c60a454fdb49e" + integrity sha512-u5wIPl++qjoU+sOmCOurh8Wfmojh/7FmIQbIkteh5aYiCkJLSj/SyQps7WvVKAgJ3njKCOuxKiqIDFZnvhbEYQ== + dependencies: + "@types/favicons" "5.5.0" + cache-loader "^4.1.0" + camelcase "^5.3.1" + favicons "5.5.0" + find-cache-dir "^3.2.0" + find-root "^1.1.0" + loader-utils "^1.2.3" + parse-author "^2.0.0" + parse5 "^5.1.0" + tapable "^1.1.3" + optionalDependencies: + html-webpack-plugin ">=4.0.0 || ^4.0.0-beta.11" + +favicons@5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/favicons/-/favicons-5.5.0.tgz#4badbecac81ddf2793b8149d0823d97c2077445b" + integrity sha512-xZ4B+fZDuq2y999iorrYq4KuBT3OIZHU+CVfjOWQbjOC1OiU0xbf6pp4Ju/yAfJn7W74RVrC3Cv0oqR5CLvviw== + dependencies: + clone "^2.1.2" + colors "^1.4.0" + core-js "^3.4.5" + image-size "^0.8.3" + jimp "^0.9.3" + jsontoxml "^1.0.1" + lodash.defaultsdeep "^4.6.1" + require-directory "^2.1.1" + sharp "^0.23.3" + through2 "^3.0.1" + tinycolor2 "^1.4.1" + to-ico "^1.1.5" + vinyl "^2.2.0" + xml2js "^0.4.22" + faye-websocket@^0.10.0: version "0.10.0" resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" @@ -2615,6 +3279,16 @@ file-loader@^6.0.0: loader-utils "^2.0.0" schema-utils "^2.6.5" +file-type@^3.1.0, file-type@^3.8.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9" + integrity sha1-JXoHg4TR24CHvESdEH1SpSZyuek= + +file-type@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-9.0.0.tgz#a68d5ad07f486414dfb2c8866f73161946714a18" + integrity sha512-Qe/5NJrgIOlwijpq3B7BEpzPFcgzggOTagZmkXQY4LA6bsXKTUstK7Wp12lEJ/mLKTpvIZxmIuRcLYWT6ov9lw== + file-uri-to-path@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" @@ -2652,7 +3326,7 @@ find-cache-dir@^2.1.0: make-dir "^2.0.0" pkg-dir "^3.0.0" -find-cache-dir@^3.0.0: +find-cache-dir@^3.0.0, find-cache-dir@^3.2.0: version "3.3.1" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880" integrity sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ== @@ -2661,6 +3335,11 @@ find-cache-dir@^3.0.0: make-dir "^3.0.2" pkg-dir "^4.1.0" +find-root@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" + integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== + find-up@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" @@ -2727,6 +3406,20 @@ for-in@^1.0.2: resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + forwarded@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" @@ -2752,6 +3445,11 @@ from2@^2.1.0: inherits "^2.0.1" readable-stream "^2.0.0" +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + fs-minipass@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" @@ -2792,6 +3490,20 @@ functional-red-black-tree@^1.0.1: resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + gensync@^1.0.0-beta.1: version "1.0.0-beta.1" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" @@ -2802,6 +3514,14 @@ get-caller-file@^2.0.1: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== +get-stream@^2.0.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de" + integrity sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4= + dependencies: + object-assign "^4.0.1" + pinkie-promise "^2.0.0" + get-stream@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" @@ -2814,6 +3534,18 @@ get-value@^2.0.3, get-value@^2.0.6: resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + +github-from-package@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" + integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4= + glob-parent@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" @@ -2877,6 +3609,14 @@ global-prefix@^3.0.0: kind-of "^6.0.2" which "^1.3.1" +global@~4.3.0: + version "4.3.2" + resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f" + integrity sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8= + dependencies: + min-document "^2.19.0" + process "~0.5.1" + globals@^11.1.0: version "11.12.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" @@ -2910,6 +3650,19 @@ handle-thing@^2.0.0: resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" + integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== + dependencies: + ajv "^6.5.5" + har-schema "^2.0.0" + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -2925,6 +3678,11 @@ has-symbols@^1.0.0, has-symbols@^1.0.1: resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + has-value@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" @@ -3040,7 +3798,7 @@ html-minifier-terser@^5.0.1, html-minifier-terser@^5.0.5: relateurl "^0.2.7" terser "^4.6.3" -html-webpack-plugin@^4.3.0: +"html-webpack-plugin@>=4.0.0 || ^4.0.0-beta.11", html-webpack-plugin@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-4.3.0.tgz#53bf8f6d696c4637d5b656d3d9863d89ce8174fd" integrity sha512-C0fzKN8yQoVLTelcJxZfJCE+aAvQiY2VUf3UuKrR4a9k5UMWYOtpDLsaXwATbcVCnI05hUS7L9ULQHWLZhyi3w== @@ -3138,6 +3896,15 @@ http-proxy@^1.17.0: follow-redirects "^1.0.0" requires-port "^1.0.0" +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + https-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" @@ -3172,6 +3939,18 @@ ignore@^4.0.6: resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== +image-size@^0.5.0: + version "0.5.5" + resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.5.5.tgz#09dfd4ab9d20e29eb1c3e80b8990378df9e3cb9c" + integrity sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w= + +image-size@^0.8.3: + version "0.8.3" + resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.8.3.tgz#f0b568857e034f29baffd37013587f2c0cad8b46" + integrity sha512-SMtq1AJ+aqHB45c3FsB4ERK0UCiA2d3H1uq8s+8T0Pf8A3W4teyBQyaFaktH6xvZqh+npwlKU7i4fJo0r7TYTg== + dependencies: + queue "6.0.1" + import-fresh@^3.0.0: version "3.2.1" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" @@ -3231,7 +4010,7 @@ inherits@2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= -ini@^1.3.4, ini@^1.3.5: +ini@^1.3.4, ini@^1.3.5, ini@~1.3.0: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== @@ -3280,6 +4059,11 @@ invert-kv@^2.0.0: resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== +ip-regex@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-1.0.3.tgz#dc589076f659f419c222039a33316f1c7387effd" + integrity sha1-3FiQdvZZ9BnCIgOaMzFvHHOH7/0= + ip-regex@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" @@ -3319,6 +4103,11 @@ is-arguments@^1.0.4: resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA== +is-arrayish@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" + integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== + is-binary-path@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" @@ -3395,6 +4184,13 @@ is-extglob@^2.1.0, is-extglob@^2.1.1: resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" @@ -3405,6 +4201,11 @@ is-fullwidth-code-point@^3.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== +is-function@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.2.tgz#4f097f30abf6efadac9833b17ca5dc03f8144e08" + integrity sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ== + is-glob@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" @@ -3485,6 +4286,11 @@ is-symbol@^1.0.2: dependencies: has-symbols "^1.0.1" +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + is-valid-path@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-valid-path/-/is-valid-path-0.1.1.tgz#110f9ff74c37f663e1ec7915eb451f2db93ac9df" @@ -3524,6 +4330,60 @@ isobject@^3.0.0, isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + +jimp@^0.2.21: + version "0.2.28" + resolved "https://registry.yarnpkg.com/jimp/-/jimp-0.2.28.tgz#dd529a937190f42957a7937d1acc3a7762996ea2" + integrity sha1-3VKak3GQ9ClXp5N9Gsw6d2KZbqI= + dependencies: + bignumber.js "^2.1.0" + bmp-js "0.0.3" + es6-promise "^3.0.2" + exif-parser "^0.1.9" + file-type "^3.1.0" + jpeg-js "^0.2.0" + load-bmfont "^1.2.3" + mime "^1.3.4" + mkdirp "0.5.1" + pixelmatch "^4.0.0" + pngjs "^3.0.0" + read-chunk "^1.0.1" + request "^2.65.0" + stream-to-buffer "^0.1.0" + tinycolor2 "^1.1.2" + url-regex "^3.0.0" + +jimp@^0.9.3: + version "0.9.8" + resolved "https://registry.yarnpkg.com/jimp/-/jimp-0.9.8.tgz#2ee87b81b42e723ad74c73b8012f879c0abe5b04" + integrity sha512-DHN4apKMwLIvD/TKO9tFfPuankNuVK98vCwHm/Jv9z5cJnrd38xhi+4I7IAGmDU3jIDlrEVhzTkFH1Ymv5yTQQ== + dependencies: + "@babel/runtime" "^7.7.2" + "@jimp/custom" "^0.9.8" + "@jimp/plugins" "^0.9.8" + "@jimp/types" "^0.9.8" + core-js "^3.4.1" + regenerator-runtime "^0.13.3" + +jpeg-js@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.1.2.tgz#135b992c0575c985cfa0f494a3227ed238583ece" + integrity sha1-E1uZLAV1yYXPoPSUoyJ+0jhYPs4= + +jpeg-js@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.2.0.tgz#53e448ec9d263e683266467e9442d2c5a2ef5482" + integrity sha1-U+RI7J0mPmgyZkZ+lELSxaLvVII= + +jpeg-js@^0.3.4: + version "0.3.7" + resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.3.7.tgz#471a89d06011640592d314158608690172b1028d" + integrity sha512-9IXdWudL61npZjvLuVe/ktHiA41iE8qFyLB+4VDTblEsWBzeg8WQTlktdUK4CdncUqtUgUg0bbOmTE2bKBKaBQ== + jquery-ui@^1.12.1: version "1.12.1" resolved "https://registry.yarnpkg.com/jquery-ui/-/jquery-ui-1.12.1.tgz#bcb4045c8dd0539c134bc1488cdd3e768a7a9e51" @@ -3547,6 +4407,11 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + jsesc@^2.5.1: version "2.5.2" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" @@ -3567,11 +4432,21 @@ json-schema-traverse@^0.4.1: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + json3@^3.3.2: version "3.3.3" resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81" @@ -3591,6 +4466,21 @@ json5@^2.1.2: dependencies: minimist "^1.2.5" +jsontoxml@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/jsontoxml/-/jsontoxml-1.0.1.tgz#07fff7f6bfbfa1097d779aec7f041b5046075e70" + integrity sha512-dtKGq0K8EWQBRqcAaePSgKR4Hyjfsz/LkurHSV3Cxk4H+h2fWDeaN2jzABz+ZmOJylgXS7FGeWmbZ6jgYUMdJQ== + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + killable@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892" @@ -3647,6 +4537,20 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" +load-bmfont@^1.2.3, load-bmfont@^1.3.1, load-bmfont@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/load-bmfont/-/load-bmfont-1.4.0.tgz#75f17070b14a8c785fe7f5bee2e6fd4f98093b6b" + integrity sha512-kT63aTAlNhZARowaNYcY29Fn/QYkc52M3l6V1ifRcPewg2lvUZDAj7R6dXjOL9D0sict76op3T5+odumDSF81g== + dependencies: + buffer-equal "0.0.1" + mime "^1.3.4" + parse-bmfont-ascii "^1.0.3" + parse-bmfont-binary "^1.0.5" + parse-bmfont-xml "^1.1.4" + phin "^2.9.1" + xhr "^2.0.1" + xtend "^4.0.0" + loader-runner@^2.4.0: version "2.4.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" @@ -3702,6 +4606,11 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" +lodash.defaultsdeep@^4.6.1: + version "4.6.1" + resolved "https://registry.yarnpkg.com/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz#512e9bd721d272d94e3d3a63653fa17516741ca6" + integrity sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA== + lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" @@ -3848,14 +4757,14 @@ mime-db@1.44.0, "mime-db@>= 1.43.0 < 2": resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== -mime-types@~2.1.17, mime-types@~2.1.24: +mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24: version "2.1.27" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== dependencies: mime-db "1.44.0" -mime@1.6.0: +mime@1.6.0, mime@^1.3.4: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== @@ -3870,6 +4779,18 @@ mimic-fn@^2.0.0, mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +mimic-response@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.1.0.tgz#d13763d35f613d09ec37ebb30bac0469c0ee8f43" + integrity sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA== + +min-document@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" + integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU= + dependencies: + dom-walk "^0.1.0" + minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" @@ -3887,7 +4808,12 @@ minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" -minimist@^1.2.0, minimist@^1.2.5: +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= + +minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== @@ -3920,6 +4846,14 @@ minipass@^3.0.0, minipass@^3.1.1: dependencies: yallist "^4.0.0" +minizlib@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.0.tgz#fd52c645301ef09a63a2c209697c294c6ce02cf3" + integrity sha512-EzTZN/fjSvifSX0SlqUERCN39o6T40AMarPbv0MrarSFtIITCBh7bi+dU8nxGFHuqs9jdIAeoYoKuQAAASsPPA== + dependencies: + minipass "^3.0.0" + yallist "^4.0.0" + mississippi@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" @@ -3944,7 +4878,19 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -mkdirp@^0.5.1, mkdirp@^0.5.3: +mkdirp-classic@^0.5.2: + version "0.5.3" + resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" + integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== + +mkdirp@0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= + dependencies: + minimist "0.0.8" + +mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== @@ -4008,7 +4954,7 @@ mute-stream@0.0.8: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== -nan@^2.12.1: +nan@^2.12.1, nan@^2.14.0: version "2.14.1" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw== @@ -4030,6 +4976,11 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" +napi-build-utils@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" + integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -4058,6 +5009,13 @@ no-case@^3.0.3: lower-case "^2.0.1" tslib "^1.10.0" +node-abi@^2.7.0: + version "2.18.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.18.0.tgz#1f5486cfd7d38bd4f5392fa44a4ad4d9a0dffbf4" + integrity sha512-yi05ZoiuNNEbyT/xXfSySZE+yVnQW6fxPZuFbLyS1s6b5Kw3HzV2PHOM4XR+nsjzkHxByK+2Wg+yCQbe35l8dw== + dependencies: + semver "^5.4.1" + node-forge@0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.9.0.tgz#d624050edbb44874adca12bb9a52ec63cb782579" @@ -4097,6 +5055,11 @@ node-releases@^1.1.53: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.55.tgz#8af23b7c561d8e2e6e36a46637bab84633b07cee" integrity sha512-H3R3YR/8TjT5WPin/wOoHOUPHgvj8leuU/Keta/rwelEQN9pA/S2Dx8/se4pZ2LBxSd0nAGzsNzhqwa77v7F1w== +noop-logger@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/noop-logger/-/noop-logger-0.1.1.tgz#94a2b1633c4f1317553007d8966fd0e841b6a4c2" + integrity sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI= + normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" @@ -4116,6 +5079,16 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" +npmlog@^4.0.1, npmlog@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + nth-check@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" @@ -4123,7 +5096,17 @@ nth-check@~1.0.1: dependencies: boolbase "~1.0.0" -object-assign@^4.0.1, object-assign@^4.1.1: +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= @@ -4192,6 +5175,11 @@ obuf@^1.0.0, obuf@^1.1.2: resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== +omggif@^1.0.9: + version "1.0.10" + resolved "https://registry.yarnpkg.com/omggif/-/omggif-1.0.10.tgz#ddaaf90d4a42f532e9e7cb3a95ecdd47f17c7b19" + integrity sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw== + on-finished@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" @@ -4342,7 +5330,7 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== -pako@~1.0.5: +pako@^1.0.5, pako@~1.0.5: version "1.0.11" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== @@ -4383,16 +5371,58 @@ parse-asn1@^5.0.0, parse-asn1@^5.1.5: pbkdf2 "^3.0.3" safe-buffer "^5.1.1" +parse-author@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/parse-author/-/parse-author-2.0.0.tgz#d3460bf1ddd0dfaeed42da754242e65fb684a81f" + integrity sha1-00YL8d3Q367tQtp1QkLmX7aEqB8= + dependencies: + author-regex "^1.0.0" + +parse-bmfont-ascii@^1.0.3: + version "1.0.6" + resolved "https://registry.yarnpkg.com/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz#11ac3c3ff58f7c2020ab22769079108d4dfa0285" + integrity sha1-Eaw8P/WPfCAgqyJ2kHkQjU36AoU= + +parse-bmfont-binary@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz#d038b476d3e9dd9db1e11a0b0e53a22792b69006" + integrity sha1-0Di0dtPp3Z2x4RoLDlOiJ5K2kAY= + +parse-bmfont-xml@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/parse-bmfont-xml/-/parse-bmfont-xml-1.1.4.tgz#015319797e3e12f9e739c4d513872cd2fa35f389" + integrity sha512-bjnliEOmGv3y1aMEfREMBJ9tfL3WR0i0CKPj61DnSLaoxWR3nLrsQrEbCId/8rF4NyRF0cCqisSVXyQYWM+mCQ== + dependencies: + xml-parse-from-string "^1.0.0" + xml2js "^0.4.5" + +parse-headers@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.3.tgz#5e8e7512383d140ba02f0c7aa9f49b4399c92515" + integrity sha512-QhhZ+DCCit2Coi2vmAKbq5RGTRcQUOE2+REgv8vdyu7MnYx2eZztegqtTx99TZ86GTIwqiy3+4nQTWZ2tgmdCA== + parse-passwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= +parse-png@^1.0.0, parse-png@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/parse-png/-/parse-png-1.1.2.tgz#f5c2ad7c7993490986020a284c19aee459711ff2" + integrity sha1-9cKtfHmTSQmGAgooTBmu5FlxH/I= + dependencies: + pngjs "^3.2.0" + parse-srcset@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/parse-srcset/-/parse-srcset-1.0.2.tgz#f2bd221f6cc970a938d88556abc589caaaa2bde1" integrity sha1-8r0iH2zJcKk42IVWq8WJyqqiveE= +parse5@^5.1.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178" + integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug== + parseurl@~1.3.2, parseurl@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" @@ -4472,6 +5502,16 @@ pbkdf2@^3.0.3: safe-buffer "^5.0.1" sha.js "^2.4.8" +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +phin@^2.9.1: + version "2.9.3" + resolved "https://registry.yarnpkg.com/phin/-/phin-2.9.3.tgz#f9b6ac10a035636fb65dfc576aaaa17b8743125c" + integrity sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA== + pify@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" @@ -4494,6 +5534,13 @@ pinkie@^2.0.0: resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= +pixelmatch@^4.0.0, pixelmatch@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/pixelmatch/-/pixelmatch-4.0.2.tgz#8f47dcec5011b477b67db03c243bc1f3085e8854" + integrity sha1-j0fc7FARtHe2fbA8JDvB8wheiFQ= + dependencies: + pngjs "^3.0.0" + pkg-dir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" @@ -4515,6 +5562,11 @@ pkg-up@^2.0.0: dependencies: find-up "^2.1.0" +pngjs@^3.0.0, pngjs@^3.2.0, pngjs@^3.3.3: + version "3.4.0" + resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f" + integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w== + portfinder@^1.0.26: version "1.0.26" resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.26.tgz#475658d56ca30bed72ac7f1378ed350bd1b64e70" @@ -4585,6 +5637,27 @@ postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.27, postcss@^7.0.5, postcss@^7.0. source-map "^0.6.1" supports-color "^6.1.0" +prebuild-install@^5.3.3: + version "5.3.4" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-5.3.4.tgz#6982d10084269d364c1856550b7d090ea31fa293" + integrity sha512-AkKN+pf4fSEihjapLEEj8n85YIw/tN6BQqkhzbDc0RvEZGdkpJBGMUYx66AAMcPG2KzmPQS7Cm16an4HVBRRMA== + dependencies: + detect-libc "^1.0.3" + expand-template "^2.0.3" + github-from-package "0.0.0" + minimist "^1.2.3" + mkdirp "^0.5.1" + napi-build-utils "^1.0.1" + node-abi "^2.7.0" + noop-logger "^0.1.1" + npmlog "^4.0.1" + pump "^3.0.0" + rc "^1.2.7" + simple-get "^3.0.3" + tar-fs "^2.0.0" + tunnel-agent "^0.6.0" + which-pm-runs "^1.0.0" + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" @@ -4608,7 +5681,7 @@ private@^0.1.8: resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== -process-nextick-args@~2.0.0: +process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== @@ -4618,6 +5691,11 @@ process@^0.11.10: resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= +process@~0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf" + integrity sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8= + progress@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" @@ -4641,6 +5719,11 @@ prr@~1.0.1: resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= +psl@^1.1.28: + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + public-encrypt@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" @@ -4688,7 +5771,7 @@ punycode@^1.2.4: resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= -punycode@^2.1.0: +punycode@^2.1.0, punycode@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== @@ -4698,6 +5781,11 @@ qs@6.7.0: resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== +qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + querystring-es3@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" @@ -4713,6 +5801,13 @@ querystringify@^2.1.1: resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.1.tgz#60e5a5fd64a7f8bfa4d2ab2ed6fdf4c85bad154e" integrity sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA== +queue@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/queue/-/queue-6.0.1.tgz#abd5a5b0376912f070a25729e0b6a7d565683791" + integrity sha512-AJBQabRCCNr9ANq8v77RJEv73DPbn55cdTb+Giq4X0AVnNVZvMHlYp7XlQiN+1npCZj1DuSmaA2hYVUUDgxFDg== + dependencies: + inherits "~2.0.3" + randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" @@ -4743,7 +5838,22 @@ raw-body@2.4.0: iconv-lite "0.4.24" unpipe "1.0.0" -"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +read-chunk@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-chunk/-/read-chunk-1.0.1.tgz#5f68cab307e663f19993527d9b589cace4661194" + integrity sha1-X2jKswfmY/GZk1J9m1icrORmEZQ= + +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -4756,7 +5866,7 @@ raw-body@2.4.0: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.6.0: +"readable-stream@2 || 3", readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== @@ -4786,7 +5896,7 @@ regenerate@^1.4.0: resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg== -regenerator-runtime@^0.13.4: +regenerator-runtime@^0.13.3, regenerator-runtime@^0.13.4: version "0.13.5" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz#d878a1d094b4306d10b9096484b33ebd55e26697" integrity sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA== @@ -4875,6 +5985,37 @@ repeat-string@^1.6.1: resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= +replace-ext@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.1.tgz#2d6d996d04a15855d967443631dd5f77825b016a" + integrity sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw== + +request@^2.65.0: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -4890,6 +6031,18 @@ requires-port@^1.0.0: resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= +resize-img@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/resize-img/-/resize-img-1.1.2.tgz#fad650faf3ef2c53ea63112bc272d95e9d92550e" + integrity sha1-+tZQ+vPvLFPqYxErwnLZXp2SVQ4= + dependencies: + bmp-js "0.0.1" + file-type "^3.8.0" + get-stream "^2.0.0" + jimp "^0.2.21" + jpeg-js "^0.1.1" + parse-png "^1.1.1" + resolve-cwd@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" @@ -5003,11 +6156,16 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" -"safer-buffer@>= 2.1.2 < 3": +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== +sax@>=0.6.0: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + schema-utils@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" @@ -5017,6 +6175,15 @@ schema-utils@^1.0.0: ajv-errors "^1.0.0" ajv-keywords "^3.1.0" +schema-utils@^2.0.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7" + integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A== + dependencies: + "@types/json-schema" "^7.0.4" + ajv "^6.12.2" + ajv-keywords "^3.4.1" + schema-utils@^2.6.1, schema-utils@^2.6.5, schema-utils@^2.6.6: version "2.6.6" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.6.6.tgz#299fe6bd4a3365dc23d99fd446caff8f1d6c330c" @@ -5104,7 +6271,7 @@ serve-static@1.14.1: parseurl "~1.3.3" send "0.17.1" -set-blocking@^2.0.0: +set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= @@ -5142,6 +6309,21 @@ sha.js@^2.4.0, sha.js@^2.4.8: inherits "^2.0.1" safe-buffer "^5.0.1" +sharp@^0.23.3: + version "0.23.4" + resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.23.4.tgz#ca36067cb6ff7067fa6c77b01651cb9a890f8eb3" + integrity sha512-fJMagt6cT0UDy9XCsgyLi0eiwWWhQRxbwGmqQT6sY8Av4s0SVsT/deg8fobBQCTDU5iXRgz0rAeXoE2LBZ8g+Q== + dependencies: + color "^3.1.2" + detect-libc "^1.0.3" + nan "^2.14.0" + npmlog "^4.1.2" + prebuild-install "^5.3.3" + semver "^6.3.0" + simple-get "^3.1.0" + tar "^5.0.5" + tunnel-agent "^0.6.0" + shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" @@ -5171,6 +6353,27 @@ signal-exit@^3.0.0, signal-exit@^3.0.2: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== +simple-concat@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.0.tgz#7344cbb8b6e26fb27d66b2fc86f9f6d5997521c6" + integrity sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY= + +simple-get@^3.0.3, simple-get@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-3.1.0.tgz#b45be062435e50d159540b576202ceec40b9c6b3" + integrity sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA== + dependencies: + decompress-response "^4.2.0" + once "^1.3.1" + simple-concat "^1.0.0" + +simple-swizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" + integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= + dependencies: + is-arrayish "^0.3.1" + slice-ansi@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" @@ -5305,6 +6508,21 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= +sshpk@^1.7.0: + version "1.16.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" + integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + ssri@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" @@ -5365,6 +6583,35 @@ stream-shift@^1.0.0: resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== +stream-to-buffer@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/stream-to-buffer/-/stream-to-buffer-0.1.0.tgz#26799d903ab2025c9bd550ac47171b00f8dd80a9" + integrity sha1-JnmdkDqyAlyb1VCsRxcbAPjdgKk= + dependencies: + stream-to "~0.2.0" + +stream-to@~0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/stream-to/-/stream-to-0.2.2.tgz#84306098d85fdb990b9fa300b1b3ccf55e8ef01d" + integrity sha1-hDBgmNhf25kLn6MAsbPM9V6O8B0= + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2": + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + string-width@^3.0.0, string-width@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" @@ -5438,6 +6685,13 @@ strip-ansi@^3.0.0, strip-ansi@^3.0.1: dependencies: ansi-regex "^2.0.0" +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" @@ -5462,6 +6716,11 @@ strip-json-comments@^3.1.0: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.0.tgz#7638d31422129ecf4457440009fba03f9f9ac180" integrity sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w== +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + style-loader@^1.1.3: version "1.2.1" resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.2.1.tgz#c5cbbfbf1170d076cfdd86e0109c5bba114baa1a" @@ -5506,6 +6765,39 @@ tapable@^1.0.0, tapable@^1.1.3: resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== +tar-fs@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.0.tgz#d1cdd121ab465ee0eb9ccde2d35049d3f3daf0d5" + integrity sha512-9uW5iDvrIMCVpvasdFHW0wJPez0K4JnMZtsuIeDI7HyMGJNxmDZDOCQROr7lXyS+iL/QMpj07qcjGYTSdRFXUg== + dependencies: + chownr "^1.1.1" + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^2.0.0" + +tar-stream@^2.0.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.1.2.tgz#6d5ef1a7e5783a95ff70b69b97455a5968dc1325" + integrity sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q== + dependencies: + bl "^4.0.1" + end-of-stream "^1.4.1" + fs-constants "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.1.1" + +tar@^5.0.5: + version "5.0.5" + resolved "https://registry.yarnpkg.com/tar/-/tar-5.0.5.tgz#03fcdb7105bc8ea3ce6c86642b9c942495b04f93" + integrity sha512-MNIgJddrV2TkuwChwcSNds/5E9VijOiw7kAc1y5hTNJoLDSuIyid2QtLYiCYNnICebpuvjhPQZsXwUL0O3l7OQ== + dependencies: + chownr "^1.1.3" + fs-minipass "^2.0.0" + minipass "^3.0.0" + minizlib "^2.1.0" + mkdirp "^0.5.0" + yallist "^4.0.0" + terser-webpack-plugin@^1.4.3: version "1.4.3" resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz#5ecaf2dbdc5fb99745fd06791f46fc9ddb1c9a7c" @@ -5543,6 +6835,13 @@ through2@^2.0.0: readable-stream "~2.3.6" xtend "~4.0.1" +through2@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/through2/-/through2-3.0.1.tgz#39276e713c3302edf9e388dd9c812dd3b825bd5a" + integrity sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww== + dependencies: + readable-stream "2 || 3" + through@^2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" @@ -5560,6 +6859,16 @@ timers-browserify@^2.0.4: dependencies: setimmediate "^1.0.4" +timm@^1.6.1: + version "1.6.2" + resolved "https://registry.yarnpkg.com/timm/-/timm-1.6.2.tgz#dfd8c6719f7ba1fcfc6295a32670a1c6d166c0bd" + integrity sha512-IH3DYDL1wMUwmIlVmMrmesw5lZD6N+ZOAFWEyLrtpoL9Bcrs9u7M/vyOnHzDD2SMs4irLkVjqxZbHrXStS/Nmw== + +tinycolor2@^1.1.2, tinycolor2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.1.tgz#f4fad333447bc0b07d4dc8e9209d8f39a8ac77e8" + integrity sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g= + tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" @@ -5577,6 +6886,17 @@ to-fast-properties@^2.0.0: resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= +to-ico@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/to-ico/-/to-ico-1.1.5.tgz#1d32da5f2c90922edee6b686d610c54527b5a8d5" + integrity sha512-5kIh7m7bkIlqIESEZkL8gAMMzucXKfPe3hX2FoDY5HEAfD9OJU+Qh9b6Enp74w0qRcxVT5ejss66PHKqc3AVkg== + dependencies: + arrify "^1.0.1" + buffer-alloc "^1.1.0" + image-size "^0.5.0" + parse-png "^1.0.0" + resize-img "^1.1.0" + to-object-path@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" @@ -5607,6 +6927,14 @@ toidentifier@1.0.0: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== +tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + tslib@^1.10.0, tslib@^1.9.0: version "1.11.2" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.2.tgz#9c79d83272c9a7aaf166f73915c9667ecdde3cc9" @@ -5617,6 +6945,18 @@ tty-browserify@0.0.0: resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" @@ -5737,6 +7077,13 @@ url-parse@^1.4.3: querystringify "^2.1.1" requires-port "^1.0.0" +url-regex@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/url-regex/-/url-regex-3.2.0.tgz#dbad1e0c9e29e105dd0b1f09f6862f7fdb482724" + integrity sha1-260eDJ4p4QXdCx8J9oYvf9tIJyQ= + dependencies: + ip-regex "^1.0.1" + url@^0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" @@ -5750,6 +7097,13 @@ use@^3.1.0: resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== +utif@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/utif/-/utif-2.0.1.tgz#9e1582d9bbd20011a6588548ed3266298e711759" + integrity sha512-Z/S1fNKCicQTf375lIP9G8Sa1H/phcysstNrrSdZKj1f9g58J4NMgb5IgiEZN9/nLMPDwF0W7hdOe9Qq2IYoLg== + dependencies: + pako "^1.0.5" + util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" @@ -5807,6 +7161,27 @@ vary@~1.1.2: resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +vinyl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.2.0.tgz#d85b07da96e458d25b2ffe19fece9f2caa13ed86" + integrity sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg== + dependencies: + clone "^2.1.1" + clone-buffer "^1.0.0" + clone-stats "^1.0.0" + cloneable-readable "^1.0.0" + remove-trailing-separator "^1.0.1" + replace-ext "^1.0.0" + vm-browserify@^1.0.1: version "1.1.2" resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" @@ -5973,6 +7348,11 @@ which-module@^2.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= +which-pm-runs@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-pm-runs/-/which-pm-runs-1.0.0.tgz#670b3afbc552e0b55df6b7780ca74615f23ad1cb" + integrity sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs= + which@^1.2.14, which@^1.2.9, which@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" @@ -5987,6 +7367,13 @@ which@^2.0.1: dependencies: isexe "^2.0.0" +wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + word-wrap@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" @@ -6027,6 +7414,34 @@ ws@^6.2.1: dependencies: async-limiter "~1.0.0" +xhr@^2.0.1: + version "2.5.0" + resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.5.0.tgz#bed8d1676d5ca36108667692b74b316c496e49dd" + integrity sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ== + dependencies: + global "~4.3.0" + is-function "^1.0.1" + parse-headers "^2.0.0" + xtend "^4.0.0" + +xml-parse-from-string@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz#a9029e929d3dbcded169f3c6e28238d95a5d5a28" + integrity sha1-qQKekp09vN7RafPG4oI42VpdWig= + +xml2js@^0.4.22, xml2js@^0.4.5: + version "0.4.23" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" + integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug== + dependencies: + sax ">=0.6.0" + xmlbuilder "~11.0.0" + +xmlbuilder@~11.0.0: + version "11.0.1" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" + integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== + xtend@^4.0.0, xtend@~4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" From 04ab8cdc7df6428ac276c1ffd610e3cf3fd99231 Mon Sep 17 00:00:00 2001 From: Scott Lamb Date: Sat, 30 May 2020 19:08:54 -0700 Subject: [PATCH 6/6] more readable async web code This uses "async fn" throughout rather than a mix of async and the older futures style. And it takes advantage of the "self: Arc" syntax to avoid having a ServiceInner. It was confusing to have some methods on Service and some on ServiceInner; now that distinction is gone. One downside is there's a little more atomic reference-counting. Before, service_fn essentially took an &Arc, which means it could call Arc::clone where its use of self actually outlived the future (see stream_live_m4s) but didn't need to otherwise. After, it calls an async fn that takes Arc. Using &Arc is apparently possible (as of Rust 1.41) but using that with "async fn" means the returned future is tied to its lifetime. The workaround is to use async blocks as described here: but that's really ugly: it brings back the explicit Future reference, requires futures::future::Either in some cases, and introduces another level of indenting. I think it's better to just pay the arc costs which are probably negligible, or at least cheaper than the boxing was before. Oh, and I make this compile on Rust 1.40 again as it claimed to. http-serve accidentally used the &Arc thing which broke this. Update to a freshly-pushed commit which doesn't do that. --- Cargo.lock | 2 +- src/cmds/run.rs | 9 +- src/web.rs | 742 +++++++++++++++++++++++------------------------- 3 files changed, 356 insertions(+), 397 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e74c34e..2a6cb15 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -843,7 +843,7 @@ dependencies = [ [[package]] name = "http-serve" version = "0.2.2" -source = "git+https://github.com/scottlamb/http-serve?branch=dir#be4a4039b0bf70c951ee56e2d08d63d48dd5dbb3" +source = "git+https://github.com/scottlamb/http-serve?branch=dir#efde86035aedf6c623c11d1125aa256a3e99e6a2" dependencies = [ "bytes", "flate2", diff --git a/src/cmds/run.rs b/src/cmds/run.rs index 6e3a35c..01e6498 100644 --- a/src/cmds/run.rs +++ b/src/cmds/run.rs @@ -39,7 +39,6 @@ use futures::future::FutureExt; use hyper::service::{make_service_fn, service_fn}; use log::{info, warn}; use std::path::PathBuf; -use std::pin::Pin; use std::sync::Arc; use std::sync::atomic::{AtomicBool, Ordering}; use std::thread; @@ -188,13 +187,13 @@ pub async fn run(args: &Args) -> Result<(), Error> { let time_zone_name = resolve_zone()?; info!("Resolved timezone: {}", &time_zone_name); - let s = web::Service::new(web::Config { + let svc = Arc::new(web::Service::new(web::Config { db: db.clone(), ui_dir: Some(&args.ui_dir), allow_unauthenticated_permissions: args.allow_unauthenticated_permissions.clone(), trust_forward_hdrs: args.trust_forward_hdrs, time_zone_name, - })?; + })?); // Start a streamer for each stream. let shutdown_streamers = Arc::new(AtomicBool::new(false)); @@ -267,8 +266,8 @@ pub async fn run(args: &Args) -> Result<(), Error> { // Start the web interface. let make_svc = make_service_fn(move |_conn| { futures::future::ok::<_, std::convert::Infallible>(service_fn({ - let mut s = s.clone(); - move |req| Pin::from(s.serve(req)) + let svc = Arc::clone(&svc); + move |req| Arc::clone(&svc).serve(req) })) }); let server = ::hyper::server::Server::bind(&args.http_addr) diff --git a/src/web.rs b/src/web.rs index 7082101..57e0220 100644 --- a/src/web.rs +++ b/src/web.rs @@ -31,7 +31,7 @@ use base::clock::Clocks; use base::{ErrorKind, bail_t, strutil}; use bytes::Bytes; -use crate::body::{Body, BoxedError}; +use crate::body::Body; use crate::json; use crate::mp4; use bytes::{BufMut, BytesMut}; @@ -42,7 +42,6 @@ use db::dir::SampleFileDir; use failure::{Error, bail, format_err}; use fnv::FnvHashMap; use futures::sink::SinkExt; -use futures::future::{self, Either, Future, TryFutureExt, err}; use futures::stream::StreamExt; use http::{Request, Response, status::StatusCode}; use http::header::{self, HeaderValue}; @@ -56,15 +55,11 @@ use nom::sequence::{preceded, tuple}; use std::cmp; use std::net::IpAddr; use std::ops::Range; -use std::pin::Pin; use std::sync::Arc; use tokio_tungstenite::tungstenite; use url::form_urlencoded; use uuid::Uuid; -type BoxedFuture = Box, BoxedError>> + - Sync + Send + 'static>; - #[derive(Debug, Eq, PartialEq)] enum Path { TopLevel, // "/api/" @@ -242,18 +237,6 @@ struct Caller { session: Option, } -impl Caller { -} - -struct ServiceInner { - db: Arc, - ui_dir: Option>, - dirs_by_stream_id: Arc>>, - time_zone_name: String, - allow_unauthenticated_permissions: Option, - trust_forward_hdrs: bool, -} - type ResponseResult = Result, Response>; fn serve_json(req: &Request, out: &T) -> ResponseResult { @@ -266,7 +249,308 @@ fn serve_json(req: &Request, out: &T) -> Ok(resp) } -impl ServiceInner { +fn csrf_matches(csrf: &str, session: auth::SessionHash) -> bool { + let mut b64 = [0u8; 32]; + session.encode_base64(&mut b64); + ::ring::constant_time::verify_slices_are_equal(&b64[..], csrf.as_bytes()).is_ok() +} + +/// Extracts `s` cookie from the HTTP request. Does not authenticate. +fn extract_sid(req: &Request) -> Option { + let hdr = match req.headers().get(header::COOKIE) { + None => return None, + Some(c) => c, + }; + for mut cookie in hdr.as_bytes().split(|&b| b == b';') { + if cookie.starts_with(b" ") { + cookie = &cookie[1..]; + } + if cookie.starts_with(b"s=") { + let s = &cookie[2..]; + if let Ok(s) = auth::RawSessionId::decode_base64(s) { + return Some(s); + } + } + } + None +} + +/// Extracts an `application/json` POST body from a request. +/// +/// This returns the request body as bytes rather than performing +/// deserialization. Keeping the bytes allows the caller to use a `Deserialize` +/// that borrows from the bytes. +async fn extract_json_body(req: &mut Request) -> Result> { + if *req.method() != http::method::Method::POST { + return Err(plain_response(StatusCode::METHOD_NOT_ALLOWED, "POST expected")); + } + let correct_mime_type = match req.headers().get(header::CONTENT_TYPE) { + Some(t) if t == "application/json" => true, + Some(t) if t == "application/json; charset=UTF-8" => true, + _ => false, + }; + if !correct_mime_type { + return Err(bad_req("expected application/json request body")); + } + let b = ::std::mem::replace(req.body_mut(), hyper::Body::empty()); + hyper::body::to_bytes(b).await + .map_err(|e| internal_server_err(format_err!("unable to read request body: {}", e))) +} + +pub struct Config<'a> { + pub db: Arc, + pub ui_dir: Option<&'a std::path::Path>, + pub trust_forward_hdrs: bool, + pub time_zone_name: String, + pub allow_unauthenticated_permissions: Option, +} + +pub struct Service { + db: Arc, + ui_dir: Option>, + dirs_by_stream_id: Arc>>, + time_zone_name: String, + allow_unauthenticated_permissions: Option, + trust_forward_hdrs: bool, +} + +/// Useful HTTP `Cache-Control` values to set on successful (HTTP 200) API responses. +enum CacheControl { + /// For endpoints which have private data that may change from request to request. + PrivateDynamic, + + /// For endpoints which rarely change for a given URL. + /// E.g., a fixed segment of video. The underlying video logically never changes; there may + /// rarely be some software change to the actual bytes (which would result in a new etag) so + /// (unlike the content-hashed static content) it's not entirely immutable. + PrivateStatic, + + None, +} + +impl Service { + pub fn new(config: Config) -> Result { + let mut ui_dir = None; + if let Some(d) = config.ui_dir { + match FsDir::builder().for_path(&d) { + Err(e) => { + warn!("Unable to load --ui-dir={}; will serve no static files: {}", + d.display(), e); + }, + Ok(d) => ui_dir = Some(d), + }; + } + let dirs_by_stream_id = { + let l = config.db.lock(); + let mut d = + FnvHashMap::with_capacity_and_hasher(l.streams_by_id().len(), Default::default()); + for (&id, s) in l.streams_by_id().iter() { + let dir_id = match s.sample_file_dir_id { + Some(d) => d, + None => continue, + }; + d.insert(id, l.sample_file_dirs_by_id() + .get(&dir_id) + .unwrap() + .get()?); + } + Arc::new(d) + }; + + Ok(Service { + db: config.db, + dirs_by_stream_id, + ui_dir, + allow_unauthenticated_permissions: config.allow_unauthenticated_permissions, + trust_forward_hdrs: config.trust_forward_hdrs, + time_zone_name: config.time_zone_name, + }) + } + + fn stream_live_m4s(self: Arc, req: Request<::hyper::Body>, caller: Caller, uuid: Uuid, + stream_type: db::StreamType) -> ResponseResult { + if !caller.permissions.view_video { + return Err(plain_response(StatusCode::UNAUTHORIZED, "view_video required")); + } + + let stream_id; + let open_id; + let (sub_tx, sub_rx) = futures::channel::mpsc::unbounded(); + { + let mut db = self.db.lock(); + open_id = match db.open { + None => return Err(plain_response( + StatusCode::PRECONDITION_FAILED, + "database is read-only; there are no live streams")), + Some(o) => o.id, + }; + let camera = db.get_camera(uuid) + .ok_or_else(|| plain_response(StatusCode::NOT_FOUND, + format!("no such camera {}", uuid)))?; + stream_id = camera.streams[stream_type.index()] + .ok_or_else(|| plain_response(StatusCode::NOT_FOUND, + format!("no such stream {}/{}", uuid, + stream_type)))?; + db.watch_live(stream_id, Box::new(move |l| sub_tx.unbounded_send(l).is_ok())) + .expect("stream_id refed by camera"); + } + + let (parts, body) = req.into_parts(); + let req = Request::from_parts(parts, ()); + let response = tungstenite::handshake::server::create_response(&req) + .map_err(|e| bad_req(e.to_string()))?; + let (parts, ()) = response.into_parts(); + + tokio::spawn(self.stream_live_m4s_ws(stream_id, open_id, body, sub_rx)); + + Ok(Response::from_parts(parts, Body::from(""))) + } + + async fn stream_live_m4s_ws( + self: Arc, stream_id: i32, open_id: u32, body: hyper::Body, + mut sub_rx: futures::channel::mpsc::UnboundedReceiver) { + let upgraded = match body.on_upgrade().await { + Ok(u) => u, + Err(e) => { + warn!("Unable to upgrade stream to websocket: {}", e); + return; + }, + }; + let mut ws = tokio_tungstenite::WebSocketStream::from_raw_socket( + upgraded, + tungstenite::protocol::Role::Server, + None, + ).await; + loop { + let live = match sub_rx.next().await { + Some(l) => l, + None => return, + }; + if let Err(e) = self.stream_live_m4s_chunk(open_id, stream_id, &mut ws, live).await { + info!("Dropping WebSocket after error: {}", e); + return; + } + } + } + + async fn stream_live_m4s_chunk( + &self, open_id: u32, stream_id: i32, + ws: &mut tokio_tungstenite::WebSocketStream, + live: db::LiveSegment) -> Result<(), Error> { + let mut builder = mp4::FileBuilder::new(mp4::Type::MediaSegment); + let mut vse_id = None; + let mut start = None; + { + let db = self.db.lock(); + let mut rows = 0; + db.list_recordings_by_id(stream_id, live.recording .. live.recording+1, &mut |r| { + rows += 1; + let vse = db.video_sample_entries_by_id().get(&r.video_sample_entry_id) + .unwrap(); + vse_id = Some(strutil::hex(&vse.sha1)); + start = Some(r.start); + builder.append(&db, r, live.off_90k.clone())?; + Ok(()) + })?; + if rows != 1 { + bail_t!(Internal, "unable to find {:?}", live); + } + } + let vse_id = vse_id.unwrap(); + let start = start.unwrap(); + use http_serve::Entity; + let mp4 = builder.build(self.db.clone(), self.dirs_by_stream_id.clone())?; + let mut hdrs = header::HeaderMap::new(); + mp4.add_headers(&mut hdrs); + let mime_type = hdrs.get(header::CONTENT_TYPE).unwrap(); + let hdr = format!( + "Content-Type: {}\r\n\ + X-Recording-Start: {}\r\n\ + X-Recording-Id: {}.{}\r\n\ + X-Time-Range: {}-{}\r\n\ + X-Video-Sample-Entry-Sha1: {}\r\n\r\n", + mime_type.to_str().unwrap(), + start.0, + open_id, + live.recording, + live.off_90k.start, + live.off_90k.end, + &vse_id); + let mut v = /*Pin::from(*/hdr.into_bytes()/*)*/; + mp4.append_into_vec(&mut v).await?; + //let v = Pin::into_inner(); + ws.send(tungstenite::Message::Binary(v)).await?; + Ok(()) + } + + async fn signals(&self, req: Request, caller: Caller) -> ResponseResult { + use http::method::Method; + match *req.method() { + Method::POST => self.post_signals(req, caller).await, + Method::GET | Method::HEAD => self.get_signals(&req), + _ => Err(plain_response(StatusCode::METHOD_NOT_ALLOWED, + "POST, GET, or HEAD expected")), + } + } + + async fn serve_inner(self: Arc, req: Request<::hyper::Body>, p: Path, caller: Caller) + -> ResponseResult { + let (cache, mut response) = match p { + Path::InitSegment(sha1, debug) => { + (CacheControl::PrivateStatic, self.init_segment(sha1, debug, &req)?) + }, + Path::TopLevel => (CacheControl::PrivateDynamic, self.top_level(&req, caller)?), + Path::Request => (CacheControl::PrivateDynamic, self.request(&req)?), + Path::Camera(uuid) => (CacheControl::PrivateDynamic, self.camera(&req, uuid)?), + Path::StreamRecordings(uuid, type_) => { + (CacheControl::PrivateDynamic, self.stream_recordings(&req, uuid, type_)?) + }, + Path::StreamViewMp4(uuid, type_, debug) => { + (CacheControl::PrivateStatic, + self.stream_view_mp4(&req, caller, uuid, type_, mp4::Type::Normal, debug)?) + }, + Path::StreamViewMp4Segment(uuid, type_, debug) => { + (CacheControl::PrivateStatic, + self.stream_view_mp4(&req, caller, uuid, type_, mp4::Type::MediaSegment, debug)?) + }, + Path::StreamLiveMp4Segments(uuid, type_) => { + (CacheControl::PrivateDynamic, self.stream_live_m4s(req, caller, uuid, type_)?) + }, + Path::NotFound => return Err(not_found("path not understood")), + Path::Login => (CacheControl::PrivateDynamic, self.login(req).await?), + Path::Logout => (CacheControl::PrivateDynamic, self.logout(req).await?), + Path::Signals => (CacheControl::PrivateDynamic, self.signals(req, caller).await?), + Path::Static => (CacheControl::None, self.static_file(req).await?) + }; + match cache { + CacheControl::PrivateStatic => { + response.headers_mut().insert(header::CACHE_CONTROL, + HeaderValue::from_static("private, max-age=3600")); + }, + CacheControl::PrivateDynamic => { + response.headers_mut().insert(header::CACHE_CONTROL, + HeaderValue::from_static("private, no-cache")); + }, + CacheControl::None => {}, + } + Ok(response) + } + + pub async fn serve(self: Arc, req: Request<::hyper::Body>) + -> Result, std::convert::Infallible> { + let p = Path::decode(req.uri().path()); + let always_allow_unauthenticated = match p { + Path::NotFound | Path::Request | Path::Login | Path::Logout | Path::Static => true, + _ => false, + }; + debug!("request on: {}: {:?}", req.uri(), p); + let caller = match self.authenticate(&req, always_allow_unauthenticated) { + Ok(c) => c, + Err(e) => return Ok(from_base_error(e)), + }; + Ok(self.serve_inner(req, p, caller).await.unwrap_or_else(|e| e)) + } + fn top_level(&self, req: &Request<::hyper::Body>, caller: Caller) -> ResponseResult { let mut days = false; let mut camera_configs = false; @@ -514,39 +798,31 @@ impl ServiceInner { Ok(http_serve::serve(mp4, req)) } - fn static_file(&self, req: Request) - -> impl Future + 'static { - let dir = match self.ui_dir.clone() { - None => { - return Either::Left( - err(not_found("--ui-dir not configured; no static files available."))) - }, - Some(d) => d, + async fn static_file(&self, req: Request) -> ResponseResult { + let dir = self.ui_dir.clone() + .ok_or_else(|| not_found("--ui-dir not configured; no static files available."))?; + let static_req = match StaticFileRequest::parse(req.uri().path()) { + None => return Err(not_found("static file not found")), + Some(r) => r, }; - Either::Right(async move { - let static_req = match StaticFileRequest::parse(req.uri().path()) { - None => return Err(not_found("static file not found")), - Some(r) => r, - }; - let f = dir.get(static_req.path, req.headers()); - let node = f.await - .map_err(|e| if e.kind() == std::io::ErrorKind::NotFound { - not_found("no such static file") - } else { - internal_server_err(e) - })?; - let mut hdrs = http::HeaderMap::new(); - node.add_encoding_headers(&mut hdrs); - hdrs.insert(header::CACHE_CONTROL, HeaderValue::from_static(if static_req.immutable { - // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#Caching_static_assets - "public, max-age=604800, immutable" + let f = dir.get(static_req.path, req.headers()); + let node = f.await + .map_err(|e| if e.kind() == std::io::ErrorKind::NotFound { + not_found("no such static file") } else { - "public" - })); - hdrs.insert(header::CONTENT_TYPE, HeaderValue::from_static(static_req.mime)); - let e = node.into_file_entity(hdrs).map_err(internal_server_err)?; - Ok(http_serve::serve(e, &req)) - }) + internal_server_err(e) + })?; + let mut hdrs = http::HeaderMap::new(); + node.add_encoding_headers(&mut hdrs); + hdrs.insert(header::CACHE_CONTROL, HeaderValue::from_static(if static_req.immutable { + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#Caching_static_assets + "public, max-age=604800, immutable" + } else { + "public" + })); + hdrs.insert(header::CONTENT_TYPE, HeaderValue::from_static(static_req.mime)); + let e = node.into_file_entity(hdrs).map_err(internal_server_err)?; + Ok(http_serve::serve(e, &req)) } fn authreq(&self, req: &Request<::hyper::Body>) -> auth::Request { @@ -588,10 +864,11 @@ impl ServiceInner { .unwrap_or(false) } - fn login(&self, req: &Request<::hyper::Body>, body: Bytes) -> ResponseResult { - let r: json::LoginRequest = serde_json::from_slice(&body) + async fn login(&self, mut req: Request<::hyper::Body>) -> ResponseResult { + let r = extract_json_body(&mut req).await?; + let r: json::LoginRequest = serde_json::from_slice(&r) .map_err(|e| bad_req(e.to_string()))?; - let authreq = self.authreq(req); + let authreq = self.authreq(&req); let host = req.headers().get(header::HOST).ok_or_else(|| bad_req("missing Host header!"))?; let host = host.as_bytes(); let domain = match memchr(b':', host) { @@ -599,7 +876,7 @@ impl ServiceInner { None => host, }.to_owned(); let mut l = self.db.lock(); - let is_secure = self.is_secure(req); + let is_secure = self.is_secure(&req); let flags = (auth::SessionFlag::HttpOnly as i32) | (auth::SessionFlag::SameSite as i32) | (auth::SessionFlag::SameSiteStrict as i32) | @@ -625,13 +902,14 @@ impl ServiceInner { .body(b""[..].into()).unwrap()) } - fn logout(&self, req: &Request, body: Bytes) -> ResponseResult { - let r: json::LogoutRequest = serde_json::from_slice(&body) + async fn logout(&self, mut req: Request) -> ResponseResult { + let r = extract_json_body(&mut req).await?; + let r: json::LogoutRequest = serde_json::from_slice(&r) .map_err(|e| bad_req(e.to_string()))?; let mut res = Response::new(b""[..].into()); - if let Some(sid) = extract_sid(req) { - let authreq = self.authreq(req); + if let Some(sid) = extract_sid(&req) { + let authreq = self.authreq(&req); let mut l = self.db.lock(); let hash = sid.hash(); let need_revoke = match l.authenticate_session(authreq.clone(), &hash) { @@ -666,12 +944,13 @@ impl ServiceInner { Ok(res) } - fn post_signals(&self, req: &Request, caller: Caller, body: Bytes) - -> ResponseResult { + async fn post_signals(&self, mut req: Request, caller: Caller) + -> ResponseResult { if !caller.permissions.update_signals { return Err(plain_response(StatusCode::UNAUTHORIZED, "update_signals required")); } - let r: json::PostSignalsRequest = serde_json::from_slice(&body) + let r = extract_json_body(&mut req).await?; + let r: json::PostSignalsRequest = serde_json::from_slice(&r) .map_err(|e| bad_req(e.to_string()))?; let mut l = self.db.lock(); let now = recording::Time::new(self.db.clocks().realtime()); @@ -684,7 +963,7 @@ impl ServiceInner { }, }; l.update_signals(start .. end, &r.signal_ids, &r.states).map_err(from_base_error)?; - serve_json(req, &json::PostSignalsResponse { + serve_json(&req, &json::PostSignalsResponse { time_90k: now.0, }) } @@ -754,327 +1033,6 @@ impl ServiceInner { } } -fn csrf_matches(csrf: &str, session: auth::SessionHash) -> bool { - let mut b64 = [0u8; 32]; - session.encode_base64(&mut b64); - ::ring::constant_time::verify_slices_are_equal(&b64[..], csrf.as_bytes()).is_ok() -} - -/// Extracts `s` cookie from the HTTP request. Does not authenticate. -fn extract_sid(req: &Request) -> Option { - let hdr = match req.headers().get(header::COOKIE) { - None => return None, - Some(c) => c, - }; - for mut cookie in hdr.as_bytes().split(|&b| b == b';') { - if cookie.starts_with(b" ") { - cookie = &cookie[1..]; - } - if cookie.starts_with(b"s=") { - let s = &cookie[2..]; - if let Ok(s) = auth::RawSessionId::decode_base64(s) { - return Some(s); - } - } - } - None -} - -/// Returns a future separating the request from its JSON body. -/// -/// If this is not a `POST` or the body's `Content-Type` is not -/// `application/json`, returns an appropriate error response instead. -/// -/// Use with `and_then` to chain logic which consumes the form body. -async fn with_json_body(mut req: Request) - -> Result<(Request, Bytes), Response> { - if *req.method() != http::method::Method::POST { - return Err(plain_response(StatusCode::METHOD_NOT_ALLOWED, "POST expected")); - } - let correct_mime_type = match req.headers().get(header::CONTENT_TYPE) { - Some(t) if t == "application/json" => true, - Some(t) if t == "application/json; charset=UTF-8" => true, - _ => false, - }; - if !correct_mime_type { - return Err(bad_req("expected application/json request body")); - } - let b = ::std::mem::replace(req.body_mut(), hyper::Body::empty()); - match hyper::body::to_bytes(b).await { - Ok(b) => Ok((req, b)), - Err(e) => Err(internal_server_err(format_err!("unable to read request body: {}", e))), - } -} - - -pub struct Config<'a> { - pub db: Arc, - pub ui_dir: Option<&'a std::path::Path>, - pub trust_forward_hdrs: bool, - pub time_zone_name: String, - pub allow_unauthenticated_permissions: Option, -} - -#[derive(Clone)] -pub struct Service(Arc); - -/// Useful HTTP `Cache-Control` values to set on successful (HTTP 200) API responses. -enum CacheControl { - /// For endpoints which have private data that may change from request to request. - PrivateDynamic, - - /// For endpoints which rarely change for a given URL. - /// E.g., a fixed segment of video. The underlying video logically never changes; there may - /// rarely be some software change to the actual bytes (which would result in a new etag) so - /// (unlike the content-hashed static content) it's not entirely immutable. - PrivateStatic, - - None, -} - -impl Service { - pub fn new(config: Config) -> Result { - let mut ui_dir = None; - if let Some(d) = config.ui_dir { - match FsDir::builder().for_path(&d) { - Err(e) => { - warn!("Unable to load --ui-dir={}; will serve no static files: {}", - d.display(), e); - }, - Ok(d) => ui_dir = Some(d), - }; - } - let dirs_by_stream_id = { - let l = config.db.lock(); - let mut d = - FnvHashMap::with_capacity_and_hasher(l.streams_by_id().len(), Default::default()); - for (&id, s) in l.streams_by_id().iter() { - let dir_id = match s.sample_file_dir_id { - Some(d) => d, - None => continue, - }; - d.insert(id, l.sample_file_dirs_by_id() - .get(&dir_id) - .unwrap() - .get()?); - } - Arc::new(d) - }; - - Ok(Service(Arc::new(ServiceInner { - db: config.db, - dirs_by_stream_id, - ui_dir, - allow_unauthenticated_permissions: config.allow_unauthenticated_permissions, - trust_forward_hdrs: config.trust_forward_hdrs, - time_zone_name: config.time_zone_name, - }))) - } - - fn stream_live_m4s(&self, req: Request<::hyper::Body>, caller: Caller, uuid: Uuid, - stream_type: db::StreamType) -> ResponseResult { - if !caller.permissions.view_video { - return Err(plain_response(StatusCode::UNAUTHORIZED, "view_video required")); - } - - let stream_id; - let open_id; - let (sub_tx, sub_rx) = futures::channel::mpsc::unbounded(); - { - let mut db = self.0.db.lock(); - open_id = match db.open { - None => return Err(plain_response( - StatusCode::PRECONDITION_FAILED, - "database is read-only; there are no live streams")), - Some(o) => o.id, - }; - let camera = db.get_camera(uuid) - .ok_or_else(|| plain_response(StatusCode::NOT_FOUND, - format!("no such camera {}", uuid)))?; - stream_id = camera.streams[stream_type.index()] - .ok_or_else(|| plain_response(StatusCode::NOT_FOUND, - format!("no such stream {}/{}", uuid, - stream_type)))?; - db.watch_live(stream_id, Box::new(move |l| sub_tx.unbounded_send(l).is_ok())) - .expect("stream_id refed by camera"); - } - - let (parts, body) = req.into_parts(); - let req = Request::from_parts(parts, ()); - let response = tungstenite::handshake::server::create_response(&req) - .map_err(|e| bad_req(e.to_string()))?; - let (parts, ()) = response.into_parts(); - - tokio::spawn(self.clone().stream_live_m4s_ws(stream_id, open_id, body, sub_rx)); - - Ok(Response::from_parts(parts, Body::from(""))) - } - - async fn stream_live_m4s_ws( - self, stream_id: i32, open_id: u32, body: hyper::Body, - mut sub_rx: futures::channel::mpsc::UnboundedReceiver) { - let upgraded = match body.on_upgrade().await { - Ok(u) => u, - Err(e) => { - warn!("Unable to upgrade stream to websocket: {}", e); - return; - }, - }; - let mut ws = tokio_tungstenite::WebSocketStream::from_raw_socket( - upgraded, - tungstenite::protocol::Role::Server, - None, - ).await; - loop { - let live = match sub_rx.next().await { - Some(l) => l, - None => return, - }; - if let Err(e) = self.stream_live_m4s_chunk(open_id, stream_id, &mut ws, live).await { - info!("Dropping WebSocket after error: {}", e); - return; - } - } - } - - async fn stream_live_m4s_chunk( - &self, open_id: u32, stream_id: i32, - ws: &mut tokio_tungstenite::WebSocketStream, - live: db::LiveSegment) -> Result<(), Error> { - let mut builder = mp4::FileBuilder::new(mp4::Type::MediaSegment); - let mut vse_id = None; - let mut start = None; - { - let db = self.0.db.lock(); - let mut rows = 0; - db.list_recordings_by_id(stream_id, live.recording .. live.recording+1, &mut |r| { - rows += 1; - let vse = db.video_sample_entries_by_id().get(&r.video_sample_entry_id) - .unwrap(); - vse_id = Some(strutil::hex(&vse.sha1)); - start = Some(r.start); - builder.append(&db, r, live.off_90k.clone())?; - Ok(()) - })?; - if rows != 1 { - bail_t!(Internal, "unable to find {:?}", live); - } - } - let vse_id = vse_id.unwrap(); - let start = start.unwrap(); - use http_serve::Entity; - let mp4 = builder.build(self.0.db.clone(), self.0.dirs_by_stream_id.clone())?; - let mut hdrs = header::HeaderMap::new(); - mp4.add_headers(&mut hdrs); - let mime_type = hdrs.get(header::CONTENT_TYPE).unwrap(); - let hdr = format!( - "Content-Type: {}\r\n\ - X-Recording-Start: {}\r\n\ - X-Recording-Id: {}.{}\r\n\ - X-Time-Range: {}-{}\r\n\ - X-Video-Sample-Entry-Sha1: {}\r\n\r\n", - mime_type.to_str().unwrap(), - start.0, - open_id, - live.recording, - live.off_90k.start, - live.off_90k.end, - &vse_id); - let mut v = /*Pin::from(*/hdr.into_bytes()/*)*/; - mp4.append_into_vec(&mut v).await?; - //let v = Pin::into_inner(); - ws.send(tungstenite::Message::Binary(v)).await?; - Ok(()) - } - - fn signals(&self, req: Request, caller: Caller) - -> Box, Response>> + Send + Sync + 'static> { - use http::method::Method; - match *req.method() { - Method::POST => Box::new(with_json_body(req) - .and_then({ - let s = self.0.clone(); - move |(req, b)| future::ready(s.post_signals(&req, caller, b)) - })), - Method::GET | Method::HEAD => Box::new(future::ready(self.0.get_signals(&req))), - _ => Box::new(future::err(plain_response(StatusCode::METHOD_NOT_ALLOWED, - "POST, GET, or HEAD expected"))), - } - } - - pub fn serve(&mut self, req: Request<::hyper::Body>) -> BoxedFuture { - fn wrap(cache_hdr: CacheControl, r: R) -> BoxedFuture - where R: Future, Response>> + Send + Sync + 'static { - return Box::new(r.or_else(|e| futures::future::ok(e)).map_ok(move |mut r| { - match cache_hdr { - CacheControl::PrivateStatic => { - r.headers_mut().insert(header::CACHE_CONTROL, - HeaderValue::from_static("private, max-age=3600")); - }, - CacheControl::PrivateDynamic => { - r.headers_mut().insert(header::CACHE_CONTROL, - HeaderValue::from_static("private, no-cache")); - }, - CacheControl::None => {}, - } - r - })) - } - - fn wrap_r(cache_hdr: CacheControl, r: ResponseResult) - -> Box, BoxedError>> + Send + Sync + 'static> { - return wrap(cache_hdr, future::ready(r)) - } - - let p = Path::decode(req.uri().path()); - let always_allow_unauthenticated = match p { - Path::NotFound | Path::Request | Path::Login | Path::Logout | Path::Static => true, - _ => false, - }; - debug!("request on: {}: {:?}", req.uri(), p); - let caller = match self.0.authenticate(&req, always_allow_unauthenticated) { - Ok(c) => c, - Err(e) => return Box::new(future::ok(from_base_error(e))), - }; - match p { - Path::InitSegment(sha1, debug) => { - wrap_r(CacheControl::PrivateStatic, self.0.init_segment(sha1, debug, &req)) - }, - Path::TopLevel => wrap_r(CacheControl::PrivateDynamic, self.0.top_level(&req, caller)), - Path::Request => wrap_r(CacheControl::PrivateDynamic, self.0.request(&req)), - Path::Camera(uuid) => wrap_r(CacheControl::PrivateDynamic, self.0.camera(&req, uuid)), - Path::StreamRecordings(uuid, type_) => { - wrap_r(CacheControl::PrivateDynamic, self.0.stream_recordings(&req, uuid, type_)) - }, - Path::StreamViewMp4(uuid, type_, debug) => { - wrap_r(CacheControl::PrivateStatic, - self.0.stream_view_mp4(&req, caller, uuid, type_, mp4::Type::Normal, debug)) - }, - Path::StreamViewMp4Segment(uuid, type_, debug) => { - wrap_r(CacheControl::PrivateStatic, - self.0.stream_view_mp4(&req, caller, uuid, type_, mp4::Type::MediaSegment, - debug)) - }, - Path::StreamLiveMp4Segments(uuid, type_) => { - wrap_r(CacheControl::PrivateDynamic, self.stream_live_m4s(req, caller, uuid, type_)) - }, - Path::NotFound => wrap(CacheControl::PrivateDynamic, - future::err(not_found("path not understood"))), - Path::Login => wrap(CacheControl::PrivateDynamic, with_json_body(req).and_then({ - let s = self.clone(); - move |(req, b)| future::ready(s.0.login(&req, b)) - })), - Path::Logout => wrap(CacheControl::PrivateDynamic, with_json_body(req).and_then({ - let s = self.clone(); - move |(req, b)| future::ready(s.0.logout(&req, b)) - })), - Path::Signals => wrap(CacheControl::PrivateDynamic, - Pin::from(self.signals(req, caller))), - Path::Static => wrap(CacheControl::None, self.0.static_file(req)) - } - } -} - #[derive(Debug, Eq, PartialEq)] struct StaticFileRequest<'a> { path: &'a str, @@ -1123,6 +1081,7 @@ mod tests { use log::info; use std::collections::HashMap; use std::str::FromStr; + use std::sync::Arc; use super::{Segments, StaticFileRequest}; struct Server { @@ -1137,17 +1096,17 @@ mod tests { fn new(allow_unauthenticated_permissions: Option) -> Server { let db = TestDb::new(base::clock::RealClocks {}); let (shutdown_tx, shutdown_rx) = futures::channel::oneshot::channel::<()>(); - let service = super::Service::new(super::Config { + let service = Arc::new(super::Service::new(super::Config { db: db.db.clone(), ui_dir: None, allow_unauthenticated_permissions, trust_forward_hdrs: true, time_zone_name: "".to_owned(), - }).unwrap(); + }).unwrap()); let make_svc = hyper::service::make_service_fn(move |_conn| { futures::future::ok::<_, std::convert::Infallible>(hyper::service::service_fn({ - let mut s = service.clone(); - move |req| std::pin::Pin::from(s.serve(req)) + let s = Arc::clone(&service); + move |req| Arc::clone(&s).serve(req) })) }); let (tx, rx) = std::sync::mpsc::channel(); @@ -1440,6 +1399,7 @@ mod bench { use db::testutil::{self, TestDb}; use hyper; use lazy_static::lazy_static; + use std::sync::Arc; use uuid::Uuid; struct Server { @@ -1452,17 +1412,17 @@ mod bench { let db = TestDb::new(::base::clock::RealClocks {}); let test_camera_uuid = db.test_camera_uuid; testutil::add_dummy_recordings_to_db(&db.db, 1440); - let service = super::Service::new(super::Config { + let service = Arc::new(super::Service::new(super::Config { db: db.db.clone(), ui_dir: None, allow_unauthenticated_permissions: Some(db::Permissions::default()), trust_forward_hdrs: false, time_zone_name: "".to_owned(), - }).unwrap(); + }).unwrap()); let make_svc = hyper::service::make_service_fn(move |_conn| { futures::future::ok::<_, std::convert::Infallible>(hyper::service::service_fn({ - let mut s = service.clone(); - move |req| std::pin::Pin::from(s.serve(req)) + let s = Arc::clone(&service); + move |req| Arc::clone(&s).serve(req) })) }); let mut rt = tokio::runtime::Runtime::new().unwrap();