diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..9ac2a53b9 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ +# editorconfig.org +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = tab +insert_final_newline = true + +[*.json] +indent_size = 2 +indent_style = space diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..90b9f343a --- /dev/null +++ b/.gitattributes @@ -0,0 +1,5 @@ +* text eol=lf +*.png binary +*.exe binary +*.dll binary + diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 000000000..a958ae0e2 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,24 @@ +Thanks for filing a bug! To save time, if you're having trouble using the library, please check off the items you have tried. If you are just asking a question, skip right to the bottom. + +### Please verify these steps before filing an issue, and check them off as you go +- [ ] The relevant native JavascriptEngineSwitcher library packages are installed (such as `JavaScriptEngineSwitcher.V8.Native.win-x64`) +- [ ] The VC++ 2017 runtime is installed +- [ ] The value of `SetUseReact` and `SetUseBabel` is correct in `ReactConfig.cs` or `Startup.cs` +- [ ] I've looked at the sample projects in this repo to verify that my app is configured correctly + +### I'm using these library versions: +- `ReactJS.NET`: +- `JavaScriptEngineSwitcher`: +- `react` and `react-dom`: (N/A if using bundled react, or version number) +- `webpack`: (N/A if using bundled react) +- `node`: (N/A if using bundled react) + +### Runtime environment: +- OS: (Mac, Windows, Linux flavor. Include 32-bit/64-bit and version) +- .NET Framework or .NET Core Version: + +### Steps to reproduce + +------- + +(Describe your issue here) diff --git a/.github/workflows/dotnet-core-desktop.yml b/.github/workflows/dotnet-core-desktop.yml new file mode 100644 index 000000000..194ac738e --- /dev/null +++ b/.github/workflows/dotnet-core-desktop.yml @@ -0,0 +1,64 @@ +name: .NET Core Desktop + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + + build: + + strategy: + matrix: + configuration: [Debug, Release] + + runs-on: windows-latest # For a list of available runner types, refer to + # https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idruns-on + + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Cache node modules + uses: actions/cache@v2 + env: + cache-name: cache-node-modules + with: + # npm cache files are stored in `~/.npm` on Linux/macOS + path: ~/.npm + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-build-${{ env.cache-name }}- + ${{ runner.os }}-build- + ${{ runner.os }}- + + - name: Install .NET Core + uses: actions/setup-dotnet@v1 + with: + dotnet-version: 3.1.x + + - name: Use Node.js 12 + uses: actions/setup-node@v1 + with: + node-version: 12 + + - name: Setup MSBuild.exe + uses: microsoft/setup-msbuild@2008f912f56e61277eefaac6d1888b750582aa16 + env: + ACTIONS_ALLOW_UNSECURE_COMMANDS: true + + - name: Build + run: msbuild build.proj /p:PackageOutputDir="${{ env.GITHUB_WORKSPACE }}/nuget-output" /p:Configuration=${{ matrix.configuration }} + env: + ACTIONS_ALLOW_UNSECURE_COMMANDS: true + Configuration: ${{ matrix.configuration }} + + - name: Upload build artifacts + uses: actions/upload-artifact@v1 + with: + name: Nuget Package + path: "${{ env.GITHUB_WORKSPACE }}/nuget-output" diff --git a/.gitignore b/.gitignore index ed7ef684c..b32bd32fb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,20 @@ _old/ src/SharedAssemblyVersionInfo.cs *.nupkg +*.snupkg src/**/*.nuspec !src/template.nuspec site/jekyll/_site src/React.Sample.Cassette/cassette-cache +src/React.Sample.*/ClearScript.V8 +src/React.Sample.Webpack/build *.generated.js +*.generated.js.map +*.generated.min.js +*.lock.json +.vs/ +results/ +dist/ ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. diff --git a/.gitmodules b/.gitmodules index ee3518802..e69de29bb 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +0,0 @@ -[submodule "site/packages"] - path = site/packages - url = https://github.com/Daniel15/simple-nuget-server.git -[submodule "lib/VroomJs"] - path = lib/VroomJs - url = https://github.com/Daniel15/vroomjs.git diff --git a/LICENSE b/LICENSE index 3cac634d4..10d9a688c 100644 --- a/LICENSE +++ b/LICENSE @@ -1,28 +1,21 @@ -BSD License for ReactJS.NET +MIT License for ReactJS.NET -Copyright (c) 2014, Facebook, Inc. All rights reserved. +Copyright (c) Facebook, Inc. and its affiliates. -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - * Neither the name Facebook nor the names of its contributors may be used to - endorse or promote products derived from this software without specific - prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/PATENTS b/PATENTS deleted file mode 100644 index e0ee8eb12..000000000 --- a/PATENTS +++ /dev/null @@ -1,23 +0,0 @@ -Additional Grant of Patent Rights - -�Software� means the ReactJS.NET software distributed by Facebook, Inc. - -Facebook hereby grants you a perpetual, worldwide, royalty-free, non-exclusive, -irrevocable (subject to the termination provision below) license under any -rights in any patent claims owned by Facebook, to make, have made, use, sell, -offer to sell, import, and otherwise transfer the Software. For avoidance of -doubt, no license is granted under Facebook�s rights in any patent claims that -are infringed by (i) modifications to the Software made by you or a third party, -or (ii) the Software in combination with any software or other technology -provided by you or a third party. - -The license granted hereunder will terminate, automatically and without notice, -for anyone that makes any claim (including by filing any lawsuit, assertion or -other action) alleging (a) direct, indirect, or contributory infringement or -inducement to infringe any patent: (i) by Facebook or any of its subsidiaries or -affiliates, whether or not such claim is related to the Software, (ii) by any -party if such claim arises in whole or in part from any software, product or -service of Facebook or any of its subsidiaries or affiliates, whether or not -such claim is related to the Software, or (iii) by any party relating to the -Software; or (b) that any right in any patent claim of Facebook is invalid or -unenforceable. \ No newline at end of file diff --git a/README.md b/README.md index e60dd314a..8a6674e56 100644 --- a/README.md +++ b/README.md @@ -1,64 +1,55 @@ -[ReactJS.NET](http://reactjs.net/) -=========== +# [ReactJS.NET](http://reactjs.net/) -ReactJS.NET is a library that makes it easier to use Facebook's -[React](http://facebook.github.io/react/) and -[JSX](http://facebook.github.io/react/docs/jsx-in-depth.html) from C#. +ReactJS.NET is a library that makes it easier to use [Babel](http://babeljs.io/) along with Facebook's [React](https://reactjs.org/) and [JSX](https://reactjs.org/docs/jsx-in-depth.html) from C#. -[![Build status](http://img.shields.io/teamcity/codebetter/bt1242.svg)]((http://teamcity.codebetter.com/viewType.html?buildTypeId=bt1242&guest=1))  -![Code coverage](http://img.shields.io/teamcity/coverage/bt1242.svg)  -![NuGet downloads](http://img.shields.io/nuget/dt/React.Core.svg)  -![NuGet version](http://img.shields.io/nuget/v/React.Core.svg) +![.NET Core Desktop](https://github.com/reactjs/React.NET/workflows/.NET%20Core%20Desktop/badge.svg) +[![NuGet version](http://img.shields.io/nuget/v/React.Core.svg)](https://www.nuget.org/packages/React.Core/) +[![Download count](https://img.shields.io/nuget/dt/React.Core.svg)](https://www.nuget.org/packages/React.Core/) -Features -======== - * On-the-fly [JSX to JavaScript compilation](http://reactjs.net/getting-started/usage.html) - * JSX to JavaScript compilation via popular minification/combination - libraries: - * [ASP.NET Bundling and Minification](http://reactjs.net/guides/weboptimizer.html) - * [Cassette](http://reactjs.net/guides/cassette.html) - * [Server-side component rendering](http://reactjs.net/guides/server-side-rendering.html) - to make your initial render super-fast (experimental!) - * [Runs on Linux](http://reactjs.net/guides/mono.html) via Mono and V8 +# Features -Quick Start -=========== -Install the package -``` -Install-Package React.Web.Mvc4 -``` +- On-the-fly [JSX to JavaScript compilation](http://reactjs.net/getting-started/usage.html) via [Babel](http://babeljs.io/) -Create JSX files -```javascript -// /Scripts/HelloWorld.jsx -/** @jsx React.DOM */ -var HelloWorld = React.createClass({ - render: function () { - return ( -
Hello {this.props.name}
- ); - } -}); -``` +* JSX to JavaScript compilation via popular minification/combination + libraries: + - [ASP.NET Bundling and Minification](http://reactjs.net/bundling/weboptimizer.html) + - [Cassette](http://reactjs.net/bundling/cassette.html) + - [Webpack](http://reactjs.net/bundling/webpack.html) + - [MSBuild](http://reactjs.net/bundling/msbuild.html) +* [Server-side component rendering](http://reactjs.net/features/server-side-rendering.html) + to make your initial render super-fast, including support for: + - [CSS-in-JS libraries](https://reactjs.net/features/css-in-js.html) + - [React Router](https://reactjs.net/features/react-router.html) + - [React Helmet](https://reactjs.net/features/react-helmet.html) + - Custom JS logic via implementing [IRenderFunctions](https://github.com/reactjs/React.NET/blob/c93921f059bfe9419ad7094c184979da422a4477/src/React.Core/IRenderFunctions.cs) and passing to [Html.React](https://github.com/reactjs/React.NET/blob/c93921f059bfe9419ad7094c184979da422a4477/src/React.AspNet/HtmlHelperExtensions.cs#L71) +* [Runs on Windows, OS X and Linux](http://reactjs.net/getting-started/chakracore.html) via .NET Core and ChakraCore +* Supports both ASP.NET 4.0/4.5 and ASP.NET Core + +# Quick Start -Reference the JSX files from your HTML -```html - ``` +dotnet new -i React.Template +dotnet new reactnet-vanilla +dotnet run +``` + +#### Planning on using `require` or `import` module syntax in your application? Use the `reactnet-webpack` template instead for webpack support. -Now you can use the `HelloWorld` component. +See also: -For information on more advanced topics (including precompilation and -server-side rendering), check out [the documentation](http://reactjs.net/docs) +- [Getting Started](https://reactjs.net/getting-started/aspnetcore.html) +- [Tutorial](https://reactjs.net/tutorials/aspnetcore.html) -Building Manually and Contributing ----------------------------------- +## Building Manually and Contributing When building your own copy of ReactJS.NET (for example, if implementing a new -feature or fixing a bug), your first build always needs to be done using the -build script (`dev-build.bat`) as this generates a few files required by the -build (such as `SharedAssemblyVersionInfo.cs`). Once this build is completed, +feature or fixing a bug), your first build always needs to be done using the +build script (`dev-build.bat`) as this generates a few files required by the +build (such as `SharedAssemblyVersionInfo.cs`). Once this build is completed, you can open `React.sln` in Visual Studio and compile directly from Visual -Studio. Please refer to the [documentation page on +Studio. Please refer to the [documentation page on contributing](http://reactjs.net/dev/contributing.html) for more information on contributing to ReactJS.NET. + +Note that the build requires you to have Git installed. If you do not want to +install Git, you may remove the `GitVersion` task from `build.proj`. diff --git a/azure-pipelines.yml b/azure-pipelines.yml new file mode 100644 index 000000000..2c176e021 --- /dev/null +++ b/azure-pipelines.yml @@ -0,0 +1,39 @@ +trigger: + - main + - ci-updates + +pool: + vmImage: 'windows-2019' + +variables: + buildPlatform: 'Any CPU' + buildConfiguration: 'Release' + buildType: 'Release' + +steps: + - task: NodeTool@0 + inputs: + versionSpec: '10.x' + + - script: npm install --global npm + + - task: UseDotNet@2 + displayName: 'Use .NET Core sdk' + inputs: + packageType: 'sdk' + version: '3.1.x' + + - task: VSBuild@1 + inputs: + solution: 'build.proj' + msbuildArgs: '/p:PackageOutputDir="$(build.artifactStagingDirectory)"' + platform: '$(buildPlatform)' + configuration: '$(buildConfiguration)' + + - task: DotNetCoreCLI@2 + inputs: + command: 'test' + projects: 'tests/React.Tests/React.Tests.csproj' + arguments: '--no-build --configuration $(buildConfiguration)' + + - task: PublishBuildArtifacts@1 diff --git a/build.proj b/build.proj index a175ac947..afbf537d6 100644 --- a/build.proj +++ b/build.proj @@ -1,6 +1,6 @@ - 1 - 1 - 1 + 5 + 2 + 13 0 http://reactjs.net/packages/ $(MSBuildProjectDirectory)\tools\MSBuildTasks + $(MSBuildProjectDirectory)\output + Dev + src\React.sln - output - + + + + + + + + - + - - - - - + + + + + + + + - + + $(Major).$(Minor).$(Build) + - $(Build)-dev-$(Date) + $(Major).$(Minor).$(Build)-dev-$(Date) + + AssemblyFileVersion="$(VersionString).$(Revision)" + AssemblyInformationalVersion="$(VersionString)" + /> + + + + + + - + + + - - - - + - - + + + + + + + + + + + + + - + - + + + + + + @@ -107,7 +155,7 @@ of patent rights can be found in the PATENTS file in the same directory. @@ -116,4 +164,4 @@ of patent rights can be found in the PATENTS file in the same directory. Command="tools\NuGet\nuget.exe push $(PackageOutputDir)\*.symbols.nupkg -Source $(DevNuGetServer) -NonInteractive" /> - \ No newline at end of file + diff --git a/dev-build-push.bat b/dev-build-push.bat index 59041e18a..68f142d80 100644 --- a/dev-build-push.bat +++ b/dev-build-push.bat @@ -1,3 +1 @@ -@echo off -"%ProgramFiles(x86)%\MSBuild\12.0\Bin\MSBuild.exe" build.proj /t:Package;Push /p:BuildType=Dev -pause \ No newline at end of file +call runs-msbuild.bat "/p:BuildType=Dev" "/t:Package;Push" diff --git a/dev-build.bat b/dev-build.bat index b11d61502..b09ae3031 100644 --- a/dev-build.bat +++ b/dev-build.bat @@ -1,3 +1 @@ -@echo off -"%ProgramFiles(x86)%\MSBuild\12.0\Bin\MSBuild.exe" build.proj /p:BuildType=Dev -pause \ No newline at end of file +call runs-msbuild.bat "/p:BuildType=Dev" diff --git a/lib/Mvc3/System.Web.Mvc.dll b/lib/Mvc3/System.Web.Mvc.dll deleted file mode 100644 index eed0d994a..000000000 Binary files a/lib/Mvc3/System.Web.Mvc.dll and /dev/null differ diff --git a/lib/Mvc3/System.Web.Razor.dll b/lib/Mvc3/System.Web.Razor.dll deleted file mode 100644 index cd950e6d1..000000000 Binary files a/lib/Mvc3/System.Web.Razor.dll and /dev/null differ diff --git a/lib/Mvc3/System.Web.WebPages.Razor.dll b/lib/Mvc3/System.Web.WebPages.Razor.dll deleted file mode 100644 index 9846dd3fc..000000000 Binary files a/lib/Mvc3/System.Web.WebPages.Razor.dll and /dev/null differ diff --git a/lib/Mvc3/System.Web.WebPages.dll b/lib/Mvc3/System.Web.WebPages.dll deleted file mode 100644 index 9fea01285..000000000 Binary files a/lib/Mvc3/System.Web.WebPages.dll and /dev/null differ diff --git a/lib/VroomJs b/lib/VroomJs deleted file mode 160000 index 5f8cc0ec7..000000000 --- a/lib/VroomJs +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 5f8cc0ec7d3c37075ed1b8f233e6de343444d7de diff --git a/lib/VroomJs.dll b/lib/VroomJs.dll deleted file mode 100644 index 2167ac61a..000000000 Binary files a/lib/VroomJs.dll and /dev/null differ diff --git a/lib/build-vroomjs.bat b/lib/build-vroomjs.bat deleted file mode 100644 index 51d905dc0..000000000 --- a/lib/build-vroomjs.bat +++ /dev/null @@ -1,3 +0,0 @@ -@echo off -"%ProgramFiles(x86)%\MSBuild\12.0\Bin\MSBuild.exe" VroomJs\VroomJs\VroomJs.csproj /p:BuildProjectReferences=false /p:Configuration=Release /p:OutputPath=..\..\ /p:SignAssembly=true /p:AssemblyOriginatorKeyFile=..\..\..\src\Key.snk -pause \ No newline at end of file diff --git a/netlify.toml b/netlify.toml new file mode 100644 index 000000000..31296b025 --- /dev/null +++ b/netlify.toml @@ -0,0 +1,65 @@ +[build] + base = "site/jekyll" + publish = "site/jekyll/_site" + command = "bundle exec jekyll build" + +# Shortcuts +[[redirects]] + from = "/download" + to = "/getting-started/download.html" + status = 302 + +[[redirects]] + from = "/docs" + to = "/getting-started/aspnetcore.html" + status = 302 + +# Old documentation URLs +[[redirects]] + from = "/getting-started/aspnet5.html" + to = "/getting-started/aspnetcore.html" + +[[redirects]] + from = "/getting-started/tutorial.html" + to = "/tutorials/aspnetcore.html" + +[[redirects]] + from = "/guides/weboptimizer.html" + to = "/bundling/weboptimizer.html" + +[[redirects]] + from = "/guides/cassette.html" + to = "/bundling/cassette.html" + +[[redirects]] + from = "/guides/webpack.html" + to = "/bundling/webpack.html" + +[[redirects]] + from = "/guides/msbuild.html" + to = "/bundling/msbuild.html" + +[[redirects]] + from = "/guides/server-side-rendering.html" + to = "/features/server-side-rendering.html" + +[[redirects]] + from = "/guides/es6.html" + to = "/features/es6.html" + +[[redirects]] + from = "/guides/react-router.html" + to = "/features/react-router.html" + +[[redirects]] + from = "/guides/chakracore.html" + to = "/getting-started/chakracore.html" + +# Old package URLs +[[redirects]] + from = "/packages/*" + to = "https://ci.appveyor.com/nuget/reactjs.net/:splat" + +[[redirects]] + from = "/dev/packages/*" + to = "https://ci.appveyor.com/nuget/reactjs.net/:splat" diff --git a/release-build-push.bat b/release-build-push.bat index 724c9dc50..9a9f15c34 100644 --- a/release-build-push.bat +++ b/release-build-push.bat @@ -1,3 +1 @@ -@echo off -"%ProgramFiles(x86)%\MSBuild\12.0\Bin\MSBuild.exe" build.proj /t:Package;Push /p:BuildType=Release -pause \ No newline at end of file +call runs-msbuild.bat "/p:BuildType=Release" "/t:Package;Push" diff --git a/release-build.bat b/release-build.bat index 39ae9d306..788e125a5 100644 --- a/release-build.bat +++ b/release-build.bat @@ -1,3 +1 @@ -@echo off -"%ProgramFiles(x86)%\MSBuild\12.0\Bin\MSBuild.exe" build.proj /p:BuildType=Release -pause \ No newline at end of file +call runs-msbuild.bat "/p:BuildType=Release" diff --git a/renovate.json b/renovate.json new file mode 100644 index 000000000..f197b0de8 --- /dev/null +++ b/renovate.json @@ -0,0 +1,39 @@ +{ + "extends": [ + "config:base" + ], + "packageRules": [ + { + "sourceUrlPrefixes": ["https://github.com/Taritsyn/JavaScriptEngineSwitcher"], + "groupName": "JavaScriptEngineSwitcher packages" + }, + { + "sourceUrlPrefixes": ["https://github.com/aspnet/Extensions"], + "groupName": "ASP.NET Extensions" + }, + { + "packagePatterns": ["^Microsoft.AspNetCore"], + "groupName": "ASP.NET Core packages" + }, + { + "packagePatterns": ["^Microsoft.Owin"], + "groupName": "Owin packages" + }, + { + "sourceUrlPrefixes": [ + "https://github.com/aspnet/MetaPackages", + "https://github.com/aspnet/AspNetCore" + ], + "groupName": "ASP.NET Core packages" + }, + { + "packagePatterns": ["^React"], + "groupName": "React.NET packages" + } + ], + "separateMinorPatch": true, + "automerge": false, + "patch": { + "automerge": true + } +} diff --git a/runs-msbuild.bat b/runs-msbuild.bat new file mode 100644 index 000000000..360f79b15 --- /dev/null +++ b/runs-msbuild.bat @@ -0,0 +1,23 @@ +@echo off + +set BUILDTYPE="%~1" +set ACTION="%~2" + +for %%s in ( + "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Community\MSBuild\Current\Bin\MSBuild.exe" + "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\MSBuild.exe" + "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Professional\MSBuild\Current\Bin\MSBuild.exe" + "%ProgramFiles(x86)%\Microsoft Visual Studio\2019\Preview\MSBuild\Current\Bin\MSBuild.exe" +) do ( + if exist %%s ( + echo %%s build.proj %ACTION% %BUILDTYPE% + %%s build.proj %ACTION% %BUILDTYPE% + goto :done + ) +) + +:notfound +echo Could not find MSBuild.exe. Make sure Visual Studio 2019 is installed and try again. + +:done +pause diff --git a/site/build.sh b/site/build.sh new file mode 100755 index 000000000..69fdc556d --- /dev/null +++ b/site/build.sh @@ -0,0 +1,6 @@ +#!/bin/bash +set -ex +cd jekyll +bundle install +bundle exec jekyll build +cd .. diff --git a/site/jekyll/Gemfile b/site/jekyll/Gemfile new file mode 100644 index 000000000..5b8edb617 --- /dev/null +++ b/site/jekyll/Gemfile @@ -0,0 +1,10 @@ +source 'https://rubygems.org' + +gem 'jekyll', '~>1.5.1' +gem 'jekyll-assets', '~>0.9.2' +gem 'bourbon', '~>3' + +# For markdown header cleanup +gem 'sanitize' + +gem 'wdm', '~> 0.1.0' if Gem.win_platform? diff --git a/site/jekyll/Gemfile.lock b/site/jekyll/Gemfile.lock new file mode 100644 index 000000000..60c113656 --- /dev/null +++ b/site/jekyll/Gemfile.lock @@ -0,0 +1,96 @@ +GEM + remote: https://rubygems.org/ + specs: + blankslate (2.1.2.4) + bourbon (3.2.4) + sass (~> 3.2) + thor + classifier (1.3.4) + fast-stemmer (>= 1.0.0) + colorator (0.1) + commander (4.1.6) + highline (~> 1.6.11) + crass (1.0.6) + fast-stemmer (1.0.2) + ffi (1.9.18) + ffi (1.9.18-x64-mingw32) + highline (1.6.21) + hike (1.2.3) + jekyll (1.5.1) + classifier (~> 1.3) + colorator (~> 0.1) + commander (~> 4.1.3) + liquid (~> 2.5.5) + listen (~> 1.3) + maruku (= 0.7.0) + pygments.rb (~> 0.5.0) + redcarpet (~> 2.3.0) + safe_yaml (~> 1.0) + toml (~> 0.1.0) + jekyll-assets (0.9.2) + jekyll (>= 1.0.0, < 3.0.0) + sass (~> 3.2) + sprockets (~> 2.10) + sprockets-helpers + sprockets-sass + liquid (2.5.5) + listen (1.3.1) + rb-fsevent (>= 0.9.3) + rb-inotify (>= 0.9) + rb-kqueue (>= 0.2) + maruku (0.7.0) + mini_portile2 (2.4.0) + multi_json (1.12.1) + nokogiri (1.10.9) + mini_portile2 (~> 2.4.0) + nokogiri (1.10.9-x64-mingw32) + mini_portile2 (~> 2.4.0) + nokogumbo (2.0.2) + nokogiri (~> 1.8, >= 1.8.4) + parslet (1.5.0) + blankslate (~> 2.0) + posix-spawn (0.3.13) + pygments.rb (0.5.4) + posix-spawn (~> 0.3.6) + yajl-ruby (~> 1.1.0) + rack (1.6.12) + rb-fsevent (0.9.8) + rb-inotify (0.9.8) + ffi (>= 0.5.0) + rb-kqueue (0.2.4) + ffi (>= 0.5.0) + redcarpet (2.3.0) + safe_yaml (1.0.4) + sanitize (5.2.1) + crass (~> 1.0.2) + nokogiri (>= 1.8.0) + nokogumbo (~> 2.0) + sass (3.4.23) + sprockets (2.12.4) + hike (~> 1.2) + multi_json (~> 1.0) + rack (~> 1.0) + tilt (~> 1.1, != 1.3.0) + sprockets-helpers (1.2.1) + sprockets (>= 2.2) + sprockets-sass (1.3.1) + sprockets (~> 2.0) + tilt (~> 1.1) + thor (0.19.4) + tilt (1.4.1) + toml (0.1.2) + parslet (~> 1.5.0) + yajl-ruby (1.1.0) + +PLATFORMS + ruby + x64-mingw32 + +DEPENDENCIES + bourbon (~> 3) + jekyll (~> 1.5.1) + jekyll-assets (~> 0.9.2) + sanitize + +BUNDLED WITH + 1.14.5 diff --git a/site/jekyll/_assets/stylesheets/react.scss b/site/jekyll/_assets/stylesheets/react.scss index 35ea0dea3..36ea1f560 100644 --- a/site/jekyll/_assets/stylesheets/react.scss +++ b/site/jekyll/_assets/stylesheets/react.scss @@ -17,7 +17,28 @@ $columnGutter: 40px; $twoColumnWidth: 2 * $columnWidth + $columnGutter; $navHeight: 50px; +// Breakpoints +$bp-large: 960px; +$bp-medium: 640px; +$bp-small: 480px; +@mixin bp-small { + @media (max-width: $bp-small) { + @content; + } +} + +@mixin bp-medium { + @media (max-width: $bp-medium) { + @content; + } +} + +@mixin bp-large { + @media (max-width: $bp-large) { + @content; + } +} // basic reset * { @@ -145,7 +166,6 @@ h1, h2, h3, h4, h5, h6 { } .nav-logo { - @include retina-image('../img/logo_small', 38px 38px); vertical-align: middle; } @@ -765,3 +785,47 @@ div[data-twttr-id] iframe { .three-column > ul:first-child { margin-left: 20px; } + +/* Algolia Doc Search */ + +input#algolia-doc-search { + background: transparent url('../img/search.png') no-repeat 10px center; + background-size: 16px 16px; + + position: relative; + vertical-align: top; + margin-left: 10px; + padding: 0 10px; + padding-left: 35px; + height: 30px; + margin-top: 10px; + font-size: 16px; + line-height: 20px; + background-color: #333; + border-radius: 4px; + color: white; + outline: none; + width: 170px; + + transition: width .2s ease; + + &:focus { + width: 240px; + } + + @include bp-large { + background-color: transparent; + width: 0; + cursor: pointer; + + &:focus { + width: 200px; + background-color: #333; + } + } +} + +.algolia-autocomplete { + vertical-align: top; + height: 53px; +} diff --git a/site/jekyll/_config.yml b/site/jekyll/_config.yml index c7ff9a184..7f32721e7 100644 --- a/site/jekyll/_config.yml +++ b/site/jekyll/_config.yml @@ -4,13 +4,19 @@ pygments: true permalink: /:year/:month/:title.html paginate: 5 paginate_path: /blog/page:num.html -url: http://reactjs.net +url: https://reactjs.net doc-sections: - - id: getting-started - title: Getting Started - - id: guides - title: Guides - - id: dev - title: Development + - id: getting-started + title: 'Getting Started' + - id: tutorials + title: Tutorials + - id: features + title: Features + - id: bundling + title: Bundling + - id: dev + title: Development + +title: Development assets: - css_compressor: sass + css_compressor: sass diff --git a/site/jekyll/_layouts/default.html b/site/jekyll/_layouts/default.html index 1d821026d..d59c8b506 100644 --- a/site/jekyll/_layouts/default.html +++ b/site/jekyll/_layouts/default.html @@ -9,14 +9,15 @@ - + - + {% stylesheet main %} + @@ -38,8 +39,10 @@ - + + - + ``` The server-rendered HTML will automatically be reused by React client-side, meaning your initial render will be super fast. +If you encounter any errors with the JavaScript, you may want to temporarily disable server-side rendering in order to debug your components in your browser. You can do this by calling `DisableServerSideRendering()` in your ReactJS.NET config. + For a more in-depth example, take a look at the included sample application (**React.Samples.Mvc4**). + +5 - Server-side only rendering + +If there is no need to have a React application client side and you just want to use the server side rendering but without the React specific data attributes, call `Html.React` and pass serverOnly parameter as true. + +```csharp +@Html.React("HelloWorld", new +{ + name = "Daniel" +}, serverOnly: true) +``` + +And the HTML will look like the one following which is a lot cleaner. In this case there is no need to load the React script or call the `Html.ReactInitJavaScript()` method. + +```html +
+
+ Hello + Daniel +
+
+``` diff --git a/site/jekyll/features/typescript.md b/site/jekyll/features/typescript.md new file mode 100644 index 000000000..1668e8d60 --- /dev/null +++ b/site/jekyll/features/typescript.md @@ -0,0 +1,44 @@ +--- +layout: docs +title: Typescript compilation +--- + +Just want to see the code? Check out the [sample project](https://github.com/reactjs/React.NET/tree/main/src/React.Sample.Mvc4). + +Typescript is a library for writing type-safe Javascript. Starting with version 5, ReactJS.NET supports stripping out type definitions from `.TS` and .`TSX` files, powered by Babel. + +Note that just using the library will compile your Typescript to Javascript, but will _not_ warn you about code that does not type check. To set up type checking in your project during the build: + +1. Install a supported version of [Node](https://nodejs.org/en/download/) (either LTS or Current is fine) +1. Create an empty `package.json` to your project root by running `npm init`. Optionally fill out the questions asked by `npm`, or press Enter to accept the defaults. +1. Run `npm i typescript --save-dev`, which will update the freshly generated `package.json`. It's important that the Typescript version is declared in this file so every developer on your project has the same type checking rules. +1. Copy the [tsconfig.json](https://github.com/reactjs/react.net/blob/main/src/React.Sample.Mvc4/tsconfig.json) file from the Mvc sample to your project root. If your components are not located in `Content`, change that path to the appropriate directory. +1. Typescript needs to be informed of the libraries available on the global scope. To do this, create [types/index.d.ts](https://github.com/reactjs/react.net/blob/main/src/React.Sample.Mvc4/types/index.d.ts) in your project root: + +```ts +import _React from 'react'; +import _PropTypes from 'prop-types'; // @types/prop-types is a dependency of `@types/react` +import _Reactstrap from 'reactstrap'; // Third party library example + +declare global { + const React: typeof _React; // the React types _also_ exported by the React namespace, but export them again here just in case. + const PropTypes: typeof _PropTypes; + const Reactstrap: typeof _Reactstrap; +} +``` + +Libraries imported in `types/index.d.ts` must be listed in `package.json` before typescript will load their type definitions. Types for `react` are defined by the `@types/react` library in the [DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/main/types/react) repo, so install the types package with `npm i --save-dev @types/react`. Sometimes libraries will ship with typescript support; if so, install the package directly via `npm i --save-dev ` to make the types resolve. If a library you're using does not ship with types, chances are there will be community-provided types in DefinitelyTyped. + +To check that everything works at this point, run `node_modules/.bin/tsc` from your project's working directory. You'll see empty output from `tsc` if the type checking succeeds. + +Finally, add a compile-time step to your project file to get type checking with every Visual Studio build (works in both ASP.NET and .NET Core): + +```xml + + + +``` + +You're done! Introduce a type error in your project to verify things are working as expected. For example, you will see a message similar to `6>C:\code\react.net\src\React.Sample.Mvc4\Content/Sample.tsx(27,19): error TS2551: Property 'initialCommentss' does not exist on type 'CommentsBoxProps'. Did you mean 'initialComments'?` + +Check out the [sample project](https://github.com/reactjs/React.NET/tree/main/src/React.Sample.Mvc4) for the completed integration. diff --git a/site/jekyll/getting-started/aspnet.md b/site/jekyll/getting-started/aspnet.md new file mode 100644 index 000000000..3c6ca685e --- /dev/null +++ b/site/jekyll/getting-started/aspnet.md @@ -0,0 +1,61 @@ +--- +id: aspnet +layout: docs +title: Getting Started (ASP.NET 4.x) +--- + +#### 👀 Just want to see the code? Check out the [sample project](https://github.com/reactjs/React.NET/tree/main/src/React.Sample.Mvc4). + +This guide covers enabling server-side rendering and Babel compilation. If you want a step-by-step guide on configuring a brand new site, see [the ReactJS.NET tutorial for ASP.NET](/tutorials/aspnet4.html). + +ReactJS.NET requires Visual Studio 2015 and MVC 4 or 5. + +Install the `React.Web.Mvc4` package through NuGet. You will also need to install a JS engine to use (either V8 or ChakraCore are recommended). See the [JSEngineSwitcher docs](https://github.com/Taritsyn/JavaScriptEngineSwitcher/wiki/Registration-of-JS-engines) for more information. + +To use V8, add the following packages: + +``` +JavaScriptEngineSwitcher.V8 +JavaScriptEngineSwitcher.V8.Native.win-x64 +``` + +`ReactConfig.cs` will be automatically generated for you. Update it to register a JS engine and your JSX files: + +```csharp +using JavaScriptEngineSwitcher.Core; +using JavaScriptEngineSwitcher.V8; + +[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(React.Sample.Mvc4.ReactConfig), "Configure")] + +namespace React.Sample.Mvc4 +{ + public static class ReactConfig + { + public static void Configure() + { + ReactSiteConfiguration.Configuration + .AddScript("~/Content/Sample.jsx"); + + JsEngineSwitcher.Current.DefaultEngineName = V8JsEngine.EngineName; + JsEngineSwitcher.Current.EngineFactories.AddV8(); + } + } +} +``` + +Reference JSX files directly in script tags at the end of the page: + +```html + +@Html.ReactInitJavaScript(); +``` + +You're done! You can now call `Html.React` from within Razor files: + +``` +@Html.React("Sample", new { initialComments = Model.Comments, page = Model.Page }) +``` + +You can also use [webpack](/guides/webpack.html) or [System.Web.Optimization](/guides/weboptimizer.html) to bundle your scripts together. + +Check out the [sample project](https://github.com/reactjs/React.NET/tree/main/src/React.Sample.Mvc4) for a working demo. diff --git a/site/jekyll/getting-started/aspnetcore.md b/site/jekyll/getting-started/aspnetcore.md new file mode 100644 index 000000000..9e2626e39 --- /dev/null +++ b/site/jekyll/getting-started/aspnetcore.md @@ -0,0 +1,105 @@ +--- +id: aspnetcore +layout: docs +title: Getting Started (ASP.NET Core) +--- + +#### 👀 Just want to see the code? Check out the [sample project](https://github.com/reactjs/React.NET/tree/main/src/React.Template/reactnet-webpack). + +## For new projects: + +``` +dotnet new -i React.Template +dotnet new reactnet-vanilla +dotnet run +``` + +#### Heads up! This configuration only supports globally-scoped modules. If you're planning on using `require` or `import` module syntax in your application, use the `reactnet-webpack` template instead for webpack support. + +## For existing projects: + +This guide covers enabling server-side rendering and Babel compilation. Getting started with ReactJS.NET on ASP.NET Core requires a few more steps compared to previous versions of ASP.NET and MVC. If you want a step-by-step guide on configuring a brand new site, see [the ReactJS.NET tutorial for ASP.NET Core](/tutorials/aspnetcore.html). + +ReactJS.NET requires at least Visual Studio 2015 and ASP.NET Core 1.0, but has also been tested with VS 2017 and .NET Core 2.1. + +Install the `React.AspNet` package through NuGet. You will also need to install a JS engine to use (either V8 or ChakraCore are recommended) and `JavaScriptEngineSwitcher.Extensions.MsDependencyInjection` package. See the [JSEngineSwitcher docs](https://github.com/Taritsyn/JavaScriptEngineSwitcher/wiki/Registration-of-JS-engines) for more information. After these packages are installed, ReactJS.NET needs to be initialised in your `Startup.cs` file (unfortunately this can not be done automatically like in previous versions of ASP.NET with WebActivator). + +At the top of Startup.cs, add: + +``` +using Microsoft.AspNetCore.Http; +using JavaScriptEngineSwitcher.ChakraCore; +using JavaScriptEngineSwitcher.Extensions.MsDependencyInjection; +using React.AspNet; +``` + +Directly above: + +```csharp +// Add framework services. +services.AddMvc(); +``` + +Add: + +```csharp +services.AddSingleton(); +services.AddReact(); + +// Make sure a JS engine is registered, or you will get an error! +services.AddJsEngineSwitcher(options => options.DefaultEngineName = ChakraCoreJsEngine.EngineName) + .AddChakraCore(); +``` + +Directly **above**: + +```csharp +app.UseStaticFiles(); +``` + +Add: + +```csharp +// Initialise ReactJS.NET. Must be before static files. +app.UseReact(config => +{ + // If you want to use server-side rendering of React components, + // add all the necessary JavaScript files here. This includes + // your components as well as all of their dependencies. + // See http://reactjs.net/ for more information. Example: + //config + // .AddScript("~/js/First.jsx") + // .AddScript("~/js/Second.jsx"); + + // If you use an external build too (for example, Babel, Webpack, + // Browserify or Gulp), you can improve performance by disabling + // ReactJS.NET's version of Babel and loading the pre-transpiled + // scripts. Example: + //config + // .SetLoadBabel(false) + // .AddScriptWithoutTransform("~/Scripts/bundle.server.js"); +}); +``` + +Finally, add this to `Views\_ViewImports.cshtml` (or create it if it doesn't exist): + +```csharp +@using React.AspNet +``` + +Reference JSX files directly in script tags at the end of the page: + +```html + +@Html.ReactInitJavaScript(); +``` + +You're done! You can now call `Html.React` from within Razor files: + +``` +@Html.React("Sample", new { initialComments = Model.Comments, page = Model.Page }) +``` + +If you need support for non-Windows platforms, please see the [Linux/macOS guide](/getting-started/chakracore.html) + +Check out the [sample project](https://github.com/reactjs/React.NET/tree/main/src/React.Template/reactnet-webpack) for a working demo. diff --git a/site/jekyll/getting-started/chakracore.md b/site/jekyll/getting-started/chakracore.md new file mode 100644 index 000000000..0bde5940a --- /dev/null +++ b/site/jekyll/getting-started/chakracore.md @@ -0,0 +1,44 @@ +--- +layout: docs +title: macOS/Linux +--- + +ReactJS.NET supports running on non-Windows platforms via both Mono and .NET Core. This guide focuses on Linux / macOS support via the ChakraCore engine and .NET Core, which uses precompiled binaries. To use the full .NET Framework with Mono, please see the [Mono guide](/guides/mono.html). + +Add `React.AspNet` as a dependency to your .NET Core project. Check out the [sample project](https://github.com/reactjs/React.NET/tree/main/src/React.Template/reactnet-webpack) or the [documentation](https://reactjs.net/getting-started/aspnetcore.html) if you need more details on that. + +Next, install the `JavascriptEngineSwitcher.ChakraCore` and `JavaScriptEngineSwitcher.Extensions.MsDependencyInjection` NuGet packages. Depending on the platform(s) you want to support, also install one or more of these NuGet packages: + +- Windows: `JavaScriptEngineSwitcher.ChakraCore.Native.win-x64`. The VC++ 2017 runtime is also required. +- OS X: ``JavaScriptEngineSwitcher.ChakraCore.Native.osx-x64` +- Linux x64: ``JavaScriptEngineSwitcher.ChakraCore.Native.linux-x64` + +In `Startup.cs`, set ChakraCore as the default Javascript engine. + +```csharp +using JavaScriptEngineSwitcher.ChakraCore; +using JavaScriptEngineSwitcher.Extensions.MsDependencyInjection; + +public void ConfigureServices(IServiceCollection services) +{ + services.AddJsEngineSwitcher(options => options.DefaultEngineName = ChakraCoreJsEngine.EngineName) + .AddChakraCore(); + + // existing services below: + services.AddSingleton(); + services.AddReact(); + services.AddMvc(); +} +``` + +You're done! Server-side rendering and JSX compilation should now be working properly. + +For more information about registering Javascript engines, check out the [JavascriptEngineSwitcher documentation](https://github.com/Taritsyn/JavaScriptEngineSwitcher/wiki/Registration-of-JS-engines). + +### Mono + +While Mono is supported, we strongly recommend using .NET Core instead. + +To use ReactJS.NET with Mono, follow the documentation on the [JavaScriptEngineSwitcher repo](https://github.com/Taritsyn/JavaScriptEngineSwitcher/wiki/ChakraCore#mono-support) to install ChakraCore, and then register the JS Engine as the default in `Startup.cs` or `ReactConfig.cs`. + +If ChakraCore fails to load, you will see an exception when your application is started. If this happens, run Mono with the `MONO_LOG_LEVEL=debug` environment variable to get more useful debugging information. diff --git a/site/jekyll/getting-started/download.md b/site/jekyll/getting-started/download.md index 82ac79c74..15423242e 100644 --- a/site/jekyll/getting-started/download.md +++ b/site/jekyll/getting-started/download.md @@ -4,31 +4,30 @@ layout: docs title: Downloading and Installing --- -Release Versions ----------------- +## Release Versions + The best way to install ReactJS.NET is via NuGet. There are several NuGet packages available: - * [React.Core](https://www.nuget.org/packages/React.Core/) - The core React library. Contains the main functionality of - React and JSX. You will normally use this through an integration library - like React.Mvc4. - * [React.Web.Mvc4](https://www.nuget.org/packages/React.Web.Mvc4/) - Integration with ASP.NET MVC 4 and 5. - * [React.Web.Mvc3](https://www.nuget.org/packages/React.Web.Mvc3/) - Integration with ASP.NET MVC 3. - * [React.JavaScriptEngine.VroomJs](https://www.nuget.org/packages/React.JavaScriptEngine.VroomJs/) - Support for Mono (Linux) via Google's V8 engine - * [Cassette.React](https://www.nuget.org/packages/Cassette.React/) - Integration with [Cassette](http://getcassette.net/). The recommended way to combine and minify your JavaScript. - * [System.Web.Optimization.React](https://www.nuget.org/packages/System.Web.Optimization.React/) - Integration with - [ASP.NET Bundling and Minification](http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification). +- [React.Core](https://www.nuget.org/packages/React.Core/) - The core React library. Contains the main functionality of + React and JSX. You will normally use this through an integration library + like React.Mvc4. +- [React.Web.Mvc4](https://www.nuget.org/packages/React.Web.Mvc4/) - Integration with ASP.NET MVC 4 and 5. +- [React.AspNet](https://www.nuget.org/packages/React.AspNet/) - Integration with ASP.NET Core. [Learn more about ASP.NET 5 support](/getting-started/aspnetcore.html) +- [Cassette.React](https://www.nuget.org/packages/Cassette.React/) - Integration with [Cassette](http://getcassette.net/). The recommended way to combine and minify your JavaScript. +- [System.Web.Optimization.React](https://www.nuget.org/packages/System.Web.Optimization.React/) - Integration with + [ASP.NET Bundling and Minification](http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification). These packages can be installed either via the [UI in Visual Studio](https://docs.nuget.org/docs/start-here/managing-nuget-packages-using-the-dialog), or via the Package Manager Console: ``` -Install-Package React.Web.Mvc4 +Install-Package React.AspNet ``` -Development Builds ------------------- +## Development Builds + Development builds are automatically built after every change. Use these if you want the very latest bleeding-edge version. These are located on a [custom package server](http://reactjs.net/packages/) so you need to add this as a @@ -41,17 +40,16 @@ package source in Visual Studio: 4. When adding the packages to your application, manually select "ReactJS.NET Dev" as the package source, and ensure "Include Prerelease" is enabled. -Building Manually ------------------ +## Building Manually To build your own copy of ReactJS.NET (for example, if implementing a new feature or fixing a bug): -1. Compile ReactJS.NET by running `build.bat` +1. Compile ReactJS.NET by running `dev-build.bat` 2. Reference React.dll and React.Mvc4.dll (if using MVC 4) in your Web Application project -Your first build always needs to be done using the build script (build.bat) as +Your first build always needs to be done using the build script (`dev-build.bat`) as this generates a few files required by the build (such as `SharedAssemblyVersionInfo.cs`). Once this build is completed, you can open `React.sln` in Visual Studio and compile directly from Visual Studio. diff --git a/site/jekyll/getting-started/tutorial.md b/site/jekyll/getting-started/tutorial.md deleted file mode 100644 index 749a277c3..000000000 --- a/site/jekyll/getting-started/tutorial.md +++ /dev/null @@ -1,1009 +0,0 @@ ---- -id: tutorial -title: Tutorial -layout: docs ---- - -This tutorial covers the end-to-end process of creating a brand new ASP.NET MVC website and adding a React component in it. We will start from scratch and end with a fully functioning component. It assumes you have basic knowledge of ASP.NET MVC and using Visual Studio. This tutorial is based off the [original React tutorial](http://facebook.github.io/react/docs/tutorial.html) but has been modified specifically for ReactJS.NET. - -We'll be building a simple, but realistic comments box that you can drop into a blog, a basic version of the realtime comments offered by Disqus, LiveFyre or Facebook comments. - -We'll provide: - -* A view of all of the comments -* A form to submit a comment -* Simple server-side in-memory storage for comments - -It'll also have a few neat features: - -* **Optimistic commenting:** comments appear in the list before they're saved on the server so it feels fast. -* **Live updates:** as other users comment we'll pop them into the comment view in real time -* **Markdown formatting:** users can use Markdown to format their text - -## Getting started - -For this tutorial we'll be using Visual Studio 2013, although any version of Visual Studio from 2010 onwards is fine, including [Visual Studio Express 2013](http://www.visualstudio.com/en-us/products/visual-studio-express-vs.aspx) which is completely free. We will be using ASP.NET MVC 4, although similar steps apply for ASP.NET MVC 5. - -### New Project - -Start by creating a new ASP.NET MVC 4 project: - -1. File → New → Project -2. Select ".NET Framework 4" and Templates → Visual C# → Web → ASP.NET MVC 4 Web Application. Call it "ReactDemo" - Screenshot: New Project -3. In the "New ASP.NET MVC 4 Project" dialog, select the Empty template. I always recommend using this template for new sites, as the others include a large amount of third-party packages that you may not even use. - Screenshot: New ASP.NET MVC 4 Project dialog - -### Install ReactJS.NET - -We need to install ReactJS.NET to the newly-created project. This is accomplished using NuGet, a package manager for .NET. Right-click on the "ReactDemo" project in the Solution Explorer and select "Manage NuGet Packages". Search for "ReactJS.NET" and install the **ReactJS.NET (MVC 4 and 5)** package. - -Screenshot: Install NuGet Packages - -### Create basic controller and view - -Since this tutorial focuses mainly on ReactJS.NET itself, we will not cover creation of an MVC controller in much detail. To learn more about ASP.NET MVC, refer to [its official website](http://www.asp.net/mvc). - -Right-click on the Controllers folder and click Add → Controller. Name the controller "HomeController" and select "Empty MVC Controller" as the template. Once the controller has been created, right-click on `return View()` and click "Add View". Enter the following details: - - - View name: Index - - View Engine: Razor (CSHTML) - - Create a strongly-typed view: Unticked - - Create as a partial view: Unticked - - Use a layout or master page: Unticked - -*Note: In a real ASP.NET MVC site, you'd use a layout. However, to keep this tutorial simple, we will keep all HTML in the one view file.* - -Replace the contents of the new view file with the following: - -```html -@{ - Layout = null; -} - - - Hello React - - -
- - - - -``` - -We also need to create the referenced JavaScript file (`Tutorial.jsx`). Right-click on ReactDemo project, select Add → New Folder, and enter "Scripts" as the folder name. Once created, right-click on the folder and select Add → New Item. Select Web → JavaScript File, enter "Tutorial.jsx" as the file name, and click "Add". - -For the remainder of this tutorial, we'll be writing our JavaScript code in this file. - -### Your first component - -React is all about modular, composable components. For our comment box example, we'll have the following component structure: - -``` -- CommentBox - - CommentList - - Comment - - CommentForm -``` - -Let's build the `CommentBox` component, which is just a simple `
`. Add this code to `Tutorial.jsx`: - -```javascript -/** @jsx React.DOM */ -var CommentBox = React.createClass({ - render: function() { - return ( -
- Hello, world! I am a CommentBox. -
- ); - } -}); -React.renderComponent( - , - document.getElementById('content') -); -``` - -At this point, run your application by clicking the "Play" button in Visual Studio. If successful, your default browser should start and you should see "Hello, world! I am a CommentBox." - -Screenshot: Hello ReactJS.NET World! - -If you see this, congratulations! You've just built your first React component. You can leave the application running while you continue this tutorial. Simply change the JSX file and refresh to see your changes. - -#### JSX Syntax - -The first thing you'll notice is the XML-ish syntax in your JavaScript. We have a simple precompiler that translates the syntactic sugar to this plain JavaScript: - -```javascript -// tutorial1-raw.js -var CommentBox = React.createClass({ - render: function() { - return ( - React.DOM.div({ - className: 'commentBox', - children: 'Hello, world! I am a CommentBox.' - }) - ); - } -}); -React.renderComponent( - CommentBox({}), - document.getElementById('content') -); -``` - -Its use is optional but we've found JSX syntax easier to use than plain JavaScript. Read more on the [JSX Syntax article](http://facebook.github.io/react/docs/jsx-in-depth.html). - -#### What's going on - -We pass some methods in a JavaScript object to `React.createClass()` to create a new React component. The most important of these methods is called `render` which returns a tree of React components that will eventually render to HTML. - -The `
` tags are not actual DOM nodes; they are instantiations of React `div` components. You can think of these as markers or pieces of data that React knows how to handle. React is **safe**. We are not generating HTML strings so XSS protection is the default. - -You do not have to return basic HTML. You can return a tree of components that you (or someone else) built. This is what makes React **composable**: a key tenet of maintainable frontends. - -`React.renderComponent()` instantiates the root component, starts the framework, and injects the markup into a raw DOM element, provided as the second argument. - -## Composing components - -Let's build skeletons for `CommentList` and `CommentForm` which will, again, be simple `
`s: - -```javascript -var CommentList = React.createClass({ - render: function() { - return ( -
- Hello, world! I am a CommentList. -
- ); - } -}); - -var CommentForm = React.createClass({ - render: function() { - return ( -
- Hello, world! I am a CommentForm. -
- ); - } -}); -``` - -Next, update the `CommentBox` component to use its new friends: - -```javascript{5-7} -var CommentBox = React.createClass({ - render: function() { - return ( -
-

Comments

- - -
- ); - } -}); -``` - -Notice how we're mixing HTML tags and components we've built. HTML components are regular React components, just like the ones you define, with one difference. The JSX compiler will automatically rewrite HTML tags to "React.DOM.tagName" expressions and leave everything else alone. This is to prevent the pollution of the global namespace. - -### Component Properties - -Let's create our third component, `Comment`. We will want to pass it the author name and comment text so we can reuse the same code for each unique comment. First let's add some comments to the `CommentList`: - -```javascript{5-7} -var CommentList = React.createClass({ - render: function() { - return ( -
- Hello ReactJS.NET World! - This is one comment - This is *another* comment -
- ); - } -}); -``` - -Note that we have passed some data from the parent `CommentList` component to the child `Comment` component as both XML-like children and attributes. Data passed from parent to child is called **props**, short for properties. - -### Using props - -Let's create the Comment component. It will read the data passed to it from the CommentList and render some markup: - -```javascript -var Comment = React.createClass({ - render: function() { - return ( -
-

- {this.props.author} -

- {this.props.children} -
- ); - } -}); -``` - -By surrounding a JavaScript expression in braces inside JSX (as either an attribute or child), you can drop text or React components into the tree. We access named attributes passed to the component as keys on `this.props` and any nested elements as `this.props.children`. - - -### Adding Markdown - -Markdown is a simple way to format your text inline. For example, surrounding text with asterisks will make it emphasized. - -First, add the third-party **Showdown** library to your application. This is a JavaScript library which takes Markdown text and converts it to raw HTML. We will add it via NuGet (search for "Showdown" and install it, similar to how you installed ReactJS.NET earlier) and reference the script tag in your view: - -```html{2} - - - -``` - -Next, let's convert the comment text to Markdown and output it: - -```javascript{1,9} -var converter = new Showdown.converter(); -var Comment = React.createClass({ - render: function() { - return ( -
-

- {this.props.author} -

- {converter.makeHtml(this.props.children.toString())} -
- ); - } -}); -``` - -All we're doing here is calling the Showdown library. We need to convert `this.props.children` from React's wrapped text to a raw string that Showdown will understand so we explicitly call `toString()`. - -But there's a problem! Our rendered comments look like this in the browser: "`

`This is ``another`` comment`

`". We want those tags to actually render as HTML. - -That's React protecting you from an XSS attack. There's a way to get around it but the framework warns you not to use it: - -```javascript{4,10} -var converter = new Showdown.converter(); -var Comment = React.createClass({ - render: function() { - var rawMarkup = converter.makeHtml(this.props.children.toString()); - return ( -
-

- {this.props.author} -

- -
- ); - } -}); -``` - -This is a special API that intentionally makes it difficult to insert raw HTML, but for Showdown we'll take advantage of this backdoor. - -**Remember:** by using this feature you're relying on Showdown to be secure. - -### Hook up the data model - -So far we've been inserting the comments directly in the source code. Instead, let's render a blob of JSON data into the comment list. Eventually this will come from the server, but for now, write it in your source: - -```javascript -var data = [ - { Author: "Daniel Lo Nigro", Text: "Hello ReactJS.NET World!" }, - { Author: "Pete Hunt", Text: "This is one comment" }, - { Author: "Jordan Walke", Text: "This is *another* comment" } -]; -``` - -We need to get this data into `CommentList` in a modular way. Modify `CommentBox` and the `renderComponent()` call to pass this data into the `CommentList` via props: - -```javascript{6,14} -var CommentBox = React.createClass({ - render: function() { - return ( -
-

Comments

- - -
- ); - } -}); - -React.renderComponent( - , - document.getElementById('content') -); -``` - -Now that the data is available in the `CommentList`, let's render the comments dynamically: - -```javascript{3-5,8} -var CommentList = React.createClass({ - render: function() { - var commentNodes = this.props.data.map(function (comment) { - return {comment.Text}; - }); - return ( -
- {commentNodes} -
- ); - } -}); -``` - -That's it! - -### Server-side Data - -Let's return some data from the server. To do so, we need to first create a C# class to represent our comments. Right-click on the Models folder (which should be empty), select Add → Class, and enter "CommentModel.cs" as the file name. We'll create a basic comment model: - -```csharp -namespace ReactDemo.Models -{ - public class CommentModel - { - public string Author { get; set; } - public string Text { get; set; } - } -} -``` - -In a real application, you'd use the repository pattern here, and retrieve the comments from a database. For simplicity, we'll just modify our controller to have a hard-coded list of comments. - -```csharp{9,13-30} -using System.Collections.Generic; -using System.Web.Mvc; -using ReactDemo.Models; - -namespace ReactDemo.Controllers -{ - public class HomeController : Controller - { - private static readonly IList _comments; - - static HomeController() - { - _comments = new List - { - new CommentModel - { - Author = "Daniel Lo Nigro", - Text = "Hello ReactJS.NET World!" - }, - new CommentModel - { - Author = "Pete Hunt", - Text = "This is one comment" - }, - new CommentModel - { - Author = "Jordan Walke", - Text = "This is *another* comment" - }, - }; - } - - public ActionResult Index() - { - return View(); - } - } -} -``` - -Let's also add a new controller action to return the list of comments: - -```csharp -public ActionResult Comments() -{ - return Json(_comments, JsonRequestBehavior.AllowGet); -} -``` - -And a corresponding route in `App_Start\RouteConfig.cs`: - -```csharp{12-16} -using System.Web.Mvc; -using System.Web.Routing; - -namespace ReactDemo -{ - public class RouteConfig - { - public static void RegisterRoutes(RouteCollection routes) - { - routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); - - routes.MapRoute( - name: "Comments", - url: "comments", - defaults: new { controller = "Home", action = "Comments" } - ); - - routes.MapRoute( - name: "Default", - url: "{controller}/{action}/{id}", - defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } - ); - } - } -} -``` - -If you hit `/comments` in your browser, you should now see the data encoded as JSON: - -Screenshot: JSON data source - -### Fetching from the server - -Now that we have a data source, we can replace the hard-coded data with the dynamic data from the server. We will remove the data prop and replace it with a URL to fetch: - -```javascript{2} -React.renderComponent( - , - document.getElementById('content') -); -``` - -This component is different from the prior components because it will have to re-render itself. The component won't have any data until the request from the server comes back, at which point the component may need to render some new comments. - -### Reactive state - -So far, each component has rendered itself once based on its props. `props` are immutable: they are passed from the parent and are "owned" by the parent. To implement interactions, we introduce mutable **state** to the component. `this.state` is private to the component and can be changed by calling `this.setState()`. When the state is updated, the component re-renders itself. - -`render()` methods are written declaratively as functions of `this.props` and `this.state`. The framework guarantees the UI is always consistent with the inputs. - -When the server fetches data, we will be changing the comment data we have. Let's add an array of comment data to the `CommentBox` component as its state: - -```javascript{2-4,9} -var CommentBox = React.createClass({ - getInitialState: function() { - return {data: []}; - }, - render: function() { - return ( -
-

Comments

- - -
- ); - } -}); -``` - -`getInitialState()` executes exactly once during the lifecycle of the component and sets up the initial state of the component. - -#### Updating state -When the component is first created, we want to GET some JSON from the server and update the state to reflect the latest data. We'll use the standard XMLHttpRequest API to retrieve the data. If you need support for old browsers (mainly old Internet Explorer), you can use an AJAX library or a multipurpose library such as jQuery. - -```javascript{6-12} -var CommentBox = React.createClass({ - getInitialState: function() { - return {data: []}; - }, - componentWillMount: function() { - var xhr = new XMLHttpRequest(); - xhr.open('get', this.props.url, true); - xhr.onload = function() { - var data = JSON.parse(xhr.responseText); - this.setState({ data: data }); - }.bind(this); - xhr.send(); - }, - render: function() { - return ( -
-

Comments

- - -
- ); - } -}); -``` - -Here, `componentWillMount` is a method called automatically by React before a component is rendered. The key to dynamic updates is the call to `this.setState()`. We replace the old array of comments with the new one from the server and the UI automatically updates itself. Because of this reactivity, it is only a minor change to add live updates. We will use simple polling here but you could easily use [SignalR](http://signalr.net/) or other technologies. - -```javascript{2,15-16,30} -var CommentBox = React.createClass({ - loadCommentsFromServer: function() { - var xhr = new XMLHttpRequest(); - xhr.open('get', this.props.url, true); - xhr.onload = function() { - var data = JSON.parse(xhr.responseText); - this.setState({ data: data }); - }.bind(this); - xhr.send(); - }, - getInitialState: function() { - return {data: []}; - }, - componentWillMount: function() { - this.loadCommentsFromServer(); - window.setInterval(this.loadCommentsFromServer, this.props.pollInterval); - }, - render: function() { - return ( -
-

Comments

- - -
- ); - } -}); - -React.renderComponent( - , - document.getElementById('content') -); -``` - -All we have done here is move the AJAX call to a separate method and call it when the component is first loaded and every 2 seconds after that. - -### Adding new comments - -To accept new comments, we need to first add a controller action to handle it. This will just be some simple C# code that appends the new comment to the static list of comments: - -```csharp -[HttpPost] -public ActionResult AddComment(CommentModel comment) -{ - _comments.Add(comment); - return Content("Success :)"); -} -``` -Let's also add it to the `App_Start\RouteConfig.cs` file, like we did earlier for the comments list: - -```csharp -routes.MapRoute( - name: "NewComment", - url: "comments/new", - defaults: new { controller = "Home", action = "AddComment" } -); - -``` - -#### The Form - -Now it's time to build the form. Our `CommentForm` component should ask the user for their name and comment text and send a request to the server to save the comment. - -```javascript{4-8} -var CommentForm = React.createClass({ - render: function() { - return ( -
- - - -
- ); - } -}); -``` - -Let's make the form interactive. When the user submits the form, we should clear it, submit a request to the server, and refresh the list of comments. To start, let's listen for the form's submit event and clear it. - -```javascript{2-12,15-16,20} -var CommentForm = React.createClass({ - handleSubmit: function() { - var author = this.refs.author.getDOMNode().value.trim(); - var text = this.refs.text.getDOMNode().value.trim(); - if (!text || !author) { - return false; - } - // TODO: send request to the server - this.refs.author.getDOMNode().value = ''; - this.refs.text.getDOMNode().value = ''; - return false; - }, - render: function() { - return ( -
- - - -
- ); - } -}); -``` - -##### Events - -React attaches event handlers to components using a camelCase naming convention. We attach an `onSubmit` handler to the form that clears the form fields when the form is submitted with valid input. - -We always return `false` from the event handler to prevent the browser's default action of submitting the form. (If you prefer, you can instead take the event as an argument and call `preventDefault()` on it.) - -##### Refs - -We use the `ref` attribute to assign a name to a child component and `this.refs` to reference the component. We can call `getDOMNode()` on a component to get the native browser DOM element. - -##### Callbacks as props - -When a user submits a comment, we will need to refresh the list of comments to include the new one. It makes sense to do all of this logic in `CommentBox` since `CommentBox` owns the state that represents the list of comments. - -We need to pass data from the child component to its parent. We do this by passing a `callback` in props from parent to child: - -```javascript{11-13,27} -var CommentBox = React.createClass({ - loadCommentsFromServer: function() { - var xhr = new XMLHttpRequest(); - xhr.open('get', this.props.url, true); - xhr.onload = function() { - var data = JSON.parse(xhr.responseText); - this.setState({ data: data }); - }.bind(this); - xhr.send(); - }, - handleCommentSubmit: function(comment) { - // TODO: submit to the server and refresh the list - }, - getInitialState: function() { - return {data: []}; - }, - componentWillMount: function() { - this.loadCommentsFromServer(); - window.setInterval(this.loadCommentsFromServer, this.props.pollInterval); - }, - render: function() { - return ( -
-

Comments

- - -
- ); - } -}); -``` - -Let's call the callback from the `CommentForm` when the user submits the form: - -```javascript{8} -var CommentForm = React.createClass({ - handleSubmit: function() { - var author = this.refs.author.getDOMNode().value.trim(); - var text = this.refs.text.getDOMNode().value.trim(); - if (!text || !author) { - return false; - } - this.props.onCommentSubmit({author: author, text: text}); - this.refs.author.getDOMNode().value = ''; - this.refs.text.getDOMNode().value = ''; - return false; - }, - render: function() { - return ( -
- - - -
- ); - } -}); -``` - -Now that the callbacks are in place, all we have to do is submit to the server and refresh the list: - -```javascript{12-21,44} -var CommentBox = React.createClass({ - loadCommentsFromServer: function() { - var xhr = new XMLHttpRequest(); - xhr.open('get', this.props.url, true); - xhr.onload = function() { - var data = JSON.parse(xhr.responseText); - this.setState({ data: data }); - }.bind(this); - xhr.send(); - }, - handleCommentSubmit: function(comment) { - var data = new FormData(); - data.append('Author', comment.author); - data.append('Text', comment.text); - - var xhr = new XMLHttpRequest(); - xhr.open('post', this.props.submitUrl, true); - xhr.onload = function() { - this.loadCommentsFromServer(); - }.bind(this); - xhr.send(data); - }, - getInitialState: function() { - return {data: []}; - }, - componentWillMount: function() { - this.loadCommentsFromServer(); - window.setInterval(this.loadCommentsFromServer, this.props.pollInterval); - }, - render: function() { - return ( -
-

Comments

- - -
- ); - } -}); - -React.renderComponent( - , - document.getElementById('content') -); -``` - -## Congrats! - -You have just built a comment box in a few simple steps. The below tweaks are not absolutely necessary, but they will improve the performance and polish of your application, so we suggest reading through them :) - -We hope you have enjoyed learning about React, and how ReactJS.NET allows you to easily use it from an ASP.NET MVC web application. Learn more about [why to use React](http://facebook.github.io/react/docs/why-react.html) and how to [think about React components](http://facebook.github.io/react/docs/thinking-in-react.html), or dive into the [API reference](http://facebook.github.io/react/docs/top-level-api.html) and start hacking! - -Continue on for more awesomeness! - -## Optimization: optimistic updates - -Our application is now feature complete but it feels slow to have to wait for the request to complete before your comment appears in the list. We can optimistically add this comment to the list to make the app feel faster. - -```javascript{12-14} -var CommentBox = React.createClass({ - loadCommentsFromServer: function() { - var xhr = new XMLHttpRequest(); - xhr.open('get', this.props.url, true); - xhr.onload = function() { - var data = JSON.parse(xhr.responseText); - this.setState({ data: data }); - }.bind(this); - xhr.send(); - }, - handleCommentSubmit: function(comment) { - var comments = this.state.data; - var newComments = comments.concat([comment]); - this.setState({data: newComments}); - - var data = new FormData(); - data.append('Author', comment.Author); - data.append('Text', comment.Text); - - var xhr = new XMLHttpRequest(); - xhr.open('post', this.props.submitUrl, true); - xhr.onload = function() { - this.loadCommentsFromServer(); - }.bind(this); - xhr.send(data); - }, - getInitialState: function() { - return {data: []}; - }, - componentWillMount: function() { - this.loadCommentsFromServer(); - window.setInterval(this.loadCommentsFromServer, this.props.pollInterval); - }, - render: function() { - return ( -
-

Comments

- - -
- ); - } -}); -``` - -## Optimization: Bundling and minification -Bundling refers to the practice of combining multiple JavaScript files into a single large file to reduce the number of HTTP requests to load a page. Minification refers to the removal of comments and unnecessary whitespace from JavaScript files to make them smaller. Together, bundling and minification can help to significantly improve the performance of your website. ReactJS.NET supports ASP.NET Bundling and Minification to achieve this. You can refer to [Microsoft's official documentation](http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification) for more information on ASP.NET Bundling and Minification. This tutorial will just cover the basics. - -To get started, install the "ReactJS.NET - JSX for ASP.NET Web Optimization Framework" NuGet package. This will automatically install the ASP.NET Bundling and Minification package along with all its dependencies. - -Once installed, modify `BundleConfig.cs` to reference the Showdown and Tutorial JavaScript files: - -```csharp{11-19} -using System.Web.Optimization; -using System.Web.Optimization.React; - -namespace ReactDemo -{ - public static class BundleConfig - { - // For more information on Bundling, visit http://go.microsoft.com/fwlink/?LinkId=254725 - public static void RegisterBundles(BundleCollection bundles) - { - bundles.Add(new JsxBundle("~/bundles/main").Include( - "~/Scripts/Tutorial.jsx", - "~/Scripts/showdown.js" - )); - - // Forces files to be combined and minified in debug mode - // Only used here to demonstrate how combination/minification works - // Normally you would use unminified versions in debug mode. - BundleTable.EnableOptimizations = true; - } - } -} -``` - -Now that the bundle has been registered, we need to reference it from the view: - -```html{12} -@model IEnumerable -@{ - Layout = null; -} - - - Hello React - - -
- - @Scripts.Render("~/bundles/main") - @Html.ReactInitJavaScript() - - -``` - -That's it! Now if you view the source for the page, you should see a single script tag for the bundle: - -```html - - -``` - -If you go to this URL in your browser, you should notice that the code has been minified, and both the tutorial code and the Showdown code are in the same file. - -## Optimization: Server-side rendering - -Server-side rendering means that your application initially renders the components on the server-side, rather than fetching data from the server and rendering using JavaScript. This enhances the performance of your application since the user will see the initial state immediately. - -We need to make some motifications to `CommentBox` to support server-side rendering. Firstly, we need to accept an `initialData` prop, which will be used to set the initial state of the component, rather than doing an AJAX request. We also need to ensure the `setInterval` call for polling for new comments is only executed client-side, by moving it to the `componentDidMount` method. Finally, we will remove the `loadCommentsFromServer` call from `getInitialState`, since it is no longer required. - -```javascript{28,30-32} -var CommentBox = React.createClass({ - loadCommentsFromServer: function() { - var xhr = new XMLHttpRequest(); - xhr.open('get', this.props.url, true); - xhr.onload = function() { - var data = JSON.parse(xhr.responseText); - this.setState({ data: data }); - }.bind(this); - xhr.send(); - }, - handleCommentSubmit: function(comment) { - var comments = this.state.data; - var newComments = comments.concat([comment]); - this.setState({data: newComments}); - - var data = new FormData(); - data.append('Author', comment.Author); - data.append('Text', comment.Text); - - var xhr = new XMLHttpRequest(); - xhr.open('post', this.props.submitUrl, true); - xhr.onload = function() { - this.loadCommentsFromServer(); - }.bind(this); - xhr.send(data); - }, - getInitialState: function() { - return { data: this.props.initialData }; - }, - componentDidMount: function() { - window.setInterval(this.loadCommentsFromServer, this.props.pollInterval); - }, - render: function() { - return ( -
-

Comments

- - -
- ); - } -}); -``` - -In the view, we will accept the list of comments as the model, and use `Html.React` to render the component. This will replace the `React.renderComponent` call that currently exists in Tutorial.jsx. All the props from the current `React.renderComponent` call should be moved here, and the `React.renderComponent` call should be deleted. - -```html{1,10-16,20} -@model IEnumerable -@{ - Layout = null; -} - - - Hello React - - - @Html.React("CommentBox", new - { - initialData = Model, - url = Url.Action("Comments"), - submitUrl = Url.Action("AddComment"), - pollInterval = 2000, - }) - - - - @Html.ReactInitJavaScript() - - -``` - -We need to modify the controller action to pass the data to the view: - -```csharp{3} -public ActionResult Index() -{ - return View(_comments); -} -``` - -We also need to modify `App_Start\ReactConfig.cs` to tell ReactJS.NET which JavaScript files it requires for the server-side rendering: - -```csharp{13-15} -using React; - -[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(ReactDemo.ReactConfig), "Configure")] - -namespace ReactDemo -{ - public static class ReactConfig - { - public static void Configure() - { - ReactSiteConfiguration.Configuration = new ReactSiteConfiguration(); - - ReactSiteConfiguration.Configuration - .AddScript("~/Scripts/showdown.js") - .AddScript("~/Scripts/Tutorial.jsx"); - } - } -} -``` - -That's it! Now if you build and refresh your application, you should notice that the comments box is rendered immediately rather than having a slight delay. If you view the source of the page, you will see the initial comments directly in the HTML itself: - -```html - - - Hello React - - -
-
-

Comments

-
-
-

Daniel Lo Nigro

-

Hello ReactJS.NET World!

-
- - -``` diff --git a/site/jekyll/getting-started/usage.md b/site/jekyll/getting-started/usage.md index c05e5a5f5..8fbf04517 100644 --- a/site/jekyll/getting-started/usage.md +++ b/site/jekyll/getting-started/usage.md @@ -3,30 +3,24 @@ layout: docs title: Basic Usage --- -Once installed, create your React components as usual, ensuring you add the -`/** @jsx React.DOM */` docblock. +Once installed, create your React components as usual. ```javascript // /Scripts/HelloWorld.jsx -/** @jsx React.DOM */ -var HelloWorld = React.createClass({ - render: function () { - return ( -
Hello {this.props.name}
- ); - } -}); +const HelloWorld = props => { + return
Hello {props.name}
; +}; ``` -On-the-Fly JSX to JavaScript Compilation ----------------------------------------- +## On-the-fly JSX to JavaScript Compilation + Hit a JSX file in your browser (eg. `/Scripts/HelloWorld.jsx`) and observe the magnificence of JSX being compiled into JavaScript with no precompilation necessary. -Next Steps ------------ +## Next Steps + On-the-fly JSX compilation is good for fast iteration during development, but for production you will want to precompile for best performance. This can be -done via [ASP.NET Bundling and Minification](/guides/weboptimizer.html) or -[Cassette](/guides/cassette.html). +done via [Webpack](/bundling/webpack.html) (recommended), [ASP.NET Bundling and Minification](/bundling/weboptimizer.html) or +[Cassette](/bundling/cassette.html). diff --git a/site/jekyll/guides/es6.md b/site/jekyll/guides/es6.md deleted file mode 100644 index f3fc4d366..000000000 --- a/site/jekyll/guides/es6.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -layout: docs -title: ES6 Features ---- - -React can optionally use some ECMAScript 6 features thanks to the bundled version of [JSTransform](https://github.com/facebook/jstransform). ECMAScript 6 (or "ES6" for short) is the next version of ECMAScript/JavaScript and contains several useful features: - -* **[Arrow functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/arrow_functions)** — A syntax for inline lambda functions similar to C#. These are very useful when combined with the `map` and `filter` methods of arrays: - -```javascript -var numbers = [1, 2, 3, 4]; -var doubled = numbers.map(number => number * 2); // [2, 4, 6, 8] -``` - -Arrow functions also implicitly bind `this`, so you do not need to write `.bind(this)` when passing around a function as a callback. - -* **Concise methods** — You no longer need to write `: function` in your object literals: - -```javascript{13,16} -// The old way -var OldAndBusted = React.createClass({ - render: function() { - // ... - }, - doStuff: function() { - // ... - } -}); - -// The new way -var NewHotness = React.createClass({ - render() { - // ... - }, - doStuff() { - // ... - } -}); -``` - -* **[Classes](http://wiki.ecmascript.org/doku.php?id=strawman:maximally_minimal_classes)** — Similar to the class systems included in JavaScript frameworks such as Prototype and MooTools, but will (eventually) be native to JavaScript - -```javascript -class AwesomeStuff { - add(first, second) { - return first + second; - } -} - -var foo = new AwesomeStuff(); -foo.add(2, 3); // 5 -``` - -* **[Short object notation](http://ariya.ofilabs.com/2013/02/es6-and-object-literal-property-value-shorthand.html)** -* And more! See the [JSTransform source code](https://github.com/facebook/jstransform/tree/master/visitors), you never know what goodies you'll find. - -How to use ----------- -To use the ES6 transforms, you'll need to enable them. For ASP.NET MVC sites, this is done in your `ReactConfig.cs` by calling `.SetUseHarmony(true)`: - -```csharp{2} -ReactSiteConfiguration.Configuration - .SetUseHarmony(true) - .AddScript("~/Content/Sample.jsx"); -``` -If you are using [MSBuild to precompile your JSX](/guide/msbuild.html), you also need to enable it in MSBuild via the `UseHarmony="true"` flag in your build script (`TransformJsx.proj` by default): - -```xml - -``` diff --git a/site/jekyll/guides/mono.md b/site/jekyll/guides/mono.md deleted file mode 100644 index f6f4a5f11..000000000 --- a/site/jekyll/guides/mono.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -layout: docs -title: Linux (Mono) ---- - -**New in ReactJS.NET 1.0** - -ReactJS.NET 1.0 includes full support for Mono via Google's [V8 JavaScript engine](https://code.google.com/p/v8/), the same engine used by Google Chrome and Node.js. To use ReactJS.NET with Mono, you need to compile V8 and VroomJs (a .NET wrapper around V8). This can be accomplished by running the following shell commands on your Linux or Mac OS X machine: - -```sh -# Get a supported version of V8 -cd /usr/local/src/ -git clone https://github.com/v8/v8.git v8-3.17 -cd v8-3.17 -git checkout 3.17 - -# Build V8 -make dependencies -make native werror=no library=shared soname_version=3.17.16.2 -j4 -cp out/native/lib.target/libv8.so.3.17.16.2 /usr/local/lib/ - -# Get ReactJS.NET's version of libvroomjs -cd /usr/local/src/ -git clone https://github.com/reactjs/react.net.git -cd react.net -git submodule update --init -cd lib/VroomJs/libvroomjs/ - -# Build libvroomjs -g++ jscontext.cpp jsengine.cpp managedref.cpp bridge.cpp jsscript.cpp -o libVroomJsNative.so -shared -L /usr/local/src/v8-3.17/out/native/lib.target/ -I /usr/local/src/v8-3.17/include/ -fPIC -Wl,--no-as-needed -l:/usr/local/lib/libv8.so.3.17.16.2 -cp libVroomJsNative.so /usr/local/lib/ -ldconfig -``` - -Once this has been completed, install the **React.JavaScriptEngine.VroomJs** package to your website. - -If VroomJs fails to load, you will see an exception when your application is started. If this happens, run Mono with the `MONO_LOG_LEVEL=debug` environment variable to get more useful debugging information. Often, this occurs when Mono is unable to locate V8 (ie. it's not in /usr/lib/ or /usr/local/lib/) diff --git a/site/jekyll/guides/weboptimizer.md b/site/jekyll/guides/weboptimizer.md deleted file mode 100644 index 1c760f3ed..000000000 --- a/site/jekyll/guides/weboptimizer.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -layout: docs -title: ASP.NET Bundling and Minification ---- - -ReactJS.NET supports the use of Microsoft's -[ASP.NET Bundling and Minification](http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification) -library to compile JSX into JavaScript and minify it along with all your other -JavaScript. Simply create a `JsxBundle` containing any number of JSX or regular -JavaScript files: - -```csharp -// In BundleConfig.cs -bundles.Add(new JsxBundle("~/bundles/main").Include( - // Add your JSX files here - "~/Content/HelloWorld.react.jsx", - "~/Content/AnythingElse.react.jsx", - // You can include regular JavaScript files in the bundle too - "~/Content/ajax.js", -)); -``` - -`JsxBundle` will compile your JSX to JavaScript and then minify it. For more -control (eg. if you want to run other transforms as well), you can use -`JsxTransform` directly: - -```csharp -// In BundleConfig.cs -bundles.Add(new Bundle("~/bundles/main", new IBundleTransform[] -{ - // This works the same as JsxBundle (transform then minify) but you could - //add your own transforms as well. - new JsxTransform(), - new JsMinify(), -}).Include( - "~/Content/HelloWorld.react.jsx" -)); -``` diff --git a/site/jekyll/img/logo.svg b/site/jekyll/img/logo.svg new file mode 100644 index 000000000..4aedc6f63 --- /dev/null +++ b/site/jekyll/img/logo.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/site/jekyll/img/logo_64.png b/site/jekyll/img/logo_64.png new file mode 100644 index 000000000..1336aea03 Binary files /dev/null and b/site/jekyll/img/logo_64.png differ diff --git a/site/jekyll/img/logo_small.png b/site/jekyll/img/logo_small.png deleted file mode 100644 index eea1f6744..000000000 Binary files a/site/jekyll/img/logo_small.png and /dev/null differ diff --git a/site/jekyll/img/search.png b/site/jekyll/img/search.png new file mode 100644 index 000000000..222fb660d Binary files /dev/null and b/site/jekyll/img/search.png differ diff --git a/site/jekyll/img/tutorial/helloworld-2019.png b/site/jekyll/img/tutorial/helloworld-2019.png new file mode 100644 index 000000000..6a760ff34 Binary files /dev/null and b/site/jekyll/img/tutorial/helloworld-2019.png differ diff --git a/site/jekyll/img/tutorial/new_webapp_2019.png b/site/jekyll/img/tutorial/new_webapp_2019.png new file mode 100644 index 000000000..be43168d5 Binary files /dev/null and b/site/jekyll/img/tutorial/new_webapp_2019.png differ diff --git a/site/jekyll/img/tutorial/new_webapp_600_2019.png b/site/jekyll/img/tutorial/new_webapp_600_2019.png new file mode 100644 index 000000000..b4435d84c Binary files /dev/null and b/site/jekyll/img/tutorial/new_webapp_600_2019.png differ diff --git a/site/jekyll/img/tutorial/newproject_core.png b/site/jekyll/img/tutorial/newproject_core.png new file mode 100644 index 000000000..58c42e6bb Binary files /dev/null and b/site/jekyll/img/tutorial/newproject_core.png differ diff --git a/site/jekyll/img/tutorial/newproject_core_600.png b/site/jekyll/img/tutorial/newproject_core_600.png new file mode 100644 index 000000000..99878795b Binary files /dev/null and b/site/jekyll/img/tutorial/newproject_core_600.png differ diff --git a/site/jekyll/img/tutorial/nuget_core_2019.png b/site/jekyll/img/tutorial/nuget_core_2019.png new file mode 100644 index 000000000..3f7e5b831 Binary files /dev/null and b/site/jekyll/img/tutorial/nuget_core_2019.png differ diff --git a/site/jekyll/img/tutorial/nuget_core_650_2019.png b/site/jekyll/img/tutorial/nuget_core_650_2019.png new file mode 100644 index 000000000..3ff706595 Binary files /dev/null and b/site/jekyll/img/tutorial/nuget_core_650_2019.png differ diff --git a/site/jekyll/index.md b/site/jekyll/index.md index 7cf1ff96b..5b8ba666d 100644 --- a/site/jekyll/index.md +++ b/site/jekyll/index.md @@ -3,6 +3,7 @@ layout: default title: React integration for ASP.NET MVC id: home --- +
ReactJS.NET
@@ -15,18 +16,20 @@ id: home

ReactJS.NET makes it easier to use Facebook's - [React](http://facebook.github.io/react/) and - [JSX](http://facebook.github.io/react/docs/jsx-in-depth.html) from C# and + [React](https://reactjs.org/) and + [JSX](https://reactjs.org/docs/jsx-in-depth.html) from C# and other .NET languages, focusing specifically on ASP.NET MVC (although it - also works in other environments). It assumes you already have some basic - knowledge about React. It is cross-platform and can run on Linux via Mono. - Take a look at [the tutorial](/getting-started/tutorial.html) to see how + also works in other environments). It supports both ASP.NET 4 (with MVC 4 or 5), + and ASP.NET Core MVC. It is cross-platform and can run on Linux via Mono + or .NET Core. + Take a look at [the tutorial](/tutorials/aspnetcore.html) to see how easy it is to get started with React and ReactJS.NET!

Latest news: {{ site.posts.first.title }} + ({{ site.posts.first.date | date: "%B %e, %Y" }})

@@ -46,16 +49,18 @@ id: home ```javascript // /Scripts/HelloWorld.jsx -var HelloWorld = React.createClass({ +class HelloWorld extends React.Component { render: function() { return
Hello world!
; } -}); +} ``` + ```html ``` +
@@ -69,6 +74,11 @@ var HelloWorld = React.createClass({ Reference your JSX files and they will be included in your bundles along with your other JavaScript files.

+

+ If you're a fan of Node.js-based libraries, you can use + [Webpack](/guides/webpack.html) or Browserify instead, and still + take advantage of ReactJS.NET's server-side rendering. +

@@ -82,10 +92,12 @@ bundles.Add(new JsxBundle("~/bundles/main").Include( "~/Scripts/ajax.js", )); ``` + ```html @Scripts.Render("~/bundles/main") ``` +
@@ -105,10 +117,13 @@ bundles.Add(new JsxBundle("~/bundles/main").Include( }) - + + + @Scripts.Render("~/bundles/main") @Html.ReactInitJavaScript() ``` +
@@ -116,8 +131,8 @@ bundles.Add(new JsxBundle("~/bundles/main").Include(
diff --git a/site/jekyll/tutorials/aspnet4.md b/site/jekyll/tutorials/aspnet4.md new file mode 100644 index 000000000..3190fc941 --- /dev/null +++ b/site/jekyll/tutorials/aspnet4.md @@ -0,0 +1,1181 @@ +--- +id: tutorial +title: Tutorial (ASP.NET 4.x) +layout: docs +--- + +> Note: +> +> This tutorial is for Visual Studio 2013 and ASP.NET MVC 4. If you like, you can [see the tutorial for ASP.NET Core instead](/tutorials/aspnetcore.html) + +This tutorial covers the end-to-end process of creating a brand new ASP.NET MVC website and adding a React component in it. We will start from scratch and end with a fully functioning component. It assumes you have basic knowledge of ASP.NET MVC and using Visual Studio. This tutorial is based off the [original React tutorial](https://reactjs.org/tutorial/tutorial.html) but has been modified specifically for ReactJS.NET. + +We'll be building a simple, but realistic, comments box that you can drop into a blog. It's a basic version of the realtime comments offered by Disqus, LiveFyre or Facebook comments. + +We'll provide: + +- A view of all of the comments +- A form to submit a comment +- Simple server-side in-memory storage for comments + +It'll also have a few neat features: + +- **Optimistic updates:** comments appear in the list before they're saved on the server so it feels fast. +- **Live updates:** other users' comments are popped into the comment view in real time. +- **Markdown formatting:** users can use Markdown to format their text. + +## Getting started + +For this tutorial we'll be using Visual Studio 2013, although any version of Visual Studio from 2010 onwards is fine, including [Visual Studio Express](https://www.visualstudio.com/vs/express/) which is completely free. We will be using ASP.NET MVC 4, although similar steps apply for ASP.NET MVC 5. + +### New Project + +Start by creating a new ASP.NET MVC 4 project: + +1. File → New → Project +1. Select ".NET Framework 4" and Templates → Visual C# → Web → ASP.NET MVC 4 Web Application. +1. Call it "ReactDemo" + Screenshot: New Project +1. In the "New ASP.NET MVC 4 Project" dialog, select the Empty template. I always recommend using this template for new sites, as the others include a large number of third-party packages that you may not even use. + Screenshot: New ASP.NET MVC 4 Project dialog + +### Install ReactJS.NET + +We need to install ReactJS.NET to the newly-created project. This is accomplished using NuGet, a package manager for .NET. Right-click on the "ReactDemo" project in the Solution Explorer and select "Manage NuGet Packages". Search for "ReactJS.NET" and install the **React.Web.Mvc4** package. + +Screenshot: Install NuGet Packages + +You will also need to install a JS engine to use (either V8 or ChakraCore are recommended). See the [JSEngineSwitcher docs](https://github.com/Taritsyn/JavaScriptEngineSwitcher/wiki/Registration-of-JS-engines) for more information. + +To use V8, add the following packages: + +``` +JavaScriptEngineSwitcher.V8 +JavaScriptEngineSwitcher.V8.Native.win-x64 +``` + +`ReactConfig.cs` will be automatically generated for you. Update it to register a JS engine: + +```csharp +using JavaScriptEngineSwitcher.Core; +using JavaScriptEngineSwitcher.V8; + +[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(React.Sample.Mvc4.ReactConfig), "Configure")] + +namespace React.Sample.Mvc4 +{ + public static class ReactConfig + { + public static void Configure() + { + JsEngineSwitcher.Current.DefaultEngineName = V8JsEngine.EngineName; + JsEngineSwitcher.Current.EngineFactories.AddV8(); + } + } +} +``` + +### Create basic controller and view + +Since this tutorial focuses mainly on ReactJS.NET itself, we will not cover creation of an MVC controller in much detail. To learn more about ASP.NET MVC, refer to [its official website](https://www.asp.net/mvc). + +Right-click on the Controllers folder and click Add → Controller. Name the controller "HomeController" and select "Empty MVC Controller" as the template. Once the controller has been created, right-click on `return View()` and click "Add View". Enter the following details: + +- View name: Index +- View Engine: Razor (CSHTML) +- Create a strongly-typed view: Unticked +- Create as a partial view: Unticked +- Use a layout or master page: Unticked + +_Note: In a real ASP.NET MVC site, you'd use a layout. However, to keep this tutorial simple, we will keep all HTML in the one view file._ + +Replace the contents of the new view file with the following: + +```html +@{ + Layout = null; +} + + + Hello React + + +
+ + + + + + +``` + +We also need to create the referenced JavaScript file (`Tutorial.jsx`). Right-click on ReactDemo project, select Add → New Folder, and enter "Scripts" as the folder name. Once created, right-click on the folder and select Add → New Item. Select Web → JavaScript File, enter "Tutorial.jsx" as the file name, and click "Add". + +For the remainder of this tutorial, we'll be writing our JavaScript code in this file. + +### Your first component + +React is all about modular, composable components. For our comment box example, we'll have the following component structure: + +``` +- CommentBox + - CommentList + - Comment + - CommentForm +``` + +Let's build the `CommentBox` component, which just displays a simple `
`. Add this code to `Tutorial.jsx`: + +```javascript +class CommentBox extends React.Component { + render() { + return ( +
Hello, world! I am a CommentBox.
+ ); + } +} + +ReactDOM.render(, document.getElementById('content')); +``` + +Note that native HTML element names start with a lowercase letter, while custom React class names begin with an uppercase letter. + +At this point, run your application by clicking the "Play" button in Visual Studio. If successful, your default browser should start and you should see "Hello, world! I am a CommentBox." + +Screenshot: Hello ReactJS.NET World! + +If you see this, congratulations! You've just built your first React component. You can leave the application running while you continue this tutorial. Simply change the JSX file and refresh to see your changes. + +#### JSX Syntax + +The first thing you'll notice is the XML-ish syntax in your JavaScript. We have a simple precompiler that translates the syntactic sugar to this plain JavaScript: + +```javascript +class CommentBox extends React.Component { + render() { + return React.createElement( + 'div', + { className: 'commentBox' }, + 'Hello, world! I am a CommentBox.', + ); + } +} + +ReactDOM.render( + React.createElement(CommentBox, null), + document.getElementById('content'), +); +``` + +Its use is optional but we've found JSX syntax easier to use than plain JavaScript. Read more in React's ["JSX In Depth"](https://reactjs.org/docs/jsx-in-depth.html) article. + +#### What's going on + +We are defining a new JavaScript class that extends from the React.Component class. In our class, we will define some properties and some methods to build from what React.Component already gives us. The most important of these methods is called `render` which returns a tree of React components that will eventually render to HTML. + +The `
` tags are not actual DOM nodes; they are instantiations of React `div` components. You can think of these as markers or pieces of data that React knows how to handle. React is **safe**. We are not generating HTML strings so XSS protection is the default. + +You do not have to return basic HTML. You can return a tree of components that you (or someone else) built. This is what makes React **composable**: a key tenet of maintainable frontends. + +`ReactDOM.render()` instantiates the root component, starts the framework, and injects the markup into a raw DOM element, provided as the second argument. + +The `ReactDOM` module exposes DOM-specific methods, while `React` has the core tools shared by React on different platforms (e.g., [React Native](https://reactnative.dev/)). + +## Composing components + +Let's build skeletons for `CommentList` and `CommentForm` which will, again, be simple `
`s. Add these two components to your file, keeping the existing `CommentBox` declaration and `ReactDOM.render` call: + +```javascript +class CommentList extends React.Component { + render() { + return ( +
Hello, world! I am a CommentList.
+ ); + } +} + +class CommentForm extends React.Component { + render() { + return ( +
Hello, world! I am a CommentForm.
+ ); + } +} +``` + +Next, update the `CommentBox` component to use these new components: + +```javascript{5-7} +class CommentBox extends React.Component { + render() { + return ( +
+

Comments

+ + +
+ ); + } +} +``` + +Notice how we're mixing HTML tags and components we've built. HTML tags are React components just like the ones you define, but they have one difference. The JSX compiler will automatically rewrite HTML tags to `React.createElement(tagName)` expressions and leave everything else alone. This is to prevent the pollution of the global namespace. + +### Using props + +Let's create the `Comment` component, which will depend on data passed in from our `CommentList` component. Data passed in from the `CommentList` component is available as a 'property' on our `Comment` component. These 'properties' are accessed through `this.props`. Using props, we will be able to read the data passed to the `Comment` from the `CommentList`, and render some markup: + +```javascript +class Comment extends React.Component { + render() { + return ( +
+

{this.props.author}

+ {this.props.children} +
+ ); + } +} +``` + +By surrounding a JavaScript expression with braces inside JSX (as either an attribute or child), you can drop text or React components into the tree. We access named attributes passed to the component as keys on `this.props` and any nested elements as `this.props.children`. + +### Component Properties + +Now that we have defined the `Comment` component, we will want to pass it the author name and comment text. This allows us to reuse the same code for each unique comment. Now let's add some comments within our `CommentList`: + +```javascript{5-7} +class CommentList extends React.Component { + render() { + return ( +
+ + Hello ReactJS.NET World! + + This is one comment + + This is *another* comment + +
+ ); + } +} +``` + +Note that we have passed some data from the parent `CommentList` component to the child `Comment` components. For example, we passed _Daniel Lo Nigro_ (via the `author` attribute) and _Hello ReactJS.NET World_ (via an XML-like child node) to the first `Comment`. As noted above, the `Comment` component will access these 'properties' through `this.props.author`, and `this.props.children`. + +### Adding Markdown + +Markdown is a simple way to format your text inline. For example, surrounding text with asterisks will make it emphasized. + +In this tutorial we use a third-party library called [remarkable](https://github.com/jonschlinkert/remarkable) which takes Markdown text and converts it to raw HTML. We already included this library with the original markup for the page, so we can just start using it. Let's convert the comment text to Markdown and output it: + +```javascript{3,9} +class Comment extends React.Component { + render() { + const md = new Remarkable(); + return ( +
+

{this.props.author}

+ {md.render(this.props.children.toString())} +
+ ); + } +} +``` + +All we're doing here is calling the remarkable library. We need to convert `this.props.children` from React's wrapped text to a raw string that remarkable will understand so we explicitly call `toString()`. + +But there's a problem! Our rendered comments look like this in the browser: "`

`This is ``another`` comment`

`". We want those tags to actually render as HTML. + +That's React protecting you from an [XSS attack](https://en.wikipedia.org/wiki/Cross-site_scripting). There's a way to get around it but the framework warns you not to use it: + +```javascript{2-6,13} +class Comment extends React.Component { + rawMarkup() { + const md = new Remarkable(); + const rawMarkup = md.render(this.props.children.toString()); + return { __html: rawMarkup }; + } + render() { + return ( +
+

{this.props.author}

+ +
+ ); + } +} +``` + +This is a special API that intentionally makes it difficult to insert raw HTML, but for remarkable we'll take advantage of this backdoor. + +**Remember:** by using this feature you're relying on remarkable to be secure. In this case, remarkable automatically strips HTML markup and insecure links from the output. + +### Hook up the data model + +So far we've been inserting the comments directly in the source code. Instead, let's render a blob of JSON data into the comment list. Eventually this will come from the server, but for now, write it in your source: + +```javascript +const data = [ + { Id: 1, Author: 'Daniel Lo Nigro', Text: 'Hello ReactJS.NET World!' }, + { Id: 2, Author: 'Pete Hunt', Text: 'This is one comment' }, + { Id: 3, Author: 'Jordan Walke', Text: 'This is *another* comment' }, +]; +``` + +We need to get this data into `CommentList` in a modular way. Modify `CommentBox` and the `ReactDOM.render()` call to pass this data into the `CommentList` via props: + +```javascript{6,14} +class CommentBox extends React.Component { + render() { + return ( +
+

Comments

+ + +
+ ); + } +} + +ReactDOM.render(, document.getElementById('content')); +``` + +Now that the data is available in the `CommentList`, let's render the comments dynamically: + +```javascript{3-7,10} +class CommentList extends React.Component { + render() { + const commentNodes = this.props.data.map(comment => ( + + {comment.Text} + + )); + return
{commentNodes}
; + } +} +``` + +That's it! + +### Server-side Data + +Let's return some data from the server. To do so, we need to first create a C# class to represent our comments. Right-click on the Models folder (which should be empty), select Add → Class, and enter "CommentModel.cs" as the file name. We'll create a basic comment model: + +```csharp +namespace ReactDemo.Models +{ + public class CommentModel + { + public int Id { get; set; } + public string Author { get; set; } + public string Text { get; set; } + } +} +``` + +In a real application, you'd use the repository pattern here, and retrieve the comments from a database. For simplicity, we'll just modify our controller to have a hard-coded list of comments. + +```csharp{9,13-30} +using System.Collections.Generic; +using System.Web.Mvc; +using ReactDemo.Models; + +namespace ReactDemo.Controllers +{ + public class HomeController : Controller + { + private static readonly IList _comments; + + static HomeController() + { + _comments = new List + { + new CommentModel + { + Id = 1, + Author = "Daniel Lo Nigro", + Text = "Hello ReactJS.NET World!" + }, + new CommentModel + { + Id = 2, + Author = "Pete Hunt", + Text = "This is one comment" + }, + new CommentModel + { + Id = 3, + Author = "Jordan Walke", + Text = "This is *another* comment" + }, + }; + } + + public ActionResult Index() + { + return View(); + } + } +} +``` + +Let's also add a new controller action to return the list of comments: + +```csharp +[OutputCache(Location = OutputCacheLocation.None)] +public ActionResult Comments() +{ + return Json(_comments, JsonRequestBehavior.AllowGet); +} +``` + +The `OutputCache` attribute is used here to prevent browsers from caching the response. When designing a real world API, caching of API requests should be considered more carefully. For this tutorial it is easiest to simply disable caching. + +Finally we add a corresponding route in `App_Start\RouteConfig.cs`: + +```csharp{12-16} +using System.Web.Mvc; +using System.Web.Routing; + +namespace ReactDemo +{ + public class RouteConfig + { + public static void RegisterRoutes(RouteCollection routes) + { + routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); + + routes.MapRoute( + name: "Comments", + url: "comments", + defaults: new { controller = "Home", action = "Comments" } + ); + + routes.MapRoute( + name: "Default", + url: "{controller}/{action}/{id}", + defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } + ); + } + } +} +``` + +If you hit `/comments` in your browser, you should now see the data encoded as JSON: + +Screenshot: JSON data source + +### Fetching from the server + +Now that we have a data source, we can replace the hard-coded data with the dynamic data from the server. We will remove the data prop and replace it with a URL to fetch: + +```javascript{2} +ReactDOM.render( + , + document.getElementById('content'), +); +``` + +Note that in a real app, you should generate the URL server-side (via `Url.Action` call) and pass it down, or use [RouteJs](https://github.com/Daniel15/RouteJs) rather than hard-coding it. This tutorial hard-codes it for simplicity. + +This component is different from the prior components because it will have to re-render itself. The component won't have any data until the request from the server comes back, at which point the component may need to render some new comments. + +### Reactive state + +So far, based on its props, each component has rendered itself once. `props` are immutable: they are passed from the parent and are "owned" by the parent. To implement interactions, we introduce mutable **state** to the component. `this.state` is private to the component and can be changed by calling `this.setState()` and passing an object that represents changes in state. When the state updates, the component re-renders itself. + +`render()` methods are written declaratively as functions of `this.props` and `this.state`. The framework guarantees the UI is always consistent with the inputs. + +When the server fetches data, we will be changing the comment data we have. Let's add an array of comment data to the `CommentBox` component as its state: + +```javascript{2-5,10} +class CommentBox extends React.Component { + constructor(props) { + super(props); + this.state = { data: [] }; + } + render() { + return ( +
+

Comments

+ + +
+ ); + } +} +``` + +The `constructor()` executes exactly once during the lifecycle of the component and sets up the initial state of the component. Remember to call the super class (the class we're extending, React.Component) via `super(props)` before using the `this` keyword. + +#### Updating state + +When the component is first created, we want to GET some JSON from the server and update the state to reflect the latest data. We'll use the standard XMLHttpRequest API to retrieve the data. If you need support for old browsers (mainly old Internet Explorer), you can use an AJAX library or a multipurpose library such as jQuery. `componentWillMount()` executes immediately and only once before the rendering occurs. In the following example, `componentWillMount()` loads the data from our XMLHttpRequest and assigns it to the `data` variable. Finally, it sets the `data` variable in state, using `setState()`. + +```javascript{6-14} +class CommentBox extends React.Component { + constructor(props) { + super(props); + this.state = { data: [] }; + } + componentWillMount() { + const xhr = new XMLHttpRequest(); + xhr.open('get', this.props.url, true); + xhr.onload = () => { + const data = JSON.parse(xhr.responseText); + this.setState({ data: data }); + }; + xhr.send(); + } + render() { + return ( +
+

Comments

+ + +
+ ); + } +} +``` + +Below, we're using `componentDidMount()`, a method called automatically by React _after_ a component is rendered for the first time. By moving the XMLHttpRequest call from `componentWillMount()`, which is executed only once _before_ rendering, to a function called `loadCommentsFromServer()`, we can then call it multiple times from `componentDidMount()` at a set interval to check for any updates to the comments. + +The key to these dynamic updates is the call to `this.setState()`. We replace the old array of comments with the new one from the server and the UI automatically updates itself. Because of this reactivity, it is only a minor change to add live updates. We will use simple polling here but you could easily use [SignalR](http://signalr.net/) or other technologies. + +```javascript{6,15-18,31} +class CommentBox extends React.Component { + constructor(props) { + super(props); + this.state = { data: [] }; + } + loadCommentsFromServer() { + const xhr = new XMLHttpRequest(); + xhr.open('get', this.props.url, true); + xhr.onload = () => { + const data = JSON.parse(xhr.responseText); + this.setState({ data: data }); + }; + xhr.send(); + } + componentDidMount() { + this.loadCommentsFromServer(); + window.setInterval( + () => this.loadCommentsFromServer(), + this.props.pollInterval, + ); + } + render() { + return ( +
+

Comments

+ + +
+ ); + } +} + +ReactDOM.render( + , + document.getElementById('content'), +); +``` + +All we have done here is move the AJAX call to a separate method and call it when the component is first loaded and every 2 seconds after that. + +### Adding new comments + +To accept new comments, we need to first add a controller action to handle it. This will just be some simple C# code that appends the new comment to the static list of comments: + +```csharp +[HttpPost] +public ActionResult AddComment(CommentModel comment) +{ + // Create a fake ID for this comment + comment.Id = _comments.Count + 1; + _comments.Add(comment); + return Content("Success :)"); +} +``` + +Let's also add it to the `App_Start\RouteConfig.cs` file, like we did earlier for the comments list: + +```csharp +routes.MapRoute( + name: "NewComment", + url: "comments/new", + defaults: new { controller = "Home", action = "AddComment" } +); +``` + +#### The Form + +Now it's time to build the form. Our `CommentForm` component should ask the user for their name and comment text and send a request to the server to save the comment. + +```javascript{4-8} +class CommentForm extends React.Component { + render() { + return ( +
+ + + +
+ ); + } +} +``` + +#### Controlled components + +With the traditional DOM, `input` elements are rendered and the browser manages the state (its rendered value). As a result, the state of the actual DOM will differ from that of the component. This is not ideal as the state of the view will differ from that of the component. In React, components should always represent the state of the view and not only at the point of initialization. + +Hence, we will be using `this.state` to save the user's input as it is entered. We define an initial `state` with two properties `author` and `text` and set them to be empty strings. In our `` elements, we set the `value` prop to reflect the `state` of the component and attach `onChange` handlers to them. These `` elements with a `value` set are called controlled components. Read more about controlled components on the [Forms article](https://reactjs.org/docs/forms.html#controlled-components). + +```javascript{2-13,16-28} +class CommentForm extends React.Component { + constructor(props) { + super(props); + this.state = { author: '', text: '' }; + this.handleAuthorChange = this.handleAuthorChange.bind(this); + this.handleTextChange = this.handleTextChange.bind(this); + } + handleAuthorChange(e) { + this.setState({ author: e.target.value }); + } + handleTextChange(e) { + this.setState({ text: e.target.value }); + } + render() { + return ( +
+ + + +
+ ); + } +} +``` + +#### Events + +React attaches event handlers to components using a camelCase naming convention. We attach `onChange` handlers to the two `` elements. Now, as the user enters text into the `` fields, the attached `onChange` callbacks are fired and the `state` of the component is modified. Subsequently, the rendered value of the `input` element will be updated to reflect the current component `state`. + +You'll notice that we are explicitly binding our event handlers to `this` in the constructor. While older techniques, like `React.createClass(...)`, featured automatic binding, we are using ES6 classes to define our components. React components declared as ES6 classes don't automatically bind `this` to the instance, so we have to explicitly use `.bind(this)`. + +For components with many event handlers, this explicit binding approach can get tedious. It's also easy to forget to declare your bindings which can cause some baffling bugs. React does offer two other techniques for ensuring your event handlers are bound properly to your component. Check out the [Handling Events](https://reactjs.org/docs/handling-events.html) documentation on the React website for more information. + +#### Submitting the form + +Let's make the form interactive. When the user submits the form, we should clear it, submit a request to the server, and refresh the list of comments. To start, let's listen for the form's submit event and clear it. + +```javascript{7,15-24,27} +class CommentForm extends React.Component { + constructor(props) { + super(props); + this.state = { author: '', text: '' }; + this.handleAuthorChange = this.handleAuthorChange.bind(this); + this.handleTextChange = this.handleTextChange.bind(this); + this.handleSubmit = this.handleSubmit.bind(this); + } + handleAuthorChange(e) { + this.setState({ author: e.target.value }); + } + handleTextChange(e) { + this.setState({ text: e.target.value }); + } + handleSubmit(e) { + e.preventDefault(); + const author = this.state.author.trim(); + const text = this.state.text.trim(); + if (!text || !author) { + return; + } + // TODO: send request to the server + this.setState({ author: '', text: '' }); + } + render() { + return ( +
+ + + +
+ ); + } +} +``` + +We attach an `onSubmit` handler to the form that clears the form fields when the form is submitted with valid input. We call `preventDefault()` on the event to prevent the browser's default action of submitting the form. + +#### Callbacks as props + +When a user submits a comment, we will need to refresh the list of comments to include the new one. It makes sense to do all of this logic in `CommentBox` since `CommentBox` owns the state that represents the list of comments. + +We need to pass data from the child component back up to its parent. We do this in our parent's `render` method by passing a new callback (`handleCommentSubmit`) into the child, binding it to the child's `onCommentSubmit` event. Whenever the event is triggered, the callback will be invoked: + +```javascript{5,16-18,28} +class CommentBox extends React.Component { + constructor(props) { + super(props); + this.state = { data: [] }; + this.handleCommentSubmit = this.handleCommentSubmit.bind(this); + } + loadCommentsFromServer() { + const xhr = new XMLHttpRequest(); + xhr.open('get', this.props.url, true); + xhr.onload = () => { + const data = JSON.parse(xhr.responseText); + this.setState({ data: data }); + }; + xhr.send(); + } + handleCommentSubmit(comment) { + // TODO: submit to the server and refresh the list + } + componentDidMount() { + this.loadCommentsFromServer(); + window.setInterval( + () => this.loadCommentsFromServer(), + this.props.pollInterval, + ); + } + render() { + return ( +
+

Comments

+ + +
+ ); + } +} +``` + +Now that `CommentBox` has made the callback available to `CommentForm` via the `onCommentSubmit` prop, the `CommentForm` can call the callback when the user submits the form: + +```javascript{22} +class CommentForm extends React.Component { + constructor(props) { + super(props); + this.state = { author: '', text: '' }; + this.handleAuthorChange = this.handleAuthorChange.bind(this); + this.handleTextChange = this.handleTextChange.bind(this); + this.handleSubmit = this.handleSubmit.bind(this); + } + handleAuthorChange(e) { + this.setState({ author: e.target.value }); + } + handleTextChange(e) { + this.setState({ text: e.target.value }); + } + handleSubmit(e) { + e.preventDefault(); + const author = this.state.author.trim(); + const text = this.state.text.trim(); + if (!text || !author) { + return; + } + this.props.onCommentSubmit({ Author: author, Text: text }); + this.setState({ author: '', text: '' }); + } + render() { + return ( +
+ + + +
+ ); + } +} +``` + +Now that the callbacks are in place, all we have to do is submit to the server and refresh the list: + +```javascript{16-25,42} +class CommentBox extends React.Component { + constructor(props) { + super(props); + this.state = { data: [] }; + this.handleCommentSubmit = this.handleCommentSubmit.bind(this); + } + loadCommentsFromServer() { + const xhr = new XMLHttpRequest(); + xhr.open('get', this.props.url, true); + xhr.onload = () => { + const data = JSON.parse(xhr.responseText); + this.setState({ data: data }); + }; + xhr.send(); + } + handleCommentSubmit(comment) { + const data = new FormData(); + data.append('Author', comment.Author); + data.append('Text', comment.Text); + + const xhr = new XMLHttpRequest(); + xhr.open('post', this.props.submitUrl, true); + xhr.onload = () => this.loadCommentsFromServer(); + xhr.send(data); + } + componentDidMount() { + this.loadCommentsFromServer(); + window.setInterval( + () => this.loadCommentsFromServer(), + this.props.pollInterval, + ); + } + render() { + return ( +
+

Comments

+ + +
+ ); + } +} + +ReactDOM.render( + , + document.getElementById('content'), +); +``` + +## Congrats! + +You have just built a comment box in a few simple steps. The below tweaks are not absolutely necessary, but they will improve the performance and polish of your application, so we suggest reading through them. :) + +We hope you have enjoyed learning about React and how ReactJS.NET allows you to easily use it from an ASP.NET MVC web application. Learn more about [React from the project homepage](https://reactjs.org/) and how to [think about React components](https://reactjs.org/docs/thinking-in-react.html), or dive into the [API reference](https://reactjs.org/docs/react-api.html) and start hacking! + +Continue on for more awesomeness! + +## Optimization: optimistic updates + +Our application is now feature complete but it feels slow to have to wait for the request to complete before your comment appears in the list. We can optimistically add this comment to the list to make the app feel faster. + +```javascript{17-23} +class CommentBox extends React.Component { + constructor(props) { + super(props); + this.state = { data: [] }; + this.handleCommentSubmit = this.handleCommentSubmit.bind(this); + } + loadCommentsFromServer() { + const xhr = new XMLHttpRequest(); + xhr.open('get', this.props.url, true); + xhr.onload = () => { + const data = JSON.parse(xhr.responseText); + this.setState({ data: data }); + }; + xhr.send(); + } + handleCommentSubmit(comment) { + const comments = this.state.data; + // Optimistically set an id on the new comment. It will be replaced by an + // id generated by the server. In a production application you would likely + // use a more robust system for ID generation. + comment.Id = comments.length + 1; + const newComments = comments.concat([comment]); + this.setState({ data: newComments }); + + const data = new FormData(); + data.append('Author', comment.Author); + data.append('Text', comment.Text); + + const xhr = new XMLHttpRequest(); + xhr.open('post', this.props.submitUrl, true); + xhr.onload = () => this.loadCommentsFromServer(); + xhr.send(data); + } + componentDidMount() { + this.loadCommentsFromServer(); + window.setInterval( + () => this.loadCommentsFromServer(), + this.props.pollInterval, + ); + } + render() { + return ( +
+

Comments

+ + +
+ ); + } +} +``` + +## Optimization: Bundling and minification + +Bundling refers to the practice of combining multiple JavaScript files into a single large file to reduce the number of HTTP requests to load a page. Minification refers to the removal of comments and unnecessary whitespace from JavaScript files to make them smaller. Together, bundling and minification can help to significantly improve the performance of your website. ReactJS.NET supports ASP.NET Bundling and Minification to achieve this. You can refer to [Microsoft's official documentation on Bundling and Minification](https://docs.microsoft.com/en-us/aspnet/mvc/overview/performance/bundling-and-minification). This tutorial will just cover the basics. + +To get started, install the "System.Web.Optimization.React" NuGet package. This will automatically install the ASP.NET Bundling and Minification package along with all its dependencies. + +Once installed, modify `BundleConfig.cs` to reference the tutorial JavaScript file: + +```csharp{11-18} +using System.Web.Optimization; +using System.Web.Optimization.React; + +namespace ReactDemo +{ + public static class BundleConfig + { + // For more information on Bundling, visit http://go.microsoft.com/fwlink/?LinkId=254725 + public static void RegisterBundles(BundleCollection bundles) + { + bundles.Add(new BabelBundle("~/bundles/main").Include( + "~/Scripts/Tutorial.jsx", + )); + + // Forces files to be combined and minified in debug mode + // Only used here to demonstrate how combination/minification works + // Normally you would use unminified versions in debug mode. + BundleTable.EnableOptimizations = true; + } + } +} +``` + +Now that the bundle has been registered, we need to reference it from the view: + +```html{13} +@model IEnumerable +@{ + Layout = null; +} + + + Hello React + + +
+ + + @Scripts.Render("~/bundles/main") + @Html.ReactInitJavaScript() + + +``` + +That's it! Now if you view the source for the page, you should see a single script tag for the bundle: + +```html + + +``` + +If you go to this URL in your browser, you should notice that the code has been minified. + +## Optimization: Server-side rendering + +Server-side rendering means that your application initially renders the components on the server-side, rather than fetching data from the server and rendering using the client. Server-side rendering enhances the performance of your application since the user will see the initial state immediately. + +We need to make some modifications to `CommentBox` to support server-side rendering. Firstly, we need to accept an `initialData` prop, which will be used to set the initial state of the component, rather than doing an AJAX request. We also need to remove the `loadCommentsFromServer` call from `componentDidMount`, since it is no longer required. Also, we need to remove the `ReactDOM.render` call from the JSX file, as server-side rendering automatically outputs the correct `ReactDOM.render` call for you. + +```javascript{4,31-33} +class CommentBox extends React.Component { + constructor(props) { + super(props); + this.state = { data: this.props.initialData }; + this.handleCommentSubmit = this.handleCommentSubmit.bind(this); + } + loadCommentsFromServer() { + const xhr = new XMLHttpRequest(); + xhr.open('get', this.props.url, true); + xhr.onload = () => { + const data = JSON.parse(xhr.responseText); + this.setState({ data: data }); + }; + xhr.send(); + } + handleCommentSubmit(comment) { + const comments = this.state.data; + comment.Id = comments.length + 1; + const newComments = comments.concat([comment]); + this.setState({ data: newComments }); + + const data = new FormData(); + data.append('Author', comment.Author); + data.append('Text', comment.Text); + + const xhr = new XMLHttpRequest(); + xhr.open('post', this.props.submitUrl, true); + xhr.onload = () => this.loadCommentsFromServer(); + xhr.send(data); + } + componentDidMount() { + window.setInterval( + () => this.loadCommentsFromServer(), + this.props.pollInterval, + ); + } + render() { + return ( +
+

Comments

+ + +
+ ); + } +} +``` + +We also need to update the `Comment` component to use `Remarkable` from either `global` or `window`, due to a bug in Remarkable: + +```javascript{3} +function createRemarkable() { + var remarkable = + 'undefined' != typeof global && global.Remarkable + ? global.Remarkable + : window.Remarkable; + + return new remarkable(); +} + +class Comment extends React.Component { + rawMarkup() { + const md = createRemarkable(); + const rawMarkup = md.render(this.props.children.toString()); + return { __html: rawMarkup }; + } + render() { + return ( +
+

{this.props.author}

+ +
+ ); + } +} +``` + +In the view, we will accept the list of comments as the model, and use `Html.React` to render the component. This will replace the `ReactDOM.render` call that currently exists in Tutorial.jsx. All the props from the current `ReactDOM.render` call should be moved here, and the `ReactDOM.render` call should be deleted. + +```html{1,10-16,21} +@model IEnumerable +@{ + Layout = null; +} + + + Hello React + + + @Html.React("CommentBox", new + { + initialData = Model, + url = Url.Action("Comments"), + submitUrl = Url.Action("AddComment"), + pollInterval = 2000 + }) + + + + + @Html.ReactInitJavaScript() + + +``` + +We need to modify the controller action to pass the data to the view: + +```csharp{3} +public ActionResult Index() +{ + return View(_comments); +} +``` + +We also need to modify `App_Start\ReactConfig.cs` to tell ReactJS.NET which JavaScript files it requires for the server-side rendering: + +```csharp{11-12} +using React; + +[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(ReactDemo.ReactConfig), "Configure")] + +namespace ReactDemo +{ + public static class ReactConfig + { + public static void Configure() + { + ReactSiteConfiguration.Configuration + .AddScript("~/js/remarkable.min.js") + .AddScript("~/Scripts/Tutorial.jsx"); + } + } +} +``` + +Note that we need a copy of Remarkable in order to load it for server-side rendering. In a production app you'd probably use Bower or npm for this, but for our tutorial you can just [download the file from CDNJS](https://cdnjs.cloudflare.com/ajax/libs/remarkable/1.7.1/remarkable.min.js) and save it into `~/js`. + +That's it! Now if you build and refresh your application, you should notice that the comments box is rendered immediately rather than having a slight delay. If you view the source of the page, you will see the initial comments directly in the HTML itself: + +```html + + + Hello React + + +
+
+

Comments

+
+
+

Daniel Lo Nigro

+ Hello ReactJS.NET World! +
+ +``` + +How is this magic possible? Well, React was built with server-side rendering in mind, so adding that capability to React.NET wasn't as magical as you'd think. React exposes [the ReactDOMServer object](https://reactjs.org/docs/react-dom-server.html) which enables a JavaScript engine to render a React component into static markup. From there, it's possible to "hydrate" that static markup in the client and make reactivity possible again. If you view the source of your page again, you will see a reference to `ReactDOM.hydrate()` where our `@Html.ReactInitJavaScript()` call is: + +```html + + +``` + +**Note**, this hand-off between server and client means that you should ensure the version of React included in the browser is the same as in the NuGet package. If not, you may find yourself battling confusing errors or witnessing strange behavior. Check the [React.Web.Mvc4](https://www.nuget.org/packages/React.Web.Mvc4) and [React.Core](https://www.nuget.org/packages/React.Core/) packages for details. diff --git a/site/jekyll/tutorials/aspnetcore.md b/site/jekyll/tutorials/aspnetcore.md new file mode 100644 index 000000000..0a79d245c --- /dev/null +++ b/site/jekyll/tutorials/aspnetcore.md @@ -0,0 +1,1169 @@ +--- +id: tutorial +title: Tutorial (ASP.NET Core) +layout: docs +--- + +> Note: +> +> This tutorial is for Visual Studio 2019 and ASP.NET Core MVC. If you're still using ASP.NET 4 and ASP.NET MVC 5, you can [follow the ASP.NET 4 tutorial instead](/tutorials/aspnet4.html) + +## Quick start + +``` +dotnet new -i React.Template +dotnet new reactnet-vanilla +dotnet run +``` + +#### Heads up! This configuration only supports globally-scoped modules. If you're planning on using `require` or `import` module syntax in your application, use the `reactnet-webpack` template instead for webpack support. + +## Step by step version + +This tutorial covers the end-to-end process of creating a brand new ASP.NET MVC website and adding a React component in it. We will start from scratch and end with a fully functioning component. It assumes you have basic knowledge of ASP.NET MVC and using Visual Studio. This tutorial is based off the [original React tutorial](https://reactjs.org/tutorial/tutorial.html) but has been modified specifically for ReactJS.NET. + +We'll be building a simple, but realistic comments box that you can drop into a blog, a basic version of the realtime comments offered by Disqus, LiveFyre or Facebook comments. + +We'll provide: + +- A view of all of the comments +- A form to submit a comment +- Simple server-side in-memory storage for comments + +It'll also have a few neat features: + +- **Optimistic commenting:** comments appear in the list before they're saved on the server so it feels fast. +- **Live updates:** other users' comments are popped into the comment view in real time. +- **Markdown formatting:** users can use Markdown to format their text. + +## Want to skip all this and see the source? + +[It's all on GitHub](https://github.com/reactjs/React.NET/tree/main/src/React.Template/reactnet-vanilla). + +## Getting started + +For this tutorial we'll be using Visual Studio 2019. If you do not already have a copy of Visual Studio, [the Community version](https://www.visualstudio.com/vs/community/) is free. We will be using ASP.NET Core MVC. + +### New Project + +Start by creating a new ASP.NET Core MVC project: + +1. File → New → Project... +2. Select "ASP.NET Core Web Application". You may search for it via the search box or narrow down your choices via the drop-downs - C#, All platforms, Web is a good way to get it as the first result. + [Screenshot: New Project](/img/tutorial/newproject_core.png) +3. Click "Next". +4. Enter "ReactDemo" for the project name and location to store it. +5. Click "Create". +6. In the "Create a new ASP.NET Core web application" dialog, select the "Web Application (Model-View-Controller)" template. Also, ensure "Change Authentication" is set to "No Authentication". + [Screenshot: New ASP.NET Core MVC Project dialog](/img/tutorial/new_webapp_2019.png) +7. Click "Create". + +Note: We are using .NET Core 3.1 in this tutorial. + +### Remove example content + +The default Web Application template includes some example content that we don't need. Delete the following files: + +- `Controllers\HomeController.cs` +- `Views\Home` and `Views\Shared` folders + +### Install ReactJS.NET + +We need to install ReactJS.NET to the newly-created project. This is accomplished using NuGet, a package manager for .NET. Right-click on the "ReactDemo" project in the Solution Explorer and select "Manage NuGet Packages...". Click the "Browse" tab, search for "React.AspNet", and install the **React.AspNet** package. + +[Screenshot: Install NuGet Packages](/img/tutorial/nuget_core_2019.png) + +### Install a JS engine + +While we're managing NuGet packages, we need to install a JS engine. Search for and install one of either: + +- `JavaScriptEngineSwitcher.V8` (what this tutorial uses) +- `JavaScriptEngineSwitcher.ChakraCore` + +If you choose ChakraCore, make sure you change any code/using statements in this tutorial where needed. + +Now, install the native assembly based on your architecture and engine choice: + +V8: + +- `JavaScriptEngineSwitcher.V8.Native.win-x86` +- `JavaScriptEngineSwitcher.V8.Native.win-x64` (what this tutorial uses) + +Chakra: + +- `JavaScriptEngineSwitcher.ChakraCore.Native.win-x86` +- `JavaScriptEngineSwitcher.ChakraCore.Native.win-x64` +- `JavaScriptEngineSwitcher.ChakraCore.Native.win-arm` +- `JavaScriptEngineSwitcher.ChakraCore.Native.linux-x64` +- `JavaScriptEngineSwitcher.ChakraCore.Native.osx-x64` + +Lastly, install `JavaScriptEngineSwitcher.Extensions.MsDependencyInjection`. + +### Modify Startup.cs + +We also need to modify the `Startup.cs` file to initialize ReactJS.NET. You can learn more about this on the [Getting Started on ASP.NET Core](/getting-started/aspnetcore.html) page. Open `Startup.cs` and perform the following changes: + +At the top of the file, add: + +```csharp +using Microsoft.AspNetCore.Http; +using JavaScriptEngineSwitcher.V8; +using JavaScriptEngineSwitcher.Extensions.MsDependencyInjection; +using React.AspNet; +``` + +Directly above: + +```csharp +services.AddControllersWithViews(); +``` + +Add: + +```csharp +services.AddSingleton(); +services.AddReact(); + +// Make sure a JS engine is registered, or you will get an error! +services.AddJsEngineSwitcher(options => options.DefaultEngineName = V8JsEngine.EngineName) + .AddV8(); +``` + +Directly **above**: + +```csharp +app.UseStaticFiles(); +``` + +Add: + +```csharp +// Initialise ReactJS.NET. Must be before static files. +app.UseReact(config => +{ + // If you want to use server-side rendering of React components, + // add all the necessary JavaScript files here. This includes + // your components as well as all of their dependencies. + // See http://reactjs.net/ for more information. Example: + //config + // .AddScript("~/js/First.jsx") + // .AddScript("~/js/Second.jsx"); + + // If you use an external build tool (for example, Babel, Webpack, + // Browserify or Gulp), you can improve performance by disabling + // ReactJS.NET's version of Babel and loading the pre-transpiled + // scripts. Example: + //config + // .SetLoadBabel(false) + // .AddScriptWithoutTransform("~/js/bundle.server.js"); +}); +``` + +Finally, add this to the top of `Views\_ViewImports.cshtml`: + +```csharp +@using React.AspNet +``` + +### Create basic controller and view + +Since this tutorial focuses mainly on ReactJS.NET itself, we will not cover creation of an MVC controller in much detail. To learn more about ASP.NET MVC, refer to [its official website](https://dotnet.microsoft.com/apps/aspnet/mvc). + +1. Right-click on the Controllers folder and select Add → New Item... +2. Select ASP.NET Core → Controller Class +3. Name the file `HomeController.cs` +4. Click "Add" + +Once the controller has been created, we also need to create a view + +1. Right-click on the Views folder, select Add → New Folder, and create a "Home" folder +2. Right-click on the Views\Home folder and select Add → View... +3. Name the view file `Index` +4. Click "Add" + +Replace the contents of the new view file with the following: + +```html +@{ + Layout = null; +} + + + Hello React + + +
+ + + + + + +``` + +_Note: In a real ASP.NET MVC site, you'd use a layout. However, to keep this tutorial simple, we will keep all HTML in the one view file._ + +We also need to create the referenced JavaScript file (`tutorial.jsx`). Right-click on `wwwroot\js` and select Add → New Item. Select ASP.NET Core → Web → Scripts → JavaScript File, enter "tutorial.jsx" as the file name, and click "Add". + +For the remainder of this tutorial, we'll be writing our JavaScript code in this file. + +### Your first component + +React is all about modular, composable components. For our comment box example, we'll have the following component structure: + +``` +- CommentBox + - CommentList + - Comment + - CommentForm +``` + +Let's build the `CommentBox` component, which displays a simple `
`. Add this code to `Tutorial.jsx`: + +```javascript +class CommentBox extends React.Component { + render() { + return ( +
Hello, world! I am a CommentBox.
+ ); + } +} + +ReactDOM.render(, document.getElementById('content')); +``` + +Note that native HTML element names start with a lowercase letter, while custom React class names begin with an uppercase letter. + +At this point, run your application by clicking the "Play" button in Visual Studio. If successful, your default browser should start and you should see "Hello, world! I am a CommentBox." + +Screenshot: Hello ReactJS.NET World! + +If you see this, congratulations! You've just built your first React component. You can leave the application running while you continue this tutorial. Simply change the JSX file and refresh to see your changes. + +#### JSX Syntax + +The first thing you'll notice is the XML-ish syntax in your JavaScript. We have a simple precompiler that translates the syntactic sugar to this plain JavaScript: + +```javascript +class CommentBox extends React.Component { + render() { + return React.createElement( + 'div', + { className: 'commentBox' }, + 'Hello, world! I am a CommentBox.', + ); + } +} + +ReactDOM.render( + React.createElement(CommentBox, null), + document.getElementById('content'), +); +``` + +Its use is optional but we've found JSX syntax easier to use than plain JavaScript. Read more in React's ["JSX In Depth"](https://reactjs.org/docs/jsx-in-depth.html) article. + +#### What's going on + +We are defining a new JavaScript class that extends from the React.Component class. In our class, we will define some properties and some methods to build from what React.Component already gives us. The most important of these methods is called `render` which returns a tree of React components that will eventually render to HTML. + +The `
` tags are not actual DOM nodes; they are instantiations of React `div` components. You can think of these as markers or pieces of data that React knows how to handle. React is **safe**. We are not generating HTML strings so XSS protection is the default. + +You do not have to return basic HTML. You can return a tree of components that you (or someone else) built. This is what makes React **composable**: a key tenet of maintainable frontends. + +`ReactDOM.render()` instantiates the root component, starts the framework, and injects the markup into a raw DOM element, provided as the second argument. + +The `ReactDOM` module exposes DOM-specific methods, while `React` has the core tools shared by React on different platforms (e.g., [React Native](https://reactnative.dev/)). + +## Composing components + +Let's build skeletons for `CommentList` and `CommentForm` which will, again, be simple `
`s. Add these two components to your file, keeping the existing `CommentBox` declaration and `ReactDOM.render` call: + +```javascript +class CommentList extends React.Component { + render() { + return ( +
Hello, world! I am a CommentList.
+ ); + } +} + +class CommentForm extends React.Component { + render() { + return ( +
Hello, world! I am a CommentForm.
+ ); + } +} +``` + +Next, update the `CommentBox` component to use these new components: + +```javascript{5-7} +class CommentBox extends React.Component { + render() { + return ( +
+

Comments

+ + +
+ ); + } +} +``` + +Notice how we're mixing HTML tags and components we've built. HTML tags are React components just like the ones you define, but they have one difference. The JSX compiler will automatically rewrite HTML tags to `React.createElement(tagName)` expressions and leave everything else alone. This is to prevent the pollution of the global namespace. + +### Using props + +Let's create the `Comment` component, which will depend on data passed in from our `CommentList` component. Data passed in from the `CommentList` component is available as a 'property' on our `Comment` component. These 'properties' are accessed through `this.props`. Using props, we will be able to read the data passed to the `Comment` from the `CommentList`, and render some markup: + +```javascript +class Comment extends React.Component { + render() { + return ( +
+

{this.props.author}

+ {this.props.children} +
+ ); + } +} +``` + +By surrounding a JavaScript expression with braces inside JSX (as either an attribute or child), you can drop text or React components into the tree. We access named attributes passed to the component as keys on `this.props` and any nested elements as `this.props.children`. + +### Component Properties + +Now that we have defined the `Comment` component, we will want to pass it the author name and comment text. This allows us to reuse the same code for each unique comment. Now let's add some comments within our `CommentList`: + +```javascript{5-7} +class CommentList extends React.Component { + render() { + return ( +
+ + Hello ReactJS.NET World! + + This is one comment + + This is *another* comment + +
+ ); + } +} +``` + +Note that we have passed some data from the parent `CommentList` component to the child `Comment` components. For example, we passed _Daniel Lo Nigro_ (via the `author` attribute) and _Hello ReactJS.NET World_ (via an XML-like child node) to the first `Comment`. As noted above, the `Comment` component will access these 'properties' through `this.props.author`, and `this.props.children`. + +### Adding Markdown + +Markdown is a simple way to format your text inline. For example, surrounding text with asterisks will make it emphasized. + +In this tutorial we use a third-party library called [remarkable](https://github.com/jonschlinkert/remarkable) which takes Markdown text and converts it to raw HTML. We already included this library with the original markup for the page, so we can start using it right away. Let's convert the comment text to Markdown and output it: + +```javascript{12,18} +function createRemarkable() { + var remarkable = + 'undefined' != typeof global && global.Remarkable + ? global.Remarkable + : window.Remarkable; + + return new remarkable(); +} + +class Comment extends React.Component { + render() { + const md = createRemarkable(); + return ( +
+

{this.props.author}

+ {md.render(this.props.children.toString())} +
+ ); + } +} +``` + +All we're doing here is finding and calling the remarkable library. We need to convert `this.props.children` from React's wrapped text to a raw string that remarkable will understand so we explicitly call `toString()`. + +But there's a problem! Our rendered comments look like this in the browser: "`

`This is ``another`` comment`

`". We want those tags to actually render as HTML. + +That's React protecting you from an [XSS attack](https://en.wikipedia.org/wiki/Cross-site_scripting). There's a way to get around it but the framework warns you not to use it: + +```javascript{2-6,13} +class Comment extends React.Component { + rawMarkup() { + const md = new Remarkable(); + const rawMarkup = md.render(this.props.children.toString()); + return { __html: rawMarkup }; + } + render() { + return ( +
+

{this.props.author}

+ +
+ ); + } +} +``` + +This is a special API that intentionally makes it difficult to insert raw HTML, but for remarkable we'll take advantage of this backdoor. + +**Remember:** by using this feature you're relying on remarkable to be secure. In this case, remarkable automatically strips HTML markup and insecure links from the output. + +### Hook up the data model + +So far we've been inserting the comments directly in the source code. Instead, let's render a blob of JSON data into the comment list. Eventually this will come from the server, but for now, write it in your source: + +```javascript +const data = [ + { id: 1, author: 'Daniel Lo Nigro', text: 'Hello ReactJS.NET World!' }, + { id: 2, author: 'Pete Hunt', text: 'This is one comment' }, + { id: 3, author: 'Jordan Walke', text: 'This is *another* comment' }, +]; +``` + +We need to get this data into `CommentList` in a modular way. Modify `CommentBox` and the `ReactDOM.render()` call to pass this data into the `CommentList` via props: + +```javascript{6,13} +class CommentBox extends React.Component { + render() { + return ( +
+

Comments

+ + +
+ ); + } +} + +ReactDOM.render(, document.getElementById('content')); +``` + +Now that the data is available in the `CommentList`, let's render the comments dynamically: + +```javascript{3-8} +class CommentList extends React.Component { + render() { + const commentNodes = this.props.data.map(comment => ( + + {comment.text} + + )); + return
{commentNodes}
; + } +} +``` + +That's it! + +### Server-side Data + +Let's return some data from the server. If you are still debugging, end it by pressing the Stop button. To do so, we need to first create a C# class to represent our comments. You should have a "Models" folder, but if not, right-click on ReactDemo and select Add → New Folder and name the folder "Models". Once the models folder exists, right click on it, select Add → Class..., and enter "CommentModel.cs" as the file name. We'll create a basic comment model: + +```csharp +namespace ReactDemo.Models +{ + public class CommentModel + { + public int Id { get; set; } + public string Author { get; set; } + public string Text { get; set; } + } +} +``` + +In a real application, you'd use the repository pattern here, and retrieve the comments from a database. For simplicity, we'll modify our controller to have a hard-coded list of comments. + +```csharp{9,13-33} +using System.Collections.Generic; +using Microsoft.AspNetCore.Mvc; +using ReactDemo.Models; + +namespace ReactDemo.Controllers +{ + public class HomeController : Controller + { + private static readonly IList _comments; + + static HomeController() + { + _comments = new List + { + new CommentModel + { + Id = 1, + Author = "Daniel Lo Nigro", + Text = "Hello ReactJS.NET World!" + }, + new CommentModel + { + Id = 2, + Author = "Pete Hunt", + Text = "This is one comment" + }, + new CommentModel + { + Id = 3, + Author = "Jordan Walke", + Text = "This is *another* comment" + }, + }; + } + + public ActionResult Index() + { + return View(); + } + } +} +``` + +Let's also add a new controller action to return the list of comments: + +```csharp +[Route("comments")] +[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)] +public ActionResult Comments() +{ + return Json(_comments); +} +``` + +The `Route` attribute specifies that this action should be used when `/comments` is loaded. This method of defining URL routes is known as "attribute routing". + +The `ResponseCache` attribute is used here to prevent browsers from caching the response. When designing a real world API, caching of API requests should be considered more carefully. For this tutorial it is easiest to simply disable caching. + +Let's restart debugging (press the play button) and hit `/comments` in your browser, you should now see the data encoded as JSON: + +Screenshot: JSON data source + +### Fetching from the server + +Now that we have a data source, we can replace the hard-coded data with the dynamic data from the server. We will remove the data prop and replace it with a URL to fetch: + +```javascript{2} +ReactDOM.render( + , + document.getElementById('content') +); +``` + +Note that in a real app, you should generate the URL server-side (via `Url.Action` call) and pass it down, or use [RouteJs](https://github.com/Daniel15/RouteJs) rather than hard-coding it. This tutorial hard-codes it for simplicity. + +This component is different from the prior components because it will have to re-render itself. The component won't have any data until the request from the server comes back, at which point the component may need to render some new comments. + +### Reactive state + +So far, based on its props, each component has rendered itself once. `props` are immutable: they are passed from the parent and are "owned" by the parent. To implement interactions, we introduce mutable **state** to the component. `this.state` is private to the component and can be changed by calling `this.setState()` and passing an object that represents changes in state. When the state updates, the component re-renders itself. + +`render()` methods are written declaratively as functions of `this.props` and `this.state`. The framework guarantees the UI is always consistent with the inputs. + +When the server fetches data, we will be changing the comment data we have. Let's add an array of comment data to the `CommentBox` component as its state: + +```javascript{2-5,10} +class CommentBox extends React.Component { + constructor(props) { + super(props); + this.state = { data: [] }; + } + render() { + return ( +
+

Comments

+ + +
+ ); + } +} +``` + +The `constructor()` executes exactly once during the lifecycle of the component and sets up the initial state of the component. Remember to call the super class (the class we're extending, React.Component) via `super(props)` before using the `this` keyword. + +#### Updating state + +When the component is first created, we want to GET some JSON from the server and update the state to reflect the latest data. We'll use the standard XMLHttpRequest API to retrieve the data. If you need support for old browsers (mainly old Internet Explorer), you can use an AJAX library or a multipurpose library such as jQuery. `componentWillMount()` executes immediately and only once before the rendering occurs. In the following example, `componentWillMount()` loads the data from our XMLHttpRequest and assigns it to the `data` variable. Finally, it sets the `data` variable in state, using `setState()`. + +```javascript{6-14} +class CommentBox extends React.Component { + constructor(props) { + super(props); + this.state = { data: [] }; + } + componentWillMount() { + const xhr = new XMLHttpRequest(); + xhr.open('get', this.props.url, true); + xhr.onload = () => { + const data = JSON.parse(xhr.responseText); + this.setState({ data: data }); + }; + xhr.send(); + } + render() { + return ( +
+

Comments

+ + +
+ ); + } +} +``` + +Below, we're using `componentDidMount()`, a method called automatically by React _after_ a component is rendered for the first time. By moving the XMLHttpRequest call from `componentWillMount()`, which is executed only once _before_ rendering, to a function called `loadCommentsFromServer()`, we can then call it multiple times from `componentDidMount()` at a set interval to check for any updates to the comments. + +The key to these dynamic updates is the call to `this.setState()`. We replace the old array of comments with the new one from the server and the UI automatically updates itself. Because of this reactivity, it is only a minor change to add live updates. We will use simple polling here but you could easily use [SignalR](http://signalr.net/) or other technologies. + +```javascript{6,15-21,34} +class CommentBox extends React.Component { + constructor(props) { + super(props); + this.state = { data: [] }; + } + loadCommentsFromServer() { + const xhr = new XMLHttpRequest(); + xhr.open('get', this.props.url, true); + xhr.onload = () => { + const data = JSON.parse(xhr.responseText); + this.setState({ data: data }); + }; + xhr.send(); + } + componentDidMount() { + this.loadCommentsFromServer(); + window.setInterval( + () => this.loadCommentsFromServer(), + this.props.pollInterval, + ); + } + render() { + return ( +
+

Comments

+ + +
+ ); + } +} + +ReactDOM.render( + , + document.getElementById('content'), +); +``` + +All we have done here is move the AJAX call to a separate method and call it when the component is first loaded and every 2 seconds after that. + +### Adding new comments + +To accept new comments, we need to first add a controller action to handle it. This will be some simple C# code that appends the new comment to the static list of comments: + +```csharp +[Route("comments/new")] +[HttpPost] +public ActionResult AddComment(CommentModel comment) +{ + // Create a fake ID for this comment + comment.Id = _comments.Count + 1; + _comments.Add(comment); + return Content("Success :)"); +} +``` + +#### The Form + +Now it's time to build the form. Our `CommentForm` component should ask the user for their name and comment text and send a request to the server to save the comment. + +```javascript{4-8} +class CommentForm extends React.Component { + render() { + return ( +
+ + + +
+ ); + } +} +``` + +#### Controlled components + +With the traditional DOM, `input` elements are rendered and the browser manages the state (its rendered value). As a result, the state of the actual DOM will differ from that of the component. This is not ideal as the state of the view will differ from that of the component. In React, components should always represent the state of the view and not only at the point of initialization. + +Hence, we will be using `this.state` to save the user's input as it is entered. We define an initial `state` with two properties `author` and `text` and set them to be empty strings. In our `` elements, we set the `value` prop to reflect the `state` of the component and attach `onChange` handlers to them. These `` elements with a `value` set are called controlled components. Read more about controlled components on the [Forms article](https://reactjs.org/docs/forms.html#controlled-components). + +```javascript{2-13,17-28} +class CommentForm extends React.Component { + constructor(props) { + super(props); + this.state = { author: '', text: '' }; + this.handleAuthorChange = this.handleAuthorChange.bind(this); + this.handleTextChange = this.handleTextChange.bind(this); + } + handleAuthorChange(e) { + this.setState({ author: e.target.value }); + } + handleTextChange(e) { + this.setState({ text: e.target.value }); + } + render() { + return ( +
+ + + +
+ ); + } +} +``` + +#### Events + +React attaches event handlers to components using a camelCase naming convention. We attach `onChange` handlers to the two `` elements. Now, as the user enters text into the `` fields, the attached `onChange` callbacks are fired and the `state` of the component is modified. Subsequently, the rendered value of the `input` element will be updated to reflect the current component `state`. + +You'll notice that we are explicitly binding our event handlers to `this` in the constructor. While older techniques, like `React.createClass(...)`, featured automatic binding, we are using ES6 classes to define our components. React components declared as ES6 classes don't automatically bind `this` to the instance, so we have to explicitly use `.bind(this)`. + +For components with many event handlers, this explicit binding approach can get tedious. It's also easy to forget to declare your bindings which can cause some baffling bugs. React does offer two other techniques for ensuring your event handlers are bound properly to your component. Check out the [Handling Events](https://reactjs.org/docs/handling-events.html) documentation on the React website for more information. + +#### Submitting the form + +Let's make the form interactive. When the user submits the form, we should clear it, submit a request to the server, and refresh the list of comments. To start, let's listen for the form's submit event and clear it. + +```javascript{7,15-24,27} +class CommentForm extends React.Component { + constructor(props) { + super(props); + this.state = { author: '', text: '' }; + this.handleAuthorChange = this.handleAuthorChange.bind(this); + this.handleTextChange = this.handleTextChange.bind(this); + this.handleSubmit = this.handleSubmit.bind(this); + } + handleAuthorChange(e) { + this.setState({ author: e.target.value }); + } + handleTextChange(e) { + this.setState({ text: e.target.value }); + } + handleSubmit(e) { + e.preventDefault(); + const author = this.state.author.trim(); + const text = this.state.text.trim(); + if (!text || !author) { + return; + } + // TODO: send request to the server + this.setState({ author: '', text: '' }); + } + render() { + return ( +
+ + + +
+ ); + } +} +``` + +We attach an `onSubmit` handler to the form that clears the form fields when the form is submitted with valid input. We call `preventDefault()` on the event to prevent the browser's default action of submitting the form. + +#### Callbacks as props + +When a user submits a comment, we will need to refresh the list of comments to include the new one. It makes sense to do all of this logic in `CommentBox` since `CommentBox` owns the state that represents the list of comments. + +We need to pass data from the child component back up to its parent. We do this in our parent's `render` method by passing a new callback (`handleCommentSubmit`) into the child, binding it to the child's `onCommentSubmit` event. Whenever the event is triggered, the callback will be invoked: + +```javascript{5,16-18,31} +class CommentBox extends React.Component { + constructor(props) { + super(props); + this.state = { data: [] }; + this.handleCommentSubmit = this.handleCommentSubmit.bind(this); + } + loadCommentsFromServer() { + const xhr = new XMLHttpRequest(); + xhr.open('get', this.props.url, true); + xhr.onload = () => { + const data = JSON.parse(xhr.responseText); + this.setState({ data: data }); + }; + xhr.send(); + } + handleCommentSubmit(comment) { + // TODO: submit to the server and refresh the list + } + componentDidMount() { + this.loadCommentsFromServer(); + window.setInterval( + () => this.loadCommentsFromServer(), + this.props.pollInterval, + ); + } + render() { + return ( +
+

Comments

+ + +
+ ); + } +} +``` + +Now that `CommentBox` has made the callback available to `CommentForm` via the `onCommentSubmit` prop, the `CommentForm` can call the callback when the user submits the form: + +```javascript{22} +class CommentForm extends React.Component { + constructor(props) { + super(props); + this.state = { author: '', text: '' }; + this.handleAuthorChange = this.handleAuthorChange.bind(this); + this.handleTextChange = this.handleTextChange.bind(this); + this.handleSubmit = this.handleSubmit.bind(this); + } + handleAuthorChange(e) { + this.setState({ author: e.target.value }); + } + handleTextChange(e) { + this.setState({ text: e.target.value }); + } + handleSubmit(e) { + e.preventDefault(); + const author = this.state.author.trim(); + const text = this.state.text.trim(); + if (!text || !author) { + return; + } + this.props.onCommentSubmit({ author: author, text: text }); + this.setState({ author: '', text: '' }); + } + render() { + return ( +
+ + + +
+ ); + } +} +``` + +Now that the callbacks are in place, all we have to do is submit to the server and refresh the list: + +```javascript{16-25,45-49} +class CommentBox extends React.Component { + constructor(props) { + super(props); + this.state = { data: [] }; + this.handleCommentSubmit = this.handleCommentSubmit.bind(this); + } + loadCommentsFromServer() { + const xhr = new XMLHttpRequest(); + xhr.open('get', this.props.url, true); + xhr.onload = () => { + const data = JSON.parse(xhr.responseText); + this.setState({ data: data }); + }; + xhr.send(); + } + handleCommentSubmit(comment) { + const data = new FormData(); + data.append('Author', comment.author); + data.append('Text', comment.text); + + const xhr = new XMLHttpRequest(); + xhr.open('post', this.props.submitUrl, true); + xhr.onload = () => this.loadCommentsFromServer(); + xhr.send(data); + } + componentDidMount() { + this.loadCommentsFromServer(); + window.setInterval( + () => this.loadCommentsFromServer(), + this.props.pollInterval, + ); + } + render() { + return ( +
+

Comments

+ + +
+ ); + } +} + +ReactDOM.render( + , + document.getElementById('content'), +); +``` + +## Congrats! + +You have just built a comment box in a few simple steps. The below tweaks are not absolutely necessary, but they will improve the performance and polish of your application, so we suggest reading through them. :) + +We hope you have enjoyed learning about React and how ReactJS.NET allows you to easily use it from an ASP.NET MVC web application. Learn more about [React from the project homepage](https://reactjs.org/) and how to [think about React components](https://reactjs.org/docs/thinking-in-react.html), or dive into the [API reference](https://reactjs.org/docs/react-api.html) and start hacking! + +Continue on for more awesomeness! + +## Optimization: optimistic updates + +Our application is now feature complete but it feels slow to have to wait for the request to complete before your comment appears in the list. We can optimistically add this comment to the list to make the app feel faster. + +```javascript{17-23} +class CommentBox extends React.Component { + constructor(props) { + super(props); + this.state = { data: [] }; + this.handleCommentSubmit = this.handleCommentSubmit.bind(this); + } + loadCommentsFromServer() { + const xhr = new XMLHttpRequest(); + xhr.open('get', this.props.url, true); + xhr.onload = () => { + const data = JSON.parse(xhr.responseText); + this.setState({ data: data }); + }; + xhr.send(); + } + handleCommentSubmit(comment) { + const comments = this.state.data; + // Optimistically set an id on the new comment. It will be replaced by an + // id generated by the server. In a production application you would likely + // use a more robust system for ID generation. + comment.id = comments.length + 1; + const newComments = comments.concat([comment]); + this.setState({ data: newComments }); + + const data = new FormData(); + data.append('Author', comment.author); + data.append('Text', comment.text); + + const xhr = new XMLHttpRequest(); + xhr.open('post', this.props.submitUrl, true); + xhr.onload = () => this.loadCommentsFromServer(); + xhr.send(data); + } + componentDidMount() { + this.loadCommentsFromServer(); + window.setInterval( + () => this.loadCommentsFromServer(), + this.props.pollInterval, + ); + } + render() { + return ( +
+

Comments

+ + +
+ ); + } +} +``` + +## Optimization: Bundling and minification + +Bundling refers to the practice of combining multiple JavaScript files into a single large file to reduce the number of HTTP requests to load a page. Minification refers to the removal of comments and unnecessary whitespace from JavaScript files to make them smaller. Together, bundling and minification can help to significantly improve the performance of your website. + +There used to be a section on bundling and minification in this tutorial, but unfortunately the latest library being used by ASP.NET Core MVC ([BundlerMinifier](https://github.com/madskristensen/BundlerMinifier)) is not easily extensible, which makes it difficult to add JSX processing to it. For production use, it is currently recommended to use a tool like Gulp or [Webpack](/guides/webpack.html) to bundle and minify your JavaScript. + +## Optimization: Server-side rendering + +Server-side rendering means that your application initially renders the components on the server-side, rather than fetching data from the server and rendering using the client. Server-side rendering enhances the performance of your application since the user will see the initial state immediately. + +We need to make some modifications to `CommentBox` to support server-side rendering. Firstly, we need to accept an `initialData` prop, which will be used to set the initial state of the component, rather than doing an AJAX request. We also need to remove the initial `loadCommentsFromServer` call from `componentDidMount`, since it is no longer required. + +```javascript{4,31-33} +class CommentBox extends React.Component { + constructor(props) { + super(props); + this.state = { data: this.props.initialData }; + this.handleCommentSubmit = this.handleCommentSubmit.bind(this); + } + loadCommentsFromServer() { + const xhr = new XMLHttpRequest(); + xhr.open('get', this.props.url, true); + xhr.onload = () => { + const data = JSON.parse(xhr.responseText); + this.setState({ data: data }); + }; + xhr.send(); + } + handleCommentSubmit(comment) { + const comments = this.state.data; + comment.Id = comments.length + 1; + const newComments = comments.concat([comment]); + this.setState({ data: newComments }); + + const data = new FormData(); + data.append('Author', comment.Author); + data.append('Text', comment.Text); + + const xhr = new XMLHttpRequest(); + xhr.open('post', this.props.submitUrl, true); + xhr.onload = () => this.loadCommentsFromServer(); + xhr.send(data); + } + componentDidMount() { + window.setInterval( + () => this.loadCommentsFromServer(), + this.props.pollInterval, + ); + } + render() { + return ( +
+

Comments

+ + +
+ ); + } +} +``` + +Also, we need to remove the `ReactDOM.render` call from the JSX file, as server-side rendering automatically outputs the correct `ReactDOM.render` call for you. + +```csharp +// ReactDOM.render( +// , +// document.getElementById('content') +// ); +``` + +We need to update the Comment component to use Remarkable from either global or window, due to a bug in Remarkable. A utility function was provided earlier in the tutorial. + +```javascript{3} +class Comment extends React.Component { + rawMarkup() { + const md = createRemarkable(); + const rawMarkup = md.render(this.props.children.toString()); + return { __html: rawMarkup }; + } +``` + +In the view, we will accept the list of comments as the model, and use `Html.React` to render the component. This will replace the `ReactDOM.render` call that currently exists in Tutorial.jsx. All the props from the current `ReactDOM.render` call should be moved here, and the `ReactDOM.render` call should be deleted. + +```html{1,10-16,21} +@model IEnumerable +@{ + Layout = null; +} + + + Hello React + + + @Html.React("CommentBox", new + { + initialData = Model, + url = Url.Action("Comments"), + submitUrl = Url.Action("AddComment"), + pollInterval = 2000, + }) + + + + + @Html.ReactInitJavaScript() + + +``` + +We need to modify the controller action to pass the data to the view: + +```csharp{3} +public ActionResult Index() +{ + return View(_comments); +} +``` + +We also need to modify `Startup.cs` to tell ReactJS.NET which JavaScript files it requires for the server-side rendering: + +```csharp{4-6} +// Initialise ReactJS.NET. Must be before static files. +app.UseReact(config => +{ + config + .AddScript("~/js/remarkable.min.js") + .AddScript("~/js/tutorial.jsx"); +}); +``` + +Note that we need a copy of Remarkable in order to load it for server-side rendering. In a production app you'd probably use Bower or npm for this, but for our tutorial you can [download the file from CDNJS](https://cdnjs.cloudflare.com/ajax/libs/remarkable/1.7.1/remarkable.min.js) and save it into `~/js`. + +That's it! Now if you build and refresh your application, you should notice that the comments box is rendered immediately rather than having a slight delay. If you view the source of the page, you will see the initial comments directly in the HTML itself: + +```html + + + Hello React + + +
+
Comments +
+
+

Daniel Lo Nigro

+

Hello ReactJS.NET World!

+
+ + +``` diff --git a/site/nginx.conf b/site/nginx.conf index b2abdda0e..bd7ee24f3 100644 --- a/site/nginx.conf +++ b/site/nginx.conf @@ -1,24 +1,28 @@ server { + listen 80; + server_name reactjs.net localdev.reactjs.net; + return 301 https://$host$request_uri; +} + +server { + listen 443 ssl http2; server_name reactjs.net localdev.reactjs.net; root /var/www/reactjs.net/site/public/; index index.html index.php; + ssl_certificate /etc/letsencrypt/live/reactjs.net/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/reactjs.net/privkey.pem; + # Shortcuts rewrite ^/download$ /getting-started/download.html redirect; rewrite ^/docs$ /getting-started/download.html redirect; - rewrite ^/packages/$ /packages/index.php; - rewrite ^/packages/\$metadata$ /packages/metadata.xml; - rewrite ^/packages/Search\(\)/\$count$ /packages/count.php; - rewrite ^/packages/Search\(\)$ /packages/search.php; - rewrite ^/packages/Packages\(\)$ /packages/search.php; - rewrite ^/packages/Packages\(Id='([^']+)',Version='([^']+)'\)$ /packages/findByID.php?id=$1&version=$2; - rewrite ^/packages/GetUpdates\(\)$ /packages/updates.php; - rewrite ^/packages/FindPackagesById\(\)$ /packages/findByID.php; - rewrite ^/packages/download/([^/]+)/([^/]+)$ /packages/download.php?id=$1&version=$2; + # Old documentation URLs + rewrite ^/getting-started/aspnet5.html$ /getting-started/aspnetcore.html permanent; # Old package URLs - rewrite ^/dev/packages/(.*)$ /packages/$1 permanent; + rewrite ^/packages/(.*)$ https://ci.appveyor.com/nuget/reactjs.net/$1 permanent; + rewrite ^/dev/packages/(.*)$ https://ci.appveyor.com/nuget/reactjs.net/$1 permanent; # Far future expires header for combined assets location /assets { @@ -40,11 +44,4 @@ server { fastcgi_param REQUEST_METHOD POST; fastcgi_param HTTP_X_METHOD_OVERRIDE $request_method; } - - # Used with X-Accel-Redirect - location /packagefiles { - internal; - root /var/www/reactjs.net/site/packages/; - } } - diff --git a/site/packages b/site/packages deleted file mode 160000 index 960c39412..000000000 --- a/site/packages +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 960c39412a7b819f2ef2d5584411531aebb967ac diff --git a/site/public/2015 b/site/public/2015 new file mode 120000 index 000000000..3766411aa --- /dev/null +++ b/site/public/2015 @@ -0,0 +1 @@ +../jekyll/_site/2015 \ No newline at end of file diff --git a/site/public/2016 b/site/public/2016 new file mode 120000 index 000000000..a0969822b --- /dev/null +++ b/site/public/2016 @@ -0,0 +1 @@ +../jekyll/_site/2016 \ No newline at end of file diff --git a/src/.nuget/packages.config b/src/.nuget/packages.config deleted file mode 100644 index 7025a729d..000000000 --- a/src/.nuget/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/Cassette.React/AssemblyRegistration.cs b/src/Cassette.React/AssemblyRegistration.cs index 9f42d6b34..18d3ce015 100644 --- a/src/Cassette.React/AssemblyRegistration.cs +++ b/src/Cassette.React/AssemblyRegistration.cs @@ -1,10 +1,8 @@ /* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ using React; diff --git a/src/Cassette.React/BabelBundleProcessor.cs b/src/Cassette.React/BabelBundleProcessor.cs new file mode 100644 index 000000000..5126ad148 --- /dev/null +++ b/src/Cassette.React/BabelBundleProcessor.cs @@ -0,0 +1,48 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using Cassette.BundleProcessing; +using Cassette.Scripts; +using React; + +namespace Cassette.React +{ + /// + /// Handles processing of script bundles in Cassette. Adds a + /// for all .js and .jsx files. + /// + public class BabelBundleProcessor : IBundleProcessor + { + private readonly CassetteSettings _settings; + private readonly IReactEnvironment _environment; + + /// + /// Initializes a new instance of the class. + /// + /// Cassette settings. + /// The ReactJS.NET environment + public BabelBundleProcessor(CassetteSettings settings, IReactEnvironment environment) + { + _settings = settings; + _environment = environment; + } + + /// + /// Processes the specified bundle. Adds a for all files. + /// + /// The bundle. + public void Process(ScriptBundle bundle) + { + foreach (var asset in bundle.Assets) + { + asset.AddAssetTransformer( + new CompileAsset(new BabelCompiler(_environment), _settings.SourceDirectory) + ); + } + } + } +} diff --git a/src/Cassette.React/BabelCompiler.cs b/src/Cassette.React/BabelCompiler.cs new file mode 100644 index 000000000..d14010daf --- /dev/null +++ b/src/Cassette.React/BabelCompiler.cs @@ -0,0 +1,45 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System.IO; +using System.Linq; +using React; + +namespace Cassette.React +{ + /// + /// Handles compilation of JavaScript files via Babel in Cassette + /// + public class BabelCompiler : ICompiler + { + private readonly IReactEnvironment _environment; + + /// + /// Initializes a new instance of the class. + /// + /// The ReactJS.NET environment + public BabelCompiler(IReactEnvironment environment) + { + _environment = environment; + } + + /// + /// Compiles the specified JavaScript file via Babel + /// + /// The source. + /// The context. + /// JavaScript + public CompileResult Compile(string source, CompileContext context) + { + var output = _environment.Babel.Transform( + source, + Path.GetFileName(context.SourceFilePath) + ); + return new CompileResult(output, Enumerable.Empty()); + } + } +} diff --git a/src/Cassette.React/Cassette.React.csproj b/src/Cassette.React/Cassette.React.csproj index 5b8335e53..f278c05c7 100644 --- a/src/Cassette.React/Cassette.React.csproj +++ b/src/Cassette.React/Cassette.React.csproj @@ -1,93 +1,45 @@ - - - + + - Debug - AnyCPU - {F591F1E8-3D6B-494A-B72A-152FCCA6210D} - Library - Properties - Cassette.React + Allows you to transpile JavaScript via Babel using Cassette. + Copyright 2014-Present Facebook, Inc + ReactJS.NET - Babel for Cassette + Daniel Lo Nigro + net40 + true Cassette.React - v4.0 - 512 - - - true - full - false - ..\..\bin\Debug\Cassette.React\ - DEBUG;TRACE - prompt - 4 - 1607 - ..\..\bin\Debug\Cassette.React\Cassette.React.XML - - - pdbonly - true - ..\..\bin\Release\Cassette.React\ - TRACE - prompt - 4 - 1607 - true - ..\..\bin\Release\Cassette.React\Cassette.React.XML + Cassette.React + asp.net;mvc;asp;jquery;javascript;js;react;facebook;reactjs;babel;cassette + logo_64.png + https://github.com/reactjs/react.net + https://github.com/reactjs/React.NET#licence + false + true + true + $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb + true + snupkg + - - False - ..\packages\AjaxMin.4.84.4790.14417\lib\net40\AjaxMin.dll - - - False - ..\packages\Cassette.2.4.1\lib\net40-client\Cassette.dll - - - - - - - - + + + + - - Properties\SharedAssemblyInfo.cs - - - Properties\SharedAssemblyVersionInfo.cs - - - - - - - - - - + + - - + + + - - - {134edd16-8dc8-4983-a2e0-b38dab1ecf1c} - React.Web - - - {d0cc8a22-cee6-485c-924b-1f94426fea59} - React - + + + + - - - \ No newline at end of file + + diff --git a/src/Cassette.React/Cassette.React.nutrans b/src/Cassette.React/Cassette.React.nutrans deleted file mode 100644 index 1f4cdddb5..000000000 --- a/src/Cassette.React/Cassette.React.nutrans +++ /dev/null @@ -1,19 +0,0 @@ - - - - - ReactJS.NET - JSX for Cassette - Allows you to compile JSX to JavaScript using Cassette - asp.net mvc asp jquery javascript js react facebook reactjs cassette - - - diff --git a/src/Cassette.React/CassetteMSBuildStartup.cs b/src/Cassette.React/CassetteMSBuildStartup.cs index 0cb18af8f..8c41a27e0 100644 --- a/src/Cassette.React/CassetteMSBuildStartup.cs +++ b/src/Cassette.React/CassetteMSBuildStartup.cs @@ -1,14 +1,12 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. +/* + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ -using System; -using System.Diagnostics; +using JavaScriptEngineSwitcher.Core; +using JavaScriptEngineSwitcher.Msie; using React; namespace Cassette.React @@ -31,6 +29,9 @@ public void Start() return; } + JsEngineSwitcher.Current.DefaultEngineName = MsieJsEngine.EngineName; + JsEngineSwitcher.Current.EngineFactories.AddMsie(); + // All "per-request" registrations should be singletons in MSBuild, since there's no // such thing as a "request" Initializer.Initialize(requestLifetimeRegistration: registration => registration.AsSingleton()); diff --git a/src/Cassette.React/InsertIntoPipelineJsxBundleProcessor.cs b/src/Cassette.React/InsertIntoPipelineJsxBundleProcessor.cs index 6a5676e00..28a7f59cc 100644 --- a/src/Cassette.React/InsertIntoPipelineJsxBundleProcessor.cs +++ b/src/Cassette.React/InsertIntoPipelineJsxBundleProcessor.cs @@ -1,10 +1,8 @@ /* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ using Cassette.BundleProcessing; @@ -13,7 +11,7 @@ namespace Cassette.React { /// - /// Inserts the into the script bundle pipeline + /// Inserts the into the script bundle pipeline /// public class InsertIntoPipelineJsxBundleProcessor : IBundlePipelineModifier { @@ -25,7 +23,7 @@ public class InsertIntoPipelineJsxBundleProcessor : IBundlePipelineModifier Modify(IBundlePipeline pipeline) { var index = pipeline.IndexOf(); - pipeline.Insert(index + 1); + pipeline.Insert(index + 1); return pipeline; } } diff --git a/src/Cassette.React/JsxBundleProcessor.cs b/src/Cassette.React/JsxBundleProcessor.cs deleted file mode 100644 index 9dcc381c9..000000000 --- a/src/Cassette.React/JsxBundleProcessor.cs +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -using System; -using Cassette.BundleProcessing; -using Cassette.Scripts; -using React; - -namespace Cassette.React -{ - /// - /// Handles processing of script bundles in Cassette. Adds a - /// for all .jsx files. - /// - public class JsxBundleProcessor : IBundleProcessor - { - private readonly CassetteSettings _settings; - private readonly IReactEnvironment _environment; - - /// - /// Initializes a new instance of the class. - /// - /// Cassette settings. - /// The ReactJS.NET environment - public JsxBundleProcessor(CassetteSettings settings, IReactEnvironment environment) - { - _settings = settings; - _environment = environment; - } - - /// - /// Processes the specified bundle. Adds a for all .jsx files. - /// - /// The bundle. - public void Process(ScriptBundle bundle) - { - foreach (var asset in bundle.Assets) - { - if (asset.Path.EndsWith(".jsx", StringComparison.InvariantCultureIgnoreCase)) - { - asset.AddAssetTransformer( - new CompileAsset(new JsxCompiler(_environment), _settings.SourceDirectory) - ); - } - } - } - } -} diff --git a/src/Cassette.React/JsxCompiler.cs b/src/Cassette.React/JsxCompiler.cs deleted file mode 100644 index e9bdd0f58..000000000 --- a/src/Cassette.React/JsxCompiler.cs +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -using System.Linq; -using React; - -namespace Cassette.React -{ - /// - /// Handles compilation of JSX in Cassette - /// - public class JsxCompiler : ICompiler - { - private readonly IReactEnvironment _environment; - - /// - /// Initializes a new instance of the class. - /// - /// The ReactJS.NET environment - public JsxCompiler(IReactEnvironment environment) - { - _environment = environment; - } - - /// - /// Compiles the specified JSX file into JavaScript - /// - /// The source. - /// The context. - /// JavaScript - public CompileResult Compile(string source, CompileContext context) - { - var output = _environment.JsxTransformer.TransformJsx(source); - return new CompileResult(output, Enumerable.Empty()); - } - } -} diff --git a/src/Cassette.React/JsxFileSearchModifier.cs b/src/Cassette.React/JsxFileSearchModifier.cs index be9cdf075..5a6a378cb 100644 --- a/src/Cassette.React/JsxFileSearchModifier.cs +++ b/src/Cassette.React/JsxFileSearchModifier.cs @@ -1,10 +1,8 @@ /* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ using Cassette.Scripts; diff --git a/src/Cassette.React/MSBuildUtils.cs b/src/Cassette.React/MSBuildUtils.cs index 26850128b..afd429965 100644 --- a/src/Cassette.React/MSBuildUtils.cs +++ b/src/Cassette.React/MSBuildUtils.cs @@ -1,10 +1,8 @@ /* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ using System; diff --git a/src/Cassette.React/Properties/AssemblyInfo.cs b/src/Cassette.React/Properties/AssemblyInfo.cs index 3919d25a6..93fe22fe1 100644 --- a/src/Cassette.React/Properties/AssemblyInfo.cs +++ b/src/Cassette.React/Properties/AssemblyInfo.cs @@ -1,10 +1,8 @@ /* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ using System.Reflection; @@ -13,4 +11,4 @@ [assembly: AssemblyTitle("Cassette.React")] [assembly: AssemblyDescription("Cassette integration for ReactJS.NET")] [assembly: ComVisible(false)] -[assembly: Guid("06e9b63a-8a35-4eb6-b673-b7805b0dd31c")] \ No newline at end of file +[assembly: Guid("06e9b63a-8a35-4eb6-b673-b7805b0dd31c")] diff --git a/src/Cassette.React/ReactContainerConfiguration.cs b/src/Cassette.React/ReactContainerConfiguration.cs index 36613d0bf..85fcb82d4 100644 --- a/src/Cassette.React/ReactContainerConfiguration.cs +++ b/src/Cassette.React/ReactContainerConfiguration.cs @@ -1,10 +1,8 @@ /* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ using CassetteTinyIoCContainer = Cassette.TinyIoC.TinyIoCContainer; diff --git a/src/Cassette.React/packages.config b/src/Cassette.React/packages.config deleted file mode 100644 index bf1c04cb8..000000000 --- a/src/Cassette.React/packages.config +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/React.AspNet.Middleware/AspNetFileSystem.cs b/src/React.AspNet.Middleware/AspNetFileSystem.cs new file mode 100644 index 000000000..33289c792 --- /dev/null +++ b/src/React.AspNet.Middleware/AspNetFileSystem.cs @@ -0,0 +1,56 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System.IO; +using Microsoft.AspNetCore.Hosting; +using React.Exceptions; + +#if NETCOREAPP2_0 || NETSTANDARD2_0 +using IWebHostEnvironment = Microsoft.AspNetCore.Hosting.IHostingEnvironment; +#endif + +namespace React.AspNet +{ + /// + /// Handles file system functionality, such as reading files. Maps all paths from + /// application-relative (~/...) to full paths using ASP.NET's MapPath method. + /// + public class AspNetFileSystem : FileSystemBase + { + private readonly IWebHostEnvironment _hostingEnv; + + /// + /// Initializes a new instance of the class. + /// + /// The .NET Core hosting environment + public AspNetFileSystem(IWebHostEnvironment hostingEnv) + { + _hostingEnv = hostingEnv; + } + + /// + /// Converts a path from an application relative path (~/...) to a full filesystem path + /// + /// App-relative path of the file + /// Full path of the file + public override string MapPath(string relativePath) + { + if (_hostingEnv.WebRootPath == null) + { + throw new ReactException("WebRootPath was null, has the wwwroot folder been deployed along with your app?"); + } + + if (relativePath.StartsWith(_hostingEnv.WebRootPath)) + { + return relativePath; + } + relativePath = relativePath.TrimStart('~').TrimStart('/').TrimStart('\\'); + + return Path.GetFullPath(Path.Combine(_hostingEnv.WebRootPath, relativePath)); + } + } +} diff --git a/src/React.AspNet.Middleware/AssemblyRegistration.cs b/src/React.AspNet.Middleware/AssemblyRegistration.cs new file mode 100644 index 000000000..dd8e3082d --- /dev/null +++ b/src/React.AspNet.Middleware/AssemblyRegistration.cs @@ -0,0 +1,28 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using React.TinyIoC; + +namespace React.AspNet +{ + /// + /// Handles registration of ReactJS.NET components that are only applicable + /// in the context of an ASP.NET web application. + /// + public class AssemblyRegistration : IAssemblyRegistration + { + /// + /// Registers components in the React IoC container + /// + /// Container to register components in + public void Register(TinyIoCContainer container) + { + container.Register().AsSingleton(); + container.Register().AsSingleton(); + } + } +} diff --git a/src/React.AspNet.Middleware/BabelFileMiddleware.cs b/src/React.AspNet.Middleware/BabelFileMiddleware.cs new file mode 100644 index 000000000..06d127c43 --- /dev/null +++ b/src/React.AspNet.Middleware/BabelFileMiddleware.cs @@ -0,0 +1,99 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.StaticFiles; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; + +#if NETCOREAPP2_0 || NETSTANDARD2_0 +using IWebHostEnvironment = Microsoft.AspNetCore.Hosting.IHostingEnvironment; +#endif + +namespace React.AspNet +{ + /// + /// Enables serving static JavaScript files compiled via Babel. Wraps around StaticFileMiddleware. + /// + public class BabelFileMiddleware + { + private readonly RequestDelegate _next; + private readonly IWebHostEnvironment _hostingEnv; + private readonly ILoggerFactory _loggerFactory; + private readonly BabelFileOptions _options; + + /// + /// Creates a new instance of the BabelFileMiddleware. + /// + /// The next middleware in the pipeline. + /// The configuration options. + /// The hosting environment. + /// An instance used to create loggers. + public BabelFileMiddleware(RequestDelegate next, BabelFileOptions options, IWebHostEnvironment hostingEnv, ILoggerFactory loggerFactory) + { + if (next == null) + throw new ArgumentNullException("next"); + + _next = next; + _hostingEnv = hostingEnv; + _loggerFactory = loggerFactory; + + // Default values + _options = options ?? new BabelFileOptions(); + } + + /// + /// Processes a request to determine if it matches a known JavaScript file, and if so, transforms + /// it via Babel and serves it + /// + /// ASP.NET HTTP context + public async Task Invoke(HttpContext context) + { + if (!context.Request.Path.HasValue || !_options.Extensions.Any(context.Request.Path.Value.EndsWith)) + { + // Not a request for a JavaScript file, so just pass through to the next middleware + await _next(context); + return; + } + + var internalStaticMiddleware = CreateFileMiddleware(ReactEnvironment.Current.Babel); + await internalStaticMiddleware.Invoke(context); + } + + /// + /// Creates the internal used to serve files. + /// + /// + /// + private StaticFileMiddleware CreateFileMiddleware(IBabel babel) + { + return new StaticFileMiddleware( + _next, + _hostingEnv, + Options.Create(new StaticFileOptions + { + ContentTypeProvider = _options.StaticFileOptions.ContentTypeProvider, + DefaultContentType = _options.StaticFileOptions.DefaultContentType, + OnPrepareResponse = _options.StaticFileOptions.OnPrepareResponse, + RequestPath = _options.StaticFileOptions.RequestPath, + ServeUnknownFileTypes = _options.StaticFileOptions.ServeUnknownFileTypes, + FileProvider = new BabelFileSystem( + babel, + _options.StaticFileOptions.FileProvider ?? _hostingEnv.WebRootFileProvider, + _options.Extensions + ) + }), + _loggerFactory + ); + } + } +} diff --git a/src/React.AspNet.Middleware/BabelFileOptions.cs b/src/React.AspNet.Middleware/BabelFileOptions.cs new file mode 100644 index 000000000..875291580 --- /dev/null +++ b/src/React.AspNet.Middleware/BabelFileOptions.cs @@ -0,0 +1,55 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +using System.Collections.Generic; +#if OWIN +using Microsoft.Owin.StaticFiles; +using Microsoft.Owin.StaticFiles.ContentTypes; +#else +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.StaticFiles; +#endif + +#if OWIN +namespace React.Owin +#else +namespace React.AspNet +#endif +{ + /// + /// Options for serving JavaScript files transformed via Babel. + /// + public class BabelFileOptions + { + /// + /// Collection of extensions that will be handled. Defaults to ".jsx" and ".js". + /// + public IEnumerable Extensions { get; set; } + + /// + /// Options for static file middleware used to serve JavaScript files. + /// + public StaticFileOptions StaticFileOptions { get; set; } + + /// + /// Creates a new instance of the class. + /// + public BabelFileOptions() + { + Extensions = new[] { ".jsx", ".tsx" }; + StaticFileOptions = new StaticFileOptions() { ContentTypeProvider = new JsxContentTypeProvider() } ; + } + + private class JsxContentTypeProvider : IContentTypeProvider + { + public bool TryGetContentType(string subpath, out string contentType) + { + contentType = "text/javascript"; + return true; + } + } + } +} diff --git a/src/React.AspNet.Middleware/BabelFileSystem.cs b/src/React.AspNet.Middleware/BabelFileSystem.cs new file mode 100644 index 000000000..1dcd3d11b --- /dev/null +++ b/src/React.AspNet.Middleware/BabelFileSystem.cs @@ -0,0 +1,204 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +#if OWIN +using Microsoft.Owin.FileSystems; +using IOwinFileSystem = Microsoft.Owin.FileSystems.IFileSystem; +#else +using Microsoft.Extensions.FileProviders; +using Microsoft.Extensions.Primitives; +using IOwinFileSystem = Microsoft.Extensions.FileProviders.IFileProvider; +using PhysicalFileSystem = Microsoft.Extensions.FileProviders.PhysicalFileProvider; +#endif + +#if OWIN +namespace React.Owin +#else +namespace React.AspNet +#endif +{ + /// + /// File system that serves transformed JavaScript files. + /// + public class BabelFileSystem : IOwinFileSystem + { + private readonly IBabel _transformer; + private readonly IOwinFileSystem _physicalFileSystem; + private readonly string[] _extensions; + + /// + /// Creates a new instance of the BabelFileSystem. + /// + /// Babel transformer used to compile files + /// The root directory + /// Extensions of files that will be treated as JavaScript files + public BabelFileSystem(IBabel transformer, string root, IEnumerable extensions) + : this(transformer, new PhysicalFileSystem(root), extensions) + { + } + + /// + /// Creates a new instance of the BabelFileSystem. + /// + /// Babel transformer used to compile files + /// File system used to look up files + /// Extensions of files that will be treated as JavaScript files + public BabelFileSystem(IBabel transformer, IOwinFileSystem fileSystem, IEnumerable extensions) + { + _transformer = transformer; + _physicalFileSystem = fileSystem; + + if (extensions != null) + { + // Make sure the extensions start with dot + _extensions = extensions.Select(extension => extension.StartsWith(".") ? extension : "." + extension).ToArray(); + } + } + +#if OWIN + /// + /// Locate a JavaScript file at the given path. + /// + /// The path that identifies the file + /// The discovered file if any + /// + /// True if a JavaScript file was located at the given path + /// + public bool TryGetFileInfo(string subpath, out IFileInfo fileInfo) + { + IFileInfo internalFileInfo; + fileInfo = null; + + if (!_physicalFileSystem.TryGetFileInfo(subpath, out internalFileInfo)) + return false; + + if (_extensions != null && !_extensions.Any(internalFileInfo.Name.EndsWith)) + return false; + + if (internalFileInfo.IsDirectory) + return false; + + fileInfo = new BabelFileInfo(_transformer, internalFileInfo); + return true; + } + + /// + /// Enumerate a directory at the given path, if any + /// + /// The path that identifies the directory + /// The contents if any + /// + /// True if a directory was located at the given path + /// + public bool TryGetDirectoryContents(string subpath, out IEnumerable contents) + { + return _physicalFileSystem.TryGetDirectoryContents(subpath, out contents); + } +#else + + /// + /// Locate a file at the given path. + /// + /// The path that identifies the file + /// The discovered file if any + public IFileInfo GetFileInfo(string subpath) + { + var internalFileInfo = _physicalFileSystem.GetFileInfo(subpath); + return new BabelFileInfo(_transformer, internalFileInfo); + } + + /// + /// Enumerate a directory at the given path, if any + /// + /// The path that identifies the directory + /// The contents if any + public IDirectoryContents GetDirectoryContents(string subpath) + { + return _physicalFileSystem.GetDirectoryContents(subpath); + } + + /// + /// Creates a for the + /// specified . + /// + /// + /// Filter string used to determine what files or folders to monitor. + /// Example: **/*.cs, *.*, subFolder/**/*.cshtml. + /// + /// An that is notified + /// when a file matching is added, modified or deleted. + /// + public IChangeToken Watch(string filter) + { + return _physicalFileSystem.Watch(filter); + } +#endif + + private class BabelFileInfo : IFileInfo + { + private readonly IBabel _babel; + private readonly IFileInfo _fileInfo; + private readonly Lazy _content; + + public BabelFileInfo(IBabel babel, IFileInfo fileInfo) + { + _babel = babel; + _fileInfo = fileInfo; + + _content = new Lazy( + () => Encoding.UTF8.GetBytes(_babel.TransformFile(fileInfo.PhysicalPath)) + ); + } + + public Stream CreateReadStream() + { + return new MemoryStream(_content.Value); + } + + public long Length + { + get { return _content.Value.Length; } + } + + public string PhysicalPath + { + get { return null; } + } + + public string Name + { + get { return _fileInfo.Name; } + } + + public bool IsDirectory + { + get { return _fileInfo.IsDirectory; } + } + +#if OWIN + public DateTime LastModified + { + get { return _fileInfo.LastModified; } + } +#else + public DateTimeOffset LastModified + { + get { return _fileInfo.LastModified; } + } + + public bool Exists + { + get { return _fileInfo.Exists; } + } +#endif + } + } +} diff --git a/src/React.AspNet.Middleware/HttpContextLifetimeProvider.cs b/src/React.AspNet.Middleware/HttpContextLifetimeProvider.cs new file mode 100644 index 000000000..fc271e91b --- /dev/null +++ b/src/React.AspNet.Middleware/HttpContextLifetimeProvider.cs @@ -0,0 +1,123 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System; +using System.Collections.Concurrent; +using System.Linq; +using Microsoft.AspNetCore.Http; +using React.Exceptions; +using React.TinyIoC; +using Microsoft.Extensions.DependencyInjection; + +namespace React.AspNet +{ + /// + /// Handles registering per-request objects in the dependency injection container. + /// + internal class HttpContextLifetimeProvider : TinyIoCContainer.ITinyIoCObjectLifetimeProvider + { + private readonly IHttpContextAccessor _httpContextAccessor; + + /// + /// Creates a new . + /// + public HttpContextLifetimeProvider(IHttpContextAccessor httpContextAccessor) + { + if (httpContextAccessor == null) + { + throw new ReactNotInitialisedException( + "IHttpContextAccessor is not registered correctly. Please add it to your " + + "application startup:\n" + + "services.AddSingleton();" + ); + } + _httpContextAccessor = httpContextAccessor; + } + + /// + /// Prefix to use on HttpContext items + /// + private const string PREFIX = "React.PerRequest."; + + /// + /// Name of the key for this particular registration + /// + private readonly string _keyName = PREFIX + Guid.NewGuid(); + + /// + /// Gets the current per-request registrations for the current request. + /// + private PerRequestRegistrations Registrations + { + get + { + var requestServices = _httpContextAccessor.HttpContext.RequestServices; + var registrations = requestServices.GetService(); + if (registrations == null) + { + throw new ReactNotInitialisedException( + "ReactJS.NET has not been initialised correctly. Please ensure you have " + + "called services.AddReact() and app.UseReact() in your Startup.cs file." + ); + } + return registrations; + } + } + + /// + /// Gets the value of this item in the dependency injection container. + /// + /// + public object GetObject() + { + object value; + Registrations.TryGetValue(_keyName, out value); + return value; + } + + /// + /// Sets the value of this item in the dependency injection container. + /// + /// Value to set + public void SetObject(object value) + { + Registrations[_keyName] = value; + } + + /// + /// Removes this item from the dependency injection container. + /// + public void ReleaseObject() + { + object value; + if (Registrations.TryRemove(_keyName, out value)) + { + if (value is IDisposable) + { + ((IDisposable)value).Dispose(); + } + } + } + + /// + /// Contains all per-request dependency injection registrations. + /// + internal class PerRequestRegistrations : ConcurrentDictionary, IDisposable + { + /// + /// Disposes all registrations in this container. + /// + public void Dispose() + { + foreach (var kvp in this.Where(kvp => kvp.Value is IDisposable)) + { + ((IDisposable)kvp.Value).Dispose(); + } + } + } + } +} \ No newline at end of file diff --git a/src/React.AspNet.Middleware/MemoryFileCacheCore.cs b/src/React.AspNet.Middleware/MemoryFileCacheCore.cs new file mode 100644 index 000000000..87fc47c90 --- /dev/null +++ b/src/React.AspNet.Middleware/MemoryFileCacheCore.cs @@ -0,0 +1,91 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +using System; +using System.Collections.Generic; +using Microsoft.Extensions.Caching.Memory; +using System.Linq; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.FileProviders; + +#if NETCOREAPP2_0 || NETSTANDARD2_0 +using IWebHostEnvironment = Microsoft.AspNetCore.Hosting.IHostingEnvironment; +#endif + +namespace React.AspNet +{ + /// + /// Memory cache implementation for React.ICache. Uses IMemoryCache from .NET Core. + /// + public class MemoryFileCacheCore : ICache + { + private readonly IMemoryCache _cache; + private readonly IWebHostEnvironment _hostingEnv; + + /// + /// Initializes a new instance of the class. + /// + /// The cache to use + /// The ASP.NET hosting environment. + public MemoryFileCacheCore(IMemoryCache cache, IWebHostEnvironment hostingEnv) + { + _cache = cache; + _hostingEnv = hostingEnv; + } + + /// + /// Get an item from the cache. Returns if the item does + /// not exist. + /// + /// Type of data + /// The cache key + /// Value to return if item is not in the cache + /// Data from cache, otherwise + public T Get(string key, T fallback = default(T)) + { + return (T)(_cache.Get(key) ?? fallback); + } + + /// + /// Sets an item in the cache. + /// + /// Type of data + /// The cache key + /// Data to cache + /// + /// Sliding expiration, if cache key is not accessed in this time period it will + /// automatically be removed from the cache + /// + /// + /// Filenames this cached item is dependent on. If any of these files change, the cache + /// will be cleared automatically + /// + public void Set(string key, T data, TimeSpan slidingExpiration, IEnumerable cacheDependencyFiles = null) + { + if (data == null) + { + _cache.Remove(key); + return; + } + + var options = new MemoryCacheEntryOptions + { + SlidingExpiration = slidingExpiration, + }; + + if (cacheDependencyFiles != null) + { + foreach (var file in cacheDependencyFiles) + { + var relativePath = file.Replace(_hostingEnv.WebRootPath, string.Empty).TrimStart('\\', '/'); + options.AddExpirationToken(_hostingEnv.WebRootFileProvider.Watch(relativePath)); + } + } + + _cache.Set(key, data, options); + } + } +} diff --git a/src/React.AspNet.Middleware/React.AspNet.Middleware.csproj b/src/React.AspNet.Middleware/React.AspNet.Middleware.csproj new file mode 100644 index 000000000..2d579cd39 --- /dev/null +++ b/src/React.AspNet.Middleware/React.AspNet.Middleware.csproj @@ -0,0 +1,63 @@ + + + + ASP.NET Core middleware to transpile JavaScript via Babel. Please refer to project site (http://reactjs.net/) for full installation instructions, usage examples and sample code + Copyright 2014-Present Facebook, Inc + ReactJS.NET - Babel middleware for ASP.NET Core + Daniel Lo Nigro + netstandard2.0;netcoreapp3.0 + true + React.AspNet.Middleware + ../key.snk + true + true + React.AspNet.Middleware + asp.net;mvc;asp;javascript;js;react;facebook;reactjs;vnext;asp.net 5;asp.net core + logo_64.png + https://github.com/reactjs/react.net + https://github.com/reactjs/React.NET#licence + true + true + $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb + false + $(DefineConstants);ASPNETCORE + React.AspNet + true + snupkg + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + 7035 + + + diff --git a/src/React.AspNet.Middleware/ReactBuilderExtensions.cs b/src/React.AspNet.Middleware/ReactBuilderExtensions.cs new file mode 100644 index 000000000..4226c7a44 --- /dev/null +++ b/src/React.AspNet.Middleware/ReactBuilderExtensions.cs @@ -0,0 +1,96 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using React.Exceptions; +using React.TinyIoC; +using Microsoft.Extensions.DependencyInjection; +using Newtonsoft.Json.Serialization; + +#if !NET451 +using Microsoft.Extensions.Caching.Memory; +#endif + +#if NETCOREAPP2_0 || NETSTANDARD2_0 +using IWebHostEnvironment = Microsoft.AspNetCore.Hosting.IHostingEnvironment; +#endif + +namespace React.AspNet +{ + /// + /// Handles registering ReactJS.NET middleware in an ASP.NET . + /// + public static class ReactBuilderExtensions + { + /// + /// Initialises ReactJS.NET for this application + /// + /// ASP.NET application builder + /// ReactJS.NET configuration + /// Options to use for serving files + /// The application builder (for chaining) + public static IApplicationBuilder UseReact( + this IApplicationBuilder app, + Action configure, + BabelFileOptions fileOptions = null + ) + { + RegisterAspNetServices(React.AssemblyRegistration.Container, app.ApplicationServices); + + Initializer.Initialize(registerOptions => AsPerRequestSingleton( + app.ApplicationServices.GetService(), + registerOptions + )); + + // Camelcase JSON properties by default - Can be overridden per-site in "configure". + ReactSiteConfiguration.Configuration.JsonSerializerSettings.ContractResolver = + new CamelCasePropertyNamesContractResolver(); + + configure(ReactSiteConfiguration.Configuration); + + // Allow serving of .jsx files + app.UseMiddleware(fileOptions ?? new BabelFileOptions()); + + return app; + } + + /// + /// Registers a class such that every ASP.NET web request has a single instance of it. + /// + /// ASP.NET HTTP context accessor + /// Registration options + /// Registration options (for chaining) + private static TinyIoCContainer.RegisterOptions AsPerRequestSingleton( + IHttpContextAccessor httpContextAccessor, + TinyIoCContainer.RegisterOptions registerOptions + ) + { + return TinyIoCContainer.RegisterOptions.ToCustomLifetimeManager( + registerOptions, + new HttpContextLifetimeProvider(httpContextAccessor), + "per request singleton" + ); + } + + /// + /// Registers required ASP.NET services in ReactJS.NET's TinyIoC container. This is used + /// for ASP.NET services that are required by ReactJS.NET. + /// + /// ReactJS.NET dependency injection container + /// ASP.NET dependency injection container + private static void RegisterAspNetServices(TinyIoCContainer container, IServiceProvider services) + { + container.Register(services.GetRequiredService()); +#if !NET451 + container.Register(services.GetRequiredService()); +#endif + } + } +} diff --git a/src/React.AspNet.Middleware/ReactServiceCollectionExtensions.cs b/src/React.AspNet.Middleware/ReactServiceCollectionExtensions.cs new file mode 100644 index 000000000..07a4691fb --- /dev/null +++ b/src/React.AspNet.Middleware/ReactServiceCollectionExtensions.cs @@ -0,0 +1,28 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using Microsoft.Extensions.DependencyInjection; + +namespace React.AspNet +{ + /// + /// Handles registering ReactJS.NET services in the ASP.NET . + /// + public static class ReactServiceCollectionExtensions + { + /// + /// Registers all services required for ReactJS.NET + /// + /// ASP.NET services + /// The service collection (for chaining) + public static IServiceCollection AddReact(this IServiceCollection services) + { + services.AddScoped(); + return services; + } + } +} \ No newline at end of file diff --git a/src/React.AspNet/HtmlHelperExtensions.cs b/src/React.AspNet/HtmlHelperExtensions.cs new file mode 100644 index 000000000..08336eefd --- /dev/null +++ b/src/React.AspNet/HtmlHelperExtensions.cs @@ -0,0 +1,236 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System; +using System.IO; +using System.Linq; +using System.Text; + +#if LEGACYASPNET +using System.Web; +using IHtmlHelper = System.Web.Mvc.HtmlHelper; +using IUrlHelper = System.Web.Mvc.UrlHelper; +#else +using Microsoft.AspNetCore.Mvc.Rendering; +using Microsoft.AspNetCore.Html; +using IHtmlString = Microsoft.AspNetCore.Html.IHtmlContent; +using Microsoft.AspNetCore.Mvc; +#endif + +#if LEGACYASPNET +namespace React.Web.Mvc +#else +namespace React.AspNet +#endif +{ + /// + /// HTML Helpers for utilising React from an ASP.NET MVC application. + /// + public static class HtmlHelperExtensions + { + [ThreadStatic] + private static StringWriter _sharedStringWriter; + + /// + /// Gets the React environment + /// + private static IReactEnvironment Environment + { + get + { + return ReactEnvironment.GetCurrentOrThrow; + } + } + + /// + /// Renders the specified React component + /// + /// Type of the props + /// HTML helper + /// Name of the component + /// Props to initialise the component with + /// HTML tag to wrap the component in. Defaults to <div> + /// ID to use for the container HTML tag. Defaults to an auto-generated ID + /// Skip rendering server-side and only output client-side initialisation code. Defaults to false + /// Skip rendering React specific data-attributes, container and client-side initialisation during server side rendering. Defaults to false + /// HTML class(es) to set on the container tag + /// A custom exception handler that will be called if a component throws during a render. Args: (Exception ex, string componentName, string containerId) + /// Functions to call during component render + /// The component's HTML + public static IHtmlString React( + this IHtmlHelper htmlHelper, + string componentName, + T props, + string htmlTag = null, + string containerId = null, + bool clientOnly = false, + bool serverOnly = false, + string containerClass = null, + Action exceptionHandler = null, + IRenderFunctions renderFunctions = null + ) + { + try + { + var reactComponent = Environment.CreateComponent(componentName, props, containerId, clientOnly, serverOnly); + if (!string.IsNullOrEmpty(htmlTag)) + { + reactComponent.ContainerTag = htmlTag; + } + + if (!string.IsNullOrEmpty(containerClass)) + { + reactComponent.ContainerClass = containerClass; + } + + return RenderToString(writer => reactComponent.RenderHtml(writer, clientOnly, serverOnly, exceptionHandler, renderFunctions)); + } + finally + { + Environment.ReturnEngineToPool(); + } + } + + /// + /// Renders the specified React component, along with its client-side initialisation code. + /// Normally you would use the method, but + /// is useful when rendering self-contained partial views. + /// + /// Type of the props + /// HTML helper + /// Name of the component + /// Props to initialise the component with + /// HTML tag to wrap the component in. Defaults to <div> + /// ID to use for the container HTML tag. Defaults to an auto-generated ID + /// Skip rendering server-side and only output client-side initialisation code. Defaults to false + /// Skip rendering React specific data-attributes, container and client-side initialisation during server side rendering. Defaults to false + /// HTML class(es) to set on the container tag + /// A custom exception handler that will be called if a component throws during a render. Args: (Exception ex, string componentName, string containerId) + /// Functions to call during component render + /// The component's HTML + public static IHtmlString ReactWithInit( + this IHtmlHelper htmlHelper, + string componentName, + T props, + string htmlTag = null, + string containerId = null, + bool clientOnly = false, + bool serverOnly = false, + string containerClass = null, + Action exceptionHandler = null, + IRenderFunctions renderFunctions = null + ) + { + try + { + var reactComponent = Environment.CreateComponent(componentName, props, containerId, clientOnly); + if (!string.IsNullOrEmpty(htmlTag)) + { + reactComponent.ContainerTag = htmlTag; + } + + if (!string.IsNullOrEmpty(containerClass)) + { + reactComponent.ContainerClass = containerClass; + } + + return RenderToString(writer => + { + reactComponent.RenderHtml(writer, clientOnly, serverOnly, exceptionHandler: exceptionHandler, renderFunctions); + writer.WriteLine(); + WriteScriptTag(writer, bodyWriter => reactComponent.RenderJavaScript(bodyWriter, waitForDOMContentLoad: true)); + }); + + } + finally + { + Environment.ReturnEngineToPool(); + } + } + + /// + /// Renders the JavaScript required to initialise all components client-side. This will + /// attach event handlers to the server-rendered HTML. + /// + /// JavaScript for all components + public static IHtmlString ReactInitJavaScript(this IHtmlHelper htmlHelper, bool clientOnly = false) + { + try + { + return RenderToString(writer => + { + WriteScriptTag(writer, bodyWriter => Environment.GetInitJavaScript(bodyWriter, clientOnly)); + }); + } + finally + { + Environment.ReturnEngineToPool(); + } + } + + /// + /// Returns script tags based on the webpack asset manifest + /// + /// + /// Optional IUrlHelper instance. Enables the use of tilde/relative (~/) paths inside the expose-components.js file. + /// + public static IHtmlString ReactGetScriptPaths(this IHtmlHelper htmlHelper, IUrlHelper urlHelper = null) + { + string nonce = Environment.Configuration.ScriptNonceProvider != null + ? $" nonce=\"{Environment.Configuration.ScriptNonceProvider()}\"" + : ""; + + return new HtmlString(string.Join("", Environment.GetScriptPaths() + .Select(scriptPath => $""))); + } + + /// + /// Returns style tags based on the webpack asset manifest + /// + /// + /// Optional IUrlHelper instance. Enables the use of tilde/relative (~/) paths inside the expose-components.js file. + /// + public static IHtmlString ReactGetStylePaths(this IHtmlHelper htmlHelper, IUrlHelper urlHelper = null) + { + return new HtmlString(string.Join("", Environment.GetStylePaths() + .Select(stylePath => $""))); + } + + private static IHtmlString RenderToString(Action withWriter) + { + var stringWriter = _sharedStringWriter; + if (stringWriter != null) + { + stringWriter.GetStringBuilder().Clear(); + } + else + { + _sharedStringWriter = stringWriter = new StringWriter(new StringBuilder(128)); + } + + withWriter(stringWriter); + return new HtmlString(stringWriter.ToString()); + } + + private static void WriteScriptTag(TextWriter writer, Action bodyWriter) + { + writer.Write(""); + + bodyWriter(writer); + + writer.Write(""); + } + } +} diff --git a/src/React.AspNet/React.AspNet.csproj b/src/React.AspNet/React.AspNet.csproj new file mode 100644 index 000000000..2a1758dc3 --- /dev/null +++ b/src/React.AspNet/React.AspNet.csproj @@ -0,0 +1,56 @@ + + + + ReactJS and Babel tools for ASP.NET Core, including ASP.NET Core MVC. Please refer to project site (http://reactjs.net/) for full installation instructions, usage examples and sample code + Copyright 2014-Present Facebook, Inc + ReactJS.NET (ASP.NET Core MVC) + Daniel Lo Nigro + netstandard2.0;netcoreapp3.0 + true + React.AspNet + ../key.snk + true + true + React.AspNet + asp.net;mvc;asp;javascript;js;react;facebook;reactjs;vnext;asp.net 5;asp.net core + logo_64.png + https://github.com/reactjs/react.net + https://github.com/reactjs/React.NET#licence + false + $(DefineConstants);ASPNETCORE + true + snupkg + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + 7035 + + + diff --git a/src/React/AssemblyRegistration.cs b/src/React.Core/AssemblyRegistration.cs similarity index 52% rename from src/React/AssemblyRegistration.cs rename to src/React.Core/AssemblyRegistration.cs index f6ddcd7bb..7d4b0990c 100644 --- a/src/React/AssemblyRegistration.cs +++ b/src/React.Core/AssemblyRegistration.cs @@ -1,15 +1,11 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. +/* + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ -using JavaScriptEngineSwitcher.Jint; -using JavaScriptEngineSwitcher.Msie; -using JavaScriptEngineSwitcher.Msie.Configuration; +using JavaScriptEngineSwitcher.Core; using React.TinyIoC; namespace React @@ -37,26 +33,11 @@ public void Register(TinyIoCContainer container) // One instance shared for the whole app container.Register((c, o) => ReactSiteConfiguration.Configuration); container.Register().AsPerRequestSingleton(); + container.Register((c, o) => JsEngineSwitcher.Current); container.Register().AsSingleton(); + container.Register().AsSingleton(); container.Register().AsPerRequestSingleton(); - - // JavaScript engines - container.Register(new JavaScriptEngineFactory.Registration - { - Factory = () => new MsieJsEngine(new MsieConfiguration { EngineMode = JsEngineMode.ChakraActiveScript }), - Priority = 10 - }, "MsieChakra"); - container.Register(new JavaScriptEngineFactory.Registration - { - Factory = () => new MsieJsEngine(new MsieConfiguration { EngineMode = JsEngineMode.Classic }), - Priority = 20 - }, "MsieClassic"); - container.Register(new JavaScriptEngineFactory.Registration - { - Factory = () => new JintJsEngine(), - Priority = 100 - }, "Jint"); } } } diff --git a/src/React.Core/Babel.cs b/src/React.Core/Babel.cs new file mode 100644 index 000000000..d73ac06dc --- /dev/null +++ b/src/React.Core/Babel.cs @@ -0,0 +1,384 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System; +using System.Diagnostics; +using System.IO; +using React.Exceptions; + +namespace React +{ + /// + /// Handles compiling JavaScript files via Babel (http://babeljs.io/). + /// + public class Babel : IBabel + { + /// + /// Cache key for JavaScript compilation + /// + protected const string JSX_CACHE_KEY = "JSX_v3_{0}"; + /// + /// Suffix to append to compiled files + /// + protected const string COMPILED_FILE_SUFFIX = ".generated.js"; + /// + /// Suffix to append to source map files + /// + protected const string SOURE_MAP_FILE_SUFFIX = ".map"; + /// + /// Number of lines in the header prepended to compiled files. + /// + protected const int LINES_IN_HEADER = 5; + + /// + /// Environment this transformer has been created in + /// + protected readonly IReactEnvironment _environment; + /// + /// Cache used for storing compiled JavaScript + /// + protected readonly ICache _cache; + /// + /// File system wrapper + /// + protected readonly IFileSystem _fileSystem; + /// + /// Hash algorithm for file-based cache + /// + protected readonly IFileCacheHash _fileCacheHash; + /// + /// Site-wide configuration + /// + protected readonly IReactSiteConfiguration _config; + /// + /// The serialized Babel configuration + /// + protected readonly string _babelConfig; + + /// + /// Initializes a new instance of the class. + /// + /// The ReactJS.NET environment + /// The cache to use for compilation + /// File system wrapper + /// Hash algorithm for file-based cache + /// Site-wide configuration + public Babel(IReactEnvironment environment, ICache cache, IFileSystem fileSystem, IFileCacheHash fileCacheHash, IReactSiteConfiguration siteConfig) + { + _environment = environment; + _cache = cache; + _fileSystem = fileSystem; + _fileCacheHash = fileCacheHash; + _config = siteConfig; + _babelConfig = siteConfig.BabelConfig.Serialize(_config.BabelVersion ?? BabelVersions.Babel7); + } + + /// + /// Transforms a JavaScript file. Results of the transformation are cached. + /// + /// Name of the file to load + /// JavaScript + public virtual string TransformFile(string filename) + { + return TransformFileWithSourceMap(filename, false).Code; + } + + /// + /// Transforms a JavaScript file via Babel and also returns a source map to map the + /// compiled source to the original version. Results of the transformation are cached. + /// + /// Name of the file to load + /// + /// true to re-transform the file if a cached version with no source map is available + /// + /// JavaScript and source map + public virtual JavaScriptWithSourceMap TransformFileWithSourceMap( + string filename, + bool forceGenerateSourceMap = false + ) + { + var cacheKey = string.Format(JSX_CACHE_KEY, filename); + + // 1. Check in-memory cache. We need to invalidate any in-memory cache if there's no + // source map cached and forceGenerateSourceMap is true. + var cached = _cache.Get(cacheKey); + var cacheIsValid = cached != null && (!forceGenerateSourceMap || cached.SourceMap != null); + if (cacheIsValid) + { + return cached; + } + + // 2. Check on-disk cache + var contents = _fileSystem.ReadAsString(filename); + var hash = _fileCacheHash.CalculateHash(contents); + var output = LoadFromFileCache(filename, hash, forceGenerateSourceMap); + if (output == null) + { + // 3. Not cached, perform the transformation + try + { + output = TransformWithHeader(filename, contents, hash); + } + catch (BabelException ex) + { + // Add the filename to the error message + throw new BabelException(string.Format( + "In file \"{0}\": {1}", + filename, + ex.Message + ), ex); + } + } + + // Cache the result from above (either disk cache or live transformation) to memory + var fullPath = _fileSystem.MapPath(filename); + _cache.Set( + cacheKey, + output, + slidingExpiration: TimeSpan.FromMinutes(30), + cacheDependencyFiles: new[] { fullPath } + ); + return output; + } + + /// + /// Loads a transformed JavaScript file from the disk cache. If the cache is invalid or there is + /// no cached version, returns null. + /// + /// Name of the file to load + /// /// Hash of the input file, to validate the cache + /// + /// true to re-transform the file if a cached version with no source map is available + /// + /// + protected virtual JavaScriptWithSourceMap LoadFromFileCache(string filename, string hash, bool forceGenerateSourceMap) + { + var cacheFilename = GetOutputPath(filename); + if (!_fileSystem.FileExists(cacheFilename)) + { + // Cache file doesn't exist on disk + return null; + } + var cacheContents = _fileSystem.ReadAsString(cacheFilename); + if (!_fileCacheHash.ValidateHash(cacheContents, hash)) + { + // Hash of the cache is invalid (file changed since the time the cache was written). + return null; + } + + // Cache is valid :D + // See if we have a source map cached alongside the file + SourceMap sourceMap = null; + var sourceMapFilename = GetSourceMapOutputPath(filename); + if (_fileSystem.FileExists(sourceMapFilename)) + { + try + { + var sourceMapString = _fileSystem.ReadAsString(sourceMapFilename); + if (!string.IsNullOrEmpty(sourceMapString)) + { + sourceMap = SourceMap.FromJson(sourceMapString); + } + } + catch (Exception e) + { + // Just ignore it + Trace.WriteLine("Error reading source map file: " + e.Message); + } + } + + // If forceGenerateSourceMap is true, we need to explicitly ignore this cached version + // if there's no source map + if (forceGenerateSourceMap && sourceMap == null) + { + return null; + } + + return new JavaScriptWithSourceMap + { + Code = cacheContents, + SourceMap = sourceMap, + Hash = hash, + }; + } + + /// + /// Transforms JavaScript via Babel, and prepends a header used for caching + /// purposes. + /// + /// Name of the file being transformed + /// Contents of the input file + /// Hash of the input. If null, it will be calculated + /// JavaScript + protected virtual JavaScriptWithSourceMap TransformWithHeader( + string filename, + string contents, + string hash = null + ) + { + var result = TransformWithSourceMap(contents, filename); + if (string.IsNullOrEmpty(hash)) + { + hash = _fileCacheHash.CalculateHash(contents); + } + // Prepend header to generated code + var header = GetFileHeader(hash, result.BabelVersion); + result.Code = header + result.Code; + result.Hash = hash; + + if (result.SourceMap != null && result.SourceMap.Mappings != null) + { + // Since we prepend a header to the code, the source map no longer matches up exactly + // (it's off by the number of lines in the header). Fix this issue by adding five + // blank lines to the source map. This is kinda hacky but saves us having to load a + // proper source map library. If this ever breaks, I'll replace it with actual proper + // source map modification code (https://gist.github.com/Daniel15/4bdb15836bfd960c2956). + result.SourceMap.Mappings = ";;;;;" + result.SourceMap.Mappings; + } + + return result; + } + + /// + /// Transforms JavaScript via Babel. The result is not cached. Use + /// if loading from a file since this will cache the result. + /// + /// JavaScript + /// Name of the file being transformed + /// JavaScript + public virtual string Transform(string input, string filename = "unknown.jsx") + { + try + { + var output = _environment.ExecuteWithBabel( + "ReactNET_transform", + input, + _babelConfig, + filename + ); + return output; + } + catch (Exception ex) + { + throw new BabelException(ex.Message, ex); + } + } + + /// + /// Transforms JavaScript via Babel and also returns a source map to map the compiled + /// source to the original version. The result is not cached. + /// + /// JavaScript + /// Name of the file being transformed + /// JavaScript and source map + public virtual JavaScriptWithSourceMap TransformWithSourceMap( + string input, + string filename = "unknown" + ) + { + try + { + return _environment.ExecuteWithBabel( + "ReactNET_transform_sourcemap", + input, + _babelConfig, + filename + ); + } + catch (Exception ex) + { + throw new BabelException(ex.Message, ex); + } + } + + /// + /// Gets the header prepended to transformed files. Contains a hash that is used to + /// validate the cache. + /// + /// Hash of the input + /// Version of Babel used to perform this transformation + /// Header for the cache + protected virtual string GetFileHeader(string hash, string babelVersion) + { + return string.Format( +@"{0} +// Automatically generated by ReactJS.NET. Do not edit, your changes will be overridden. +// Version: {1} with Babel {3} +// Generated at: {2} +/////////////////////////////////////////////////////////////////////////////// +", _fileCacheHash.AddPrefix(hash), _environment.Version, DateTime.Now, babelVersion); + } + + /// + /// Returns the path the specified file's compilation will be cached to + /// + /// Path of the input file + /// Output path of the compiled file + public virtual string GetOutputPath(string path) + { + return Path.Combine( + Path.GetDirectoryName(path), + Path.GetFileNameWithoutExtension(path) + COMPILED_FILE_SUFFIX + ); + } + + /// + /// Returns the path the specified file's source map will be cached to if + /// is called. + /// + /// Path of the input file + /// Output path of the source map + public virtual string GetSourceMapOutputPath(string path) + { + return GetOutputPath(path) + SOURE_MAP_FILE_SUFFIX; + } + + /// + /// Transforms JavaScript via Babel and saves the result into a ".generated.js" file + /// alongside the original file. + /// + /// Name of the file to load + /// File contents + public virtual string TransformAndSaveFile( + string filename + ) + { + var outputPath = GetOutputPath(filename); + var contents = _fileSystem.ReadAsString(filename); + if (CacheIsValid(contents, outputPath)) + return outputPath; + + var result = TransformWithHeader(filename, contents, null); + + var sourceMapPath = GetSourceMapOutputPath(filename); + _fileSystem.WriteAsString(outputPath, result.Code); + _fileSystem.WriteAsString(sourceMapPath, result.SourceMap == null ? string.Empty : result.SourceMap.ToJson()); + + return outputPath; + } + + /// + /// Checks whether an input file (given as inputFileContents) should be transpiled + /// by calculating the hash and comparing it to the hash value stored + /// in the file given by outputPath. If the outputPath file does not + /// exist the input file should always be transpiled. + /// + /// The contents of the input file. + /// The output path of the (possibly previously) generated file. + /// Returns false if the file should be transpiled, true otherwise. + public virtual bool CacheIsValid(string inputFileContents, string outputPath) + { + if (!_fileSystem.FileExists(outputPath)) + return false; + + var hashForInputFile = _fileCacheHash.CalculateHash(inputFileContents); + var existingOutputContents = _fileSystem.ReadAsString(outputPath); + var fileHasNotChanged = _fileCacheHash.ValidateHash(existingOutputContents, hashForInputFile); + return fileHasNotChanged; + } + } +} diff --git a/src/React.Core/BabelConfig.cs b/src/React.Core/BabelConfig.cs new file mode 100644 index 000000000..2bd66973c --- /dev/null +++ b/src/React.Core/BabelConfig.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; +using React.Exceptions; + +namespace React +{ + /// + /// Configuration for Babel (see http://babeljs.io/docs/usage/options/ for detailed + /// documentation). + /// + public class BabelConfig + { + /// + /// Gets or sets the Babel plugins to use. See http://babeljs.io/docs/plugins/ for a full + /// list of plugins. + /// + public ISet Plugins { get; set; } + + /// + /// Gets or sets the Babel presets to use. See http://babeljs.io/docs/plugins/ for a full + /// list of presets. + /// + public ISet Presets { get; set; } + + /// + /// Serializes this Babel configuration into the format required for Babel. + /// + /// + public string Serialize(string babelVersion) + { + ISet defaultPresets = babelVersion == BabelVersions.Babel7 + ? new HashSet { "typescript", "react" } + : babelVersion == BabelVersions.Babel6 || babelVersion == null + ? new HashSet { "es2015-no-commonjs", "stage-1", "react" } + : throw new ArgumentException(nameof(babelVersion)); + + ISet defaultPlugins = babelVersion == BabelVersions.Babel7 + ? new HashSet { "proposal-class-properties", "proposal-object-rest-spread" } + : babelVersion == BabelVersions.Babel6 || babelVersion == null + ? new HashSet() + : throw new ArgumentException(nameof(babelVersion)); + + return JsonConvert.SerializeObject( + new BabelConfig + { + Plugins = Plugins ?? defaultPlugins, + Presets = Presets ?? defaultPresets, + }, + new JsonSerializerSettings + { + ContractResolver = new CamelCasePropertyNamesContractResolver(), + }); + } + } +} diff --git a/src/React.Core/BabelVersions.cs b/src/React.Core/BabelVersions.cs new file mode 100644 index 000000000..d510a310a --- /dev/null +++ b/src/React.Core/BabelVersions.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace React +{ + /// + /// Public string values for babel versions + /// + public static class BabelVersions + { + /// + /// Babel 6 + /// + public static readonly string Babel6 = "babel-6"; + + /// + /// Babel 7 + /// + public static readonly string Babel7 = "babel-7"; + } +} diff --git a/src/React.Core/Exceptions/BabelException.cs b/src/React.Core/Exceptions/BabelException.cs new file mode 100644 index 000000000..fb4e7967a --- /dev/null +++ b/src/React.Core/Exceptions/BabelException.cs @@ -0,0 +1,38 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System; +using System.Runtime.Serialization; + +namespace React.Exceptions +{ + /// + /// Thrown when an error occurs when transforming a JavaScript file via Babel. + /// + [Serializable] + public class BabelException : ReactException + { + /// + /// Initializes a new instance of the class. + /// + /// The message that describes the error. + public BabelException(string message) : base(message) { } + /// + /// Initializes a new instance of the class. + /// + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + public BabelException(string message, Exception innerException) + : base(message, innerException) { } + + /// + /// Used by deserialization + /// + protected BabelException(SerializationInfo info, StreamingContext context) + : base(info, context) { } + } +} diff --git a/src/React.Core/Exceptions/BabelNotLoadedException.cs b/src/React.Core/Exceptions/BabelNotLoadedException.cs new file mode 100644 index 000000000..5e3e19a80 --- /dev/null +++ b/src/React.Core/Exceptions/BabelNotLoadedException.cs @@ -0,0 +1,44 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System; +using System.Runtime.Serialization; + +namespace React.Exceptions +{ + /// + /// Thrown when Babel is required but has not been loaded. + /// + [Serializable] + public class BabelNotLoadedException : ReactException + { + /// + /// Initializes a new instance of the class. + /// + public BabelNotLoadedException() : base(GetMessage()) { } + + /// + /// Used by deserialization + /// + protected BabelNotLoadedException(SerializationInfo info, StreamingContext context) + : base(info, context) + { } + + /// + /// Gets a message that describes the current exception. + /// + private static string GetMessage() + { + return + "Babel has not been loaded, so JSX transformation can not be done. Please either " + + "transform your JavaScript files through an external tool (such as Babel, " + + "Webpack, Browserify or Gulp) and use the \"AddScriptWithoutTransform\" method to load " + + "them for server-side rendering, or enable the \"LoadBabel\" option in the ReactJS.NET " + + "configuration. Refer to the ReactJS.NET documentation for more details."; + } + } +} diff --git a/src/React/Exceptions/ReactConfigurationException.cs b/src/React.Core/Exceptions/ReactConfigurationException.cs similarity index 78% rename from src/React/Exceptions/ReactConfigurationException.cs rename to src/React.Core/Exceptions/ReactConfigurationException.cs index 718d7610c..3f7242826 100644 --- a/src/React/Exceptions/ReactConfigurationException.cs +++ b/src/React.Core/Exceptions/ReactConfigurationException.cs @@ -1,10 +1,8 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. +/* + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ using System; @@ -30,10 +28,11 @@ public ReactConfigurationException(string message) : base(message) { } /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. public ReactConfigurationException(string message, Exception innerException) : base(message, innerException) { } + /// /// Used by deserialization /// - protected ReactConfigurationException(SerializationInfo info, StreamingContext context) + protected ReactConfigurationException(SerializationInfo info, StreamingContext context) : base(info, context) { } } } diff --git a/src/React.Core/Exceptions/ReactEngineNotFoundException.cs b/src/React.Core/Exceptions/ReactEngineNotFoundException.cs new file mode 100644 index 000000000..3e2f161dc --- /dev/null +++ b/src/React.Core/Exceptions/ReactEngineNotFoundException.cs @@ -0,0 +1,31 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System; +using System.Runtime.Serialization; + +namespace React.Exceptions +{ + /// + /// Thrown when no valid JavaScript engine is found. + /// + [Serializable] + public class ReactEngineNotFoundException : ReactException + { + /// + /// Initializes a new instance of the class. + /// + /// The message that describes the error. + public ReactEngineNotFoundException(string message) : base(message) { } + + /// + /// Used by deserialization + /// + protected ReactEngineNotFoundException(SerializationInfo info, StreamingContext context) + : base(info, context) { } + } +} diff --git a/src/React/Exceptions/ReactException.cs b/src/React.Core/Exceptions/ReactException.cs similarity index 80% rename from src/React/Exceptions/ReactException.cs rename to src/React.Core/Exceptions/ReactException.cs index db3671387..20de0b70a 100644 --- a/src/React/Exceptions/ReactException.cs +++ b/src/React.Core/Exceptions/ReactException.cs @@ -1,10 +1,8 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. +/* + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ using System; @@ -34,10 +32,11 @@ public ReactException(string message) : base(message) { } /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. public ReactException(string message, Exception innerException) : base(message, innerException) { } + /// /// Used by deserialization /// - protected ReactException(SerializationInfo info, StreamingContext context) + protected ReactException(SerializationInfo info, StreamingContext context) : base(info, context) { } } diff --git a/src/React/Exceptions/ReactInvalidComponentException.cs b/src/React.Core/Exceptions/ReactInvalidComponentException.cs similarity index 78% rename from src/React/Exceptions/ReactInvalidComponentException.cs rename to src/React.Core/Exceptions/ReactInvalidComponentException.cs index 3257a758d..e93ae92fc 100644 --- a/src/React/Exceptions/ReactInvalidComponentException.cs +++ b/src/React.Core/Exceptions/ReactInvalidComponentException.cs @@ -1,10 +1,8 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. +/* + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ using System; @@ -30,10 +28,11 @@ public ReactInvalidComponentException(string message) : base(message) { } /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. public ReactInvalidComponentException(string message, Exception innerException) : base(message, innerException) { } + /// /// Used by deserialization /// - protected ReactInvalidComponentException(SerializationInfo info, StreamingContext context) + protected ReactInvalidComponentException(SerializationInfo info, StreamingContext context) : base(info, context) { } } } diff --git a/src/React.Core/Exceptions/ReactNotInitialisedException.cs b/src/React.Core/Exceptions/ReactNotInitialisedException.cs new file mode 100644 index 000000000..8a83eb700 --- /dev/null +++ b/src/React.Core/Exceptions/ReactNotInitialisedException.cs @@ -0,0 +1,39 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System; +using System.Runtime.Serialization; + +namespace React.Exceptions +{ + /// + /// Thrown when React has not been initialised correctly. + /// + [Serializable] + public class ReactNotInitialisedException : ReactException + { + /// + /// Initializes a new instance of the class. + /// + /// The message that describes the error. + public ReactNotInitialisedException(string message) : base(message) { } + + /// + /// Initializes a new instance of the class. + /// + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + public ReactNotInitialisedException(string message, Exception innerException) + : base(message, innerException) { } + + /// + /// Used by deserialization + /// + protected ReactNotInitialisedException(SerializationInfo info, StreamingContext context) + : base(info, context) { } + } +} diff --git a/src/React.Core/Exceptions/ReactScriptLoadException.cs b/src/React.Core/Exceptions/ReactScriptLoadException.cs new file mode 100644 index 000000000..71817183c --- /dev/null +++ b/src/React.Core/Exceptions/ReactScriptLoadException.cs @@ -0,0 +1,39 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System; +using System.Runtime.Serialization; + +namespace React.Exceptions +{ + /// + /// Thrown when an error is encountered while loading a JavaScript file. + /// + [Serializable] + public class ReactScriptLoadException : ReactException + { + /// + /// Initializes a new instance of the class. + /// + /// The message that describes the error. + public ReactScriptLoadException(string message) : base(message) { } + + /// + /// Initializes a new instance of the class. + /// + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + public ReactScriptLoadException(string message, Exception innerException) + : base(message, innerException) { } + + /// + /// Used by deserialization + /// + protected ReactScriptLoadException(SerializationInfo info, StreamingContext context) + : base(info, context) { } + } +} diff --git a/src/React.Core/Exceptions/ReactScriptPrecompilationNotAvailableException.cs b/src/React.Core/Exceptions/ReactScriptPrecompilationNotAvailableException.cs new file mode 100644 index 000000000..d8464ab87 --- /dev/null +++ b/src/React.Core/Exceptions/ReactScriptPrecompilationNotAvailableException.cs @@ -0,0 +1,31 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System; +using System.Runtime.Serialization; + +namespace React.Exceptions +{ + /// + /// Thrown when the script pre-compilation is not available. + /// + [Serializable] + public class ReactScriptPrecompilationNotAvailableException : ReactException + { + /// + /// Initializes a new instance of the class. + /// + /// The message that describes the error. + public ReactScriptPrecompilationNotAvailableException(string message) : base(message) { } + + /// + /// Used by deserialization + /// + protected ReactScriptPrecompilationNotAvailableException(SerializationInfo info, StreamingContext context) + : base(info, context) { } + } +} diff --git a/src/React.Core/Exceptions/ReactServerRenderingException.cs b/src/React.Core/Exceptions/ReactServerRenderingException.cs new file mode 100644 index 000000000..f06975cc3 --- /dev/null +++ b/src/React.Core/Exceptions/ReactServerRenderingException.cs @@ -0,0 +1,39 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System; +using System.Runtime.Serialization; + +namespace React.Exceptions +{ + /// + /// Thrown when an error occurs during server rendering of a React component. + /// + [Serializable] + public class ReactServerRenderingException : ReactException + { + /// + /// Initializes a new instance of the class. + /// + /// The message that describes the error. + public ReactServerRenderingException(string message) : base(message) { } + + /// + /// Initializes a new instance of the class. + /// + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + public ReactServerRenderingException(string message, Exception innerException) + : base(message, innerException) { } + + /// + /// Used by deserialization + /// + protected ReactServerRenderingException(SerializationInfo info, StreamingContext context) + : base(info, context) { } + } +} diff --git a/src/React/FileCacheHash.cs b/src/React.Core/FileCacheHash.cs similarity index 75% rename from src/React/FileCacheHash.cs rename to src/React.Core/FileCacheHash.cs index 2a6d18cbb..e68fe573f 100644 --- a/src/React/FileCacheHash.cs +++ b/src/React.Core/FileCacheHash.cs @@ -1,10 +1,8 @@ /* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ using System; @@ -21,12 +19,17 @@ public class FileCacheHash : IFileCacheHash /// /// Prefix used for hash line in transformed file. Used for caching. /// - internal const string HASH_PREFIX = "// @hash "; + private const string HASH_PREFIX = "// @hash v3-"; + // TODO: Do we really need to use SHA1Cng specifically? /// - /// Althorithm for calculating file hashes + /// Algorithm for calculating file hashes /// - private readonly HashAlgorithm _hash = MD5.Create(); +#if NET40 || NET45 + private readonly HashAlgorithm _hash = SHA1.Create("System.Security.Cryptography.SHA1Cng"); +#else + private readonly HashAlgorithm _hash = SHA1.Create(); +#endif /// /// Calculates a hash for the specified input @@ -47,7 +50,7 @@ public string CalculateHash(string input) /// Contents retrieved from cache /// Hash of the input /// true if the cache is still valid - public bool ValidateHash(string cacheContents, string hash) + public virtual bool ValidateHash(string cacheContents, string hash) { if (string.IsNullOrWhiteSpace(cacheContents)) { @@ -75,9 +78,9 @@ public bool ValidateHash(string cacheContents, string hash) /// /// Hash to prepend prefix to /// Hash with prefix - public string AddPrefix(string hash) + public virtual string AddPrefix(string hash) { return HASH_PREFIX + hash; } } -} \ No newline at end of file +} diff --git a/src/React.Core/FileSystemBase.cs b/src/React.Core/FileSystemBase.cs new file mode 100644 index 000000000..8fa936e4b --- /dev/null +++ b/src/React.Core/FileSystemBase.cs @@ -0,0 +1,85 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; + +namespace React +{ + /// + /// Handles file system functionality, such as reading files. + /// + abstract public class FileSystemBase : IFileSystem + { + /// + /// Prefix for relative paths + /// + public const string RELATIVE_PREFIX = "~/"; + + /// + /// Converts a path from an application relative path (~/...) to a full filesystem path + /// + /// App-relative path of the file + /// Full path of the file + public abstract string MapPath(string relativePath); + + /// + /// Converts a path from a full filesystem path to an application relative path (~/...) + /// + /// Full path of the file + /// App-relative path of the file + public virtual string ToRelativePath(string absolutePath) + { + var root = MapPath(RELATIVE_PREFIX); + return absolutePath.Replace(root, RELATIVE_PREFIX).Replace('\\', '/'); + } + + /// + /// Reads the contents of a file as a string. + /// + /// App-relative path of the file + /// Contents of the file + public virtual string ReadAsString(string relativePath) + { + return File.ReadAllText(MapPath(relativePath), Encoding.UTF8); + } + + /// + /// Writes a string to a file + /// + /// App-relative path of the file + /// Contents of the file + public virtual void WriteAsString(string relativePath, string contents) + { + File.WriteAllText(MapPath(relativePath), contents, Encoding.UTF8); + } + + /// + /// Determines if the specified file exists + /// + /// App-relative path of the file + /// true if the file exists + public virtual bool FileExists(string relativePath) + { + return File.Exists(MapPath(relativePath)); + } + + /// + /// Gets all the file paths that match the specified pattern + /// + /// Pattern to search for (eg. "~/Scripts/*.js") + /// File paths that match the pattern + public virtual IEnumerable Glob(string glob) + { + var path = MapPath(Path.GetDirectoryName(glob)); + var searchPattern = Path.GetFileName(glob); + return Directory.EnumerateFiles(path, searchPattern).Select(ToRelativePath); + } + } +} diff --git a/src/React.Core/FileSystemExtensions.cs b/src/React.Core/FileSystemExtensions.cs new file mode 100644 index 000000000..fde0f9afb --- /dev/null +++ b/src/React.Core/FileSystemExtensions.cs @@ -0,0 +1,28 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System.IO; + +namespace React +{ + /// + /// Extension methods relating to file system paths. + /// + public static class FileSystemExtensions + { + /// + /// Determines if the specified string is a glob pattern that can be used with + /// . + /// + /// String + /// true if the specified string is a glob pattern + public static bool IsGlobPattern(this string input) + { + return input.Contains("*") || input.Contains("?"); + } + } +} diff --git a/src/React/IAssemblyRegistration.cs b/src/React.Core/IAssemblyRegistration.cs similarity index 63% rename from src/React/IAssemblyRegistration.cs rename to src/React.Core/IAssemblyRegistration.cs index be752bc5c..d20eb9ec4 100644 --- a/src/React/IAssemblyRegistration.cs +++ b/src/React.Core/IAssemblyRegistration.cs @@ -1,10 +1,8 @@ /* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ using React.TinyIoC; diff --git a/src/React.Core/IBabel.cs b/src/React.Core/IBabel.cs new file mode 100644 index 000000000..fa04c9566 --- /dev/null +++ b/src/React.Core/IBabel.cs @@ -0,0 +1,77 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +namespace React +{ + /// + /// Handles compiling JavaScript files via Babel (http://babeljs.io/). + /// + public interface IBabel + { + /// + /// Transforms a JavaScript file. Results of the transformation are cached. + /// + /// Name of the file to load + /// JavaScript + string TransformFile(string filename); + + /// + /// Transforms a JavaScript file via Babel and also returns a source map to map the + /// compiled source to the original version. Results of the transformation are cached. + /// + /// Name of the file to load + /// + /// true to re-transform the file if a cached version with no source map is available + /// + /// JavaScript and source map + JavaScriptWithSourceMap TransformFileWithSourceMap( + string filename, + bool forceGenerateSourceMap = false + ); + + /// + /// Transforms JavaScript via Babel. The result is not cached. Use + /// if loading from a file since this will cache the result. + /// + /// JavaScript + /// Name of the file being transformed + /// JavaScript + string Transform(string input, string filename = "unknown.jsx"); + + /// + /// Transforms JavaScript via Babel and also returns a source map to map the compiled + /// source to the original version. The result is not cached. + /// + /// JavaScript + /// Name of the file being transformed + /// JavaScript and source map + JavaScriptWithSourceMap TransformWithSourceMap(string input, string filename = "unknown"); + + /// + /// Transforms JavaScript via Babel and saves the result into a ".generated.js" file + /// alongside the original file. + /// + /// Name of the file to load + /// File contents + string TransformAndSaveFile(string filename); + + /// + /// Returns the path the specified file's compilation will be cached to + /// + /// Path of the input file + /// Output path of the compiled file + string GetOutputPath(string path); + + /// + /// Returns the path the specified file's source map will be cached to if + /// is called. + /// + /// Path of the input file + /// Output path of the source map + string GetSourceMapOutputPath(string path); + } +} diff --git a/src/React.Core/ICache.cs b/src/React.Core/ICache.cs new file mode 100644 index 000000000..4a7ff52b7 --- /dev/null +++ b/src/React.Core/ICache.cs @@ -0,0 +1,49 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System; +using System.Collections.Generic; + +namespace React +{ + /// + /// Handles caching of data and optionally tracking dependencies + /// + public interface ICache + { + /// + /// Get an item from the cache. Returns if the item does + /// not exist. + /// + /// Type of data + /// The cache key + /// Value to return if item is not in the cache + /// Data from cache, otherwise + T Get(string key, T fallback = default(T)); + + /// + /// Sets an item in the cache. + /// + /// Type of data + /// The cache key + /// Data to cache + /// + /// Sliding expiration, if cache key is not accessed in this time period it will + /// automatically be removed from the cache + /// + /// + /// Filenames this cached item is dependent on. If any of these files change, the cache + /// will be cleared automatically + /// + void Set( + string key, + T data, + TimeSpan slidingExpiration, + IEnumerable cacheDependencyFiles = null + ); + } +} diff --git a/src/React/IFileCacheHash.cs b/src/React.Core/IFileCacheHash.cs similarity index 77% rename from src/React/IFileCacheHash.cs rename to src/React.Core/IFileCacheHash.cs index f3c4a1108..cfabfbd28 100644 --- a/src/React/IFileCacheHash.cs +++ b/src/React.Core/IFileCacheHash.cs @@ -1,10 +1,8 @@ /* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ namespace React @@ -37,4 +35,4 @@ public interface IFileCacheHash /// Hash with prefix string AddPrefix(string hash); } -} \ No newline at end of file +} diff --git a/src/React/IFileSystem.cs b/src/React.Core/IFileSystem.cs similarity index 60% rename from src/React/IFileSystem.cs rename to src/React.Core/IFileSystem.cs index 15b648085..c972b49e5 100644 --- a/src/React/IFileSystem.cs +++ b/src/React.Core/IFileSystem.cs @@ -1,12 +1,12 @@ /* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ +using System.Collections.Generic; + namespace React { /// @@ -21,6 +21,13 @@ public interface IFileSystem /// Full path of the file string MapPath(string relativePath); + /// + /// Converts a path from a full filesystem path to anan application relative path (~/...) + /// + /// Full path of the file + /// App-relative path of the file + string ToRelativePath(string absolutePath); + /// /// Reads the contents of a file as a string. /// @@ -41,5 +48,12 @@ public interface IFileSystem /// App-relative path of the file /// true if the file exists bool FileExists(string relativePath); + + /// + /// Gets all the files that match the specified pattern + /// + /// Pattern to search for (eg. "~/Scripts/*.js") + /// File names that match the pattern + IEnumerable Glob(string glob); } } diff --git a/src/React.Core/IJavaScriptEngineFactory.cs b/src/React.Core/IJavaScriptEngineFactory.cs new file mode 100644 index 000000000..adb731d3a --- /dev/null +++ b/src/React.Core/IJavaScriptEngineFactory.cs @@ -0,0 +1,30 @@ +using JavaScriptEngineSwitcher.Core; +using JSPool; + +namespace React +{ + /// + /// Handles creation of JavaScript engines. All methods are thread-safe. + /// + public interface IJavaScriptEngineFactory + { + /// + /// Gets the JavaScript engine for the current thread. It is recommended to use + /// instead, which will pool/reuse engines. + /// + /// The JavaScript engine + IJsEngine GetEngineForCurrentThread(); + + /// + /// Disposes the JavaScript engine for the current thread. This should only be used + /// if the engine was acquired through . + /// + void DisposeEngineForCurrentThread(); + + /// + /// Gets a JavaScript engine from the pool. + /// + /// The JavaScript engine + PooledJsEngine GetEngine(); + } +} \ No newline at end of file diff --git a/src/React.Core/IReactComponent.cs b/src/React.Core/IReactComponent.cs new file mode 100644 index 000000000..6e4e8127b --- /dev/null +++ b/src/React.Core/IReactComponent.cs @@ -0,0 +1,87 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System; +using System.IO; + +namespace React +{ + /// + /// Represents a React JavaScript component. + /// + public interface IReactComponent + { + /// + /// Gets or sets the props for this component + /// + object Props { get; set; } + + /// + /// Gets or sets the name of the component + /// + string ComponentName { get; set; } + + /// + /// Gets or sets the unique ID for the container of this component + /// + string ContainerId { get; set; } + + /// + /// Gets or sets the HTML tag the component is wrapped in + /// + string ContainerTag { get; set; } + + /// + /// Gets or sets the HTML class for the container of this component + /// + string ContainerClass { get; set; } + + /// + /// Get or sets if this components only should be rendered server side + /// + bool ServerOnly { get; set; } + + /// + /// Renders the HTML for this component. This will execute the component server-side and + /// return the rendered HTML. + /// + /// Only renders component container. Used for client-side only rendering. + /// Only renders the common HTML mark up and not any React specific data attributes. Used for server-side only rendering. + /// A custom exception handler that will be called if a component throws during a render. Args: (Exception ex, string componentName, string containerId) + /// Functions to call during component render + /// HTML + string RenderHtml(bool renderContainerOnly = false, bool renderServerOnly = false, Action exceptionHandler = null, IRenderFunctions renderFunctions = null); + + /// + /// Renders the HTML for this component. This will execute the component server-side and + /// return the rendered HTML. + /// + /// The to which the content is written + /// Only renders component container. Used for client-side only rendering. + /// Only renders the common HTML mark up and not any React specific data attributes. Used for server-side only rendering. + /// A custom exception handler that will be called if a component throws during a render. Args: (Exception ex, string componentName, string containerId) + /// Functions to call during component render + /// HTML + void RenderHtml(TextWriter writer, bool renderContainerOnly = false, bool renderServerOnly = false, Action exceptionHandler = null, IRenderFunctions renderFunctions = null); + + /// + /// Renders the JavaScript required to initialise this component client-side. This will + /// initialise the React component, which includes attach event handlers to the + /// server-rendered HTML. + /// + /// JavaScript + string RenderJavaScript(bool waitForDOMContentLoad); + + /// + /// Renders the JavaScript required to initialise this component client-side. This will + /// initialise the React component, which includes attach event handlers to the + /// server-rendered HTML. + /// + /// JavaScript + void RenderJavaScript(TextWriter writer, bool waitForDOMContentLoad); + } +} diff --git a/src/React.Core/IReactEnvironment.cs b/src/React.Core/IReactEnvironment.cs new file mode 100644 index 000000000..a62437a5b --- /dev/null +++ b/src/React.Core/IReactEnvironment.cs @@ -0,0 +1,139 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + +using System.Collections.Generic; +using System.IO; + +namespace React +{ + /// + /// Request-specific ReactJS.NET environment. This is unique to the individual request and is + /// not shared. + /// + public interface IReactEnvironment + { + /// + /// Gets the version number of ReactJS.NET + /// + string Version { get; } + + /// + /// Gets the name and version of the JavaScript engine in use by ReactJS.NET + /// + string EngineVersion { get; } + + /// + /// Executes the provided JavaScript code. + /// + /// JavaScript to execute + void Execute(string code); + + /// + /// Executes the provided JavaScript code, returning a result of the specified type. + /// + /// Type to return + /// Code to execute + /// Result of the JavaScript code + T Execute(string code); + + /// + /// Executes the provided JavaScript function, returning a result of the specified type. + /// + /// Type to return + /// JavaScript function to execute + /// Arguments to pass to function + /// Result of the JavaScript code + T Execute(string function, params object[] args); + + /// + /// Attempts to execute the provided JavaScript code using a non-pooled JavaScript engine (ie. + /// creates a new JS engine per-thread). This is because Babel uses a LOT of memory, so we + /// should completely dispose any engines that have loaded Babel in order to conserve memory. + /// + /// If an exception is thrown, retries the execution using a new thread (and hence a new engine) + /// with a larger maximum stack size. + /// This is required because JSXTransformer uses a huge stack which ends up being larger + /// than what ASP.NET allows by default (256 KB). + /// + /// Type to return from JavaScript call + /// JavaScript function to execute + /// Arguments to pass to function + /// Result returned from JavaScript code + T ExecuteWithBabel(string function, params object[] args); + + /// + /// Determines if the specified variable exists in the JavaScript engine + /// + /// Name of the variable + /// true if the variable exists; false otherwise + bool HasVariable(string name); + + /// + /// Creates an instance of the specified React JavaScript component. + /// + /// Type of the props + /// Name of the component + /// Props to use + /// ID to use for the container HTML tag. Defaults to an auto-generated ID + /// True if server-side rendering will be bypassed. Defaults to false. + /// True if this component only should be rendered server-side. Defaults to false. + /// Skip adding to components list, which is used during GetInitJavascript + /// The component + IReactComponent CreateComponent(string componentName, T props, string containerId = null, bool clientOnly = false, bool serverOnly = false, bool skipLazyInit = false); + + /// + /// Adds the provided to the list of components to render client side. + /// + /// Component to add to client side render list + /// True if server-side rendering will be bypassed. Defaults to false. + /// The component + IReactComponent CreateComponent(IReactComponent component, bool clientOnly = false); + + /// + /// Renders the JavaScript required to initialise all components client-side. This will + /// attach event handlers to the server-rendered HTML. + /// + /// True if server-side rendering will be bypassed. Defaults to false. + /// JavaScript for all components + string GetInitJavaScript(bool clientOnly = false); + + /// + /// Gets the JSX Transformer for this environment. + /// + IBabel Babel { get; } + + /// + /// Returns the currently held JS engine to the pool. (no-op if engine pooling is disabled) + /// + void ReturnEngineToPool(); + + /// + /// Gets the site-wide configuration. + /// + IReactSiteConfiguration Configuration { get; } + + /// + /// Renders the JavaScript required to initialise all components client-side. This will + /// attach event handlers to the server-rendered HTML. + /// + /// The to which the content is written + /// True if server-side rendering will be bypassed. Defaults to false. + /// JavaScript for all components + void GetInitJavaScript(TextWriter writer, bool clientOnly = false); + + /// + /// Returns a list of paths to scripts generated by the React app + /// + IEnumerable GetScriptPaths(); + + /// + /// Returns a list of paths to stylesheets generated by the React app + /// + IEnumerable GetStylePaths(); + } +} diff --git a/src/React.Core/IReactIdGenerator.cs b/src/React.Core/IReactIdGenerator.cs new file mode 100644 index 000000000..57aacdaec --- /dev/null +++ b/src/React.Core/IReactIdGenerator.cs @@ -0,0 +1,21 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +namespace React +{ + /// + /// Fast component ID generator + /// + public interface IReactIdGenerator + { + /// + /// Returns a short react identifier starts with "react_". + /// + /// + string Generate(); + } +} diff --git a/src/React.Core/IReactSiteConfiguration.cs b/src/React.Core/IReactSiteConfiguration.cs new file mode 100644 index 000000000..5bd18d0b4 --- /dev/null +++ b/src/React.Core/IReactSiteConfiguration.cs @@ -0,0 +1,232 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System; +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace React +{ + /// + /// Site-wide configuration for ReactJS.NET + /// + public interface IReactSiteConfiguration + { + /// + /// Adds a script to the list of scripts that are executed. This should be called for all + /// React components and their dependencies. If the script does not have any JSX in it + /// (for example, it's built using Webpack or Gulp), use + /// instead. + /// + /// + /// Name of the file to execute. Should be a server relative path starting with ~ (eg. + /// ~/Scripts/Awesome.js) + /// + /// This configuration, for chaining + IReactSiteConfiguration AddScript(string filename); + + /// + /// Adds a script to the list of scripts that are executed. This is the same as + /// except it does not run JSX transformation on the script and thus is + /// more efficient. + /// + /// + /// Name of the file to execute. Should be a server relative path starting with ~ (eg. + /// ~/Scripts/Awesome.js) + /// + /// The configuration, for chaining + IReactSiteConfiguration AddScriptWithoutTransform(string filename); + + /// + /// Gets a list of all the scripts that have been added to this configuration and require JSX + /// transformation to be run. + /// + IEnumerable Scripts { get; } + + /// + /// Gets a list of all the scripts that have been added to this configuration and do not + /// require JSX transformation to be run. + /// + IEnumerable ScriptsWithoutTransform { get; } + + /// + /// Gets or sets whether JavaScript engines should be reused across requests. + /// + /// + bool ReuseJavaScriptEngines { get; set; } + /// + /// Sets whether JavaScript engines should be reused across requests. + /// + IReactSiteConfiguration SetReuseJavaScriptEngines(bool value); + + /// + /// Gets or sets the configuration for JSON serializer. + /// + JsonSerializerSettings JsonSerializerSettings { get; set; } + + /// + /// Sets the configuration for json serializer. + /// + /// + /// This confiquration is used when component initialization script + /// is being generated server-side. + /// + /// The settings. + IReactSiteConfiguration SetJsonSerializerSettings(JsonSerializerSettings settings); + + /// + /// Gets or sets the number of engines to initially start when a pool is created. + /// Defaults to 10. + /// + int? StartEngines { get; set; } + /// + /// Sets the number of engines to initially start when a pool is created. + /// Defaults to 10. + /// + IReactSiteConfiguration SetStartEngines(int? startEngines); + + /// + /// Gets or sets the maximum number of engines that will be created in the pool. + /// Defaults to 25. + /// + int? MaxEngines { get; set; } + /// + /// Sets the maximum number of engines that will be created in the pool. + /// Defaults to 25. + /// + IReactSiteConfiguration SetMaxEngines(int? maxEngines); + + /// + /// Gets or sets the maximum number of times an engine can be reused before it is disposed. + /// 0 is unlimited. Defaults to 100. + /// + int? MaxUsagesPerEngine { get; set; } + /// + /// Sets the maximum number of times an engine can be reused before it is disposed. + /// 0 is unlimited. Defaults to 100. + /// + IReactSiteConfiguration SetMaxUsagesPerEngine(int? maxUsagesPerEngine); + + /// + /// Gets or sets whether to allow the JavaScript pre-compilation (accelerates the + /// initialization of JavaScript engines). + /// + bool AllowJavaScriptPrecompilation { get; set; } + /// + /// Sets whether to allow the JavaScript pre-compilation (accelerates the initialization of + /// JavaScript engines). + /// + /// + IReactSiteConfiguration SetAllowJavaScriptPrecompilation(bool allowJavaScriptPrecompilation); + + /// + /// Gets or sets whether the built-in version of React is loaded. If false, you must + /// provide your own version of React. + /// + bool LoadReact { get; set; } + /// + /// Sets whether the built-in version of React is loaded. If false, you must + /// provide your own version of React. + /// + /// The configuration, for chaining + IReactSiteConfiguration SetLoadReact(bool loadReact); + + /// + /// Gets or sets whether Babel is loading. Disabling the loading of Babel can improve startup + /// performance, but all your JSX files must be transformed beforehand (eg. through Babel, + /// Webpack or Browserify). + /// + bool LoadBabel { get; set; } + /// + /// Sets whether Babel is loading. Disabling the loading of Babel can improve startup + /// performance, but all your JSX files must be transformed beforehand (eg. through Babel, + /// Webpack or Browserify). + /// + IReactSiteConfiguration SetLoadBabel(bool loadBabel); + + /// + /// Gets or sets the Babel configuration to use. + /// + BabelConfig BabelConfig { get; set; } + /// + /// Sets the Babel configuration to use. + /// + /// The configuration, for chaining + IReactSiteConfiguration SetBabelConfig(BabelConfig value); + + /// + /// Gets or sets the Babel version to use. Supports "babel@6 or babel@7". + /// + string BabelVersion { get; set; } + + /// + /// Sets the Babel configuration to use. + /// + /// The configuration, for chaining + IReactSiteConfiguration SetBabelVersion(string value); + + /// + /// Gets or sets whether to use the debug version of React. This is slower, but gives + /// useful debugging tips. + /// + bool UseDebugReact { get; set; } + /// + /// Sets whether to use the debug version of React. This is slower, but gives + /// useful debugging tips. + /// + IReactSiteConfiguration SetUseDebugReact(bool value); + + /// + /// Gets or sets whether server-side rendering is enabled. + /// + bool UseServerSideRendering { get; set; } + /// + /// Disables server-side rendering. This is useful when debugging your scripts. + /// + IReactSiteConfiguration DisableServerSideRendering(); + + /// + /// An exception handler which will be called if a render exception is thrown. + /// If unset, unhandled exceptions will be thrown for all component renders. + /// + Action ExceptionHandler { get; set; } + + /// + /// Sets an exception handler which will be called if a render exception is thrown. + /// If unset, unhandled exceptions will be thrown for all component renders. + /// + /// + /// + IReactSiteConfiguration SetExceptionHandler(Action handler); + + /// + /// A provider that returns a nonce to be used on any script tags on the page. + /// This value must match the nonce used in the Content Security Policy header on the response. + /// + Func ScriptNonceProvider { get; set; } + + /// + /// Sets a provider that returns a nonce to be used on any script tags on the page. + /// This value must match the nonce used in the Content Security Policy header on the response. + /// + /// + /// + IReactSiteConfiguration SetScriptNonceProvider(Func provider); + + /// + /// The path to the application bundles built by webpack or create-react-app + /// + string ReactAppBuildPath { get; set; } + + /// + /// Sets the path to the application bundles built by webpack or create-react-app + /// + /// + /// + IReactSiteConfiguration SetReactAppBuildPath(string reactAppBuildPath); + } +} diff --git a/src/React.Core/IRenderFunctions.cs b/src/React.Core/IRenderFunctions.cs new file mode 100644 index 000000000..890eb5758 --- /dev/null +++ b/src/React.Core/IRenderFunctions.cs @@ -0,0 +1,48 @@ +using System; + +namespace React +{ + /// + /// Functions to execute during a render request. + /// These functions will share the same Javascript context, so state can be passed around via variables. + /// + public interface IRenderFunctions + { + /// + /// Executes before component render. + /// It takes a func that accepts a Javascript code expression to evaluate, which returns the result of the expression. + /// This is useful for setting up variables that will be referenced after the render completes. + /// The func to execute + /// + void PreRender(Func executeJs); + + + /// + /// Transforms the React.createElement expression. + /// This is useful for libraries like styled components which require wrapping the root component + /// inside a helper to generate a stylesheet. + /// Example transform: React.createElement(Foo, ...) => wrapComponent(React.createElement(Foo, ...)) + /// + /// The Javascript expression to wrap + /// A wrapped expression + string WrapComponent(string componentToRender); + + + /// + /// Transforms the compiled rendered component HTML + /// This is useful for libraries like emotion which take rendered component HTML and output the transformed HTML plus additional style tags + /// + /// The component HTML + /// A wrapped expression + string TransformRenderedHtml(string input); + + + /// + /// Executes after component render. + /// It takes a func that accepts a Javascript code expression to evaluate, which returns the result of the expression. + /// This is useful for reading computed state, such as generated stylesheets or a router redirect result. + /// + /// The func to execute + void PostRender(Func executeJs); + } +} diff --git a/src/React/Initializer.cs b/src/React.Core/Initializer.cs similarity index 61% rename from src/React/Initializer.cs rename to src/React.Core/Initializer.cs index 847856276..794556b59 100644 --- a/src/React/Initializer.cs +++ b/src/React.Core/Initializer.cs @@ -1,17 +1,20 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. +/* + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ using System; +using System.Collections.Generic; using System.Linq; using System.Reflection; using RegisterOptions = React.TinyIoC.TinyIoCContainer.RegisterOptions; +#if !NET40 && !NET45 +using Microsoft.Extensions.DependencyModel; +#endif + namespace React { /// @@ -19,6 +22,16 @@ namespace React /// public static class Initializer { + /// + /// Assemblies that are ignored when finding + /// implementations to register dependencies. + /// + private readonly static ISet _obsoleteAssemblies = new HashSet + { + "React.JavaScriptEngine.VroomJs", + "React.JavaScriptEngine.ClearScriptV8", + }; + /// /// Intialise ReactJS.NET /// @@ -40,9 +53,15 @@ public static void Initialize(Func requestLife private static void InitializeIoC(Func requestLifetimeRegistration) { TinyIoCExtensions.AsRequestLifetime = requestLifetimeRegistration; +#if NET40 || NET45 var types = AppDomain.CurrentDomain.GetAssemblies() // Only bother checking React assemblies .Where(IsReactAssembly) +#else + var types = DependencyContext.Default.RuntimeLibraries + .Where(library => IsReactAssembly(library.Name)) + .Select(library => Assembly.Load(new AssemblyName(library.Name))) +#endif .SelectMany(assembly => assembly.GetTypes()) .Where(IsComponentRegistration); @@ -63,10 +82,23 @@ private static void InitializeIoC(Func request private static bool IsReactAssembly(Assembly assembly) { var nameWithoutVersion = assembly.FullName.Split(',')[0]; + return IsReactAssembly(nameWithoutVersion); + } + + /// + /// Determines if the specified assembly is part of ReactJS.NET + /// + /// Name of the assembly + /// + /// true if this is a ReactJS.NET assembly; otherwise, false. + /// + private static bool IsReactAssembly(string assemblyName) + { return - nameWithoutVersion == "React" || - nameWithoutVersion.StartsWith("React.") || - nameWithoutVersion.EndsWith(".React"); + (assemblyName.Equals("React", StringComparison.OrdinalIgnoreCase) || + assemblyName.StartsWith("React.", StringComparison.OrdinalIgnoreCase) || + assemblyName.EndsWith(".React", StringComparison.OrdinalIgnoreCase)) && + !_obsoleteAssemblies.Contains(assemblyName, StringComparer.OrdinalIgnoreCase); } /// diff --git a/src/React.Core/JavaScriptEngineFactory.cs b/src/React.Core/JavaScriptEngineFactory.cs new file mode 100644 index 000000000..63772c3db --- /dev/null +++ b/src/React.Core/JavaScriptEngineFactory.cs @@ -0,0 +1,394 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Threading; +using JavaScriptEngineSwitcher.Core; +using JSPool; +using React.Exceptions; + +namespace React +{ + /// + /// Handles creation of JavaScript engines. All methods are thread-safe. + /// + public class JavaScriptEngineFactory : IDisposable, IJavaScriptEngineFactory + { + /// + /// React configuration for the current site + /// + protected readonly IReactSiteConfiguration _config; + /// + /// Cache used for storing the pre-compiled scripts + /// + protected readonly ICache _cache; + /// + /// File system wrapper + /// + protected readonly IFileSystem _fileSystem; + /// + /// Function used to create new JavaScript engine instances. + /// + protected readonly Func _factory; + /// + /// The JavaScript Engine Switcher instance used by ReactJS.NET + /// + protected readonly IJsEngineSwitcher _jsEngineSwitcher; + /// + /// Contains all current JavaScript engine instances. One per thread, keyed on thread ID. + /// + protected readonly ConcurrentDictionary _engines + = new ConcurrentDictionary(); + /// + /// Pool of JavaScript engines to use + /// + protected IJsPool _pool; + /// + /// Whether this class has been disposed. + /// + protected bool _disposed; + /// + /// The exception that was thrown during the most recent recycle of the pool. + /// + protected Exception _scriptLoadException; + + /// + /// Initializes a new instance of the class. + /// + public JavaScriptEngineFactory( + IJsEngineSwitcher jsEngineSwitcher, + IReactSiteConfiguration config, + ICache cache, + IFileSystem fileSystem + ) + { + _jsEngineSwitcher = jsEngineSwitcher; + _config = config; + _cache = cache; + _fileSystem = fileSystem; +#pragma warning disable 618 + _factory = GetFactory(_jsEngineSwitcher); +#pragma warning restore 618 + if (_config.ReuseJavaScriptEngines) + { + _pool = CreatePool(); + } + } + + /// + /// Creates a new JavaScript engine pool. + /// + protected virtual IJsPool CreatePool() + { + var allFiles = _config.Scripts + .Concat(_config.ScriptsWithoutTransform) + .Concat(_config.ReactAppBuildPath != null + ? new[] { $"{_config.ReactAppBuildPath}/asset-manifest.json"} + : Enumerable.Empty()) + .Select(_fileSystem.MapPath); + + var poolConfig = new JsPoolConfig + { + EngineFactory = _factory, + Initializer = InitialiseEngine, + WatchPath = _fileSystem.MapPath("~/"), + WatchFiles = allFiles + }; + if (_config.MaxEngines != null) + { + poolConfig.MaxEngines = _config.MaxEngines.Value; + } + if (_config.StartEngines != null) + { + poolConfig.StartEngines = _config.StartEngines.Value; + } + if (_config.MaxUsagesPerEngine != null) + { + poolConfig.MaxUsagesPerEngine = _config.MaxUsagesPerEngine.Value; + } + + var pool = new JsPool(poolConfig); + // Reset the recycle exception on recycle. If there *are* errors loading the scripts + // during recycle, the errors will be caught in the initializer. + pool.Recycled += (sender, args) => _scriptLoadException = null; + return pool; + } + + /// + /// Loads standard React and Babel scripts into the engine. + /// + protected virtual void InitialiseEngine(IJsEngine engine) + { +#if NET40 + var thisAssembly = typeof(ReactEnvironment).Assembly; +#else + var thisAssembly = typeof(ReactEnvironment).GetTypeInfo().Assembly; +#endif + LoadResource(engine, "React.Core.Resources.shims.js", thisAssembly); + if (_config.LoadReact) + { + LoadResource( + engine, + _config.UseDebugReact + ? "React.Core.Resources.react.generated.js" + : "React.Core.Resources.react.generated.min.js", + thisAssembly + ); + } + + LoadUserScripts(engine); + if (!_config.LoadReact && _scriptLoadException == null) + { + // We expect the user to have loaded their own version of React in the scripts that + // were loaded above, let's ensure that's the case. + EnsureReactLoaded(engine); + } + } + + /// + /// Loads code from embedded JavaScript resource into the engine. + /// + /// Engine to load a code from embedded JavaScript resource + /// The case-sensitive resource name + /// The assembly, which contains the embedded resource + private void LoadResource(IJsEngine engine, string resourceName, Assembly assembly) + { + if (_config.AllowJavaScriptPrecompilation + && engine.TryExecuteResourceWithPrecompilation(_cache, resourceName, assembly)) + { + // Do nothing. + } + else + { + engine.ExecuteResource(resourceName, assembly); + } + } + + /// + /// Loads any user-provided scripts. Only scripts that don't need JSX transformation can + /// run immediately here. JSX files are loaded in ReactEnvironment. + /// + /// Engine to load scripts into + private void LoadUserScripts(IJsEngine engine) + { + try + { + IEnumerable manifestFiles = Enumerable.Empty(); + if (_config.ReactAppBuildPath != null) + { + var manifest = ReactAppAssetManifest.LoadManifest(_config, _fileSystem, _cache, useCacheRead: false); + manifestFiles = (manifest?.Entrypoints?.Where(x => x != null && x.EndsWith(".js"))) ?? Enumerable.Empty(); + } + + foreach (var file in _config.ScriptsWithoutTransform.Concat(manifestFiles)) + { + try + { + if (_config.AllowJavaScriptPrecompilation + && engine.TryExecuteFileWithPrecompilation(_cache, _fileSystem, file)) + { + // Do nothing. + } + else + { + engine.ExecuteFile(_fileSystem, file); + } + } + catch (JsException ex) + { + // We can't simply rethrow the exception here, as it's possible this is running + // on a background thread (ie. as a response to a file changing). If we did + // throw the exception here, it would terminate the entire process. Instead, + // save the exception, and then just rethrow it later when getting the engine. + _scriptLoadException = new ReactScriptLoadException(string.Format( + "Error while loading \"{0}\": {1}", + file, + ex.Message + ), ex); + } + } + } + catch (IOException ex) + { + // Files could be in the process of being rebuilt by JS build tooling + _scriptLoadException = new ReactScriptLoadException(ex.Message, ex);; + } + } + + /// + /// Ensures that React has been correctly loaded into the specified engine. + /// + /// Engine to check + private void EnsureReactLoaded(IJsEngine engine) + { + var globalsString = engine.CallFunction("ReactNET_initReact"); + string[] globals = globalsString.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); + + if (globals.Length != 0) + { + _scriptLoadException = new ReactNotInitialisedException( + $"React has not been loaded correctly: missing ({string.Join(", ", globals)})." + + "Please expose your version of React as global variables named " + + "'React', 'ReactDOM', and 'ReactDOMServer', or enable the 'LoadReact'" + + "configuration option to use the built-in version of React." + ); + } + } + + /// + /// Gets the JavaScript engine for the current thread. It is recommended to use + /// instead, which will pool/reuse engines. + /// + /// The JavaScript engine + public virtual IJsEngine GetEngineForCurrentThread() + { + EnsureValidState(); + return _engines.GetOrAdd(Thread.CurrentThread.ManagedThreadId, id => + { + var engine = _factory(); + InitialiseEngine(engine); + EnsureValidState(); + return engine; + }); + } + + /// + /// Disposes the JavaScript engine for the current thread. + /// + public virtual void DisposeEngineForCurrentThread() + { + IJsEngine engine; + if (_engines.TryRemove(Thread.CurrentThread.ManagedThreadId, out engine)) + { + if (engine != null) + { + engine.Dispose(); + } + } + } + + /// + /// Gets a JavaScript engine from the pool. + /// + /// The JavaScript engine + public virtual PooledJsEngine GetEngine() + { + EnsureValidState(); + return _pool.GetEngine(); + } + + /// + /// Gets a factory for the most appropriate JavaScript engine for the current environment. + /// The first functioning JavaScript engine with the lowest priority will be used. + /// + /// Function to create JavaScript engine + private static Func GetFactory(IJsEngineSwitcher jsEngineSwitcher) + { + string defaultEngineName = jsEngineSwitcher.DefaultEngineName; + if (!string.IsNullOrWhiteSpace(defaultEngineName)) + { + var engineFactory = jsEngineSwitcher.EngineFactories.Get(defaultEngineName); + if (engineFactory != null) + { + return engineFactory.CreateEngine; + } + else + { + throw new ReactEngineNotFoundException( + "Could not find a factory that creates an instance of the JavaScript " + + "engine with name `" + defaultEngineName + "`."); + } + } + + if (jsEngineSwitcher.EngineFactories.Count == 0) + { + throw new ReactException("No JS engines were registered. Visit https://reactjs.net/docs for more information."); + } + + var exceptionMessages = new List(); + foreach (var engineFactory in jsEngineSwitcher.EngineFactories.GetRegisteredFactories()) + { + IJsEngine engine = null; + try + { + engine = engineFactory.CreateEngine(); + if (EngineIsUsable(engine)) + { + // Success! Use this one. + return engineFactory.CreateEngine; + } + } + catch (JsEngineLoadException ex) + { + Trace.WriteLine(string.Format("Error initialising {0}: {1}", engineFactory, ex.Message)); + exceptionMessages.Add(ex.Message); + } + catch (Exception ex) + { + Trace.WriteLine(string.Format("Error initialising {0}: {1}", engineFactory, ex)); + exceptionMessages.Add(ex.ToString()); + } + finally + { + if (engine != null) + { + engine.Dispose(); + } + } + } + + throw new ReactEngineNotFoundException("There was an error initializing the registered JS engines. " + string.Join(Environment.NewLine, exceptionMessages)); + } + + /// + /// Performs a sanity check to ensure the specified engine type is usable. + /// + /// Engine to test + /// + private static bool EngineIsUsable(IJsEngine engine) + { + // Perform a sanity test to ensure this engine is usable + return engine.Evaluate("1 + 1") == 2; + } + + /// + /// Clean up all engines + /// + public virtual void Dispose() + { + _disposed = true; + foreach (var engine in _engines) + { + if (engine.Value != null) + { + engine.Value.Dispose(); + } + } + if (_pool != null) + { + _pool.Dispose(); + _pool = null; + } + } + + /// + /// Ensures that this object has not been disposed, and that no error was thrown while + /// loading the scripts. + /// + public void EnsureValidState() + { + if (_disposed) + { + throw new ObjectDisposedException(GetType().Name); + } + if (_scriptLoadException != null) + { + // This means an exception occurred while loading the script (eg. syntax error in the file) + throw _scriptLoadException; + } + } + } +} diff --git a/src/React.Core/JavaScriptEnginePrecompilationUtils.cs b/src/React.Core/JavaScriptEnginePrecompilationUtils.cs new file mode 100644 index 000000000..856579fc8 --- /dev/null +++ b/src/React.Core/JavaScriptEnginePrecompilationUtils.cs @@ -0,0 +1,117 @@ +using System; +using System.Reflection; +using JavaScriptEngineSwitcher.Core; +using React.Exceptions; + +namespace React +{ + /// + /// Helper methods for pre-compilation features of the JavaScript engine environment. + /// + public static class JavaScriptEnginePrecompilationUtils + { + /// + /// Cache key for the script resource pre-compilation + /// + private const string PRECOMPILED_JS_RESOURCE_CACHE_KEY = "PRECOMPILED_JS_RESOURCE_{0}"; + /// + /// Cache key for the script file pre-compilation + /// + private const string PRECOMPILED_JS_FILE_CACHE_KEY = "PRECOMPILED_JS_FILE_{0}"; + /// + /// Value that indicates whether a cache entry, that contains a precompiled script, should be + /// evicted if it has not been accessed in a given span of time + /// + private readonly static TimeSpan PRECOMPILED_JS_CACHE_ENTRY_SLIDING_EXPIRATION = TimeSpan.FromMinutes(30); + + /// + /// Tries to execute a code from JavaScript file with pre-compilation. + /// + /// Engine to execute code from JavaScript file with pre-compilation + /// Cache used for storing the pre-compiled scripts + /// File system wrapper + /// Path to the JavaScript file + /// Delegate that loads a code from specified JavaScript file + /// true if can perform a script pre-compilation; otherwise, false. + public static bool TryExecuteFileWithPrecompilation(this IJsEngine engine, ICache cache, + IFileSystem fileSystem, string path, Func scriptLoader = null) + { + EnsurePrecompilationAvailability(engine, cache); + + var cacheKey = string.Format(PRECOMPILED_JS_FILE_CACHE_KEY, path); + var precompiledScript = cache.Get(cacheKey); + + if (precompiledScript == null) + { + var contents = scriptLoader != null ? scriptLoader(path) : fileSystem.ReadAsString(path); + precompiledScript = engine.Precompile(contents, path); + var fullPath = fileSystem.MapPath(path); + cache.Set( + cacheKey, + precompiledScript, + slidingExpiration: PRECOMPILED_JS_CACHE_ENTRY_SLIDING_EXPIRATION, + cacheDependencyFiles: new[] { fullPath } + ); + } + + engine.Execute(precompiledScript); + + return true; + } + + /// + /// Tries to execute a code from embedded JavaScript resource with pre-compilation. + /// + /// Engine to execute a code from embedded JavaScript resource with pre-compilation + /// Cache used for storing the pre-compiled scripts + /// The case-sensitive resource name + /// The assembly, which contains the embedded resource + /// true if can perform a script pre-compilation; otherwise, false. + public static bool TryExecuteResourceWithPrecompilation(this IJsEngine engine, ICache cache, + string resourceName, Assembly assembly) + { + EnsurePrecompilationAvailability(engine, cache); + + var cacheKey = string.Format(PRECOMPILED_JS_RESOURCE_CACHE_KEY, resourceName); + var precompiledScript = cache.Get(cacheKey); + + if (precompiledScript == null) + { + precompiledScript = engine.PrecompileResource(resourceName, assembly); + cache.Set( + cacheKey, + precompiledScript, + slidingExpiration: PRECOMPILED_JS_CACHE_ENTRY_SLIDING_EXPIRATION + ); + } + + engine.Execute(precompiledScript); + + return true; + } + + /// + /// Ensures that the script pre-compilation is available. + /// + /// Instance of the JavaScript engine + /// Cache used for storing the pre-compiled scripts + private static void EnsurePrecompilationAvailability(IJsEngine engine, ICache cache) + { + if (!engine.SupportsScriptPrecompilation) + { + throw new ReactScriptPrecompilationNotAvailableException(string.Format( + "The {0} version {1} does not support the script pre-compilation.", + engine.Name, + engine.Version + )); + } + + if (cache is NullCache) + { + throw new ReactScriptPrecompilationNotAvailableException(string.Format( + "Usage of the script pre-compilation without caching does not make sense." + )); + } + } + } +} diff --git a/src/React.Core/JavaScriptEngineUtils.cs b/src/React.Core/JavaScriptEngineUtils.cs new file mode 100644 index 000000000..6ea8c8c3e --- /dev/null +++ b/src/React.Core/JavaScriptEngineUtils.cs @@ -0,0 +1,67 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System; +using JavaScriptEngineSwitcher.Core; +using JavaScriptEngineSwitcher.Core.Helpers; +using Newtonsoft.Json; +using React.Exceptions; + +namespace React +{ + /// + /// Various helper methods for the JavaScript engine environment. + /// + public static class JavaScriptEngineUtils + { + /// + /// Executes a code from JavaScript file. + /// + /// Engine to execute code from JavaScript file + /// File system wrapper + /// Path to the JavaScript file + public static void ExecuteFile(this IJsEngine engine, IFileSystem fileSystem, string path) + { + var contents = fileSystem.ReadAsString(path); + engine.Execute(contents, path); + } + + /// + /// Calls a JavaScript function using the specified engine. If is + /// not a scalar type, the function is assumed to return a string of JSON that can be + /// parsed as that type. + /// + /// Type returned by function + /// Engine to execute function with + /// Name of the function to execute + /// Arguments to pass to function + /// Value returned by function + public static T CallFunctionReturningJson(this IJsEngine engine, string function, params object[] args) + { + if (ValidationHelpers.IsSupportedType(typeof(T))) + { + // Type is supported directly (ie. a scalar type like string/int/bool) + // Just execute the function directly. + return engine.CallFunction(function, args); + } + // The type is not a scalar type. Assume the function will return its result as + // JSON. + var resultJson = engine.CallFunction(function, args); + try + { + return JsonConvert.DeserializeObject(resultJson); + } + catch (JsonReaderException ex) + { + throw new ReactException(string.Format( + "{0} did not return valid JSON: {1}.\n\n{2}", + function, ex.Message, resultJson + ), ex); + } + } + } +} diff --git a/src/React.Core/JavaScriptWithSourceMap.cs b/src/React.Core/JavaScriptWithSourceMap.cs new file mode 100644 index 000000000..6f2989565 --- /dev/null +++ b/src/React.Core/JavaScriptWithSourceMap.cs @@ -0,0 +1,39 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System; + +namespace React +{ + /// + /// Represents the result of a Babel transformation along with its + /// corresponding source map. + /// + [Serializable] + public class JavaScriptWithSourceMap + { + /// + /// Gets or sets the version of Babel used to perform this transformation. + /// + public string BabelVersion { get; set; } + + /// + /// The transformed result + /// + public string Code { get; set; } + + /// + /// The hash of the input file. + /// + public string Hash { get; set; } + + /// + /// The source map for this code + /// + public SourceMap SourceMap { get; set; } + } +} diff --git a/src/React.Core/MemoryFileCache.cs b/src/React.Core/MemoryFileCache.cs new file mode 100644 index 000000000..47aefd3d1 --- /dev/null +++ b/src/React.Core/MemoryFileCache.cs @@ -0,0 +1,75 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#if NET40 || NET45 +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Caching; + +namespace React +{ + /// + /// Memory cache implementation for React.ICache. Uses System.Runtime.Caching. + /// + public class MemoryFileCache : ICache + { + private readonly ObjectCache _cache; + + /// + /// Initializes a new instance of the class. + /// + public MemoryFileCache() + { + _cache = MemoryCache.Default; + } + + /// + /// Get an item from the cache. Returns if the item does + /// not exist. + /// + /// Type of data + /// The cache key + /// Value to return if item is not in the cache + /// Data from cache, otherwise + public T Get(string key, T fallback = default(T)) + { + return (T)(_cache.Get(key) ?? fallback); + } + + /// + /// Sets an item in the cache. + /// + /// Type of data + /// The cache key + /// Data to cache + /// + /// Sliding expiration, if cache key is not accessed in this time period it will + /// automatically be removed from the cache + /// + /// + /// Filenames this cached item is dependent on. If any of these files change, the cache + /// will be cleared automatically + /// + public void Set(string key, T data, TimeSpan slidingExpiration, IEnumerable cacheDependencyFiles = null) + { + if (data == null) + { + _cache.Remove(key); + return; + } + + var policy = new CacheItemPolicy { SlidingExpiration = slidingExpiration }; + + if (cacheDependencyFiles != null && cacheDependencyFiles.Any()) + policy.ChangeMonitors.Add(new HostFileChangeMonitor(cacheDependencyFiles.ToList())); + + _cache.Set(key, data, policy); + } + } +} +#endif diff --git a/src/React.Core/NullCache.cs b/src/React.Core/NullCache.cs new file mode 100644 index 000000000..445fd7e75 --- /dev/null +++ b/src/React.Core/NullCache.cs @@ -0,0 +1,50 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System; +using System.Collections.Generic; + +namespace React +{ + /// + /// Implementation of that never caches. + /// + public class NullCache : ICache + { + /// + /// Get an item from the cache. Returns if the item does + /// not exist. + /// + /// Type of data + /// The cache key + /// Value to return if item is not in the cache + /// Data from cache, otherwise + public T Get(string key, T fallback = default(T)) + { + return fallback; + } + + /// + /// Sets an item in the cache. + /// + /// Type of data + /// The cache key + /// Data to cache + /// + /// Sliding expiration, if cache key is not accessed in this time period it will + /// automatically be removed from the cache + /// + /// + /// Filenames this cached item is dependent on. If any of these files change, the cache + /// will be cleared automatically + /// + public void Set(string key, T data, TimeSpan slidingExpiration, IEnumerable cacheDependencyFiles = null) + { + // no-op + } + } +} diff --git a/src/React/Properties/AssemblyInfo.cs b/src/React.Core/Properties/AssemblyInfo.cs similarity index 100% rename from src/React/Properties/AssemblyInfo.cs rename to src/React.Core/Properties/AssemblyInfo.cs diff --git a/src/React.Core/React.Core.csproj b/src/React.Core/React.Core.csproj new file mode 100644 index 000000000..08ec0a3c6 --- /dev/null +++ b/src/React.Core/React.Core.csproj @@ -0,0 +1,65 @@ + + + + ReactJS and Babel tools for .NET. Important: This package does not do much on its own; you probably want an integration package (like React.Web.Mvc4) as well. Please refer to project site (http://reactjs.net/) for more details, usage examples and sample code. + Copyright 2014-Present Facebook, Inc + ReactJS.NET Core + Daniel Lo Nigro + net40;net45;netstandard2.0 + true + React.Core + ../key.snk + true + true + React.Core + asp.net;mvc;asp;jquery;javascript;js;react;facebook;reactjs;babel + logo_64.png + https://github.com/reactjs/react.net + https://github.com/reactjs/React.NET#licence + true + true + $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb + false + true + snupkg + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/React.Core/ReactAppAssetManifest.cs b/src/React.Core/ReactAppAssetManifest.cs new file mode 100644 index 000000000..1bd9a8453 --- /dev/null +++ b/src/React.Core/ReactAppAssetManifest.cs @@ -0,0 +1,37 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System; +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace React +{ + internal class ReactAppAssetManifest + { + public Dictionary Files { get; set; } + public List Entrypoints { get; set; } + + public static ReactAppAssetManifest LoadManifest(IReactSiteConfiguration config, IFileSystem fileSystem, ICache cache, bool useCacheRead) + { + string cacheKey = "REACT_APP_MANIFEST"; + + if (useCacheRead) + { + var cachedManifest = cache.Get(cacheKey); + if (cachedManifest != null) + return cachedManifest; + } + + var manifestString = fileSystem.ReadAsString($"{config.ReactAppBuildPath}/asset-manifest.json"); + var manifest = JsonConvert.DeserializeObject(manifestString); + + cache.Set(cacheKey, manifest, TimeSpan.FromHours(1)); + return manifest; + } + } +} diff --git a/src/React.Core/ReactComponent.cs b/src/React.Core/ReactComponent.cs new file mode 100644 index 000000000..9b54f10ff --- /dev/null +++ b/src/React.Core/ReactComponent.cs @@ -0,0 +1,322 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System; +using System.Collections.Concurrent; +using System.IO; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using JavaScriptEngineSwitcher.Core; +using Newtonsoft.Json; +using React.Exceptions; + +namespace React +{ + /// + /// Represents a React JavaScript component. + /// + public class ReactComponent : IReactComponent + { + private static readonly ConcurrentDictionary _componentNameValidCache = new ConcurrentDictionary(StringComparer.Ordinal); + + [ThreadStatic] + private static StringWriter _sharedStringWriter; + + /// + /// Regular expression used to validate JavaScript identifiers. Used to ensure component + /// names are valid. + /// Based off https://gist.github.com/Daniel15/3074365 + /// + private static readonly Regex _identifierRegex = new Regex(@"^[a-zA-Z_$][0-9a-zA-Z_$]*(?:\[(?:"".+""|\'.+\'|\d+)\])*?$", RegexOptions.Compiled); + + /// + /// Environment this component has been created in + /// + protected readonly IReactEnvironment _environment; + + /// + /// Global site configuration + /// + protected readonly IReactSiteConfiguration _configuration; + + /// + /// Raw props for this component + /// + protected object _props; + + /// + /// JSON serialized props for this component + /// + protected string _serializedProps; + + /// + /// Gets or sets the name of the component + /// + public string ComponentName { get; set; } + + /// + /// Gets or sets the unique ID for the DIV container of this component + /// + public string ContainerId { get; set; } + + /// + /// Gets or sets the HTML tag the component is wrapped in + /// + public string ContainerTag { get; set; } + + /// + /// Gets or sets the HTML class for the container of this component + /// + public string ContainerClass { get; set; } + + /// + /// Get or sets if this components only should be rendered server side + /// + public bool ServerOnly { get; set; } + + /// + /// Gets or sets the props for this component + /// + public object Props + { + get { return _props; } + set + { + _props = value; + _serializedProps = JsonConvert.SerializeObject( + value, + _configuration.JsonSerializerSettings); + } + } + /// + /// Get or sets if this components only should be rendered client side + /// + public bool ClientOnly { get; set; } + + /// + /// Initializes a new instance of the class. + /// + /// The environment. + /// Site-wide configuration. + /// React Id generator. + /// Name of the component. + /// The ID of the container DIV for this component + public ReactComponent(IReactEnvironment environment, IReactSiteConfiguration configuration, IReactIdGenerator reactIdGenerator, string componentName, string containerId) + { + EnsureComponentNameValid(componentName); + _environment = environment; + _configuration = configuration; + ComponentName = componentName; + ContainerId = string.IsNullOrEmpty(containerId) ? reactIdGenerator.Generate() : containerId; + ContainerTag = "div"; + } + + /// + /// Renders the HTML for this component. This will execute the component server-side and + /// return the rendered HTML. + /// + /// Only renders component container. Used for client-side only rendering. + /// Only renders the common HTML mark up and not any React specific data attributes. Used for server-side only rendering. + /// A custom exception handler that will be called if a component throws during a render. Args: (Exception ex, string componentName, string containerId) + /// Functions to call during component render + /// HTML + public virtual string RenderHtml(bool renderContainerOnly = false, bool renderServerOnly = false, Action exceptionHandler = null, IRenderFunctions renderFunctions = null) + { + return GetStringFromWriter(renderHtmlWriter => RenderHtml(renderHtmlWriter, renderContainerOnly, renderServerOnly, exceptionHandler, renderFunctions)); + } + + /// + /// Renders the HTML for this component. This will execute the component server-side and + /// return the rendered HTML. + /// + /// The to which the content is written + /// Only renders component container. Used for client-side only rendering. + /// Only renders the common HTML mark up and not any React specific data attributes. Used for server-side only rendering. + /// A custom exception handler that will be called if a component throws during a render. Args: (Exception ex, string componentName, string containerId) + /// Functions to call during component render + /// HTML + public virtual void RenderHtml(TextWriter writer, bool renderContainerOnly = false, bool renderServerOnly = false, Action exceptionHandler = null, IRenderFunctions renderFunctions = null) + { + if (!_configuration.UseServerSideRendering) + { + renderContainerOnly = true; + } + + if (!renderContainerOnly) + { + EnsureComponentExists(); + } + + var html = string.Empty; + if (!renderContainerOnly) + { + var stringWriter = _sharedStringWriter; + if (stringWriter != null) + { + stringWriter.GetStringBuilder().Clear(); + } + else + { + _sharedStringWriter = stringWriter = new StringWriter(new StringBuilder(_serializedProps.Length + 128)); + } + + try + { + stringWriter.Write(renderServerOnly ? "ReactDOMServer.renderToStaticMarkup(" : "ReactDOMServer.renderToString("); + if (renderFunctions != null) + { + stringWriter.Write(renderFunctions.WrapComponent(GetStringFromWriter(componentInitWriter => WriteComponentInitialiser(componentInitWriter)))); + } + else + { + WriteComponentInitialiser(stringWriter); + } + stringWriter.Write(')'); + + if (renderFunctions != null) + { + renderFunctions.PreRender(x => _environment.Execute(x)); + html = _environment.Execute(renderFunctions.TransformRenderedHtml(stringWriter.ToString())); + renderFunctions.PostRender(x => _environment.Execute(x)); + } + else + { + html = _environment.Execute(stringWriter.ToString()); + } + + if (renderServerOnly) + { + writer.Write(html); + return; + } + } + catch (JsException ex) + { + if (exceptionHandler == null) + { + exceptionHandler = _configuration.ExceptionHandler; + } + + exceptionHandler(ex, ComponentName, ContainerId); + } + } + + writer.Write('<'); + writer.Write(ContainerTag); + writer.Write(" id=\""); + writer.Write(ContainerId); + writer.Write('"'); + if (!string.IsNullOrEmpty(ContainerClass)) + { + writer.Write(" class=\""); + writer.Write(ContainerClass); + writer.Write('"'); + } + + writer.Write('>'); + writer.Write(html); + writer.Write("'); + } + + /// + /// Renders the JavaScript required to initialise this component client-side. This will + /// initialise the React component, which includes attach event handlers to the + /// server-rendered HTML. + /// + /// JavaScript + public virtual string RenderJavaScript(bool waitForDOMContentLoad) + { + return GetStringFromWriter(renderJsWriter => RenderJavaScript(renderJsWriter, waitForDOMContentLoad)); + } + + /// + /// Renders the JavaScript required to initialise this component client-side. This will + /// initialise the React component, which includes attach event handlers to the + /// server-rendered HTML. + /// + /// The to which the content is written + /// Delays the component init until the page load event fires. Useful if the component script tags are located after the call to Html.ReactWithInit. + /// JavaScript + public virtual void RenderJavaScript(TextWriter writer, bool waitForDOMContentLoad) + { + if (waitForDOMContentLoad) + { + writer.Write("window.addEventListener('DOMContentLoaded', function() {"); + } + + writer.Write( + !_configuration.UseServerSideRendering || ClientOnly ? "ReactDOM.render(" : "ReactDOM.hydrate("); + WriteComponentInitialiser(writer); + writer.Write(", document.getElementById(\""); + writer.Write(ContainerId); + writer.Write("\"))"); + + if (waitForDOMContentLoad) + { + writer.Write("});"); + } + } + + /// + /// Ensures that this component exists in global scope + /// + protected virtual void EnsureComponentExists() + { + // This is safe as componentName was validated via EnsureComponentNameValid() + var componentExists = _environment.Execute(string.Format( + "typeof {0} !== 'undefined'", + ComponentName + )); + if (!componentExists) + { + throw new ReactInvalidComponentException(string.Format( + "Could not find a component named '{0}'. Did you forget to add it to " + + "App_Start\\ReactConfig.cs?", + ComponentName + )); + } + } + + /// + /// Gets the JavaScript code to initialise the component + /// + /// The to which the content is written + protected virtual void WriteComponentInitialiser(TextWriter writer) + { + writer.Write("React.createElement("); + writer.Write(ComponentName); + writer.Write(", "); + writer.Write(_serializedProps); + writer.Write(')'); + } + + /// + /// Validates that the specified component name is valid + /// + /// + internal static void EnsureComponentNameValid(string componentName) + { + var isValid = _componentNameValidCache.GetOrAdd(componentName, compName => compName.Split('.').All(segment => _identifierRegex.IsMatch(segment))); + if (!isValid) + { + throw new ReactInvalidComponentException($"Invalid component name '{componentName}'"); + } + } + + private string GetStringFromWriter(Action fnWithTextWriter) + { + using (var textWriter = new StringWriter()) + { + fnWithTextWriter(textWriter); + return textWriter.ToString(); + } + } + } +} diff --git a/src/React.Core/ReactEnvironment.cs b/src/React.Core/ReactEnvironment.cs new file mode 100644 index 000000000..9ec081d40 --- /dev/null +++ b/src/React.Core/ReactEnvironment.cs @@ -0,0 +1,527 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Threading; +using JavaScriptEngineSwitcher.Core; +using JSPool; +using React.Exceptions; +using React.TinyIoC; + +namespace React +{ + /// + /// Request-specific ReactJS.NET environment. This is unique to the individual request and is + /// not shared. + /// + public class ReactEnvironment : IReactEnvironment, IDisposable + { + /// + /// JavaScript variable set when user-provided scripts have been loaded + /// + protected const string USER_SCRIPTS_LOADED_KEY = "_ReactNET_UserScripts_Loaded"; + /// + /// Stack size to use for JSXTransformer if the default stack is insufficient + /// + protected const int LARGE_STACK_SIZE = 2 * 1024 * 1024; + + /// + /// Factory to create JavaScript engines + /// + protected readonly IJavaScriptEngineFactory _engineFactory; + /// + /// Site-wide configuration + /// + protected readonly IReactSiteConfiguration _config; + /// + /// Cache used for storing compiled JSX + /// + protected readonly ICache _cache; + /// + /// File system wrapper + /// + protected readonly IFileSystem _fileSystem; + /// + /// Hash algorithm for file-based cache + /// + protected readonly IFileCacheHash _fileCacheHash; + /// + /// React Id generator + /// + private readonly IReactIdGenerator _reactIdGenerator; + + /// + /// JSX Transformer instance for this environment + /// + protected readonly Lazy _babelTransformer; + /// + /// Version number of ReactJS.NET + /// + protected readonly Lazy _version = new Lazy(GetVersion); + + /// + /// Contains an engine acquired from a pool of engines. Only used if + /// is enabled. + /// + protected Lazy _engineFromPool; + + /// + /// List of all components instantiated in this environment + /// + protected readonly IList _components = new List(); + + /// + /// Gets the for the current request. If no environment + /// has been created for the current request, creates a new one. + /// + public static IReactEnvironment Current + { + get { return AssemblyRegistration.Container.Resolve(); } + } + + /// + /// Gets the for the current request. If no environment + /// has been created for the current request, creates a new one. + /// Also provides more specific error information in the event that ReactJS.NET is misconfigured. + /// + public static IReactEnvironment GetCurrentOrThrow + { + get + { + try + { + return Current; + } + catch (TinyIoCResolutionException ex) + { + throw new ReactNotInitialisedException( +#if NET451 + "ReactJS.NET has not been initialised correctly.", +#else + "ReactJS.NET has not been initialised correctly. Please ensure you have " + + "called services.AddReact() and app.UseReact() in your Startup.cs file.", +#endif + ex + ); + } + } + } + + /// + /// Initializes a new instance of the class. + /// + /// The JavaScript engine factory + /// The site-wide configuration + /// The cache to use for JSX compilation + /// File system wrapper + /// Hash algorithm for file-based cache + /// React ID generator + public ReactEnvironment( + IJavaScriptEngineFactory engineFactory, + IReactSiteConfiguration config, + ICache cache, + IFileSystem fileSystem, + IFileCacheHash fileCacheHash, + IReactIdGenerator reactIdGenerator + ) + { + _engineFactory = engineFactory; + _config = config; + _cache = cache; + _fileSystem = fileSystem; + _fileCacheHash = fileCacheHash; + _reactIdGenerator = reactIdGenerator; + _babelTransformer = new Lazy(() => + new Babel(this, _cache, _fileSystem, _fileCacheHash, _config) + ); + _engineFromPool = new Lazy(() => _engineFactory.GetEngine()); + } + + /// + /// Gets the JavaScript engine to use for this environment. + /// + protected virtual IJsEngine Engine + { + get + { + return _config.ReuseJavaScriptEngines + ? _engineFromPool.Value + : _engineFactory.GetEngineForCurrentThread(); + } + } + + /// + /// Gets the Babel transformer for this environment. + /// + public virtual IBabel Babel + { + get { return _babelTransformer.Value; } + } + + /// + /// Gets the version of the JavaScript engine in use by ReactJS.NET + /// + public virtual string EngineVersion + { + get { return Engine.Name + " " + Engine.Version; } + } + + /// + /// Gets the version number of ReactJS.NET + /// + public virtual string Version + { + get { return _version.Value; } + } + + /// + /// Ensures any user-provided scripts have been loaded. This only loads JSX files; files + /// that need no transformation are loaded in JavaScriptEngineFactory. + /// + protected virtual void EnsureUserScriptsLoaded() + { + // Scripts already loaded into this environment, don't load them again + if (Engine.HasVariable(USER_SCRIPTS_LOADED_KEY) || _config == null) + { + return; + } + + foreach (var file in _config.Scripts) + { + try + { + if (_config.AllowJavaScriptPrecompilation + && Engine.TryExecuteFileWithPrecompilation(_cache, _fileSystem, file, Babel.TransformFile)) + { + // Do nothing. + } + else + { + var contents = Babel.TransformFile(file); + Engine.Execute(contents, file); + } + } + catch (JsException ex) + { + throw new ReactScriptLoadException(string.Format( + "Error while loading \"{0}\": {1}", + file, + ex.Message + ), ex); + } + } + Engine.SetVariableValue(USER_SCRIPTS_LOADED_KEY, true); + } + + /// + /// Executes the provided JavaScript code. + /// + /// JavaScript to execute + public virtual void Execute(string code) + { + Engine.Execute(code); + } + + /// + /// Executes the provided JavaScript code, returning a result of the specified type. + /// + /// Type to return + /// Code to execute + /// Result of the JavaScript code + public virtual T Execute(string code) + { + return Engine.Evaluate(code); + } + + /// + /// Executes the provided JavaScript function, returning a result of the specified type. + /// + /// Type to return + /// JavaScript function to execute + /// Arguments to pass to function + /// Result of the JavaScript code + public virtual T Execute(string function, params object[] args) + { + return Engine.CallFunctionReturningJson(function, args); + } + + /// + /// Determines if the specified variable exists in the JavaScript engine + /// + /// Name of the variable + /// true if the variable exists; false otherwise + public virtual bool HasVariable(string name) + { + return Engine.HasVariable(name); + } + + /// + /// Creates an instance of the specified React JavaScript component. + /// + /// Type of the props + /// Name of the component + /// Props to use + /// ID to use for the container HTML tag. Defaults to an auto-generated ID + /// True if server-side rendering will be bypassed. Defaults to false. + /// True if this component only should be rendered server-side. Defaults to false. + /// Skip adding to components list, which is used during GetInitJavascript + /// The component + public virtual IReactComponent CreateComponent(string componentName, T props, string containerId = null, bool clientOnly = false, bool serverOnly = false, bool skipLazyInit = false) + { + if (!clientOnly) + { + EnsureUserScriptsLoaded(); + } + + var component = new ReactComponent(this, _config, _reactIdGenerator, componentName, containerId) + { + ClientOnly = clientOnly, + Props = props, + ServerOnly = serverOnly + }; + + if (!skipLazyInit) + { + _components.Add(component); + } + return component; + } + + /// + /// Adds the provided to the list of components to render client side. + /// + /// Component to add to client side render list + /// True if server-side rendering will be bypassed. Defaults to false. + /// The component + public virtual IReactComponent CreateComponent(IReactComponent component, bool clientOnly = false) + { + if (!clientOnly) + { + EnsureUserScriptsLoaded(); + } + + _components.Add(component); + return component; + } + + /// + /// Renders the JavaScript required to initialise all components client-side. This will + /// attach event handlers to the server-rendered HTML. + /// + /// True if server-side rendering will be bypassed. Defaults to false. + /// JavaScript for all components + public virtual string GetInitJavaScript(bool clientOnly = false) + { + using (var writer = new StringWriter()) + { + GetInitJavaScript(writer, clientOnly); + return writer.ToString(); + } + } + + /// + /// Renders the JavaScript required to initialise all components client-side. This will + /// attach event handlers to the server-rendered HTML. + /// + /// The to which the content is written + /// True if server-side rendering will be bypassed. Defaults to false. + /// JavaScript for all components + public virtual void GetInitJavaScript(TextWriter writer, bool clientOnly = false) + { + // Propagate any server-side console.log calls to corresponding client-side calls. + if (!clientOnly && _components.Count != 0) + { + var consoleCalls = Execute("console.getCalls()"); + writer.Write(consoleCalls); + } + + foreach (var component in _components) + { + if (!component.ServerOnly) + { + component.RenderJavaScript(writer, waitForDOMContentLoad: false); + writer.WriteLine(';'); + } + } + } + + private ReactAppAssetManifest GetAppManifest() => ReactAppAssetManifest.LoadManifest(_config, _fileSystem, _cache, useCacheRead: true); + + /// + /// Returns a list of paths to scripts generated by the React app + /// + public virtual IEnumerable GetScriptPaths() + { + return GetAppManifest().Entrypoints + .Where(path => path.EndsWith(".js")); + } + + /// + /// Returns a list of paths to stylesheets generated by the React app + /// + public virtual IEnumerable GetStylePaths() + { + return GetAppManifest().Entrypoints + .Where(path => path.EndsWith(".css")); + } + + /// + /// Attempts to execute the provided JavaScript code using a non-pooled JavaScript engine (ie. + /// creates a new JS engine per-thread). This is because Babel uses a LOT of memory, so we + /// should completely dispose any engines that have loaded Babel in order to conserve memory. + /// + /// If an exception is thrown, retries the execution using a new thread (and hence a new engine) + /// with a larger maximum stack size. + /// This is required because JSXTransformer uses a huge stack which ends up being larger + /// than what ASP.NET allows by default (256 KB). + /// + /// Type to return from JavaScript call + /// JavaScript function to execute + /// Arguments to pass to function + /// Result returned from JavaScript code + public virtual T ExecuteWithBabel(string function, params object[] args) + { + var engine = _engineFactory.GetEngineForCurrentThread(); + EnsureBabelLoaded(engine); + +#if NET40 || NET45 || NETSTANDARD2_0 + try + { + return engine.CallFunctionReturningJson(function, args); + } + + catch (Exception) + { + // Assume the exception MAY be an "out of stack space" error. Try running the code + // in a different thread with larger stack. If the same exception occurs, we know + // it wasn't a stack space issue. + T result = default(T); + Exception innerEx = null; + var thread = new Thread(() => + { + // New engine will be created here (as this is a new thread) + var threadEngine = _engineFactory.GetEngineForCurrentThread(); + EnsureBabelLoaded(threadEngine); + try + { + result = threadEngine.CallFunctionReturningJson(function, args); + } + catch (Exception threadEx) + { + // Unhandled exceptions in threads kill the whole process. + // Pass the exception back to the parent thread to rethrow. + innerEx = threadEx; + } + finally + { + _engineFactory.DisposeEngineForCurrentThread(); + } + }, LARGE_STACK_SIZE); + thread.Start(); + thread.Join(); + // Rethrow any exceptions that occured in the thread + if (innerEx != null) + { + throw innerEx; + } + return result; + } +#else + return engine.CallFunctionReturningJson(function, args); +#endif + } + + /// + /// Gets the ReactJS.NET version number. Use instead. + /// + private static string GetVersion() + { +#if NET40 + var assembly = Assembly.GetExecutingAssembly(); + var rawVersion = FileVersionInfo.GetVersionInfo(assembly.Location).FileVersion; +#else + var assembly = typeof(ReactEnvironment).GetTypeInfo().Assembly; + var rawVersion = assembly.GetCustomAttribute().Version; +#endif + var lastDot = rawVersion.LastIndexOf('.'); + var version = rawVersion.Substring(0, lastDot); + var build = rawVersion.Substring(lastDot + 1); + return string.Format("{0} (build {1})", version, build); + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public virtual void Dispose() + { + _engineFactory.DisposeEngineForCurrentThread(); + ReturnEngineToPool(); + } + + /// + /// Returns the currently held JS engine to the pool. (no-op if engine pooling is disabled) + /// + public void ReturnEngineToPool() + { + if (_engineFromPool.IsValueCreated) + { + _engineFromPool.Value.Dispose(); + _engineFromPool = new Lazy(() => _engineFactory.GetEngine()); + } + } + + /// + /// Gets the site-wide configuration. + /// + public virtual IReactSiteConfiguration Configuration + { + get { return _config; } + } + + /// + /// Ensures that Babel has been loaded into the JavaScript engine. + /// + private void EnsureBabelLoaded(IJsEngine engine) + { + // If Babel is disabled in the config, don't even try loading it + if (!_config.LoadBabel) + { + throw new BabelNotLoadedException(); + } + + var babelLoaded = engine.Evaluate("typeof ReactNET_transform !== 'undefined'"); + if (!babelLoaded) + { +#if NET40 + var assembly = typeof(ReactEnvironment).Assembly; +#else + var assembly = typeof(ReactEnvironment).GetTypeInfo().Assembly; +#endif + string resourceName = _config.BabelVersion == BabelVersions.Babel7 || _config.BabelVersion == null + ? "React.Core.Resources.babel.generated.min.js" + : _config.BabelVersion == BabelVersions.Babel6 + ? "React.Core.Resources.babel-legacy.generated.min.js" + : throw new ReactConfigurationException("BabelVersion was not null, but did not contain a valid value."); + + if (_config.AllowJavaScriptPrecompilation + && engine.TryExecuteResourceWithPrecompilation(_cache, resourceName, assembly)) + { + // Do nothing. + } + else + { + engine.ExecuteResource(resourceName, assembly); + } + } + } + } +} diff --git a/src/React.Core/ReactIdGenerator.cs b/src/React.Core/ReactIdGenerator.cs new file mode 100644 index 000000000..c4c62d9d3 --- /dev/null +++ b/src/React.Core/ReactIdGenerator.cs @@ -0,0 +1,66 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System; +using System.Threading; + +namespace React +{ + /// + /// React ID generator. + /// + public class ReactIdGenerator : IReactIdGenerator + { + private static readonly string _encode32Chars = "0123456789ABCDEFGHIJKLMNOPQRSTUV"; + + private static long _random = DateTime.UtcNow.Ticks; + + private static readonly char[] reactPrefix = "react_".ToCharArray(); + + /// + /// "react_".Length = 6 + 13 random symbols + /// + private const int reactIdLength = 19; + + [ThreadStatic] + private static char[] _chars; + + /// + /// Returns a short react identifier starts with "react_". + /// + /// + public string Generate() + { + var chars = _chars; + if (chars == null) + { + _chars = chars = new char[reactIdLength]; + Array.Copy(reactPrefix, 0, chars, 0, reactPrefix.Length); + } + + var id = Interlocked.Increment(ref _random); + + // from 6 because "react_".Length == 6, _encode32Chars.Length == 32 (base32), + // base32 characters are 5 bits in length and from long (64 bits) we can get 13 symbols + chars[6] = _encode32Chars[(int)(id >> 60) & 31]; + chars[7] = _encode32Chars[(int)(id >> 55) & 31]; + chars[8] = _encode32Chars[(int)(id >> 50) & 31]; + chars[9] = _encode32Chars[(int)(id >> 45) & 31]; + chars[10] = _encode32Chars[(int)(id >> 40) & 31]; + chars[11] = _encode32Chars[(int)(id >> 35) & 31]; + chars[12] = _encode32Chars[(int)(id >> 30) & 31]; + chars[13] = _encode32Chars[(int)(id >> 25) & 31]; + chars[14] = _encode32Chars[(int)(id >> 20) & 31]; + chars[15] = _encode32Chars[(int)(id >> 15) & 31]; + chars[16] = _encode32Chars[(int)(id >> 10) & 31]; + chars[17] = _encode32Chars[(int)(id >> 5) & 31]; + chars[18] = _encode32Chars[(int)id & 31]; + + return new string(chars, 0, reactIdLength); + } + } +} diff --git a/src/React.Core/ReactSiteConfiguration.cs b/src/React.Core/ReactSiteConfiguration.cs new file mode 100644 index 000000000..e4b36d29c --- /dev/null +++ b/src/React.Core/ReactSiteConfiguration.cs @@ -0,0 +1,379 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using Newtonsoft.Json; +using React.Exceptions; + +namespace React +{ + /// + /// Site-wide configuration for ReactJS.NET + /// + public class ReactSiteConfiguration : IReactSiteConfiguration + { + /// + /// Gets or sets the site-side configuration + /// + public static IReactSiteConfiguration Configuration { get; set; } + + static ReactSiteConfiguration() + { + Configuration = new ReactSiteConfiguration(); + } + + /// + /// Initializes a new instance of the class. + /// + public ReactSiteConfiguration() + { + BabelConfig = new BabelConfig(); + ReuseJavaScriptEngines = true; + AllowJavaScriptPrecompilation = false; + LoadBabel = true; + LoadReact = true; + JsonSerializerSettings = new JsonSerializerSettings + { + StringEscapeHandling = StringEscapeHandling.EscapeHtml + }; + UseDebugReact = false; + UseServerSideRendering = true; + ExceptionHandler = (Exception ex, string ComponentName, string ContainerId) => + throw new ReactServerRenderingException(string.Format( + "Error while rendering \"{0}\" to \"{2}\": {1}", + ComponentName, + ex.Message, + ContainerId + ), ex); + } + + /// + /// All the scripts that have been added to this configuration and require JSX + /// transformation to be run. + /// + private readonly IList _scriptFiles = new List(); + /// + /// All the scripts that have been added to this configuration and do not require JSX + /// transformation to be run. + /// + private readonly IList _scriptFilesWithoutTransform = new List(); + + /// + /// Adds a script to the list of scripts that are executed. This should be called for all + /// React components and their dependencies. If the script does not have any JSX in it + /// (for example, it's built using Webpack or Gulp), use + /// instead. + /// + /// + /// Name of the file to execute. Should be a server relative path starting with ~ (eg. + /// ~/Scripts/Awesome.js) + /// + /// This configuration, for chaining + public IReactSiteConfiguration AddScript(string filename) + { + _scriptFiles.Add(filename); + return this; + } + + /// + /// Adds a script to the list of scripts that are executed. This is the same as + /// except it does not run JSX transformation on the script and thus is + /// more efficient. + /// + /// + /// Name of the file to execute. Should be a server relative path starting with ~ (eg. + /// ~/Scripts/Awesome.js) + /// + /// The configuration, for chaining + public IReactSiteConfiguration AddScriptWithoutTransform(string filename) + { + _scriptFilesWithoutTransform.Add(filename); + return this; + } + + /// + /// Gets all the file paths that match the specified pattern. If the pattern is a plain + /// path, just returns that path verbatim. + /// + /// + /// Patterns to search for (eg. ~/Scripts/*.js or ~/Scripts/Awesome.js + /// + /// File paths that match this pattern + private IEnumerable Glob(string glob) + { + if (!glob.IsGlobPattern()) + { + return new[] {glob}; + } + // Directly touching the IoC container is not ideal, but we only want to pull the FileSystem + // dependency if it's absolutely necessary. + var fileSystem = AssemblyRegistration.Container.Resolve(); + return fileSystem.Glob(glob); + } + + /// + /// Gets a list of all the scripts that have been added to this configuration and require JSX + /// transformation to be run. + /// + public IEnumerable Scripts + { + // TODO: It's a bit strange to do the globbing here, ideally this class should just be a simple + // bag of settings with no logic. + get { return _scriptFiles.SelectMany(Glob); } + } + + /// + /// Gets a list of all the scripts that have been added to this configuration. + /// + public IEnumerable ScriptsWithoutTransform + { + get { return _scriptFilesWithoutTransform.SelectMany(Glob); } + } + + /// + /// Gets or sets the configuration for JSON serializer. + /// + public JsonSerializerSettings JsonSerializerSettings { get; set; } + + /// + /// Sets the configuration for json serializer. + /// + /// Settings. + /// + /// Thic confiquration is used when component initialization script + /// is being generated server-side. + /// + public IReactSiteConfiguration SetJsonSerializerSettings(JsonSerializerSettings settings) + { + JsonSerializerSettings = settings; + return this; + } + + /// + /// Gets or sets whether JavaScript engines should be reused across requests. + /// + public bool ReuseJavaScriptEngines { get; set; } + /// + /// Sets whether JavaScript engines should be reused across requests. + /// + public IReactSiteConfiguration SetReuseJavaScriptEngines(bool value) + { + ReuseJavaScriptEngines = value; + return this; + } + + /// + /// Gets or sets the number of engines to initially start when a pool is created. + /// Defaults to 10. + /// + public int? StartEngines { get; set; } + /// + /// Sets the number of engines to initially start when a pool is created. + /// Defaults to 10. + /// + public IReactSiteConfiguration SetStartEngines(int? startEngines) + { + StartEngines = startEngines; + return this; + } + + /// + /// Gets or sets the maximum number of engines that will be created in the pool. + /// Defaults to 25. + /// + public int? MaxEngines { get; set; } + /// + /// Sets the maximum number of engines that will be created in the pool. + /// Defaults to 25. + /// + public IReactSiteConfiguration SetMaxEngines(int? maxEngines) + { + MaxEngines = maxEngines; + return this; + } + + /// + /// Gets or sets the maximum number of times an engine can be reused before it is disposed. + /// 0 is unlimited. Defaults to 100. + /// + public int? MaxUsagesPerEngine { get; set; } + /// + /// Sets the maximum number of times an engine can be reused before it is disposed. + /// 0 is unlimited. Defaults to 100. + /// + public IReactSiteConfiguration SetMaxUsagesPerEngine(int? maxUsagesPerEngine) + { + MaxUsagesPerEngine = maxUsagesPerEngine; + return this; + } + + /// + /// Gets or sets whether to allow the JavaScript pre-compilation (accelerates the + /// initialization of JavaScript engines). + /// + public bool AllowJavaScriptPrecompilation { get; set; } + + /// + /// Sets whether to allow the JavaScript pre-compilation (accelerates the initialization of + /// JavaScript engines). + /// + /// + public IReactSiteConfiguration SetAllowJavaScriptPrecompilation(bool allowJavaScriptPrecompilation) + { + AllowJavaScriptPrecompilation = allowJavaScriptPrecompilation; + return this; + } + + /// + /// Gets or sets whether the built-in version of React is loaded. If false, you must + /// provide your own version of React. + /// + public bool LoadReact { get; set; } + + /// + /// Sets whether the built-in version of React is loaded. If false, you must + /// provide your own version of React. + /// + /// The configuration, for chaining + public IReactSiteConfiguration SetLoadReact(bool loadReact) + { + LoadReact = loadReact; + return this; + } + + /// + /// Gets or sets whether Babel is loading. Disabling the loading of Babel can improve startup + /// performance, but all your JSX files must be transformed beforehand (eg. through Babel, + /// Webpack or Browserify). + /// + public bool LoadBabel { get; set; } + + /// + /// Sets whether Babel is loading. Disabling the loading of Babel can improve startup + /// performance, but all your JSX files must be transformed beforehand (eg. through Babel, + /// Webpack or Browserify). + /// + public IReactSiteConfiguration SetLoadBabel(bool loadBabel) + { + LoadBabel = loadBabel; + return this; + } + + /// + /// Gets or sets the Babel configuration to use. + /// + public BabelConfig BabelConfig { get; set; } + + /// + /// Sets the Babel configuration to use. + /// + /// The configuration, for chaining + public IReactSiteConfiguration SetBabelConfig(BabelConfig value) + { + BabelConfig = value; + return this; + } + + /// + /// Gets or sets the Babel version to use. Supports "babel@6 or babel@7". + /// + public string BabelVersion { get; set; } + + /// + /// Sets the Babel version to use. + /// + /// The configuration, for chaining + public IReactSiteConfiguration SetBabelVersion(string value) + { + BabelVersion = value; + return this; + } + + /// + /// Gets or sets whether to use the debug version of React. This is slower, but gives + /// useful debugging tips. + /// + public bool UseDebugReact { get; set; } + + /// + /// Sets whether to use the debug version of React. This is slower, but gives + /// useful debugging tips. + /// + public IReactSiteConfiguration SetUseDebugReact(bool value) + { + UseDebugReact = value; + return this; + } + + /// + /// Gets or sets whether server-side rendering is enabled. + /// + public bool UseServerSideRendering { get; set; } + + /// + /// Disables server-side rendering. This is useful when debugging your scripts. + /// + public IReactSiteConfiguration DisableServerSideRendering() + { + UseServerSideRendering = false; + return this; + } + + /// + /// Handle an exception caught during server-render of a component. + /// If unset, unhandled exceptions will be thrown for all component renders. + /// + public Action ExceptionHandler { get; set; } + + /// + /// + /// + /// + /// + public IReactSiteConfiguration SetExceptionHandler(Action handler) + { + ExceptionHandler = handler; + return this; + } + + /// + /// A provider that returns a nonce to be used on any script tags on the page. + /// This value must match the nonce used in the Content Security Policy header on the response. + /// + public Func ScriptNonceProvider { get; set; } + + /// + /// Sets a provider that returns a nonce to be used on any script tags on the page. + /// This value must match the nonce used in the Content Security Policy header on the response. + /// + /// + /// + public IReactSiteConfiguration SetScriptNonceProvider(Func provider) + { + ScriptNonceProvider = provider; + return this; + } + + /// + /// The path to the application bundles built by webpack or create-react-app + /// + public string ReactAppBuildPath { get; set; } + + /// + /// Sets the path to the application bundles built by webpack or create-react-app + /// + /// + /// + public IReactSiteConfiguration SetReactAppBuildPath(string reactAppBuildPath) + { + ReactAppBuildPath = reactAppBuildPath; + return this; + } + } +} diff --git a/src/React.Core/RenderFunctions/ChainedRenderFunctions.cs b/src/React.Core/RenderFunctions/ChainedRenderFunctions.cs new file mode 100644 index 000000000..5e53b8773 --- /dev/null +++ b/src/React.Core/RenderFunctions/ChainedRenderFunctions.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; + +namespace React.RenderFunctions +{ + /// + /// Helper to chain functions to be executed during server-side rendering. + /// For instance, React Router and React Helmet can both be used together using this class. + /// + public class ChainedRenderFunctions : IRenderFunctions + { + private readonly ReadOnlyCollection _chainedFunctions; + + /// + /// Constructor. Supports chained calls to multiple render functions by passing in a set of functions that should be called next. + /// + /// The chained render functions to call + public ChainedRenderFunctions(params IRenderFunctions[] chainedFunctions) + { + _chainedFunctions = chainedFunctions.Where(x => x != null).ToList().AsReadOnly(); + } + + /// + /// Executes before component render. + /// It takes a func that accepts a Javascript code expression to evaluate, which returns the result of the expression. + /// This is useful for setting up variables that will be referenced after the render completes. + /// The func to execute + /// + public void PreRender(Func executeJs) + { + foreach (var chainedFunction in _chainedFunctions) + { + chainedFunction.PreRender(executeJs); + } + } + + + /// + /// Transforms the React.createElement expression. + /// This is useful for libraries like styled components which require wrapping the root component + /// inside a helper to generate a stylesheet. + /// Example transform: React.createElement(Foo, ...) => wrapComponent(React.createElement(Foo, ...)) + /// + /// The Javascript expression to wrap + /// A wrapped expression + public string WrapComponent(string componentToRender) + { + string wrappedComponent = componentToRender; + + foreach (var chainedFunction in _chainedFunctions) + { + wrappedComponent = chainedFunction.WrapComponent(wrappedComponent); + } + + return wrappedComponent; + } + + + /// + /// Transforms the compiled rendered component HTML + /// This is useful for libraries like emotion which take rendered component HTML and output the transformed HTML plus additional style tags + /// + /// The component HTML + /// A wrapped expression + public string TransformRenderedHtml(string input) + { + string renderedHtml = input; + + foreach (var chainedFunction in _chainedFunctions) + { + renderedHtml = chainedFunction.TransformRenderedHtml(renderedHtml); + } + + return renderedHtml; + } + + + /// + /// Executes after component render. + /// It takes a func that accepts a Javascript code expression to evaluate, which returns the result of the expression. + /// This is useful for reading computed state, such as generated stylesheets or a router redirect result. + /// + /// The func to execute + public void PostRender(Func executeJs) + { + foreach (var chainedFunction in _chainedFunctions) + { + chainedFunction.PostRender(executeJs); + } + } + } +} diff --git a/src/React.Core/RenderFunctions/EmotionFunctions.cs b/src/React.Core/RenderFunctions/EmotionFunctions.cs new file mode 100644 index 000000000..0707fc3c9 --- /dev/null +++ b/src/React.Core/RenderFunctions/EmotionFunctions.cs @@ -0,0 +1,22 @@ +using System; +using System.Text; + +namespace React.RenderFunctions +{ + /// + /// Render functions for Emotion. https://github.com/emotion-js/emotion + /// Requires `emotion-server` to be exposed globally as `EmotionServer` + /// + public class EmotionFunctions : RenderFunctionsBase + { + /// + /// Implementation of TransformRenderedHtml + /// + /// + /// + public override string TransformRenderedHtml(string input) + { + return $"EmotionServer.renderStylesToString({input})"; + } + } +} diff --git a/src/React.Core/RenderFunctions/ReactHelmetFunctions.cs b/src/React.Core/RenderFunctions/ReactHelmetFunctions.cs new file mode 100644 index 000000000..56c12e662 --- /dev/null +++ b/src/React.Core/RenderFunctions/ReactHelmetFunctions.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Newtonsoft.Json; + +namespace React.RenderFunctions +{ + /// + /// Render functions for React-Helmet. https://github.com/nfl/react-helmet + /// Requires `react-helmet` to be exposed globally as `Helmet` + /// + public class ReactHelmetFunctions : RenderFunctionsBase + { + /// + /// Dictionary of Helmet properties, rendered as raw HTML tags + /// Available keys: "base", "bodyAttributes", "htmlAttributes", "link", "meta", "noscript", "script", "style", "title" + /// + public Dictionary RenderedHelmet { get; private set; } + + /// + /// Implementation of PostRender + /// + /// + public override void PostRender(Func executeJs) + { + var helmetString = executeJs(@" +var helmetResult = Helmet.renderStatic(); +JSON.stringify(['base', 'bodyAttributes', 'htmlAttributes', 'link', 'meta', 'noscript', 'script', 'style', 'title'] + .reduce((mappedResults, helmetKey) => Object.assign(mappedResults, { [helmetKey]: helmetResult[helmetKey] && helmetResult[helmetKey].toString() }), {}));"); + + RenderedHelmet = JsonConvert.DeserializeObject>(helmetString); + } + } +} diff --git a/src/React.Core/RenderFunctions/ReactJssFunctions.cs b/src/React.Core/RenderFunctions/ReactJssFunctions.cs new file mode 100644 index 000000000..155d961b4 --- /dev/null +++ b/src/React.Core/RenderFunctions/ReactJssFunctions.cs @@ -0,0 +1,44 @@ +using System; + +namespace React.RenderFunctions +{ + /// + /// Render functions for React-JSS. https://github.com/cssinjs/react-jss + /// Requires `react-jss` to be exposed globally as `ReactJss` + /// + public class ReactJssFunctions : RenderFunctionsBase + { + /// + /// HTML style tag containing the rendered styles + /// + public string RenderedStyles { get; private set; } + + /// + /// Implementation of PreRender + /// + /// + public override void PreRender(Func executeJs) + { + executeJs("var reactJssProps = { registry: new ReactJss.SheetsRegistry() };"); + } + + /// + /// Implementation of WrapComponent + /// + /// + /// + public override string WrapComponent(string componentToRender) + { + return ($"React.createElement(ReactJss.JssProvider, reactJssProps, ({componentToRender}))"); + } + + /// + /// Implementation of PostRender + /// + /// + public override void PostRender(Func executeJs) + { + RenderedStyles = $""; + } + } +} diff --git a/src/React.Core/RenderFunctions/StyledComponentsFunctions.cs b/src/React.Core/RenderFunctions/StyledComponentsFunctions.cs new file mode 100644 index 000000000..2cfbbe25a --- /dev/null +++ b/src/React.Core/RenderFunctions/StyledComponentsFunctions.cs @@ -0,0 +1,44 @@ +using System; + +namespace React.RenderFunctions +{ + /// + /// Render functions for styled components. https://github.com/styled-components/styled-components + /// Requires `styled-components` to be exposed globally as `Styled` + /// + public class StyledComponentsFunctions : RenderFunctionsBase + { + /// + /// HTML style tag containing the rendered styles + /// + public string RenderedStyles { get; private set; } + + /// + /// Implementation of PreRender + /// + /// + public override void PreRender(Func executeJs) + { + executeJs("var serverStyleSheet = new Styled.ServerStyleSheet();"); + } + + /// + /// Implementation of WrapComponent + /// + /// + /// + public override string WrapComponent(string componentToRender) + { + return ($"serverStyleSheet.collectStyles({componentToRender})"); + } + + /// + /// Implementation of PostRender + /// + /// + public override void PostRender(Func executeJs) + { + RenderedStyles = executeJs("serverStyleSheet.getStyleTags()"); + } + } +} diff --git a/src/React.Core/RenderFunctionsBase.cs b/src/React.Core/RenderFunctionsBase.cs new file mode 100644 index 000000000..fdf4f3fcf --- /dev/null +++ b/src/React.Core/RenderFunctionsBase.cs @@ -0,0 +1,52 @@ +using System; + +namespace React +{ + /// + /// Functions to execute during a render request. + /// These functions will share the same Javascript context, so state can be passed around via variables. + /// + public abstract class RenderFunctionsBase : IRenderFunctions + { + /// + /// Executes before component render. + /// It takes a func that accepts a Javascript code expression to evaluate, which returns the result of the expression. + /// This is useful for setting up variables that will be referenced after the render completes. + /// The func to execute + /// + public virtual void PreRender(Func executeJs) + { + } + + + /// + /// Transforms the React.createElement expression. + /// This is useful for libraries like styled components which require wrapping the root component + /// inside a helper to generate a stylesheet. + /// Example transform: React.createElement(Foo, ...) => wrapComponent(React.createElement(Foo, ...)) + /// + /// The Javascript expression to wrap + /// A wrapped expression + public virtual string WrapComponent(string componentToRender) => componentToRender; + + + /// + /// Transforms the compiled rendered component HTML + /// This is useful for libraries like emotion which take rendered component HTML and output the transformed HTML plus additional style tags + /// + /// The component HTML + /// A wrapped expression + public virtual string TransformRenderedHtml(string input) => input; + + + /// + /// Executes after component render. + /// It takes a func that accepts a Javascript code expression to evaluate, which returns the result of the expression. + /// This is useful for reading computed state, such as generated stylesheets or a router redirect result. + /// + /// The func to execute + public virtual void PostRender(Func executeJs) + { + } + } +} diff --git a/src/React.Core/Resources/babel-legacy/babel.js b/src/React.Core/Resources/babel-legacy/babel.js new file mode 100644 index 000000000..47ac7290b --- /dev/null +++ b/src/React.Core/Resources/babel-legacy/babel.js @@ -0,0 +1,42 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import {transform as babelTransform, version as babelVersion} from 'babel-standalone'; + +export function ReactNET_transform(input, babelConfig, filename) { + babelConfig = { + ...JSON.parse(babelConfig), + ast: false, + filename, + } + try { + return babelTransform(input, babelConfig).code; + } catch (ex) { + // Parsing stack is extremely long and not very useful, so just rethrow the message. + throw new Error(ex.message); + } +} + +export function ReactNET_transform_sourcemap(input, babelConfig, filename) { + babelConfig = { + ...JSON.parse(babelConfig), + ast: false, + filename, + sourceMaps: true, + }; + try { + var result = babelTransform(input, babelConfig); + return JSON.stringify({ + babelVersion, + code: result.code, + sourceMap: result.map + }); + } catch (ex) { + // Parsing stack is extremely long and not very useful, so just rethrow the message. + throw new Error(ex.message); + } +} \ No newline at end of file diff --git a/src/React.Core/Resources/babel-legacy/package-lock.json b/src/React.Core/Resources/babel-legacy/package-lock.json new file mode 100644 index 000000000..c9a5e7f2c --- /dev/null +++ b/src/React.Core/Resources/babel-legacy/package-lock.json @@ -0,0 +1,5202 @@ +{ + "name": "react-net-babel-legacy", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@webassemblyjs/ast": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", + "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", + "dev": true, + "requires": { + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", + "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", + "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", + "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==", + "dev": true + }, + "@webassemblyjs/helper-code-frame": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", + "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", + "dev": true, + "requires": { + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "@webassemblyjs/helper-fsm": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", + "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==", + "dev": true + }, + "@webassemblyjs/helper-module-context": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", + "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", + "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", + "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", + "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", + "dev": true, + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", + "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", + "dev": true, + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", + "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", + "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/helper-wasm-section": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-opt": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", + "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", + "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", + "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "@webassemblyjs/wast-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", + "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/floating-point-hex-parser": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-code-frame": "1.9.0", + "@webassemblyjs/helper-fsm": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", + "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "acorn": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", + "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", + "dev": true + }, + "ajv": { + "version": "6.12.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz", + "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", + "dev": true + }, + "ajv-keywords": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", + "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", + "dev": true + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "dev": true, + "requires": { + "object-assign": "^4.1.1", + "util": "0.10.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", + "dev": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "babel-core": { + "version": "6.26.3", + "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", + "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", + "dev": true, + "requires": { + "babel-code-frame": "^6.26.0", + "babel-generator": "^6.26.0", + "babel-helpers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-register": "^6.26.0", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "convert-source-map": "^1.5.1", + "debug": "^2.6.9", + "json5": "^0.5.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.4", + "path-is-absolute": "^1.0.1", + "private": "^0.1.8", + "slash": "^1.0.0", + "source-map": "^0.5.7" + }, + "dependencies": { + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true + } + } + }, + "babel-generator": { + "version": "6.26.1", + "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", + "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", + "dev": true, + "requires": { + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "detect-indent": "^4.0.0", + "jsesc": "^1.3.0", + "lodash": "^4.17.4", + "source-map": "^0.5.7", + "trim-right": "^1.0.1" + } + }, + "babel-helper-bindify-decorators": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz", + "integrity": "sha1-FMGeXxQte0fxmlJDHlKxzLxAozA=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-builder-binary-assignment-operator-visitor": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", + "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", + "dev": true, + "requires": { + "babel-helper-explode-assignable-expression": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-call-delegate": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", + "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", + "dev": true, + "requires": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-define-map": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", + "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", + "dev": true, + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "babel-helper-explode-assignable-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", + "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-explode-class": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz", + "integrity": "sha1-fcKjkQ3uAHBW4eMdZAztPVTqqes=", + "dev": true, + "requires": { + "babel-helper-bindify-decorators": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", + "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", + "dev": true, + "requires": { + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-get-function-arity": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", + "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-hoist-variables": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", + "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-optimise-call-expression": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", + "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-helper-regex": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", + "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "babel-helper-remap-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", + "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", + "dev": true, + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helper-replace-supers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", + "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", + "dev": true, + "requires": { + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-helpers": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", + "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-loader": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-7.1.5.tgz", + "integrity": "sha512-iCHfbieL5d1LfOQeeVJEUyD9rTwBcP/fcEbRCfempxTDuqrKpu0AZjLAQHEQa3Yqyj9ORKe2iHfoj4rHLf7xpw==", + "dev": true, + "requires": { + "find-cache-dir": "^1.0.0", + "loader-utils": "^1.0.2", + "mkdirp": "^0.5.1" + }, + "dependencies": { + "find-cache-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-1.0.0.tgz", + "integrity": "sha1-kojj6ePMN0hxfTnq3hfPcfww7m8=", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^1.0.0", + "pkg-dir": "^2.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + } + } + }, + "babel-messages": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", + "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-check-es2015-constants": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", + "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-syntax-async-functions": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", + "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=", + "dev": true + }, + "babel-plugin-syntax-async-generators": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz", + "integrity": "sha1-a8lj67FuzLrmuStZbrfzXDQqi5o=", + "dev": true + }, + "babel-plugin-syntax-class-constructor-call": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-constructor-call/-/babel-plugin-syntax-class-constructor-call-6.18.0.tgz", + "integrity": "sha1-nLnTn+Q8hgC+yBRkVt3L1OGnZBY=", + "dev": true + }, + "babel-plugin-syntax-class-properties": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz", + "integrity": "sha1-1+sjt5oxf4VDlixQW4J8fWysJ94=", + "dev": true + }, + "babel-plugin-syntax-decorators": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz", + "integrity": "sha1-MSVjtNvePMgGzuPkFszurd0RrAs=", + "dev": true + }, + "babel-plugin-syntax-do-expressions": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-do-expressions/-/babel-plugin-syntax-do-expressions-6.13.0.tgz", + "integrity": "sha1-V0d1YTmqJtOQ0JQQsDdEugfkeW0=", + "dev": true + }, + "babel-plugin-syntax-dynamic-import": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz", + "integrity": "sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo=", + "dev": true + }, + "babel-plugin-syntax-exponentiation-operator": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", + "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=", + "dev": true + }, + "babel-plugin-syntax-export-extensions": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz", + "integrity": "sha1-cKFITw+QiaToStRLrDU8lbmxJyE=", + "dev": true + }, + "babel-plugin-syntax-function-bind": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-function-bind/-/babel-plugin-syntax-function-bind-6.13.0.tgz", + "integrity": "sha1-SMSV8Xe98xqYHnMvVa3AvdJgH0Y=", + "dev": true + }, + "babel-plugin-syntax-object-rest-spread": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", + "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=", + "dev": true + }, + "babel-plugin-syntax-trailing-function-commas": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", + "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=", + "dev": true + }, + "babel-plugin-transform-async-generator-functions": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz", + "integrity": "sha1-8FiQAUX9PpkHpt3yjaWfIVJYpds=", + "dev": true, + "requires": { + "babel-helper-remap-async-to-generator": "^6.24.1", + "babel-plugin-syntax-async-generators": "^6.5.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-async-to-generator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", + "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", + "dev": true, + "requires": { + "babel-helper-remap-async-to-generator": "^6.24.1", + "babel-plugin-syntax-async-functions": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-class-constructor-call": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-constructor-call/-/babel-plugin-transform-class-constructor-call-6.24.1.tgz", + "integrity": "sha1-gNwoVQWsBn3LjWxl4vbxGrd2Xvk=", + "dev": true, + "requires": { + "babel-plugin-syntax-class-constructor-call": "^6.18.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-class-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz", + "integrity": "sha1-anl2PqYdM9NvN7YRqp3vgagbRqw=", + "dev": true, + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-plugin-syntax-class-properties": "^6.8.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-decorators": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz", + "integrity": "sha1-eIAT2PjGtSIr33s0Q5Df13Vp4k0=", + "dev": true, + "requires": { + "babel-helper-explode-class": "^6.24.1", + "babel-plugin-syntax-decorators": "^6.13.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-do-expressions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-do-expressions/-/babel-plugin-transform-do-expressions-6.22.0.tgz", + "integrity": "sha1-KMyvkoEtlJws0SgfaQyP3EaK6bs=", + "dev": true, + "requires": { + "babel-plugin-syntax-do-expressions": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-arrow-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", + "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-block-scoped-functions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", + "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-block-scoping": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", + "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "lodash": "^4.17.4" + } + }, + "babel-plugin-transform-es2015-classes": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", + "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", + "dev": true, + "requires": { + "babel-helper-define-map": "^6.24.1", + "babel-helper-function-name": "^6.24.1", + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-helper-replace-supers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-computed-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", + "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-destructuring": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", + "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-duplicate-keys": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", + "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-for-of": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", + "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-function-name": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", + "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", + "dev": true, + "requires": { + "babel-helper-function-name": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", + "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-modules-amd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", + "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", + "dev": true, + "requires": { + "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-modules-commonjs": { + "version": "6.26.2", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", + "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", + "dev": true, + "requires": { + "babel-plugin-transform-strict-mode": "^6.24.1", + "babel-runtime": "^6.26.0", + "babel-template": "^6.26.0", + "babel-types": "^6.26.0" + } + }, + "babel-plugin-transform-es2015-modules-systemjs": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", + "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", + "dev": true, + "requires": { + "babel-helper-hoist-variables": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-modules-umd": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", + "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", + "dev": true, + "requires": { + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-object-super": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", + "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", + "dev": true, + "requires": { + "babel-helper-replace-supers": "^6.24.1", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-parameters": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", + "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", + "dev": true, + "requires": { + "babel-helper-call-delegate": "^6.24.1", + "babel-helper-get-function-arity": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-shorthand-properties": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", + "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-spread": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", + "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-sticky-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", + "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", + "dev": true, + "requires": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-plugin-transform-es2015-template-literals": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", + "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-typeof-symbol": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", + "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-es2015-unicode-regex": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", + "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", + "dev": true, + "requires": { + "babel-helper-regex": "^6.24.1", + "babel-runtime": "^6.22.0", + "regexpu-core": "^2.0.0" + } + }, + "babel-plugin-transform-exponentiation-operator": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", + "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", + "dev": true, + "requires": { + "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", + "babel-plugin-syntax-exponentiation-operator": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-export-extensions": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-export-extensions/-/babel-plugin-transform-export-extensions-6.22.0.tgz", + "integrity": "sha1-U3OLR+deghhYnuqUbLvTkQm75lM=", + "dev": true, + "requires": { + "babel-plugin-syntax-export-extensions": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-function-bind": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-function-bind/-/babel-plugin-transform-function-bind-6.22.0.tgz", + "integrity": "sha1-xvuOlqwpajELjPjqQBRiQH3fapc=", + "dev": true, + "requires": { + "babel-plugin-syntax-function-bind": "^6.8.0", + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-transform-object-rest-spread": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz", + "integrity": "sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY=", + "dev": true, + "requires": { + "babel-plugin-syntax-object-rest-spread": "^6.8.0", + "babel-runtime": "^6.26.0" + } + }, + "babel-plugin-transform-regenerator": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", + "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", + "dev": true, + "requires": { + "regenerator-transform": "^0.10.0" + } + }, + "babel-plugin-transform-strict-mode": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", + "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-preset-es2015": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz", + "integrity": "sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk=", + "dev": true, + "requires": { + "babel-plugin-check-es2015-constants": "^6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", + "babel-plugin-transform-es2015-block-scoping": "^6.24.1", + "babel-plugin-transform-es2015-classes": "^6.24.1", + "babel-plugin-transform-es2015-computed-properties": "^6.24.1", + "babel-plugin-transform-es2015-destructuring": "^6.22.0", + "babel-plugin-transform-es2015-duplicate-keys": "^6.24.1", + "babel-plugin-transform-es2015-for-of": "^6.22.0", + "babel-plugin-transform-es2015-function-name": "^6.24.1", + "babel-plugin-transform-es2015-literals": "^6.22.0", + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", + "babel-plugin-transform-es2015-modules-systemjs": "^6.24.1", + "babel-plugin-transform-es2015-modules-umd": "^6.24.1", + "babel-plugin-transform-es2015-object-super": "^6.24.1", + "babel-plugin-transform-es2015-parameters": "^6.24.1", + "babel-plugin-transform-es2015-shorthand-properties": "^6.24.1", + "babel-plugin-transform-es2015-spread": "^6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "^6.24.1", + "babel-plugin-transform-es2015-template-literals": "^6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "^6.22.0", + "babel-plugin-transform-es2015-unicode-regex": "^6.24.1", + "babel-plugin-transform-regenerator": "^6.24.1" + } + }, + "babel-preset-stage-0": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-stage-0/-/babel-preset-stage-0-6.24.1.tgz", + "integrity": "sha1-VkLRUEL5E4TX5a+LyIsduVsDnmo=", + "dev": true, + "requires": { + "babel-plugin-transform-do-expressions": "^6.22.0", + "babel-plugin-transform-function-bind": "^6.22.0", + "babel-preset-stage-1": "^6.24.1" + } + }, + "babel-preset-stage-1": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-stage-1/-/babel-preset-stage-1-6.24.1.tgz", + "integrity": "sha1-dpLNfc1oSZB+auSgqFWJz7niv7A=", + "dev": true, + "requires": { + "babel-plugin-transform-class-constructor-call": "^6.24.1", + "babel-plugin-transform-export-extensions": "^6.22.0", + "babel-preset-stage-2": "^6.24.1" + } + }, + "babel-preset-stage-2": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz", + "integrity": "sha1-2eKWD7PXEYfw5k7sYrwHdnIZvcE=", + "dev": true, + "requires": { + "babel-plugin-syntax-dynamic-import": "^6.18.0", + "babel-plugin-transform-class-properties": "^6.24.1", + "babel-plugin-transform-decorators": "^6.24.1", + "babel-preset-stage-3": "^6.24.1" + } + }, + "babel-preset-stage-3": { + "version": "6.24.1", + "resolved": "https://registry.npmjs.org/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz", + "integrity": "sha1-g2raCp56f6N8sTj7kyb4eTSkg5U=", + "dev": true, + "requires": { + "babel-plugin-syntax-trailing-function-commas": "^6.22.0", + "babel-plugin-transform-async-generator-functions": "^6.24.1", + "babel-plugin-transform-async-to-generator": "^6.24.1", + "babel-plugin-transform-exponentiation-operator": "^6.24.1", + "babel-plugin-transform-object-rest-spread": "^6.22.0" + } + }, + "babel-register": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", + "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", + "dev": true, + "requires": { + "babel-core": "^6.26.0", + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "home-or-tmp": "^2.0.0", + "lodash": "^4.17.4", + "mkdirp": "^0.5.1", + "source-map-support": "^0.4.15" + }, + "dependencies": { + "source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "dev": true, + "requires": { + "source-map": "^0.5.6" + } + } + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "babel-standalone": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-standalone/-/babel-standalone-6.26.0.tgz", + "integrity": "sha1-Ffs9NfLEVmlYFevx7Zb+fwFbaIY=", + "dev": true + }, + "babel-template": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", + "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "babel-traverse": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "lodash": "^4.17.4" + } + }, + "babel-traverse": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", + "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", + "dev": true, + "requires": { + "babel-code-frame": "^6.26.0", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.26.0", + "babel-types": "^6.26.0", + "babylon": "^6.18.0", + "debug": "^2.6.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" + } + }, + "babel-types": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", + "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "dev": true, + "requires": { + "babel-runtime": "^6.26.0", + "esutils": "^2.0.2", + "lodash": "^4.17.4", + "to-fast-properties": "^1.0.3" + } + }, + "babylon": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", + "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "base64-js": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", + "dev": true + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "optional": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "randombytes": "^2.0.1" + } + }, + "browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "dev": true, + "requires": { + "bn.js": "^4.1.1", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.2", + "elliptic": "^6.0.0", + "inherits": "^2.0.1", + "parse-asn1": "^5.0.0" + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "requires": { + "pako": "~1.0.5" + } + }, + "buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "cacache": { + "version": "12.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", + "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", + "dev": true, + "requires": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + } + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "chrome-trace-event": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", + "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "convert-source-map": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", + "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "dev": true, + "requires": { + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "core-js": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.5.tgz", + "integrity": "sha512-klh/kDpwX8hryYL14M9w/xei6vrv6sE8gTHDG7/T/+SEovB/G4ejwcfE/CBzO6Edsu+OETZMZ3wcX/EjUkrl5A==", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "create-ecdh": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", + "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.0.0" + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "cyclist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", + "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true + }, + "detect-indent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", + "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", + "dev": true, + "requires": { + "repeating": "^2.0.0" + } + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true + }, + "duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "dev": true, + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "elliptic": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz", + "integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==", + "dev": true, + "requires": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "dev": true + }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "enhanced-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz", + "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.4.0", + "tapable": "^1.0.0" + } + }, + "errno": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", + "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "dev": true, + "requires": { + "prr": "~1.0.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "events": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", + "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", + "dev": true + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "fast-deep-equal": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", + "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "figgy-pudding": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", + "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", + "dev": true + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "findup-sync": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", + "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", + "dev": true, + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + } + }, + "flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.12.tgz", + "integrity": "sha512-Ggd/Ktt7E7I8pxZRbGIs7vwqAPscSESMrCSkx2FtWeqmheJgCo2R74fTsZFCifr0VTPwqRpPv17+6b8Zp7th0Q==", + "dev": true, + "optional": true, + "requires": { + "bindings": "^1.5.0", + "nan": "^2.12.1", + "node-pre-gyp": "*" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.4", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "3.2.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.6.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "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" + } + }, + "glob": { + "version": "7.1.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "bundled": true, + "dev": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "bundled": true, + "dev": true, + "optional": true + }, + "minipass": { + "version": "2.9.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.9.0" + } + }, + "mkdirp": { + "version": "0.5.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "ms": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.3.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.14.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4.4.2" + } + }, + "nopt": { + "version": "4.0.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-normalize-package-bin": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "readable-stream": { + "version": "2.3.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.7.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.7.1", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.13", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "yallist": { + "version": "3.1.1", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "requires": { + "global-prefix": "^3.0.0" + }, + "dependencies": { + "global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "requires": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + } + } + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true + }, + "graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "dev": true + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + } + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "home-or-tmp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", + "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.1" + } + }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "dev": true + }, + "iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", + "dev": true + }, + "import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "dev": true, + "requires": { + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "jsesc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + }, + "loader-runner": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", + "dev": true + }, + "loader-utils": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "mississippi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "dev": true, + "requires": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^3.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + } + }, + "mixin-deep": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", + "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + } + } + }, + "move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "dev": true, + "requires": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "dev": true, + "optional": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "neo-async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", + "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "dev": true, + "requires": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "^1.0.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + } + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "p-limit": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.1.0.tgz", + "integrity": "sha512-H2RyIJ7+A3rjkwKC2l5GGtU4H1vkxKCAGsWasNVd0Set+6i4znxbWy6/j16YDPJDWxhsgZiKAstMEP8wCdSpjA==", + "dev": true + }, + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + }, + "parallel-transform": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", + "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", + "dev": true, + "requires": { + "cyclist": "^1.0.1", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + } + }, + "parse-asn1": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", + "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", + "dev": true, + "requires": { + "asn1.js": "^4.0.0", + "browserify-aes": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "pbkdf2": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", + "dev": true + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", + "dev": true + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "regenerate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", + "dev": true + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "dev": true + }, + "regenerator-transform": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", + "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", + "dev": true, + "requires": { + "babel-runtime": "^6.18.0", + "babel-types": "^6.19.0", + "private": "^0.1.6" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "regexpu-core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", + "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", + "dev": true, + "requires": { + "regenerate": "^1.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" + } + }, + "regjsgen": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", + "dev": true + }, + "regjsparser": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", + "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + } + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "dev": true, + "requires": { + "is-finite": "^1.0.0" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "dev": true, + "requires": { + "resolve-from": "^3.0.0" + } + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "dependencies": { + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + } + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "dev": true, + "requires": { + "aproba": "^1.1.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", + "dev": true + }, + "serialize-javascript": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", + "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-value": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", + "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "dev": true, + "requires": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.17", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.17.tgz", + "integrity": "sha512-bwdKOBZ5L0gFRh4KOxNap/J/MpvX9Yxsq9lFDx65s3o7F/NiHy7JRaGIS8MwW6tZPAq9UXE207Il0cfcb5yu/Q==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "ssri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1" + } + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-each": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", + "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "tapable": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.1.tgz", + "integrity": "sha512-9I2ydhj8Z9veORCw5PRm4u9uebCn0mcCa6scWoNcbZ6dAtoo2618u9UUzxgmsCOreJpqDDuv61LvwofW7hLcBA==", + "dev": true + }, + "terser": { + "version": "4.6.11", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.11.tgz", + "integrity": "sha512-76Ynm7OXUG5xhOpblhytE7X58oeNSmC8xnNhjWVo8CksHit0U0kO4hfNbPrrYwowLWFgM2n9L176VNx2QaHmtA==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "terser-webpack-plugin": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", + "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", + "dev": true, + "requires": { + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", + "is-wsl": "^1.1.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^2.1.2", + "source-map": "^0.6.1", + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", + "worker-farm": "^1.7.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "timers-browserify": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", + "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", + "dev": true, + "requires": { + "setimmediate": "^1.0.4" + } + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "to-fast-properties": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", + "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", + "dev": true + }, + "tslib": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz", + "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==", + "dev": true + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "union-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", + "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^0.4.3" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "set-value": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.1", + "to-object-path": "^0.3.0" + } + } + } + }, + "unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dev": true, + "requires": { + "unique-slug": "^2.0.0" + } + }, + "unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "v8-compile-cache": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz", + "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==", + "dev": true + }, + "vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true + }, + "watchpack": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.1.tgz", + "integrity": "sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==", + "dev": true, + "requires": { + "chokidar": "^2.1.8", + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0" + } + }, + "webpack": { + "version": "4.43.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.43.0.tgz", + "integrity": "sha512-GW1LjnPipFW2Y78OOab8NJlCflB7EFskMih2AHdvjbpKMeDJqEgSx24cXXXiPS65+WSwVyxtDsJH6jGX2czy+g==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/wasm-edit": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "acorn": "^6.4.1", + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^4.1.0", + "eslint-scope": "^4.0.3", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^2.4.0", + "loader-utils": "^1.2.3", + "memory-fs": "^0.4.1", + "micromatch": "^3.1.10", + "mkdirp": "^0.5.3", + "neo-async": "^2.6.1", + "node-libs-browser": "^2.2.1", + "schema-utils": "^1.0.0", + "tapable": "^1.1.3", + "terser-webpack-plugin": "^1.4.3", + "watchpack": "^1.6.1", + "webpack-sources": "^1.4.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "dev": true + } + } + }, + "webpack-cli": { + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.12.tgz", + "integrity": "sha512-NVWBaz9k839ZH/sinurM+HcDvJOTXwSjYp1ku+5XKeOC03z8v5QitnK/x+lAxGXFyhdayoIf/GOpv85z3/xPag==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "cross-spawn": "^6.0.5", + "enhanced-resolve": "^4.1.1", + "findup-sync": "^3.0.0", + "global-modules": "^2.0.0", + "import-local": "^2.0.0", + "interpret": "^1.4.0", + "loader-utils": "^1.4.0", + "supports-color": "^6.1.0", + "v8-compile-cache": "^2.1.1", + "yargs": "^13.3.2" + }, + "dependencies": { + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, + "enhanced-resolve": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.2.0.tgz", + "integrity": "sha512-S7eiFb/erugyd1rLb6mQ3Vuq+EXHv5cpCkNqqIkYkBgN2QdFnyCZzFBleqwGEx4lgNGYij81BWnCrFNK7vxvjQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.5.0", + "tapable": "^1.0.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + }, + "memory-fs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", + "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + } + } + }, + "webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dev": true, + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "worker-farm": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", + "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", + "dev": true, + "requires": { + "errno": "~0.1.7" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } +} diff --git a/src/React.Core/Resources/babel-legacy/package.json b/src/React.Core/Resources/babel-legacy/package.json new file mode 100644 index 000000000..b1b94873b --- /dev/null +++ b/src/React.Core/Resources/babel-legacy/package.json @@ -0,0 +1,20 @@ +{ + "name": "react-net-babel-legacy", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "build": "webpack" + }, + "devDependencies": { + "babel-core": "6.26.3", + "babel-loader": "7.1.5", + "babel-preset-es2015": "6.24.1", + "babel-preset-stage-0": "6.24.1", + "babel-standalone": "6.26.0", + "webpack": "4.43.0", + "webpack-cli": "3.3.12" + }, + "author": "", + "license": "MIT" +} diff --git a/src/React.Core/Resources/babel-legacy/webpack.config.js b/src/React.Core/Resources/babel-legacy/webpack.config.js new file mode 100644 index 000000000..6c5baff26 --- /dev/null +++ b/src/React.Core/Resources/babel-legacy/webpack.config.js @@ -0,0 +1,31 @@ +const path = require('path'); + +module.exports = [ + { + entry: { + 'babel-legacy': './babel.js', + }, + output: { + filename: '[name].generated.min.js', + globalObject: 'this', + path: path.resolve(__dirname, '../'), + libraryTarget: 'this', + }, + mode: 'production', + module: { + rules: [ + { + test: /\.jsx?$/, + exclude: /node_modules/, + loader: 'babel-loader', + query: { + presets: ['es2015', 'stage-0'], + }, + }, + ], + }, + performance: { + hints: false, + }, + }, +]; diff --git a/src/React.Core/Resources/babel.js b/src/React.Core/Resources/babel.js new file mode 100644 index 000000000..5c37230f5 --- /dev/null +++ b/src/React.Core/Resources/babel.js @@ -0,0 +1,40 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import {transform as babelTransform, version as babelVersion} from '@babel/standalone'; + +export function ReactNET_transform(input, babelConfig, filename) { + babelConfig = Object.assign({}, JSON.parse(babelConfig), { + ast: false, + filename, + }); + try { + return babelTransform(input, babelConfig).code; + } catch (ex) { + // Parsing stack is extremely long and not very useful, so just rethrow the message. + throw new Error(ex.message); + } +} + +export function ReactNET_transform_sourcemap(input, babelConfig, filename) { + babelConfig = Object.assign({}, JSON.parse(babelConfig), { + ast: false, + filename, + sourceMaps: true, + }); + try { + var result = babelTransform(input, babelConfig); + return JSON.stringify({ + babelVersion, + code: result.code, + sourceMap: result.map, + }); + } catch (ex) { + // Parsing stack is extremely long and not very useful, so just rethrow the message. + throw new Error(ex.message); + } +} diff --git a/src/React.Core/Resources/react.js b/src/React.Core/Resources/react.js new file mode 100644 index 000000000..b04ca18f6 --- /dev/null +++ b/src/React.Core/Resources/react.js @@ -0,0 +1,14 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +// Exports all the parts of React that ReactJS.NET cares about. +module.exports = { + React: require('react'), + ReactDOM: require('react-dom'), + ReactDOMServer: require('react-dom/server'), + PropTypes: require('prop-types'), +}; diff --git a/src/React.Core/Resources/shims.js b/src/React.Core/Resources/shims.js new file mode 100644 index 000000000..f99e4f264 --- /dev/null +++ b/src/React.Core/Resources/shims.js @@ -0,0 +1,120 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +var global = global || {}; +var React, ReactDOM, ReactDOMServer, setTimeout, clearTimeout; + +// Basic console shim. Caches all calls to console methods. +function MockConsole() { + this._calls = []; + ['log', 'error', 'warn', 'debug', 'info', 'dir', 'group', 'groupEnd', 'groupCollapsed'].forEach(function (methodName) { + this[methodName] = this._handleCall.bind(this, methodName); + }, this); +} +MockConsole.prototype = { + _handleCall: function(methodName/*, ...args*/) { + var serializedArgs = []; + for (var i = 1; i < arguments.length; i++) { + serializedArgs.push(JSON.stringify(arguments[i])); + } + + this._calls.push({ + method: methodName, + args: serializedArgs, + stack: '\nCall stack: ' + (new Error().stack || 'not available') + }); + }, + _formatCall: function(call) { + return 'console.' + call.method + '("[.NET]", ' + call.args.join(', ') + ', ' + JSON.stringify(call.stack) + ');'; + }, + getCalls: function() { + return this._calls.map(this._formatCall).join('\n'); + } +}; +var console = new MockConsole(); + +if (!Object.freeze) { + Object.freeze = function() { }; +} + +/** + * Finds a user-supplied version of React and ensures it's exposed globally. + * + * @return {string} Comma-separated list of missing globals. + */ +function ReactNET_initReact() { + var missing = []; + + if (typeof React === 'undefined') { + if (global.React) { + React = global.React; + } else { + missing.push('React'); + } + } + + if (typeof ReactDOM === 'undefined') { + if (global.ReactDOM) { + ReactDOM = global.ReactDOM; + } else { + missing.push('ReactDOM'); + } + } + + if (typeof ReactDOMServer === 'undefined') { + if (global.ReactDOMServer) { + ReactDOMServer = global.ReactDOMServer; + } + else { + missing.push('ReactDOMServer'); + } + } + + return missing.join(','); +} + +setTimeout = setTimeout || global.setTimeout; +if (setTimeout === undefined) { + setTimeout = function() { + throw new Error('setTimeout is not supported in server-rendered Javascript.'); + } +} + +clearTimeout = clearTimeout || global.clearTimeout; +if (clearTimeout === undefined) { + clearTimeout = function() { + throw new Error('clearTimeout is not supported in server-rendered Javascript.'); + } +} + +/** + * Polyfill for engines that do not support Object.assign + */ +if (typeof Object.assign !== 'function') { + Object.assign = function (target, varArgs) { // .length of function is 2 + 'use strict'; + if (target == null) { // TypeError if undefined or null + throw new TypeError('Cannot convert undefined or null to object'); + } + + var to = Object(target); + + for (var index = 1; index < arguments.length; index++) { + var nextSource = arguments[index]; + + if (nextSource != null) { // Skip over if undefined or null + for (var nextKey in nextSource) { + // Avoid bugs when hasOwnProperty is shadowed + if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { + to[nextKey] = nextSource[nextKey]; + } + } + } + } + return to; + }; +} diff --git a/src/React/SimpleFileSystem.cs b/src/React.Core/SimpleFileSystem.cs similarity index 65% rename from src/React/SimpleFileSystem.cs rename to src/React.Core/SimpleFileSystem.cs index 4b8a783e7..acfcad830 100644 --- a/src/React/SimpleFileSystem.cs +++ b/src/React.Core/SimpleFileSystem.cs @@ -1,10 +1,8 @@ /* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ namespace React diff --git a/src/React.Core/SourceMap.cs b/src/React.Core/SourceMap.cs new file mode 100644 index 000000000..dbcfa241f --- /dev/null +++ b/src/React.Core/SourceMap.cs @@ -0,0 +1,84 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System; +using System.Collections.Generic; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; + +namespace React +{ + /// + /// Represents the data contained in a source map + /// + [Serializable] + public class SourceMap + { + /// + /// Version number of the source map spec used to build this source map. Expected + /// to be version 3. + /// + public int Version { get; set; } + + /// + /// An optional name of the generated code that this source map is associated with. + /// + public string File { get; set; } + + /// + /// An optional source root, useful for relocating source files on a server or + /// removing repeated values in the entry. This value is + /// prepended to the individual entries in the field. + /// + public string SourceRoot { get; set; } + + /// + /// A list of original sources used by the entry. + /// + public IList Sources { get; set; } + + /// + /// An optional list of source content, useful when the can't + /// be hosted. The contents are listed in the same order as the . + /// null may be used if some original sources should be retrieved by name. + /// + public IList SourcesContent { get; set; } + + /// + /// A list of symbol names used by the entry. + /// + public IList Names { get; set; } + + /// + /// A string with the mapping data encoded in base 64 VLQ. + /// + public string Mappings { get; set; } + + /// + /// Outputs this source map as JSON. + /// + /// + public string ToJson() + { + return JsonConvert.SerializeObject(this, new JsonSerializerSettings + { + // Camelcase keys (eg. "SourcesContent" -> "sourcesContent") + ContractResolver = new CamelCasePropertyNamesContractResolver() + }); + } + + /// + /// Parse a source map from JSON + /// + /// JSON input + /// Source map + public static SourceMap FromJson(string json) + { + return JsonConvert.DeserializeObject(json); + } + } +} diff --git a/src/React/SystemEnvironmentUtils.cs b/src/React.Core/SystemEnvironmentUtils.cs similarity index 72% rename from src/React/SystemEnvironmentUtils.cs rename to src/React.Core/SystemEnvironmentUtils.cs index ec02fec03..8452fe5d7 100644 --- a/src/React/SystemEnvironmentUtils.cs +++ b/src/React.Core/SystemEnvironmentUtils.cs @@ -1,10 +1,8 @@ /* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ using System; @@ -15,10 +13,12 @@ namespace React /// /// Utility functions for handling system environmental differences /// - public class SystemEnvironmentUtils + public static class SystemEnvironmentUtils { +#if NET40 [DllImport("libc")] private static extern int uname(IntPtr buf); +#endif /// /// Determines whether the application is running on Mac OS. @@ -32,6 +32,7 @@ public static bool IsRunningOnMac() private readonly static Lazy _isRunningOnMac = new Lazy(() => { +#if NET40 if (Environment.OSVersion.Platform != PlatformID.Unix) { return false; @@ -58,6 +59,11 @@ public static bool IsRunningOnMac() Marshal.FreeHGlobal(buf); } return false; +#else + // This code was specifically to work around a bug in Mono. If running under .NET Core, we + // don't need to worry. + return false; +#endif }); } } diff --git a/src/React/TinyIoC/TinyIoC.cs b/src/React.Core/TinyIoC/TinyIoC.cs similarity index 86% rename from src/React/TinyIoC/TinyIoC.cs rename to src/React.Core/TinyIoC/TinyIoC.cs index 1d5f46908..400fb6c89 100644 --- a/src/React/TinyIoC/TinyIoC.cs +++ b/src/React.Core/TinyIoC/TinyIoC.cs @@ -19,20 +19,42 @@ // register the TinyMessenger messenger/event aggregator //#define TINYMESSENGER +// Uncomment this line if you want to internalize this library +//#define TINYIOC_INTERNAL + +// Uncomment this line if you want to target PCL. +//#define PORTABLE + // Preprocessor directives for enabling/disabling functionality // depending on platform features. If the platform has an appropriate // #DEFINE then these should be set automatically below. -#define EXPRESSIONS // Platform supports System.Linq.Expressions +#define EXPRESSIONS + +// Platform supports System.Linq.Expressions #define COMPILED_EXPRESSIONS // Platform supports compiling expressions #define APPDOMAIN_GETASSEMBLIES // Platform supports getting all assemblies from the AppDomain object #define UNBOUND_GENERICS_GETCONSTRUCTORS // Platform supports GetConstructors on unbound generic types #define GETPARAMETERS_OPEN_GENERICS // Platform supports GetParameters on open generics #define RESOLVE_OPEN_GENERICS // Platform supports resolving open generics #define READER_WRITER_LOCK_SLIM // Platform supports ReaderWriterLockSlim +#define SERIALIZABLE // Platform supports SerializableAttribute/SerializationInfo/StreamingContext -//// NETFX_CORE -//#if NETFX_CORE -//#endif +#if PORTABLE +#undef APPDOMAIN_GETASSEMBLIES +#undef COMPILED_EXPRESSIONS +#undef READER_WRITER_LOCK_SLIM +#undef SERIALIZABLE +#endif + +#if NETSTANDARD1_0 || NETSTANDARD1_1 || NETSTANDARD1_2 +#undef COMPILED_EXPRESSIONS +#undef READER_WRITER_LOCK_SLIM +#endif + +#if NETSTANDARD1_0 || NETSTANDARD1_1 || NETSTANDARD1_2 || NETSTANDARD1_3 || NETSTANDARD1_4 || NETSTANDARD1_5 || NETSTANDARD1_6 +#undef APPDOMAIN_GETASSEMBLIES +#undef SERIALIZABLE +#endif // CompactFramework / Windows Phone 7 // By default does not support System.Linq.Expressions. @@ -66,6 +88,10 @@ #endif #endregion +#if SERIALIZABLE +using System.Runtime.Serialization; +#endif + namespace React.TinyIoC { using System; @@ -89,7 +115,12 @@ namespace React.TinyIoC #region SafeDictionary #if READER_WRITER_LOCK_SLIM - public class SafeDictionary : IDisposable +#if TINYIOC_INTERNAL + internal +#else + public +#endif + class SafeDictionary : IDisposable { private readonly ReaderWriterLockSlim _padlock = new ReaderWriterLockSlim(); private readonly Dictionary _Dictionary = new Dictionary(); @@ -203,7 +234,12 @@ where item is IDisposable #endregion } #else - public class SafeDictionary : IDisposable +#if TINYIOC_INTERNAL + internal +#else + public +#endif + class SafeDictionary : IDisposable { private readonly object _Padlock = new object(); private readonly Dictionary _Dictionary = new Dictionary(); @@ -259,7 +295,7 @@ public IEnumerable Keys return _Dictionary.Keys; } } - #region IDisposable Members + #region IDisposable Members public void Dispose() { @@ -278,13 +314,18 @@ where item is IDisposable GC.SuppressFinalize(this); } - #endregion + #endregion } #endif #endregion #region Extensions - public static class AssemblyExtensions +#if TINYIOC_INTERNAL + internal +#else + public +#endif + static class AssemblyExtensions { public static Type[] SafeGetTypes(this Assembly assembly) { @@ -292,8 +333,12 @@ public static Type[] SafeGetTypes(this Assembly assembly) try { - assemblies = assembly.GetTypes(); - } +#if PORTABLE || NETSTANDARD1_0 || NETSTANDARD1_1 || NETSTANDARD1_2 + assemblies = assembly.ExportedTypes.ToArray(); +#else + assemblies = assembly.GetTypes(); +#endif + } catch (System.IO.FileNotFoundException) { assemblies = new Type[] { }; @@ -312,7 +357,38 @@ public static Type[] SafeGetTypes(this Assembly assembly) } } - public static class TypeExtensions +#if PORTABLE || NETSTANDARD1_0 || NETSTANDARD1_1 || NETSTANDARD1_2 + [Flags] + internal enum BindingFlags { + Default = 0, + IgnoreCase = 1, + DeclaredOnly = 2, + Instance = 4, + Static = 8, + Public = 16, + NonPublic = 32, + FlattenHierarchy = 64, + InvokeMethod = 256, + CreateInstance = 512, + GetField = 1024, + SetField = 2048, + GetProperty = 4096, + SetProperty = 8192, + PutDispProperty = 16384, + ExactBinding = 65536, + PutRefDispProperty = 32768, + SuppressChangeType = 131072, + OptionalParamBinding = 262144, + IgnoreReturn = 16777216 + } +#endif + +#if TINYIOC_INTERNAL + internal +#else + public +#endif + static class TypeExtensions { private static SafeDictionary _genericMethodCache; @@ -321,34 +397,139 @@ static TypeExtensions() _genericMethodCache = new SafeDictionary(); } -//#if NETFX_CORE -// /// -// /// Gets a generic method from a type given the method name, generic types and parameter types -// /// -// /// Source type -// /// Name of the method -// /// Generic types to use to make the method generic -// /// Method parameters -// /// MethodInfo or null if no matches found -// /// -// /// -// public static MethodInfo GetGenericMethod(this Type sourceType, string methodName, Type[] genericTypes, Type[] parameterTypes) -// { -// MethodInfo method; -// var cacheKey = new GenericMethodCacheKey(sourceType, methodName, genericTypes, parameterTypes); - -// // Shouldn't need any additional locking -// // we don't care if we do the method info generation -// // more than once before it gets cached. -// if (!_genericMethodCache.TryGetValue(cacheKey, out method)) -// { -// method = GetMethod(sourceType, methodName, genericTypes, parameterTypes); -// _genericMethodCache[cacheKey] = method; -// } - -// return method; -// } -//#else +#if PORTABLE || NETSTANDARD1_0 || NETSTANDARD1_1 || NETSTANDARD1_2 + private static BindingFlags DefaultFlags = BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance; + + public static ConstructorInfo[] GetConstructors(this Type type) + { + return type.GetConstructors(DefaultFlags); + } + + public static ConstructorInfo[] GetConstructors(this Type type, BindingFlags bindingFlags) + { + return type.GetConstructors(bindingFlags, null); + } + + private static ConstructorInfo[] GetConstructors(this Type type, BindingFlags bindingFlags, IList parameterTypes) + { + return type.GetTypeInfo().DeclaredConstructors.Where( + c => + { + if (!TestAccessibility(c, bindingFlags)) + { + return false; + } + + if (parameterTypes != null && !c.GetParameters().Select(p => p.ParameterType).SequenceEqual(parameterTypes)) + { + return false; + } + + return true; + }).ToArray(); + } + + public static MethodInfo GetGetMethod(this PropertyInfo propertyInfo) { + return propertyInfo.GetGetMethod(false); + } + + public static MethodInfo GetGetMethod(this PropertyInfo propertyInfo, bool nonPublic) { + MethodInfo getMethod = propertyInfo.GetMethod; + if (getMethod != null && (getMethod.IsPublic || nonPublic)) { + return getMethod; + } + + return null; + } + + public static MethodInfo GetSetMethod(this PropertyInfo propertyInfo) { + return propertyInfo.GetSetMethod(false); + } + + public static MethodInfo GetSetMethod(this PropertyInfo propertyInfo, bool nonPublic) { + MethodInfo setMethod = propertyInfo.SetMethod; + if (setMethod != null && (setMethod.IsPublic || nonPublic)) { + return setMethod; + } + + return null; + } + + public static Type[] GetGenericArguments(this Type type) + { + return type.GetTypeInfo().GenericTypeArguments; + } + + public static IEnumerable GetProperties(this Type type) + { + TypeInfo t = type.GetTypeInfo(); + IList properties = new List(); + while (t != null) + { + foreach (PropertyInfo member in t.DeclaredProperties) + { + if (!properties.Any(p => p.Name == member.Name)) + { + properties.Add(member); + } + } + t = (t.BaseType != null) ? t.BaseType.GetTypeInfo() : null; + } + + return properties; + } + + public static IEnumerable GetInterfaces(this Type type) + { + return type.GetTypeInfo().ImplementedInterfaces; + } + + public static MethodInfo GetMethod(this Type type, string name, IList parameterTypes) + { + return type.GetMethod(name, DefaultFlags, null, parameterTypes, null); + } + + public static MethodInfo GetMethod(this Type type, string name, BindingFlags bindingFlags, object placeHolder1, IList parameterTypes, object placeHolder2) + { + return type.GetTypeInfo().DeclaredMethods.Where( + m => + { + if (name != null && m.Name != name) + { + return false; + } + + if (!TestAccessibility(m, bindingFlags)) + { + return false; + } + + return m.GetParameters().Select(p => p.ParameterType).SequenceEqual(parameterTypes); + }).SingleOrDefault(); + } + + public static IEnumerable GetMethods(this Type type, BindingFlags bindingFlags) + { + return type.GetTypeInfo().DeclaredMethods; + } + + public static bool IsAssignableFrom(this Type type, Type c) + { + return type.GetTypeInfo().IsAssignableFrom(c.GetTypeInfo()); + } + + private static bool TestAccessibility(MethodBase member, BindingFlags bindingFlags) + { + bool visibility = (member.IsPublic && bindingFlags.HasFlag(BindingFlags.Public)) || + (!member.IsPublic && bindingFlags.HasFlag(BindingFlags.NonPublic)); + + bool instance = (member.IsStatic && bindingFlags.HasFlag(BindingFlags.Static)) || + (!member.IsStatic && bindingFlags.HasFlag(BindingFlags.Instance)); + + return visibility && instance; + } +#endif + /// /// Gets a generic method from a type given the method name, binding flags, generic types and parameter types /// @@ -376,7 +557,7 @@ public static MethodInfo GetGenericMethod(this Type sourceType, BindingFlags bin return method; } -//#endif + //#endif #if NETFX_CORE private static MethodInfo GetMethod(Type sourceType, BindingFlags flags, string methodName, Type[] genericTypes, Type[] parameterTypes) @@ -510,9 +691,9 @@ private int GenerateHashCode() } } - } + } - // @mbrit - 2012-05-22 - shim for ForEach call on List... + // @mbrit - 2012-05-22 - shim for ForEach call on List... #if NETFX_CORE internal static class ListExtender { @@ -524,10 +705,18 @@ internal static void ForEach(this List list, Action callback) } #endif - #endregion +#endregion - #region TinyIoC Exception Types - public class TinyIoCResolutionException : Exception +#region TinyIoC Exception Types +#if SERIALIZABLE + [Serializable] +#endif +#if TINYIOC_INTERNAL + internal +#else + public +#endif + class TinyIoCResolutionException : Exception { private const string ERROR_TEXT = "Unable to resolve type: {0}"; @@ -540,9 +729,22 @@ public TinyIoCResolutionException(Type type, Exception innerException) : base(String.Format(ERROR_TEXT, type.FullName), innerException) { } +#if SERIALIZABLE + protected TinyIoCResolutionException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } +#endif } - - public class TinyIoCRegistrationTypeException : Exception +#if SERIALIZABLE + [Serializable] +#endif +#if TINYIOC_INTERNAL + internal +#else + public +#endif + class TinyIoCRegistrationTypeException : Exception { private const string REGISTER_ERROR_TEXT = "Cannot register type {0} - abstract classes or interfaces are not valid implementation types for {1}."; @@ -555,9 +757,22 @@ public TinyIoCRegistrationTypeException(Type type, string factory, Exception inn : base(String.Format(REGISTER_ERROR_TEXT, type.FullName, factory), innerException) { } +#if SERIALIZABLE + protected TinyIoCRegistrationTypeException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } +#endif } - - public class TinyIoCRegistrationException : Exception +#if SERIALIZABLE + [Serializable] +#endif +#if TINYIOC_INTERNAL + internal +#else + public +#endif + class TinyIoCRegistrationException : Exception { private const string CONVERT_ERROR_TEXT = "Cannot convert current registration of {0} to {1}"; private const string GENERIC_CONSTRAINT_ERROR_TEXT = "Type {1} is not valid for a registration of type {0}"; @@ -581,9 +796,22 @@ public TinyIoCRegistrationException(Type registerType, Type implementationType, : base(String.Format(GENERIC_CONSTRAINT_ERROR_TEXT, registerType.FullName, implementationType.FullName), innerException) { } +#if SERIALIZABLE + protected TinyIoCRegistrationException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } +#endif } - - public class TinyIoCWeakReferenceException : Exception +#if SERIALIZABLE + [Serializable] +#endif +#if TINYIOC_INTERNAL + internal +#else + public +#endif + class TinyIoCWeakReferenceException : Exception { private const string ERROR_TEXT = "Unable to instantiate {0} - referenced object has been reclaimed"; @@ -596,9 +824,22 @@ public TinyIoCWeakReferenceException(Type type, Exception innerException) : base(String.Format(ERROR_TEXT, type.FullName), innerException) { } +#if SERIALIZABLE + protected TinyIoCWeakReferenceException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } +#endif } - - public class TinyIoCConstructorResolutionException : Exception +#if SERIALIZABLE + [Serializable] +#endif +#if TINYIOC_INTERNAL + internal +#else + public +#endif + class TinyIoCConstructorResolutionException : Exception { private const string ERROR_TEXT = "Unable to resolve constructor for {0} using provided Expression."; @@ -621,9 +862,22 @@ public TinyIoCConstructorResolutionException(string message) : base(message) { } +#if SERIALIZABLE + protected TinyIoCConstructorResolutionException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } +#endif } - - public class TinyIoCAutoRegistrationException : Exception +#if SERIALIZABLE + [Serializable] +#endif +#if TINYIOC_INTERNAL + internal +#else + public +#endif + class TinyIoCAutoRegistrationException : Exception { private const string ERROR_TEXT = "Duplicate implementation of type {0} found ({1})."; @@ -636,6 +890,12 @@ public TinyIoCAutoRegistrationException(Type registerType, IEnumerable typ : base(String.Format(ERROR_TEXT, registerType, GetTypesString(types)), innerException) { } +#if SERIALIZABLE + protected TinyIoCAutoRegistrationException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + } +#endif private static string GetTypesString(IEnumerable types) { @@ -645,13 +905,18 @@ private static string GetTypesString(IEnumerable types) return string.Join(",", typeNames.ToArray()); } } - #endregion +#endregion - #region Public Setup / Settings Classes +#region Public Setup / Settings Classes /// /// Name/Value pairs for specifying "user" parameters when resolving /// - public sealed class NamedParameterOverloads : Dictionary +#if TINYIOC_INTERNAL + internal +#else + public +#endif + sealed class NamedParameterOverloads : Dictionary { public static NamedParameterOverloads FromIDictionary(IDictionary data) { @@ -678,11 +943,16 @@ public static NamedParameterOverloads Default } } - public enum UnregisteredResolutionActions +#if TINYIOC_INTERNAL + internal +#else + public +#endif + enum UnregisteredResolutionActions { /// /// Attempt to resolve type, even if the type isn't registered. - /// + /// /// Registered types/options will always take precedence. /// AttemptResolve, @@ -695,19 +965,29 @@ public enum UnregisteredResolutionActions /// /// Attempt to resolve unregistered type if requested type is generic /// and no registration exists for the specific generic parameters used. - /// + /// /// Registered types/options will always take precedence. /// GenericsOnly } - public enum NamedResolutionFailureActions +#if TINYIOC_INTERNAL + internal +#else + public +#endif + enum NamedResolutionFailureActions { AttemptUnnamedResolution, Fail } - public enum DuplicateImplementationActions +#if TINYIOC_INTERNAL + internal +#else + public +#endif + enum DuplicateImplementationActions { RegisterSingle, RegisterMultiple, @@ -717,7 +997,12 @@ public enum DuplicateImplementationActions /// /// Resolution settings /// - public sealed class ResolveOptions +#if TINYIOC_INTERNAL + internal +#else + public +#endif + sealed class ResolveOptions { private static readonly ResolveOptions _Default = new ResolveOptions(); private static readonly ResolveOptions _FailUnregisteredAndNameNotFound = new ResolveOptions() { NamedResolutionFailureAction = NamedResolutionFailureActions.Fail, UnregisteredResolutionAction = UnregisteredResolutionActions.Fail }; @@ -782,11 +1067,16 @@ public static ResolveOptions FailUnregisteredOnly } } } - #endregion +#endregion - public sealed partial class TinyIoCContainer : IDisposable +#if TINYIOC_INTERNAL + internal +#else + public +#endif + sealed partial class TinyIoCContainer : IDisposable { - #region Fake NETFX_CORE Classes +#region Fake NETFX_CORE Classes #if NETFX_CORE private sealed class MethodAccessException : Exception { @@ -831,9 +1121,9 @@ public async Task> GetAssembliesAsync() } } #endif - #endregion +#endregion - #region "Fluent" API +#region "Fluent" API /// /// Registration options for "fluent" API /// @@ -852,7 +1142,7 @@ public RegisterOptions(TinyIoCContainer container, TypeRegistration registration /// Make registration a singleton (single instance) if possible /// /// RegisterOptions - /// + /// public RegisterOptions AsSingleton() { var currentFactory = _Container.GetCurrentFactory(_Registration); @@ -867,7 +1157,7 @@ public RegisterOptions AsSingleton() /// Make registration multi-instance if possible /// /// RegisterOptions - /// + /// public RegisterOptions AsMultiInstance() { var currentFactory = _Container.GetCurrentFactory(_Registration); @@ -882,7 +1172,7 @@ public RegisterOptions AsMultiInstance() /// Make registration hold a weak reference if possible /// /// RegisterOptions - /// + /// public RegisterOptions WithWeakReference() { var currentFactory = _Container.GetCurrentFactory(_Registration); @@ -897,7 +1187,7 @@ public RegisterOptions WithWeakReference() /// Make registration hold a strong reference if possible /// /// RegisterOptions - /// + /// public RegisterOptions WithStrongReference() { var currentFactory = _Container.GetCurrentFactory(_Registration); @@ -934,7 +1224,7 @@ public RegisterOptions UsingConstructor(Expression /// Switches to a custom lifetime manager factory if possible. - /// + /// /// Usually used for RegisterOptions "To*" extension methods such as the ASP.Net per-request one. /// /// RegisterOptions instance @@ -949,7 +1239,7 @@ public static RegisterOptions ToCustomLifetimeManager(RegisterOptions instance, if (lifetimeProvider == null) throw new ArgumentNullException("lifetimeProvider", "lifetimeProvider is null."); - if (String.IsNullOrEmpty(errorString)) + if (string.IsNullOrEmpty(errorString)) throw new ArgumentException("errorString is null or empty.", "errorString"); var currentFactory = instance._Container.GetCurrentFactory(instance._Registration); @@ -981,7 +1271,7 @@ public MultiRegisterOptions(IEnumerable registerOptions) /// Make registration a singleton (single instance) if possible /// /// RegisterOptions - /// + /// public MultiRegisterOptions AsSingleton() { _RegisterOptions = ExecuteOnAllRegisterOptions(ro => ro.AsSingleton()); @@ -992,13 +1282,41 @@ public MultiRegisterOptions AsSingleton() /// Make registration multi-instance if possible /// /// MultiRegisterOptions - /// + /// public MultiRegisterOptions AsMultiInstance() { _RegisterOptions = ExecuteOnAllRegisterOptions(ro => ro.AsMultiInstance()); return this; } + /// + /// Switches to a custom lifetime manager factory if possible. + /// + /// Usually used for RegisterOptions "To*" extension methods such as the ASP.Net per-request one. + /// + /// MultiRegisterOptions instance + /// Custom lifetime manager + /// Error string to display if switch fails + /// MultiRegisterOptions + public static MultiRegisterOptions ToCustomLifetimeManager( + MultiRegisterOptions instance, + ITinyIoCObjectLifetimeProvider lifetimeProvider, + string errorString) + { + if (instance == null) + throw new ArgumentNullException("instance", "instance is null."); + + if (lifetimeProvider == null) + throw new ArgumentNullException("lifetimeProvider", "lifetimeProvider is null."); + + if (string.IsNullOrEmpty(errorString)) + throw new ArgumentException("errorString is null or empty.", "errorString"); + + instance._RegisterOptions = instance.ExecuteOnAllRegisterOptions(ro => RegisterOptions.ToCustomLifetimeManager(ro, lifetimeProvider, errorString)); + + return instance; + } + private IEnumerable ExecuteOnAllRegisterOptions(Func action) { var newRegisterOptions = new List(); @@ -1011,20 +1329,20 @@ private IEnumerable ExecuteOnAllRegisterOptions(Func /// Attempt to automatically register all non-generic classes and interfaces in the current app domain. - /// + /// /// If more than one class implements an interface then only one implementation will be registered /// although no error will be thrown. /// @@ -1033,14 +1351,14 @@ public void AutoRegister() #if APPDOMAIN_GETASSEMBLIES AutoRegisterInternal(AppDomain.CurrentDomain.GetAssemblies().Where(a => !IsIgnoredAssembly(a)), DuplicateImplementationActions.RegisterSingle, null); #else - AutoRegisterInternal(new Assembly[] {this.GetType().Assembly()}, true, null); + AutoRegisterInternal(new Assembly[] { this.GetType().Assembly() }, DuplicateImplementationActions.RegisterSingle, null); #endif } /// /// Attempt to automatically register all non-generic classes and interfaces in the current app domain. /// Types will only be registered if they pass the supplied registration predicate. - /// + /// /// If more than one class implements an interface then only one implementation will be registered /// although no error will be thrown. /// @@ -1050,7 +1368,7 @@ public void AutoRegister(Func registrationPredicate) #if APPDOMAIN_GETASSEMBLIES AutoRegisterInternal(AppDomain.CurrentDomain.GetAssemblies().Where(a => !IsIgnoredAssembly(a)), DuplicateImplementationActions.RegisterSingle, registrationPredicate); #else - AutoRegisterInternal(new Assembly[] { this.GetType().Assembly()}, true, registrationPredicate); + AutoRegisterInternal(new Assembly[] { this.GetType().Assembly() }, DuplicateImplementationActions.RegisterSingle, registrationPredicate); #endif } @@ -1064,7 +1382,7 @@ public void AutoRegister(DuplicateImplementationActions duplicateAction) #if APPDOMAIN_GETASSEMBLIES AutoRegisterInternal(AppDomain.CurrentDomain.GetAssemblies().Where(a => !IsIgnoredAssembly(a)), duplicateAction, null); #else - AutoRegisterInternal(new Assembly[] { this.GetType().Assembly() }, ignoreDuplicateImplementations, null); + AutoRegisterInternal(new Assembly[] { this.GetType().Assembly() }, duplicateAction, null); #endif } @@ -1080,13 +1398,13 @@ public void AutoRegister(DuplicateImplementationActions duplicateAction, Func !IsIgnoredAssembly(a)), duplicateAction, registrationPredicate); #else - AutoRegisterInternal(new Assembly[] { this.GetType().Assembly() }, ignoreDuplicateImplementations, registrationPredicate); + AutoRegisterInternal(new Assembly[] { this.GetType().Assembly() }, duplicateAction, registrationPredicate); #endif } - /// + /// /// Attempt to automatically register all non-generic classes and interfaces in the specified assemblies - /// + /// /// If more than one class implements an interface then only one implementation will be registered /// although no error will be thrown. /// @@ -1099,7 +1417,7 @@ public void AutoRegister(IEnumerable assemblies) /// /// Attempt to automatically register all non-generic classes and interfaces in the specified assemblies /// Types will only be registered if they pass the supplied registration predicate. - /// + /// /// If more than one class implements an interface then only one implementation will be registered /// although no error will be thrown. /// @@ -1253,7 +1571,7 @@ public RegisterOptions Register(Type registerType, Func /// Creates/replaces a container class registration with default options. /// - /// Type to register + /// Type to register /// RegisterOptions for fluent API public RegisterOptions Register() where RegisterType : class @@ -1264,7 +1582,7 @@ public RegisterOptions Register() /// /// Creates/replaces a named container class registration with default options. /// - /// Type to register + /// Type to register /// Name of registration /// RegisterOptions for fluent API public RegisterOptions Register(string name) @@ -1391,7 +1709,7 @@ public RegisterOptions Register(Func /// Register multiple implementations of a type. - /// + /// /// Internally this registers each implementation using the full name of the class as its registration name. /// /// Type that each implementation implements @@ -1404,7 +1722,7 @@ public MultiRegisterOptions RegisterMultiple(IEnumerable imp /// /// Register multiple implementations of a type. - /// + /// /// Internally this registers each implementation using the full name of the class as its registration name. /// /// Type that each implementation implements @@ -1416,20 +1734,20 @@ public MultiRegisterOptions RegisterMultiple(Type registrationType, IEnumerable< throw new ArgumentNullException("types", "types is null."); foreach (var type in implementationTypes) -//#if NETFX_CORE -// if (!registrationType.GetTypeInfo().IsAssignableFrom(type.GetTypeInfo())) -//#else + //#if NETFX_CORE + // if (!registrationType.GetTypeInfo().IsAssignableFrom(type.GetTypeInfo())) + //#else if (!registrationType.IsAssignableFrom(type)) -//#endif - throw new ArgumentException(String.Format("types: The type {0} is not assignable from {1}", registrationType.FullName, type.FullName)); + //#endif + throw new ArgumentException(String.Format("types: The type {0} is not assignable from {1}", registrationType.FullName, type.FullName)); if (implementationTypes.Count() != implementationTypes.Distinct().Count()) { var queryForDuplicatedTypes = from i in implementationTypes group i by i into j - where j.Count() > 1 - select j.Key.FullName; + where j.Count() > 1 + select j.Key.FullName; var fullNamesOfDuplicatedTypes = string.Join(",\n", queryForDuplicatedTypes.ToArray()); var multipleRegMessage = string.Format("types: The same implementation type cannot be specified multiple times for {0}\n\n{1}", registrationType.FullName, fullNamesOfDuplicatedTypes); @@ -1445,9 +1763,57 @@ where j.Count() > 1 return new MultiRegisterOptions(registerOptions); } - #endregion +#endregion + +#region Unregistration - #region Resolution + /// + /// Remove a container class registration. + /// + /// Type to unregister + /// true if the registration is successfully found and removed; otherwise, false. + public bool Unregister() + { + return Unregister(typeof(RegisterType), string.Empty); + } + + /// + /// Remove a named container class registration. + /// + /// Type to unregister + /// Name of registration + /// true if the registration is successfully found and removed; otherwise, false. + public bool Unregister(string name) + { + return Unregister(typeof(RegisterType), name); + } + + /// + /// Remove a container class registration. + /// + /// Type to unregister + /// true if the registration is successfully found and removed; otherwise, false. + public bool Unregister(Type registerType) + { + return Unregister(registerType, string.Empty); + } + + /// + /// Remove a named container class registration. + /// + /// Type to unregister + /// Name of registration + /// true if the registration is successfully found and removed; otherwise, false. + public bool Unregister(Type registerType, string name) + { + var typeRegistration = new TypeRegistration(registerType, name); + + return RemoveRegistration(typeRegistration); + } + +#endregion + +#region Resolution /// /// Attempts to resolve a type using default options. /// @@ -1698,7 +2064,6 @@ public ResolveType Resolve(string name, NamedParameterOverloads par /// Note: Resolution may still fail if user defined factory registations fail to construct objects when called. /// /// Type to resolve - /// Name of registration /// Bool indicating whether the type can be resolved public bool CanResolve(Type resolveType) { @@ -1711,6 +2076,7 @@ public bool CanResolve(Type resolveType) /// Note: Resolution may still fail if user defined factory registations fail to construct objects when called. /// /// Type to resolve + /// Name of registration /// Bool indicating whether the type can be resolved private bool CanResolve(Type resolveType, string name) { @@ -1723,7 +2089,6 @@ private bool CanResolve(Type resolveType, string name) /// Note: Resolution may still fail if user defined factory registations fail to construct objects when called. /// /// Type to resolve - /// Name of registration /// Resolution options /// Bool indicating whether the type can be resolved public bool CanResolve(Type resolveType, ResolveOptions options) @@ -1750,7 +2115,7 @@ public bool CanResolve(Type resolveType, string name, ResolveOptions options) /// /// Parameters are used in conjunction with normal container resolution to find the most suitable constructor (if one exists). /// All user supplied parameters must exist in at least one resolvable constructor of RegisterType or resolution will fail. - /// + /// /// Note: Resolution may still fail if user defined factory registations fail to construct objects when called. /// /// Type to resolve @@ -1766,7 +2131,7 @@ public bool CanResolve(Type resolveType, NamedParameterOverloads parameters) /// /// Parameters are used in conjunction with normal container resolution to find the most suitable constructor (if one exists). /// All user supplied parameters must exist in at least one resolvable constructor of RegisterType or resolution will fail. - /// + /// /// Note: Resolution may still fail if user defined factory registations fail to construct objects when called. /// /// Type to resolve @@ -1783,7 +2148,7 @@ public bool CanResolve(Type resolveType, string name, NamedParameterOverloads pa /// /// Parameters are used in conjunction with normal container resolution to find the most suitable constructor (if one exists). /// All user supplied parameters must exist in at least one resolvable constructor of RegisterType or resolution will fail. - /// + /// /// Note: Resolution may still fail if user defined factory registations fail to construct objects when called. /// /// Type to resolve @@ -1800,7 +2165,7 @@ public bool CanResolve(Type resolveType, NamedParameterOverloads parameters, Res /// /// Parameters are used in conjunction with normal container resolution to find the most suitable constructor (if one exists). /// All user supplied parameters must exist in at least one resolvable constructor of RegisterType or resolution will fail. - /// + /// /// Note: Resolution may still fail if user defined factory registations fail to construct objects when called. /// /// Type to resolve @@ -1819,7 +2184,6 @@ public bool CanResolve(Type resolveType, string name, NamedParameterOverloads pa /// Note: Resolution may still fail if user defined factory registations fail to construct objects when called. /// /// Type to resolve - /// Name of registration /// Bool indicating whether the type can be resolved public bool CanResolve() where ResolveType : class @@ -1846,7 +2210,6 @@ public bool CanResolve(string name) /// Note: Resolution may still fail if user defined factory registations fail to construct objects when called. /// /// Type to resolve - /// Name of registration /// Resolution options /// Bool indicating whether the type can be resolved public bool CanResolve(ResolveOptions options) @@ -1875,7 +2238,7 @@ public bool CanResolve(string name, ResolveOptions options) /// /// Parameters are used in conjunction with normal container resolution to find the most suitable constructor (if one exists). /// All user supplied parameters must exist in at least one resolvable constructor of RegisterType or resolution will fail. - /// + /// /// Note: Resolution may still fail if user defined factory registations fail to construct objects when called. /// /// Type to resolve @@ -1892,7 +2255,7 @@ public bool CanResolve(NamedParameterOverloads parameters) /// /// Parameters are used in conjunction with normal container resolution to find the most suitable constructor (if one exists). /// All user supplied parameters must exist in at least one resolvable constructor of RegisterType or resolution will fail. - /// + /// /// Note: Resolution may still fail if user defined factory registations fail to construct objects when called. /// /// Type to resolve @@ -1910,7 +2273,7 @@ public bool CanResolve(string name, NamedParameterOverloads paramet /// /// Parameters are used in conjunction with normal container resolution to find the most suitable constructor (if one exists). /// All user supplied parameters must exist in at least one resolvable constructor of RegisterType or resolution will fail. - /// + /// /// Note: Resolution may still fail if user defined factory registations fail to construct objects when called. /// /// Type to resolve @@ -1928,7 +2291,7 @@ public bool CanResolve(NamedParameterOverloads parameters, ResolveO /// /// Parameters are used in conjunction with normal container resolution to find the most suitable constructor (if one exists). /// All user supplied parameters must exist in at least one resolvable constructor of RegisterType or resolution will fail. - /// + /// /// Note: Resolution may still fail if user defined factory registations fail to construct objects when called. /// /// Type to resolve @@ -1945,7 +2308,7 @@ public bool CanResolve(string name, NamedParameterOverloads paramet /// /// Attemps to resolve a type using the default options /// - /// Type to resolve + /// Type to resolve /// Resolved type or default if resolve fails /// True if resolved sucessfully, false otherwise public bool TryResolve(Type resolveType, out object resolvedType) @@ -1965,7 +2328,7 @@ public bool TryResolve(Type resolveType, out object resolvedType) /// /// Attemps to resolve a type using the given options /// - /// Type to resolve + /// Type to resolve /// Resolution options /// Resolved type or default if resolve fails /// True if resolved sucessfully, false otherwise @@ -1986,7 +2349,7 @@ public bool TryResolve(Type resolveType, ResolveOptions options, out object reso /// /// Attemps to resolve a type using the default options and given name /// - /// Type to resolve + /// Type to resolve /// Name of registration /// Resolved type or default if resolve fails /// True if resolved sucessfully, false otherwise @@ -2007,7 +2370,7 @@ public bool TryResolve(Type resolveType, string name, out object resolvedType) /// /// Attemps to resolve a type using the given options and name /// - /// Type to resolve + /// Type to resolve /// Name of registration /// Resolution options /// Resolved type or default if resolve fails @@ -2029,7 +2392,7 @@ public bool TryResolve(Type resolveType, string name, ResolveOptions options, ou /// /// Attemps to resolve a type using the default options and supplied constructor parameters /// - /// Type to resolve + /// Type to resolve /// User specified constructor parameters /// Resolved type or default if resolve fails /// True if resolved sucessfully, false otherwise @@ -2050,7 +2413,7 @@ public bool TryResolve(Type resolveType, NamedParameterOverloads parameters, out /// /// Attemps to resolve a type using the default options and supplied name and constructor parameters /// - /// Type to resolve + /// Type to resolve /// Name of registration /// User specified constructor parameters /// Resolved type or default if resolve fails @@ -2072,8 +2435,7 @@ public bool TryResolve(Type resolveType, string name, NamedParameterOverloads pa /// /// Attemps to resolve a type using the supplied options and constructor parameters /// - /// Type to resolve - /// Name of registration + /// Type to resolve /// User specified constructor parameters /// Resolution options /// Resolved type or default if resolve fails @@ -2095,7 +2457,7 @@ public bool TryResolve(Type resolveType, NamedParameterOverloads parameters, Res /// /// Attemps to resolve a type using the supplied name, options and constructor parameters /// - /// Type to resolve + /// Type to resolve /// Name of registration /// User specified constructor parameters /// Resolution options @@ -2252,7 +2614,6 @@ public bool TryResolve(string name, NamedParameterOverloads paramet /// Attemps to resolve a type using the supplied options and constructor parameters /// /// Type to resolve - /// Name of registration /// User specified constructor parameters /// Resolution options /// Resolved type or default if resolve fails @@ -2299,7 +2660,7 @@ public bool TryResolve(string name, NamedParameterOverloads paramet /// /// Returns all registrations of a type /// - /// Type to resolveAll + /// Type to resolveAll /// Whether to include un-named (default) registrations /// IEnumerable public IEnumerable ResolveAll(Type resolveType, bool includeUnnamed) @@ -2310,7 +2671,7 @@ public IEnumerable ResolveAll(Type resolveType, bool includeUnnamed) /// /// Returns all registrations of a type, both named and unnamed /// - /// Type to resolveAll + /// Type to resolveAll /// IEnumerable public IEnumerable ResolveAll(Type resolveType) { @@ -2333,7 +2694,6 @@ public IEnumerable ResolveAll(bool includeUnnamed) /// Returns all registrations of a type, both named and unnamed /// /// Type to resolveAll - /// Whether to include un-named (default) registrations /// IEnumerable public IEnumerable ResolveAll() where ResolveType : class @@ -2359,10 +2719,10 @@ public void BuildUp(object input, ResolveOptions resolveOptions) { BuildUpInternal(input, resolveOptions); } - #endregion - #endregion +#endregion +#endregion - #region Object Factories +#region Object Factories /// /// Provides custom lifetime management for ASP.Net per-request lifetimes etc. /// @@ -2390,7 +2750,7 @@ private abstract class ObjectFactoryBase { /// /// Whether to assume this factory sucessfully constructs its objects - /// + /// /// Generally set to true for delegate style factories as CanResolve cannot delve /// into the delegates they contain. /// @@ -2475,13 +2835,13 @@ private class MultiInstanceFactory : ObjectFactoryBase public MultiInstanceFactory(Type registerType, Type registerImplementation) { -//#if NETFX_CORE -// if (registerImplementation.GetTypeInfo().IsAbstract() || registerImplementation.GetTypeInfo().IsInterface()) -// throw new TinyIoCRegistrationTypeException(registerImplementation, "MultiInstanceFactory"); -//#else + //#if NETFX_CORE + // if (registerImplementation.GetTypeInfo().IsAbstract() || registerImplementation.GetTypeInfo().IsInterface()) + // throw new TinyIoCRegistrationTypeException(registerImplementation, "MultiInstanceFactory"); + //#else if (registerImplementation.IsAbstract() || registerImplementation.IsInterface()) throw new TinyIoCRegistrationTypeException(registerImplementation, "MultiInstanceFactory"); -//#endif + //#endif if (!IsValidAssignment(registerType, registerImplementation)) throw new TinyIoCRegistrationTypeException(registerImplementation, "MultiInstanceFactory"); @@ -2548,7 +2908,7 @@ public override object GetObject(Type requestedType, TinyIoCContainer container, } } - public DelegateFactory( Type registerType, Func factory) + public DelegateFactory(Type registerType, Func factory) { if (factory == null) throw new ArgumentNullException("factory"); @@ -2716,7 +3076,7 @@ public void Dispose() /// /// Stores an particular instance to return for a type - /// + /// /// Stores the instance with a weak reference /// private class WeakInstanceFactory : ObjectFactoryBase, IDisposable @@ -2805,11 +3165,11 @@ private class SingletonFactory : ObjectFactoryBase, IDisposable public SingletonFactory(Type registerType, Type registerImplementation) { -//#if NETFX_CORE -// if (registerImplementation.GetTypeInfo().IsAbstract() || registerImplementation.GetTypeInfo().IsInterface()) -//#else + //#if NETFX_CORE + // if (registerImplementation.GetTypeInfo().IsAbstract() || registerImplementation.GetTypeInfo().IsInterface()) + //#else if (registerImplementation.IsAbstract() || registerImplementation.IsInterface()) -//#endif + //#endif throw new TinyIoCRegistrationTypeException(registerImplementation, "SingletonFactory"); if (!IsValidAssignment(registerType, registerImplementation)) @@ -2896,11 +3256,11 @@ public CustomObjectLifetimeFactory(Type registerType, Type registerImplementatio if (!IsValidAssignment(registerType, registerImplementation)) throw new TinyIoCRegistrationTypeException(registerImplementation, "SingletonFactory"); -//#if NETFX_CORE -// if (registerImplementation.GetTypeInfo().IsAbstract() || registerImplementation.GetTypeInfo().IsInterface()) -//#else + //#if NETFX_CORE + // if (registerImplementation.GetTypeInfo().IsAbstract() || registerImplementation.GetTypeInfo().IsInterface()) + //#else if (registerImplementation.IsAbstract() || registerImplementation.IsInterface()) -//#endif + //#endif throw new TinyIoCRegistrationTypeException(registerImplementation, errorMessage); this.registerType = registerType; @@ -2968,9 +3328,9 @@ public void Dispose() _LifetimeProvider.ReleaseObject(); } } - #endregion +#endregion - #region Singleton Container +#region Singleton Container private static readonly TinyIoCContainer _Current = new TinyIoCContainer(); static TinyIoCContainer() @@ -2987,9 +3347,9 @@ public static TinyIoCContainer Current return _Current; } } - #endregion +#endregion - #region Type Registrations +#region Type Registrations public sealed class TypeRegistration { private int _hashCode; @@ -3036,9 +3396,9 @@ public override int GetHashCode() private delegate object ObjectConstructor(params object[] parameters); private static readonly SafeDictionary _ObjectConstructorCache = new SafeDictionary(); #endif - #endregion +#endregion - #region Constructors +#region Constructors public TinyIoCContainer() { _RegisteredTypes = new SafeDictionary(); @@ -3052,9 +3412,9 @@ private TinyIoCContainer(TinyIoCContainer parent) { _Parent = parent; } - #endregion +#endregion - #region Internal Methods +#region Internal Methods private readonly object _AutoRegisterLock = new object(); private void AutoRegisterInternal(IEnumerable assemblies, DuplicateImplementationActions duplicateAction, Func registrationPredicate) { @@ -3062,9 +3422,9 @@ private void AutoRegisterInternal(IEnumerable assemblies, DuplicateImp { var types = assemblies.SelectMany(a => a.SafeGetTypes()).Where(t => !IsIgnoredType(t, registrationPredicate)).ToList(); - var concreteTypes = from type in types - where type.IsClass() && (type.IsAbstract() == false) && (type != this.GetType() && (type.DeclaringType != this.GetType()) && (!type.IsGenericTypeDefinition())) - select type; + var concreteTypes = types + .Where(type => type.IsClass() && (type.IsAbstract() == false) && (type != this.GetType() && (type.DeclaringType != this.GetType()) && (!type.IsGenericTypeDefinition()))) + .ToList(); foreach (var type in concreteTypes) { @@ -3072,7 +3432,11 @@ where type.IsClass() && (type.IsAbstract() == false) && (type != this.GetType() { RegisterInternal(type, string.Empty, GetDefaultObjectFactory(type, type)); } +#if PORTABLE || NETSTANDARD1_0 || NETSTANDARD1_1 || NETSTANDARD1_2 || NETSTANDARD1_3 || NETSTANDARD1_4 || NETSTANDARD1_5 || NETSTANDARD1_6 + catch (MemberAccessException) +#else catch (MethodAccessException) +#endif { // Ignore methods we can't access - added for Silverlight } @@ -3089,7 +3453,7 @@ where type.IsClass() && (type.IsAbstract() == false) && (type != this.GetType() where localType.IsAssignableFrom(implementationType) select implementationType; - if (implementations.Count() > 1) + if (implementations.Skip(1).Any()) { if (duplicateAction == DuplicateImplementationActions.Fail) throw new TinyIoCAutoRegistrationException(type, implementations); @@ -3107,7 +3471,11 @@ where localType.IsAssignableFrom(implementationType) { RegisterInternal(type, string.Empty, GetDefaultObjectFactory(type, firstImplementation)); } +#if PORTABLE || NETSTANDARD1_0 || NETSTANDARD1_1 || NETSTANDARD1_2 || NETSTANDARD1_3 || NETSTANDARD1_4 || NETSTANDARD1_5 || NETSTANDARD1_6 + catch (MemberAccessException) +#else catch (MethodAccessException) +#endif { // Ignore methods we can't access - added for Silverlight } @@ -3128,6 +3496,7 @@ private bool IsIgnoredAssembly(Assembly assembly) asm => asm.FullName.StartsWith("mscorlib,", StringComparison.Ordinal), asm => asm.FullName.StartsWith("CR_VSTest", StringComparison.Ordinal), asm => asm.FullName.StartsWith("DevExpress.CodeRush", StringComparison.Ordinal), + asm => asm.FullName.StartsWith("xunit.", StringComparison.Ordinal), }; foreach (var check in ignoreChecks) @@ -3201,18 +3570,18 @@ private RegisterOptions AddUpdateRegistration(TypeRegistration typeRegistration, return new RegisterOptions(this, typeRegistration); } - private void RemoveRegistration(TypeRegistration typeRegistration) + private bool RemoveRegistration(TypeRegistration typeRegistration) { - _RegisteredTypes.Remove(typeRegistration); + return _RegisteredTypes.Remove(typeRegistration); } private ObjectFactoryBase GetDefaultObjectFactory(Type registerType, Type registerImplementation) { -//#if NETFX_CORE -// if (registerType.GetTypeInfo().IsInterface() || registerType.GetTypeInfo().IsAbstract()) -//#else + //#if NETFX_CORE + // if (registerType.GetTypeInfo().IsInterface() || registerType.GetTypeInfo().IsAbstract()) + //#else if (registerType.IsInterface() || registerType.IsAbstract()) -//#endif + //#endif return new SingletonFactory(registerType, registerImplementation); return new MultiInstanceFactory(registerType, registerImplementation); @@ -3239,7 +3608,7 @@ private bool CanResolveInternal(TypeRegistration registration, NamedParameterOve } #if RESOLVE_OPEN_GENERICS - if (checkType.IsInterface && checkType.IsGenericType) + if (checkType.IsInterface() && checkType.IsGenericType()) { // if the type is registered as an open generic, then see if the open generic is registered if (_RegisteredTypes.TryGetValue(new TypeRegistration(checkType.GetGenericTypeDefinition(), name), out factory)) @@ -3257,11 +3626,11 @@ private bool CanResolveInternal(TypeRegistration registration, NamedParameterOve // Fail if requesting named resolution and settings set to fail if unresolved // Or bubble up if we have a parent - if (!String.IsNullOrEmpty(name) && options.NamedResolutionFailureAction == NamedResolutionFailureActions.Fail) + if (!string.IsNullOrEmpty(name) && options.NamedResolutionFailureAction == NamedResolutionFailureActions.Fail) return (_Parent != null) ? _Parent.CanResolveInternal(registration, parameters, options) : false; // Attemped unnamed fallback container resolution if relevant and requested - if (!String.IsNullOrEmpty(name) && options.NamedResolutionFailureAction == NamedResolutionFailureActions.AttemptUnnamedResolution) + if (!string.IsNullOrEmpty(name) && options.NamedResolutionFailureAction == NamedResolutionFailureActions.AttemptUnnamedResolution) { if (_RegisteredTypes.TryGetValue(new TypeRegistration(checkType), out factory)) { @@ -3317,19 +3686,19 @@ private bool IsAutomaticLazyFactoryRequest(Type type) return true; // 2 parameter func with string as first parameter (name) -//#if NETFX_CORE -// if ((genericType == typeof(Func<,>) && type.GetTypeInfo().GenericTypeArguments[0] == typeof(string))) -//#else + //#if NETFX_CORE + // if ((genericType == typeof(Func<,>) && type.GetTypeInfo().GenericTypeArguments[0] == typeof(string))) + //#else if ((genericType == typeof(Func<,>) && type.GetGenericArguments()[0] == typeof(string))) -//#endif + //#endif return true; // 3 parameter func with string as first parameter (name) and IDictionary as second (parameters) -//#if NETFX_CORE -// if ((genericType == typeof(Func<,,>) && type.GetTypeInfo().GenericTypeArguments[0] == typeof(string) && type.GetTypeInfo().GenericTypeArguments[1] == typeof(IDictionary))) -//#else + //#if NETFX_CORE + // if ((genericType == typeof(Func<,,>) && type.GetTypeInfo().GenericTypeArguments[0] == typeof(string) && type.GetTypeInfo().GenericTypeArguments[1] == typeof(IDictionary))) + //#else if ((genericType == typeof(Func<,,>) && type.GetGenericArguments()[0] == typeof(string) && type.GetGenericArguments()[1] == typeof(IDictionary))) -//#endif + //#endif return true; return false; @@ -3414,11 +3783,11 @@ private object ResolveInternal(TypeRegistration registration, NamedParameterOver } // Fail if requesting named resolution and settings set to fail if unresolved - if (!String.IsNullOrEmpty(registration.Name) && options.NamedResolutionFailureAction == NamedResolutionFailureActions.Fail) + if (!string.IsNullOrEmpty(registration.Name) && options.NamedResolutionFailureAction == NamedResolutionFailureActions.Fail) throw new TinyIoCResolutionException(registration.Type); // Attemped unnamed fallback container resolution if relevant and requested - if (!String.IsNullOrEmpty(registration.Name) && options.NamedResolutionFailureAction == NamedResolutionFailureActions.AttemptUnnamedResolution) + if (!string.IsNullOrEmpty(registration.Name) && options.NamedResolutionFailureAction == NamedResolutionFailureActions.AttemptUnnamedResolution) { if (_RegisteredTypes.TryGetValue(new TypeRegistration(registration.Type, string.Empty), out factory)) { @@ -3463,22 +3832,22 @@ private object GetLazyAutomaticFactoryRequest(Type type) return null; Type genericType = type.GetGenericTypeDefinition(); -//#if NETFX_CORE -// Type[] genericArguments = type.GetTypeInfo().GenericTypeArguments.ToArray(); -//#else + //#if NETFX_CORE + // Type[] genericArguments = type.GetTypeInfo().GenericTypeArguments.ToArray(); + //#else Type[] genericArguments = type.GetGenericArguments(); -//#endif + //#endif // Just a func if (genericType == typeof(Func<>)) { Type returnType = genericArguments[0]; -//#if NETFX_CORE -// MethodInfo resolveMethod = typeof(TinyIoCContainer).GetTypeInfo().GetDeclaredMethods("Resolve").First(mi => !mi.GetParameters().Any()); -//#else + //#if NETFX_CORE + // MethodInfo resolveMethod = typeof(TinyIoCContainer).GetTypeInfo().GetDeclaredMethods("Resolve").First(mi => !mi.GetParameters().Any()); + //#else MethodInfo resolveMethod = typeof(TinyIoCContainer).GetMethod("Resolve", new Type[] { }); -//#endif + //#endif resolveMethod = resolveMethod.MakeGenericMethod(returnType); var resolveCall = Expression.Call(Expression.Constant(this), resolveMethod); @@ -3493,11 +3862,11 @@ private object GetLazyAutomaticFactoryRequest(Type type) { Type returnType = genericArguments[1]; -//#if NETFX_CORE -// MethodInfo resolveMethod = typeof(TinyIoCContainer).GetTypeInfo().GetDeclaredMethods("Resolve").First(mi => mi.GetParameters().Length == 1 && mi.GetParameters()[0].GetType() == typeof(String)); -//#else + //#if NETFX_CORE + // MethodInfo resolveMethod = typeof(TinyIoCContainer).GetTypeInfo().GetDeclaredMethods("Resolve").First(mi => mi.GetParameters().Length == 1 && mi.GetParameters()[0].GetType() == typeof(String)); + //#else MethodInfo resolveMethod = typeof(TinyIoCContainer).GetMethod("Resolve", new Type[] { typeof(String) }); -//#endif + //#endif resolveMethod = resolveMethod.MakeGenericMethod(returnType); ParameterExpression[] resolveParameters = new ParameterExpression[] { Expression.Parameter(typeof(String), "name") }; @@ -3509,22 +3878,22 @@ private object GetLazyAutomaticFactoryRequest(Type type) } // 3 parameter func with string as first parameter (name) and IDictionary as second (parameters) -//#if NETFX_CORE -// if ((genericType == typeof(Func<,,>) && type.GenericTypeArguments[0] == typeof(string) && type.GenericTypeArguments[1] == typeof(IDictionary))) -//#else + //#if NETFX_CORE + // if ((genericType == typeof(Func<,,>) && type.GenericTypeArguments[0] == typeof(string) && type.GenericTypeArguments[1] == typeof(IDictionary))) + //#else if ((genericType == typeof(Func<,,>) && type.GetGenericArguments()[0] == typeof(string) && type.GetGenericArguments()[1] == typeof(IDictionary))) -//#endif + //#endif { Type returnType = genericArguments[2]; var name = Expression.Parameter(typeof(string), "name"); var parameters = Expression.Parameter(typeof(IDictionary), "parameters"); -//#if NETFX_CORE -// MethodInfo resolveMethod = typeof(TinyIoCContainer).GetTypeInfo().GetDeclaredMethods("Resolve").First(mi => mi.GetParameters().Length == 2 && mi.GetParameters()[0].GetType() == typeof(String) && mi.GetParameters()[1].GetType() == typeof(NamedParameterOverloads)); -//#else + //#if NETFX_CORE + // MethodInfo resolveMethod = typeof(TinyIoCContainer).GetTypeInfo().GetDeclaredMethods("Resolve").First(mi => mi.GetParameters().Length == 2 && mi.GetParameters()[0].GetType() == typeof(String) && mi.GetParameters()[1].GetType() == typeof(NamedParameterOverloads)); + //#else MethodInfo resolveMethod = typeof(TinyIoCContainer).GetMethod("Resolve", new Type[] { typeof(String), typeof(NamedParameterOverloads) }); -//#endif + //#endif resolveMethod = resolveMethod.MakeGenericMethod(returnType); var resolveCall = Expression.Call(Expression.Constant(this), resolveMethod, name, Expression.Call(typeof(NamedParameterOverloads), "FromIDictionary", null, parameters)); @@ -3539,11 +3908,11 @@ private object GetLazyAutomaticFactoryRequest(Type type) #endif private object GetIEnumerableRequest(Type type) { -//#if NETFX_CORE -// var genericResolveAllMethod = this.GetType().GetGenericMethod("ResolveAll", type.GenericTypeArguments, new[] { typeof(bool) }); -//#else + //#if NETFX_CORE + // var genericResolveAllMethod = this.GetType().GetGenericMethod("ResolveAll", type.GenericTypeArguments, new[] { typeof(bool) }); + //#else var genericResolveAllMethod = this.GetType().GetGenericMethod(BindingFlags.Public | BindingFlags.Instance, "ResolveAll", type.GetGenericArguments(), new[] { typeof(bool) }); -//#endif + //#endif return genericResolveAllMethod.Invoke(this, new object[] { false }); } @@ -3560,11 +3929,11 @@ private bool CanConstruct(ConstructorInfo ctor, NamedParameterOverloads paramete var isParameterOverload = parameters.ContainsKey(parameter.Name); -//#if NETFX_CORE -// if (parameter.ParameterType.GetTypeInfo().IsPrimitive && !isParameterOverload) -//#else + //#if NETFX_CORE + // if (parameter.ParameterType.GetTypeInfo().IsPrimitive && !isParameterOverload) + //#else if (parameter.ParameterType.IsPrimitive() && !isParameterOverload) -//#endif + //#endif return false; if (!isParameterOverload && !CanResolveInternal(new TypeRegistration(parameter.ParameterType), NamedParameterOverloads.Default, options)) @@ -3579,11 +3948,11 @@ private ConstructorInfo GetBestConstructor(Type type, NamedParameterOverloads pa if (parameters == null) throw new ArgumentNullException("parameters"); -//#if NETFX_CORE -// if (type.GetTypeInfo().IsValueType) -//#else + //#if NETFX_CORE + // if (type.GetTypeInfo().IsValueType) + //#else if (type.IsValueType()) -//#endif + //#endif return null; // Get constructors in reverse order based on the number of parameters @@ -3601,11 +3970,11 @@ private ConstructorInfo GetBestConstructor(Type type, NamedParameterOverloads pa private IEnumerable GetTypeConstructors(Type type) { -//#if NETFX_CORE -// return type.GetTypeInfo().DeclaredConstructors.OrderByDescending(ctor => ctor.GetParameters().Count()); -//#else + //#if NETFX_CORE + // return type.GetTypeInfo().DeclaredConstructors.OrderByDescending(ctor => ctor.GetParameters().Count()); + //#else return type.GetConstructors().OrderByDescending(ctor => ctor.GetParameters().Count()); -//#endif + //#endif } private object ConstructType(Type requestedType, Type implementationType, ResolveOptions options) @@ -3701,7 +4070,7 @@ private static ObjectConstructor CreateObjectConstructionDelegateWithCache(Const // We could lock the cache here, but there's no real side // effect to two threads creating the same ObjectConstructor - // at the same time, compared to the cost of a lock for + // at the same time, compared to the cost of a lock for // every creation. var constructorParams = constructor.GetParameters(); var lambdaParams = Expression.Parameter(typeof(object[]), "parameters"); @@ -3727,15 +4096,15 @@ private static ObjectConstructor CreateObjectConstructionDelegateWithCache(Const private void BuildUpInternal(object input, ResolveOptions resolveOptions) { -//#if NETFX_CORE -// var properties = from property in input.GetType().GetTypeInfo().DeclaredProperties -// where (property.GetMethod != null) && (property.SetMethod != null) && !property.PropertyType.GetTypeInfo().IsValueType -// select property; -//#else + //#if NETFX_CORE + // var properties = from property in input.GetType().GetTypeInfo().DeclaredProperties + // where (property.GetMethod != null) && (property.SetMethod != null) && !property.PropertyType.GetTypeInfo().IsValueType + // select property; + //#else var properties = from property in input.GetType().GetProperties() where (property.GetGetMethod() != null) && (property.GetSetMethod() != null) && !property.PropertyType.IsValueType() select property; -//#endif + //#endif foreach (var property in properties) { @@ -3765,7 +4134,7 @@ private IEnumerable GetParentRegistrationsForType(Type resolve private IEnumerable ResolveAllInternal(Type resolveType, bool includeUnnamed) { - var registrations = _RegisteredTypes.Keys.Where(tr => tr.Type == resolveType).Concat(GetParentRegistrationsForType(resolveType)); + var registrations = _RegisteredTypes.Keys.Where(tr => tr.Type == resolveType).Concat(GetParentRegistrationsForType(resolveType)).Distinct(); if (!includeUnnamed) registrations = registrations.Where(tr => tr.Name != string.Empty); @@ -3775,28 +4144,6 @@ private IEnumerable ResolveAllInternal(Type resolveType, bool includeUnn private static bool IsValidAssignment(Type registerType, Type registerImplementation) { -//#if NETFX_CORE -// var registerTypeDef = registerType.GetTypeInfo(); -// var registerImplementationDef = registerImplementation.GetTypeInfo(); - -// if (!registerTypeDef.IsGenericTypeDefinition) -// { -// if (!registerTypeDef.IsAssignableFrom(registerImplementationDef)) -// return false; -// } -// else -// { -// if (registerTypeDef.IsInterface()) -// { -// if (!registerImplementationDef.ImplementedInterfaces.Any(t => t.GetTypeInfo().Name == registerTypeDef.Name)) -// return false; -// } -// else if (registerTypeDef.IsAbstract() && registerImplementationDef.BaseType() != registerType) -// { -// return false; -// } -// } -//#else if (!registerType.IsGenericTypeDefinition()) { if (!registerType.IsAssignableFrom(registerImplementation)) @@ -3806,21 +4153,26 @@ private static bool IsValidAssignment(Type registerType, Type registerImplementa { if (registerType.IsInterface()) { +#if (PORTABLE || NETSTANDARD1_0 || NETSTANDARD1_1 || NETSTANDARD1_2 || NETSTANDARD1_3 || NETSTANDARD1_4 || NETSTANDARD1_5 || NETSTANDARD1_6) + if (!registerImplementation.GetInterfaces().Any(t => t.Name == registerType.Name)) + return false; +#else if (!registerImplementation.FindInterfaces((t, o) => t.Name == registerType.Name, null).Any()) return false; +#endif } else if (registerType.IsAbstract() && registerImplementation.BaseType() != registerType) { return false; } } -//#endif + //#endif return true; } - #endregion +#endregion - #region IDisposable Members +#region IDisposable Members bool disposed = false; public void Dispose() { @@ -3834,16 +4186,66 @@ public void Dispose() } } - #endregion +#endregion } -} +#if PORTABLE || NETSTANDARD1_0 || NETSTANDARD1_1 || NETSTANDARD1_2 || NETSTANDARD1_3 || NETSTANDARD1_4 || NETSTANDARD1_5 || NETSTANDARD1_6 + static class ReverseTypeExtender + { + public static bool IsClass(this Type type) + { + return type.GetTypeInfo().IsClass; + } -// reverse shim for WinRT SR changes... -#if !NETFX_CORE -namespace System.Reflection -{ - public static class ReverseTypeExtender + public static bool IsAbstract(this Type type) + { + return type.GetTypeInfo().IsAbstract; + } + + public static bool IsInterface(this Type type) + { + return type.GetTypeInfo().IsInterface; + } + + public static bool IsPrimitive(this Type type) + { + return type.GetTypeInfo().IsPrimitive; + } + + public static bool IsValueType(this Type type) + { + return type.GetTypeInfo().IsValueType; + } + + public static bool IsGenericType(this Type type) + { + return type.GetTypeInfo().IsGenericType; + } + + public static bool IsGenericParameter(this Type type) + { + return type.IsGenericParameter; + } + + public static bool IsGenericTypeDefinition(this Type type) + { + return type.GetTypeInfo().IsGenericTypeDefinition; + } + + public static Type BaseType(this Type type) + { + return type.GetTypeInfo().BaseType; + } + + public static Assembly Assembly(this Type type) + { + return type.GetTypeInfo().Assembly; + } + } +#endif + // reverse shim for WinRT SR changes... +#if (!NETFX_CORE && !PORTABLE && !NETSTANDARD1_0 && !NETSTANDARD1_1 && !NETSTANDARD1_2 && !NETSTANDARD1_3 && !NETSTANDARD1_4 && !NETSTANDARD1_5 && !NETSTANDARD1_6) + static class ReverseTypeExtender { public static bool IsClass(this Type type) { @@ -3895,6 +4297,5 @@ public static Assembly Assembly(this Type type) return type.Assembly; } } -} #endif -#pragma warning restore \ No newline at end of file +} diff --git a/src/React/TinyIoCExtensions.cs b/src/React.Core/TinyIoCExtensions.cs similarity index 80% rename from src/React/TinyIoCExtensions.cs rename to src/React.Core/TinyIoCExtensions.cs index 812dbe1b4..1ea6f8980 100644 --- a/src/React/TinyIoCExtensions.cs +++ b/src/React.Core/TinyIoCExtensions.cs @@ -1,10 +1,8 @@ /* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ using System; diff --git a/src/React.Core/package-lock.json b/src/React.Core/package-lock.json new file mode 100644 index 000000000..95d7482a5 --- /dev/null +++ b/src/React.Core/package-lock.json @@ -0,0 +1,4462 @@ +{ + "name": "React.Core", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.8.3" + } + }, + "@babel/core": { + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.7.tgz", + "integrity": "sha512-rBlqF3Yko9cynC5CCFy6+K/w2N+Sq/ff2BPy+Krp7rHlABIr5epbA7OxVeKoMHB39LZOp1UY5SuLjy6uWi35yA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.8.7", + "@babel/helpers": "^7.8.4", + "@babel/parser": "^7.8.7", + "@babel/template": "^7.8.6", + "@babel/traverse": "^7.8.6", + "@babel/types": "^7.8.7", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.0", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.7.tgz", + "integrity": "sha512-DQwjiKJqH4C3qGiyQCAExJHoZssn49JTMJgZ8SANGgVFdkupcUhLOdkAeoC6kmHZCPfoDG5M0b6cFlSN5wW7Ew==", + "dev": true, + "requires": { + "@babel/types": "^7.8.7", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", + "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helpers": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.8.4.tgz", + "integrity": "sha512-VPbe7wcQ4chu4TDQjimHv/5tj73qz88o12EPkO2ValS2QiQS/1F2SsjyIGNnAD0vF/nZS6Cf9i+vW6HIlnaR8w==", + "dev": true, + "requires": { + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.4", + "@babel/types": "^7.8.3" + } + }, + "@babel/highlight": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", + "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + } + } + }, + "@babel/parser": { + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.7.tgz", + "integrity": "sha512-9JWls8WilDXFGxs0phaXAZgpxTZhSk/yOYH2hTHC0X1yC7Z78IJfvR1vJ+rmJKq3I35td2XzXzN6ZLYlna+r/A==", + "dev": true + }, + "@babel/standalone": { + "version": "7.8.8", + "resolved": "https://registry.npmjs.org/@babel/standalone/-/standalone-7.8.8.tgz", + "integrity": "sha512-TeUxX+DYxNWliyU71gF4ti5NGrEheuB6NrxOumGRX/07EZXBBM90UljRzC9XjiP9f0NsEQYLQVmjd2Pu7NNARA==", + "dev": true + }, + "@babel/template": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", + "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6" + } + }, + "@babel/traverse": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.6.tgz", + "integrity": "sha512-2B8l0db/DPi8iinITKuo7cbPznLCEk0kCxDoB9/N6gGNg/gxOXiR/IcymAFPiBwk5w6TtQ27w4wpElgp9btR9A==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.8.6", + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.7.tgz", + "integrity": "sha512-k2TreEHxFA4CjGkL+GYjRyx35W0Mr7DP5+9q6WMkyKXB+904bYmG40syjMFV0oLlhhFCwWl0vA0DyzTDkwAiJw==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "@webassemblyjs/ast": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", + "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", + "dev": true, + "requires": { + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", + "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", + "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", + "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==", + "dev": true + }, + "@webassemblyjs/helper-code-frame": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", + "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", + "dev": true, + "requires": { + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "@webassemblyjs/helper-fsm": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", + "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==", + "dev": true + }, + "@webassemblyjs/helper-module-context": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", + "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", + "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", + "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", + "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", + "dev": true, + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", + "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", + "dev": true, + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", + "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", + "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/helper-wasm-section": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-opt": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", + "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", + "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", + "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "@webassemblyjs/wast-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", + "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/floating-point-hex-parser": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-code-frame": "1.9.0", + "@webassemblyjs/helper-fsm": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", + "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "acorn": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", + "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", + "dev": true + }, + "ajv": { + "version": "6.12.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz", + "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", + "dev": true + }, + "ajv-keywords": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", + "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", + "dev": true + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "dev": true, + "requires": { + "object-assign": "^4.1.1", + "util": "0.10.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", + "dev": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "base64-js": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", + "dev": true + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "optional": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", + "dev": true + } + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "randombytes": "^2.0.1" + } + }, + "browserify-sign": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", + "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "dev": true, + "requires": { + "bn.js": "^4.1.1", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.2", + "elliptic": "^6.0.0", + "inherits": "^2.0.1", + "parse-asn1": "^5.0.0" + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "requires": { + "pako": "~1.0.5" + } + }, + "buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "cacache": { + "version": "12.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", + "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", + "dev": true, + "requires": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + } + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "chrome-trace-event": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", + "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "dev": true, + "requires": { + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "create-ecdh": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", + "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.0.0" + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "cyclist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", + "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true + }, + "duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "dev": true, + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + } + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "dev": true + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + }, + "dependencies": { + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + } + } + }, + "enhanced-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz", + "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.4.0", + "tapable": "^1.0.0" + }, + "dependencies": { + "graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "errno": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.6.tgz", + "integrity": "sha512-IsORQDpaaSwcDP4ZZnHxgE85werpo34VYn1Ud3mq+eUsF593faR8oCZNXrROVkpFu2TsbrNhHin0aUrTsQ9vNw==", + "dev": true, + "requires": { + "prr": "~1.0.1" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "events": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", + "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", + "dev": true + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "fast-deep-equal": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", + "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "figgy-pudding": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", + "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", + "dev": true + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "findup-sync": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", + "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", + "dev": true, + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + } + }, + "flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "1.2.12", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.12.tgz", + "integrity": "sha512-Ggd/Ktt7E7I8pxZRbGIs7vwqAPscSESMrCSkx2FtWeqmheJgCo2R74fTsZFCifr0VTPwqRpPv17+6b8Zp7th0Q==", + "dev": true, + "optional": true, + "requires": { + "bindings": "^1.5.0", + "nan": "^2.12.1", + "node-pre-gyp": "*" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.4", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "3.2.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.6.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "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" + } + }, + "glob": { + "version": "7.1.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "bundled": true, + "dev": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "bundled": true, + "dev": true, + "optional": true + }, + "minipass": { + "version": "2.9.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.9.0" + } + }, + "mkdirp": { + "version": "0.5.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "ms": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.3.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.14.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4.4.2" + } + }, + "nopt": { + "version": "4.0.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-normalize-package-bin": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "readable-stream": { + "version": "2.3.7", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.7.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.7.1", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.13", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "yallist": { + "version": "3.1.1", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "gensync": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", + "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "requires": { + "global-prefix": "^3.0.0" + }, + "dependencies": { + "global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "requires": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + } + } + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "dev": true + }, + "iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", + "dev": true + }, + "import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "dev": true, + "requires": { + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json5": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz", + "integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true + }, + "loader-runner": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", + "dev": true + }, + "loader-utils": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", + "dev": true + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", + "dev": true + } + } + }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "mississippi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "dev": true, + "requires": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^3.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + } + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "dev": true, + "requires": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "dev": true, + "optional": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "neo-async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", + "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "dev": true, + "requires": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "^1.0.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + } + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "once": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", + "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, + "p-limit": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz", + "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", + "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", + "dev": true + }, + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + }, + "parallel-transform": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", + "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", + "dev": true, + "requires": { + "cyclist": "^1.0.1", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + } + }, + "parse-asn1": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", + "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", + "dev": true, + "requires": { + "asn1.js": "^4.0.0", + "browserify-aes": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "pbkdf2": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", + "dev": true + }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "dev": true, + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + }, + "dependencies": { + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + } + } + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", + "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==", + "dev": true + } + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + }, + "dependencies": { + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + }, + "dependencies": { + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + } + } + } + } + }, + "pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "react": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react/-/react-16.13.1.tgz", + "integrity": "sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w==", + "dev": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2" + } + }, + "react-dom": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.13.1.tgz", + "integrity": "sha512-81PIMmVLnCNLO/fFOQxdQkvEq/+Hfpv24XNJfpyZhTRfO0QcmQIF/PgCa1zCOj2w1hrn12MFLyaJ/G0+Mxtfag==", + "dev": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.19.1" + } + }, + "react-is": { + "version": "16.8.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.2.tgz", + "integrity": "sha512-D+NxhSR2HUCjYky1q1DwpNUD44cDpUXzSmmFyC3ug1bClcU/iDNy0YNn1iwme28fn+NFhpA13IndOd42CrFb+Q==", + "dev": true + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "resolve": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", + "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "dev": true, + "requires": { + "resolve-from": "^3.0.0" + } + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "dependencies": { + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + } + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "dev": true, + "requires": { + "aproba": "^1.1.1" + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "dev": true + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "scheduler": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", + "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", + "dev": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", + "dev": true + }, + "serialize-javascript": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", + "integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "dev": true, + "requires": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.17", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.17.tgz", + "integrity": "sha512-bwdKOBZ5L0gFRh4KOxNap/J/MpvX9Yxsq9lFDx65s3o7F/NiHy7JRaGIS8MwW6tZPAq9UXE207Il0cfcb5yu/Q==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "ssri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1" + } + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-each": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", + "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "tapable": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.1.tgz", + "integrity": "sha512-9I2ydhj8Z9veORCw5PRm4u9uebCn0mcCa6scWoNcbZ6dAtoo2618u9UUzxgmsCOreJpqDDuv61LvwofW7hLcBA==", + "dev": true + }, + "terser": { + "version": "4.6.11", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.6.11.tgz", + "integrity": "sha512-76Ynm7OXUG5xhOpblhytE7X58oeNSmC8xnNhjWVo8CksHit0U0kO4hfNbPrrYwowLWFgM2n9L176VNx2QaHmtA==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "terser-webpack-plugin": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz", + "integrity": "sha512-QMxecFz/gHQwteWwSo5nTc6UaICqN1bMedC5sMtUc7y3Ha3Q8y6ZO0iCR8pq4RJC8Hjf0FEPEHZqcMB/+DFCrA==", + "dev": true, + "requires": { + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", + "is-wsl": "^1.1.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^2.1.2", + "source-map": "^0.6.1", + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", + "worker-farm": "^1.7.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "timers-browserify": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", + "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", + "dev": true, + "requires": { + "setimmediate": "^1.0.4" + } + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "tslib": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz", + "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==", + "dev": true + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dev": true, + "requires": { + "unique-slug": "^2.0.0" + } + }, + "unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + } + } + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "v8-compile-cache": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz", + "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==", + "dev": true + }, + "vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true + }, + "watchpack": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.1.tgz", + "integrity": "sha512-+IF9hfUFOrYOOaKyfaI7h7dquUIOgyEMoQMLA7OP5FxegKA2+XdXThAZ9TU2kucfhDH7rfMHs1oPYziVGWRnZA==", + "dev": true, + "requires": { + "chokidar": "^2.1.8", + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0" + } + }, + "webpack": { + "version": "4.43.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.43.0.tgz", + "integrity": "sha512-GW1LjnPipFW2Y78OOab8NJlCflB7EFskMih2AHdvjbpKMeDJqEgSx24cXXXiPS65+WSwVyxtDsJH6jGX2czy+g==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/wasm-edit": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "acorn": "^6.4.1", + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^4.1.0", + "eslint-scope": "^4.0.3", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^2.4.0", + "loader-utils": "^1.2.3", + "memory-fs": "^0.4.1", + "micromatch": "^3.1.10", + "mkdirp": "^0.5.3", + "neo-async": "^2.6.1", + "node-libs-browser": "^2.2.1", + "schema-utils": "^1.0.0", + "tapable": "^1.1.3", + "terser-webpack-plugin": "^1.4.3", + "watchpack": "^1.6.1", + "webpack-sources": "^1.4.1" + }, + "dependencies": { + "tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "dev": true + } + } + }, + "webpack-cli": { + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.12.tgz", + "integrity": "sha512-NVWBaz9k839ZH/sinurM+HcDvJOTXwSjYp1ku+5XKeOC03z8v5QitnK/x+lAxGXFyhdayoIf/GOpv85z3/xPag==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "cross-spawn": "^6.0.5", + "enhanced-resolve": "^4.1.1", + "findup-sync": "^3.0.0", + "global-modules": "^2.0.0", + "import-local": "^2.0.0", + "interpret": "^1.4.0", + "loader-utils": "^1.4.0", + "supports-color": "^6.1.0", + "v8-compile-cache": "^2.1.1", + "yargs": "^13.3.2" + }, + "dependencies": { + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, + "enhanced-resolve": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.2.0.tgz", + "integrity": "sha512-S7eiFb/erugyd1rLb6mQ3Vuq+EXHv5cpCkNqqIkYkBgN2QdFnyCZzFBleqwGEx4lgNGYij81BWnCrFNK7vxvjQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.5.0", + "tapable": "^1.0.0" + } + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + }, + "memory-fs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", + "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dev": true, + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "worker-farm": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", + "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", + "dev": true, + "requires": { + "errno": "~0.1.7" + }, + "dependencies": { + "errno": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", + "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "dev": true, + "requires": { + "prr": "~1.0.1" + } + } + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } +} diff --git a/src/React.Core/package.json b/src/React.Core/package.json new file mode 100644 index 000000000..bfe3c8db2 --- /dev/null +++ b/src/React.Core/package.json @@ -0,0 +1,17 @@ +{ + "version": "1.0.0", + "name": "React.Core", + "private": true, + "scripts": { + "build": "webpack" + }, + "devDependencies": { + "@babel/core": "7.8.7", + "@babel/standalone": "7.8.8", + "prop-types": "15.7.2", + "react": "16.13.1", + "react-dom": "16.13.1", + "webpack": "4.43.0", + "webpack-cli": "3.3.12" + } +} diff --git a/src/React.Core/webpack.config.js b/src/React.Core/webpack.config.js new file mode 100644 index 000000000..2afbd5295 --- /dev/null +++ b/src/React.Core/webpack.config.js @@ -0,0 +1,36 @@ +const path = require('path'); + +module.exports = [ + { + entry: './Resources/react.js', + output: { + filename: 'react.generated.js', + globalObject: 'this', + path: path.resolve(__dirname, 'Resources/'), + libraryTarget: 'this', + }, + mode: 'development', + performance: { + hints: false, + }, + }, + { + entry: { + react: './Resources/react.js', + babel: './Resources/babel.js', + }, + output: { + filename: '[name].generated.min.js', + globalObject: 'this', + path: path.resolve(__dirname, 'Resources/'), + libraryTarget: 'this', + }, + mode: 'production', + node: { + fs: 'empty', + }, + performance: { + hints: false, + }, + }, +]; diff --git a/src/React.JavaScriptEngine.VroomJs/AssemblyRegistration.cs b/src/React.JavaScriptEngine.VroomJs/AssemblyRegistration.cs deleted file mode 100644 index d54050004..000000000 --- a/src/React.JavaScriptEngine.VroomJs/AssemblyRegistration.cs +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -using React.TinyIoC; - -namespace React.JavaScriptEngine.VroomJs -{ - /// - /// Handles registration of VroomJS for ReactJS.NET. - /// - public class AssemblyRegistration : IAssemblyRegistration - { - /// - /// Registers components in the React IoC container - /// - /// Container to register components in - public void Register(TinyIoCContainer container) - { - // Only supported on Linux or Mac - if (!VroomJsUtils.IsEnvironmentSupported()) - { - return; - } - - VroomJsUtils.EnsureEngineFunctional(); - container.Register(new JavaScriptEngineFactory.Registration - { - Factory = () => new VroomJsEngine(), - Priority = 10 - }, "VroomJs"); - } - } -} diff --git a/src/React.JavaScriptEngine.VroomJs/Properties/AssemblyInfo.cs b/src/React.JavaScriptEngine.VroomJs/Properties/AssemblyInfo.cs deleted file mode 100644 index 89a82c5e0..000000000 --- a/src/React.JavaScriptEngine.VroomJs/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -using System.Reflection; -using System.Runtime.InteropServices; - -[assembly: AssemblyTitle("React.JavaScriptEngine.VroomJs")] -[assembly: AssemblyDescription("VroomJs JavaScript library for ReactJS.NET")] -[assembly: ComVisible(false)] -[assembly: Guid("3c246f9a-d9ae-4a43-86fb-00d4591e2a38")] \ No newline at end of file diff --git a/src/React.JavaScriptEngine.VroomJs/React.JavaScriptEngine.VroomJs.csproj b/src/React.JavaScriptEngine.VroomJs/React.JavaScriptEngine.VroomJs.csproj deleted file mode 100644 index f445dd9a9..000000000 --- a/src/React.JavaScriptEngine.VroomJs/React.JavaScriptEngine.VroomJs.csproj +++ /dev/null @@ -1,96 +0,0 @@ - - - - - Debug - AnyCPU - {B4A5902A-70E2-4FA4-817D-DCC78D31E9B9} - Library - Properties - React.JavaScriptEngine.VroomJs - React.JavaScriptEngine.VroomJs - v4.0 - 512 - - - true - full - false - ..\..\bin\Debug\React.JavaScriptEngine.VroomJs\ - DEBUG;TRACE - prompt - 4 - ..\..\bin\Debug\React.JavaScriptEngine.VroomJs\React.JavaScriptEngine.VroomJs.xml - 1607 - - - pdbonly - true - ..\..\bin\Release\React.JavaScriptEngine.VroomJs\ - TRACE - prompt - 4 - ..\..\bin\Release\React.JavaScriptEngine.VroomJs\React.JavaScriptEngine.VroomJs.xml - true - 1607 - - - true - - - ..\Key.snk - - - - ..\packages\JavaScriptEngineSwitcher.Core.1.1.3\lib\net40\JavaScriptEngineSwitcher.Core.dll - - - ..\packages\Newtonsoft.Json.5.0.4\lib\net40\Newtonsoft.Json.dll - - - - - - ..\..\lib\VroomJs.dll - True - - - - - Properties\SharedAssemblyInfo.cs - - - Properties\SharedAssemblyVersionInfo.cs - - - - - - - - - - - - - - {d0cc8a22-cee6-485c-924b-1f94426fea59} - React - - - - - - - - - - - - \ No newline at end of file diff --git a/src/React.JavaScriptEngine.VroomJs/React.JavaScriptEngine.VroomJs.nutrans b/src/React.JavaScriptEngine.VroomJs/React.JavaScriptEngine.VroomJs.nutrans deleted file mode 100644 index a88887ad4..000000000 --- a/src/React.JavaScriptEngine.VroomJs/React.JavaScriptEngine.VroomJs.nutrans +++ /dev/null @@ -1,25 +0,0 @@ - - - - - ReactJS.NET - Mono Support - Mono support for ReactJS.NET, using VroomJs and V8. Allows you to use ReactJS.NET on Linux and Mac OS X. Install this package in addition to the regular ReactJS.NET packages (eg. React.Web.Mvc4 for ASP.NET MVC 4 integration). -Please refer to project site (http://reactjs.net/) for more details, usage examples and sample code. - - Mono (Linux and Mac OS X) support for ReactJS.NET - asp.net mvc asp jquery javascript js react facebook reactjs mono linux mac macos v8 - - - - - - diff --git a/src/React.JavaScriptEngine.VroomJs/VroomJsEngine.cs b/src/React.JavaScriptEngine.VroomJs/VroomJsEngine.cs deleted file mode 100644 index 2d6e04868..000000000 --- a/src/React.JavaScriptEngine.VroomJs/VroomJsEngine.cs +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -using System; -using System.Linq; -using JavaScriptEngineSwitcher.Core; -using Newtonsoft.Json; -using VroomJs; -using OriginalJsEngine = VroomJs.JsEngine; -using OriginalJsException = VroomJs.JsException; - -namespace React.JavaScriptEngine.VroomJs -{ - /// - /// Basic implementation of a VroomJs JavaScript engine for JavaScriptEngineSwitcher. - /// Connects to the V8 JavaScript engine on Linux and Mac OS X. - /// - public class VroomJsEngine : JsEngineBase - { - /// - /// The VroomJs engine. One engine is shared for the whole app, and separate contexts are - /// used for each instance of this class. - /// - private static readonly Lazy _jsEngine = - new Lazy(() => new OriginalJsEngine()); - - /// - /// The V8 context - /// - private readonly JsContext _context; - - /// - /// Name of JavaScript engine - /// - public override string Name - { - get { return "VroomJs JavaScript engine"; } - } - - /// - /// Version of original JavaScript engine - /// - public override string Version - { - get { return "86f8558d (Aug 17, 2013)"; } - } - - /// - /// The VroomJs engine. One engine is shared for the whole app, and separate contexts are - /// used for each instance of this class. - /// - private OriginalJsEngine Engine - { - get { return _jsEngine.Value; } - } - - /// - /// Constructs instance of adapter for VroomJs - /// - public VroomJsEngine() - { - try - { - // We use one engine with multiple contexts - _context = Engine.CreateContext(); - } - catch (Exception e) - { - - throw new JsEngineLoadException( - string.Format( - JavaScriptEngineSwitcher.Core.Resources.Strings.Runtime_JsEngineNotLoaded, - Name, - e.Message - ), - Name, - Version, - e - ); - } - } - - /// - /// Converts a VroomJs exception into a . - /// - /// VroomJs exception - /// JavaScriptEngineSwitcher exception - private JsRuntimeException ConvertJavaScriptExceptionToJsRuntimeException( - OriginalJsException jsException - ) - { - return new JsRuntimeException(jsException.Message, Name, Version) - { - Category = jsException.Type, - LineNumber = jsException.Line, - ColumnNumber = jsException.Column - }; - } - - /// - /// Evaluates the specified JavaScript expression - /// - /// Expression to evaluate - /// Result of the expression - protected override object InnerEvaluate(string expression) - { - try - { - return _context.Execute(expression); - } - catch (OriginalJsException ex) - { - throw ConvertJavaScriptExceptionToJsRuntimeException(ex); - } - } - - /// - /// Evaluates the specified JavaScript expression - /// - /// Expression to evaluate - /// Return type - /// Result of the expression - protected override T InnerEvaluate(string expression) - { - return (T) InnerEvaluate(expression); - } - - /// - /// Executes the specified JavaScript code - /// - /// Code to execute - protected override void InnerExecute(string code) - { - try - { - _context.Execute(code); - } - catch (OriginalJsException ex) - { - throw ConvertJavaScriptExceptionToJsRuntimeException(ex); - } - } - - /// - /// Calls the specified JavaScript function - /// - /// Function to call - /// Arguments to pass to function - /// Result of the function - protected override object InnerCallFunction(string functionName, params object[] args) - { - var code = string.Format( - "{0}({1})", - functionName, - string.Join(", ", args.Select(JsonConvert.SerializeObject)) - ); - - try - { - return _context.Execute(code); - } - catch (OriginalJsException ex) - { - throw ConvertJavaScriptExceptionToJsRuntimeException(ex); - } - } - - /// - /// Calls the specified JavaScript function - /// - /// Function to call - /// Arguments to pass to function - /// Return type of the function - /// Result of the function - protected override T InnerCallFunction(string functionName, params object[] args) - { - return (T) InnerCallFunction(functionName, args); - } - - /// - /// Determines if the specified variable has been set - /// - /// Name of the variable - /// true if the variable is defined - protected override bool InnerHasVariable(string variableName) - { - var code = string.Format("typeof {0} !== 'undefined'", variableName); - return InnerEvaluate(code); - } - - /// - /// Gets the value of the specified variable - /// - /// Variable to get value of - /// Value - protected override object InnerGetVariableValue(string variableName) - { - try - { - return _context.GetVariable(variableName); - } - catch (OriginalJsException ex) - { - throw ConvertJavaScriptExceptionToJsRuntimeException(ex); - } - } - - /// - /// Gets the value of the specified variable - /// - /// Variable to get value of - /// Type of the variable - /// Value - protected override T InnerGetVariableValue(string variableName) - { - return (T)InnerGetVariableValue(variableName); - } - - /// - /// Sets the value of the specified variable - /// - /// Variable to get value of - /// New value to set - /// Value - protected override void InnerSetVariableValue(string variableName, object value) - { - try - { - _context.SetVariable(variableName, value); - } - catch (OriginalJsException ex) - { - throw ConvertJavaScriptExceptionToJsRuntimeException(ex); - } - } - - /// - /// Deletes a variable - /// - /// Variable to delete - protected override void InnerRemoveVariable(string variableName) - { - var code = string.Format("{0} = undefined", variableName); - try - { - _context.Execute(code); - } - catch (OriginalJsException ex) - { - throw ConvertJavaScriptExceptionToJsRuntimeException(ex); - } - } - - /// - /// Releases resources used by this engine. - /// - public override void Dispose() - { - if (!_disposed) - { - _context.Dispose(); - _disposed = true; - } - } - } -} diff --git a/src/React.JavaScriptEngine.VroomJs/VroomJsInitialisationException.cs b/src/React.JavaScriptEngine.VroomJs/VroomJsInitialisationException.cs deleted file mode 100644 index 653c7e4b0..000000000 --- a/src/React.JavaScriptEngine.VroomJs/VroomJsInitialisationException.cs +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -using System; -using System.Runtime.Serialization; -using React.Exceptions; - -namespace React.JavaScriptEngine.VroomJs -{ - /// - /// Thrown when the JavaScript engine does not support JSX transformation - /// - [Serializable] - public class VroomJsInitialisationException : ReactException - { - /// - /// Initializes a new instance of the class. - /// - public VroomJsInitialisationException(string innerMessage) : - base(GetMessage(innerMessage)) { } - - /// - /// Used by deserialization - /// - protected VroomJsInitialisationException(SerializationInfo info, StreamingContext context) - : base(info, context) { } - - /// - /// Gets a message that describes the current exception. - /// - private static string GetMessage(string innerMessage) - { - return - "Failed to initialise VroomJs. This is most likely caused by the native library " + - "(libVroomJsNative.so) being out of date or your system lacking a compatible version of " + - "V8. Please run Mono with the `MONO_LOG_LEVEL=debug` environment variable for " + - "more debugging information. \n\n " + - "More details: " + innerMessage; - } - } -} diff --git a/src/React.JavaScriptEngine.VroomJs/VroomJsUtils.cs b/src/React.JavaScriptEngine.VroomJs/VroomJsUtils.cs deleted file mode 100644 index dcc93d987..000000000 --- a/src/React.JavaScriptEngine.VroomJs/VroomJsUtils.cs +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -using System; -using React.Exceptions; - -namespace React.JavaScriptEngine.VroomJs -{ - /// - /// Utility methods for VroomJs JavaScript engine - /// - public static class VroomJsUtils - { - /// - /// Determines if the current environment supports the VroomJs engine - /// - /// - public static bool IsEnvironmentSupported() - { - return Environment.OSVersion.Platform == PlatformID.Unix; - } - - /// - /// If the user is explicitly referencing this assembly, they probably want to use it. - /// Attempt to use the engine and throw an exception if it doesn't work. - /// - public static void EnsureEngineFunctional() - { - int result = 0; - try - { - using (var engine = new VroomJsEngine()) - { - result = engine.Evaluate("1 + 1"); - } - } - catch (Exception ex) - { - throw new VroomJsInitialisationException(ex.Message); - } - - if (result != 2) - { - throw new ReactException("Mathematics is broken. 1 + 1 = " + result); - } - } - } -} diff --git a/src/React.JavaScriptEngine.VroomJs/packages.config b/src/React.JavaScriptEngine.VroomJs/packages.config deleted file mode 100644 index 1f1ecd502..000000000 --- a/src/React.JavaScriptEngine.VroomJs/packages.config +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/React.JavaScriptEngine.VroomJs/readme.txt b/src/React.JavaScriptEngine.VroomJs/readme.txt deleted file mode 100644 index e8900a533..000000000 --- a/src/React.JavaScriptEngine.VroomJs/readme.txt +++ /dev/null @@ -1,31 +0,0 @@ -To use ReactJS.NET on Linux or Mac OS X, you need to compile VroomJs and V8. This can be -accomplished using the following shell commands: - -# Get a supported version of V8 -cd /usr/local/src/ -git clone https://github.com/v8/v8.git -cd v8 -git checkout 3.17 - -# Build V8 -make dependencies -make native werror=no library=shared soname_version=3.17.16.2 -j4 -cp out/native/lib.target/libv8.so.3.17.16.2 /usr/local/lib/ - -# Get ReactJS.NET's version of libvroomjs -cd /usr/local/src/ -git clone https://github.com/reactjs/react.net.git -cd react.net -git submodule update --init -cd lib/VroomJs/libvroomjs/ - -# Build libvroomjs -g++ jscontext.cpp jsengine.cpp managedref.cpp bridge.cpp jsscript.cpp -o libVroomJsNative.so -shared -L /usr/local/src/v8/out/native/lib.target/ -I /usr/local/src/v8/include/ -fPIC -Wl,--no-as-needed -l:/usr/local/lib/libv8.so.3.17.16.2 -cp libVroomJsNative.so /usr/local/lib/ -ldconfig - -If VroomJs fails to load, run Mono with the `MONO_LOG_LEVEL=debug` environment variable to get -more useful debugging information. Often, this occurs when Mono is unable to locate V8 (ie. it's -not in /usr/lib/ or /usr/local/lib/) - -For more information, please see the ReactJS.NET website at http://reactjs.net/ diff --git a/src/React.MSBuild/AssemblyBindingRedirect.cs b/src/React.MSBuild/AssemblyBindingRedirect.cs new file mode 100644 index 000000000..dade8e7e9 --- /dev/null +++ b/src/React.MSBuild/AssemblyBindingRedirect.cs @@ -0,0 +1,83 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Reflection; + +namespace React.MSBuild +{ + /// + /// Hacks around the fact that it's not possible to do assembly binding redirects in MSBuild. + /// + /// https://github.com/Microsoft/msbuild/issues/1309 + /// http://blog.slaks.net/2013-12-25/redirecting-assembly-loads-at-runtime/ + /// + public static class AssemblyBindingRedirect + { + /// + /// Redirects that have been configured + /// + private static readonly Dictionary _redirects = new Dictionary(); + + static AssemblyBindingRedirect() + { + // This is in a static constructor because it needs to run as early as possible + ConfigureRedirect("JavaScriptEngineSwitcher.Core"); + AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; + } + + /// + /// Enables assembly binding redirects + /// + public static void Enable() + { + // Intentionally empty. This is just meant to ensure the static constructor + // has run. + } + + /// + /// Configures a redirect for the specified assembly. Redirects to the version in the bin directory. + /// + /// Name of the assembly to redirect + private static void ConfigureRedirect(string name) + { + var currentAssemblyPath = Assembly.GetExecutingAssembly().Location; + var redirectAssemblyPath = Path.Combine( + Path.GetDirectoryName(currentAssemblyPath), + name + ".dll" + ); + + try + { + var realAssembly = Assembly.LoadFile(redirectAssemblyPath); + var version = realAssembly.GetName().Version; + _redirects[name] = version; + } + catch (Exception ex) + { + Trace.WriteLine("Warning: Could not determine version of " + name + " to use! " + ex.Message); + } + } + + /// + /// Overrides assembly resolution to redirect if necessary. + /// + private static Assembly ResolveAssembly(object sender, ResolveEventArgs args) + { + var requestedAssembly = new AssemblyName(args.Name); + + if (_redirects.ContainsKey(requestedAssembly.Name) && requestedAssembly.Version != _redirects[requestedAssembly.Name]) + { + requestedAssembly.Version = _redirects[requestedAssembly.Name]; + return Assembly.Load(requestedAssembly); + } + return null; + } + } +} diff --git a/src/React.MSBuild/AssemblyRegistration.cs b/src/React.MSBuild/AssemblyRegistration.cs index 8a777821f..e0accd796 100644 --- a/src/React.MSBuild/AssemblyRegistration.cs +++ b/src/React.MSBuild/AssemblyRegistration.cs @@ -1,10 +1,8 @@ /* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ using System.Diagnostics; diff --git a/src/React.MSBuild/Content/TransformBabel.proj b/src/React.MSBuild/Content/TransformBabel.proj new file mode 100644 index 000000000..06d7d91fa --- /dev/null +++ b/src/React.MSBuild/Content/TransformBabel.proj @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/React.MSBuild/Content/TransformJsx.proj b/src/React.MSBuild/Content/TransformJsx.proj deleted file mode 100644 index d38b16bfb..000000000 --- a/src/React.MSBuild/Content/TransformJsx.proj +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/src/React.MSBuild/MSBuildHost.cs b/src/React.MSBuild/MSBuildHost.cs index ca8e852cf..3562fcec9 100644 --- a/src/React.MSBuild/MSBuildHost.cs +++ b/src/React.MSBuild/MSBuildHost.cs @@ -1,14 +1,12 @@ /* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ - using System; using System.Diagnostics; +using System.Reflection; namespace React.MSBuild { @@ -36,6 +34,8 @@ public static bool EnsureInitialized() /// private static bool Initialize() { + AssemblyBindingRedirect.Enable(); + // All "per-request" registrations should be singletons in MSBuild, since there's no // such thing as a "request" Initializer.Initialize(requestLifetimeRegistration: registration => registration.AsSingleton()); diff --git a/src/React.MSBuild/Properties/AssemblyInfo.cs b/src/React.MSBuild/Properties/AssemblyInfo.cs index dda39fdae..01e4bf7ce 100644 --- a/src/React.MSBuild/Properties/AssemblyInfo.cs +++ b/src/React.MSBuild/Properties/AssemblyInfo.cs @@ -1,10 +1,8 @@ /* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ using System.Reflection; @@ -13,4 +11,4 @@ [assembly: AssemblyTitle("React.MSBuild")] [assembly: AssemblyDescription("MSBuild integration for ReactJS.NET")] [assembly: ComVisible(false)] -[assembly: Guid("6b314671-5ea3-47ea-bdd8-7d75b1b1d9fa")] \ No newline at end of file +[assembly: Guid("6b314671-5ea3-47ea-bdd8-7d75b1b1d9fa")] diff --git a/src/React.MSBuild/React.MSBuild.csproj b/src/React.MSBuild/React.MSBuild.csproj index e154ddaca..bc440065e 100644 --- a/src/React.MSBuild/React.MSBuild.csproj +++ b/src/React.MSBuild/React.MSBuild.csproj @@ -1,76 +1,57 @@ - - - + + - Debug - AnyCPU - {AF531A37-B93F-4113-9C2C-4DB28064B926} - Library - Properties - React.MSBuild + An MSBuild task to transpile JavaScript via Babel. + Copyright 2014-Present Facebook, Inc + ReactJS.NET - Babel for MSBuild + Daniel Lo Nigro + net40 + true React.MSBuild - v4.0 - 512 - - - true - full - false - ..\..\bin\Debug\React.MSBuild\ - DEBUG;TRACE - prompt - 4 - 1607 - ..\..\bin\Debug\React.MSBuild\React.MSBuild.XML - - - pdbonly - true - ..\..\bin\Release\React.MSBuild\ - TRACE - prompt - 4 - true - 1607 - ..\..\bin\Release\React.MSBuild\React.MSBuild.XML + ../key.snk + true + true + React.MSBuild + asp.net;mvc;asp;jquery;javascript;js;react;facebook;reactjs;babel;msbuild + logo_64.png + https://github.com/reactjs/react.net + https://github.com/reactjs/React.NET#licence + true + true + $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb + false + true + snupkg + - - - - - + + + + true + tools\ + + + true + content\ + + + - - Properties\SharedAssemblyInfo.cs - - - Properties\SharedAssemblyVersionInfo.cs - - - - - + + + - - {d0cc8a22-cee6-485c-924b-1f94426fea59} - React - + - - - - - + + + + + + - - - \ No newline at end of file + + diff --git a/src/React.MSBuild/React.MSBuild.nutrans b/src/React.MSBuild/React.MSBuild.nutrans deleted file mode 100644 index 1653b88ce..000000000 --- a/src/React.MSBuild/React.MSBuild.nutrans +++ /dev/null @@ -1,24 +0,0 @@ - - - - - React.MSBuild - ReactJS.NET - JSX for MSBuild - Allows you to compile JSX to JavaScript via an MSBuild task - asp.net mvc asp jquery javascript js react facebook reactjs msbuild - - - - - - - \ No newline at end of file diff --git a/src/React.MSBuild/TransformJsx.cs b/src/React.MSBuild/TransformBabel.cs similarity index 51% rename from src/React.MSBuild/TransformJsx.cs rename to src/React.MSBuild/TransformBabel.cs index f9f5c72d4..8e79c4e15 100644 --- a/src/React.MSBuild/TransformJsx.cs +++ b/src/React.MSBuild/TransformBabel.cs @@ -1,23 +1,23 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. +/* + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ using System.Diagnostics; using System.IO; +using JavaScriptEngineSwitcher.Core; +using JavaScriptEngineSwitcher.Msie; using Microsoft.Build.Framework; using Microsoft.Build.Utilities; namespace React.MSBuild { /// - /// MSBuild task that handles transforming JSX to JavaScript + /// MSBuild task that handles transforming JavaScript via Babel /// - public class TransformJsx : Task + public class TransformBabel : Task { /// /// The ReactJS.NET environment @@ -25,16 +25,15 @@ public class TransformJsx : Task private IReactEnvironment _environment; /// - /// Directory to process JSX files in. All subdirectories will be searched. + /// Directory to process JavaScript files in. All subdirectories will be searched. /// [Required] public string SourceDir { get; set; } /// - /// A value indicating if es6 syntax should be rewritten. + /// The file extension pattern of the JavaScript files to transpile. Optional, defaults to *.jsx /// - /// true if support for es6 syntax should be rewritten. - public bool UseHarmony { get; set; } + public string FileExtensionPattern { get; set; } = "*.jsx"; /// /// Executes the task. @@ -44,14 +43,18 @@ public override bool Execute() { MSBuildHost.EnsureInitialized(); var config = React.AssemblyRegistration.Container.Resolve(); - config.UseHarmony = UseHarmony; + config + .SetReuseJavaScriptEngines(false); - _environment = React.AssemblyRegistration.Container.Resolve(); + JsEngineSwitcher.Current.DefaultEngineName = MsieJsEngine.EngineName; + JsEngineSwitcher.Current.EngineFactories.AddMsie(); - Log.LogMessage("Starting TransformJsx"); + _environment = ReactEnvironment.Current; + + Log.LogMessage("Starting Babel transform"); var stopwatch = Stopwatch.StartNew(); var result = ExecuteInternal(); - Log.LogMessage("TransformJsx completed in {0}", stopwatch.Elapsed); + Log.LogMessage("Babel transform completed in {0}", stopwatch.Elapsed); return result; } @@ -61,12 +64,12 @@ public override bool Execute() /// true on success private bool ExecuteInternal() { - var files = Directory.EnumerateFiles(SourceDir, "*.jsx", SearchOption.AllDirectories); + var files = Directory.EnumerateFiles(SourceDir, FileExtensionPattern, SearchOption.AllDirectories); foreach (var path in files) { var relativePath = path.Substring(SourceDir.Length + 1); Log.LogMessage(" -> Processing {0}", relativePath); - _environment.JsxTransformer.TransformAndSaveJsxFile(path); + _environment.Babel.TransformAndSaveFile(path); } return true; diff --git a/src/React.MSBuild/tools/install.ps1 b/src/React.MSBuild/tools/install.ps1 index 6b50dde81..5ecccd106 100644 --- a/src/React.MSBuild/tools/install.ps1 +++ b/src/React.MSBuild/tools/install.ps1 @@ -30,8 +30,8 @@ function Get-MSBuildProject { $project = Get-Project $buildProject = Get-MSBuildProject -$target = $buildProject.Xml.AddTarget("TransformJsx") +$target = $buildProject.Xml.AddTarget("TransformBabel") $target.AfterTargets = "Build" $task = $target.AddTask("Exec") -$task.SetParameter("Command", '"$(msbuildtoolspath)\msbuild.exe" $(ProjectDirectory)TransformJsx.proj /p:OutputPath=$(OutputPath) /nr:false') +$task.SetParameter("Command", '"$(msbuildtoolspath)\msbuild.exe" $(ProjectDirectory)TransformBabel.proj /p:OutputPath=$(OutputPath) /nr:false') $project.Save() \ No newline at end of file diff --git a/src/React.MSBuild/tools/uninstall.ps1 b/src/React.MSBuild/tools/uninstall.ps1 index fea4c5d50..2de76b9f5 100644 --- a/src/React.MSBuild/tools/uninstall.ps1 +++ b/src/React.MSBuild/tools/uninstall.ps1 @@ -31,7 +31,7 @@ function Get-MSBuildProject { $project = Get-Project $buildProject = Get-MSBuildProject -$existingImports = $buildProject.Xml.Targets | where {$_.Name -eq "TransformJsx"} +$existingImports = $buildProject.Xml.Targets | where {$_.Name -eq "TransformBabel"} foreach ($import in $existingImports) { $buildProject.Xml.RemoveChild($import) } diff --git a/src/React.Owin/AssemblyRegistration.cs b/src/React.Owin/AssemblyRegistration.cs new file mode 100644 index 000000000..6cb1040be --- /dev/null +++ b/src/React.Owin/AssemblyRegistration.cs @@ -0,0 +1,28 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using React.TinyIoC; + +namespace React.Owin +{ + /// + /// Handles registration of ReactJS.NET components that are only applicable + /// when used with Owin. + /// + public class AssemblyRegistration : IAssemblyRegistration + { + /// + /// Registers components in the React IoC container + /// + /// Container to register components in + public void Register(TinyIoCContainer container) + { + container.Register(); + container.Register(); + } + } +} diff --git a/src/React.Owin/BabelFileExtensions.cs b/src/React.Owin/BabelFileExtensions.cs new file mode 100644 index 000000000..675db1df5 --- /dev/null +++ b/src/React.Owin/BabelFileExtensions.cs @@ -0,0 +1,25 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using Owin; + +namespace React.Owin +{ + /// + /// Extensions for BabelFileMiddleware. + /// + public static class BabelFileExtensions + { + /// + /// Enables serving JavaScript files compiled via Babel. + /// + public static IAppBuilder UseBabel(this IAppBuilder builder, BabelFileOptions options = null) + { + return builder.Use(options ?? new BabelFileOptions()); + } + } +} diff --git a/src/React.Owin/BabelFileMiddleware.cs b/src/React.Owin/BabelFileMiddleware.cs new file mode 100644 index 000000000..08e29899b --- /dev/null +++ b/src/React.Owin/BabelFileMiddleware.cs @@ -0,0 +1,89 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +using Microsoft.Owin.StaticFiles; + +namespace React.Owin +{ + /// + /// Enables serving static JavaScript files compiled via Babel. Wraps around StaticFileMiddleware. + /// + public class BabelFileMiddleware + { + private readonly Func, Task> _next; + private readonly BabelFileOptions _options; + + static BabelFileMiddleware() + { + // Assume that request will ask for the "per request" instances only once. + Initializer.Initialize(options => options.AsMultiInstance()); + } + + /// + /// Creates a new instance of the BabelFileMiddleware. + /// + /// The next middleware in the pipeline. + /// The configuration options. + public BabelFileMiddleware(Func, Task> next, BabelFileOptions options) + { + if (next == null) + throw new ArgumentNullException("next"); + + _next = next; + + // Default values + _options = options ?? new BabelFileOptions(); + } + + /// + /// Processes a request to determine if it matches a known JSX file, and if so, serves it compiled to JavaScript. + /// + /// OWIN environment dictionary which stores state information about the request, response and relevant server state. + /// + public async Task Invoke(IDictionary environment) + { + // Create all "per request" instances + var reactEnvironment = ReactEnvironment.Current; + + var internalStaticMiddleware = CreateFileMiddleware(reactEnvironment.Babel); + await internalStaticMiddleware.Invoke(environment); + + // Clean up all "per request" instances + var disposable = reactEnvironment as IDisposable; + if (disposable != null) + disposable.Dispose(); + } + + /// + /// Creates the internal used to serve files. + /// + /// + /// + private StaticFileMiddleware CreateFileMiddleware(IBabel babel) + { + return new StaticFileMiddleware( + _next, + new StaticFileOptions() + { + ContentTypeProvider = _options.StaticFileOptions.ContentTypeProvider, + DefaultContentType = _options.StaticFileOptions.DefaultContentType, + OnPrepareResponse = _options.StaticFileOptions.OnPrepareResponse, + RequestPath = _options.StaticFileOptions.RequestPath, + ServeUnknownFileTypes = _options.StaticFileOptions.ServeUnknownFileTypes, + FileSystem = new BabelFileSystem( + babel, + _options.StaticFileOptions.FileSystem, + _options.Extensions + ) + }); + } + } +} diff --git a/src/React.Owin/EntryAssemblyFileSystem.cs b/src/React.Owin/EntryAssemblyFileSystem.cs new file mode 100644 index 000000000..7b193359d --- /dev/null +++ b/src/React.Owin/EntryAssemblyFileSystem.cs @@ -0,0 +1,57 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System.IO; +using System.Reflection; + +namespace React.Owin +{ + /// + /// Implements React file system that maps "~" into entry assembly location. + /// + internal class EntryAssemblyFileSystem : FileSystemBase + { + private readonly string _rootPath; + + /// + /// Initializes a new instance of the class, using the + /// entry assembly's location as the root directory. + /// + public EntryAssemblyFileSystem() + : this(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)) + { + } + + /// + /// Initializes a new instance of the class, using the + /// specified path as the root directory. + /// + /// The root path. + public EntryAssemblyFileSystem(string rootPath) + { + _rootPath = rootPath; + } + + /// + /// Converts a path from an application relative path (~/...) to a full filesystem path + /// + /// App-relative path of the file + /// Full path of the file + public override string MapPath(string relativePath) + { + if (relativePath.StartsWith("~")) + { + relativePath = relativePath + .Replace("~/", string.Empty) + .Replace('/', '\\'); + return Path.Combine(_rootPath, relativePath); + } + + return relativePath; + } + } +} diff --git a/src/React.Owin/Properties/AssemblyInfo.cs b/src/React.Owin/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..e4a8ce952 --- /dev/null +++ b/src/React.Owin/Properties/AssemblyInfo.cs @@ -0,0 +1,7 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("React.Owin")] +[assembly: AssemblyDescription("Owin integration for ReactJS.NET")] +[assembly: ComVisible(false)] +[assembly: Guid("7f0500f5-5a9f-48c9-b136-41cfd1787724")] \ No newline at end of file diff --git a/src/React.Owin/React.Owin.csproj b/src/React.Owin/React.Owin.csproj new file mode 100644 index 000000000..fff94081b --- /dev/null +++ b/src/React.Owin/React.Owin.csproj @@ -0,0 +1,51 @@ + + + + OWIN middleware for transpiling JavaScript via Babel. + Copyright 2014-Present Facebook, Inc + ReactJS.NET - Babel for OWIN + Daniel Lo Nigro + net45 + $(DefineConstants);OWIN + true + React.Owin + ../key.snk + true + true + React.Owin + asp.net;mvc;asp;jquery;javascript;js;react;facebook;reactjs;babel;owin + logo_64.png + https://github.com/reactjs/react.net + https://github.com/reactjs/React.NET#licence + true + true + $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb + false + true + snupkg + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/React.Web.Mvc3/Content/Views/web.config.transform b/src/React.Router.Mvc4/Content/Views/web.config.transform similarity index 79% rename from src/React.Web.Mvc3/Content/Views/web.config.transform rename to src/React.Router.Mvc4/Content/Views/web.config.transform index 4087d0d7b..c562609d3 100644 --- a/src/React.Web.Mvc3/Content/Views/web.config.transform +++ b/src/React.Router.Mvc4/Content/Views/web.config.transform @@ -2,7 +2,7 @@ - + diff --git a/src/React.Router.Mvc4/React.Router.Mvc4.csproj b/src/React.Router.Mvc4/React.Router.Mvc4.csproj new file mode 100644 index 000000000..88da61a2b --- /dev/null +++ b/src/React.Router.Mvc4/React.Router.Mvc4.csproj @@ -0,0 +1,59 @@ + + + + React Router support for ReactJS.NET. + Copyright 2014-Present Facebook, Inc + ReactJS.NET Router + Daniel Lo Nigro, Gunnar Már Óttarsson + net451 + true + React.Router.Mvc4 + $(DefineConstants);LEGACYASPNET + ../key.snk + true + true + React.Router.Mvc4 + asp.net;mvc;asp;javascript;js;react;facebook;reactjs;babel;router;react router + logo_64.png + https://github.com/reactjs/react.net + https://github.com/reactjs/React.NET#licence + true + true + $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb + false + true + snupkg + + + + + + + + true + content\ + + + + + + + + + + + + + + + + + + + + + + true + + + diff --git a/src/React.Router/ExecutionResult.cs b/src/React.Router/ExecutionResult.cs new file mode 100644 index 000000000..4145eac09 --- /dev/null +++ b/src/React.Router/ExecutionResult.cs @@ -0,0 +1,25 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +namespace React.Router +{ + /// + /// Contains the context object used during execution in addition to + /// the string result of rendering the React Router component. + /// + public class ExecutionResult + { + /// + /// String result of ReactDOMServer render of provided component. + /// + public string RenderResult { get; set; } + + /// + /// Context object used during JS engine execution. + /// + public RoutingContext Context { get; set; } + } +} diff --git a/src/React.Router/HtmlHelperExtensions.cs b/src/React.Router/HtmlHelperExtensions.cs new file mode 100644 index 000000000..076638b58 --- /dev/null +++ b/src/React.Router/HtmlHelperExtensions.cs @@ -0,0 +1,154 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System; + +#if LEGACYASPNET +using System.Web; +using HttpResponse = System.Web.HttpResponseBase; +using IHtmlHelper = System.Web.Mvc.HtmlHelper; +#else +using Microsoft.AspNetCore.Mvc.Rendering; +using IHtmlString = Microsoft.AspNetCore.Html.IHtmlContent; +using HttpResponse = Microsoft.AspNetCore.Http.HttpResponse; +using Microsoft.AspNetCore.Html; +#endif + +namespace React.Router +{ + /// + /// Render a React StaticRouter Component with context. + /// + public static class HtmlHelperExtensions + { + /// + /// Gets the React environment + /// + private static IReactEnvironment Environment + { + get + { + return ReactEnvironment.GetCurrentOrThrow; + } + } + + /// + /// Render a React StaticRouter Component with context object. + /// Can optionally be provided with a custom context handler to handle the various status codes. + /// + /// MVC Razor + /// Name of React Static Router component. Expose component globally to ReactJS.NET + /// Props to initialise the component with + /// F.x. from Request.Path. Used by React Static Router to determine context and routing. + /// Optional custom context handler, can be used instead of providing a Response object + /// HTML tag to wrap the component in. Defaults to <div> + /// ID to use for the container HTML tag. Defaults to an auto-generated ID + /// Skip rendering server-side and only output client-side initialisation code. Defaults to false + /// Skip rendering React specific data-attributes during server side rendering. Defaults to false + /// HTML class(es) to set on the container tag + /// containing the rendered markup for provided React Router component + [Obsolete("Please use Html.ReactRouter instead")] + public static IHtmlString ReactRouterWithContext( + this IHtmlHelper htmlHelper, + string componentName, + T props, + string path = null, + string htmlTag = null, + string containerId = null, + bool clientOnly = false, + bool serverOnly = false, + string containerClass = null, + Action contextHandler = null + ) + { + return ReactRouter(htmlHelper, componentName, props, path, htmlTag, containerId, clientOnly, serverOnly, containerClass, contextHandler); + } + + /// + /// Render a React StaticRouter Component with context object. + /// Can optionally be provided with a custom context handler to handle the various status codes. + /// + /// MVC Razor + /// Name of React Static Router component. Expose component globally to ReactJS.NET + /// Props to initialise the component with + /// F.x. from Request.Path. Used by React Static Router to determine context and routing. + /// Optional custom context handler, can be used instead of providing a Response object + /// HTML tag to wrap the component in. Defaults to <div> + /// ID to use for the container HTML tag. Defaults to an auto-generated ID + /// Skip rendering server-side and only output client-side initialisation code. Defaults to false + /// Skip rendering React specific data-attributes during server side rendering. Defaults to false + /// HTML class(es) to set on the container tag + /// Functions to call during component render + /// containing the rendered markup for provided React Router component + public static IHtmlString ReactRouter( + this IHtmlHelper htmlHelper, + string componentName, + T props, + string path = null, + string htmlTag = null, + string containerId = null, + bool clientOnly = false, + bool serverOnly = false, + string containerClass = null, + Action contextHandler = null, + IRenderFunctions renderFunctions = null + ) + { + try + { + var response = htmlHelper.ViewContext.HttpContext.Response; + var request = htmlHelper.ViewContext.HttpContext.Request; + var queryString = request != null && request.QueryString != null ? request.QueryString.ToString() : ""; + if (!string.IsNullOrWhiteSpace(queryString) && !queryString.StartsWith("?")) + { + queryString = $"?{queryString}"; + } + path = path ?? request.Path.ToString() + queryString; + + var reactComponent + = Environment.CreateRouterComponent( + componentName, + props, + path, + containerId, + clientOnly + ); + + if (!string.IsNullOrEmpty(htmlTag)) + { + reactComponent.ContainerTag = htmlTag; + } + if (!string.IsNullOrEmpty(containerClass)) + { + reactComponent.ContainerClass = containerClass; + } + + var executionResult = reactComponent.RenderRouterWithContext(clientOnly, serverOnly, renderFunctions); + + if (executionResult.Context?.status != null || executionResult.Context?.url != null) + { + // Use provided contextHandler + if (contextHandler != null) + { + contextHandler(response, executionResult.Context); + } + // Handle routing context internally + else + { + SetServerResponse.ModifyResponse(executionResult.Context, response); + } + } + + return new HtmlString(executionResult.RenderResult); + } + finally + { + Environment.ReturnEngineToPool(); + } + } + } +} diff --git a/src/React.Router/Properties/AssemblyInfo.cs b/src/React.Router/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..c2cbf2eae --- /dev/null +++ b/src/React.Router/Properties/AssemblyInfo.cs @@ -0,0 +1,7 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("React.Router")] +[assembly: AssemblyDescription("React Router support for ReactJS.NET")] +[assembly: ComVisible(false)] +[assembly: Guid("277850fc-8765-4042-945f-a50b8f2525a9")] diff --git a/src/React.Router/React.Router.csproj b/src/React.Router/React.Router.csproj new file mode 100644 index 000000000..672de81b9 --- /dev/null +++ b/src/React.Router/React.Router.csproj @@ -0,0 +1,55 @@ + + + + React Router support for ReactJS.NET. + Copyright 2014-Present Facebook, Inc + ReactJS.NET Router + Daniel Lo Nigro, Gunnar Már Óttarsson + netstandard2.0;netcoreapp3.0 + true + React.Router + ../key.snk + true + true + React.Router + asp.net;mvc;asp;javascript;js;react;facebook;reactjs;babel;router;react router + logo_64.png + https://github.com/reactjs/react.net + https://github.com/reactjs/React.NET#licence + true + true + $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb + false + true + snupkg + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + diff --git a/src/React.Router/ReactEnvironmentExtensions.cs b/src/React.Router/ReactEnvironmentExtensions.cs new file mode 100644 index 000000000..af0527b91 --- /dev/null +++ b/src/React.Router/ReactEnvironmentExtensions.cs @@ -0,0 +1,52 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +namespace React.Router +{ + /// + /// extension for rendering a React Router Component with context + /// + public static class ReactEnvironmentExtensions + { + /// + /// Create a React Router Component with context and add it to the list of components to render client side, + /// if applicable. + /// + /// Type of the props + /// React Environment + /// Name of the component + /// Props to use + /// F.x. from Request.Path. Used by React Static Router to determine context and routing. + /// ID to use for the container HTML tag. Defaults to an auto-generated ID + /// True if server-side rendering will be bypassed. Defaults to false. + /// + public static ReactRouterComponent CreateRouterComponent( + this IReactEnvironment env, + string componentName, + T props, + string path, + string containerId = null, + bool clientOnly = false + ) + { + var component = new ReactRouterComponent( + env, + AssemblyRegistration.Container.Resolve(), + AssemblyRegistration.Container.Resolve(), + componentName, + containerId, + path + ) + { + Props = props, + ClientOnly = clientOnly, + }; + + return env.CreateComponent(component, clientOnly) as ReactRouterComponent; + } + } +} diff --git a/src/React.Router/ReactRouterComponent.cs b/src/React.Router/ReactRouterComponent.cs new file mode 100644 index 000000000..ad53580f2 --- /dev/null +++ b/src/React.Router/ReactRouterComponent.cs @@ -0,0 +1,118 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System.IO; +using Newtonsoft.Json; +using React.RenderFunctions; + +namespace React.Router +{ + /// + /// Represents a React Router JavaScript component. + /// + public class ReactRouterComponent : ReactComponent + { + /// + /// F.x. from Request.Path. Used by React Static Router to determine context and routing. + /// + protected string _path; + + /// + /// Initialises a new instance of the class. + /// + /// The environment. + /// Site-wide configuration. + /// React Id generator. + /// Name of the component. + /// The ID of the container DIV for this component + /// F.x. from Request.Path. Used by React Static Router to determine context and routing. + public ReactRouterComponent( + IReactEnvironment environment, + IReactSiteConfiguration configuration, + IReactIdGenerator reactIdGenerator, + string componentName, + string containerId, + string path + ) : base(environment, configuration, reactIdGenerator, componentName, containerId) + { + _path = path; + } + + /// + /// Render a React StaticRouter Component with context object. + /// + /// Only renders component container. Used for client-side only rendering. Does not make sense in this context but included for consistency + /// Only renders the common HTML mark up and not any React specific data attributes. Used for server-side only rendering. + /// Functions to call during component render + /// Object containing HTML in string format and the React Router context object + public virtual ExecutionResult RenderRouterWithContext( + bool renderContainerOnly = false, + bool renderServerOnly = false, + IRenderFunctions renderFunctions = null + ) + { + var reactRouterFunctions = new ReactRouterFunctions(); + + var html = RenderHtml( + renderContainerOnly, + renderServerOnly, + renderFunctions: new ChainedRenderFunctions(renderFunctions, reactRouterFunctions) + ); + + return new ExecutionResult + { + RenderResult = html, + Context = JsonConvert.DeserializeObject(reactRouterFunctions.ReactRouterContext), + }; + } + + /// + /// Gets the JavaScript code to initialise the component + /// + /// JavaScript for component initialisation + protected override void WriteComponentInitialiser(TextWriter writer) + { + writer.Write("React.createElement("); + writer.Write(ComponentName); + writer.Write(", Object.assign("); + writer.Write(_serializedProps); + writer.Write(", { location: "); + writer.Write(JsonConvert.SerializeObject( + _path, + _configuration.JsonSerializerSettings)); + writer.Write(", context: context }))"); + } + + /// + /// Renders the JavaScript required to initialise this component client-side. This will + /// initialise the React component, which includes attach event handlers to the + /// server-rendered HTML. + /// Uses base Component initialiser. + /// Client side React Router does not need context nor explicit path parameter. + /// + /// JavaScript + public override void RenderJavaScript(TextWriter writer, bool waitForDOMContentLoad) + { + if (waitForDOMContentLoad) + { + writer.Write("window.addEventListener('DOMContentLoaded', function() {"); + } + + writer.Write( + !_configuration.UseServerSideRendering || ClientOnly ? "ReactDOM.render(" : "ReactDOM.hydrate("); + base.WriteComponentInitialiser(writer); + writer.Write(", document.getElementById(\""); + writer.Write(ContainerId); + writer.Write("\"))"); + + if (waitForDOMContentLoad) + { + writer.Write("});"); + } + } + } +} diff --git a/src/React.Router/ReactRouterException.cs b/src/React.Router/ReactRouterException.cs new file mode 100644 index 000000000..bf79e5fe9 --- /dev/null +++ b/src/React.Router/ReactRouterException.cs @@ -0,0 +1,47 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +using System; +using System.Runtime.Serialization; + +namespace React.Router +{ + /// + /// React Router Exception + /// +#if LEGACYASPNET + [Serializable] +#endif + public class ReactRouterException : Exception + { + /// + /// Initializes a new instance of the class. + /// + public ReactRouterException() : base() { } + /// + /// Initializes a new instance of the class. + /// + /// The message that describes the error. + public ReactRouterException(string message) : base(message) { } + /// + /// Initializes a new instance of the class. + /// + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + public ReactRouterException(string message, Exception innerException) + : base(message, innerException) { } + + +#if LEGACYASPNET + /// + /// Used by deserialization + /// + protected ReactRouterException(SerializationInfo info, StreamingContext context) + : base(info, context) + { } +#endif + } +} diff --git a/src/React.Router/ReactRouterFunctions.cs b/src/React.Router/ReactRouterFunctions.cs new file mode 100644 index 000000000..973f816d8 --- /dev/null +++ b/src/React.Router/ReactRouterFunctions.cs @@ -0,0 +1,35 @@ +using System; + +namespace React.Router +{ + /// + /// Render functions for React Router + /// + public class ReactRouterFunctions : RenderFunctionsBase + { + /// + /// The returned react router context, as a JSON string + /// A default value wards off deserialization exceptions + /// when server side rendering is disabled + /// + public string ReactRouterContext { get; private set; } = "{}"; + + /// + /// Implementation of PreRender + /// + /// + public override void PreRender(Func executeJs) + { + executeJs("var context = {};"); + } + + /// + /// Implementation of PostRender + /// + /// + public override void PostRender(Func executeJs) + { + ReactRouterContext = executeJs("JSON.stringify(context);"); + } + } +} diff --git a/src/React.Router/RoutingContext.cs b/src/React.Router/RoutingContext.cs new file mode 100644 index 000000000..402deae3c --- /dev/null +++ b/src/React.Router/RoutingContext.cs @@ -0,0 +1,26 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +namespace React.Router +{ + /// + /// Context object used during render of React Router component + /// + public class RoutingContext + { + /// + /// HTTP Status Code. + /// If present signifies that the given status code should be returned by server. + /// + public int? status { get; set; } + + /// + /// URL to redirect to. + /// If included this signals that React Router determined a redirect should happen. + /// + public string url { get; set; } + } +} diff --git a/src/React.Router/SetServerResponse.cs b/src/React.Router/SetServerResponse.cs new file mode 100644 index 000000000..fa8d8e62c --- /dev/null +++ b/src/React.Router/SetServerResponse.cs @@ -0,0 +1,68 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#if LEGACYASPNET +using HttpResponse = System.Web.HttpResponseBase; +#else +using HttpResponse = Microsoft.AspNetCore.Http.HttpResponse; +#endif + +namespace React.Router +{ + /// + /// Helper class that takes the values in the + /// to modify the servers response. + /// F.x. return an http status code of 404 not found + /// or redirect the client to a new URL. + /// + public static class SetServerResponse + { + /// + /// Uses the values in the to modify + /// the servers response. + /// F.x. return an http status code of 404 not found + /// or redirect the client to a new URL. + /// + /// + /// The routing context returned by React Router. + /// It contains new values for the server response. + /// + /// The response object to use. + public static void ModifyResponse(RoutingContext context, HttpResponse Response) + { + var statusCode = context.status ?? 302; + + // 300-399 + if (statusCode >= 300 && statusCode < 400) + { + if (!string.IsNullOrEmpty(context.url)) + { + if (statusCode == 301) + { +#if LEGACYASPNET + Response.RedirectPermanent(context.url); +#else + Response.Redirect(context.url, true); +#endif + } + else // 302 and all others + { + Response.Redirect(context.url); + } + } + else + { + throw new ReactRouterException("Router requested redirect but no url provided."); + } + } + else + { + Response.StatusCode = statusCode; + } + } + } +} diff --git a/src/React.Sample.Cassette/App_Start/ReactConfig.cs b/src/React.Sample.Cassette/App_Start/ReactConfig.cs new file mode 100644 index 000000000..9b25c12d0 --- /dev/null +++ b/src/React.Sample.Cassette/App_Start/ReactConfig.cs @@ -0,0 +1,27 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using JavaScriptEngineSwitcher.Core; +using JavaScriptEngineSwitcher.Msie; + +[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(React.Sample.Mvc4.ReactConfig), "Configure")] + +namespace React.Sample.Mvc4 +{ + public static class ReactConfig + { + public static void Configure() + { + ReactSiteConfiguration.Configuration + .SetReuseJavaScriptEngines(true) + .AddScript("~/Content/Sample.jsx"); + + JsEngineSwitcher.Current.DefaultEngineName = MsieJsEngine.EngineName; + JsEngineSwitcher.Current.EngineFactories.AddMsie(); + } + } +} diff --git a/src/React.Sample.Cassette/Cassette.targets b/src/React.Sample.Cassette/Cassette.targets index 124c93f89..98fc928c6 100644 --- a/src/React.Sample.Cassette/Cassette.targets +++ b/src/React.Sample.Cassette/Cassette.targets @@ -6,7 +6,7 @@ - + - \ No newline at end of file + diff --git a/src/React.Sample.Cassette/CassetteConfiguration.cs b/src/React.Sample.Cassette/CassetteConfiguration.cs index 0e15eaac7..88943fed1 100644 --- a/src/React.Sample.Cassette/CassetteConfiguration.cs +++ b/src/React.Sample.Cassette/CassetteConfiguration.cs @@ -1,10 +1,8 @@ /* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ using Cassette; @@ -27,4 +25,4 @@ public void Configure(BundleCollection bundles) bundles.Add("main.js", "Content/Sample.jsx"); } } -} \ No newline at end of file +} diff --git a/src/React.Sample.Cassette/Content/Sample.css b/src/React.Sample.Cassette/Content/Sample.css index a7cff6b7f..b02c980ca 100644 --- a/src/React.Sample.Cassette/Content/Sample.css +++ b/src/React.Sample.Cassette/Content/Sample.css @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Facebook, Inc. + * Copyright (c) 2014-Present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the @@ -20,4 +20,4 @@ body { .commentList li { border-bottom: 1px solid #999; padding: 0.5em 0; -} \ No newline at end of file +} diff --git a/src/React.Sample.Cassette/Content/Sample.jsx b/src/React.Sample.Cassette/Content/Sample.jsx index f09cd14af..ffaa668eb 100644 --- a/src/React.Sample.Cassette/Content/Sample.jsx +++ b/src/React.Sample.Cassette/Content/Sample.jsx @@ -1,28 +1,27 @@ /** - * Copyright (c) 2014, Facebook, Inc. + * Copyright (c) 2014-Present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant + * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. - * - * @jsx React.DOM */ -var CommentsBox = React.createClass({ - propTypes: { - initialComments: React.PropTypes.array.isRequired, - commentsPerPage: React.PropTypes.number.isRequired - }, - getInitialState: function() { - return { - comments: this.props.initialComments, - page: 1, - hasMore: true, - loadingMore: false - }; - }, - loadMoreClicked: function(evt) { + +class CommentsBox extends React.Component { + static propTypes = { + initialComments: PropTypes.array.isRequired, + commentsPerPage: PropTypes.number.isRequired + }; + + state = { + comments: this.props.initialComments, + page: 1, + hasMore: true, + loadingMore: false + }; + + loadMoreClicked = (evt) => { var nextPage = this.state.page + 1; this.setState({ page: nextPage, @@ -41,9 +40,10 @@ var CommentsBox = React.createClass({ }); }.bind(this); xhr.send(); - return false; - }, - render: function() { + evt.preventDefault(); + }; + + render() { var commentNodes = this.state.comments.map(function (comment) { return {comment.Text}; }); @@ -57,8 +57,9 @@ var CommentsBox = React.createClass({ {this.renderMoreLink()} ); - }, - renderMoreLink: function() { + } + + renderMoreLink = () => { if (this.state.loadingMore) { return Loading...; } else if (this.state.hasMore) { @@ -70,14 +71,15 @@ var CommentsBox = React.createClass({ } else { return No more comments; } - } -}); + }; +} + +class Comment extends React.Component { + static propTypes = { + author: PropTypes.object.isRequired + }; -var Comment = React.createClass({ - propTypes: { - author: React.PropTypes.object.isRequired - }, - render: function() { + render() { return (
  • @@ -86,13 +88,14 @@ var Comment = React.createClass({
  • ); } -}); +} -var Avatar = React.createClass({ - propTypes: { - author: React.PropTypes.object.isRequired - }, - render: function() { +class Avatar extends React.Component { + static propTypes = { + author: PropTypes.object.isRequired + }; + + render() { return ( ); - }, - getPhotoUrl: function(author) { - return 'http://graph.facebook.com/' + author.Facebook + '/picture'; } -}); \ No newline at end of file + + getPhotoUrl = (author) => { + return 'https://avatars.githubusercontent.com/' + author.GithubUsername + '?s=50'; + }; +} diff --git a/src/React.Sample.Cassette/Global.asax.cs b/src/React.Sample.Cassette/Global.asax.cs index 23c337bea..fa8831cd9 100644 --- a/src/React.Sample.Cassette/Global.asax.cs +++ b/src/React.Sample.Cassette/Global.asax.cs @@ -1,12 +1,11 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. +/* + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ +using System.Web.Hosting; using System.Web.Mvc; using System.Web.Routing; using React.Sample.Mvc4; @@ -19,10 +18,29 @@ public class MvcApplication : System.Web.HttpApplication { protected void Application_Start() { + Initializer.Initialize(registration => registration.AsSingleton()); + var container = React.AssemblyRegistration.Container; + + container.Register(); + container.Register(); + AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); } + + private class AspNetFileSystem : FileSystemBase + { + /// + /// Converts a path from an application relative path (~/...) to a full filesystem path + /// + /// App-relative path of the file + /// Full path of the file + public override string MapPath(string relativePath) + { + return HostingEnvironment.MapPath(relativePath); + } + } } -} \ No newline at end of file +} diff --git a/src/React.Sample.Cassette/Properties/AssemblyInfo.cs b/src/React.Sample.Cassette/Properties/AssemblyInfo.cs index ba3b48430..6537a92bd 100644 --- a/src/React.Sample.Cassette/Properties/AssemblyInfo.cs +++ b/src/React.Sample.Cassette/Properties/AssemblyInfo.cs @@ -1,10 +1,8 @@ /* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ using System.Reflection; @@ -13,4 +11,4 @@ [assembly: AssemblyTitle("React.Sample.Cassette")] [assembly: AssemblyDescription("Cassette + MVC 4 sample for ReactJS.NET")] [assembly: ComVisible(false)] -[assembly: Guid("595d5716-a9b7-463e-a8f7-0536d7733bd2")] \ No newline at end of file +[assembly: Guid("595d5716-a9b7-463e-a8f7-0536d7733bd2")] diff --git a/src/React.Sample.Cassette/React.Sample.Cassette.csproj b/src/React.Sample.Cassette/React.Sample.Cassette.csproj index 301eecf7d..674629b37 100644 --- a/src/React.Sample.Cassette/React.Sample.Cassette.csproj +++ b/src/React.Sample.Cassette/React.Sample.Cassette.csproj @@ -20,6 +20,13 @@ + true + + + + + 12.0 + true @@ -38,29 +45,45 @@ TRACE prompt 4 + 1607 - - False - ..\packages\AjaxMin.4.84.4790.14417\lib\net40\AjaxMin.dll + + ..\packages\AdvancedStringBuilder.0.1.0\lib\net40-client\AdvancedStringBuilder.dll + + + ..\packages\AjaxMin.5.14.5506.26202\lib\net40\AjaxMin.dll + True - - False - ..\packages\Cassette.2.4.1\lib\net40-client\Cassette.dll + + ..\packages\Cassette.2.4.2\lib\net40-client\Cassette.dll + True - - False - ..\packages\Cassette.Aspnet.2.4.1\lib\net40\Cassette.Aspnet.dll + + ..\packages\Cassette.Aspnet.2.4.2\lib\net40\Cassette.Aspnet.dll + True - - False - ..\packages\Cassette.MSBuild.2.4.1\lib\net40\Cassette.MSBuild.dll + + ..\packages\Cassette.MSBuild.2.4.2\lib\net40\Cassette.MSBuild.dll + True - False - ..\packages\Cassette.Views.2.4.1\lib\net40\Cassette.Views.dll + ..\packages\Cassette.Views.2.4.2\lib\net40\Cassette.Views.dll + True + + + ..\packages\JavaScriptEngineSwitcher.Core.3.1.0\lib\net40-client\JavaScriptEngineSwitcher.Core.dll + + + ..\packages\JavaScriptEngineSwitcher.Msie.3.1.0\lib\net40-client\JavaScriptEngineSwitcher.Msie.dll + + ..\packages\MsieJavaScriptEngine.3.0.3\lib\net40-client\MsieJavaScriptEngine.dll + + + ..\packages\PolyfillsForOldDotNet.System.Threading.0.1.1\lib\net40-client\PolyfillsForOldDotNet.System.Threading.dll + @@ -111,17 +134,15 @@ True ..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.Razor.dll - - ..\packages\WebActivatorEx.2.0.5\lib\net40\WebActivatorEx.dll + + ..\packages\WebActivatorEx.2.2.0\lib\net40\WebActivatorEx.dll + True App_Start\FilterConfig.cs - - App_Start\ReactConfig.cs - App_Start\RouteConfig.cs @@ -134,6 +155,7 @@ Properties\SharedAssemblyVersionInfo.cs + Global.asax @@ -164,29 +186,25 @@ + + + + + + - {f591f1e8-3d6b-494a-b72a-152fcca6210d} + {b7d39e1d-6caa-4489-a03f-0c176402cfb2} Cassette.React + + {d0cc8a22-cee6-485c-924b-1f94426fea59} + React.Core + {662d52ac-1ee9-4372-bd74-379f9ac56451} React.Web.Mvc4 - - {134edd16-8dc8-4983-a2e0-b38dab1ecf1c} - React.Web - - - {d0cc8a22-cee6-485c-924b-1f94426fea59} - React - - - - - - - 10.0 @@ -219,7 +237,7 @@ - @Html.React("CommentsBox", new { initialComments = Model.Comments }) - + - + + + @Bundles.RenderScripts() @Html.ReactInitJavaScript() - \ No newline at end of file + diff --git a/src/React.Sample.Cassette/Web.config b/src/React.Sample.Cassette/Web.config index adfa2e438..f409ca222 100644 --- a/src/React.Sample.Cassette/Web.config +++ b/src/React.Sample.Cassette/Web.config @@ -5,61 +5,72 @@ --> - -
    - - - - - - - - + +
    + - - - + + + + + + + - - - - - - - - - - - - - - - + + + + + + + + + + - - - - - - - - - + + + - - + + + + + + + - + + + - + + - + + + + - - - - + + + + + + + + + + + + + + + + + + diff --git a/src/React.Sample.Cassette/packages.config b/src/React.Sample.Cassette/packages.config index 3b041ee28..9400273a0 100644 --- a/src/React.Sample.Cassette/packages.config +++ b/src/React.Sample.Cassette/packages.config @@ -1,14 +1,19 @@  - - - - - + + + + + + + + - + + + \ No newline at end of file diff --git a/src/React.Sample.ConsoleApp/App.config b/src/React.Sample.ConsoleApp/App.config new file mode 100644 index 000000000..0c9bc599e --- /dev/null +++ b/src/React.Sample.ConsoleApp/App.config @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/src/React.Sample.ConsoleApp/Program.cs b/src/React.Sample.ConsoleApp/Program.cs new file mode 100644 index 000000000..493fabe8b --- /dev/null +++ b/src/React.Sample.ConsoleApp/Program.cs @@ -0,0 +1,46 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System; +using JavaScriptEngineSwitcher.ChakraCore; +using JavaScriptEngineSwitcher.Core; + +namespace React.Sample.ConsoleApp +{ + class Program + { + static void Main(string[] args) + { + Initialize(); + + ReactSiteConfiguration.Configuration + .SetReuseJavaScriptEngines(false) + .AddScript("Sample.jsx"); + + JsEngineSwitcher.Current.DefaultEngineName = ChakraCoreJsEngine.EngineName; + JsEngineSwitcher.Current.EngineFactories.AddChakraCore(); + + var environment = ReactEnvironment.Current; + var component = environment.CreateComponent("HelloWorld", new { name = "Daniel" }); + // renderServerOnly omits the data-reactid attributes + var html = component.RenderHtml(renderServerOnly: true); + + Console.WriteLine(html); + Console.ReadKey(); + } + + private static void Initialize() + { + Initializer.Initialize(registration => registration.AsSingleton()); + var container = React.AssemblyRegistration.Container; + // Register some components that are normally provided by the integration library + // (eg. React.AspNet or React.Web.Mvc4) + container.Register(); + container.Register(); + } + } +} diff --git a/src/React.Sample.ConsoleApp/Properties/AssemblyInfo.cs b/src/React.Sample.ConsoleApp/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..e0628e58b --- /dev/null +++ b/src/React.Sample.ConsoleApp/Properties/AssemblyInfo.cs @@ -0,0 +1,14 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System.Reflection; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("React.Sample.Console")] +[assembly: AssemblyDescription("Command line sample for ReactJS.NET")] +[assembly: ComVisible(false)] +[assembly: Guid("350efb8e-693c-4dfe-8162-c99c359cfc71")] \ No newline at end of file diff --git a/src/React.Sample.ConsoleApp/React.Sample.ConsoleApp.csproj b/src/React.Sample.ConsoleApp/React.Sample.ConsoleApp.csproj new file mode 100644 index 000000000..cc8612e85 --- /dev/null +++ b/src/React.Sample.ConsoleApp/React.Sample.ConsoleApp.csproj @@ -0,0 +1,43 @@ + + + + Copyright 2014-Present Facebook, Inc + ReactJS.NET Console Sample + Daniel Lo Nigro + net40;netcoreapp2.0 + React.Sample.ConsoleApp + Exe + React.Sample.ConsoleApp + 1701 + false + + + + + + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + + diff --git a/src/React.Sample.ConsoleApp/Sample.jsx b/src/React.Sample.ConsoleApp/Sample.jsx new file mode 100644 index 000000000..e8e23fceb --- /dev/null +++ b/src/React.Sample.ConsoleApp/Sample.jsx @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +class HelloWorld extends React.Component { + render() { + return ( +
    + Hello {this.props.name}! +
    + ); + } +} diff --git a/src/React.Sample.Mvc4/App_Start/BundleConfig.cs b/src/React.Sample.Mvc4/App_Start/BundleConfig.cs index eda49f1bf..e0e4ec8b4 100644 --- a/src/React.Sample.Mvc4/App_Start/BundleConfig.cs +++ b/src/React.Sample.Mvc4/App_Start/BundleConfig.cs @@ -1,10 +1,8 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. +/* + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ using System.Web.Optimization; @@ -17,13 +15,13 @@ public static class BundleConfig // For more information on Bundling, visit http://go.microsoft.com/fwlink/?LinkId=254725 public static void RegisterBundles(BundleCollection bundles) { - bundles.Add(new JsxBundle("~/bundles/main").Include( + bundles.Add(new BabelBundle("~/bundles/main").Include( // Add your JSX files here - "~/Content/Sample.jsx" + "~/Content/Sample.tsx" )); // Force minification/combination even in debug mode BundleTable.EnableOptimizations = true; } } -} \ No newline at end of file +} diff --git a/src/React.Sample.Mvc4/App_Start/FilterConfig.cs b/src/React.Sample.Mvc4/App_Start/FilterConfig.cs index d32ae5a61..f628efac9 100644 --- a/src/React.Sample.Mvc4/App_Start/FilterConfig.cs +++ b/src/React.Sample.Mvc4/App_Start/FilterConfig.cs @@ -1,10 +1,8 @@ /* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ using System.Web.Mvc; @@ -18,4 +16,4 @@ public static void RegisterGlobalFilters(GlobalFilterCollection filters) filters.Add(new HandleErrorAttribute()); } } -} \ No newline at end of file +} diff --git a/src/React.Sample.Mvc4/App_Start/ReactConfig.cs b/src/React.Sample.Mvc4/App_Start/ReactConfig.cs index eea13c2de..64fa64950 100644 --- a/src/React.Sample.Mvc4/App_Start/ReactConfig.cs +++ b/src/React.Sample.Mvc4/App_Start/ReactConfig.cs @@ -1,12 +1,13 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. +/* + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ +using JavaScriptEngineSwitcher.Core; +using JavaScriptEngineSwitcher.V8; + [assembly: WebActivatorEx.PreApplicationStartMethod(typeof(React.Sample.Mvc4.ReactConfig), "Configure")] namespace React.Sample.Mvc4 @@ -16,8 +17,14 @@ public static class ReactConfig public static void Configure() { ReactSiteConfiguration.Configuration - .SetUseHarmony(true) - .AddScript("~/Content/Sample.jsx"); + .SetReuseJavaScriptEngines(true) + .SetAllowJavaScriptPrecompilation(true) + .AddScriptWithoutTransform("~/Content/lib/reactstrap.min.js") + .SetBabelVersion(BabelVersions.Babel7) + .AddScript("~/Content/Sample.tsx"); + + JsEngineSwitcher.Current.DefaultEngineName = V8JsEngine.EngineName; + JsEngineSwitcher.Current.EngineFactories.AddV8(); } } -} \ No newline at end of file +} diff --git a/src/React.Sample.Mvc4/App_Start/RouteConfig.cs b/src/React.Sample.Mvc4/App_Start/RouteConfig.cs index 1ba781370..8b6102b2c 100644 --- a/src/React.Sample.Mvc4/App_Start/RouteConfig.cs +++ b/src/React.Sample.Mvc4/App_Start/RouteConfig.cs @@ -1,10 +1,8 @@ /* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ using System.Web.Mvc; @@ -17,6 +15,7 @@ public class RouteConfig public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); + routes.IgnoreRoute("favicon.ico"); routes.MapRoute( name: "Comments", @@ -31,4 +30,4 @@ public static void RegisterRoutes(RouteCollection routes) ); } } -} \ No newline at end of file +} diff --git a/src/React.Sample.Mvc4/Content/Sample.css b/src/React.Sample.Mvc4/Content/Sample.css index a7cff6b7f..b02c980ca 100644 --- a/src/React.Sample.Mvc4/Content/Sample.css +++ b/src/React.Sample.Mvc4/Content/Sample.css @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Facebook, Inc. + * Copyright (c) 2014-Present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the @@ -20,4 +20,4 @@ body { .commentList li { border-bottom: 1px solid #999; padding: 0.5em 0; -} \ No newline at end of file +} diff --git a/src/React.Sample.Mvc4/Content/Sample.tsx b/src/React.Sample.Mvc4/Content/Sample.tsx new file mode 100644 index 000000000..e1e3a2118 --- /dev/null +++ b/src/React.Sample.Mvc4/Content/Sample.tsx @@ -0,0 +1,129 @@ +/** + * Copyright (c) 2014-Present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +type AuthorProps = { + Name: string; + GithubUsername: string; +}; + +type CommentProps = { + Author: AuthorProps; + Text: string; +}; + +type CommentsBoxProps = { + initialComments: CommentProps[]; + page: number; +}; + +function CommentsBox(props: CommentsBoxProps) { + let [state, updateState] = React.useState({ + comments: props.initialComments, + page: props.page, + hasMore: true, + loadingMore: false, + }); + + function loadMoreClicked(evt: { preventDefault: () => void }) { + let nextPage = state.page + 1; + let comments = state.comments; + updateState(prevState => ({ + ...prevState, + page: nextPage, + loadingMore: true, + })); + + let url = '/comments/page-' + (state.page + 1); + let xhr = new XMLHttpRequest(); + xhr.open('GET', url, true); + xhr.setRequestHeader('Content-Type', 'application/json'); + + xhr.onload = () => { + let data = JSON.parse(xhr.responseText); + updateState(prevState => ({ + ...prevState, + comments: comments.concat(data.comments), + hasMore: data.hasMore, + loadingMore: false, + })); + }; + xhr.send(); + evt.preventDefault(); + } + + let commentNodes = state.comments.map((comment: CommentProps) => ( + {comment.Text} + )); + + function renderMoreLink() { + if (state.loadingMore) { + return Loading...; + } else if (state.hasMore) { + return ( + + Load More + + ); + } else { + return No more comments; + } + } + + return ( +
    +

    Comments

    +
      {commentNodes}
    + {renderMoreLink()} +
    +
    + ); +} + +class CommentRow extends React.Component<{ author: AuthorProps }> { + static propTypes = { + author: PropTypes.object.isRequired, + }; + + render() { + return ( +
  • + + {this.props.author.Name} + {': '} + {this.props.children} +
  • + ); + } +} + +class Avatar extends React.Component<{ author: AuthorProps }> { + static propTypes = { + author: PropTypes.object.isRequired, + }; + + render() { + return ( + {'Photo + ); + } + + getPhotoUrl = author => { + return ( + 'https://avatars.githubusercontent.com/' + + author.GithubUsername + + '?s=50' + ); + }; +} diff --git a/src/React.Sample.Mvc4/Content/lib/reactstrap.min.js b/src/React.Sample.Mvc4/Content/lib/reactstrap.min.js new file mode 100644 index 000000000..a44b4feb8 --- /dev/null +++ b/src/React.Sample.Mvc4/Content/lib/reactstrap.min.js @@ -0,0 +1,2 @@ +(function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react"),require("react-popper"),require("react-dom")):"function"==typeof define&&define.amd?define(["exports","react","react-popper","react-dom"],t):(e=e||self,t(e.Reactstrap={},e.React,e.ReactPopper || undefined,e.ReactDOM))})(this,function(e,t,o,n){'use strict';var X=String.fromCharCode;function a(){return a=Object.assign||function(e){for(var t,o=1;oo;o++)t["_"+X(o)]=o;var n=Object.getOwnPropertyNames(t).map(function(e){return t[e]});if("0123456789"!==n.join(""))return!1;var a={};return["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t"].forEach(function(e){a[e]=e}),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},a)).join("")}catch(e){return!1}}()?Object.assign:function(e){for(var t,o,n=c(e),a=1;a=t.which)for(var r,l=this.getMenuItems(),d=X(t.which).toLowerCase(),c=0;ce.activeIndex?this.setState({direction:this.state.indicatorClicked?"left":"right"}):this.props.activeIndex!==e.activeIndex&&this.setState({direction:this.state.indicatorClicked?"right":"left"}),this.setState({indicatorClicked:!1})},o.componentWillUnmount=function(){this.clearInterval(),document.removeEventListener("keyup",this.handleKeyPress)},o.setInterval=function(e){function t(){return e.apply(this,arguments)}return t.toString=function(){return e.toString()},t}(function(e){void 0===e&&(e=this.props),this.clearInterval(),e.interval&&(this.cycleInterval=setInterval(function(){e.next()},parseInt(e.interval,10)))}),o.clearInterval=function(e){function t(){return e.apply(this,arguments)}return t.toString=function(){return e.toString()},t}(function(){clearInterval(this.cycleInterval)}),o.hoverStart=function(){if("hover"===this.props.pause&&this.clearInterval(),this.props.mouseEnter){var e;(e=this.props).mouseEnter.apply(e,arguments)}},o.hoverEnd=function(){if("hover"===this.props.pause&&this.setInterval(),this.props.mouseLeave){var e;(e=this.props).mouseLeave.apply(e,arguments)}},o.handleKeyPress=function(e){this.props.keyboard&&(37===e.keyCode?this.props.previous():39===e.keyCode&&this.props.next())},o.renderItems=function(e,t){var o=this,n=this.props.slide;return Y.createElement("div",{className:t},e.map(function(e,t){var a=t===o.props.activeIndex;return Y.cloneElement(e,{in:a,slide:n})}))},o.render=function(){var t=this,o=this.props,n=o.cssModule,a=o.slide,s=o.className,r=C(pt(s,"carousel",a&&"slide"),n),l=C(pt("carousel-inner"),n),i=this.props.children.filter(function(e){return null!==e&&void 0!==e&&"boolean"!=typeof e}),d=i.every(function(e){return e.type===On});if(d)return Y.createElement("div",{className:r,onMouseEnter:this.hoverStart,onMouseLeave:this.hoverEnd},this.renderItems(i,l));if(i[0]instanceof Array){var c=i[0],p=i[1],u=i[2];return Y.createElement("div",{className:r,onMouseEnter:this.hoverStart,onMouseLeave:this.hoverEnd},this.renderItems(c,l),p,u)}var m=i[0],g=Y.cloneElement(m,{onClickHandler:function(o){"function"==typeof m.props.onClickHandler&&t.setState({indicatorClicked:!0},function(){return m.props.onClickHandler(o)})}}),f=i[1],b=i[2],h=i[3];return Y.createElement("div",{className:r,onMouseEnter:this.hoverStart,onMouseLeave:this.hoverEnd},g,this.renderItems(f,l),b,h)},t}(Y.Component);kn.propTypes={activeIndex:ct.number,next:ct.func.isRequired,previous:ct.func.isRequired,keyboard:ct.bool,pause:ct.oneOf(["hover",!1]),ride:ct.oneOf(["carousel"]),interval:ct.oneOfType([ct.number,ct.string,ct.bool]),children:ct.array,mouseEnter:ct.func,mouseLeave:ct.func,slide:ct.bool,cssModule:ct.object,className:ct.string},kn.defaultProps={interval:5e3,pause:"hover",keyboard:!0,slide:!0},kn.childContextTypes={direction:ct.string};var Pn=function(e){var t=e.direction,o=e.onClickHandler,n=e.cssModule,a=e.directionText,s=e.className,r=C(pt(s,"carousel-control-"+t),n),l=C(pt("carousel-control-"+t+"-icon"),n),i=C(pt("sr-only"),n);return Y.createElement("a",{className:r,role:"button",tabIndex:"0",onClick:function(t){t.preventDefault(),o()}},Y.createElement("span",{className:l,"aria-hidden":"true"}),Y.createElement("span",{className:i},a||t))};Pn.propTypes={direction:ct.oneOf(["prev","next"]).isRequired,onClickHandler:ct.func.isRequired,cssModule:ct.object,directionText:ct.string,className:ct.string};var wn=function(e){var t=e.items,o=e.activeIndex,n=e.cssModule,a=e.onClickHandler,s=e.className,r=C(pt(s,"carousel-indicators"),n),l=t.map(function(e,t){var s=C(pt({active:o===t}),n);return Y.createElement("li",{key:""+(e.key||Object.values(e).join("")),onClick:function(o){o.preventDefault(),a(t)},className:s})});return Y.createElement("ol",{className:r},l)};wn.propTypes={items:ct.array.isRequired,activeIndex:ct.number.isRequired,cssModule:ct.object,onClickHandler:ct.func.isRequired,className:ct.string};var _n=function(e){var t=e.captionHeader,o=e.captionText,n=e.cssModule,a=e.className,s=C(pt(a,"carousel-caption","d-none","d-md-block"),n);return Y.createElement("div",{className:s},Y.createElement("h3",null,t),Y.createElement("p",null,o))};_n.propTypes={captionHeader:ct.string,captionText:ct.string.isRequired,cssModule:ct.object,className:ct.string};var Sn={items:ct.array.isRequired,indicators:ct.bool,controls:ct.bool,autoPlay:ct.bool,defaultActiveIndex:ct.number,activeIndex:ct.number,next:ct.func,previous:ct.func,goToIndex:ct.func},Rn=function(e){function t(t){var o;return o=e.call(this,t)||this,o.animating=!1,o.state={activeIndex:t.defaultActiveIndex||0},o.next=o.next.bind(l(o)),o.previous=o.previous.bind(l(o)),o.goToIndex=o.goToIndex.bind(l(o)),o.onExiting=o.onExiting.bind(l(o)),o.onExited=o.onExited.bind(l(o)),o}s(t,e);var o=t.prototype;return o.onExiting=function(){this.animating=!0},o.onExited=function(){this.animating=!1},o.next=function(){if(!this.animating){var e=this.state.activeIndex===this.props.items.length-1?0:this.state.activeIndex+1;this.setState({activeIndex:e})}},o.previous=function(){if(!this.animating){var e=0===this.state.activeIndex?this.props.items.length-1:this.state.activeIndex-1;this.setState({activeIndex:e})}},o.goToIndex=function(e){this.animating||this.setState({activeIndex:e})},o.render=function(){var e=this,t=this.props,o=t.defaultActiveIndex,n=t.autoPlay,s=t.indicators,l=t.controls,i=t.items,d=t.goToIndex,c=r(t,["defaultActiveIndex","autoPlay","indicators","controls","items","goToIndex"]),p=this.state.activeIndex,u=i.map(function(t){return Y.createElement(On,{onExiting:e.onExiting,onExited:e.onExited,key:t.src},Y.createElement("img",{className:"d-block w-100",src:t.src,alt:t.altText}),Y.createElement(_n,{captionText:t.caption,captionHeader:t.header||t.caption}))});return Y.createElement(kn,a({activeIndex:p,next:this.next,previous:this.previous,ride:n?"carousel":void 0},c),s&&Y.createElement(wn,{items:i,activeIndex:c.activeIndex||p,onClickHandler:d||this.goToIndex}),u,l&&Y.createElement(Pn,{direction:"prev",directionText:"Previous",onClickHandler:c.previous||this.previous}),l&&Y.createElement(Pn,{direction:"next",directionText:"Next",onClickHandler:c.next||this.next}))},t}(t.Component);Rn.propTypes=Sn,Rn.defaultProps={controls:!0,indicators:!0,autoPlay:!0};var jn={tag:Tt,className:ct.string,cssModule:ct.object},In=function(e){var t=e.className,o=e.cssModule,n=e.tag,s=r(e,["className","cssModule","tag"]),l=C(pt(t,"card-subtitle"),o);return Y.createElement(n,a({},s,{className:l}))};In.propTypes=jn,In.defaultProps={tag:"div"};var Dn={tag:Tt,className:ct.string,cssModule:ct.object},An=function(e){var t=e.className,o=e.cssModule,n=e.tag,s=r(e,["className","cssModule","tag"]),l=C(pt(t,"card-text"),o);return Y.createElement(n,a({},s,{className:l}))};An.propTypes=Dn,An.defaultProps={tag:"p"};var Ln={tag:Tt,className:ct.string,cssModule:ct.object},Fn=function(e){var t=e.className,o=e.cssModule,n=e.tag,s=r(e,["className","cssModule","tag"]),l=C(pt(t,"card-title"),o);return Y.createElement(n,a({},s,{className:l}))};Fn.propTypes=Ln,Fn.defaultProps={tag:"div"};var zn={className:ct.string,id:ct.oneOfType([ct.string,ct.number]).isRequired,type:ct.string.isRequired,label:ct.node,inline:ct.bool,valid:ct.bool,invalid:ct.bool,bsSize:ct.string,htmlFor:ct.string,cssModule:ct.object,children:ct.oneOfType([ct.node,ct.array,ct.func]),innerRef:ct.oneOfType([ct.object,ct.string,ct.func])};F.propTypes=zn;var Un={children:ct.node.isRequired,popperClassName:ct.string,placement:ct.string,placementPrefix:ct.string,arrowClassName:ct.string,hideArrow:ct.bool,tag:Tt,isOpen:ct.bool.isRequired,cssModule:ct.object,offset:ct.oneOfType([ct.string,ct.number]),fallbackPlacement:ct.oneOfType([ct.string,ct.array]),flip:ct.bool,container:xt,target:xt.isRequired,modifiers:ct.object,boundariesElement:ct.oneOfType([ct.string,O]),onClosed:ct.func,fade:ct.bool,transition:ct.shape(L.propTypes)},Wn={boundariesElement:"scrollParent",placement:"auto",hideArrow:!1,isOpen:!1,offset:0,fallbackPlacement:"flip",flip:!0,container:"body",modifiers:{},onClosed:function(){},fade:!0,transition:a({},L.defaultProps)},Gn=function(e){function t(t){var o;return o=e.call(this,t)||this,o.handlePlacementChange=o.handlePlacementChange.bind(l(o)),o.setTargetNode=o.setTargetNode.bind(l(o)),o.getTargetNode=o.getTargetNode.bind(l(o)),o.getRef=o.getRef.bind(l(o)),o.onClosed=o.onClosed.bind(l(o)),o.state={isOpen:t.isOpen},o}s(t,e),t.getDerivedStateFromProps=function(e,t){return e.isOpen&&!t.isOpen?{isOpen:e.isOpen}:null};var i=t.prototype;return i.componentDidUpdate=function(){this._element&&this._element.childNodes&&this._element.childNodes[0]&&this._element.childNodes[0].focus&&this._element.childNodes[0].focus()},i.setTargetNode=function(e){this.targetNode=e},i.getTargetNode=function(){return this.targetNode},i.getContainerNode=function(){return _(this.props.container)},i.getRef=function(e){this._element=e},i.handlePlacementChange=function(e){return this.state.placement!==e.placement&&this.setState({placement:e.placement}),e},i.onClosed=function(){this.props.onClosed(),this.setState({isOpen:!1})},i.renderChildren=function(){var e=this.props,t=e.cssModule,n=e.children,s=e.isOpen,l=e.flip,i=e.target,d=e.offset,c=e.fallbackPlacement,p=e.placementPrefix,u=e.arrowClassName,m=e.hideArrow,g=e.popperClassName,f=e.tag,b=e.container,h=e.modifiers,y=e.boundariesElement,E=e.onClosed,N=e.fade,v=e.transition,x=r(e,["cssModule","children","isOpen","flip","target","offset","fallbackPlacement","placementPrefix","arrowClassName","hideArrow","popperClassName","tag","container","modifiers","boundariesElement","onClosed","fade","transition"]),T=C(pt("arrow",u),t),M=this.state.placement||x.placement,O=M.split("-")[0],k=C(pt(g,p?p+"-"+O:O),this.props.cssModule),P=a({offset:{offset:d},flip:{enabled:l,behavior:c},preventOverflow:{boundariesElement:y},update:{enabled:!0,order:950,fn:this.handlePlacementChange}},h),w=a({},L.defaultProps,v,{baseClass:N?v.baseClass:"",timeout:N?v.timeout:0});return Y.createElement(L,a({},w,x,{in:s,onExited:this.onClosed,tag:f}),Y.createElement(o.Popper,{referenceElement:this.targetNode,modifiers:P,placement:M},function(e){var t=e.ref,o=e.style,a=e.placement,s=e.arrowProps;return Y.createElement("div",{ref:t,style:o,className:k,"x-placement":a},n,!m&&Y.createElement("span",{ref:s.ref,className:T,style:s.style}))}))},i.render=function(){return this.setTargetNode(_(this.props.target)),this.state.isOpen?"inline"===this.props.container?this.renderChildren():n.createPortal(Y.createElement("div",{ref:this.getRef},this.renderChildren()),this.getContainerNode()):null},t}(Y.Component);Gn.propTypes=Un,Gn.defaultProps=Wn;var Bn=function(e,t){return t.popperManager.setTargetNode(_(e.target)),null};Bn.contextTypes={popperManager:ct.object.isRequired},Bn.propTypes={target:xt.isRequired};var qn={placement:ct.oneOf(wt),target:xt.isRequired,container:xt,isOpen:ct.bool,disabled:ct.bool,hideArrow:ct.bool,boundariesElement:ct.oneOfType([ct.string,O]),className:ct.string,innerClassName:ct.string,arrowClassName:ct.string,popperClassName:ct.string,cssModule:ct.object,toggle:ct.func,autohide:ct.bool,placementPrefix:ct.string,delay:ct.oneOfType([ct.shape({show:ct.number,hide:ct.number}),ct.number]),modifiers:ct.object,offset:ct.oneOfType([ct.string,ct.number]),innerRef:ct.oneOfType([ct.func,ct.string,ct.object]),trigger:ct.string,fade:ct.bool,flip:ct.bool},Kn={show:0,hide:0},Hn=function(e){function t(t){var o;return o=e.call(this,t)||this,o._target=null,o.addTargetEvents=o.addTargetEvents.bind(l(o)),o.handleDocumentClick=o.handleDocumentClick.bind(l(o)),o.removeTargetEvents=o.removeTargetEvents.bind(l(o)),o.toggle=o.toggle.bind(l(o)),o.showWithDelay=o.showWithDelay.bind(l(o)),o.hideWithDelay=o.hideWithDelay.bind(l(o)),o.onMouseOverTooltipContent=o.onMouseOverTooltipContent.bind(l(o)),o.onMouseLeaveTooltipContent=o.onMouseLeaveTooltipContent.bind(l(o)),o.show=o.show.bind(l(o)),o.hide=o.hide.bind(l(o)),o.onEscKeyDown=o.onEscKeyDown.bind(l(o)),o.getRef=o.getRef.bind(l(o)),o.onClosed=o.onClosed.bind(l(o)),o.state={isOpen:t.isOpen},o}s(t,e);var o=t.prototype;return o.componentDidMount=function(){this.updateTarget()},o.componentWillUnmount=function(){this.removeTargetEvents()},t.getDerivedStateFromProps=function(e,t){return e.isOpen&&!t.isOpen?{isOpen:e.isOpen}:null},o.onMouseOverTooltipContent=function(){-1=t.openCount){var o=C("modal-open",this.props.cssModule),n=new RegExp("(^| )"+o+"( |$)");document.body.className=document.body.className.replace(n," ").trim()}this.manageFocusAfterClose(),t.openCount=e(0,t.openCount-1),y(this._originalBodyPadding)},o.renderModalDialog=function(){var e,t=this,o=x(this.props,fa),n="modal-dialog";return Y.createElement("div",a({},o,{className:C(pt(n,this.props.className,(e={},e["modal-"+this.props.size]=this.props.size,e[n+"-centered"]=this.props.centered,e[n+"-scrollable"]=this.props.scrollable,e)),this.props.cssModule),role:"document",ref:function(e){t._dialog=e}}),Y.createElement("div",{className:C(pt("modal-content",this.props.contentClassName),this.props.cssModule)},this.props.children))},o.render=function(){var e=this.props.unmountOnClose;if(!!this._element&&(this.state.isOpen||!e)){var t=!!this._element&&!this.state.isOpen&&!e;this._element.style.display=t?"none":"block";var o=this.props,n=o.wrapClassName,s=o.modalClassName,r=o.backdropClassName,l=o.cssModule,i=o.isOpen,d=o.backdrop,c=o.role,p=o.labelledBy,u=o.external,m=o.innerRef,g={onClick:this.handleBackdropClick,onMouseDown:this.handleBackdropMouseDown,onKeyUp:this.handleEscape,onKeyDown:this.handleTab,style:{display:"block"},"aria-labelledby":p,role:c,tabIndex:"-1"},f=this.props.fade,b=a({},L.defaultProps,this.props.modalTransition,{baseClass:f?this.props.modalTransition.baseClass:"",timeout:f?this.props.modalTransition.timeout:0}),h=a({},L.defaultProps,this.props.backdropTransition,{baseClass:f?this.props.backdropTransition.baseClass:"",timeout:f?this.props.backdropTransition.timeout:0}),y=d&&(f?Y.createElement(L,a({},h,{in:i&&!!d,cssModule:l,className:C(pt("modal-backdrop",r),l)})):Y.createElement("div",{className:C(pt("modal-backdrop","show",r),l)}));return Y.createElement(ua,{node:this._element},Y.createElement("div",{className:C(n)},Y.createElement(L,a({},g,b,{in:i,onEntered:this.onOpened,onExited:this.onClosed,cssModule:l,className:C(pt("modal",s),l),innerRef:m}),u,this.renderModalDialog()),y))}return null},t}(Y.Component);ha.propTypes=ga,ha.defaultProps=ba,ha.openCount=0;var ya={tag:Tt,wrapTag:Tt,toggle:ct.func,className:ct.string,cssModule:ct.object,children:ct.node,closeAriaLabel:ct.string,charCode:ct.oneOfType([ct.string,ct.number]),close:ct.object},Ea=function(e){var t,o=e.className,n=e.cssModule,s=e.children,l=e.toggle,i=e.tag,d=e.wrapTag,c=e.closeAriaLabel,p=e.charCode,u=e.close,m=r(e,["className","cssModule","children","toggle","tag","wrapTag","closeAriaLabel","charCode","close"]),g=C(pt(o,"modal-header"),n);if(!u&&l){var f="number"==typeof p?X(p):p;t=Y.createElement("button",{type:"button",onClick:l,className:C("close",n),"aria-label":c},Y.createElement("span",{"aria-hidden":"true"},f))}return Y.createElement(d,a({},m,{className:g}),Y.createElement(i,{className:C("modal-title",n)},s),u||t)};Ea.propTypes=ya,Ea.defaultProps={tag:"h5",wrapTag:"div",closeAriaLabel:"Close",charCode:215};var Na={tag:Tt,className:ct.string,cssModule:ct.object},va=function(e){var t=e.className,o=e.cssModule,n=e.tag,s=r(e,["className","cssModule","tag"]),l=C(pt(t,"modal-body"),o);return Y.createElement(n,a({},s,{className:l}))};va.propTypes=Na,va.defaultProps={tag:"div"};var Ca={tag:Tt,className:ct.string,cssModule:ct.object},xa=function(e){var t=e.className,o=e.cssModule,n=e.tag,s=r(e,["className","cssModule","tag"]),l=C(pt(t,"modal-footer"),o);return Y.createElement(n,a({},s,{className:l}))};xa.propTypes=Ca,xa.defaultProps={tag:"div"};var Ta=function(e){var t=pt("tooltip","show"),o=pt("tooltip-inner",e.innerClassName);return Y.createElement(Hn,a({},e,{popperClassName:t,innerClassName:o}))};Ta.propTypes=qn,Ta.defaultProps={placement:"top",autohide:!0,placementPrefix:"bs-tooltip",trigger:"click hover focus"};var Ma={className:ct.string,cssModule:ct.object,size:ct.string,bordered:ct.bool,borderless:ct.bool,striped:ct.bool,dark:ct.bool,hover:ct.bool,responsive:ct.oneOfType([ct.bool,ct.string]),tag:Tt,responsiveTag:Tt,innerRef:ct.oneOfType([ct.func,ct.string,ct.object])},Oa=function(e){var t=e.className,o=e.cssModule,n=e.size,s=e.bordered,l=e.borderless,i=e.striped,d=e.dark,c=e.hover,p=e.responsive,u=e.tag,m=e.responsiveTag,g=e.innerRef,f=r(e,["className","cssModule","size","bordered","borderless","striped","dark","hover","responsive","tag","responsiveTag","innerRef"]),b=C(pt(t,"table",!!n&&"table-"+n,!!s&&"table-bordered",!!l&&"table-borderless",!!i&&"table-striped",!!d&&"table-dark",!!c&&"table-hover"),o),h=Y.createElement(u,a({},f,{ref:g,className:b}));if(p){var y=C(!0===p?"table-responsive":"table-responsive-"+p,o);return Y.createElement(m,{className:y},h)}return h};Oa.propTypes=Ma,Oa.defaultProps={tag:"table",responsiveTag:"div"};var ka={tag:Tt,flush:ct.bool,className:ct.string,cssModule:ct.object},Pa=function(e){var t=e.className,o=e.cssModule,n=e.tag,s=e.flush,l=r(e,["className","cssModule","tag","flush"]),i=C(pt(t,"list-group",!!s&&"list-group-flush"),o);return Y.createElement(n,a({},l,{className:i}))};Pa.propTypes=ka,Pa.defaultProps={tag:"ul"};var wa={children:ct.node,inline:ct.bool,tag:Tt,innerRef:ct.oneOfType([ct.object,ct.func,ct.string]),className:ct.string,cssModule:ct.object},_a=function(e){function t(t){var o;return o=e.call(this,t)||this,o.getRef=o.getRef.bind(l(o)),o.submit=o.submit.bind(l(o)),o}s(t,e);var o=t.prototype;return o.getRef=function(e){this.props.innerRef&&this.props.innerRef(e),this.ref=e},o.submit=function(){this.ref&&this.ref.submit()},o.render=function(){var e=this.props,t=e.className,o=e.cssModule,n=e.inline,s=e.tag,l=e.innerRef,i=r(e,["className","cssModule","inline","tag","innerRef"]),d=C(pt(t,!!n&&"form-inline"),o);return Y.createElement(s,a({},i,{ref:l,className:d}))},t}(t.Component);_a.propTypes=wa,_a.defaultProps={tag:"form"};var Sa={children:ct.node,tag:Tt,className:ct.string,cssModule:ct.object,valid:ct.bool,tooltip:ct.bool},Ra=function(e){var t=e.className,o=e.cssModule,n=e.valid,s=e.tooltip,l=e.tag,i=r(e,["className","cssModule","valid","tooltip","tag"]),d=s?"tooltip":"feedback",c=C(pt(t,n?"valid-"+d:"invalid-"+d),o);return Y.createElement(l,a({},i,{className:c}))};Ra.propTypes=Sa,Ra.defaultProps={tag:"div",valid:void 0};var ja={children:ct.node,row:ct.bool,check:ct.bool,inline:ct.bool,disabled:ct.bool,tag:Tt,className:ct.string,cssModule:ct.object},Ia=function(e){var t=e.className,o=e.cssModule,n=e.row,s=e.disabled,l=e.check,i=e.inline,d=e.tag,c=r(e,["className","cssModule","row","disabled","check","inline","tag"]),p=C(pt(t,!!n&&"row",l?"form-check":"form-group",!!(l&&i)&&"form-check-inline",!!(l&&s)&&"disabled"),o);return Y.createElement(d,a({},c,{className:p}))};Ia.propTypes=ja,Ia.defaultProps={tag:"div"};var Da={children:ct.node,inline:ct.bool,tag:Tt,color:ct.string,className:ct.string,cssModule:ct.object},Aa=function(e){var t=e.className,o=e.cssModule,n=e.inline,s=e.color,l=e.tag,i=r(e,["className","cssModule","inline","color","tag"]),d=C(pt(t,!n&&"form-text",!!s&&"text-"+s),o);return Y.createElement(l,a({},i,{className:d}))};Aa.propTypes=Da,Aa.defaultProps={tag:"small",color:"muted"};var La={children:ct.node,type:ct.string,size:ct.string,bsSize:ct.string,valid:ct.bool,invalid:ct.bool,tag:Tt,innerRef:ct.oneOfType([ct.object,ct.func,ct.string]),plaintext:ct.bool,addon:ct.bool,className:ct.string,cssModule:ct.object},Fa=function(e){function t(t){var o;return o=e.call(this,t)||this,o.getRef=o.getRef.bind(l(o)),o.focus=o.focus.bind(l(o)),o}s(t,e);var o=t.prototype;return o.getRef=function(e){this.props.innerRef&&this.props.innerRef(e),this.ref=e},o.focus=function(){this.ref&&this.ref.focus()},o.render=function(){var e=this.props,t=e.className,o=e.cssModule,n=e.type,s=e.bsSize,l=e.valid,i=e.invalid,d=e.tag,c=e.addon,p=e.plaintext,u=e.innerRef,m=r(e,["className","cssModule","type","bsSize","valid","invalid","tag","addon","plaintext","innerRef"]),g=-1<["radio","checkbox"].indexOf(n),f=/\D/g,b=d||("select"===n||"textarea"===n?n:"input"),h="form-control";p?(h+="-plaintext",b=d||"input"):"file"===n?h+="-file":g&&(c?h=null:h="form-check-input"),m.size&&f.test(m.size)&&(M("Please use the prop \"bsSize\" instead of the \"size\" to bootstrap's input sizing."),s=m.size,delete m.size);var y=C(pt(t,i&&"is-invalid",l&&"is-valid",!!s&&"form-control-"+s,h),o);return("input"===b||d&&"function"==typeof d)&&(m.type=n),m.children&&!(p||"select"===n||"string"!=typeof b||"select"===b)&&(M("Input with a type of \""+n+"\" cannot have children. Please use \"value\"/\"defaultValue\" instead."),delete m.children),Y.createElement(b,a({},m,{ref:u,className:y}))},t}(Y.Component);Fa.propTypes=La,Fa.defaultProps={type:"text"};var za={tag:Tt,size:ct.string,className:ct.string,cssModule:ct.object},Ua=function(e){var t=e.className,o=e.cssModule,n=e.tag,s=e.size,l=r(e,["className","cssModule","tag","size"]),i=C(pt(t,"input-group",s?"input-group-"+s:null),o);return Y.createElement(n,a({},l,{className:i}))};Ua.propTypes=za,Ua.defaultProps={tag:"div"};var Wa={tag:Tt,className:ct.string,cssModule:ct.object},Ga=function(e){var t=e.className,o=e.cssModule,n=e.tag,s=r(e,["className","cssModule","tag"]),l=C(pt(t,"input-group-text"),o);return Y.createElement(n,a({},s,{className:l}))};Ga.propTypes=Wa,Ga.defaultProps={tag:"span"};var Ba={tag:Tt,addonType:ct.oneOf(["prepend","append"]).isRequired,children:ct.node,className:ct.string,cssModule:ct.object},qa=function(e){var t=e.className,o=e.cssModule,n=e.tag,s=e.addonType,l=e.children,i=r(e,["className","cssModule","tag","addonType","children"]),d=C(pt(t,"input-group-"+s),o);return"string"==typeof l?Y.createElement(n,a({},i,{className:d}),Y.createElement(Ga,{children:l})):Y.createElement(n,a({},i,{className:d,children:l}))};qa.propTypes=Ba,qa.defaultProps={tag:"div"};var Ka={addonType:ct.oneOf(["prepend","append"]).isRequired,children:ct.node},Ha=function(e){return Y.createElement(mo,e)};Ha.propTypes=Ka;var $a=ct.oneOfType([ct.number,ct.string]),Va=ct.oneOfType([ct.string,ct.number,ct.shape({size:$a,order:$a,offset:$a})]),Xa={children:ct.node,hidden:ct.bool,check:ct.bool,size:ct.string,for:ct.string,tag:Tt,className:ct.string,cssModule:ct.object,xs:Va,sm:Va,md:Va,lg:Va,xl:Va,widths:ct.array},Ya=function(e,t,o){if(!0===o||""===o)return e?"col":"col-"+t;return"auto"===o?e?"col-auto":"col-"+t+"-auto":e?"col-"+o:"col-"+t+"-"+o},Ja=function(e){var t=e.className,o=e.cssModule,n=e.hidden,s=e.widths,l=e.tag,i=e.check,d=e.size,c=e.for,p=r(e,["className","cssModule","hidden","widths","tag","check","size","for"]),u=[];s.forEach(function(t,n){var a=e[t];if(delete p[t],a||""===a){var s,r=!n;if(Ft(a)){var l,i=r?"-":"-"+t+"-";s=Ya(r,t,a.size),u.push(C(pt((l={},l[s]=a.size||""===a.size,l["order"+i+a.order]=a.order||0===a.order,l["offset"+i+a.offset]=a.offset||0===a.offset,l))),o)}else s=Ya(r,t,a),u.push(s)}});var m=C(pt(t,!!n&&"sr-only",!!i&&"form-check-label",!!d&&"col-form-label-"+d,u,!!u.length&&"col-form-label"),o);return Y.createElement(l,a({htmlFor:c},p,{className:m}))};Ja.propTypes=Xa,Ja.defaultProps={tag:"label",widths:["xs","sm","md","lg","xl"]};var Za={body:ct.bool,bottom:ct.bool,children:ct.node,className:ct.string,cssModule:ct.object,heading:ct.bool,left:ct.bool,list:ct.bool,middle:ct.bool,object:ct.bool,right:ct.bool,tag:Tt,top:ct.bool},Qa=function(e){var t,o=e.body,n=e.bottom,s=e.className,l=e.cssModule,i=e.heading,d=e.left,c=e.list,p=e.middle,u=e.object,m=e.right,g=e.tag,f=e.top,b=r(e,["body","bottom","className","cssModule","heading","left","list","middle","object","right","tag","top"]);t=i?"h4":b.href?"a":b.src||u?"img":c?"ul":"div";var h=g||t,y=C(pt(s,{"media-body":o,"media-heading":i,"media-left":d,"media-right":m,"media-top":f,"media-bottom":n,"media-middle":p,"media-object":u,"media-list":c,media:!o&&!i&&!d&&!m&&!f&&!n&&!p&&!u&&!c}),l);return Y.createElement(h,a({},b,{className:y}))};Qa.propTypes=Za;var es={children:ct.node,className:ct.string,listClassName:ct.string,cssModule:ct.object,size:ct.string,tag:Tt,listTag:Tt,"aria-label":ct.string},ts=function(e){var t,o=e.className,n=e.listClassName,s=e.cssModule,l=e.size,i=e.tag,d=e.listTag,c=e["aria-label"],p=r(e,["className","listClassName","cssModule","size","tag","listTag","aria-label"]),u=C(pt(o),s),m=C(pt(n,"pagination",(t={},t["pagination-"+l]=!!l,t)),s);return Y.createElement(i,{className:u,"aria-label":c},Y.createElement(d,a({},p,{className:m})))};ts.propTypes=es,ts.defaultProps={tag:"nav",listTag:"ul","aria-label":"pagination"};var os={active:ct.bool,children:ct.node,className:ct.string,cssModule:ct.object,disabled:ct.bool,tag:Tt},ns=function(e){var t=e.active,o=e.className,n=e.cssModule,s=e.disabled,l=e.tag,i=r(e,["active","className","cssModule","disabled","tag"]),d=C(pt(o,"page-item",{active:t,disabled:s}),n);return Y.createElement(l,a({},i,{className:d}))};ns.propTypes=os,ns.defaultProps={tag:"li"};var as={"aria-label":ct.string,children:ct.node,className:ct.string,cssModule:ct.object,next:ct.bool,previous:ct.bool,first:ct.bool,last:ct.bool,tag:Tt},ss=function(e){var t,o=e.className,n=e.cssModule,s=e.next,l=e.previous,i=e.first,d=e.last,c=e.tag,p=r(e,["className","cssModule","next","previous","first","last","tag"]),u=C(pt(o,"page-link"),n);l?t="Previous":s?t="Next":i?t="First":d&&(t="Last");var m,g=e["aria-label"]||t;l?m="\u2039":s?m="\u203A":i?m="\xAB":d&&(m="\xBB");var f=e.children;return f&&Array.isArray(f)&&0===f.length&&(f=null),p.href||"a"!==c||(c="button"),(l||s||i||d)&&(f=[Y.createElement("span",{"aria-hidden":"true",key:"caret"},f||m),Y.createElement("span",{className:"sr-only",key:"sr"},g)]),Y.createElement(c,a({},p,{className:u,"aria-label":g}),f)};ss.propTypes=as,ss.defaultProps={tag:"a"};var rs=Y.createContext({}),ls={tag:Tt,activeTab:ct.any,className:ct.string,cssModule:ct.object},is=function(e){function t(t){var o;return o=e.call(this,t)||this,o.state={activeTab:o.props.activeTab},o}s(t,e),t.getDerivedStateFromProps=function(e,t){return t.activeTab===e.activeTab?null:{activeTab:e.activeTab}};var o=t.prototype;return o.render=function(){var e=this.props,t=e.className,o=e.cssModule,n=e.tag,s=x(this.props,Object.keys(ls)),r=C(pt("tab-content",t),o);return Y.createElement(rs.Provider,{value:{activeTabId:this.state.activeTab}},Y.createElement(n,a({},s,{className:r})))},t}(t.Component);A(is),is.propTypes=ls,is.defaultProps={tag:"div"};var ds={tag:Tt,className:ct.string,cssModule:ct.object,tabId:ct.any};q.propTypes=ds,q.defaultProps={tag:"div"};var cs={tag:Tt,fluid:ct.bool,className:ct.string,cssModule:ct.object},ps=function(e){var t=e.className,o=e.cssModule,n=e.tag,s=e.fluid,l=r(e,["className","cssModule","tag","fluid"]),i=C(pt(t,"jumbotron",!!s&&"jumbotron-fluid"),o);return Y.createElement(n,a({},l,{className:i}))};ps.propTypes=cs,ps.defaultProps={tag:"div"};var us={children:ct.node,className:ct.string,closeClassName:ct.string,closeAriaLabel:ct.string,cssModule:ct.object,color:ct.string,fade:ct.bool,isOpen:ct.bool,toggle:ct.func,tag:Tt,transition:ct.shape(L.propTypes),innerRef:ct.oneOfType([ct.object,ct.string,ct.func])},ms={color:"success",isOpen:!0,tag:"div",closeAriaLabel:"Close",fade:!0,transition:a({},L.defaultProps,{unmountOnExit:!0})};K.propTypes=us,K.defaultProps=ms;var gs={children:ct.node,className:ct.string,cssModule:ct.object,fade:ct.bool,isOpen:ct.bool,tag:Tt,transition:ct.shape(L.propTypes),innerRef:ct.oneOfType([ct.object,ct.string,ct.func])},fs={isOpen:!0,tag:"div",fade:!0,transition:a({},L.defaultProps,{unmountOnExit:!0})};H.propTypes=gs,H.defaultProps=fs;var bs={tag:Tt,className:ct.string,cssModule:ct.object,innerRef:ct.oneOfType([ct.object,ct.string,ct.func])},hs=function(e){var t=e.className,o=e.cssModule,n=e.innerRef,s=e.tag,l=r(e,["className","cssModule","innerRef","tag"]),i=C(pt(t,"toast-body"),o);return Y.createElement(s,a({},l,{className:i,ref:n}))};hs.propTypes=bs,hs.defaultProps={tag:"div"};var ys={tag:Tt,icon:ct.oneOfType([ct.string,ct.node]),wrapTag:Tt,toggle:ct.func,className:ct.string,cssModule:ct.object,children:ct.node,closeAriaLabel:ct.string,charCode:ct.oneOfType([ct.string,ct.number]),close:ct.object},Es=function(e){var t,o,n=e.className,s=e.cssModule,l=e.children,i=e.toggle,d=e.tag,c=e.wrapTag,p=e.closeAriaLabel,u=e.charCode,m=e.close,g=e.tagClassName,f=e.icon,b=r(e,["className","cssModule","children","toggle","tag","wrapTag","closeAriaLabel","charCode","close","tagClassName","icon"]),h=C(pt(n,"toast-header"),s);if(!m&&i){var y="number"==typeof u?X(u):u;t=Y.createElement("button",{type:"button",onClick:i,className:C("close",s),"aria-label":p},Y.createElement("span",{"aria-hidden":"true"},y))}return"string"==typeof f?o=Y.createElement("svg",{className:C("rounded text-"+f),width:"20",height:"20",xmlns:"http://www.w3.org/2000/svg",preserveAspectRatio:"xMidYMid slice",focusable:"false",role:"img"},Y.createElement("rect",{fill:"currentColor",width:"100%",height:"100%"})):f&&(o=f),Y.createElement(c,a({},b,{className:h}),o,Y.createElement(d,{className:C(pt(g,{"ml-2":null!=o}),s)},l),m||t)};Es.propTypes=ys,Es.defaultProps={tag:"strong",wrapTag:"div",tagClassName:"mr-auto",closeAriaLabel:"Close",charCode:215};var Ns,vs=a({},Jo.propTypes,{isOpen:ct.bool,children:ct.oneOfType([ct.arrayOf(ct.node),ct.node]),tag:Tt,className:ct.node,navbar:ct.bool,cssModule:ct.object,innerRef:ct.oneOfType([ct.func,ct.string,ct.object])}),Cs=a({},Jo.defaultProps,{isOpen:!1,appear:!1,enter:!0,exit:!0,tag:"div",timeout:Mt.Collapse}),xs=(Ns={},Ns[kt.ENTERING]="collapsing",Ns[kt.ENTERED]="collapse show",Ns[kt.EXITING]="collapsing",Ns[kt.EXITED]="collapse",Ns),Ts=function(e){function t(t){var o;return o=e.call(this,t)||this,o.state={height:null},["onEntering","onEntered","onExit","onExiting","onExited"].forEach(function(e){o[e]=o[e].bind(l(o))}),o}s(t,e);var o=t.prototype;return o.onEntering=function(e,t){this.setState({height:V(e)}),this.props.onEntering(e,t)},o.onEntered=function(e,t){this.setState({height:null}),this.props.onEntered(e,t)},o.onExit=function(e){this.setState({height:V(e)}),this.props.onExit(e)},o.onExiting=function(e){e.offsetHeight;this.setState({height:0}),this.props.onExiting(e)},o.onExited=function(e){this.setState({height:null}),this.props.onExited(e)},o.render=function(){var e=this,t=this.props,o=t.tag,n=t.isOpen,s=t.className,l=t.navbar,i=t.cssModule,d=t.children,c=t.innerRef,p=r(t,["tag","isOpen","className","navbar","cssModule","children","innerRef"]),u=this.state.height,m=T(p,Ot),g=x(p,Ot);return Y.createElement(Jo,a({},m,{in:n,onEntering:this.onEntering,onEntered:this.onEntered,onExit:this.onExit,onExiting:this.onExiting,onExited:this.onExited}),function(t){var n=$(t),r=C(pt(s,n,l&&"navbar-collapse"),i),c=null===u?null:{height:u};return Y.createElement(o,a({},g,{style:a({},g.style,c),className:r,ref:e.props.innerRef}),d)})},t}(t.Component);Ts.propTypes=vs,Ts.defaultProps=Cs;var Ms={tag:Tt,active:ct.bool,disabled:ct.bool,color:ct.string,action:ct.bool,className:ct.any,cssModule:ct.object},Os=function(t){t.preventDefault()},ks=function(e){var t=e.className,o=e.cssModule,n=e.tag,s=e.active,l=e.disabled,i=e.action,d=e.color,c=r(e,["className","cssModule","tag","active","disabled","action","color"]),p=C(pt(t,!!s&&"active",!!l&&"disabled",!!i&&"list-group-item-action",!!d&&"list-group-item-"+d,"list-group-item"),o);return l&&(c.onClick=Os),Y.createElement(n,a({},c,{className:p}))};ks.propTypes=Ms,ks.defaultProps={tag:"li"};var Ps={tag:Tt,className:ct.any,cssModule:ct.object},ws=function(e){var t=e.className,o=e.cssModule,n=e.tag,s=r(e,["className","cssModule","tag"]),l=C(pt(t,"list-group-item-heading"),o);return Y.createElement(n,a({},s,{className:l}))};ws.propTypes=Ps,ws.defaultProps={tag:"h5"};var _s={tag:Tt,className:ct.any,cssModule:ct.object},Ss=function(e){var t=e.className,o=e.cssModule,n=e.tag,s=r(e,["className","cssModule","tag"]),l=C(pt(t,"list-group-item-text"),o);return Y.createElement(n,a({},s,{className:l}))};Ss.propTypes=_s,Ss.defaultProps={tag:"p"};var Rs=function(e){function t(t){var o;return o=e.call(this,t)||this,o.state={isOpen:!0},o.toggle=o.toggle.bind(l(o)),o}s(t,e);var o=t.prototype;return o.toggle=function(){this.setState({isOpen:!this.state.isOpen})},o.render=function(){return Y.createElement(K,a({isOpen:this.state.isOpen,toggle:this.toggle},this.props))},t}(t.Component),js=["defaultOpen"],Is=function(e){function t(t){var o;return o=e.call(this,t)||this,o.state={isOpen:t.defaultOpen||!1},o.toggle=o.toggle.bind(l(o)),o}s(t,e);var o=t.prototype;return o.toggle=function(){this.setState({isOpen:!this.state.isOpen})},o.render=function(){return Y.createElement(fo,a({isOpen:this.state.isOpen,toggle:this.toggle},x(this.props,js)))},t}(t.Component);Is.propTypes=a({defaultOpen:ct.bool},fo.propTypes);var Ds=["toggleEvents","defaultOpen"],As={defaultOpen:ct.bool,toggler:ct.string.isRequired,toggleEvents:ct.arrayOf(ct.string)},Ls=function(e){function t(t){var o;return o=e.call(this,t)||this,o.togglers=null,o.removeEventListeners=null,o.toggle=o.toggle.bind(l(o)),o.state={isOpen:t.defaultOpen||!1},o}s(t,e);var o=t.prototype;return o.componentDidMount=function(){this.togglers=P(this.props.toggler),this.togglers.length&&(this.removeEventListeners=S(this.togglers,this.toggle,this.props.toggleEvents))},o.componentWillUnmount=function(){this.togglers.length&&this.removeEventListeners&&this.removeEventListeners()},o.toggle=function(t){this.setState(function(e){var t=e.isOpen;return{isOpen:!t}}),t.preventDefault()},o.render=function(){return Y.createElement(Ts,a({isOpen:this.state.isOpen},x(this.props,Ds)))},t}(t.Component);Ls.propTypes=As,Ls.defaultProps={toggleEvents:St};var Fs=["defaultOpen"],zs=function(e){function t(t){var o;return o=e.call(this,t)||this,o.state={isOpen:t.defaultOpen||!1},o.toggle=o.toggle.bind(l(o)),o}s(t,e);var o=t.prototype;return o.toggle=function(){this.setState({isOpen:!this.state.isOpen})},o.render=function(){return Y.createElement(mo,a({isOpen:this.state.isOpen,toggle:this.toggle},x(this.props,Fs)))},t}(t.Component);zs.propTypes=a({defaultOpen:ct.bool},mo.propTypes);var Us=["defaultOpen"],Ws=function(e){function t(t){var o;return o=e.call(this,t)||this,o.state={isOpen:t.defaultOpen||!1},o.toggle=o.toggle.bind(l(o)),o}s(t,e);var o=t.prototype;return o.toggle=function(){this.setState({isOpen:!this.state.isOpen})},o.render=function(){return Y.createElement(Ta,a({isOpen:this.state.isOpen,toggle:this.toggle},x(this.props,Us)))},t}(t.Component);Ws.propTypes=a({defaultOpen:ct.bool},Ta.propTypes);var Gs={tag:Tt,type:ct.string,size:ct.string,color:ct.string,className:ct.string,cssModule:ct.object,children:ct.string},Bs=function(e){var t=e.className,o=e.cssModule,n=e.type,s=e.size,l=e.color,i=e.children,d=e.tag,c=r(e,["className","cssModule","type","size","color","children","tag"]),p=C(pt(t,!!s&&"spinner-"+n+"-"+s,"spinner-"+n,!!l&&"text-"+l),o);return Y.createElement(d,a({role:"status"},c,{className:p}),i&&Y.createElement("span",{className:C("sr-only",o)},i))};Bs.propTypes=Gs,Bs.defaultProps={tag:"div",type:"border",children:"Loading..."},e.Alert=K,e.Badge=an,e.Breadcrumb=so,e.BreadcrumbItem=lo,e.Button=co,e.ButtonDropdown=fo,e.ButtonGroup=ho,e.ButtonToolbar=Eo,e.Card=rn,e.CardBody=fn,e.CardColumns=mn,e.CardDeck=pn,e.CardFooter=En,e.CardGroup=dn,e.CardHeader=vn,e.CardImg=xn,e.CardImgOverlay=Mn,e.CardLink=hn,e.CardSubtitle=In,e.CardText=An,e.CardTitle=Fn,e.Carousel=kn,e.CarouselCaption=_n,e.CarouselControl=Pn,e.CarouselIndicators=wn,e.CarouselItem=On,e.Col=Bt,e.Collapse=Ts,e.Container=Dt,e.CustomInput=F,e.Dropdown=mo,e.DropdownItem=vo,e.DropdownMenu=Mo,e.DropdownToggle=ko,e.Fade=L,e.Form=_a,e.FormFeedback=Ra,e.FormGroup=Ia,e.FormText=Aa,e.Input=Fa,e.InputGroup=Ua,e.InputGroupAddon=qa,e.InputGroupButtonDropdown=Ha,e.InputGroupText=Ga,e.Jumbotron=ps,e.Label=Ja,e.ListGroup=Pa,e.ListGroupItem=ks,e.ListGroupItemHeading=ws,e.ListGroupItemText=Ss,e.Media=Qa,e.Modal=ha,e.ModalBody=va,e.ModalFooter=xa,e.ModalHeader=Ea,e.Nav=Qt,e.NavItem=to,e.NavLink=no,e.Navbar=Ht,e.NavbarBrand=Vt,e.NavbarToggler=Yt,e.Pagination=ts,e.PaginationItem=ns,e.PaginationLink=ss,e.Popover=$n,e.PopoverBody=Qn,e.PopoverHeader=Jn,e.PopperContent=Gn,e.PopperTargetHelper=Bn,e.Progress=ca,e.Row=Lt,e.Spinner=Bs,e.TabContent=is,e.TabPane=q,e.Table=Oa,e.Toast=H,e.ToastBody=hs,e.ToastHeader=Es,e.Tooltip=Ta,e.UncontrolledAlert=Rs,e.UncontrolledButtonDropdown=Is,e.UncontrolledCarousel=Rn,e.UncontrolledCollapse=Ls,e.UncontrolledDropdown=zs,e.UncontrolledPopover=Xn,e.UncontrolledTooltip=Ws,e.Util=jt,Object.defineProperty(e,"__esModule",{value:!0})}); +//# sourceMappingURL=reactstrap.min.js.map diff --git a/src/React.Sample.Mvc4/Controllers/HomeController.cs b/src/React.Sample.Mvc4/Controllers/HomeController.cs index a54aaa4c9..2845c8325 100644 --- a/src/React.Sample.Mvc4/Controllers/HomeController.cs +++ b/src/React.Sample.Mvc4/Controllers/HomeController.cs @@ -1,10 +1,8 @@ /* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ // For clarity, this sample has all code in the one file. In a real project, you'd put every @@ -13,6 +11,7 @@ using System.Collections.Generic; using System.Linq; using System.Web.Mvc; +using System.Web.UI; using React.Sample.Mvc4.Models; using React.Sample.Mvc4.ViewModels; @@ -21,7 +20,7 @@ namespace React.Sample.Mvc4.Models public class AuthorModel { public string Name { get; set; } - public string Facebook { get; set; } + public string GithubUsername { get; set; } } public class CommentModel { @@ -36,32 +35,33 @@ public class IndexViewModel { public IEnumerable Comments { get; set; } public int CommentsPerPage { get; set; } + public int Page { get; set; } } } namespace React.Sample.Mvc4.Controllers { - public class HomeController : Controller - { - private const int COMMENTS_PER_PAGE = 3; + public class HomeController : Controller + { + private const int COMMENTS_PER_PAGE = 3; - private readonly IDictionary _authors; + private readonly IDictionary _authors; private readonly IList _comments; - public HomeController() - { + public HomeController() + { // In reality, you would use a repository or something for fetching data // For clarity, we'll just use a hard-coded list. _authors = new Dictionary { - {"daniel", new AuthorModel { Name = "Daniel Lo Nigro", Facebook = "daaniel" }}, - {"vjeux", new AuthorModel { Name = "Christopher Chedeau", Facebook = "vjeux" }}, - {"cpojer", new AuthorModel { Name = "Christoph Pojer", Facebook = "cpojer" }}, - {"jordwalke", new AuthorModel { Name = "Jordan Walke", Facebook = "jordwalke" }}, - {"zpao", new AuthorModel { Name = "Paul O'Shannessy", Facebook = "zpao" }}, + {"daniel", new AuthorModel { Name = "Daniel Lo Nigro", GithubUsername = "Daniel15" }}, + {"vjeux", new AuthorModel { Name = "Christopher Chedeau", GithubUsername = "vjeux" }}, + {"cpojer", new AuthorModel { Name = "Christoph Pojer", GithubUsername = "cpojer" }}, + {"jordwalke", new AuthorModel { Name = "Jordan Walke", GithubUsername = "jordwalke" }}, + {"zpao", new AuthorModel { Name = "Paul O'Shannessy", GithubUsername = "zpao" }}, }; - _comments = new List - { + _comments = new List + { new CommentModel { Author = _authors["daniel"], Text = "First!!!!111!" }, new CommentModel { Author = _authors["zpao"], Text = "React is awesome!" }, new CommentModel { Author = _authors["cpojer"], Text = "Awesome!" }, @@ -69,27 +69,43 @@ public HomeController() new CommentModel { Author = _authors["daniel"], Text = "Foo" }, new CommentModel { Author = _authors["daniel"], Text = "Bar" }, new CommentModel { Author = _authors["daniel"], Text = "FooBarBaz" }, - }; - } + }; + } - public ActionResult Index() - { - return View(new IndexViewModel - { - Comments = _comments.Take(COMMENTS_PER_PAGE), - CommentsPerPage = COMMENTS_PER_PAGE - }); - } + public ActionResult Index() + { + return View(new IndexViewModel + { + Comments = _comments.Take(COMMENTS_PER_PAGE), + CommentsPerPage = COMMENTS_PER_PAGE, + Page = 1 + }); + } - public ActionResult Comments(int page) - { - var comments = _comments.Skip((page - 1) * COMMENTS_PER_PAGE).Take(COMMENTS_PER_PAGE); + [OutputCache(Duration = 0, Location = OutputCacheLocation.Any, VaryByHeader = "Content-Type")] + public ActionResult Comments(int page) + { + Response.Cache.SetOmitVaryStar(true); + var comments = _comments.Skip((page - 1) * COMMENTS_PER_PAGE).Take(COMMENTS_PER_PAGE); var hasMore = page * COMMENTS_PER_PAGE < _comments.Count; - return Json(new { - comments = comments, - hasMore = hasMore - }, JsonRequestBehavior.AllowGet); - } - } + if (ControllerContext.HttpContext.Request.ContentType == "application/json") + { + return Json(new + { + comments = comments, + hasMore = hasMore + }, JsonRequestBehavior.AllowGet); + } + else + { + return View("Index", new IndexViewModel + { + Comments = _comments.Take(COMMENTS_PER_PAGE * page), + CommentsPerPage = COMMENTS_PER_PAGE, + Page = page + }); + } + } + } } diff --git a/src/React.Sample.Mvc4/Global.asax.cs b/src/React.Sample.Mvc4/Global.asax.cs index ee331af1d..5f81b3dbc 100644 --- a/src/React.Sample.Mvc4/Global.asax.cs +++ b/src/React.Sample.Mvc4/Global.asax.cs @@ -1,10 +1,8 @@ /* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ using System.Web.Mvc; @@ -25,4 +23,4 @@ protected void Application_Start() BundleConfig.RegisterBundles(BundleTable.Bundles); } } -} \ No newline at end of file +} diff --git a/src/React.Sample.Mvc4/React.Sample.Mvc4.csproj b/src/React.Sample.Mvc4/React.Sample.Mvc4.csproj index 07c1d2e04..fa68ba549 100644 --- a/src/React.Sample.Mvc4/React.Sample.Mvc4.csproj +++ b/src/React.Sample.Mvc4/React.Sample.Mvc4.csproj @@ -1,5 +1,7 @@  + + Debug @@ -13,14 +15,24 @@ Properties React.Sample.Mvc4 React.Sample.Mvc4 - v4.0 + v4.5 false true - ..\packages\WebGrease.1.5.2\lib + true + + + + + 12.0 + + + + + true @@ -31,6 +43,7 @@ prompt 4 1607 + false pdbonly @@ -40,15 +53,26 @@ prompt 4 1607 + false - - ..\packages\Antlr.3.4.1.9004\lib\Antlr3.Runtime.dll + + ..\packages\AdvancedStringBuilder.0.1.0\lib\net45\AdvancedStringBuilder.dll - - - ..\packages\Newtonsoft.Json.5.0.4\lib\net40\Newtonsoft.Json.dll + + ..\packages\Antlr.3.5.0.2\lib\Antlr3.Runtime.dll + True + + + ..\packages\JavaScriptEngineSwitcher.V8.3.1.0\lib\net45\ClearScript.dll + + + ..\packages\JavaScriptEngineSwitcher.Core.3.1.0\lib\net45\JavaScriptEngineSwitcher.Core.dll + + + ..\packages\JavaScriptEngineSwitcher.V8.3.1.0\lib\net45\JavaScriptEngineSwitcher.V8.dll + @@ -56,15 +80,18 @@ - - + + + ..\packages\Microsoft.AspNet.Mvc.4.0.40804.0\lib\net40\System.Web.Mvc.dll + ..\packages\Microsoft.AspNet.Web.Optimization.1.1.3\lib\net40\System.Web.Optimization.dll - - + + ..\System.Web.Optimization.React\bin\$(Configuration)\net40\System.Web.Optimization.React.dll + @@ -78,10 +105,6 @@ True ..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.Helpers.dll - - True - ..\packages\Microsoft.AspNet.Mvc.4.0.30506.0\lib\net40\System.Web.Mvc.dll - True ..\packages\Microsoft.AspNet.Razor.2.0.30506.0\lib\net40\System.Web.Razor.dll @@ -99,11 +122,12 @@ ..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.WebPages.Razor.dll - False - ..\packages\WebActivatorEx.2.0.5\lib\net40\WebActivatorEx.dll + ..\packages\WebActivatorEx.2.2.0\lib\net40\WebActivatorEx.dll + True - - ..\packages\WebGrease.1.5.2\lib\WebGrease.dll + + ..\packages\WebGrease.1.6.0\lib\WebGrease.dll + True @@ -124,9 +148,12 @@ + - + + Designer + Web.config @@ -136,38 +163,32 @@ - - {b4a5902a-70e2-4fa4-817d-dcc78d31e9b9} - React.JavaScriptEngine.VroomJs + + Designer + + + + + + + + + + + + + + {d0cc8a22-cee6-485c-924b-1f94426fea59} + React.Core {662d52ac-1ee9-4372-bd74-379f9ac56451} React.Web.Mvc4 - - {889cef81-75d6-4bab-8e2c-b64b7ca97c77} - System.Web.Optimization.React - {134edd16-8dc8-4983-a2e0-b38dab1ecf1c} React.Web - - {d0cc8a22-cee6-485c-924b-1f94426fea59} - React - - - - - - - - - - - - - 10.0 @@ -179,10 +200,10 @@ - + - + @@ -192,7 +213,7 @@ True 63919 / - http://localhost:63919/ + http://localhost:63911/ False False @@ -202,10 +223,20 @@ - - \ No newline at end of file + diff --git a/src/React.Sample.Mvc4/TransformBabel.proj b/src/React.Sample.Mvc4/TransformBabel.proj new file mode 100644 index 000000000..b700addaa --- /dev/null +++ b/src/React.Sample.Mvc4/TransformBabel.proj @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/React.Sample.Mvc4/TransformJsx.proj b/src/React.Sample.Mvc4/TransformJsx.proj deleted file mode 100644 index b51181034..000000000 --- a/src/React.Sample.Mvc4/TransformJsx.proj +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/src/React.Sample.Mvc4/Views/Home/Index.cshtml b/src/React.Sample.Mvc4/Views/Home/Index.cshtml index d6503011a..44b08a3ac 100644 --- a/src/React.Sample.Mvc4/Views/Home/Index.cshtml +++ b/src/React.Sample.Mvc4/Views/Home/Index.cshtml @@ -1,25 +1,33 @@ -@using System.Web.Optimization +@using System.Web.Optimization @model React.Sample.Mvc4.ViewModels.IndexViewModel ReactJS.NET Sample + -

    - This is an example of ReactJS.NET's server-side rendering. The initial state of this - comments box is rendered server-side, and additional data is loaded via AJAX and rendered - client-side. -

    - - - @Html.React("CommentsBox", new { initialComments = Model.Comments }) - - - - @Scripts.Render("~/bundles/main") - - @Html.ReactInitJavaScript() +
    +
    +

    ASP.NET MVC Sample

    +
    +

    + This is an example of ReactJS.NET's server-side rendering. The initial state of this + comments box is rendered server-side, and additional data is loaded via AJAX and rendered + client-side. +

    + + @Html.React("CommentsBox", new { initialComments = Model.Comments, page = Model.Page }) + + + + + + @Scripts.Render("~/bundles/main") + + @Html.ReactInitJavaScript() +
    +
    - \ No newline at end of file + diff --git a/src/React.Sample.Mvc4/Web.config b/src/React.Sample.Mvc4/Web.config index c3df22cba..d01cc635a 100644 --- a/src/React.Sample.Mvc4/Web.config +++ b/src/React.Sample.Mvc4/Web.config @@ -5,6 +5,7 @@ --> + @@ -12,12 +13,17 @@ + - - - - + + @@ -27,30 +33,49 @@ - - - - - + - - + + + - + - + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/React.Sample.Mvc4/package-lock.json b/src/React.Sample.Mvc4/package-lock.json new file mode 100644 index 000000000..b2ba51d45 --- /dev/null +++ b/src/React.Sample.Mvc4/package-lock.json @@ -0,0 +1,61 @@ +{ + "name": "React.Sample.Mvc4", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@types/prop-types": { + "version": "15.7.3", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", + "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==", + "dev": true + }, + "@types/react": { + "version": "16.9.56", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.56.tgz", + "integrity": "sha512-gIkl4J44G/qxbuC6r2Xh+D3CGZpJ+NdWTItAPmZbR5mUS+JQ8Zvzpl0ea5qT/ZT3ZNTUcDKUVqV3xBE8wv/DyQ==", + "dev": true, + "requires": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, + "@types/react-dom": { + "version": "16.9.9", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.9.9.tgz", + "integrity": "sha512-jE16FNWO3Logq/Lf+yvEAjKzhpST/Eac8EMd1i4dgZdMczfgqC8EjpxwNgEe3SExHYLliabXDh9DEhhqnlXJhg==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, + "@types/reactstrap": { + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/@types/reactstrap/-/reactstrap-8.5.3.tgz", + "integrity": "sha512-B7okIEXUGUL5Ai1vZyqyz6FmILZQUYCK5RABcVY8Mxj94JrFaRlSPmZx4NTIarX+8jhQ3I1ItR5+/LdpE5c4Uw==", + "dev": true, + "requires": { + "@types/react": "*", + "popper.js": "^1.14.1" + } + }, + "csstype": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.4.tgz", + "integrity": "sha512-xc8DUsCLmjvCfoD7LTGE0ou2MIWLx0K9RCZwSHMOdynqRsP4MtUcLeqh1HcQ2dInwDTqn+3CE0/FZh1et+p4jA==", + "dev": true + }, + "popper.js": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz", + "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==", + "dev": true + }, + "typescript": { + "version": "3.9.7", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.7.tgz", + "integrity": "sha512-BLbiRkiBzAwsjut4x/dsibSTB6yWpwT5qWmC2OfuCg3GgVQCSgMs4vEctYPhsaGtd0AeuuHMkjZ2h2WG8MSzRw==", + "dev": true + } + } +} diff --git a/src/React.Sample.Mvc4/package.json b/src/React.Sample.Mvc4/package.json new file mode 100644 index 000000000..eb41f628c --- /dev/null +++ b/src/React.Sample.Mvc4/package.json @@ -0,0 +1,15 @@ +{ + "name": "React.Sample.Mvc4", + "version": "1.0.0", + "main": "index.js", + "license": "MIT", + "scripts": { + "lint:ts": "tsc" + }, + "devDependencies": { + "@types/react": "16.9.56", + "@types/react-dom": "16.9.9", + "@types/reactstrap": "8.5.3", + "typescript": "3.9.7" + } +} diff --git a/src/React.Sample.Mvc4/packages.config b/src/React.Sample.Mvc4/packages.config index df80bfa5d..18a9fb9fe 100644 --- a/src/React.Sample.Mvc4/packages.config +++ b/src/React.Sample.Mvc4/packages.config @@ -1,12 +1,17 @@  - - - - - - - - - + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/React.Sample.Mvc4/tsconfig.json b/src/React.Sample.Mvc4/tsconfig.json new file mode 100644 index 000000000..ce2f271b6 --- /dev/null +++ b/src/React.Sample.Mvc4/tsconfig.json @@ -0,0 +1,13 @@ +{ + "compilerOptions": { + "noImplicitAny": false, + "module": "commonjs", + "target": "es6", + "jsx": "react", + "esModuleInterop": true, + "noEmit": true, + "types": ["./types"], + "lib": ["es2015", "dom"] + }, + "include": ["./Content/**/*"] +} diff --git a/src/React.Sample.Mvc4/types/index.d.ts b/src/React.Sample.Mvc4/types/index.d.ts new file mode 100644 index 000000000..b647e1abe --- /dev/null +++ b/src/React.Sample.Mvc4/types/index.d.ts @@ -0,0 +1,9 @@ +import _React from 'react'; +import _Reactstrap from 'reactstrap'; +import _PropTypes from 'prop-types'; + +declare global { + const React: typeof _React; + const Reactstrap: typeof _Reactstrap; + const PropTypes: typeof _PropTypes; +} diff --git a/src/React.Sample.Owin/CommentsMiddleware.cs b/src/React.Sample.Owin/CommentsMiddleware.cs new file mode 100644 index 000000000..9bc5a705d --- /dev/null +++ b/src/React.Sample.Owin/CommentsMiddleware.cs @@ -0,0 +1,93 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +using Microsoft.Owin; + +using Newtonsoft.Json; + +using React.Sample.Owin.Models; + +namespace React.Sample.Owin.Models +{ + public class AuthorModel + { + public string Name { get; set; } + public string GithubUsername { get; set; } + } + public class CommentModel + { + public AuthorModel Author { get; set; } + public string Text { get; set; } + } +} + +namespace React.Sample.Owin +{ + internal class CommentsMiddleware + { + private const int COMMENTS_PER_PAGE = 3; + + private readonly Func, Task> _next; + private readonly List _comments; + + public CommentsMiddleware(Func, Task> next) + { + _next = next; + + // In reality, you would use a repository or something for fetching data + // For clarity, we'll just use a hard-coded list. + var authors = new Dictionary + { + {"daniel", new AuthorModel { Name = "Daniel Lo Nigro", GithubUsername = "Daniel15" }}, + {"vjeux", new AuthorModel { Name = "Christopher Chedeau", GithubUsername = "vjeux" }}, + {"cpojer", new AuthorModel { Name = "Christoph Pojer", GithubUsername = "cpojer" }}, + {"jordwalke", new AuthorModel { Name = "Jordan Walke", GithubUsername = "jordwalke" }}, + {"zpao", new AuthorModel { Name = "Paul O'Shannessy", GithubUsername = "zpao" }}, + }; + + _comments = new List + { + new CommentModel { Author = authors["daniel"], Text = "First!!!!111!" }, + new CommentModel { Author = authors["zpao"], Text = "React is awesome!" }, + new CommentModel { Author = authors["cpojer"], Text = "Awesome!" }, + new CommentModel { Author = authors["vjeux"], Text = "Hello World" }, + new CommentModel { Author = authors["daniel"], Text = "Foo" }, + new CommentModel { Author = authors["daniel"], Text = "Bar" }, + new CommentModel { Author = authors["daniel"], Text = "FooBarBaz" }, + }; + } + + public async Task Invoke(IDictionary environment) + { + var context = new OwinContext(environment); + + // Determine if this middleware should handle the request + if (!context.Request.Path.Value.StartsWith("/comments/page-") || context.Request.Method != "GET") + { + await _next(environment); + return; + } + + // prepare the response data + int page = int.Parse(context.Request.Path.Value.Replace("/comments/page-", string.Empty)); + var responseObject = new + { + comments = _comments.Skip((page - 1) * COMMENTS_PER_PAGE).Take(COMMENTS_PER_PAGE), + hasMore = page * COMMENTS_PER_PAGE < _comments.Count + }; + + var json = await Task.Factory.StartNew(() => JsonConvert.SerializeObject(responseObject)); + + await context.Response.WriteAsync(json); + } + } +} diff --git a/src/React.Sample.Owin/Content/Index.html b/src/React.Sample.Owin/Content/Index.html new file mode 100644 index 000000000..68f13d837 --- /dev/null +++ b/src/React.Sample.Owin/Content/Index.html @@ -0,0 +1,31 @@ + + + + + + React OWIN Sample + + + +
    + + + + + + + diff --git a/src/React.Sample.Owin/Content/Sample.css b/src/React.Sample.Owin/Content/Sample.css new file mode 100644 index 000000000..b02c980ca --- /dev/null +++ b/src/React.Sample.Owin/Content/Sample.css @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2014-Present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +body { + font-family: Calibri, Verdana, sans-serif; +} + +.commentList { + list-style-type: none; + margin: 0; + padding: 0; +} + +.commentList li { + border-bottom: 1px solid #999; + padding: 0.5em 0; +} diff --git a/src/React.Sample.Mvc4/Content/Sample.jsx b/src/React.Sample.Owin/Content/Sample.jsx similarity index 59% rename from src/React.Sample.Mvc4/Content/Sample.jsx rename to src/React.Sample.Owin/Content/Sample.jsx index 1134b4f41..659164b6d 100644 --- a/src/React.Sample.Mvc4/Content/Sample.jsx +++ b/src/React.Sample.Owin/Content/Sample.jsx @@ -1,28 +1,25 @@ /** - * Copyright (c) 2014, Facebook, Inc. + * Copyright (c) 2014-Present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant + * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. - * - * @jsx React.DOM */ -var CommentsBox = React.createClass({ - propTypes: { - initialComments: React.PropTypes.array.isRequired, - commentsPerPage: React.PropTypes.number.isRequired - }, - getInitialState() { - return { - comments: this.props.initialComments, - page: 1, - hasMore: true, - loadingMore: false - }; - }, - loadMoreClicked(evt) { +class CommentsBox extends React.Component { + static propTypes = { + initialComments: PropTypes.array.isRequired + }; + + state = { + comments: this.props.initialComments || [], + page: 0, + hasMore: true, + loadingMore: false + }; + + loadMoreClicked = (evt) => { var nextPage = this.state.page + 1; this.setState({ page: nextPage, @@ -32,21 +29,29 @@ var CommentsBox = React.createClass({ var url = evt.target.href; var xhr = new XMLHttpRequest(); xhr.open('GET', url, true); - xhr.onload = function() { + xhr.onload = () => { var data = JSON.parse(xhr.responseText); this.setState({ comments: this.state.comments.concat(data.comments), hasMore: data.hasMore, loadingMore: false }); - }.bind(this); + }; xhr.send(); - return false; - }, + + if (evt.preventDefault) { + evt.preventDefault(); + } + }; + + componentDidMount() { + this.loadMoreClicked({ target: { href: "/comments/page-1" } }); + } + render() { - var commentNodes = this.state.comments.map(function (comment) { - return {comment.Text}; - }); + var commentNodes = this.state.comments.map(comment => + {comment.Text} + ); return (
    @@ -57,8 +62,9 @@ var CommentsBox = React.createClass({ {this.renderMoreLink()}
    ); - }, - renderMoreLink() { + } + + renderMoreLink = () => { if (this.state.loadingMore) { return Loading...; } else if (this.state.hasMore) { @@ -70,13 +76,14 @@ var CommentsBox = React.createClass({ } else { return No more comments; } - } -}); + }; +} + +class Comment extends React.Component { + static propTypes = { + author: PropTypes.object.isRequired + }; -var Comment = React.createClass({ - propTypes: { - author: React.PropTypes.object.isRequired - }, render() { return (
  • @@ -86,12 +93,13 @@ var Comment = React.createClass({
  • ); } -}); +} + +class Avatar extends React.Component { + static propTypes = { + author: PropTypes.object.isRequired + }; -var Avatar = React.createClass({ - propTypes: { - author: React.PropTypes.object.isRequired - }, render() { return ( ); - }, - getPhotoUrl(author) { - return 'http://graph.facebook.com/' + author.Facebook + '/picture'; } -}); + + getPhotoUrl = (author) => { + return 'https://avatars.githubusercontent.com/' + author.GithubUsername + '?s=50'; + }; +} diff --git a/src/React.Sample.Owin/Program.cs b/src/React.Sample.Owin/Program.cs new file mode 100644 index 000000000..5b7aa1cd1 --- /dev/null +++ b/src/React.Sample.Owin/Program.cs @@ -0,0 +1,25 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System; + +using Microsoft.Owin.Hosting; + +namespace React.Sample.Owin +{ + class Program + { + static void Main(string[] args) + { + using (WebApp.Start("http://localhost:12345")) + { + Console.WriteLine("Running on localhost:12345, press enter to quit"); + Console.ReadLine(); + } + } + } +} diff --git a/src/React.Sample.Owin/Properties/AssemblyInfo.cs b/src/React.Sample.Owin/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..82792741f --- /dev/null +++ b/src/React.Sample.Owin/Properties/AssemblyInfo.cs @@ -0,0 +1,8 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("React.Sample.Owin")] +[assembly: AssemblyDescription("Owin.SelfHost sample for ReactJS.NET")] +[assembly: ComVisible(false)] +[assembly: Guid("9a931389-94e4-48ac-bb28-a5810ecedfef")] \ No newline at end of file diff --git a/src/React.Sample.Owin/React.Sample.Owin.csproj b/src/React.Sample.Owin/React.Sample.Owin.csproj new file mode 100644 index 000000000..a827c56d8 --- /dev/null +++ b/src/React.Sample.Owin/React.Sample.Owin.csproj @@ -0,0 +1,45 @@ + + + + Copyright 2014-Present Facebook, Inc + ReactJS.NET OWIN Sample + Daniel Lo Nigro + net45 + React.Sample.Owin + Exe + React.Sample.Owin + false + + + + + + + PreserveNewest + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/React.Sample.Owin/Startup.cs b/src/React.Sample.Owin/Startup.cs new file mode 100644 index 000000000..f726334d5 --- /dev/null +++ b/src/React.Sample.Owin/Startup.cs @@ -0,0 +1,55 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System; +using JavaScriptEngineSwitcher.Core; +using JavaScriptEngineSwitcher.V8; +using Microsoft.Owin.FileSystems; +using Microsoft.Owin.StaticFiles; + +using Owin; + +using React.Owin; + +namespace React.Sample.Owin +{ + internal class Startup + { + public void Configuration(IAppBuilder app) + { +#if DEBUG + app.UseErrorPage(); +#endif + + app.Use( + async (context, next) => + { + // Log all exceptions and incoming requests + Console.WriteLine("{0} {1} {2}", context.Request.Method, context.Request.Path, context.Request.QueryString); + + try + { + await next(); + } + catch (Exception exception) + { + Console.WriteLine(exception.ToString()); + throw; + } + }); + + var contentFileSystem = new PhysicalFileSystem("Content"); + app.UseBabel(new BabelFileOptions() { StaticFileOptions = new StaticFileOptions() { FileSystem = contentFileSystem }}); + app.UseFileServer(new FileServerOptions() { FileSystem = contentFileSystem }); + + JsEngineSwitcher.Current.DefaultEngineName = V8JsEngine.EngineName; + JsEngineSwitcher.Current.EngineFactories.AddV8(); + + app.Use(); + } + } +} diff --git a/src/React.Sample.Webpack.CoreMvc/README.md b/src/React.Sample.Webpack.CoreMvc/README.md new file mode 100644 index 000000000..159929543 --- /dev/null +++ b/src/React.Sample.Webpack.CoreMvc/README.md @@ -0,0 +1 @@ +The sample has been moved to .NET Core templates [here](../React.Template) \ No newline at end of file diff --git a/src/React.Template/React.Template.csproj b/src/React.Template/React.Template.csproj new file mode 100644 index 000000000..0cdb42673 --- /dev/null +++ b/src/React.Template/React.Template.csproj @@ -0,0 +1,27 @@ + + + + Template + React.Template + https://github.com/reactjs/react.net + https://github.com/reactjs/React.NET#licence + ReactJS.NET Template Pack + ReactJS.NET contributors + Templates to use for bootstrapping new ReactJS.NET applications. + dotnet-new;templates;react + + netstandard2.0 + + true + false + content + true + + + + + + + + + diff --git a/src/React.Template/reactnet-vanilla/.gitattributes b/src/React.Template/reactnet-vanilla/.gitattributes new file mode 100644 index 000000000..c7e67bc5d --- /dev/null +++ b/src/React.Template/reactnet-vanilla/.gitattributes @@ -0,0 +1,4 @@ +* text eol=lf +*.png binary +*.exe binary +*.dll binary diff --git a/src/React.Template/reactnet-vanilla/.gitignore b/src/React.Template/reactnet-vanilla/.gitignore new file mode 100644 index 000000000..8f8b43bb1 --- /dev/null +++ b/src/React.Template/reactnet-vanilla/.gitignore @@ -0,0 +1,232 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +build/ +bld/ +bin/ +Bin/ +obj/ +Obj/ + +# Visual Studio 2015 cache/options directory +.vs/ +/wwwroot/dist/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Microsoft Azure ApplicationInsights config file +ApplicationInsights.config + +# Windows Store app package directory +AppPackages/ +BundleArtifacts/ + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.pfx +*.publishsettings +orleans.codegen.cs + +/node_modules + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe + +# FAKE - F# Make +.fake/ diff --git a/src/React.Template/reactnet-vanilla/.template.config/template.json b/src/React.Template/reactnet-vanilla/.template.config/template.json new file mode 100644 index 000000000..18e9c5df8 --- /dev/null +++ b/src/React.Template/reactnet-vanilla/.template.config/template.json @@ -0,0 +1,13 @@ +{ + "author": "ReactJS.NET contributors", + "classifications": [ + "Web" + ], + "name": "React.NET Starter Template", + "identity": "React.Template.NetCore", + "shortName": "reactnet-vanilla", + "tags": { + "language": "C#" + }, + "preferNameDirectory": "true" +} diff --git a/src/React.Template/reactnet-vanilla/Controllers/HomeController.cs b/src/React.Template/reactnet-vanilla/Controllers/HomeController.cs new file mode 100644 index 000000000..d76a31b23 --- /dev/null +++ b/src/React.Template/reactnet-vanilla/Controllers/HomeController.cs @@ -0,0 +1,58 @@ +using System.Collections.Generic; +using Microsoft.AspNetCore.Mvc; +using ReactDemo.Models; + +namespace ReactDemo.Controllers +{ + public class HomeController : Controller + { + private static readonly IList _comments; + + static HomeController() + { + _comments = new List + { + new CommentModel + { + Id = 1, + Author = "Daniel Lo Nigro", + Text = "Hello ReactJS.NET World!" + }, + new CommentModel + { + Id = 2, + Author = "Pete Hunt", + Text = "This is one comment" + }, + new CommentModel + { + Id = 3, + Author = "Jordan Walke", + Text = "This is *another* comment" + }, + }; + } + + public ActionResult Index() + { + return View(_comments); + } + + [Route("comments")] + [ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)] + public ActionResult Comments() + { + return Json(_comments); + } + + [Route("comments/new")] + [HttpPost] + public ActionResult AddComment(CommentModel comment) + { + // Create a fake ID for this comment + comment.Id = _comments.Count + 1; + _comments.Add(comment); + return Content("Success :)"); + } + } +} \ No newline at end of file diff --git a/src/React.Template/reactnet-vanilla/Models/CommentModel.cs b/src/React.Template/reactnet-vanilla/Models/CommentModel.cs new file mode 100644 index 000000000..73fd4239a --- /dev/null +++ b/src/React.Template/reactnet-vanilla/Models/CommentModel.cs @@ -0,0 +1,9 @@ +namespace ReactDemo.Models +{ + public class CommentModel + { + public int Id { get; set; } + public string Author { get; set; } + public string Text { get; set; } + } +} \ No newline at end of file diff --git a/src/React.Template/reactnet-vanilla/Program.cs b/src/React.Template/reactnet-vanilla/Program.cs new file mode 100644 index 000000000..db0262272 --- /dev/null +++ b/src/React.Template/reactnet-vanilla/Program.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Hosting; + +namespace ReactDemo +{ + public class Program + { + public static void Main(string[] args) + { + var host = new WebHostBuilder() + .UseKestrel() + .UseContentRoot(Directory.GetCurrentDirectory()) + .UseIISIntegration() + .UseStartup() + .Build(); + + host.Run(); + } + } +} diff --git a/src/React.Template/reactnet-vanilla/Properties/launchSettings.json b/src/React.Template/reactnet-vanilla/Properties/launchSettings.json new file mode 100644 index 000000000..69c373ef1 --- /dev/null +++ b/src/React.Template/reactnet-vanilla/Properties/launchSettings.json @@ -0,0 +1,27 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:24139/", + "sslPort": 0 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "ReactDemo": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "http://localhost:5000", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} \ No newline at end of file diff --git a/src/React.Template/reactnet-vanilla/README.md b/src/React.Template/reactnet-vanilla/README.md new file mode 100644 index 000000000..c7e9cab59 --- /dev/null +++ b/src/React.Template/reactnet-vanilla/README.md @@ -0,0 +1 @@ +This is the source code from the [tutorial on the ReactJS.NET site](https://reactjs.net/getting-started/tutorial.html). \ No newline at end of file diff --git a/src/React.Template/reactnet-vanilla/ReactDemo.sln b/src/React.Template/reactnet-vanilla/ReactDemo.sln new file mode 100644 index 000000000..f37610f01 --- /dev/null +++ b/src/React.Template/reactnet-vanilla/ReactDemo.sln @@ -0,0 +1,30 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27004.2002 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{C71B9157-9688-4CFB-812C-D0DD3AB74F21}" + ProjectSection(SolutionItems) = preProject + global.json = global.json + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "tutorial-code", "tutorial-code.csproj", "{F8367AC0-D731-4946-BCA8-972A6DBE9730}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F8367AC0-D731-4946-BCA8-972A6DBE9730}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F8367AC0-D731-4946-BCA8-972A6DBE9730}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F8367AC0-D731-4946-BCA8-972A6DBE9730}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F8367AC0-D731-4946-BCA8-972A6DBE9730}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {B65CC77E-EFFF-479D-978E-F346AF031352} + EndGlobalSection +EndGlobal diff --git a/src/React.Template/reactnet-vanilla/Startup.cs b/src/React.Template/reactnet-vanilla/Startup.cs new file mode 100644 index 000000000..6ca7827e5 --- /dev/null +++ b/src/React.Template/reactnet-vanilla/Startup.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using JavaScriptEngineSwitcher.ChakraCore; +using JavaScriptEngineSwitcher.Extensions.MsDependencyInjection; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; +using React.AspNet; + +namespace ReactDemo +{ + public class Startup + { + public Startup(IWebHostEnvironment env) + { + var builder = new ConfigurationBuilder() + .SetBasePath(env.ContentRootPath) + .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) + .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) + .AddEnvironmentVariables(); + Configuration = builder.Build(); + } + + public IConfigurationRoot Configuration { get; } + + // This method gets called by the runtime. Use this method to add services to the container. + public void ConfigureServices(IServiceCollection services) + { + services.AddJsEngineSwitcher(options => options.DefaultEngineName = ChakraCoreJsEngine.EngineName) + .AddChakraCore(); + + services.AddSingleton(); + services.AddReact(); + // Add framework services. + services.AddMvc(); + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory) + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + app.UseBrowserLink(); + } + else + { + app.UseExceptionHandler("/Home/Error"); + } + + // Initialise ReactJS.NET. Must be before static files. + app.UseReact(config => + { + // If you want to use server-side rendering of React components, + // add all the necessary JavaScript files here. This includes + // your components as well as all of their dependencies. + // See http://reactjs.net/ for more information. Example: + config + .AddScript("~/js/remarkable.min.js") + .AddScript("~/js/tutorial.jsx") + .SetJsonSerializerSettings(new JsonSerializerSettings + { + StringEscapeHandling = StringEscapeHandling.EscapeHtml, + ContractResolver = new CamelCasePropertyNamesContractResolver() + }); + + // If you use an external build tool (for example, Babel, Webpack, + // Browserify or Gulp), you can improve performance by disabling + // ReactJS.NET's version of Babel and loading the pre-transpiled + // scripts. Example: + //config + // .SetLoadBabel(false) + // .AddScriptWithoutTransform("~/Scripts/bundle.server.js"); + }); + + app.UseStaticFiles(); + + app.UseRouting(); + + app.UseEndpoints(endpoints => + { + endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}"); + }); + } + } +} diff --git a/src/React.Template/reactnet-vanilla/Views/Home/Index.cshtml b/src/React.Template/reactnet-vanilla/Views/Home/Index.cshtml new file mode 100644 index 000000000..e4b22b283 --- /dev/null +++ b/src/React.Template/reactnet-vanilla/Views/Home/Index.cshtml @@ -0,0 +1,24 @@ +@model IEnumerable +@{ + Layout = null; +} + + + Hello React + + + @Html.React("CommentBox", new + { + initialData = Model, + url = Url.Action("Comments"), + submitUrl = Url.Action("AddComment"), + pollInterval = 2000, + }) + + + + + + @Html.ReactInitJavaScript() + + diff --git a/src/React.Template/reactnet-vanilla/Views/_ViewImports.cshtml b/src/React.Template/reactnet-vanilla/Views/_ViewImports.cshtml new file mode 100644 index 000000000..11c546783 --- /dev/null +++ b/src/React.Template/reactnet-vanilla/Views/_ViewImports.cshtml @@ -0,0 +1,3 @@ +@using ReactDemo +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers +@using React.AspNet \ No newline at end of file diff --git a/src/React.Template/reactnet-vanilla/app.config b/src/React.Template/reactnet-vanilla/app.config new file mode 100644 index 000000000..49aadfaa0 --- /dev/null +++ b/src/React.Template/reactnet-vanilla/app.config @@ -0,0 +1,5 @@ + + + + + diff --git a/src/React.Template/reactnet-vanilla/appsettings.json b/src/React.Template/reactnet-vanilla/appsettings.json new file mode 100644 index 000000000..fa8ce71a9 --- /dev/null +++ b/src/React.Template/reactnet-vanilla/appsettings.json @@ -0,0 +1,10 @@ +{ + "Logging": { + "IncludeScopes": false, + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } + } +} diff --git a/src/React.Template/reactnet-vanilla/tutorial-code.csproj b/src/React.Template/reactnet-vanilla/tutorial-code.csproj new file mode 100644 index 000000000..26f0680f3 --- /dev/null +++ b/src/React.Template/reactnet-vanilla/tutorial-code.csproj @@ -0,0 +1,30 @@ + + + netcoreapp3.0 + true + tutorial-code + Exe + tutorial-code + + + + + PreserveNewest + + + + + + + + + + + + + + + Always + + + diff --git a/src/React.Template/reactnet-vanilla/web.config b/src/React.Template/reactnet-vanilla/web.config new file mode 100644 index 000000000..a2cf1fe26 --- /dev/null +++ b/src/React.Template/reactnet-vanilla/web.config @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/React.Template/reactnet-vanilla/wwwroot/js/remarkable.min.js b/src/React.Template/reactnet-vanilla/wwwroot/js/remarkable.min.js new file mode 100644 index 000000000..72e72e324 --- /dev/null +++ b/src/React.Template/reactnet-vanilla/wwwroot/js/remarkable.min.js @@ -0,0 +1,4 @@ +/*! remarkable 1.7.1 https://github.com/jonschlinkert/remarkable @license MIT */ +!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.Remarkable=e()}}(function(){var e;return function t(e,r,n){function s(i,l){if(!r[i]){if(!e[i]){var a="function"==typeof require&&require;if(!l&&a)return a(i,!0);if(o)return o(i,!0);var c=new Error("Cannot find module '"+i+"'");throw c.code="MODULE_NOT_FOUND",c}var u=r[i]={exports:{}};e[i][0].call(u.exports,function(t){var r=e[i][1][t];return s(r?r:t)},u,u.exports,t,e,r,n)}return r[i].exports}for(var o="function"==typeof require&&require,i=0;i",Gt:"≫",gt:">",gtcc:"⪧",gtcir:"⩺",gtdot:"⋗",gtlPar:"⦕",gtquest:"⩼",gtrapprox:"⪆",gtrarr:"⥸",gtrdot:"⋗",gtreqless:"⋛",gtreqqless:"⪌",gtrless:"≷",gtrsim:"≳",gvertneqq:"≩︀",gvnE:"≩︀",Hacek:"ˇ",hairsp:" ",half:"½",hamilt:"ℋ",HARDcy:"Ъ",hardcy:"ъ",hArr:"⇔",harr:"↔",harrcir:"⥈",harrw:"↭",Hat:"^",hbar:"ℏ",Hcirc:"Ĥ",hcirc:"ĥ",hearts:"♥",heartsuit:"♥",hellip:"…",hercon:"⊹",Hfr:"ℌ",hfr:"𝔥",HilbertSpace:"ℋ",hksearow:"⤥",hkswarow:"⤦",hoarr:"⇿",homtht:"∻",hookleftarrow:"↩",hookrightarrow:"↪",Hopf:"ℍ",hopf:"𝕙",horbar:"―",HorizontalLine:"─",Hscr:"ℋ",hscr:"𝒽",hslash:"ℏ",Hstrok:"Ħ",hstrok:"ħ",HumpDownHump:"≎",HumpEqual:"≏",hybull:"⁃",hyphen:"‐",Iacute:"Í",iacute:"í",ic:"⁣",Icirc:"Î",icirc:"î",Icy:"И",icy:"и",Idot:"İ",IEcy:"Е",iecy:"е",iexcl:"¡",iff:"⇔",Ifr:"ℑ",ifr:"𝔦",Igrave:"Ì",igrave:"ì",ii:"ⅈ",iiiint:"⨌",iiint:"∭",iinfin:"⧜",iiota:"℩",IJlig:"IJ",ijlig:"ij",Im:"ℑ",Imacr:"Ī",imacr:"ī",image:"ℑ",ImaginaryI:"ⅈ",imagline:"ℐ",imagpart:"ℑ",imath:"ı",imof:"⊷",imped:"Ƶ",Implies:"⇒","in":"∈",incare:"℅",infin:"∞",infintie:"⧝",inodot:"ı",Int:"∬","int":"∫",intcal:"⊺",integers:"ℤ",Integral:"∫",intercal:"⊺",Intersection:"⋂",intlarhk:"⨗",intprod:"⨼",InvisibleComma:"⁣",InvisibleTimes:"⁢",IOcy:"Ё",iocy:"ё",Iogon:"Į",iogon:"į",Iopf:"𝕀",iopf:"𝕚",Iota:"Ι",iota:"ι",iprod:"⨼",iquest:"¿",Iscr:"ℐ",iscr:"𝒾",isin:"∈",isindot:"⋵",isinE:"⋹",isins:"⋴",isinsv:"⋳",isinv:"∈",it:"⁢",Itilde:"Ĩ",itilde:"ĩ",Iukcy:"І",iukcy:"і",Iuml:"Ï",iuml:"ï",Jcirc:"Ĵ",jcirc:"ĵ",Jcy:"Й",jcy:"й",Jfr:"𝔍",jfr:"𝔧",jmath:"ȷ",Jopf:"𝕁",jopf:"𝕛",Jscr:"𝒥",jscr:"𝒿",Jsercy:"Ј",jsercy:"ј",Jukcy:"Є",jukcy:"є",Kappa:"Κ",kappa:"κ",kappav:"ϰ",Kcedil:"Ķ",kcedil:"ķ",Kcy:"К",kcy:"к",Kfr:"𝔎",kfr:"𝔨",kgreen:"ĸ",KHcy:"Х",khcy:"х",KJcy:"Ќ",kjcy:"ќ",Kopf:"𝕂",kopf:"𝕜",Kscr:"𝒦",kscr:"𝓀",lAarr:"⇚",Lacute:"Ĺ",lacute:"ĺ",laemptyv:"⦴",lagran:"ℒ",Lambda:"Λ",lambda:"λ",Lang:"⟪",lang:"⟨",langd:"⦑",langle:"⟨",lap:"⪅",Laplacetrf:"ℒ",laquo:"«",Larr:"↞",lArr:"⇐",larr:"←",larrb:"⇤",larrbfs:"⤟",larrfs:"⤝",larrhk:"↩",larrlp:"↫",larrpl:"⤹",larrsim:"⥳",larrtl:"↢",lat:"⪫",lAtail:"⤛",latail:"⤙",late:"⪭",lates:"⪭︀",lBarr:"⤎",lbarr:"⤌",lbbrk:"❲",lbrace:"{",lbrack:"[",lbrke:"⦋",lbrksld:"⦏",lbrkslu:"⦍",Lcaron:"Ľ",lcaron:"ľ",Lcedil:"Ļ",lcedil:"ļ",lceil:"⌈",lcub:"{",Lcy:"Л",lcy:"л",ldca:"⤶",ldquo:"“",ldquor:"„",ldrdhar:"⥧",ldrushar:"⥋",ldsh:"↲",lE:"≦",le:"≤",LeftAngleBracket:"⟨",LeftArrow:"←",Leftarrow:"⇐",leftarrow:"←",LeftArrowBar:"⇤",LeftArrowRightArrow:"⇆",leftarrowtail:"↢",LeftCeiling:"⌈",LeftDoubleBracket:"⟦",LeftDownTeeVector:"⥡",LeftDownVector:"⇃",LeftDownVectorBar:"⥙",LeftFloor:"⌊",leftharpoondown:"↽",leftharpoonup:"↼",leftleftarrows:"⇇",LeftRightArrow:"↔",Leftrightarrow:"⇔",leftrightarrow:"↔",leftrightarrows:"⇆",leftrightharpoons:"⇋",leftrightsquigarrow:"↭",LeftRightVector:"⥎",LeftTee:"⊣",LeftTeeArrow:"↤",LeftTeeVector:"⥚",leftthreetimes:"⋋",LeftTriangle:"⊲",LeftTriangleBar:"⧏",LeftTriangleEqual:"⊴",LeftUpDownVector:"⥑",LeftUpTeeVector:"⥠",LeftUpVector:"↿",LeftUpVectorBar:"⥘",LeftVector:"↼",LeftVectorBar:"⥒",lEg:"⪋",leg:"⋚",leq:"≤",leqq:"≦",leqslant:"⩽",les:"⩽",lescc:"⪨",lesdot:"⩿",lesdoto:"⪁",lesdotor:"⪃",lesg:"⋚︀",lesges:"⪓",lessapprox:"⪅",lessdot:"⋖",lesseqgtr:"⋚",lesseqqgtr:"⪋",LessEqualGreater:"⋚",LessFullEqual:"≦",LessGreater:"≶",lessgtr:"≶",LessLess:"⪡",lesssim:"≲",LessSlantEqual:"⩽",LessTilde:"≲",lfisht:"⥼",lfloor:"⌊",Lfr:"𝔏",lfr:"𝔩",lg:"≶",lgE:"⪑",lHar:"⥢",lhard:"↽",lharu:"↼",lharul:"⥪",lhblk:"▄",LJcy:"Љ",ljcy:"љ",Ll:"⋘",ll:"≪",llarr:"⇇",llcorner:"⌞",Lleftarrow:"⇚",llhard:"⥫",lltri:"◺",Lmidot:"Ŀ",lmidot:"ŀ",lmoust:"⎰",lmoustache:"⎰",lnap:"⪉",lnapprox:"⪉",lnE:"≨",lne:"⪇",lneq:"⪇",lneqq:"≨",lnsim:"⋦",loang:"⟬",loarr:"⇽",lobrk:"⟦",LongLeftArrow:"⟵",Longleftarrow:"⟸",longleftarrow:"⟵",LongLeftRightArrow:"⟷",Longleftrightarrow:"⟺",longleftrightarrow:"⟷",longmapsto:"⟼",LongRightArrow:"⟶",Longrightarrow:"⟹",longrightarrow:"⟶",looparrowleft:"↫",looparrowright:"↬",lopar:"⦅",Lopf:"𝕃",lopf:"𝕝",loplus:"⨭",lotimes:"⨴",lowast:"∗",lowbar:"_",LowerLeftArrow:"↙",LowerRightArrow:"↘",loz:"◊",lozenge:"◊",lozf:"⧫",lpar:"(",lparlt:"⦓",lrarr:"⇆",lrcorner:"⌟",lrhar:"⇋",lrhard:"⥭",lrm:"‎",lrtri:"⊿",lsaquo:"‹",Lscr:"ℒ",lscr:"𝓁",Lsh:"↰",lsh:"↰",lsim:"≲",lsime:"⪍",lsimg:"⪏",lsqb:"[",lsquo:"‘",lsquor:"‚",Lstrok:"Ł",lstrok:"ł",LT:"<",Lt:"≪",lt:"<",ltcc:"⪦",ltcir:"⩹",ltdot:"⋖",lthree:"⋋",ltimes:"⋉",ltlarr:"⥶",ltquest:"⩻",ltri:"◃",ltrie:"⊴",ltrif:"◂",ltrPar:"⦖",lurdshar:"⥊",luruhar:"⥦",lvertneqq:"≨︀",lvnE:"≨︀",macr:"¯",male:"♂",malt:"✠",maltese:"✠",Map:"⤅",map:"↦",mapsto:"↦",mapstodown:"↧",mapstoleft:"↤",mapstoup:"↥",marker:"▮",mcomma:"⨩",Mcy:"М",mcy:"м",mdash:"—",mDDot:"∺",measuredangle:"∡",MediumSpace:" ",Mellintrf:"ℳ",Mfr:"𝔐",mfr:"𝔪",mho:"℧",micro:"µ",mid:"∣",midast:"*",midcir:"⫰",middot:"·",minus:"−",minusb:"⊟",minusd:"∸",minusdu:"⨪",MinusPlus:"∓",mlcp:"⫛",mldr:"…",mnplus:"∓",models:"⊧",Mopf:"𝕄",mopf:"𝕞",mp:"∓",Mscr:"ℳ",mscr:"𝓂",mstpos:"∾",Mu:"Μ",mu:"μ",multimap:"⊸",mumap:"⊸",nabla:"∇",Nacute:"Ń",nacute:"ń",nang:"∠⃒",nap:"≉",napE:"⩰̸",napid:"≋̸",napos:"ʼn",napprox:"≉",natur:"♮",natural:"♮",naturals:"ℕ",nbsp:" ",nbump:"≎̸",nbumpe:"≏̸",ncap:"⩃",Ncaron:"Ň",ncaron:"ň",Ncedil:"Ņ",ncedil:"ņ",ncong:"≇",ncongdot:"⩭̸",ncup:"⩂",Ncy:"Н",ncy:"н",ndash:"–",ne:"≠",nearhk:"⤤",neArr:"⇗",nearr:"↗",nearrow:"↗",nedot:"≐̸",NegativeMediumSpace:"​",NegativeThickSpace:"​",NegativeThinSpace:"​",NegativeVeryThinSpace:"​",nequiv:"≢",nesear:"⤨",nesim:"≂̸",NestedGreaterGreater:"≫",NestedLessLess:"≪",NewLine:"\n",nexist:"∄",nexists:"∄",Nfr:"𝔑",nfr:"𝔫",ngE:"≧̸",nge:"≱",ngeq:"≱",ngeqq:"≧̸",ngeqslant:"⩾̸",nges:"⩾̸",nGg:"⋙̸",ngsim:"≵",nGt:"≫⃒",ngt:"≯",ngtr:"≯",nGtv:"≫̸",nhArr:"⇎",nharr:"↮",nhpar:"⫲",ni:"∋",nis:"⋼",nisd:"⋺",niv:"∋",NJcy:"Њ",njcy:"њ",nlArr:"⇍",nlarr:"↚",nldr:"‥",nlE:"≦̸",nle:"≰",nLeftarrow:"⇍",nleftarrow:"↚",nLeftrightarrow:"⇎",nleftrightarrow:"↮",nleq:"≰",nleqq:"≦̸",nleqslant:"⩽̸",nles:"⩽̸",nless:"≮",nLl:"⋘̸",nlsim:"≴",nLt:"≪⃒",nlt:"≮",nltri:"⋪",nltrie:"⋬",nLtv:"≪̸",nmid:"∤",NoBreak:"⁠",NonBreakingSpace:" ",Nopf:"ℕ",nopf:"𝕟",Not:"⫬",not:"¬",NotCongruent:"≢",NotCupCap:"≭",NotDoubleVerticalBar:"∦",NotElement:"∉",NotEqual:"≠",NotEqualTilde:"≂̸",NotExists:"∄",NotGreater:"≯",NotGreaterEqual:"≱",NotGreaterFullEqual:"≧̸",NotGreaterGreater:"≫̸",NotGreaterLess:"≹",NotGreaterSlantEqual:"⩾̸",NotGreaterTilde:"≵",NotHumpDownHump:"≎̸",NotHumpEqual:"≏̸",notin:"∉",notindot:"⋵̸",notinE:"⋹̸",notinva:"∉",notinvb:"⋷",notinvc:"⋶",NotLeftTriangle:"⋪",NotLeftTriangleBar:"⧏̸",NotLeftTriangleEqual:"⋬",NotLess:"≮",NotLessEqual:"≰",NotLessGreater:"≸",NotLessLess:"≪̸",NotLessSlantEqual:"⩽̸",NotLessTilde:"≴",NotNestedGreaterGreater:"⪢̸",NotNestedLessLess:"⪡̸",notni:"∌",notniva:"∌",notnivb:"⋾",notnivc:"⋽",NotPrecedes:"⊀",NotPrecedesEqual:"⪯̸",NotPrecedesSlantEqual:"⋠",NotReverseElement:"∌",NotRightTriangle:"⋫",NotRightTriangleBar:"⧐̸",NotRightTriangleEqual:"⋭",NotSquareSubset:"⊏̸",NotSquareSubsetEqual:"⋢",NotSquareSuperset:"⊐̸",NotSquareSupersetEqual:"⋣",NotSubset:"⊂⃒",NotSubsetEqual:"⊈",NotSucceeds:"⊁",NotSucceedsEqual:"⪰̸",NotSucceedsSlantEqual:"⋡",NotSucceedsTilde:"≿̸",NotSuperset:"⊃⃒",NotSupersetEqual:"⊉",NotTilde:"≁",NotTildeEqual:"≄",NotTildeFullEqual:"≇",NotTildeTilde:"≉",NotVerticalBar:"∤",npar:"∦",nparallel:"∦",nparsl:"⫽⃥",npart:"∂̸",npolint:"⨔",npr:"⊀",nprcue:"⋠",npre:"⪯̸",nprec:"⊀",npreceq:"⪯̸",nrArr:"⇏",nrarr:"↛",nrarrc:"⤳̸",nrarrw:"↝̸",nRightarrow:"⇏",nrightarrow:"↛",nrtri:"⋫",nrtrie:"⋭",nsc:"⊁",nsccue:"⋡",nsce:"⪰̸",Nscr:"𝒩",nscr:"𝓃",nshortmid:"∤",nshortparallel:"∦",nsim:"≁",nsime:"≄",nsimeq:"≄",nsmid:"∤",nspar:"∦",nsqsube:"⋢",nsqsupe:"⋣",nsub:"⊄",nsubE:"⫅̸",nsube:"⊈",nsubset:"⊂⃒",nsubseteq:"⊈",nsubseteqq:"⫅̸",nsucc:"⊁",nsucceq:"⪰̸",nsup:"⊅",nsupE:"⫆̸",nsupe:"⊉",nsupset:"⊃⃒",nsupseteq:"⊉",nsupseteqq:"⫆̸",ntgl:"≹",Ntilde:"Ñ",ntilde:"ñ",ntlg:"≸",ntriangleleft:"⋪",ntrianglelefteq:"⋬",ntriangleright:"⋫",ntrianglerighteq:"⋭",Nu:"Ν",nu:"ν",num:"#",numero:"№",numsp:" ",nvap:"≍⃒",nVDash:"⊯",nVdash:"⊮",nvDash:"⊭",nvdash:"⊬",nvge:"≥⃒",nvgt:">⃒",nvHarr:"⤄",nvinfin:"⧞",nvlArr:"⤂",nvle:"≤⃒",nvlt:"<⃒",nvltrie:"⊴⃒",nvrArr:"⤃",nvrtrie:"⊵⃒",nvsim:"∼⃒",nwarhk:"⤣",nwArr:"⇖",nwarr:"↖",nwarrow:"↖",nwnear:"⤧",Oacute:"Ó",oacute:"ó",oast:"⊛",ocir:"⊚",Ocirc:"Ô",ocirc:"ô",Ocy:"О",ocy:"о",odash:"⊝",Odblac:"Ő",odblac:"ő",odiv:"⨸",odot:"⊙",odsold:"⦼",OElig:"Œ",oelig:"œ",ofcir:"⦿",Ofr:"𝔒",ofr:"𝔬",ogon:"˛",Ograve:"Ò",ograve:"ò",ogt:"⧁",ohbar:"⦵",ohm:"Ω",oint:"∮",olarr:"↺",olcir:"⦾",olcross:"⦻",oline:"‾",olt:"⧀",Omacr:"Ō",omacr:"ō",Omega:"Ω",omega:"ω",Omicron:"Ο",omicron:"ο",omid:"⦶",ominus:"⊖",Oopf:"𝕆",oopf:"𝕠",opar:"⦷",OpenCurlyDoubleQuote:"“",OpenCurlyQuote:"‘",operp:"⦹",oplus:"⊕",Or:"⩔",or:"∨",orarr:"↻",ord:"⩝",order:"ℴ",orderof:"ℴ",ordf:"ª",ordm:"º",origof:"⊶",oror:"⩖",orslope:"⩗",orv:"⩛",oS:"Ⓢ",Oscr:"𝒪",oscr:"ℴ",Oslash:"Ø",oslash:"ø",osol:"⊘",Otilde:"Õ",otilde:"õ",Otimes:"⨷",otimes:"⊗",otimesas:"⨶",Ouml:"Ö",ouml:"ö",ovbar:"⌽",OverBar:"‾",OverBrace:"⏞",OverBracket:"⎴",OverParenthesis:"⏜",par:"∥",para:"¶",parallel:"∥",parsim:"⫳",parsl:"⫽",part:"∂",PartialD:"∂",Pcy:"П",pcy:"п",percnt:"%",period:".",permil:"‰",perp:"⊥",pertenk:"‱",Pfr:"𝔓",pfr:"𝔭",Phi:"Φ",phi:"φ",phiv:"ϕ",phmmat:"ℳ",phone:"☎",Pi:"Π",pi:"π",pitchfork:"⋔",piv:"ϖ",planck:"ℏ",planckh:"ℎ",plankv:"ℏ",plus:"+",plusacir:"⨣",plusb:"⊞",pluscir:"⨢",plusdo:"∔",plusdu:"⨥",pluse:"⩲",PlusMinus:"±",plusmn:"±",plussim:"⨦",plustwo:"⨧",pm:"±",Poincareplane:"ℌ",pointint:"⨕",Popf:"ℙ",popf:"𝕡",pound:"£",Pr:"⪻",pr:"≺",prap:"⪷",prcue:"≼",prE:"⪳",pre:"⪯",prec:"≺",precapprox:"⪷",preccurlyeq:"≼",Precedes:"≺",PrecedesEqual:"⪯",PrecedesSlantEqual:"≼",PrecedesTilde:"≾",preceq:"⪯",precnapprox:"⪹",precneqq:"⪵",precnsim:"⋨",precsim:"≾",Prime:"″",prime:"′",primes:"ℙ",prnap:"⪹",prnE:"⪵",prnsim:"⋨",prod:"∏",Product:"∏",profalar:"⌮",profline:"⌒",profsurf:"⌓",prop:"∝",Proportion:"∷",Proportional:"∝",propto:"∝",prsim:"≾",prurel:"⊰",Pscr:"𝒫",pscr:"𝓅",Psi:"Ψ",psi:"ψ",puncsp:" ",Qfr:"𝔔",qfr:"𝔮",qint:"⨌",Qopf:"ℚ",qopf:"𝕢",qprime:"⁗",Qscr:"𝒬",qscr:"𝓆",quaternions:"ℍ",quatint:"⨖",quest:"?",questeq:"≟",QUOT:'"',quot:'"',rAarr:"⇛",race:"∽̱",Racute:"Ŕ",racute:"ŕ",radic:"√",raemptyv:"⦳",Rang:"⟫",rang:"⟩",rangd:"⦒",range:"⦥",rangle:"⟩",raquo:"»",Rarr:"↠",rArr:"⇒",rarr:"→",rarrap:"⥵",rarrb:"⇥",rarrbfs:"⤠",rarrc:"⤳",rarrfs:"⤞",rarrhk:"↪",rarrlp:"↬",rarrpl:"⥅",rarrsim:"⥴",Rarrtl:"⤖",rarrtl:"↣",rarrw:"↝",rAtail:"⤜",ratail:"⤚",ratio:"∶",rationals:"ℚ",RBarr:"⤐",rBarr:"⤏",rbarr:"⤍",rbbrk:"❳",rbrace:"}",rbrack:"]",rbrke:"⦌",rbrksld:"⦎",rbrkslu:"⦐",Rcaron:"Ř",rcaron:"ř",Rcedil:"Ŗ",rcedil:"ŗ",rceil:"⌉",rcub:"}",Rcy:"Р",rcy:"р",rdca:"⤷",rdldhar:"⥩",rdquo:"”",rdquor:"”",rdsh:"↳",Re:"ℜ",real:"ℜ",realine:"ℛ",realpart:"ℜ",reals:"ℝ",rect:"▭",REG:"®",reg:"®",ReverseElement:"∋",ReverseEquilibrium:"⇋",ReverseUpEquilibrium:"⥯",rfisht:"⥽",rfloor:"⌋",Rfr:"ℜ",rfr:"𝔯",rHar:"⥤",rhard:"⇁",rharu:"⇀",rharul:"⥬",Rho:"Ρ",rho:"ρ",rhov:"ϱ",RightAngleBracket:"⟩",RightArrow:"→",Rightarrow:"⇒",rightarrow:"→",RightArrowBar:"⇥",RightArrowLeftArrow:"⇄",rightarrowtail:"↣",RightCeiling:"⌉",RightDoubleBracket:"⟧",RightDownTeeVector:"⥝",RightDownVector:"⇂",RightDownVectorBar:"⥕",RightFloor:"⌋",rightharpoondown:"⇁",rightharpoonup:"⇀",rightleftarrows:"⇄",rightleftharpoons:"⇌",rightrightarrows:"⇉",rightsquigarrow:"↝",RightTee:"⊢",RightTeeArrow:"↦",RightTeeVector:"⥛",rightthreetimes:"⋌",RightTriangle:"⊳",RightTriangleBar:"⧐",RightTriangleEqual:"⊵",RightUpDownVector:"⥏",RightUpTeeVector:"⥜",RightUpVector:"↾",RightUpVectorBar:"⥔",RightVector:"⇀",RightVectorBar:"⥓",ring:"˚",risingdotseq:"≓",rlarr:"⇄",rlhar:"⇌",rlm:"‏",rmoust:"⎱",rmoustache:"⎱",rnmid:"⫮",roang:"⟭",roarr:"⇾",robrk:"⟧",ropar:"⦆",Ropf:"ℝ",ropf:"𝕣",roplus:"⨮",rotimes:"⨵",RoundImplies:"⥰",rpar:")",rpargt:"⦔",rppolint:"⨒",rrarr:"⇉",Rrightarrow:"⇛",rsaquo:"›",Rscr:"ℛ",rscr:"𝓇",Rsh:"↱",rsh:"↱",rsqb:"]",rsquo:"’",rsquor:"’",rthree:"⋌",rtimes:"⋊",rtri:"▹",rtrie:"⊵",rtrif:"▸",rtriltri:"⧎",RuleDelayed:"⧴",ruluhar:"⥨",rx:"℞",Sacute:"Ś",sacute:"ś",sbquo:"‚",Sc:"⪼",sc:"≻",scap:"⪸",Scaron:"Š",scaron:"š",sccue:"≽",scE:"⪴",sce:"⪰",Scedil:"Ş",scedil:"ş",Scirc:"Ŝ",scirc:"ŝ",scnap:"⪺",scnE:"⪶",scnsim:"⋩",scpolint:"⨓",scsim:"≿",Scy:"С",scy:"с",sdot:"⋅",sdotb:"⊡",sdote:"⩦",searhk:"⤥",seArr:"⇘",searr:"↘",searrow:"↘",sect:"§",semi:";",seswar:"⤩",setminus:"∖",setmn:"∖",sext:"✶",Sfr:"𝔖",sfr:"𝔰",sfrown:"⌢",sharp:"♯",SHCHcy:"Щ",shchcy:"щ",SHcy:"Ш",shcy:"ш",ShortDownArrow:"↓",ShortLeftArrow:"←",shortmid:"∣",shortparallel:"∥",ShortRightArrow:"→",ShortUpArrow:"↑",shy:"­",Sigma:"Σ",sigma:"σ",sigmaf:"ς",sigmav:"ς",sim:"∼",simdot:"⩪",sime:"≃",simeq:"≃",simg:"⪞",simgE:"⪠",siml:"⪝",simlE:"⪟",simne:"≆",simplus:"⨤",simrarr:"⥲",slarr:"←",SmallCircle:"∘",smallsetminus:"∖",smashp:"⨳",smeparsl:"⧤",smid:"∣",smile:"⌣",smt:"⪪",smte:"⪬",smtes:"⪬︀",SOFTcy:"Ь",softcy:"ь",sol:"/",solb:"⧄",solbar:"⌿",Sopf:"𝕊",sopf:"𝕤",spades:"♠",spadesuit:"♠",spar:"∥",sqcap:"⊓",sqcaps:"⊓︀",sqcup:"⊔",sqcups:"⊔︀",Sqrt:"√",sqsub:"⊏",sqsube:"⊑",sqsubset:"⊏",sqsubseteq:"⊑",sqsup:"⊐",sqsupe:"⊒",sqsupset:"⊐",sqsupseteq:"⊒",squ:"□",Square:"□",square:"□",SquareIntersection:"⊓",SquareSubset:"⊏",SquareSubsetEqual:"⊑",SquareSuperset:"⊐",SquareSupersetEqual:"⊒",SquareUnion:"⊔",squarf:"▪",squf:"▪",srarr:"→",Sscr:"𝒮",sscr:"𝓈",ssetmn:"∖",ssmile:"⌣",sstarf:"⋆",Star:"⋆",star:"☆",starf:"★",straightepsilon:"ϵ",straightphi:"ϕ",strns:"¯",Sub:"⋐",sub:"⊂",subdot:"⪽",subE:"⫅",sube:"⊆",subedot:"⫃",submult:"⫁",subnE:"⫋",subne:"⊊",subplus:"⪿",subrarr:"⥹",Subset:"⋐",subset:"⊂",subseteq:"⊆",subseteqq:"⫅",SubsetEqual:"⊆",subsetneq:"⊊",subsetneqq:"⫋",subsim:"⫇",subsub:"⫕",subsup:"⫓",succ:"≻",succapprox:"⪸",succcurlyeq:"≽",Succeeds:"≻",SucceedsEqual:"⪰",SucceedsSlantEqual:"≽",SucceedsTilde:"≿",succeq:"⪰",succnapprox:"⪺",succneqq:"⪶",succnsim:"⋩",succsim:"≿",SuchThat:"∋",Sum:"∑",sum:"∑",sung:"♪",Sup:"⋑",sup:"⊃",sup1:"¹",sup2:"²",sup3:"³",supdot:"⪾",supdsub:"⫘",supE:"⫆",supe:"⊇",supedot:"⫄",Superset:"⊃",SupersetEqual:"⊇",suphsol:"⟉",suphsub:"⫗",suplarr:"⥻",supmult:"⫂",supnE:"⫌",supne:"⊋",supplus:"⫀",Supset:"⋑",supset:"⊃",supseteq:"⊇",supseteqq:"⫆",supsetneq:"⊋",supsetneqq:"⫌",supsim:"⫈",supsub:"⫔",supsup:"⫖",swarhk:"⤦",swArr:"⇙",swarr:"↙",swarrow:"↙",swnwar:"⤪",szlig:"ß",Tab:" ",target:"⌖",Tau:"Τ",tau:"τ",tbrk:"⎴",Tcaron:"Ť",tcaron:"ť",Tcedil:"Ţ",tcedil:"ţ",Tcy:"Т",tcy:"т",tdot:"⃛",telrec:"⌕",Tfr:"𝔗",tfr:"𝔱",there4:"∴",Therefore:"∴",therefore:"∴",Theta:"Θ",theta:"θ",thetasym:"ϑ",thetav:"ϑ",thickapprox:"≈",thicksim:"∼",ThickSpace:"  ",thinsp:" ",ThinSpace:" ",thkap:"≈",thksim:"∼",THORN:"Þ",thorn:"þ",Tilde:"∼",tilde:"˜",TildeEqual:"≃",TildeFullEqual:"≅",TildeTilde:"≈",times:"×",timesb:"⊠",timesbar:"⨱",timesd:"⨰",tint:"∭",toea:"⤨",top:"⊤",topbot:"⌶",topcir:"⫱",Topf:"𝕋",topf:"𝕥",topfork:"⫚",tosa:"⤩",tprime:"‴",TRADE:"™",trade:"™",triangle:"▵",triangledown:"▿",triangleleft:"◃",trianglelefteq:"⊴",triangleq:"≜",triangleright:"▹",trianglerighteq:"⊵",tridot:"◬",trie:"≜",triminus:"⨺",TripleDot:"⃛",triplus:"⨹",trisb:"⧍",tritime:"⨻",trpezium:"⏢",Tscr:"𝒯",tscr:"𝓉",TScy:"Ц",tscy:"ц",TSHcy:"Ћ",tshcy:"ћ",Tstrok:"Ŧ",tstrok:"ŧ",twixt:"≬",twoheadleftarrow:"↞",twoheadrightarrow:"↠",Uacute:"Ú",uacute:"ú",Uarr:"↟",uArr:"⇑",uarr:"↑",Uarrocir:"⥉",Ubrcy:"Ў",ubrcy:"ў",Ubreve:"Ŭ",ubreve:"ŭ",Ucirc:"Û",ucirc:"û",Ucy:"У",ucy:"у",udarr:"⇅",Udblac:"Ű",udblac:"ű",udhar:"⥮",ufisht:"⥾",Ufr:"𝔘",ufr:"𝔲",Ugrave:"Ù",ugrave:"ù",uHar:"⥣",uharl:"↿",uharr:"↾",uhblk:"▀",ulcorn:"⌜",ulcorner:"⌜",ulcrop:"⌏",ultri:"◸",Umacr:"Ū",umacr:"ū",uml:"¨",UnderBar:"_",UnderBrace:"⏟",UnderBracket:"⎵",UnderParenthesis:"⏝",Union:"⋃",UnionPlus:"⊎",Uogon:"Ų",uogon:"ų",Uopf:"𝕌",uopf:"𝕦",UpArrow:"↑",Uparrow:"⇑",uparrow:"↑",UpArrowBar:"⤒",UpArrowDownArrow:"⇅",UpDownArrow:"↕",Updownarrow:"⇕",updownarrow:"↕",UpEquilibrium:"⥮",upharpoonleft:"↿",upharpoonright:"↾",uplus:"⊎",UpperLeftArrow:"↖",UpperRightArrow:"↗",Upsi:"ϒ",upsi:"υ",upsih:"ϒ",Upsilon:"Υ",upsilon:"υ",UpTee:"⊥",UpTeeArrow:"↥",upuparrows:"⇈",urcorn:"⌝",urcorner:"⌝",urcrop:"⌎",Uring:"Ů",uring:"ů",urtri:"◹",Uscr:"𝒰",uscr:"𝓊",utdot:"⋰",Utilde:"Ũ",utilde:"ũ",utri:"▵",utrif:"▴",uuarr:"⇈",Uuml:"Ü",uuml:"ü",uwangle:"⦧",vangrt:"⦜",varepsilon:"ϵ",varkappa:"ϰ",varnothing:"∅",varphi:"ϕ",varpi:"ϖ",varpropto:"∝",vArr:"⇕",varr:"↕",varrho:"ϱ",varsigma:"ς",varsubsetneq:"⊊︀",varsubsetneqq:"⫋︀",varsupsetneq:"⊋︀",varsupsetneqq:"⫌︀",vartheta:"ϑ",vartriangleleft:"⊲",vartriangleright:"⊳",Vbar:"⫫",vBar:"⫨",vBarv:"⫩",Vcy:"В",vcy:"в",VDash:"⊫",Vdash:"⊩",vDash:"⊨",vdash:"⊢",Vdashl:"⫦",Vee:"⋁",vee:"∨",veebar:"⊻",veeeq:"≚",vellip:"⋮",Verbar:"‖",verbar:"|",Vert:"‖",vert:"|",VerticalBar:"∣",VerticalLine:"|",VerticalSeparator:"❘",VerticalTilde:"≀",VeryThinSpace:" ",Vfr:"𝔙",vfr:"𝔳",vltri:"⊲",vnsub:"⊂⃒",vnsup:"⊃⃒",Vopf:"𝕍",vopf:"𝕧",vprop:"∝",vrtri:"⊳",Vscr:"𝒱",vscr:"𝓋",vsubnE:"⫋︀",vsubne:"⊊︀",vsupnE:"⫌︀",vsupne:"⊋︀",Vvdash:"⊪",vzigzag:"⦚",Wcirc:"Ŵ",wcirc:"ŵ",wedbar:"⩟",Wedge:"⋀",wedge:"∧",wedgeq:"≙",weierp:"℘",Wfr:"𝔚",wfr:"𝔴",Wopf:"𝕎",wopf:"𝕨",wp:"℘",wr:"≀",wreath:"≀",Wscr:"𝒲",wscr:"𝓌",xcap:"⋂",xcirc:"◯",xcup:"⋃",xdtri:"▽",Xfr:"𝔛",xfr:"𝔵",xhArr:"⟺",xharr:"⟷",Xi:"Ξ",xi:"ξ",xlArr:"⟸",xlarr:"⟵",xmap:"⟼",xnis:"⋻",xodot:"⨀",Xopf:"𝕏",xopf:"𝕩",xoplus:"⨁",xotime:"⨂",xrArr:"⟹",xrarr:"⟶",Xscr:"𝒳",xscr:"𝓍",xsqcup:"⨆",xuplus:"⨄",xutri:"△",xvee:"⋁",xwedge:"⋀",Yacute:"Ý",yacute:"ý",YAcy:"Я",yacy:"я",Ycirc:"Ŷ",ycirc:"ŷ",Ycy:"Ы",ycy:"ы",yen:"¥",Yfr:"𝔜",yfr:"𝔶",YIcy:"Ї",yicy:"ї",Yopf:"𝕐",yopf:"𝕪",Yscr:"𝒴",yscr:"𝓎",YUcy:"Ю",yucy:"ю",Yuml:"Ÿ",yuml:"ÿ",Zacute:"Ź",zacute:"ź",Zcaron:"Ž",zcaron:"ž",Zcy:"З",zcy:"з",Zdot:"Ż",zdot:"ż",zeetrf:"ℨ",ZeroWidthSpace:"​",Zeta:"Ζ",zeta:"ζ",Zfr:"ℨ",zfr:"𝔷",ZHcy:"Ж",zhcy:"ж",zigrarr:"⇝",Zopf:"ℤ",zopf:"𝕫",Zscr:"𝒵",zscr:"𝓏",zwj:"‍",zwnj:"‌"}},{}],2:[function(e,t){"use strict";var r={};["article","aside","button","blockquote","body","canvas","caption","col","colgroup","dd","div","dl","dt","embed","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","header","hgroup","hr","iframe","li","map","object","ol","output","p","pre","progress","script","section","style","table","tbody","td","textarea","tfoot","th","tr","thead","ul","video"].forEach(function(e){r[e]=!0}),t.exports=r},{}],3:[function(e,t){"use strict";function r(e,t){return e=e.source,t=t||"",function r(n,s){return n?(s=s.source||s,e=e.replace(n,s),r):new RegExp(e,t)}}var n=/[a-zA-Z_:][a-zA-Z0-9:._-]*/,s=/[^"'=<>`\x00-\x20]+/,o=/'[^']*'/,i=/"[^"]*"/,l=r(/(?:unquoted|single_quoted|double_quoted)/)("unquoted",s)("single_quoted",o)("double_quoted",i)(),a=r(/(?:\s+attr_name(?:\s*=\s*attr_value)?)/)("attr_name",n)("attr_value",l)(),c=r(/<[A-Za-z][A-Za-z0-9]*attribute*\s*\/?>/)("attribute",a)(),u=/<\/[A-Za-z][A-Za-z0-9]*\s*>/,p=//,h=/<[?].*?[?]>/,f=/]*>/,d=/])*\]\]>/,g=r(/^(?:open_tag|close_tag|comment|processing|declaration|cdata)/)("open_tag",c)("close_tag",u)("comment",p)("processing",h)("declaration",f)("cdata",d)();t.exports.HTML_TAG_RE=g},{}],4:[function(e,t){"use strict";t.exports=["coap","doi","javascript","aaa","aaas","about","acap","cap","cid","crid","data","dav","dict","dns","file","ftp","geo","go","gopher","h323","http","https","iax","icap","im","imap","info","ipp","iris","iris.beep","iris.xpc","iris.xpcs","iris.lwz","ldap","mailto","mid","msrp","msrps","mtqp","mupdate","news","nfs","ni","nih","nntp","opaquelocktoken","pop","pres","rtsp","service","session","shttp","sieve","sip","sips","sms","snmp","soap.beep","soap.beeps","tag","tel","telnet","tftp","thismessage","tn3270","tip","tv","urn","vemmi","ws","wss","xcon","xcon-userid","xmlrpc.beep","xmlrpc.beeps","xmpp","z39.50r","z39.50s","adiumxtra","afp","afs","aim","apt","attachment","aw","beshare","bitcoin","bolo","callto","chrome","chrome-extension","com-eventbrite-attendee","content","cvs","dlna-playsingle","dlna-playcontainer","dtn","dvb","ed2k","facetime","feed","finger","fish","gg","git","gizmoproject","gtalk","hcp","icon","ipn","irc","irc6","ircs","itms","jar","jms","keyparc","lastfm","ldaps","magnet","maps","market","message","mms","ms-help","msnim","mumble","mvn","notes","oid","palm","paparazzi","platform","proxy","psyc","query","res","resource","rmi","rsync","rtmp","secondlife","sftp","sgn","skype","smb","soldat","spotify","ssh","steam","svn","teamspeak","things","udp","unreal","ut2004","ventrilo","view-source","webcal","wtai","wyciwyg","xfire","xri","ymsgr"]},{}],5:[function(e,t,r){"use strict";function n(e){return Object.prototype.toString.call(e)}function s(e){return"[object String]"===n(e)}function o(e,t){return e?d.call(e,t):!1}function i(e){var t=[].slice.call(arguments,1);return t.forEach(function(t){if(t){if("object"!=typeof t)throw new TypeError(t+"must be object");Object.keys(t).forEach(function(r){e[r]=t[r]})}}),e}function l(e){return e.indexOf("\\")<0?e:e.replace(g,"$1")}function a(e){return e>=55296&&57343>=e?!1:e>=64976&&65007>=e?!1:65535===(65535&e)||65534===(65535&e)?!1:e>=0&&8>=e?!1:11===e?!1:e>=14&&31>=e?!1:e>=127&&159>=e?!1:e>1114111?!1:!0}function c(e){if(e>65535){e-=65536;var t=55296+(e>>10),r=56320+(1023&e);return String.fromCharCode(t,r)}return String.fromCharCode(e)}function u(e,t){var r=0;return o(v,t)?v[t]:35===t.charCodeAt(0)&&b.test(t)&&(r="x"===t[1].toLowerCase()?parseInt(t.slice(2),16):parseInt(t.slice(1),10),a(r))?c(r):e}function p(e){return e.indexOf("&")<0?e:e.replace(m,u)}function h(e){return y[e]}function f(e){return k.test(e)?e.replace(_,h):e}var d=Object.prototype.hasOwnProperty,g=/\\([\\!"#$%&'()*+,.\/:;<=>?@[\]^_`{|}~-])/g,m=/&([a-z#][a-z0-9]{1,31});/gi,b=/^#((?:x[a-f0-9]{1,8}|[0-9]{1,8}))/i,v=e("./entities"),k=/[&<>"]/,_=/[&<>"]/g,y={"&":"&","<":"<",">":">",'"':"""};r.assign=i,r.isString=s,r.has=o,r.unescapeMd=l,r.isValidEntityCode=a,r.fromCodePoint=c,r.replaceEntities=p,r.escapeHtml=f},{"./entities":1}],6:[function(e,t){"use strict";t.exports={options:{html:!0,xhtmlOut:!0,breaks:!1,langPrefix:"language-",linkify:!1,linkTarget:"",typographer:!1,quotes:"“”‘’",highlight:null,maxNesting:20},components:{core:{rules:["block","inline","references","abbr2"]},block:{rules:["blockquote","code","fences","heading","hr","htmlblock","lheading","list","paragraph"]},inline:{rules:["autolink","backticks","emphasis","entity","escape","htmltag","links","newline","text"]}}}},{}],7:[function(e,t){"use strict";t.exports={options:{html:!1,xhtmlOut:!1,breaks:!1,langPrefix:"language-",linkify:!1,linkTarget:"",typographer:!1,quotes:"“”‘’",highlight:null,maxNesting:20},components:{core:{rules:["block","inline","references","replacements","linkify","smartquotes","references","abbr2","footnote_tail"]},block:{rules:["blockquote","code","fences","footnote","heading","hr","htmlblock","lheading","list","paragraph","table"]},inline:{rules:["autolink","backticks","del","emphasis","entity","escape","footnote_ref","htmltag","links","newline","text"]}}}},{}],8:[function(e,t){"use strict";t.exports={options:{html:!1,xhtmlOut:!1,breaks:!1,langPrefix:"language-",linkify:!1,linkTarget:"",typographer:!1,quotes:"“”‘’",highlight:null,maxNesting:20},components:{core:{},block:{},inline:{}}}},{}],9:[function(e,t){"use strict";var r=e("../common/utils").replaceEntities;t.exports=function(e){var t=r(e);try{t=decodeURI(t)}catch(n){}return encodeURI(t)}},{"../common/utils":5}],10:[function(e,t){"use strict";t.exports=function(e){return e.trim().replace(/\s+/g," ").toUpperCase()}},{}],11:[function(e,t){"use strict";var r=e("./normalize_link"),n=e("../common/utils").unescapeMd;t.exports=function(e,t){var s,o,i,l=t,a=e.posMax;if(60===e.src.charCodeAt(t)){for(t++;a>t;){if(s=e.src.charCodeAt(t),10===s)return!1;if(62===s)return i=r(n(e.src.slice(l+1,t))),e.parser.validateLink(i)?(e.pos=t+1,e.linkContent=i,!0):!1;92===s&&a>t+1?t+=2:t++}return!1}for(o=0;a>t&&(s=e.src.charCodeAt(t),32!==s)&&!(s>8&&14>s);)if(92===s&&a>t+1)t+=2;else{if(40===s&&(o++,o>1))break;if(41===s&&(o--,0>o))break;t++}return l===t?!1:(i=n(e.src.slice(l,t)),e.parser.validateLink(i)?(e.linkContent=i,e.pos=t,!0):!1)}},{"../common/utils":5,"./normalize_link":9}],12:[function(e,t){"use strict";t.exports=function(e,t){ +var r,n,s,o=-1,i=e.posMax,l=e.pos,a=e.isInLabel;if(e.isInLabel)return-1;if(e.labelUnmatchedScopes)return e.labelUnmatchedScopes--,-1;for(e.pos=t+1,e.isInLabel=!0,r=1;e.post;){if(n=e.src.charCodeAt(t),n===i)return e.pos=t+1,e.linkContent=r(e.src.slice(s+1,t)),!0;92===n&&o>t+1?t+=2:t++}return!1}},{"../common/utils":5}],14:[function(e,t){"use strict";function r(e,t,r){this.src=t,this.env=r,this.options=e.options,this.tokens=[],this.inlineMode=!1,this.inline=e.inline,this.block=e.block,this.renderer=e.renderer,this.typographer=e.typographer}function n(e,t){"string"!=typeof e&&(t=e,e="default"),this.inline=new a,this.block=new l,this.core=new i,this.renderer=new o,this.ruler=new c,this.options={},this.configure(u[e]),this.set(t||{})}var s=e("./common/utils").assign,o=e("./renderer"),i=e("./parser_core"),l=e("./parser_block"),a=e("./parser_inline"),c=e("./ruler"),u={"default":e("./configs/default"),full:e("./configs/full"),commonmark:e("./configs/commonmark")};n.prototype.set=function(e){s(this.options,e)},n.prototype.configure=function(e){var t=this;if(!e)throw new Error("Wrong `remarkable` preset, check name/content");e.options&&t.set(e.options),e.components&&Object.keys(e.components).forEach(function(r){e.components[r].rules&&t[r].ruler.enable(e.components[r].rules,!0)})},n.prototype.use=function(e,t){return e(this,t),this},n.prototype.parse=function(e,t){var n=new r(this,e,t);return this.core.process(n),n.tokens},n.prototype.render=function(e,t){return t=t||{},this.renderer.render(this.parse(e,t),this.options,t)},n.prototype.parseInline=function(e,t){var n=new r(this,e,t);return n.inlineMode=!0,this.core.process(n),n.tokens},n.prototype.renderInline=function(e,t){return t=t||{},this.renderer.render(this.parseInline(e,t),this.options,t)},t.exports=n,t.exports.utils=e("./common/utils")},{"./common/utils":5,"./configs/commonmark":6,"./configs/default":7,"./configs/full":8,"./parser_block":15,"./parser_core":16,"./parser_inline":17,"./renderer":18,"./ruler":19}],15:[function(e,t){"use strict";function r(){this.ruler=new n;for(var e=0;el&&(e.line=l=e.skipEmptyLines(l),!(l>=r))&&!(e.tShift[l]s&&!(n=o[s](e,l,r,!1));s++);if(e.tight=!a,e.isEmpty(e.line-1)&&(a=!0),l=e.line,r>l&&e.isEmpty(l)){if(a=!0,l++,r>l&&"list"===e.parentType&&e.isEmpty(l))break;e.line=l}}};var i=/[\n\t]/g,l=/\r[\n\u0085]|[\u2424\u2028\u0085]/g,a=/\u00a0/g;r.prototype.parse=function(e,t,r,n){var o,c=0,u=0;return e?(e=e.replace(a," "),e=e.replace(l,"\n"),e.indexOf(" ")>=0&&(e=e.replace(i,function(t,r){var n;return 10===e.charCodeAt(r)?(c=r+1,u=0,t):(n=" ".slice((r-c-u)%4),u=r-c+1,n)})),o=new s(e,this,t,r,n),void this.tokenize(o,o.line,o.lineMax)):[]},t.exports=r},{"./ruler":19,"./rules_block/blockquote":21,"./rules_block/code":22,"./rules_block/deflist":23,"./rules_block/fences":24,"./rules_block/footnote":25,"./rules_block/heading":26,"./rules_block/hr":27,"./rules_block/htmlblock":28,"./rules_block/lheading":29,"./rules_block/list":30,"./rules_block/paragraph":31,"./rules_block/state_block":32,"./rules_block/table":33}],16:[function(e,t){"use strict";function r(){this.options={},this.ruler=new n;for(var e=0;et;t++)n[t](e)},t.exports=r},{"./ruler":19,"./rules_core/abbr":34,"./rules_core/abbr2":35,"./rules_core/block":36,"./rules_core/footnote_tail":37,"./rules_core/inline":38,"./rules_core/linkify":39,"./rules_core/references":40,"./rules_core/replacements":41,"./rules_core/smartquotes":42}],17:[function(e,t){"use strict";function r(){this.ruler=new s;for(var e=0;e0)return void(e.pos=r);for(t=0;s>t;t++)if(n[t](e,!0))return void e.cacheSet(o,e.pos);e.pos++,e.cacheSet(o,e.pos)},r.prototype.tokenize=function(e){for(var t,r,n=this.ruler.getRules(""),s=n.length,o=e.posMax;e.posr&&!(t=n[r](e,!1));r++);if(t){if(e.pos>=o)break}else e.pending+=e.src[e.pos++]}e.pending&&e.pushPending()},r.prototype.parse=function(e,t,r,n){var s=new o(e,this,t,r,n);this.tokenize(s)},t.exports=r},{"./common/utils":5,"./ruler":19,"./rules_inline/autolink":43,"./rules_inline/backticks":44,"./rules_inline/del":45,"./rules_inline/emphasis":46,"./rules_inline/entity":47,"./rules_inline/escape":48,"./rules_inline/footnote_inline":49,"./rules_inline/footnote_ref":50,"./rules_inline/htmltag":51,"./rules_inline/ins":52,"./rules_inline/links":53,"./rules_inline/mark":54,"./rules_inline/newline":55,"./rules_inline/state_inline":56,"./rules_inline/sub":57,"./rules_inline/sup":58,"./rules_inline/text":59}],18:[function(e,t){"use strict";function r(){this.rules=n.assign({},s),this.getBreak=s.getBreak}var n=e("./common/utils"),s=e("./rules");t.exports=r,r.prototype.renderInline=function(e,t,r){for(var n=this.rules,s=e.length,o=0,i="";s--;)i+=n[e[o].type](e,o++,t,r,this);return i},r.prototype.render=function(e,t,r){for(var n=this.rules,s=e.length,o=-1,i="";++ot)throw new Error("Rules manager: invalid rule name "+e);this.__rules__[t].enabled=!0},this),this.__cache__=null},r.prototype.disable=function(e){e=Array.isArray(e)?e:[e],e.forEach(function(e){var t=this.__find__(e);if(0>t)throw new Error("Rules manager: invalid rule name "+e);this.__rules__[t].enabled=!1},this),this.__cache__=null},r.prototype.getRules=function(e){return null===this.__cache__&&this.__compile__(),this.__cache__[e]||[]},t.exports=r},{}],20:[function(e,t){"use strict";function r(e,t){return++t>=e.length-2?t:"paragraph_open"===e[t].type&&e[t].tight&&"inline"===e[t+1].type&&0===e[t+1].content.length&&"paragraph_close"===e[t+2].type&&e[t+2].tight?r(e,t+2):t}var n=e("./common/utils").has,s=e("./common/utils").unescapeMd,o=e("./common/utils").replaceEntities,i=e("./common/utils").escapeHtml,l={};l.blockquote_open=function(){return"
    \n"},l.blockquote_close=function(e,t){return"
    "+a(e,t)},l.code=function(e,t){return e[t].block?"
    "+i(e[t].content)+"
    "+a(e,t):""+i(e[t].content)+""},l.fence=function(e,t,r,l,c){var u,p,h,f=e[t],d="",g=r.langPrefix,m="";if(f.params){if(u=f.params.split(/\s+/g),p=u.join(" "),n(c.rules.fence_custom,u[0]))return c.rules.fence_custom[u[0]](e,t,r,l,c);m=i(o(s(p))),d=' class="'+g+m+'"'}return h=r.highlight?r.highlight.apply(r.highlight,[f.content].concat(u))||i(f.content):i(f.content),"
    "+h+"
    "+a(e,t)},l.fence_custom={},l.heading_open=function(e,t){return""},l.heading_close=function(e,t){return"\n"},l.hr=function(e,t,r){return(r.xhtmlOut?"
    ":"
    ")+a(e,t)},l.bullet_list_open=function(){return"
      \n"},l.bullet_list_close=function(e,t){return"
    "+a(e,t)},l.list_item_open=function(){return"
  • "},l.list_item_close=function(){return"
  • \n"},l.ordered_list_open=function(e,t){var r=e[t],n=r.order>1?' start="'+r.order+'"':"";return"\n"},l.ordered_list_close=function(e,t){return""+a(e,t)},l.paragraph_open=function(e,t){return e[t].tight?"":"

    "},l.paragraph_close=function(e,t){var r=!(e[t].tight&&t&&"inline"===e[t-1].type&&!e[t-1].content);return(e[t].tight?"":"

    ")+(r?a(e,t):"")},l.link_open=function(e,t,r){var n=e[t].title?' title="'+i(o(e[t].title))+'"':"",s=r.linkTarget?' target="'+r.linkTarget+'"':"";return'"},l.link_close=function(){return""},l.image=function(e,t,r){var n=' src="'+i(e[t].src)+'"',l=e[t].title?' title="'+i(o(e[t].title))+'"':"",a=' alt="'+(e[t].alt?i(o(s(e[t].alt))):"")+'"',c=r.xhtmlOut?" /":"";return""},l.table_open=function(){return"\n"},l.table_close=function(){return"
    \n"},l.thead_open=function(){return"\n"},l.thead_close=function(){return"\n"},l.tbody_open=function(){return"\n"},l.tbody_close=function(){return"\n"},l.tr_open=function(){return""},l.tr_close=function(){return"\n"},l.th_open=function(e,t){var r=e[t];return""},l.th_close=function(){return""},l.td_open=function(e,t){var r=e[t];return""},l.td_close=function(){return""},l.strong_open=function(){return""},l.strong_close=function(){return""},l.em_open=function(){return""},l.em_close=function(){return""},l.del_open=function(){return""},l.del_close=function(){return""},l.ins_open=function(){return""},l.ins_close=function(){return""},l.mark_open=function(){return""},l.mark_close=function(){return""},l.sub=function(e,t){return""+i(e[t].content)+""},l.sup=function(e,t){return""+i(e[t].content)+""},l.hardbreak=function(e,t,r){return r.xhtmlOut?"
    \n":"
    \n"},l.softbreak=function(e,t,r){return r.breaks?r.xhtmlOut?"
    \n":"
    \n":"\n"},l.text=function(e,t){return i(e[t].content)},l.htmlblock=function(e,t){return e[t].content},l.htmltag=function(e,t){return e[t].content},l.abbr_open=function(e,t){return''},l.abbr_close=function(){return""},l.footnote_ref=function(e,t){var r=Number(e[t].id+1).toString(),n="fnref"+r;return e[t].subId>0&&(n+=":"+e[t].subId),'['+r+"]"},l.footnote_block_open=function(e,t,r){var n=r.xhtmlOut?'
    \n':'
    \n';return n+'
    \n
      \n'},l.footnote_block_close=function(){return"
    \n
    \n"},l.footnote_open=function(e,t){var r=Number(e[t].id+1).toString();return'
  • '},l.footnote_close=function(){return"
  • \n"},l.footnote_anchor=function(e,t){var r=Number(e[t].id+1).toString(),n="fnref"+r;return e[t].subId>0&&(n+=":"+e[t].subId),' '},l.dl_open=function(){return"
    \n"},l.dt_open=function(){return"
    "},l.dd_open=function(){return"
    "},l.dl_close=function(){return"
    \n"},l.dt_close=function(){return"\n"},l.dd_close=function(){return"\n"};var a=l.getBreak=function(e,t){return t=r(e,t),tm)return!1;if(62!==e.src.charCodeAt(g++))return!1;if(e.level>=e.options.maxNesting)return!1;if(n)return!0;for(32===e.src.charCodeAt(g)&&g++,a=e.blkIndent,e.blkIndent=0,l=[e.bMarks[t]],e.bMarks[t]=g,g=m>g?e.skipSpaces(g):g,o=g>=m,i=[e.tShift[t]],e.tShift[t]=g-e.bMarks[t],p=e.parser.ruler.getRules("blockquote"),s=t+1;r>s&&(g=e.bMarks[s]+e.tShift[s],m=e.eMarks[s],!(g>=m));s++)if(62!==e.src.charCodeAt(g++)){if(o)break;for(d=!1,h=0,f=p.length;f>h;h++)if(p[h](e,s,r,!0)){d=!0;break}if(d)break;l.push(e.bMarks[s]),i.push(e.tShift[s]),e.tShift[s]=-1337}else 32===e.src.charCodeAt(g)&&g++,l.push(e.bMarks[s]),e.bMarks[s]=g,g=m>g?e.skipSpaces(g):g,o=g>=m,i.push(e.tShift[s]),e.tShift[s]=g-e.bMarks[s];for(c=e.parentType,e.parentType="blockquote",e.tokens.push({type:"blockquote_open",lines:u=[t,0],level:e.level++}),e.parser.tokenize(e,t,s),e.tokens.push({type:"blockquote_close",level:--e.level}),e.parentType=c,u[1]=e.line,h=0;hn;)if(e.isEmpty(n))n++;else{if(!(e.tShift[n]-e.blkIndent>=4))break;n++,s=n}return e.line=n,e.tokens.push({type:"code",content:e.getLines(t,s,4+e.blkIndent,!0),block:!0,lines:[t,e.line],level:e.level}),!0}},{}],23:[function(e,t){"use strict";function r(e,t){var r,n,s=e.bMarks[t]+e.tShift[t],o=e.eMarks[t];return s>=o?-1:(n=e.src.charCodeAt(s++),126!==n&&58!==n?-1:(r=e.skipSpaces(s),s===r?-1:r>=o?-1:r))}function n(e,t){var r,n,s=e.level+2;for(r=t+2,n=e.tokens.length-2;n>r;r++)e.tokens[r].level===s&&"paragraph_open"===e.tokens[r].type&&(e.tokens[r+2].tight=!0,e.tokens[r].tight=!0,r+=2)}t.exports=function(e,t,s,o){var i,l,a,c,u,p,h,f,d,g,m,b,v,k;if(o)return e.ddIndent<0?!1:r(e,t)>=0;if(h=t+1,e.isEmpty(h)&&++h>s)return!1;if(e.tShift[h]i)return!1;if(e.level>=e.options.maxNesting)return!1;p=e.tokens.length,e.tokens.push({type:"dl_open",lines:u=[t,0],level:e.level++}),a=t,l=h;e:for(;;){for(k=!0,v=!1,e.tokens.push({type:"dt_open",lines:[a,a],level:e.level++}),e.tokens.push({type:"inline",content:e.getLines(a,a+1,e.blkIndent,!1).trim(),level:e.level+1,lines:[a,a],children:[]}),e.tokens.push({type:"dt_close",level:--e.level});;){if(e.tokens.push({type:"dd_open",lines:c=[h,0],level:e.level++}),b=e.tight,d=e.ddIndent,f=e.blkIndent,m=e.tShift[l],g=e.parentType,e.blkIndent=e.ddIndent=e.tShift[l]+2,e.tShift[l]=i-e.bMarks[l],e.tight=!0,e.parentType="deflist",e.parser.tokenize(e,l,s,!0),(!e.tight||v)&&(k=!1),v=e.line-l>1&&e.isEmpty(e.line-1),e.tShift[l]=m,e.tight=b,e.parentType=g,e.blkIndent=f,e.ddIndent=d,e.tokens.push({type:"dd_close",level:--e.level}),c[1]=h=e.line,h>=s)break e;if(e.tShift[h]i)break;l=h}if(h>=s)break;if(a=h,e.isEmpty(a))break;if(e.tShift[a]=s)break;if(e.isEmpty(l)&&l++,l>=s)break;if(e.tShift[l]i)break}return e.tokens.push({type:"dl_close",level:--e.level}),u[1]=h,e.line=h,k&&n(e,p),!0}},{}],24:[function(e,t){"use strict";t.exports=function(e,t,r,n){var s,o,i,l,a,c=!1,u=e.bMarks[t]+e.tShift[t],p=e.eMarks[t];if(u+3>p)return!1;if(s=e.src.charCodeAt(u),126!==s&&96!==s)return!1;if(a=u,u=e.skipChars(u,s),o=u-a,3>o)return!1;if(i=e.src.slice(u,p).trim(),i.indexOf("`")>=0)return!1;if(n)return!0;for(l=t;(l++,!(l>=r))&&(u=a=e.bMarks[l]+e.tShift[l],p=e.eMarks[l],!(p>u&&e.tShift[l]=4||(u=e.skipChars(u,s),o>u-a||(u=e.skipSpaces(u),p>u)))){c=!0;break}return o=e.tShift[t],e.line=l+(c?1:0),e.tokens.push({type:"fence",params:i,content:e.getLines(t+1,l,o,!0),lines:[t,e.line],level:e.level}),!0}},{}],25:[function(e,t){"use strict";t.exports=function(e,t,r,n){var s,o,i,l,a,c=e.bMarks[t]+e.tShift[t],u=e.eMarks[t];if(c+4>u)return!1;if(91!==e.src.charCodeAt(c))return!1;if(94!==e.src.charCodeAt(c+1))return!1;if(e.level>=e.options.maxNesting)return!1;for(l=c+2;u>l;l++){if(32===e.src.charCodeAt(l))return!1;if(93===e.src.charCodeAt(l))break}return l===c+2?!1:l+1>=u||58!==e.src.charCodeAt(++l)?!1:n?!0:(l++,e.env.footnotes||(e.env.footnotes={}),e.env.footnotes.refs||(e.env.footnotes.refs={}),a=e.src.slice(c+2,l-2),e.env.footnotes.refs[":"+a]=-1,e.tokens.push({type:"footnote_reference_open",label:a,level:e.level++}),s=e.bMarks[t],o=e.tShift[t],i=e.parentType,e.tShift[t]=e.skipSpaces(l)-l,e.bMarks[t]=l,e.blkIndent+=4,e.parentType="footnote",e.tShift[t]=a)return!1;if(s=e.src.charCodeAt(l),35!==s||l>=a)return!1;for(o=1,s=e.src.charCodeAt(++l);35===s&&a>l&&6>=o;)o++,s=e.src.charCodeAt(++l);return o>6||a>l&&32!==s?!1:n?!0:(a=e.skipCharsBack(a,32,l),i=e.skipCharsBack(a,35,l),i>l&&32===e.src.charCodeAt(i-1)&&(a=i),e.line=t+1,e.tokens.push({type:"heading_open",hLevel:o,lines:[t,e.line],level:e.level}),a>l&&e.tokens.push({type:"inline",content:e.src.slice(l,a).trim(),level:e.level+1,lines:[t,e.line],children:[]}),e.tokens.push({type:"heading_close",hLevel:o,level:e.level}),!0)}},{}],27:[function(e,t){"use strict";t.exports=function(e,t,r,n){var s,o,i,l=e.bMarks[t],a=e.eMarks[t];if(l+=e.tShift[t],l>a)return!1;if(s=e.src.charCodeAt(l++),42!==s&&45!==s&&95!==s)return!1;for(o=1;a>l;){if(i=e.src.charCodeAt(l++),i!==s&&32!==i)return!1;i===s&&o++}return 3>o?!1:n?!0:(e.line=t+1,e.tokens.push({type:"hr",lines:[t,e.line],level:e.level}),!0)}},{}],28:[function(e,t){"use strict";function r(e){var t=32|e;return t>=97&&122>=t}var n=e("../common/html_blocks"),s=/^<([a-zA-Z]{1,15})[\s\/>]/,o=/^<\/([a-zA-Z]{1,15})[\s>]/;t.exports=function(e,t,i,l){var a,c,u,p=e.bMarks[t],h=e.eMarks[t],f=e.tShift[t];if(p+=f,!e.options.html)return!1;if(f>3||p+2>=h)return!1;if(60!==e.src.charCodeAt(p))return!1;if(a=e.src.charCodeAt(p+1),33===a||63===a){if(l)return!0}else{if(47!==a&&!r(a))return!1;if(47===a){if(c=e.src.slice(p,h).match(o),!c)return!1}else if(c=e.src.slice(p,h).match(s),!c)return!1;if(n[c[1].toLowerCase()]!==!0)return!1;if(l)return!0}for(u=t+1;u=r?!1:e.tShift[i]3?!1:(s=e.bMarks[i]+e.tShift[i],o=e.eMarks[i],s>=o?!1:(n=e.src.charCodeAt(s),45!==n&&61!==n?!1:(s=e.skipChars(s,n),s=e.skipSpaces(s),o>s?!1:(s=e.bMarks[t]+e.tShift[t],e.line=i+1,e.tokens.push({type:"heading_open",hLevel:61===n?1:2,lines:[t,e.line],level:e.level}),e.tokens.push({type:"inline",content:e.src.slice(s,e.eMarks[t]).trim(),level:e.level+1,lines:[t,e.line-1],children:[]}),e.tokens.push({type:"heading_close",hLevel:61===n?1:2,level:e.level}),!0))))}},{}],30:[function(e,t){"use strict";function r(e,t){var r,n,s;return n=e.bMarks[t]+e.tShift[t],s=e.eMarks[t],n>=s?-1:(r=e.src.charCodeAt(n++),42!==r&&45!==r&&43!==r?-1:s>n&&32!==e.src.charCodeAt(n)?-1:n)}function n(e,t){var r,n=e.bMarks[t]+e.tShift[t],s=e.eMarks[t];if(n+1>=s)return-1;if(r=e.src.charCodeAt(n++),48>r||r>57)return-1;for(;;){if(n>=s)return-1;if(r=e.src.charCodeAt(n++),!(r>=48&&57>=r)){if(41===r||46===r)break;return-1}}return s>n&&32!==e.src.charCodeAt(n)?-1:n}function s(e,t){var r,n,s=e.level+2;for(r=t+2,n=e.tokens.length-2;n>r;r++)e.tokens[r].level===s&&"paragraph_open"===e.tokens[r].type&&(e.tokens[r+2].tight=!0,e.tokens[r].tight=!0,r+=2)}t.exports=function(e,t,o,i){var l,a,c,u,p,h,f,d,g,m,b,v,k,_,y,x,w,A,q,C,S,E,M=!0;if((d=n(e,t))>=0)k=!0;else{if(!((d=r(e,t))>=0))return!1;k=!1}if(e.level>=e.options.maxNesting)return!1;if(v=e.src.charCodeAt(d-1),i)return!0;for(y=e.tokens.length,k?(f=e.bMarks[t]+e.tShift[t],b=Number(e.src.substr(f,d-f-1)),e.tokens.push({type:"ordered_list_open",order:b,lines:w=[t,0],level:e.level++})):e.tokens.push({type:"bullet_list_open",lines:w=[t,0],level:e.level++}),l=t,x=!1,q=e.parser.ruler.getRules("list");!(!(o>l)||(_=e.skipSpaces(d),g=e.eMarks[l],m=_>=g?1:_-d,m>4&&(m=1),1>m&&(m=1),a=d-e.bMarks[l]+m,e.tokens.push({type:"list_item_open",lines:A=[t,0],level:e.level++}),u=e.blkIndent,p=e.tight,c=e.tShift[t],h=e.parentType,e.tShift[t]=_-e.bMarks[t],e.blkIndent=a,e.tight=!0,e.parentType="list",e.parser.tokenize(e,t,o,!0),(!e.tight||x)&&(M=!1),x=e.line-t>1&&e.isEmpty(e.line-1),e.blkIndent=u,e.tShift[t]=c,e.tight=p,e.parentType=h,e.tokens.push({type:"list_item_close",level:--e.level}),l=t=e.line,A[1]=l,_=e.bMarks[t],l>=o)||e.isEmpty(l)||e.tShift[l]C;C++)if(q[C](e,l,o,!0)){E=!0;break}if(E)break;if(k){if(d=n(e,l),0>d)break}else if(d=r(e,l),0>d)break;if(v!==e.src.charCodeAt(d-1))break}return e.tokens.push({type:k?"ordered_list_close":"bullet_list_close",level:--e.level}),w[1]=l,e.line=l,M&&s(e,y),!0}},{}],31:[function(e,t){"use strict";t.exports=function(e,t){var r,n,s,o,i,l,a=t+1;if(r=e.lineMax,r>a&&!e.isEmpty(a))for(l=e.parser.ruler.getRules("paragraph");r>a&&!e.isEmpty(a);a++)if(!(e.tShift[a]-e.blkIndent>3)){for(s=!1,o=0,i=l.length;i>o;o++)if(l[o](e,a,r,!0)){s=!0;break}if(s)break}return n=e.getLines(t,a,e.blkIndent,!1).trim(),e.line=a,n.length&&(e.tokens.push({type:"paragraph_open",tight:!1,lines:[t,e.line],level:e.level}),e.tokens.push({type:"inline",content:n,level:e.level+1,lines:[t,e.line],children:[]}),e.tokens.push({type:"paragraph_close",tight:!1,level:e.level})),!0}},{}],32:[function(e,t){"use strict";function r(e,t,r,n,s){var o,i,l,a,c,u,p;for(this.src=e,this.parser=t,this.options=r,this.env=n,this.tokens=s,this.bMarks=[],this.eMarks=[],this.tShift=[],this.blkIndent=0,this.line=0,this.lineMax=0,this.tight=!1,this.parentType="root",this.ddIndent=-1,this.level=0,this.result="",i=this.src,u=0,p=!1,l=a=u=0,c=i.length;c>a;a++){if(o=i.charCodeAt(a),!p){if(32===o){u++;continue}p=!0}(10===o||a===c-1)&&(10!==o&&a++,this.bMarks.push(l),this.eMarks.push(a),this.tShift.push(u),p=!1,u=0,l=a+1)}this.bMarks.push(i.length),this.eMarks.push(i.length),this.tShift.push(0),this.lineMax=this.bMarks.length-1}r.prototype.isEmpty=function(e){return this.bMarks[e]+this.tShift[e]>=this.eMarks[e]},r.prototype.skipEmptyLines=function(e){for(var t=this.lineMax;t>e&&!(this.bMarks[e]+this.tShift[e]e&&32===this.src.charCodeAt(e);e++);return e},r.prototype.skipChars=function(e,t){for(var r=this.src.length;r>e&&this.src.charCodeAt(e)===t;e++);return e},r.prototype.skipCharsBack=function(e,t,r){if(r>=e)return e;for(;e>r;)if(t!==this.src.charCodeAt(--e))return e+1;return e},r.prototype.getLines=function(e,t,r,n){var s,o,i,l,a,c=e;if(e>=t)return"";if(c+1===t)return o=this.bMarks[c]+Math.min(this.tShift[c],r),i=n?this.eMarks[c]+1:this.eMarks[c],this.src.slice(o,i);for(l=new Array(t-e),s=0;t>c;c++,s++)a=this.tShift[c],a>r&&(a=r),0>a&&(a=0),o=this.bMarks[c]+a,i=t>c+1||n?this.eMarks[c]+1:this.eMarks[c],l[s]=this.src.slice(o,i);return l.join("")},t.exports=r},{}],33:[function(e,t){"use strict";function r(e,t){var r=e.bMarks[t]+e.blkIndent,n=e.eMarks[t];return e.src.substr(r,n-r)}t.exports=function(e,t,n,s){var o,i,l,a,c,u,p,h,f,d,g;if(t+2>n)return!1;if(c=t+1,e.tShift[c]=e.eMarks[c])return!1;if(o=e.src.charCodeAt(l),124!==o&&45!==o&&58!==o)return!1;if(i=r(e,t+1),!/^[-:| ]+$/.test(i))return!1;if(u=i.split("|"),2>=u)return!1;for(h=[],a=0;ac&&!(e.tShift[c]l||58!==e.charCodeAt(l+1))return-1;for(c=i.posMax,a=l+2;c>a&&10!==i.src.charCodeAt(a);a++);return u=e.slice(2,l),p=e.slice(l+2,a).trim(),0===p.length?-1:(o.abbreviations||(o.abbreviations={}),"undefined"==typeof o.abbreviations[":"+u]&&(o.abbreviations[":"+u]=p),a)}var n=e("../rules_inline/state_inline"),s=e("../helpers/parse_link_label");t.exports=function(e){var t,n,s,o,i=e.tokens;if(!e.inlineMode)for(t=1,n=i.length-1;n>t;t++)if("paragraph_open"===i[t-1].type&&"inline"===i[t].type&&"paragraph_close"===i[t+1].type){for(s=i[t].content;s.length&&(o=r(s,e.inline,e.options,e.env),!(0>o));)s=s.slice(o).trim();i[t].content=s,s.length||(i[t-1].tight=!0,i[t+1].tight=!0)}}},{"../helpers/parse_link_label":12,"../rules_inline/state_inline":56}],35:[function(e,t){"use strict";function r(e){return e.replace(/([-()\[\]{}+?*.$\^|,:#s;s++)if("inline"===g[s].type)for(i=g[s].children,t=i.length-1;t>=0;t--)if(l=i[t],"text"===l.type){for(u=0,a=l.content,h.lastIndex=0,p=l.level,c=[];f=h.exec(a);)h.lastIndex>u&&c.push({type:"text",content:a.slice(u,f.index+f[1].length),level:p}),c.push({type:"abbr_open",title:e.env.abbreviations[":"+f[2]],level:p++}),c.push({type:"text",content:f[2],level:p}),c.push({type:"abbr_close",level:--p}),u=h.lastIndex-f[3].length;c.length&&(ut;t++){for(e.tokens.push({type:"footnote_open",id:t,level:u++}),i[t].tokens?(l=[],l.push({type:"paragraph_open",tight:!1,level:u++}),l.push({type:"inline",content:"",level:u,children:i[t].tokens}),l.push({type:"paragraph_close",tight:!1,level:--u})):i[t].label&&(l=h[":"+i[t].label]),e.tokens=e.tokens.concat(l),o="paragraph_close"===e.tokens[e.tokens.length-1].type?e.tokens.pop():null,s=i[t].count>0?i[t].count:1,n=0;s>n;n++)e.tokens.push({type:"footnote_anchor",id:t,subId:n,level:u});o&&e.tokens.push(o),e.tokens.push({type:"footnote_close",level:--u})}e.tokens.push({type:"footnote_block_close",level:--u})}}},{}],38:[function(e,t){"use strict";t.exports=function(e){var t,r,n,s=e.tokens;for(r=0,n=s.length;n>r;r++)t=s[r],"inline"===t.type&&e.inline.parse(t.content,e.options,e.env,t.children)}},{}],39:[function(e,t){"use strict";function r(e){return/^\s]/i.test(e)}function n(e){return/^<\/a\s*>/i.test(e)}function s(){var e=[],t=new o({stripPrefix:!1,url:!0,email:!0,twitter:!1,replaceFn:function(t,r){switch(r.getType()){case"url":e.push({text:r.matchedText,url:r.getUrl()});break;case"email":e.push({text:r.matchedText,url:"mailto:"+r.getEmail().replace(/^mailto:/i,"")})}return!1}});return{links:e,autolinker:t}}var o=e("autolinker"),i=/www|@|\:\/\//;t.exports=function(e){var t,o,l,a,c,u,p,h,f,d,g,m,b,v=e.tokens,k=null;if(e.options.linkify)for(o=0,l=v.length;l>o;o++)if("inline"===v[o].type)for(a=v[o].children, +g=0,t=a.length-1;t>=0;t--)if(c=a[t],"link_close"!==c.type){if("htmltag"===c.type&&(r(c.content)&&g>0&&g--,n(c.content)&&g++),!(g>0)&&"text"===c.type&&i.test(c.content)){if(k||(k=s(),m=k.links,b=k.autolinker),u=c.content,m.length=0,b.link(u),!m.length)continue;for(p=[],d=c.level,h=0;hu||58!==e.charCodeAt(u+1))return-1;for(h=c.posMax,p=u+2;h>p&&(f=c.src.charCodeAt(p),32===f||10===f);p++);if(!o(c,p))return-1;for(g=c.linkContent,p=c.pos,d=p,p+=1;h>p&&(f=c.src.charCodeAt(p),32===f||10===f);p++);for(h>p&&d!==p&&i(c,p)?(m=c.linkContent,p=c.pos):(m="",p=d);h>p&&32===c.src.charCodeAt(p);)p++;return h>p&&10!==c.src.charCodeAt(p)?-1:(b=l(e.slice(1,u)),"undefined"==typeof a.references[b]&&(a.references[b]={title:m,href:g}),p)}var n=e("../rules_inline/state_inline"),s=e("../helpers/parse_link_label"),o=e("../helpers/parse_link_destination"),i=e("../helpers/parse_link_title"),l=e("../helpers/normalize_reference");t.exports=function(e){var t,n,s,o,i=e.tokens;if(e.env.references=e.env.references||{},!e.inlineMode)for(t=1,n=i.length-1;n>t;t++)if("inline"===i[t].type&&"paragraph_open"===i[t-1].type&&"paragraph_close"===i[t+1].type){for(s=i[t].content;s.length&&(o=r(s,e.inline,e.options,e.env),!(0>o));)s=s.slice(o).trim();i[t].content=s,s.length||(i[t-1].tight=!0,i[t+1].tight=!0)}}},{"../helpers/normalize_reference":10,"../helpers/parse_link_destination":11,"../helpers/parse_link_label":12,"../helpers/parse_link_title":13,"../rules_inline/state_inline":56}],41:[function(e,t){"use strict";function r(e){return e.indexOf("(")<0?e:e.replace(s,function(e,t){return o[t.toLowerCase()]})}var n=/\+-|\.\.|\?\?\?\?|!!!!|,,|--/,s=/\((c|tm|r|p)\)/gi,o={c:"©",r:"®",p:"§",tm:"™"};t.exports=function(e){var t,s,o,i,l;if(e.options.typographer)for(l=e.tokens.length-1;l>=0;l--)if("inline"===e.tokens[l].type)for(i=e.tokens[l].children,t=i.length-1;t>=0;t--)s=i[t],"text"===s.type&&(o=s.content,o=r(o),n.test(o)&&(o=o.replace(/\+-/g,"±").replace(/\.{2,}/g,"…").replace(/([?!])…/g,"$1..").replace(/([?!]){4,}/g,"$1$1$1").replace(/,{2,}/g,",").replace(/(^|[^-])---([^-]|$)/gm,"$1—$2").replace(/(^|\s)--(\s|$)/gm,"$1–$2").replace(/(^|[^-\s])--([^-\s]|$)/gm,"$1–$2")),s.content=o)}},{}],42:[function(e,t){"use strict";function r(e,t){return 0>t||t>=e.length?!1:!i.test(e[t])}function n(e,t,r){return e.substr(0,t)+r+e.substr(t+1)}var s=/['"]/,o=/['"]/g,i=/[-\s()\[\]]/,l="’";t.exports=function(e){var t,i,a,c,u,p,h,f,d,g,m,b,v,k,_,y,x;if(e.options.typographer)for(x=[],_=e.tokens.length-1;_>=0;_--)if("inline"===e.tokens[_].type)for(y=e.tokens[_].children,x.length=0,t=0;t=0&&!(x[v].level<=h);v--);x.length=v+1,a=i.content,u=0,p=a.length;e:for(;p>u&&(o.lastIndex=u,c=o.exec(a));)if(f=!r(a,c.index-1),u=c.index+1,k="'"===c[0],d=!r(a,u),d||f){if(m=!d,b=!f)for(v=x.length-1;v>=0&&(g=x[v],!(x[v].level/,o=/^<([a-zA-Z.\-]{1,25}):([^<>\x00-\x20]*)>/;t.exports=function(e,t){var i,l,a,c,u,p=e.pos;return 60!==e.src.charCodeAt(p)?!1:(i=e.src.slice(p),i.indexOf(">")<0?!1:(l=i.match(o))?r.indexOf(l[1].toLowerCase())<0?!1:(c=l[0].slice(1,-1),u=n(c),e.parser.validateLink(c)?(t||(e.push({type:"link_open",href:u,level:e.level}),e.push({type:"text",content:c,level:e.level+1}),e.push({type:"link_close",level:e.level})),e.pos+=l[0].length,!0):!1):(a=i.match(s),a?(c=a[0].slice(1,-1),u=n("mailto:"+c),e.parser.validateLink(u)?(t||(e.push({type:"link_open",href:u,level:e.level}),e.push({type:"text",content:c,level:e.level+1}),e.push({type:"link_close",level:e.level})),e.pos+=a[0].length,!0):!1):!1))}},{"../common/url_schemas":4,"../helpers/normalize_link":9}],44:[function(e,t){"use strict";t.exports=function(e,t){var r,n,s,o,i,l=e.pos,a=e.src.charCodeAt(l);if(96!==a)return!1;for(r=l,l++,n=e.posMax;n>l&&96===e.src.charCodeAt(l);)l++;for(s=e.src.slice(r,l),o=i=l;-1!==(o=e.src.indexOf("`",i));){for(i=o+1;n>i&&96===e.src.charCodeAt(i);)i++;if(i-o===s.length)return t||e.push({type:"code",content:e.src.slice(l,o).replace(/[ \n]+/g," ").trim(),block:!1,level:e.level}),e.pos=i,!0}return t||(e.pending+=s),e.pos+=s.length,!0}},{}],45:[function(e,t){"use strict";t.exports=function(e,t){var r,n,s,o,i,l=e.posMax,a=e.pos;if(126!==e.src.charCodeAt(a))return!1;if(t)return!1;if(a+4>=l)return!1;if(126!==e.src.charCodeAt(a+1))return!1;if(e.level>=e.options.maxNesting)return!1;if(o=a>0?e.src.charCodeAt(a-1):-1,i=e.src.charCodeAt(a+2),126===o)return!1;if(126===i)return!1;if(32===i||10===i)return!1;for(n=a+2;l>n&&126===e.src.charCodeAt(n);)n++;if(n>a+3)return e.pos+=n-a,t||(e.pending+=e.src.slice(a,n)),!0;for(e.pos=a+2,s=1;e.pos+1=s))){r=!0;break}e.parser.skipToken(e)}return r?(e.posMax=e.pos,e.pos=a+2,t||(e.push({type:"del_open",level:e.level++}),e.parser.tokenize(e),e.push({type:"del_close",level:--e.level})),e.pos=e.posMax+2,e.posMax=l,!0):(e.pos=a,!1)}},{}],46:[function(e,t){"use strict";function r(e){return e>=48&&57>=e||e>=65&&90>=e||e>=97&&122>=e}function n(e,t){var n,s,o,i=t,l=!0,a=!0,c=e.posMax,u=e.src.charCodeAt(t);for(n=t>0?e.src.charCodeAt(t-1):-1;c>i&&e.src.charCodeAt(i)===u;)i++;return i>=c&&(l=!1),o=i-t,o>=4?l=a=!1:(s=c>i?e.src.charCodeAt(i):-1,(32===s||10===s)&&(l=!1),(32===n||10===n)&&(a=!1),95===u&&(r(n)&&(l=!1),r(s)&&(a=!1))),{can_open:l,can_close:a,delims:o}}t.exports=function(e,t){var r,s,o,i,l,a,c,u=e.posMax,p=e.pos,h=e.src.charCodeAt(p);if(95!==h&&42!==h)return!1;if(t)return!1;if(c=n(e,p),r=c.delims,!c.can_open)return e.pos+=r,t||(e.pending+=e.src.slice(p,e.pos)),!0;if(e.level>=e.options.maxNesting)return!1;for(e.pos=p+r,a=[r];e.posl){a.push(i-l);break}if(l-=i,0===a.length)break;e.pos+=i,i=a.pop()}if(0===a.length){r=i,o=!0;break}e.pos+=s;continue}c.can_open&&a.push(s),e.pos+=s}return o?(e.posMax=e.pos,e.pos=p+r,t||((2===r||3===r)&&e.push({type:"strong_open",level:e.level++}),(1===r||3===r)&&e.push({type:"em_open",level:e.level++}),e.parser.tokenize(e),(1===r||3===r)&&e.push({type:"em_close",level:--e.level}),(2===r||3===r)&&e.push({type:"strong_close",level:--e.level})),e.pos=e.posMax+r,e.posMax=u,!0):(e.pos=p,!1)}},{}],47:[function(e,t){"use strict";var r=e("../common/entities"),n=e("../common/utils").has,s=e("../common/utils").isValidEntityCode,o=e("../common/utils").fromCodePoint,i=/^&#((?:x[a-f0-9]{1,8}|[0-9]{1,8}));/i,l=/^&([a-z][a-z0-9]{1,31});/i;t.exports=function(e,t){var a,c,u,p=e.pos,h=e.posMax;if(38!==e.src.charCodeAt(p))return!1;if(h>p+1)if(a=e.src.charCodeAt(p+1),35===a){if(u=e.src.slice(p).match(i))return t||(c="x"===u[1][0].toLowerCase()?parseInt(u[1].slice(1),16):parseInt(u[1],10),e.pending+=o(s(c)?c:65533)),e.pos+=u[0].length,!0}else if(u=e.src.slice(p).match(l),u&&n(r,u[1]))return t||(e.pending+=r[u[1]]),e.pos+=u[0].length,!0;return t||(e.pending+="&"),e.pos++,!0}},{"../common/entities":1,"../common/utils":5}],48:[function(e,t){"use strict";for(var r=[],n=0;256>n;n++)r.push(0);"\\!\"#$%&'()*+,./:;<=>?@[]^_`{|}~-".split("").forEach(function(e){r[e.charCodeAt(0)]=1}),t.exports=function(e,t){var n,s=e.pos,o=e.posMax;if(92!==e.src.charCodeAt(s))return!1;if(s++,o>s){if(n=e.src.charCodeAt(s),256>n&&0!==r[n])return t||(e.pending+=e.src[s]),e.pos+=2,!0;if(10===n){for(t||e.push({type:"hardbreak",level:e.level}),s++;o>s&&32===e.src.charCodeAt(s);)s++;return e.pos=s,!0}}return t||(e.pending+="\\"),e.pos++,!0}},{}],49:[function(e,t){"use strict";var r=e("../helpers/parse_link_label");t.exports=function(e,t){var n,s,o,i,l=e.posMax,a=e.pos;return a+2>=l?!1:94!==e.src.charCodeAt(a)?!1:91!==e.src.charCodeAt(a+1)?!1:e.level>=e.options.maxNesting?!1:(n=a+2,s=r(e,a+1),0>s?!1:(t||(e.env.footnotes||(e.env.footnotes={}),e.env.footnotes.list||(e.env.footnotes.list=[]),o=e.env.footnotes.list.length,e.pos=n,e.posMax=s,e.push({type:"footnote_ref",id:o,level:e.level}),e.linkLevel++,i=e.tokens.length,e.parser.tokenize(e),e.env.footnotes.list[o]={tokens:e.tokens.splice(i)},e.linkLevel--),e.pos=s+1,e.posMax=l,!0))}},{"../helpers/parse_link_label":12}],50:[function(e,t){"use strict";t.exports=function(e,t){var r,n,s,o,i=e.posMax,l=e.pos;if(l+3>i)return!1;if(!e.env.footnotes||!e.env.footnotes.refs)return!1;if(91!==e.src.charCodeAt(l))return!1;if(94!==e.src.charCodeAt(l+1))return!1;if(e.level>=e.options.maxNesting)return!1;for(n=l+2;i>n;n++){if(32===e.src.charCodeAt(n))return!1;if(10===e.src.charCodeAt(n))return!1;if(93===e.src.charCodeAt(n))break}return n===l+2?!1:n>=i?!1:(n++,r=e.src.slice(l+2,n-1),"undefined"==typeof e.env.footnotes.refs[":"+r]?!1:(t||(e.env.footnotes.list||(e.env.footnotes.list=[]),e.env.footnotes.refs[":"+r]<0?(s=e.env.footnotes.list.length,e.env.footnotes.list[s]={label:r,count:0},e.env.footnotes.refs[":"+r]=s):s=e.env.footnotes.refs[":"+r],o=e.env.footnotes.list[s].count,e.env.footnotes.list[s].count++,e.push({type:"footnote_ref",id:s,subId:o,level:e.level})),e.pos=n,e.posMax=i,!0))}},{}],51:[function(e,t){"use strict";function r(e){var t=32|e;return t>=97&&122>=t}var n=e("../common/html_re").HTML_TAG_RE;t.exports=function(e,t){var s,o,i,l=e.pos;return e.options.html?(i=e.posMax,60!==e.src.charCodeAt(l)||l+2>=i?!1:(s=e.src.charCodeAt(l+1),(33===s||63===s||47===s||r(s))&&(o=e.src.slice(l).match(n))?(t||e.push({type:"htmltag",content:e.src.slice(l,l+o[0].length),level:e.level}),e.pos+=o[0].length,!0):!1)):!1}},{"../common/html_re":3}],52:[function(e,t){"use strict";t.exports=function(e,t){var r,n,s,o,i,l=e.posMax,a=e.pos;if(43!==e.src.charCodeAt(a))return!1;if(t)return!1;if(a+4>=l)return!1;if(43!==e.src.charCodeAt(a+1))return!1;if(e.level>=e.options.maxNesting)return!1;if(o=a>0?e.src.charCodeAt(a-1):-1,i=e.src.charCodeAt(a+2),43===o)return!1;if(43===i)return!1;if(32===i||10===i)return!1;for(n=a+2;l>n&&43===e.src.charCodeAt(n);)n++;if(n!==a+2)return e.pos+=n-a,t||(e.pending+=e.src.slice(a,n)),!0;for(e.pos=a+2,s=1;e.pos+1=s))){r=!0;break}e.parser.skipToken(e)}return r?(e.posMax=e.pos,e.pos=a+2,t||(e.push({type:"ins_open",level:e.level++}),e.parser.tokenize(e),e.push({type:"ins_close",level:--e.level})),e.pos=e.posMax+2,e.posMax=l,!0):(e.pos=a,!1)}},{}],53:[function(e,t){"use strict";var r=e("../helpers/parse_link_label"),n=e("../helpers/parse_link_destination"),s=e("../helpers/parse_link_title"),o=e("../helpers/normalize_reference");t.exports=function(e,t){var i,l,a,c,u,p,h,f,d=!1,g=e.pos,m=e.posMax,b=e.pos,v=e.src.charCodeAt(b);if(33===v&&(d=!0,v=e.src.charCodeAt(++b)),91!==v)return!1;if(e.level>=e.options.maxNesting)return!1;if(i=b+1,l=r(e,b),0>l)return!1;if(p=l+1,m>p&&40===e.src.charCodeAt(p)){for(p++;m>p&&(f=e.src.charCodeAt(p),32===f||10===f);p++);if(p>=m)return!1;for(b=p,n(e,p)?(c=e.linkContent,p=e.pos):c="",b=p;m>p&&(f=e.src.charCodeAt(p),32===f||10===f);p++);if(m>p&&b!==p&&s(e,p))for(u=e.linkContent,p=e.pos;m>p&&(f=e.src.charCodeAt(p),32===f||10===f);p++);else u="";if(p>=m||41!==e.src.charCodeAt(p))return e.pos=g,!1;p++}else{if(e.linkLevel>0)return!1;for(;m>p&&(f=e.src.charCodeAt(p),32===f||10===f);p++);if(m>p&&91===e.src.charCodeAt(p)&&(b=p+1,p=r(e,p),p>=0?a=e.src.slice(b,p++):p=b-1),a||("undefined"==typeof a&&(p=l+1),a=e.src.slice(i,l)),h=e.env.references[o(a)],!h)return e.pos=g,!1;c=h.href,u=h.title}return t||(e.pos=i,e.posMax=l,d?e.push({type:"image",src:c,title:u,alt:e.src.substr(i,l-i),level:e.level}):(e.push({type:"link_open",href:c,title:u,level:e.level++}),e.linkLevel++,e.parser.tokenize(e),e.linkLevel--,e.push({type:"link_close",level:--e.level}))),e.pos=p,e.posMax=m,!0}},{"../helpers/normalize_reference":10,"../helpers/parse_link_destination":11,"../helpers/parse_link_label":12,"../helpers/parse_link_title":13}],54:[function(e,t){"use strict";t.exports=function(e,t){var r,n,s,o,i,l=e.posMax,a=e.pos;if(61!==e.src.charCodeAt(a))return!1;if(t)return!1;if(a+4>=l)return!1;if(61!==e.src.charCodeAt(a+1))return!1;if(e.level>=e.options.maxNesting)return!1;if(o=a>0?e.src.charCodeAt(a-1):-1,i=e.src.charCodeAt(a+2),61===o)return!1;if(61===i)return!1;if(32===i||10===i)return!1;for(n=a+2;l>n&&61===e.src.charCodeAt(n);)n++;if(n!==a+2)return e.pos+=n-a,t||(e.pending+=e.src.slice(a,n)),!0;for(e.pos=a+2,s=1;e.pos+1=s))){r=!0;break}e.parser.skipToken(e)}return r?(e.posMax=e.pos,e.pos=a+2,t||(e.push({type:"mark_open",level:e.level++}),e.parser.tokenize(e),e.push({type:"mark_close",level:--e.level})),e.pos=e.posMax+2,e.posMax=l,!0):(e.pos=a,!1)}},{}],55:[function(e,t){"use strict";t.exports=function(e,t){var r,n,s=e.pos;if(10!==e.src.charCodeAt(s))return!1;if(r=e.pending.length-1,n=e.posMax,!t)if(r>=0&&32===e.pending.charCodeAt(r))if(r>=1&&32===e.pending.charCodeAt(r-1)){for(var o=r-2;o>=0;o--)if(32!==e.pending.charCodeAt(o)){e.pending=e.pending.substring(0,o+1);break}e.push({type:"hardbreak",level:e.level})}else e.pending=e.pending.slice(0,-1),e.push({type:"softbreak",level:e.level});else e.push({type:"softbreak",level:e.level});for(s++;n>s&&32===e.src.charCodeAt(s);)s++;return e.pos=s,!0}},{}],56:[function(e,t){"use strict";function r(e,t,r,n,s){this.src=e,this.env=n,this.options=r,this.parser=t,this.tokens=s,this.pos=0,this.posMax=this.src.length,this.level=0,this.pending="",this.pendingLevel=0,this.cache=[],this.isInLabel=!1,this.linkLevel=0,this.linkContent="",this.labelUnmatchedScopes=0}r.prototype.pushPending=function(){this.tokens.push({type:"text",content:this.pending,level:this.pendingLevel}),this.pending=""},r.prototype.push=function(e){this.pending&&this.pushPending(),this.tokens.push(e),this.pendingLevel=this.level},r.prototype.cacheSet=function(e,t){for(var r=this.cache.length;e>=r;r++)this.cache.push(0);this.cache[e]=t},r.prototype.cacheGet=function(e){return e?@[\]^_`{|}~-])/g;t.exports=function(e,t){var n,s,o=e.posMax,i=e.pos;if(126!==e.src.charCodeAt(i))return!1;if(t)return!1;if(i+2>=o)return!1;if(e.level>=e.options.maxNesting)return!1;for(e.pos=i+1;e.pos?@[\]^_`{|}~-])/g;t.exports=function(e,t){var n,s,o=e.posMax,i=e.pos;if(94!==e.src.charCodeAt(i))return!1;if(t)return!1;if(i+2>=o)return!1;if(e.level>=e.options.maxNesting)return!1;for(e.pos=i+1;e.poso;o++){var l=r[o],a=l.getType(),c=l.getText();if("element"===a)"a"===l.getTagName()&&(l.isClosing()?n=Math.max(n-1,0):n++),s.push(c);else if("entity"===a)s.push(c);else if(0===n){var u=this.linkifyStr(c);s.push(u)}else s.push(c)}return s.join("")},linkifyStr:function(e){return this.getMatchParser().replace(e,this.createMatchReturnVal,this)},createMatchReturnVal:function(t){var r;if(this.replaceFn&&(r=this.replaceFn.call(this,this,t)),"string"==typeof r)return r;if(r===!1)return t.getMatchedText();if(r instanceof e.HtmlTag)return r.toString();var n=this.getTagBuilder(),s=n.build(t);return s.toString()},getHtmlParser:function(){var t=this.htmlParser;return t||(t=this.htmlParser=new e.htmlParser.HtmlParser),t},getMatchParser:function(){var t=this.matchParser;return t||(t=this.matchParser=new e.matchParser.MatchParser({urls:this.urls,email:this.email,twitter:this.twitter,stripPrefix:this.stripPrefix})),t},getTagBuilder:function(){var t=this.tagBuilder;return t||(t=this.tagBuilder=new e.AnchorTagBuilder({newWindow:this.newWindow,truncate:this.truncate,className:this.className})),t}},e.link=function(t,r){var n=new e(r);return n.link(t)},e.match={},e.htmlParser={},e.matchParser={},e.Util={abstractMethod:function(){throw"abstract"},assign:function(e,t){for(var r in t)t.hasOwnProperty(r)&&(e[r]=t[r]);return e},extend:function(t,r){var n=t.prototype,s=function(){};s.prototype=n;var o;o=r.hasOwnProperty("constructor")?r.constructor:function(){n.constructor.apply(this,arguments)};var i=o.prototype=new s;return i.constructor=o,i.superclass=n,delete r.constructor,e.Util.assign(i,r),o},ellipsis:function(e,t,r){return e.length>t&&(r=null==r?"..":r,e=e.substring(0,t-r.length)+r),e},indexOf:function(e,t){if(Array.prototype.indexOf)return e.indexOf(t);for(var r=0,n=e.length;n>r;r++)if(e[r]===t)return r;return-1},splitAndCapture:function(e,t){if(!t.global)throw new Error("`splitRegex` must have the 'g' flag set");for(var r,n=[],s=0;r=t.exec(e);)n.push(e.substring(s,r.index)),n.push(r[0]),s=r.index+r[0].length;return n.push(e.substring(s)),n}},e.HtmlTag=e.Util.extend(Object,{whitespaceRegex:/\s+/,constructor:function(t){e.Util.assign(this,t),this.innerHtml=this.innerHtml||this.innerHTML},setTagName:function(e){return this.tagName=e,this},getTagName:function(){return this.tagName||""},setAttr:function(e,t){var r=this.getAttrs();return r[e]=t,this},getAttr:function(e){return this.getAttrs()[e]},setAttrs:function(t){var r=this.getAttrs();return e.Util.assign(r,t),this},getAttrs:function(){return this.attrs||(this.attrs={})},setClass:function(e){return this.setAttr("class",e)},addClass:function(t){for(var r,n=this.getClass(),s=this.whitespaceRegex,o=e.Util.indexOf,i=n?n.split(s):[],l=t.split(s);r=l.shift();)-1===o(i,r)&&i.push(r);return this.getAttrs()["class"]=i.join(" "),this},removeClass:function(t){for(var r,n=this.getClass(),s=this.whitespaceRegex,o=e.Util.indexOf,i=n?n.split(s):[],l=t.split(s);i.length&&(r=l.shift());){var a=o(i,r);-1!==a&&i.splice(a,1)}return this.getAttrs()["class"]=i.join(" "),this},getClass:function(){return this.getAttrs()["class"]||""},hasClass:function(e){return-1!==(" "+this.getClass()+" ").indexOf(" "+e+" ")},setInnerHtml:function(e){return this.innerHtml=e,this},getInnerHtml:function(){return this.innerHtml||""},toString:function(){var e=this.getTagName(),t=this.buildAttrsStr();return t=t?" "+t:"",["<",e,t,">",this.getInnerHtml(),""].join("")},buildAttrsStr:function(){if(!this.attrs)return"";var e=this.getAttrs(),t=[];for(var r in e)e.hasOwnProperty(r)&&t.push(r+'="'+e[r]+'"');return t.join(" ")}}),e.AnchorTagBuilder=e.Util.extend(Object,{constructor:function(t){e.Util.assign(this,t)},build:function(t){var r=new e.HtmlTag({tagName:"a",attrs:this.createAttrs(t.getType(),t.getAnchorHref()),innerHtml:this.processAnchorText(t.getAnchorText())});return r},createAttrs:function(e,t){var r={href:t},n=this.createCssClass(e);return n&&(r["class"]=n),this.newWindow&&(r.target="_blank"),r},createCssClass:function(e){var t=this.className;return t?t+" "+t+"-"+e:""},processAnchorText:function(e){return e=this.doTruncate(e)},doTruncate:function(t){return e.Util.ellipsis(t,this.truncate||Number.POSITIVE_INFINITY)}}),e.htmlParser.HtmlParser=e.Util.extend(Object,{htmlRegex:function(){var e=/[0-9a-zA-Z][0-9a-zA-Z:]*/,t=/[^\s\0"'>\/=\x01-\x1F\x7F]+/,r=/(?:"[^"]*?"|'[^']*?'|[^'"=<>`\s]+)/,n=t.source+"(?:\\s*=\\s*"+r.source+")?";return new RegExp(["(?:","<(!DOCTYPE)","(?:","\\s+","(?:",n,"|",r.source+")",")*",">",")","|","(?:","<(/)?","("+e.source+")","(?:","\\s+",n,")*","\\s*/?",">",")"].join(""),"gi")}(),htmlCharacterEntitiesRegex:/( | |<|<|>|>|"|"|')/gi,parse:function(e){for(var t,r,n=this.htmlRegex,s=0,o=[];null!==(t=n.exec(e));){var i=t[0],l=t[1]||t[3],a=!!t[2],c=e.substring(s,t.index);c&&(r=this.parseTextAndEntityNodes(c),o.push.apply(o,r)),o.push(this.createElementNode(i,l,a)),s=t.index+i.length}if(ss;s+=2){var i=n[s],l=n[s+1];i&&r.push(this.createTextNode(i)),l&&r.push(this.createEntityNode(l))}return r},createElementNode:function(t,r,n){return new e.htmlParser.ElementNode({text:t,tagName:r.toLowerCase(),closing:n})},createEntityNode:function(t){return new e.htmlParser.EntityNode({text:t})},createTextNode:function(t){return new e.htmlParser.TextNode({text:t})}}),e.htmlParser.HtmlNode=e.Util.extend(Object,{text:"",constructor:function(t){e.Util.assign(this,t)},getType:e.Util.abstractMethod,getText:function(){return this.text}}),e.htmlParser.ElementNode=e.Util.extend(e.htmlParser.HtmlNode,{tagName:"",closing:!1,getType:function(){return"element"},getTagName:function(){return this.tagName},isClosing:function(){return this.closing}}),e.htmlParser.EntityNode=e.Util.extend(e.htmlParser.HtmlNode,{getType:function(){return"entity"}}),e.htmlParser.TextNode=e.Util.extend(e.htmlParser.HtmlNode,{getType:function(){return"text"}}),e.matchParser.MatchParser=e.Util.extend(Object,{urls:!0,email:!0,twitter:!0,stripPrefix:!0,matcherRegex:function(){var e=/(^|[^\w])@(\w{1,15})/,t=/(?:[\-;:&=\+\$,\w\.]+@)/,r=/(?:[A-Za-z][-.+A-Za-z0-9]+:(?![A-Za-z][-.+A-Za-z0-9]+:\/\/)(?!\d+\/?)(?:\/\/)?)/,n=/(?:www\.)/,s=/[A-Za-z0-9\.\-]*[A-Za-z0-9\-]/,o=/\.(?:international|construction|contractors|enterprises|photography|productions|foundation|immobilien|industries|management|properties|technology|christmas|community|directory|education|equipment|institute|marketing|solutions|vacations|bargains|boutique|builders|catering|cleaning|clothing|computer|democrat|diamonds|graphics|holdings|lighting|partners|plumbing|supplies|training|ventures|academy|careers|company|cruises|domains|exposed|flights|florist|gallery|guitars|holiday|kitchen|neustar|okinawa|recipes|rentals|reviews|shiksha|singles|support|systems|agency|berlin|camera|center|coffee|condos|dating|estate|events|expert|futbol|kaufen|luxury|maison|monash|museum|nagoya|photos|repair|report|social|supply|tattoo|tienda|travel|viajes|villas|vision|voting|voyage|actor|build|cards|cheap|codes|dance|email|glass|house|mango|ninja|parts|photo|shoes|solar|today|tokyo|tools|watch|works|aero|arpa|asia|best|bike|blue|buzz|camp|club|cool|coop|farm|fish|gift|guru|info|jobs|kiwi|kred|land|limo|link|menu|mobi|moda|name|pics|pink|post|qpon|rich|ruhr|sexy|tips|vote|voto|wang|wien|wiki|zone|bar|bid|biz|cab|cat|ceo|com|edu|gov|int|kim|mil|net|onl|org|pro|pub|red|tel|uno|wed|xxx|xyz|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cw|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|za|zm|zw)\b/,i=/[\-A-Za-z0-9+&@#\/%=~_()|'$*\[\]?!:,.;]*[\-A-Za-z0-9+&@#\/%=~_()|'$*\[\]]/;return new RegExp(["(",e.source,")","|","(",t.source,s.source,o.source,")","|","(","(?:","(",r.source,s.source,")","|","(?:","(.?//)?",n.source,s.source,")","|","(?:","(.?//)?",s.source,o.source,")",")","(?:"+i.source+")?",")"].join(""),"gi")}(),charBeforeProtocolRelMatchRegex:/^(.)?\/\//,constructor:function(t){e.Util.assign(this,t),this.matchValidator=new e.MatchValidator},replace:function(e,t,r){var n=this;return e.replace(this.matcherRegex,function(e,s,o,i,l,a,c,u,p){var h=n.processCandidateMatch(e,s,o,i,l,a,c,u,p);if(h){var f=t.call(r,h.match);return h.prefixStr+f+h.suffixStr}return e})},processCandidateMatch:function(t,r,n,s,o,i,l,a,c){var u,p=a||c,h="",f="";if(r&&!this.twitter||o&&!this.email||i&&!this.urls||!this.matchValidator.isValidMatch(i,l,p))return null;if(this.matchHasUnbalancedClosingParen(t)&&(t=t.substr(0,t.length-1),f=")"),o)u=new e.match.Email({matchedText:t,email:o});else if(r)n&&(h=n,t=t.slice(1)),u=new e.match.Twitter({matchedText:t,twitterHandle:s});else{if(p){var d=p.match(this.charBeforeProtocolRelMatchRegex)[1]||"";d&&(h=d,t=t.slice(1))}u=new e.match.Url({matchedText:t,url:t,protocolUrlMatch:!!l,protocolRelativeMatch:!!p,stripPrefix:this.stripPrefix})}return{prefixStr:h,suffixStr:f,match:u}},matchHasUnbalancedClosingParen:function(e){var t=e.charAt(e.length-1);if(")"===t){var r=e.match(/\(/g),n=e.match(/\)/g),s=r&&r.length||0,o=n&&n.length||0;if(o>s)return!0}return!1}}),e.MatchValidator=e.Util.extend(Object,{invalidProtocolRelMatchRegex:/^[\w]\/\//,hasFullProtocolRegex:/^[A-Za-z][-.+A-Za-z0-9]+:\/\//,uriSchemeRegex:/^[A-Za-z][-.+A-Za-z0-9]+:/,hasWordCharAfterProtocolRegex:/:[^\s]*?[A-Za-z]/,isValidMatch:function(e,t,r){return t&&!this.isValidUriScheme(t)||this.urlMatchDoesNotHaveProtocolOrDot(e,t)||this.urlMatchDoesNotHaveAtLeastOneWordChar(e,t)||this.isInvalidProtocolRelativeMatch(r)?!1:!0},isValidUriScheme:function(e){var t=e.match(this.uriSchemeRegex)[0].toLowerCase();return"javascript:"!==t&&"vbscript:"!==t},urlMatchDoesNotHaveProtocolOrDot:function(e,t){return!(!e||t&&this.hasFullProtocolRegex.test(t)||-1!==e.indexOf("."))},urlMatchDoesNotHaveAtLeastOneWordChar:function(e,t){return e&&t?!this.hasWordCharAfterProtocolRegex.test(e):!1},isInvalidProtocolRelativeMatch:function(e){return!!e&&this.invalidProtocolRelMatchRegex.test(e)}}),e.match.Match=e.Util.extend(Object,{constructor:function(t){e.Util.assign(this,t)},getType:e.Util.abstractMethod,getMatchedText:function(){return this.matchedText},getAnchorHref:e.Util.abstractMethod,getAnchorText:e.Util.abstractMethod}),e.match.Email=e.Util.extend(e.match.Match,{getType:function(){return"email"},getEmail:function(){return this.email},getAnchorHref:function(){return"mailto:"+this.email},getAnchorText:function(){return this.email}}),e.match.Twitter=e.Util.extend(e.match.Match,{getType:function(){return"twitter"},getTwitterHandle:function(){return this.twitterHandle},getAnchorHref:function(){return"https://twitter.com/"+this.twitterHandle},getAnchorText:function(){return"@"+this.twitterHandle}}),e.match.Url=e.Util.extend(e.match.Match,{urlPrefixRegex:/^(https?:\/\/)?(www\.)?/i,protocolRelativeRegex:/^\/\//,protocolPrepended:!1,getType:function(){return"url"},getUrl:function(){var e=this.url;return this.protocolRelativeMatch||this.protocolUrlMatch||this.protocolPrepended||(e=this.url="http://"+e,this.protocolPrepended=!0),e},getAnchorHref:function(){var e=this.getUrl();return e.replace(/&/g,"&")},getAnchorText:function(){var e=this.getUrl();return this.protocolRelativeMatch&&(e=this.stripProtocolRelativePrefix(e)),this.stripPrefix&&(e=this.stripUrlPrefix(e)),e=this.removeTrailingSlash(e)},stripUrlPrefix:function(e){return e.replace(this.urlPrefixRegex,"")},stripProtocolRelativePrefix:function(e){return e.replace(this.protocolRelativeRegex,"")},removeTrailingSlash:function(e){return"/"===e.charAt(e.length-1)&&(e=e.slice(0,-1)),e}}),e})},{}],"/":[function(e,t){"use strict";t.exports=e("./lib/")},{"./lib/":14}]},{},[])("/")}); \ No newline at end of file diff --git a/src/React.Template/reactnet-vanilla/wwwroot/js/tutorial.jsx b/src/React.Template/reactnet-vanilla/wwwroot/js/tutorial.jsx new file mode 100644 index 000000000..08a059827 --- /dev/null +++ b/src/React.Template/reactnet-vanilla/wwwroot/js/tutorial.jsx @@ -0,0 +1,133 @@ +class CommentBox extends React.Component { + state = { data: this.props.initialData }; + + loadCommentsFromServer = () => { + var xhr = new XMLHttpRequest(); + xhr.open('get', this.props.url, true); + xhr.onload = function() { + var data = JSON.parse(xhr.responseText); + this.setState({ data: data }); + }.bind(this); + xhr.send(); + }; + + handleCommentSubmit = comment => { + var comments = this.state.data; + // Optimistically set an id on the new comment. It will be replaced by an + // id generated by the server. In a production application you would likely + // not use Date.now() for this and would have a more robust system in place. + comment.id = Date.now(); + var newComments = comments.concat([comment]); + this.setState({ data: newComments }); + + var data = new FormData(); + data.append('author', comment.author); + data.append('text', comment.text); + + var xhr = new XMLHttpRequest(); + xhr.open('post', this.props.submitUrl, true); + xhr.onload = function() { + this.loadCommentsFromServer(); + }.bind(this); + xhr.send(data); + }; + + componentDidMount() { + window.setInterval(this.loadCommentsFromServer, this.props.pollInterval); + } + + render() { + return ( +
    +

    Comments

    + + +
    + ); + } +} + +class CommentList extends React.Component { + render() { + var commentNodes = this.props.data.map(function(comment) { + return ( + + {comment.text} + + ); + }); + return
    {commentNodes}
    ; + } +} + +class CommentForm extends React.Component { + state = { + author: '', + text: '' + }; + + handleAuthorChange = e => { + this.setState({ author: e.target.value }); + }; + + handleTextChange = e => { + this.setState({ text: e.target.value }); + }; + + handleSubmit = e => { + e.preventDefault(); + var author = this.state.author.trim(); + var text = this.state.text.trim(); + if (!text || !author) { + return; + } + this.props.onCommentSubmit({ author: author, text: text }); + this.setState({ author: '', text: '' }); + }; + + render() { + return ( +
    + + + +
    + ); + } +} + +function createRemarkable() { + var remarkable = + 'undefined' != typeof global && global.Remarkable + ? global.Remarkable + : window.Remarkable; + + return new remarkable(); +} + +class Comment extends React.Component { + rawMarkup = () => { + var md = createRemarkable(); + var rawMarkup = md.render(this.props.children.toString()); + return { __html: rawMarkup }; + }; + + render() { + return ( +
    +

    {this.props.author}

    + +
    + ); + } +} diff --git a/src/React.Template/reactnet-webpack/.babelrc b/src/React.Template/reactnet-webpack/.babelrc new file mode 100644 index 000000000..3a5660bb5 --- /dev/null +++ b/src/React.Template/reactnet-webpack/.babelrc @@ -0,0 +1,8 @@ +{ + "presets": ["@babel/preset-react", "@babel/preset-env"], + "plugins": [ + "@babel/proposal-object-rest-spread", + "@babel/plugin-syntax-dynamic-import", + "@babel/proposal-class-properties" + ] +} diff --git a/src/React.Template/reactnet-webpack/.gitattributes b/src/React.Template/reactnet-webpack/.gitattributes new file mode 100644 index 000000000..c7e67bc5d --- /dev/null +++ b/src/React.Template/reactnet-webpack/.gitattributes @@ -0,0 +1,4 @@ +* text eol=lf +*.png binary +*.exe binary +*.dll binary diff --git a/src/React.Template/reactnet-webpack/.gitignore b/src/React.Template/reactnet-webpack/.gitignore new file mode 100644 index 000000000..8f8b43bb1 --- /dev/null +++ b/src/React.Template/reactnet-webpack/.gitignore @@ -0,0 +1,232 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +build/ +bld/ +bin/ +Bin/ +obj/ +Obj/ + +# Visual Studio 2015 cache/options directory +.vs/ +/wwwroot/dist/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Microsoft Azure ApplicationInsights config file +ApplicationInsights.config + +# Windows Store app package directory +AppPackages/ +BundleArtifacts/ + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.pfx +*.publishsettings +orleans.codegen.cs + +/node_modules + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe + +# FAKE - F# Make +.fake/ diff --git a/src/React.Template/reactnet-webpack/.template.config/template.json b/src/React.Template/reactnet-webpack/.template.config/template.json new file mode 100644 index 000000000..2eb228838 --- /dev/null +++ b/src/React.Template/reactnet-webpack/.template.config/template.json @@ -0,0 +1,13 @@ +{ + "author": "ReactJS.NET contributors", + "classifications": [ + "Web" + ], + "name": "React.NET Webpack Starter Template", + "identity": "React.Template.NetCore.Webpack", + "shortName": "reactnet-webpack", + "tags": { + "language": "C#" + }, + "preferNameDirectory": "true" +} diff --git a/src/React.Template/reactnet-webpack/Content/components/comments/Sample.jsx b/src/React.Template/reactnet-webpack/Content/components/comments/Sample.jsx new file mode 100644 index 000000000..6ce6b6405 --- /dev/null +++ b/src/React.Template/reactnet-webpack/Content/components/comments/Sample.jsx @@ -0,0 +1,125 @@ +/** + * Copyright (c) 2014-Present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +import React from 'react'; +import PropTypes from 'prop-types'; +import * as Reactstrap from 'reactstrap'; + +export function CommentsBox(props) { + let [state, updateState] = React.useState({ + comments: props.initialComments, + page: props.page, + hasMore: true, + loadingMore: false, + }); + + function loadMoreClicked(evt) { + let nextPage = state.page + 1; + let comments = state.comments; + updateState(prevState => ({ + ...prevState, + page: nextPage, + loadingMore: true, + })); + + let url = '/comments/page-' + (state.page + 1); + let xhr = new XMLHttpRequest(); + xhr.open('GET', url, true); + xhr.setRequestHeader('Content-Type', 'application/json'); + + xhr.onload = () => { + let data = JSON.parse(xhr.responseText); + updateState(prevState => ({ + ...prevState, + comments: comments.concat(data.comments), + hasMore: data.hasMore, + loadingMore: false, + })); + }; + xhr.send(); + evt.preventDefault(); + } + + let commentNodes = state.comments.map(comment => ( + {comment.text} + )); + + function renderMoreLink() { + if (state.loadingMore) { + return Loading...; + } else if (state.hasMore) { + return ( + + Load More + + ); + } else { + return No more comments; + } + } + + return ( +
    +

    + This is an example of ReactJS.NET's server-side rendering. The + initial state of this comments box is rendered server-side, and + additional data is loaded via AJAX and rendered client-side. +

    +
    +

    Comments

    +
      {commentNodes}
    + {renderMoreLink()} +
    +
    +
    + ); +} + +class Comment extends React.Component { + static propTypes = { + author: PropTypes.object.isRequired, + }; + + render() { + return ( +
  • + + {this.props.author.name} + {': '} + {this.props.children} +
  • + ); + } +} + +class Avatar extends React.Component { + static propTypes = { + author: PropTypes.object.isRequired, + }; + + render() { + return ( + {'Photo + ); + } + + getPhotoUrl = author => { + return ( + 'https://avatars.githubusercontent.com/' + + author.githubUsername + + '?s=50' + ); + }; +} diff --git a/src/React.Template/reactnet-webpack/Content/components/emotion.jsx b/src/React.Template/reactnet-webpack/Content/components/emotion.jsx new file mode 100644 index 000000000..ef0555e1f --- /dev/null +++ b/src/React.Template/reactnet-webpack/Content/components/emotion.jsx @@ -0,0 +1,34 @@ +import React, { Fragment } from 'react'; +import styled from 'react-emotion'; +import { Helmet } from 'react-helmet'; + +const BlueTitle = styled('h1')` + color: #222; + font-family: Helvetica, 'sans-serif'; + text-shadow: 0 0 5px lightgray; + line-height: 2; + + a { + transition: color 0.2s ease; + color: palevioletred; + text-decoration: none; + + &:hover { + color: #888; + } + } +`; + +export function EmotionDemo() { + return ( + + + ReactJS.NET Demos | Emotion + + + Hello from{' '} + emotion! + + + ); +} diff --git a/src/React.Template/reactnet-webpack/Content/components/expose-components.js b/src/React.Template/reactnet-webpack/Content/components/expose-components.js new file mode 100644 index 000000000..b89f85baf --- /dev/null +++ b/src/React.Template/reactnet-webpack/Content/components/expose-components.js @@ -0,0 +1,20 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import ReactDOMServer from 'react-dom/server'; + +import RootComponent from './home.jsx'; +import { ServerStyleSheet } from 'styled-components'; +import { JssProvider, SheetsRegistry } from 'react-jss'; +import { renderStylesToString } from 'emotion-server'; +import Helmet from 'react-helmet'; + +global.React = React; +global.ReactDOM = ReactDOM; +global.ReactDOMServer = ReactDOMServer; + +global.Styled = { ServerStyleSheet }; +global.ReactJss = { JssProvider, SheetsRegistry }; +global.EmotionServer = { renderStylesToString }; +global.Helmet = Helmet; + +global.Components = { RootComponent }; diff --git a/src/React.Template/reactnet-webpack/Content/components/home.jsx b/src/React.Template/reactnet-webpack/Content/components/home.jsx new file mode 100644 index 000000000..7cd5f4fd7 --- /dev/null +++ b/src/React.Template/reactnet-webpack/Content/components/home.jsx @@ -0,0 +1,114 @@ +import { Component, Fragment } from 'react'; +import { + Link, + BrowserRouter, + Route, + Switch, + StaticRouter, + Redirect, +} from 'react-router-dom'; +import { Helmet } from 'react-helmet'; + +import { CommentsBox } from './comments/Sample.jsx'; +import { StyledComponentsDemo } from './styled-components.jsx'; +import { EmotionDemo } from './emotion.jsx'; +import { ReactJssDemo } from './react-jss.jsx'; +import { LazyLoadDemo } from './lazy-load.jsx'; + +class Navbar extends Component { + render() { + return ( +
      +
    • + Home +
    • +
    • + Comments Demo +
    • +
    • + Styled Components Demo +
    • +
    • + React-JSS Demo +
    • +
    • + Emotion Demo +
    • +
    • + Lazy loading demo +
    • +
    + ); + } +} + +class HomePage extends Component { + render() { + return ( + + + ReactJS.NET Demos + + ReactJS.NET is 🔥🔥 + + ); + } +} + +export default class HomeComponent extends Component { + render() { + const app = ( +
    +
    +

    .NET Core Sample

    + +
    + + } + /> + + ( + + )} + /> + + + + + { + if (staticContext) staticContext.status = 404; + + return

    Not Found :(

    ; + }} + /> +
    +
    +
    + ); + + if (typeof window === 'undefined') { + return ( + + {app} + + ); + } + return {app}; + } +} diff --git a/src/React.Template/reactnet-webpack/Content/components/lazy-load.jsx b/src/React.Template/reactnet-webpack/Content/components/lazy-load.jsx new file mode 100644 index 000000000..c967c81d9 --- /dev/null +++ b/src/React.Template/reactnet-webpack/Content/components/lazy-load.jsx @@ -0,0 +1,30 @@ +import React, { Fragment, useState, useEffect } from 'react'; +import { Helmet } from 'react-helmet'; + +export function LazyLoadDemo() { + const [lazySelect, setLazySelect] = useState(); + const [framework, setFramework] = useState(); + useEffect(() => { + import('react-select').then(component => { + setLazySelect({ Component: component.default }); + }); + }, []); + return ( + + + ReactJS.NET Demos | Lazy loading + + {lazySelect && lazySelect.Component ? ( + ({ value: x, label: x }))} + className="basic-multi-select" + classNamePrefix="select" + onChange={setFramework} + /> + ) : 'Loading'} +
    {framework ? 'Pick a framework' : null}
    +
    + ); +} diff --git a/src/React.Template/reactnet-webpack/Content/components/react-jss.jsx b/src/React.Template/reactnet-webpack/Content/components/react-jss.jsx new file mode 100644 index 000000000..d999c360c --- /dev/null +++ b/src/React.Template/reactnet-webpack/Content/components/react-jss.jsx @@ -0,0 +1,49 @@ +import React, { Fragment } from 'react'; +import injectSheet from 'react-jss'; +import { Helmet } from 'react-helmet'; + +const styles = { + demoTitle: { + color: '#222', + fontFamily: 'Helvetica, sans-serif', + textShadow: '0 0 5px lightgray', + lineHeight: '2', + '& a': { + transition: 'color 0.2s ease', + color: 'palevioletred', + 'text-decoration': 'none', + + '&:hover': { + color: '#888', + }, + }, + }, +}; + +const DemoTitle = ({ classes, children }) => ( +

    + Hello from React-JSS! +

    +); + +const WithInjectedSheet = injectSheet(styles)(DemoTitle); + +export class ReactJssDemo extends React.Component { + componentDidMount() { + const serverStyles = document.getElementById('server-side-styles'); + if (serverStyles) { + serverStyles.parentNode.removeChild(serverStyles); + } + } + + render() { + return ( + + + ReactJS.NET Demos | React-JSS + + + + ); + } +} diff --git a/src/React.Template/reactnet-webpack/Content/components/styled-components.jsx b/src/React.Template/reactnet-webpack/Content/components/styled-components.jsx new file mode 100644 index 000000000..913f54d99 --- /dev/null +++ b/src/React.Template/reactnet-webpack/Content/components/styled-components.jsx @@ -0,0 +1,36 @@ +import React, { Fragment } from 'react'; +import styled from 'styled-components'; +import { Helmet } from 'react-helmet'; +const BlueTitle = styled.h1` + color: #222; + font-family: Helvetica, 'sans-serif'; + text-shadow: 0 0 5px lightgray; + line-height: 2; + + a { + transition: color 0.2s ease; + color: palevioletred; + text-decoration: none; + + &:hover { + color: #888; + } + } +`; + +export function StyledComponentsDemo() { + return ( + + + ReactJS.NET Demos | Styled Components + + + Hello from{' '} + + styled-components + + ! + + + ); +} diff --git a/src/React.Template/reactnet-webpack/Controllers/HomeController.cs b/src/React.Template/reactnet-webpack/Controllers/HomeController.cs new file mode 100644 index 000000000..f73de1d61 --- /dev/null +++ b/src/React.Template/reactnet-webpack/Controllers/HomeController.cs @@ -0,0 +1,91 @@ +using System.Collections.Generic; +using System.Linq; +using Microsoft.AspNetCore.Mvc; + +namespace React.Sample.Webpack.CoreMvc.Controllers +{ + public class HomeController : Controller + { + private const int COMMENTS_PER_PAGE = 3; + + private readonly IDictionary _authors; + private readonly IList _comments; + + public HomeController() + { + // In reality, you would use a repository or something for fetching data + // For clarity, we'll just use a hard-coded list. + _authors = new Dictionary + { + {"daniel", new AuthorModel { Name = "Daniel Lo Nigro", GithubUsername = "Daniel15" }}, + {"vjeux", new AuthorModel { Name = "Christopher Chedeau", GithubUsername = "vjeux" }}, + {"cpojer", new AuthorModel { Name = "Christoph Pojer", GithubUsername = "cpojer" }}, + {"jordwalke", new AuthorModel { Name = "Jordan Walke", GithubUsername = "jordwalke" }}, + {"zpao", new AuthorModel { Name = "Paul O'Shannessy", GithubUsername = "zpao" }}, + }; + _comments = new List + { + new CommentModel { Author = _authors["daniel"], Text = "First!!!!111!" }, + new CommentModel { Author = _authors["zpao"], Text = "React is awesome!" }, + new CommentModel { Author = _authors["cpojer"], Text = "Awesome!" }, + new CommentModel { Author = _authors["vjeux"], Text = "Hello World" }, + new CommentModel { Author = _authors["daniel"], Text = "Foo" }, + new CommentModel { Author = _authors["daniel"], Text = "Bar" }, + new CommentModel { Author = _authors["daniel"], Text = "FooBarBaz" }, + }; + } + + public ActionResult Index() + { + return View(new IndexViewModel + { + Comments = _comments.Take(COMMENTS_PER_PAGE).ToList().AsReadOnly(), + CommentsPerPage = COMMENTS_PER_PAGE, + Page = 1 + }); + } + + public ActionResult Comments(int page) + { + var comments = _comments.Skip((page - 1) * COMMENTS_PER_PAGE).Take(COMMENTS_PER_PAGE); + var hasMore = page * COMMENTS_PER_PAGE < _comments.Count; + + if (ControllerContext.HttpContext.Request.ContentType == "application/json") + { + return new JsonResult(new + { + comments = comments, + hasMore = hasMore + }); + } + else + { + return View("~/Views/Home/Index.cshtml", new IndexViewModel + { + Comments = _comments.Take(COMMENTS_PER_PAGE * page).ToList().AsReadOnly(), + CommentsPerPage = COMMENTS_PER_PAGE, + Page = page + }); + } + } + + public class AuthorModel + { + public string Name { get; set; } + public string GithubUsername { get; set; } + } + + public class CommentModel + { + public AuthorModel Author { get; set; } + public string Text { get; set; } + } + + public class IndexViewModel + { + public IReadOnlyList Comments { get; set; } + public int CommentsPerPage { get; set; } + public int Page { get; set; } + } + } +} diff --git a/src/React.Template/reactnet-webpack/Program.cs b/src/React.Template/reactnet-webpack/Program.cs new file mode 100644 index 000000000..0929370a8 --- /dev/null +++ b/src/React.Template/reactnet-webpack/Program.cs @@ -0,0 +1,18 @@ +using Microsoft.AspNetCore; +using Microsoft.AspNetCore.Hosting; + +namespace React.Sample.Webpack.CoreMvc +{ + public class Program + { + public static void Main(string[] args) + { + BuildWebHost(args).Run(); + } + + public static IWebHost BuildWebHost(string[] args) => + WebHost.CreateDefaultBuilder(args) + .UseStartup() + .Build(); + } +} diff --git a/src/React.Template/reactnet-webpack/Properties/launchSettings.json b/src/React.Template/reactnet-webpack/Properties/launchSettings.json new file mode 100644 index 000000000..adeb701d0 --- /dev/null +++ b/src/React.Template/reactnet-webpack/Properties/launchSettings.json @@ -0,0 +1,29 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:9456/", + "sslPort": 0 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "React.Sample.Webpack.CoreMvc": { + "commandName": "Project", + "launchBrowser": true, + "launchUrl": "", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "http://localhost:9457/" + } + } +} diff --git a/src/React.Template/reactnet-webpack/SampleApp.csproj b/src/React.Template/reactnet-webpack/SampleApp.csproj new file mode 100644 index 000000000..e2675751f --- /dev/null +++ b/src/React.Template/reactnet-webpack/SampleApp.csproj @@ -0,0 +1,24 @@ + + + netcoreapp3.1 + + + + + + + + + + + + + + + + + + + + + diff --git a/src/React.Template/reactnet-webpack/Startup.cs b/src/React.Template/reactnet-webpack/Startup.cs new file mode 100644 index 000000000..7bd728db3 --- /dev/null +++ b/src/React.Template/reactnet-webpack/Startup.cs @@ -0,0 +1,66 @@ +using JavaScriptEngineSwitcher.ChakraCore; +using JavaScriptEngineSwitcher.Extensions.MsDependencyInjection; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using React.AspNet; + +namespace React.Sample.Webpack.CoreMvc +{ + public class Startup + { + public Startup(IConfiguration configuration) + { + Configuration = configuration; + } + + public IConfiguration Configuration { get; } + + // This method gets called by the runtime. Use this method to add services to the container. + public void ConfigureServices(IServiceCollection services) + { + services.AddMvc(); + + services.AddJsEngineSwitcher(options => options.DefaultEngineName = ChakraCoreJsEngine.EngineName) + .AddChakraCore(); + + services.AddReact(); + services.AddSingleton(); + + // Build the intermediate service provider then return it + services.BuildServiceProvider(); + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IHostEnvironment env) + { + // Initialise ReactJS.NET. Must be before static files. + app.UseReact(config => + { + config + .SetReuseJavaScriptEngines(true) + .SetLoadBabel(false) + .SetLoadReact(false) + .SetReactAppBuildPath("~/dist"); + }); + + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + + app.UseStaticFiles(); + + app.UseRouting(); + + app.UseEndpoints(endpoints => + { + endpoints.MapControllerRoute("default", "{path?}", new { controller = "Home", action = "Index" }); + endpoints.MapControllerRoute("comments-root", "comments", new { controller = "Home", action = "Index" }); + endpoints.MapControllerRoute("comments", "comments/page-{page}", new { controller = "Home", action = "Comments" }); + }); + } + } +} diff --git a/src/React.Template/reactnet-webpack/Views/Home/Index.cshtml b/src/React.Template/reactnet-webpack/Views/Home/Index.cshtml new file mode 100644 index 000000000..05947b737 --- /dev/null +++ b/src/React.Template/reactnet-webpack/Views/Home/Index.cshtml @@ -0,0 +1,19 @@ +@using React.AspNet +@using React.RenderFunctions +@using React.Router +@model React.Sample.Webpack.CoreMvc.Controllers.HomeController.IndexViewModel + +@{ + Layout = "_Layout"; + var emotionFunctions = new EmotionFunctions(); + var styledComponentsFunctions = new StyledComponentsFunctions(); + var reactJssFunctions = new ReactJssFunctions(); + var helmetFunctions = new ReactHelmetFunctions(); + + var chainedFunctions = new ChainedRenderFunctions(emotionFunctions, styledComponentsFunctions, reactJssFunctions, helmetFunctions); +} +@Html.ReactRouter("Components.RootComponent", new { initialComments = Model.Comments, page = Model.Page }, renderFunctions: chainedFunctions) +@{ + ViewBag.ServerStyles = styledComponentsFunctions.RenderedStyles + reactJssFunctions.RenderedStyles; + ViewBag.HelmetTitle = helmetFunctions.RenderedHelmet?.GetValueOrDefault("title"); +} diff --git a/src/React.Template/reactnet-webpack/Views/Shared/_Layout.cshtml b/src/React.Template/reactnet-webpack/Views/Shared/_Layout.cshtml new file mode 100644 index 000000000..52307c13f --- /dev/null +++ b/src/React.Template/reactnet-webpack/Views/Shared/_Layout.cshtml @@ -0,0 +1,17 @@ +@using React.AspNet + + + + @Html.Raw(ViewBag.HelmetTitle) + + + + @Html.Raw(ViewBag.ServerStyles) + @Html.ReactGetStylePaths() + + + @RenderBody() + @Html.ReactGetScriptPaths() + @Html.ReactInitJavaScript() + + diff --git a/src/React.Template/reactnet-webpack/appsettings.Development.json b/src/React.Template/reactnet-webpack/appsettings.Development.json new file mode 100644 index 000000000..fa8ce71a9 --- /dev/null +++ b/src/React.Template/reactnet-webpack/appsettings.Development.json @@ -0,0 +1,10 @@ +{ + "Logging": { + "IncludeScopes": false, + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } + } +} diff --git a/src/React.Template/reactnet-webpack/appsettings.json b/src/React.Template/reactnet-webpack/appsettings.json new file mode 100644 index 000000000..26bb0ac7a --- /dev/null +++ b/src/React.Template/reactnet-webpack/appsettings.json @@ -0,0 +1,15 @@ +{ + "Logging": { + "IncludeScopes": false, + "Debug": { + "LogLevel": { + "Default": "Warning" + } + }, + "Console": { + "LogLevel": { + "Default": "Warning" + } + } + } +} diff --git a/src/React.Template/reactnet-webpack/package-lock.json b/src/React.Template/reactnet-webpack/package-lock.json new file mode 100644 index 000000000..75714070e --- /dev/null +++ b/src/React.Template/reactnet-webpack/package-lock.json @@ -0,0 +1,6758 @@ +{ + "name": "React.Sample.Webpack.CoreMvc", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", + "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", + "requires": { + "@babel/highlight": "^7.10.1" + } + }, + "@babel/compat-data": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.10.1.tgz", + "integrity": "sha512-CHvCj7So7iCkGKPRFUfryXIkU2gSBw7VSZFYLsqVhrS47269VK2Hfi9S/YcublPMW8k1u2bQBlbDruoQEm4fgw==", + "dev": true, + "requires": { + "browserslist": "^4.12.0", + "invariant": "^2.2.4", + "semver": "^5.5.0" + } + }, + "@babel/core": { + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.7.tgz", + "integrity": "sha512-rBlqF3Yko9cynC5CCFy6+K/w2N+Sq/ff2BPy+Krp7rHlABIr5epbA7OxVeKoMHB39LZOp1UY5SuLjy6uWi35yA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.8.7", + "@babel/helpers": "^7.8.4", + "@babel/parser": "^7.8.7", + "@babel/template": "^7.8.6", + "@babel/traverse": "^7.8.6", + "@babel/types": "^7.8.7", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.0", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + } + }, + "@babel/generator": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.2.tgz", + "integrity": "sha512-AxfBNHNu99DTMvlUPlt1h2+Hn7knPpH5ayJ8OqDWSeLld+Fi2AYBTC/IejWDM9Edcii4UzZRCsbUt0WlSDsDsA==", + "requires": { + "@babel/types": "^7.10.2", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.1.tgz", + "integrity": "sha512-ewp3rvJEwLaHgyWGe4wQssC2vjks3E80WiUe2BpMb0KhreTjMROCbxXcEovTrbeGVdQct5VjQfrv9EgC+xMzCw==", + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.1.tgz", + "integrity": "sha512-cQpVq48EkYxUU0xozpGCLla3wlkdRRqLWu1ksFMXA9CM5KQmyyRpSEsYXbao7JUkOw/tAaYKCaYyZq6HOFYtyw==", + "dev": true, + "requires": { + "@babel/helper-explode-assignable-expression": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-builder-react-jsx": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.10.1.tgz", + "integrity": "sha512-KXzzpyWhXgzjXIlJU1ZjIXzUPdej1suE6vzqgImZ/cpAsR/CC8gUcX4EWRmDfWz/cs6HOCPMBIJ3nKoXt3BFuw==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-builder-react-jsx-experimental": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.10.1.tgz", + "integrity": "sha512-irQJ8kpQUV3JasXPSFQ+LCCtJSc5ceZrPFVj6TElR6XCHssi3jV8ch3odIrNtjJFRZZVbrOEfJMI79TPU/h1pQ==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.10.1", + "@babel/helper-module-imports": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.2.tgz", + "integrity": "sha512-hYgOhF4To2UTB4LTaZepN/4Pl9LD4gfbJx8A34mqoluT8TLbof1mhUlYuNWTEebONa8+UlCC4X0TEXu7AOUyGA==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.10.1", + "browserslist": "^4.12.0", + "invariant": "^2.2.4", + "levenary": "^1.1.1", + "semver": "^5.5.0" + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.2.tgz", + "integrity": "sha512-5C/QhkGFh1vqcziq1vAL6SI9ymzUp8BCYjFpvYVhWP4DlATIb3u5q3iUd35mvlyGs8fO7hckkW7i0tmH+5+bvQ==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.10.1", + "@babel/helper-member-expression-to-functions": "^7.10.1", + "@babel/helper-optimise-call-expression": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/helper-replace-supers": "^7.10.1", + "@babel/helper-split-export-declaration": "^7.10.1" + } + }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.1.tgz", + "integrity": "sha512-Rx4rHS0pVuJn5pJOqaqcZR4XSgeF9G/pO/79t+4r7380tXFJdzImFnxMU19f83wjSrmKHq6myrM10pFHTGzkUA==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.10.1", + "@babel/helper-regex": "^7.10.1", + "regexpu-core": "^4.7.0" + } + }, + "@babel/helper-define-map": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.10.1.tgz", + "integrity": "sha512-+5odWpX+OnvkD0Zmq7panrMuAGQBu6aPUgvMzuMGo4R+jUOvealEj2hiqI6WhxgKrTpFoFj0+VdsuA8KDxHBDg==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.10.1", + "@babel/types": "^7.10.1", + "lodash": "^4.17.13" + } + }, + "@babel/helper-explode-assignable-expression": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.10.1.tgz", + "integrity": "sha512-vcUJ3cDjLjvkKzt6rHrl767FeE7pMEYfPanq5L16GRtrXIoznc0HykNW2aEYkcnP76P0isoqJ34dDMFZwzEpJg==", + "dev": true, + "requires": { + "@babel/traverse": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-function-name": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.1.tgz", + "integrity": "sha512-fcpumwhs3YyZ/ttd5Rz0xn0TpIwVkN7X0V38B9TWNfVF42KEkhkAAuPCQ3oXmtTRtiPJrmZ0TrfS0GKF0eMaRQ==", + "requires": { + "@babel/helper-get-function-arity": "^7.10.1", + "@babel/template": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.1.tgz", + "integrity": "sha512-F5qdXkYGOQUb0hpRaPoetF9AnsXknKjWMZ+wmsIRsp5ge5sFh4c3h1eH2pRTTuy9KKAA2+TTYomGXAtEL2fQEw==", + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.1.tgz", + "integrity": "sha512-vLm5srkU8rI6X3+aQ1rQJyfjvCBLXP8cAGeuw04zeAM2ItKb1e7pmVmLyHb4sDaAYnLL13RHOZPLEtcGZ5xvjg==", + "dev": true, + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.1.tgz", + "integrity": "sha512-u7XLXeM2n50gb6PWJ9hoO5oO7JFPaZtrh35t8RqKLT1jFKj9IWeD1zrcrYp1q1qiZTdEarfDWfTIP8nGsu0h5g==", + "dev": true, + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-module-imports": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.1.tgz", + "integrity": "sha512-SFxgwYmZ3HZPyZwJRiVNLRHWuW2OgE5k2nrVs6D9Iv4PPnXVffuEHy83Sfx/l4SqF+5kyJXjAyUmrG7tNm+qVg==", + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-module-transforms": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.1.tgz", + "integrity": "sha512-RLHRCAzyJe7Q7sF4oy2cB+kRnU4wDZY/H2xJFGof+M+SJEGhZsb+GFj5j1AD8NiSaVBJ+Pf0/WObiXu/zxWpFg==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.10.1", + "@babel/helper-replace-supers": "^7.10.1", + "@babel/helper-simple-access": "^7.10.1", + "@babel/helper-split-export-declaration": "^7.10.1", + "@babel/template": "^7.10.1", + "@babel/types": "^7.10.1", + "lodash": "^4.17.13" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.1.tgz", + "integrity": "sha512-a0DjNS1prnBsoKx83dP2falChcs7p3i8VMzdrSbfLhuQra/2ENC4sbri34dz/rWmDADsmF1q5GbfaXydh0Jbjg==", + "dev": true, + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.1.tgz", + "integrity": "sha512-fvoGeXt0bJc7VMWZGCAEBEMo/HAjW2mP8apF5eXK0wSqwLAVHAISCWRoLMBMUs2kqeaG77jltVqu4Hn8Egl3nA==", + "dev": true + }, + "@babel/helper-regex": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.10.1.tgz", + "integrity": "sha512-7isHr19RsIJWWLLFn21ubFt223PjQyg1HY7CZEMRr820HttHPpVvrsIN3bUOo44DEfFV4kBXO7Abbn9KTUZV7g==", + "dev": true, + "requires": { + "lodash": "^4.17.13" + } + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.10.1.tgz", + "integrity": "sha512-RfX1P8HqsfgmJ6CwaXGKMAqbYdlleqglvVtht0HGPMSsy2V6MqLlOJVF/0Qyb/m2ZCi2z3q3+s6Pv7R/dQuZ6A==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.10.1", + "@babel/helper-wrap-function": "^7.10.1", + "@babel/template": "^7.10.1", + "@babel/traverse": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-replace-supers": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.1.tgz", + "integrity": "sha512-SOwJzEfpuQwInzzQJGjGaiG578UYmyi2Xw668klPWV5n07B73S0a9btjLk/52Mlcxa+5AdIYqws1KyXRfMoB7A==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.10.1", + "@babel/helper-optimise-call-expression": "^7.10.1", + "@babel/traverse": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-simple-access": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.1.tgz", + "integrity": "sha512-VSWpWzRzn9VtgMJBIWTZ+GP107kZdQ4YplJlCmIrjoLVSi/0upixezHCDG8kpPVTBJpKfxTH01wDhh+jS2zKbw==", + "dev": true, + "requires": { + "@babel/template": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.1.tgz", + "integrity": "sha512-UQ1LVBPrYdbchNhLwj6fetj46BcFwfS4NllJo/1aJsT+1dLTEnXJL0qHqtY7gPzF8S2fXBJamf1biAXV3X077g==", + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz", + "integrity": "sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw==" + }, + "@babel/helper-wrap-function": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.10.1.tgz", + "integrity": "sha512-C0MzRGteVDn+H32/ZgbAv5r56f2o1fZSA/rj/TYo8JEJNHg+9BdSmKBUND0shxWRztWhjlT2cvHYuynpPsVJwQ==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.10.1", + "@babel/template": "^7.10.1", + "@babel/traverse": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/helpers": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.1.tgz", + "integrity": "sha512-muQNHF+IdU6wGgkaJyhhEmI54MOZBKsFfsXFhboz1ybwJ1Kl7IHlbm2a++4jwrmY5UYsgitt5lfqo1wMFcHmyw==", + "dev": true, + "requires": { + "@babel/template": "^7.10.1", + "@babel/traverse": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/highlight": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", + "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", + "requires": { + "@babel/helper-validator-identifier": "^7.10.1", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz", + "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==" + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.1.tgz", + "integrity": "sha512-vzZE12ZTdB336POZjmpblWfNNRpMSua45EYnRigE2XsZxcXcIyly2ixnTJasJE4Zq3U7t2d8rRF7XRUuzHxbOw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/helper-remap-async-to-generator": "^7.10.1", + "@babel/plugin-syntax-async-generators": "^7.8.0" + } + }, + "@babel/plugin-proposal-class-properties": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.8.3.tgz", + "integrity": "sha512-EqFhbo7IosdgPgZggHaNObkmO1kNUe3slaKu54d5OWvy+p9QIKOzK1GAEpAIsZtWVtPXUHSMcT4smvDrCfY4AA==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3" + } + }, + "@babel/plugin-proposal-dynamic-import": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.1.tgz", + "integrity": "sha512-Cpc2yUVHTEGPlmiQzXj026kqwjEQAD9I4ZC16uzdbgWgitg/UHKHLffKNCQZ5+y8jpIZPJcKcwsr2HwPh+w3XA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/plugin-syntax-dynamic-import": "^7.8.0" + } + }, + "@babel/plugin-proposal-json-strings": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.1.tgz", + "integrity": "sha512-m8r5BmV+ZLpWPtMY2mOKN7wre6HIO4gfIiV+eOmsnZABNenrt/kzYBwrh+KOfgumSWpnlGs5F70J8afYMSJMBg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/plugin-syntax-json-strings": "^7.8.0" + } + }, + "@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.1.tgz", + "integrity": "sha512-56cI/uHYgL2C8HVuHOuvVowihhX0sxb3nnfVRzUeVHTWmRHTZrKuAh/OBIMggGU/S1g/1D2CRCXqP+3u7vX7iA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-8qvuPwU/xxUCt78HocNlv0mXXo0wdh9VT1R04WU8HGOfaOob26pF+9P5/lYjN/q7DHOX1bvX60hnhOvuQUJdbA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.0" + } + }, + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.1.tgz", + "integrity": "sha512-VqExgeE62YBqI3ogkGoOJp1R6u12DFZjqwJhqtKc2o5m1YTUuUWnos7bZQFBhwkxIFpWYJ7uB75U7VAPPiKETA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.0" + } + }, + "@babel/plugin-proposal-optional-chaining": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.10.1.tgz", + "integrity": "sha512-dqQj475q8+/avvok72CF3AOSV/SGEcH29zT5hhohqqvvZ2+boQoOr7iGldBG5YXTO2qgCgc2B3WvVLUdbeMlGA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/plugin-syntax-optional-chaining": "^7.8.0" + } + }, + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.1.tgz", + "integrity": "sha512-JjfngYRvwmPwmnbRZyNiPFI8zxCZb8euzbCG/LxyKdeTb59tVciKo9GK9bi6JYKInk1H11Dq9j/zRqIH4KigfQ==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-jsx": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.10.1.tgz", + "integrity": "sha512-+OxyOArpVFXQeXKLO9o+r2I4dIoVoy6+Uu0vKELrlweDM3QJADZj+Z+5ERansZqIZBcLj42vHnDI8Rz9BnRIuQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.1.tgz", + "integrity": "sha512-hgA5RYkmZm8FTFT3yu2N9Bx7yVVOKYT6yEdXXo6j2JTm0wNxgqaGeQVaSHRjhfnQbX91DtjFB6McRFSlcJH3xQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.1.tgz", + "integrity": "sha512-6AZHgFJKP3DJX0eCNJj01RpytUa3SOGawIxweHkNX2L6PYikOZmoh5B0d7hIHaIgveMjX990IAa/xK7jRTN8OA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.1.tgz", + "integrity": "sha512-XCgYjJ8TY2slj6SReBUyamJn3k2JLUIiiR5b6t1mNCMSvv7yx+jJpaewakikp0uWFQSF7ChPPoe3dHmXLpISkg==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/helper-remap-async-to-generator": "^7.10.1" + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.1.tgz", + "integrity": "sha512-B7K15Xp8lv0sOJrdVAoukKlxP9N59HS48V1J3U/JGj+Ad+MHq+am6xJVs85AgXrQn4LV8vaYFOB+pr/yIuzW8Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.10.1.tgz", + "integrity": "sha512-8bpWG6TtF5akdhIm/uWTyjHqENpy13Fx8chg7pFH875aNLwX8JxIxqm08gmAT+Whe6AOmaTeLPe7dpLbXt+xUw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1", + "lodash": "^4.17.13" + } + }, + "@babel/plugin-transform-classes": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.1.tgz", + "integrity": "sha512-P9V0YIh+ln/B3RStPoXpEQ/CoAxQIhRSUn7aXqQ+FZJ2u8+oCtjIXR3+X0vsSD8zv+mb56K7wZW1XiDTDGiDRQ==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.10.1", + "@babel/helper-define-map": "^7.10.1", + "@babel/helper-function-name": "^7.10.1", + "@babel/helper-optimise-call-expression": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/helper-replace-supers": "^7.10.1", + "@babel/helper-split-export-declaration": "^7.10.1", + "globals": "^11.1.0" + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.1.tgz", + "integrity": "sha512-mqSrGjp3IefMsXIenBfGcPXxJxweQe2hEIwMQvjtiDQ9b1IBvDUjkAtV/HMXX47/vXf14qDNedXsIiNd1FmkaQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.1.tgz", + "integrity": "sha512-V/nUc4yGWG71OhaTH705pU8ZSdM6c1KmmLP8ys59oOYbT7RpMYAR3MsVOt6OHL0WzG7BlTU076va9fjJyYzJMA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.1.tgz", + "integrity": "sha512-19VIMsD1dp02RvduFUmfzj8uknaO3uiHHF0s3E1OHnVsNj8oge8EQ5RzHRbJjGSetRnkEuBYO7TG1M5kKjGLOA==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-duplicate-keys": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.1.tgz", + "integrity": "sha512-wIEpkX4QvX8Mo9W6XF3EdGttrIPZWozHfEaDTU0WJD/TDnXMvdDh30mzUl/9qWhnf7naicYartcEfUghTCSNpA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.1.tgz", + "integrity": "sha512-lr/przdAbpEA2BUzRvjXdEDLrArGRRPwbaF9rvayuHRvdQ7lUTTkZnhZrJ4LE2jvgMRFF4f0YuPQ20vhiPYxtA==", + "dev": true, + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.1.tgz", + "integrity": "sha512-US8KCuxfQcn0LwSCMWMma8M2R5mAjJGsmoCBVwlMygvmDUMkTCykc84IqN1M7t+agSfOmLYTInLCHJM+RUoz+w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.1.tgz", + "integrity": "sha512-//bsKsKFBJfGd65qSNNh1exBy5Y9gD9ZN+DvrJ8f7HXr4avE5POW6zB7Rj6VnqHV33+0vXWUwJT0wSHubiAQkw==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-literals": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.1.tgz", + "integrity": "sha512-qi0+5qgevz1NHLZroObRm5A+8JJtibb7vdcPQF1KQE12+Y/xxl8coJ+TpPW9iRq+Mhw/NKLjm+5SHtAHCC7lAw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-member-expression-literals": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.1.tgz", + "integrity": "sha512-UmaWhDokOFT2GcgU6MkHC11i0NQcL63iqeufXWfRy6pUOGYeCGEKhvfFO6Vz70UfYJYHwveg62GS83Rvpxn+NA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.1.tgz", + "integrity": "sha512-31+hnWSFRI4/ACFr1qkboBbrTxoBIzj7qA69qlq8HY8p7+YCzkCT6/TvQ1a4B0z27VeWtAeJd6pr5G04dc1iHw==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.1.tgz", + "integrity": "sha512-AQG4fc3KOah0vdITwt7Gi6hD9BtQP/8bhem7OjbaMoRNCH5Djx42O2vYMfau7QnAzQCa+RJnhJBmFFMGpQEzrg==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/helper-simple-access": "^7.10.1", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-systemjs": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.1.tgz", + "integrity": "sha512-ewNKcj1TQZDL3YnO85qh9zo1YF1CHgmSTlRQgHqe63oTrMI85cthKtZjAiZSsSNjPQ5NCaYo5QkbYqEw1ZBgZA==", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "^7.10.1", + "@babel/helper-module-transforms": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.1.tgz", + "integrity": "sha512-EIuiRNMd6GB6ulcYlETnYYfgv4AxqrswghmBRQbWLHZxN4s7mupxzglnHqk9ZiUpDI4eRWewedJJNj67PWOXKA==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.8.3.tgz", + "integrity": "sha512-f+tF/8UVPU86TrCb06JoPWIdDpTNSGGcAtaD9mLP0aYGA0OS0j7j7DHJR0GTFrUZPUU6loZhbsVZgTh0N+Qdnw==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.8.3" + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.1.tgz", + "integrity": "sha512-MBlzPc1nJvbmO9rPr1fQwXOM2iGut+JC92ku6PbiJMMK7SnQc1rytgpopveE3Evn47gzvGYeCdgfCDbZo0ecUw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.1.tgz", + "integrity": "sha512-WnnStUDN5GL+wGQrJylrnnVlFhFmeArINIR9gjhSeYyvroGhBrSAXYg/RHsnfzmsa+onJrTJrEClPzgNmmQ4Gw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/helper-replace-supers": "^7.10.1" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.1.tgz", + "integrity": "sha512-tJ1T0n6g4dXMsL45YsSzzSDZCxiHXAQp/qHrucOq5gEHncTA3xDxnd5+sZcoQp+N1ZbieAaB8r/VUCG0gqseOg==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-property-literals": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.1.tgz", + "integrity": "sha512-Kr6+mgag8auNrgEpbfIWzdXYOvqDHZOF0+Bx2xh4H2EDNwcbRb9lY6nkZg8oSjsX+DH9Ebxm9hOqtKW+gRDeNA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-react-display-name": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.10.1.tgz", + "integrity": "sha512-rBjKcVwjk26H3VX8pavMxGf33LNlbocMHdSeldIEswtQ/hrjyTG8fKKILW1cSkODyRovckN/uZlGb2+sAV9JUQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-react-jsx": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.10.1.tgz", + "integrity": "sha512-MBVworWiSRBap3Vs39eHt+6pJuLUAaK4oxGc8g+wY+vuSJvLiEQjW1LSTqKb8OUPtDvHCkdPhk7d6sjC19xyFw==", + "dev": true, + "requires": { + "@babel/helper-builder-react-jsx": "^7.10.1", + "@babel/helper-builder-react-jsx-experimental": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/plugin-syntax-jsx": "^7.10.1" + } + }, + "@babel/plugin-transform-react-jsx-self": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.10.1.tgz", + "integrity": "sha512-4p+RBw9d1qV4S749J42ZooeQaBomFPrSxa9JONLHJ1TxCBo3TzJ79vtmG2S2erUT8PDDrPdw4ZbXGr2/1+dILA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/plugin-syntax-jsx": "^7.10.1" + } + }, + "@babel/plugin-transform-react-jsx-source": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.10.1.tgz", + "integrity": "sha512-neAbaKkoiL+LXYbGDvh6PjPG+YeA67OsZlE78u50xbWh2L1/C81uHiNP5d1fw+uqUIoiNdCC8ZB+G4Zh3hShJA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/plugin-syntax-jsx": "^7.10.1" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.1.tgz", + "integrity": "sha512-B3+Y2prScgJ2Bh/2l9LJxKbb8C8kRfsG4AdPT+n7ixBHIxJaIG8bi8tgjxUMege1+WqSJ+7gu1YeoMVO3gPWzw==", + "dev": true, + "requires": { + "regenerator-transform": "^0.14.2" + } + }, + "@babel/plugin-transform-reserved-words": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.1.tgz", + "integrity": "sha512-qN1OMoE2nuqSPmpTqEM7OvJ1FkMEV+BjVeZZm9V9mq/x1JLKQ4pcv8riZJMNN3u2AUGl0ouOMjRr2siecvHqUQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.1.tgz", + "integrity": "sha512-AR0E/lZMfLstScFwztApGeyTHJ5u3JUKMjneqRItWeEqDdHWZwAOKycvQNCasCK/3r5YXsuNG25funcJDu7Y2g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-spread": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.10.1.tgz", + "integrity": "sha512-8wTPym6edIrClW8FI2IoaePB91ETOtg36dOkj3bYcNe7aDMN2FXEoUa+WrmPc4xa1u2PQK46fUX2aCb+zo9rfw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.1.tgz", + "integrity": "sha512-j17ojftKjrL7ufX8ajKvwRilwqTok4q+BjkknmQw9VNHnItTyMP5anPFzxFJdCQs7clLcWpCV3ma+6qZWLnGMA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/helper-regex": "^7.10.1" + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.1.tgz", + "integrity": "sha512-t7B/3MQf5M1T9hPCRG28DNGZUuxAuDqLYS03rJrIk2prj/UV7Z6FOneijhQhnv/Xa039vidXeVbvjK2SK5f7Gg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.1.tgz", + "integrity": "sha512-qX8KZcmbvA23zDi+lk9s6hC1FM7jgLHYIjuLgULgc8QtYnmB3tAVIYkNoKRQ75qWBeyzcoMoK8ZQmogGtC/w0g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.1.tgz", + "integrity": "sha512-Y/2a2W299k0VIUdbqYm9X2qS6fE0CUBhhiPpimK6byy7OJ/kORLlIX+J6UrjgNu5awvs62k+6RSslxhcvVw2Tw==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/preset-env": { + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.8.7.tgz", + "integrity": "sha512-BYftCVOdAYJk5ASsznKAUl53EMhfBbr8CJ1X+AJLfGPscQkwJFiaV/Wn9DPH/7fzm2v6iRYJKYHSqyynTGw0nw==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.8.6", + "@babel/helper-compilation-targets": "^7.8.7", + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-proposal-async-generator-functions": "^7.8.3", + "@babel/plugin-proposal-dynamic-import": "^7.8.3", + "@babel/plugin-proposal-json-strings": "^7.8.3", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-proposal-object-rest-spread": "^7.8.3", + "@babel/plugin-proposal-optional-catch-binding": "^7.8.3", + "@babel/plugin-proposal-optional-chaining": "^7.8.3", + "@babel/plugin-proposal-unicode-property-regex": "^7.8.3", + "@babel/plugin-syntax-async-generators": "^7.8.0", + "@babel/plugin-syntax-dynamic-import": "^7.8.0", + "@babel/plugin-syntax-json-strings": "^7.8.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0", + "@babel/plugin-syntax-object-rest-spread": "^7.8.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.0", + "@babel/plugin-syntax-top-level-await": "^7.8.3", + "@babel/plugin-transform-arrow-functions": "^7.8.3", + "@babel/plugin-transform-async-to-generator": "^7.8.3", + "@babel/plugin-transform-block-scoped-functions": "^7.8.3", + "@babel/plugin-transform-block-scoping": "^7.8.3", + "@babel/plugin-transform-classes": "^7.8.6", + "@babel/plugin-transform-computed-properties": "^7.8.3", + "@babel/plugin-transform-destructuring": "^7.8.3", + "@babel/plugin-transform-dotall-regex": "^7.8.3", + "@babel/plugin-transform-duplicate-keys": "^7.8.3", + "@babel/plugin-transform-exponentiation-operator": "^7.8.3", + "@babel/plugin-transform-for-of": "^7.8.6", + "@babel/plugin-transform-function-name": "^7.8.3", + "@babel/plugin-transform-literals": "^7.8.3", + "@babel/plugin-transform-member-expression-literals": "^7.8.3", + "@babel/plugin-transform-modules-amd": "^7.8.3", + "@babel/plugin-transform-modules-commonjs": "^7.8.3", + "@babel/plugin-transform-modules-systemjs": "^7.8.3", + "@babel/plugin-transform-modules-umd": "^7.8.3", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.8.3", + "@babel/plugin-transform-new-target": "^7.8.3", + "@babel/plugin-transform-object-super": "^7.8.3", + "@babel/plugin-transform-parameters": "^7.8.7", + "@babel/plugin-transform-property-literals": "^7.8.3", + "@babel/plugin-transform-regenerator": "^7.8.7", + "@babel/plugin-transform-reserved-words": "^7.8.3", + "@babel/plugin-transform-shorthand-properties": "^7.8.3", + "@babel/plugin-transform-spread": "^7.8.3", + "@babel/plugin-transform-sticky-regex": "^7.8.3", + "@babel/plugin-transform-template-literals": "^7.8.3", + "@babel/plugin-transform-typeof-symbol": "^7.8.4", + "@babel/plugin-transform-unicode-regex": "^7.8.3", + "@babel/types": "^7.8.7", + "browserslist": "^4.8.5", + "core-js-compat": "^3.6.2", + "invariant": "^2.2.2", + "levenary": "^1.1.1", + "semver": "^5.5.0" + } + }, + "@babel/preset-react": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.8.3.tgz", + "integrity": "sha512-9hx0CwZg92jGb7iHYQVgi0tOEHP/kM60CtWJQnmbATSPIQQ2xYzfoCI3EdqAhFBeeJwYMdWQuDUHMsuDbH9hyQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-transform-react-display-name": "^7.8.3", + "@babel/plugin-transform-react-jsx": "^7.8.3", + "@babel/plugin-transform-react-jsx-self": "^7.8.3", + "@babel/plugin-transform-react-jsx-source": "^7.8.3" + } + }, + "@babel/runtime": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.2.tgz", + "integrity": "sha512-6sF3uQw2ivImfVIl62RZ7MXhO2tap69WeWK57vAaimT6AZbE4FbqjdEJIN1UqoD6wI6B+1n9UiagafH1sxjOtg==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/template": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", + "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==", + "requires": { + "@babel/code-frame": "^7.10.1", + "@babel/parser": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/traverse": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.1.tgz", + "integrity": "sha512-C/cTuXeKt85K+p08jN6vMDz8vSV0vZcI0wmQ36o6mjbuo++kPMdpOYw23W2XH04dbRt9/nMEfA4W3eR21CD+TQ==", + "requires": { + "@babel/code-frame": "^7.10.1", + "@babel/generator": "^7.10.1", + "@babel/helper-function-name": "^7.10.1", + "@babel/helper-split-export-declaration": "^7.10.1", + "@babel/parser": "^7.10.1", + "@babel/types": "^7.10.1", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + } + }, + "@babel/types": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", + "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", + "requires": { + "@babel/helper-validator-identifier": "^7.10.1", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "@emotion/babel-utils": { + "version": "0.6.10", + "resolved": "https://registry.npmjs.org/@emotion/babel-utils/-/babel-utils-0.6.10.tgz", + "integrity": "sha512-/fnkM/LTEp3jKe++T0KyTszVGWNKPNOUJfjNKLO17BzQ6QPxgbg3whayom1Qr2oLFH3V92tDymU+dT5q676uow==", + "requires": { + "@emotion/hash": "^0.6.6", + "@emotion/memoize": "^0.6.6", + "@emotion/serialize": "^0.9.1", + "convert-source-map": "^1.5.1", + "find-root": "^1.1.0", + "source-map": "^0.7.2" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" + } + } + }, + "@emotion/cache": { + "version": "10.0.29", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-10.0.29.tgz", + "integrity": "sha512-fU2VtSVlHiF27empSbxi1O2JFdNWZO+2NFHfwO0pxgTep6Xa3uGb+3pVKfLww2l/IBGLNEZl5Xf/++A4wAYDYQ==", + "requires": { + "@emotion/sheet": "0.9.4", + "@emotion/stylis": "0.8.5", + "@emotion/utils": "0.11.3", + "@emotion/weak-memoize": "0.2.5" + }, + "dependencies": { + "@emotion/stylis": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz", + "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==" + }, + "@emotion/utils": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-0.11.3.tgz", + "integrity": "sha512-0o4l6pZC+hI88+bzuaX/6BgOvQVhbt2PfmxauVaYOGgbsAw14wdKyvMCZXnsnsHys94iadcF+RG/wZyx6+ZZBw==" + } + } + }, + "@emotion/core": { + "version": "10.0.28", + "resolved": "https://registry.npmjs.org/@emotion/core/-/core-10.0.28.tgz", + "integrity": "sha512-pH8UueKYO5jgg0Iq+AmCLxBsvuGtvlmiDCOuv8fGNYn3cowFpLN98L8zO56U0H1PjDIyAlXymgL3Wu7u7v6hbA==", + "requires": { + "@babel/runtime": "^7.5.5", + "@emotion/cache": "^10.0.27", + "@emotion/css": "^10.0.27", + "@emotion/serialize": "^0.11.15", + "@emotion/sheet": "0.9.4", + "@emotion/utils": "0.11.3" + }, + "dependencies": { + "@emotion/hash": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", + "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==" + }, + "@emotion/memoize": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", + "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==" + }, + "@emotion/serialize": { + "version": "0.11.16", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-0.11.16.tgz", + "integrity": "sha512-G3J4o8by0VRrO+PFeSc3js2myYNOXVJ3Ya+RGVxnshRYgsvErfAOglKAiy1Eo1vhzxqtUvjCyS5gtewzkmvSSg==", + "requires": { + "@emotion/hash": "0.8.0", + "@emotion/memoize": "0.7.4", + "@emotion/unitless": "0.7.5", + "@emotion/utils": "0.11.3", + "csstype": "^2.5.7" + } + }, + "@emotion/unitless": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" + }, + "@emotion/utils": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-0.11.3.tgz", + "integrity": "sha512-0o4l6pZC+hI88+bzuaX/6BgOvQVhbt2PfmxauVaYOGgbsAw14wdKyvMCZXnsnsHys94iadcF+RG/wZyx6+ZZBw==" + } + } + }, + "@emotion/css": { + "version": "10.0.27", + "resolved": "https://registry.npmjs.org/@emotion/css/-/css-10.0.27.tgz", + "integrity": "sha512-6wZjsvYeBhyZQYNrGoR5yPMYbMBNEnanDrqmsqS1mzDm1cOTu12shvl2j4QHNS36UaTE0USIJawCH9C8oW34Zw==", + "requires": { + "@emotion/serialize": "^0.11.15", + "@emotion/utils": "0.11.3", + "babel-plugin-emotion": "^10.0.27" + }, + "dependencies": { + "@emotion/hash": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", + "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==" + }, + "@emotion/memoize": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", + "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==" + }, + "@emotion/serialize": { + "version": "0.11.16", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-0.11.16.tgz", + "integrity": "sha512-G3J4o8by0VRrO+PFeSc3js2myYNOXVJ3Ya+RGVxnshRYgsvErfAOglKAiy1Eo1vhzxqtUvjCyS5gtewzkmvSSg==", + "requires": { + "@emotion/hash": "0.8.0", + "@emotion/memoize": "0.7.4", + "@emotion/unitless": "0.7.5", + "@emotion/utils": "0.11.3", + "csstype": "^2.5.7" + } + }, + "@emotion/unitless": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" + }, + "@emotion/utils": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-0.11.3.tgz", + "integrity": "sha512-0o4l6pZC+hI88+bzuaX/6BgOvQVhbt2PfmxauVaYOGgbsAw14wdKyvMCZXnsnsHys94iadcF+RG/wZyx6+ZZBw==" + }, + "babel-plugin-emotion": { + "version": "10.0.33", + "resolved": "https://registry.npmjs.org/babel-plugin-emotion/-/babel-plugin-emotion-10.0.33.tgz", + "integrity": "sha512-bxZbTTGz0AJQDHm8k6Rf3RQJ8tX2scsfsRyKVgAbiUPUNIRtlK+7JxP+TAd1kRLABFxe0CFm2VdK4ePkoA9FxQ==", + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@emotion/hash": "0.8.0", + "@emotion/memoize": "0.7.4", + "@emotion/serialize": "^0.11.16", + "babel-plugin-macros": "^2.0.0", + "babel-plugin-syntax-jsx": "^6.18.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^1.0.5", + "find-root": "^1.1.0", + "source-map": "^0.5.7" + } + } + } + }, + "@emotion/hash": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.6.6.tgz", + "integrity": "sha512-ojhgxzUHZ7am3D2jHkMzPpsBAiB005GF5YU4ea+8DNPybMk01JJUM9V9YRlF/GE95tcOm8DxQvWA2jq19bGalQ==" + }, + "@emotion/is-prop-valid": { + "version": "0.6.8", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.6.8.tgz", + "integrity": "sha512-IMSL7ekYhmFlILXcouA6ket3vV7u9BqStlXzbKOF9HBtpUPMMlHU+bBxrLOa2NvleVwNIxeq/zL8LafLbeUXcA==", + "requires": { + "@emotion/memoize": "^0.6.6" + } + }, + "@emotion/memoize": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.6.6.tgz", + "integrity": "sha512-h4t4jFjtm1YV7UirAFuSuFGyLa+NNxjdkq6DpFLANNQY5rHueFZHVY+8Cu1HYVP6DrheB0kv4m5xPjo7eKT7yQ==" + }, + "@emotion/serialize": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-0.9.1.tgz", + "integrity": "sha512-zTuAFtyPvCctHBEL8KZ5lJuwBanGSutFEncqLn/m9T1a6a93smBStK+bZzcNPgj4QS8Rkw9VTwJGhRIUVO8zsQ==", + "requires": { + "@emotion/hash": "^0.6.6", + "@emotion/memoize": "^0.6.6", + "@emotion/unitless": "^0.6.7", + "@emotion/utils": "^0.8.2" + } + }, + "@emotion/sheet": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-0.9.4.tgz", + "integrity": "sha512-zM9PFmgVSqBw4zL101Q0HrBVTGmpAxFZH/pYx/cjJT5advXguvcgjHFTCaIO3enL/xr89vK2bh0Mfyj9aa0ANA==" + }, + "@emotion/stylis": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.7.1.tgz", + "integrity": "sha512-/SLmSIkN13M//53TtNxgxo57mcJk/UJIDFRKwOiLIBEyBHEcipgR6hNMQ/59Sl4VjCJ0Z/3zeAZyvnSLPG/1HQ==" + }, + "@emotion/unitless": { + "version": "0.6.7", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.6.7.tgz", + "integrity": "sha512-Arj1hncvEVqQ2p7Ega08uHLr1JuRYBuO5cIvcA+WWEQ5+VmkOE3ZXzl04NbQxeQpWX78G7u6MqxKuNX3wvYZxg==" + }, + "@emotion/utils": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-0.8.2.tgz", + "integrity": "sha512-rLu3wcBWH4P5q1CGoSSH/i9hrXs7SlbRLkoq9IGuoPYNGQvDJ3pt/wmOM+XgYjIDRMVIdkUWt0RsfzF50JfnCw==" + }, + "@emotion/weak-memoize": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz", + "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==" + }, + "@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" + }, + "@webassemblyjs/ast": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", + "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", + "dev": true, + "requires": { + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", + "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", + "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", + "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==", + "dev": true + }, + "@webassemblyjs/helper-code-frame": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", + "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", + "dev": true, + "requires": { + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "@webassemblyjs/helper-fsm": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", + "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==", + "dev": true + }, + "@webassemblyjs/helper-module-context": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", + "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", + "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", + "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", + "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", + "dev": true, + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", + "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", + "dev": true, + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", + "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", + "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/helper-wasm-section": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-opt": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", + "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", + "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", + "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "@webassemblyjs/wast-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", + "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/floating-point-hex-parser": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-code-frame": "1.9.0", + "@webassemblyjs/helper-fsm": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", + "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, + "acorn": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", + "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", + "dev": true + }, + "ajv": { + "version": "6.12.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz", + "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", + "dev": true + }, + "ajv-keywords": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", + "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", + "dev": true + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "optional": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "dev": true, + "requires": { + "object-assign": "^4.1.1", + "util": "0.10.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", + "dev": true, + "optional": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "babel-loader": { + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.0.6.tgz", + "integrity": "sha512-4BmWKtBOBm13uoUwd08UwjZlaw3O9GWf456R9j+5YykFZ6LUIjIKLc0zEZf+hauxPOJs96C8k6FvYD09vWzhYw==", + "dev": true, + "requires": { + "find-cache-dir": "^2.0.0", + "loader-utils": "^1.0.2", + "mkdirp": "^0.5.1", + "pify": "^4.0.1" + } + }, + "babel-plugin-dynamic-import-node": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", + "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", + "dev": true, + "requires": { + "object.assign": "^4.1.0" + } + }, + "babel-plugin-emotion": { + "version": "9.2.11", + "resolved": "https://registry.npmjs.org/babel-plugin-emotion/-/babel-plugin-emotion-9.2.11.tgz", + "integrity": "sha512-dgCImifnOPPSeXod2znAmgc64NhaaOjGEHROR/M+lmStb3841yK1sgaDYAYMnlvWNz8GnpwIPN0VmNpbWYZ+VQ==", + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@emotion/babel-utils": "^0.6.4", + "@emotion/hash": "^0.6.2", + "@emotion/memoize": "^0.6.1", + "@emotion/stylis": "^0.7.0", + "babel-plugin-macros": "^2.0.0", + "babel-plugin-syntax-jsx": "^6.18.0", + "convert-source-map": "^1.5.0", + "find-root": "^1.1.0", + "mkdirp": "^0.5.1", + "source-map": "^0.5.7", + "touch": "^2.0.1" + } + }, + "babel-plugin-macros": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz", + "integrity": "sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==", + "requires": { + "@babel/runtime": "^7.7.2", + "cosmiconfig": "^6.0.0", + "resolve": "^1.12.0" + } + }, + "babel-plugin-styled-components": { + "version": "1.10.7", + "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-1.10.7.tgz", + "integrity": "sha512-MBMHGcIA22996n9hZRf/UJLVVgkEOITuR2SvjHLb5dSTUyR4ZRGn+ngITapes36FI3WLxZHfRhkA1ffHxihOrg==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-module-imports": "^7.0.0", + "babel-plugin-syntax-jsx": "^6.18.0", + "lodash": "^4.17.11" + } + }, + "babel-plugin-syntax-jsx": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", + "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=" + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "dev": true + } + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "base64-js": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", + "dev": true + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true + }, + "binary-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", + "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", + "dev": true, + "optional": true + }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "bn.js": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.2.tgz", + "integrity": "sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "brcast": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/brcast/-/brcast-3.0.2.tgz", + "integrity": "sha512-f5XwwFCCuvgqP2nMH/hJ74FqnGmb4X3D+NC//HphxJzzhsZvSZa+Hk/syB7j3ZHpPDLMoYU8oBgviRWfNvEfKA==" + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "randombytes": "^2.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "browserify-sign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.0.tgz", + "integrity": "sha512-hEZC1KEeYuoHRqhGhTy6gWrpJA3ZDjFWv0DE61643ZnOXAKJb3u7yWcrU0mMc9SwAqK1n7myPGndkp0dFG7NFA==", + "dev": true, + "requires": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.2", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + } + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "requires": { + "pako": "~1.0.5" + } + }, + "browserslist": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.12.0.tgz", + "integrity": "sha512-UH2GkcEDSI0k/lRkuDSzFl9ZZ87skSy9w2XAn1MsZnL+4c4rqbBd3e82UWHbYDpztABrPBhZsTEeuxVfHppqDg==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001043", + "electron-to-chromium": "^1.3.413", + "node-releases": "^1.1.53", + "pkg-up": "^2.0.0" + } + }, + "buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + } + } + }, + "buffer-from": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-0.1.2.tgz", + "integrity": "sha512-RiWIenusJsmI2KcvqQABB83tLxCByE3upSP8QU3rJDMVFGPWLvPQJt/O1Su9moRWeH7d+Q2HYb68f6+v+tw2vg==" + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "cacache": { + "version": "12.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", + "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", + "dev": true, + "requires": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + }, + "dependencies": { + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "camelize": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", + "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" + }, + "caniuse-lite": { + "version": "1.0.30001081", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001081.tgz", + "integrity": "sha512-iZdh3lu09jsUtLE6Bp8NAbJskco4Y3UDtkR3GTCJGsbMowBU5IWDFF79sV2ws7lSqTzWyKazxam2thasHymENQ==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chokidar": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz", + "integrity": "sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==", + "dev": true, + "optional": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.4.0" + }, + "dependencies": { + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "optional": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "optional": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "optional": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "optional": true, + "requires": { + "is-number": "^7.0.0" + } + } + } + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "chrome-trace-event": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", + "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "classnames": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz", + "integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==" + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + }, + "dependencies": { + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "dev": true, + "requires": { + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" + }, + "dependencies": { + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "core-js": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", + "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", + "dev": true + }, + "core-js-compat": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.5.tgz", + "integrity": "sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng==", + "dev": true, + "requires": { + "browserslist": "^4.8.5", + "semver": "7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true + } + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + } + }, + "create-ecdh": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", + "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "create-emotion": { + "version": "9.2.12", + "resolved": "https://registry.npmjs.org/create-emotion/-/create-emotion-9.2.12.tgz", + "integrity": "sha512-P57uOF9NL2y98Xrbl2OuiDQUZ30GVmASsv5fbsjF4Hlraip2kyAvMm+2PoYUvFFw03Fhgtxk3RqZSm2/qHL9hA==", + "requires": { + "@emotion/hash": "^0.6.2", + "@emotion/memoize": "^0.6.1", + "@emotion/stylis": "^0.7.0", + "@emotion/unitless": "^0.6.2", + "csstype": "^2.5.2", + "stylis": "^3.5.0", + "stylis-rule-sheet": "^0.0.10" + } + }, + "create-emotion-server": { + "version": "9.2.12", + "resolved": "https://registry.npmjs.org/create-emotion-server/-/create-emotion-server-9.2.12.tgz", + "integrity": "sha512-ET+E6A5MkQTEBNDYAnjh6+0cB33qStFXhtflkZNPEaOmvzYlB/xcPnpUk4J7ul3MVa8PCQx2Ei5g2MGY/y1n+g==", + "requires": { + "html-tokenize": "^2.0.0", + "multipipe": "^1.0.2", + "through": "^2.3.8" + } + }, + "create-emotion-styled": { + "version": "9.2.8", + "resolved": "https://registry.npmjs.org/create-emotion-styled/-/create-emotion-styled-9.2.8.tgz", + "integrity": "sha512-2LrNM5MREWzI5hZK+LyiBHglwE18WE3AEbBQgpHQ1+zmyLSm/dJsUZBeFAwuIMb+TjNZP0KsMZlV776ufOtFdg==", + "requires": { + "@emotion/is-prop-valid": "^0.6.1" + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "create-react-context": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.3.0.tgz", + "integrity": "sha512-dNldIoSuNSvlTJ7slIKC/ZFGKexBMBrrcc+TTe1NdmROnaASuLPvqpwj9v4XS4uXZ8+YPu0sNmShX2rXI5LNsw==", + "requires": { + "gud": "^1.0.0", + "warning": "^4.0.3" + }, + "dependencies": { + "warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "requires": { + "loose-envify": "^1.0.0" + } + } + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=" + }, + "css-to-react-native": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-2.3.2.tgz", + "integrity": "sha512-VOFaeZA053BqvvvqIA8c9n0+9vFppVBAHCp6JgFTtTMU3Mzi+XnelJ9XC9ul3BqFzZyQ5N+H0SnwsWT2Ebchxw==", + "requires": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^3.3.0" + } + }, + "css-vendor": { + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-0.3.8.tgz", + "integrity": "sha1-ZCHP0wNM5mT+dnOXL9ARn8KJQfo=", + "requires": { + "is-in-browser": "^1.0.2" + } + }, + "csstype": { + "version": "2.6.10", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.10.tgz", + "integrity": "sha512-D34BqZU4cIlMCY93rZHbrq9pjTAQJ3U8S8rfBqjwHxkGPThWFjzZDQpgMJY0QViLxth6ZKYiwFBo14RdN44U/w==" + }, + "cyclist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", + "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", + "dev": true + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "deep-equal": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", + "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", + "requires": { + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.1", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.2.0" + }, + "dependencies": { + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + } + } + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "requires": { + "object-keys": "^1.0.12" + }, + "dependencies": { + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + } + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "dom-helpers": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.1.4.tgz", + "integrity": "sha512-TjMyeVUvNEnOnhzs6uAn9Ya47GmMo3qq7m+Lr/3ON0Rs5kHvb8I+SQYjLUSYn7qhEm0QjW0yrBkvz9yOrwwz1A==", + "requires": { + "@babel/runtime": "^7.8.7", + "csstype": "^2.6.7" + } + }, + "domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true + }, + "duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "requires": { + "readable-stream": "^2.0.2" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "dev": true, + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "electron-to-chromium": { + "version": "1.3.468", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.468.tgz", + "integrity": "sha512-+KAppdklzPd5v8nLOvtDiD/S67mCT9gFRAvngYe8zuFy9azHhT9vWWH6WEPPCcyjQ1JMYVgqbN29yZ0paqxsEw==", + "dev": true + }, + "elliptic": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz", + "integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==", + "dev": true, + "requires": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, + "emotion": { + "version": "9.2.12", + "resolved": "https://registry.npmjs.org/emotion/-/emotion-9.2.12.tgz", + "integrity": "sha512-hcx7jppaI8VoXxIWEhxpDW7I+B4kq9RNzQLmsrF6LY8BGKqe2N+gFAQr0EfuFucFlPs2A9HM4+xNj4NeqEWIOQ==", + "requires": { + "babel-plugin-emotion": "^9.2.11", + "create-emotion": "^9.2.12" + } + }, + "emotion-server": { + "version": "9.2.12", + "resolved": "https://registry.npmjs.org/emotion-server/-/emotion-server-9.2.12.tgz", + "integrity": "sha512-Bhjdl7eNoIeiAVa2QPP5d+1nP/31SiO/K1P/qI9cdXCydg91NwGYmteqhhge8u7PF8fLGTEVQfcPwj21815eBw==", + "requires": { + "create-emotion-server": "^9.2.12" + } + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "enhanced-resolve": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", + "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.5.0", + "tapable": "^1.0.0" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "memory-fs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", + "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "errno": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", + "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "dev": true, + "requires": { + "prr": "~1.0.1" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", + "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + }, + "dependencies": { + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + } + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "events": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", + "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", + "dev": true + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "figgy-pudding": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", + "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", + "dev": true + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "findup-sync": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", + "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", + "dev": true, + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + } + }, + "flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "gensync": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", + "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "optional": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "requires": { + "global-prefix": "^3.0.0" + }, + "dependencies": { + "global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "requires": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + } + } + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "gud": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gud/-/gud-1.0.0.tgz", + "integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw==" + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==" + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + } + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "history": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", + "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "requires": { + "@babel/runtime": "^7.1.2", + "loose-envify": "^1.2.0", + "resolve-pathname": "^3.0.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0", + "value-equal": "^1.0.1" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "hoist-non-react-statics": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz", + "integrity": "sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw==" + }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "html-tokenize": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-tokenize/-/html-tokenize-2.0.1.tgz", + "integrity": "sha512-QY6S+hZ0f5m1WT8WffYN+Hg+xm/w5I8XeUcAq/ZYP5wVC8xbKi4Whhru3FtrAebD5EhBW8rmFzkDI6eCAuFe2w==", + "requires": { + "buffer-from": "~0.1.1", + "inherits": "~2.0.1", + "minimist": "~1.2.5", + "readable-stream": "~1.0.27-1", + "through2": "~0.4.1" + } + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "hyphenate-style-name": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.3.tgz", + "integrity": "sha512-EcuixamT82oplpoJ2XU4pDtKGWQ7b00CD9f1ug9IaQ3p1bkHMiKCZ9ut9QDI6qsa6cpUuB+A/I+zLtdNK4n2DQ==" + }, + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "dev": true + }, + "iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", + "dev": true + }, + "import-fresh": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", + "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "dev": true, + "requires": { + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-arguments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", + "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==" + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "optional": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-callable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==" + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-function": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.2.tgz", + "integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==" + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-in-browser": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-in-browser/-/is-in-browser-1.1.3.tgz", + "integrity": "sha1-Vv9NtoOgeMYILrldrX3GLh0E+DU=" + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "requires": { + "isobject": "^3.0.1" + } + }, + "is-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-what": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.8.0.tgz", + "integrity": "sha512-UKeBoQfV8bjlM4pmx1FLDHdxslW/1mTksEs8ReVsilPmUv5cORd4+2/wFcviI3cUjrLybxCjzc8DnodAzJ/Wrg==" + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jss": { + "version": "9.8.7", + "resolved": "https://registry.npmjs.org/jss/-/jss-9.8.7.tgz", + "integrity": "sha512-awj3XRZYxbrmmrx9LUSj5pXSUfm12m8xzi/VKeqI1ZwWBtQ0kVPTs3vYs32t4rFw83CgFDukA8wKzOE9sMQnoQ==", + "requires": { + "is-in-browser": "^1.1.3", + "symbol-observable": "^1.1.0", + "warning": "^3.0.0" + } + }, + "jss-camel-case": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jss-camel-case/-/jss-camel-case-6.1.0.tgz", + "integrity": "sha512-HPF2Q7wmNW1t79mCqSeU2vdd/vFFGpkazwvfHMOhPlMgXrJDzdj9viA2SaHk9ZbD5pfL63a8ylp4++irYbbzMQ==", + "requires": { + "hyphenate-style-name": "^1.0.2" + } + }, + "jss-compose": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/jss-compose/-/jss-compose-5.0.0.tgz", + "integrity": "sha512-YofRYuiA0+VbeOw0VjgkyO380sA4+TWDrW52nSluD9n+1FWOlDzNbgpZ/Sb3Y46+DcAbOS21W5jo6SAqUEiuwA==", + "requires": { + "warning": "^3.0.0" + } + }, + "jss-default-unit": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/jss-default-unit/-/jss-default-unit-8.0.2.tgz", + "integrity": "sha512-WxNHrF/18CdoAGw2H0FqOEvJdREXVXLazn7PQYU7V6/BWkCV0GkmWsppNiExdw8dP4TU1ma1dT9zBNJ95feLmg==" + }, + "jss-expand": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/jss-expand/-/jss-expand-5.3.0.tgz", + "integrity": "sha512-NiM4TbDVE0ykXSAw6dfFmB1LIqXP/jdd0ZMnlvlGgEMkMt+weJIl8Ynq1DsuBY9WwkNyzWktdqcEW2VN0RAtQg==" + }, + "jss-extend": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jss-extend/-/jss-extend-6.2.0.tgz", + "integrity": "sha512-YszrmcB6o9HOsKPszK7NeDBNNjVyiW864jfoiHoMlgMIg2qlxKw70axZHqgczXHDcoyi/0/ikP1XaHDPRvYtEA==", + "requires": { + "warning": "^3.0.0" + } + }, + "jss-global": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/jss-global/-/jss-global-3.0.0.tgz", + "integrity": "sha512-wxYn7vL+TImyQYGAfdplg7yaxnPQ9RaXY/cIA8hawaVnmmWxDHzBK32u1y+RAvWboa3lW83ya3nVZ/C+jyjZ5Q==" + }, + "jss-nested": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/jss-nested/-/jss-nested-6.0.1.tgz", + "integrity": "sha512-rn964TralHOZxoyEgeq3hXY8hyuCElnvQoVrQwKHVmu55VRDd6IqExAx9be5HgK0yN/+hQdgAXQl/GUrBbbSTA==", + "requires": { + "warning": "^3.0.0" + } + }, + "jss-preset-default": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/jss-preset-default/-/jss-preset-default-4.5.0.tgz", + "integrity": "sha512-qZbpRVtHT7hBPpZEBPFfafZKWmq3tA/An5RNqywDsZQGrlinIF/mGD9lmj6jGqu8GrED2SMHZ3pPKLmjCZoiaQ==", + "requires": { + "jss-camel-case": "^6.1.0", + "jss-compose": "^5.0.0", + "jss-default-unit": "^8.0.2", + "jss-expand": "^5.3.0", + "jss-extend": "^6.2.0", + "jss-global": "^3.0.0", + "jss-nested": "^6.0.1", + "jss-props-sort": "^6.0.0", + "jss-template": "^1.0.1", + "jss-vendor-prefixer": "^7.0.0" + } + }, + "jss-props-sort": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/jss-props-sort/-/jss-props-sort-6.0.0.tgz", + "integrity": "sha512-E89UDcrphmI0LzmvYk25Hp4aE5ZBsXqMWlkFXS0EtPkunJkRr+WXdCNYbXbksIPnKlBenGB9OxzQY+mVc70S+g==" + }, + "jss-template": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/jss-template/-/jss-template-1.0.1.tgz", + "integrity": "sha512-m5BqEWha17fmIVXm1z8xbJhY6GFJxNB9H68GVnCWPyGYfxiAgY9WTQyvDAVj+pYRgrXSOfN5V1T4+SzN1sJTeg==", + "requires": { + "warning": "^3.0.0" + } + }, + "jss-vendor-prefixer": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/jss-vendor-prefixer/-/jss-vendor-prefixer-7.0.0.tgz", + "integrity": "sha512-Agd+FKmvsI0HLcYXkvy8GYOw3AAASBUpsmIRvVQheps+JWaN892uFOInTr0DRydwaD91vSSUCU4NssschvF7MA==", + "requires": { + "css-vendor": "^0.3.8" + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true + }, + "levenary": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/levenary/-/levenary-1.1.1.tgz", + "integrity": "sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ==", + "dev": true, + "requires": { + "leven": "^3.1.0" + } + }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" + }, + "loader-runner": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", + "dev": true + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + } + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "memoize-one": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.1.1.tgz", + "integrity": "sha512-HKeeBpWvqiVJD57ZUAsJNm71eHTykffzcLZVYWiVfQeI1rJtuEaS7hQiEpWfVVk18donPwJEcFKIkCmPJNOhHA==" + }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "merge-anything": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/merge-anything/-/merge-anything-2.4.4.tgz", + "integrity": "sha512-l5XlriUDJKQT12bH+rVhAHjwIuXWdAIecGwsYjv2LJo+dA1AeRTmeQS+3QBpO6lEthBMDi2IUMpLC1yyRvGlwQ==", + "requires": { + "is-what": "^3.3.1" + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "mini-create-react-context": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.0.tgz", + "integrity": "sha512-b0TytUgFSbgFJGzJqXPKCFCBWigAjpjo+Fl7Vf7ZbKRDptszpppKxXH6DRXEABZ/gcEQczeb0iZ7JvL8e8jjCA==", + "requires": { + "@babel/runtime": "^7.5.5", + "tiny-warning": "^1.0.3" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "mississippi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "dev": true, + "requires": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^3.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + } + } + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + }, + "move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "dev": true, + "requires": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + }, + "dependencies": { + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "multipipe": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-1.0.2.tgz", + "integrity": "sha1-zBPv2DPJzamfIk+GhGG44aP9k50=", + "requires": { + "duplexer2": "^0.1.2", + "object-assign": "^4.1.0" + } + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "neo-async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", + "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "dev": true, + "requires": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "^1.0.1" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + } + } + } + } + }, + "node-releases": { + "version": "1.1.58", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.58.tgz", + "integrity": "sha512-NxBudgVKiRh/2aPWMgPR7bPTX0VPmGx5QBwCtdHitnqFE5/O8DeBXuIMH1nwNnw/aMo6AjOrpsHzfY3UbUJ7yg==", + "dev": true + }, + "nopt": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", + "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=", + "requires": { + "abbrev": "1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==" + }, + "object-is": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.2.tgz", + "integrity": "sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "object-keys": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", + "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=" + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + }, + "dependencies": { + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + } + } + }, + "object.entries": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.2.tgz", + "integrity": "sha512-BQdB9qKmb/HyNdMNWVr7O3+z5MUIx3aiegEIJqjMBbBf0YT9RRxTJSim4mzFqtyr7PDAHigq0N9dO0m0tRakQA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5", + "has": "^1.0.3" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + }, + "parallel-transform": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", + "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", + "dev": true, + "requires": { + "cyclist": "^1.0.1", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-asn1": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", + "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", + "dev": true, + "requires": { + "asn1.js": "^4.0.0", + "browserify-aes": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "parse-json": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" + } + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true, + "optional": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" + }, + "path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "requires": { + "isarray": "0.0.1" + } + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" + }, + "pbkdf2": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz", + "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true, + "optional": true + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + } + } + }, + "pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", + "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + }, + "popper.js": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz", + "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==" + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==" + }, + "private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", + "dev": true + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, + "promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", + "dev": true + }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "react": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react/-/react-16.13.1.tgz", + "integrity": "sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2" + } + }, + "react-dom": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.13.1.tgz", + "integrity": "sha512-81PIMmVLnCNLO/fFOQxdQkvEq/+Hfpv24XNJfpyZhTRfO0QcmQIF/PgCa1zCOj2w1hrn12MFLyaJ/G0+Mxtfag==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.19.1" + } + }, + "react-emotion": { + "version": "9.2.12", + "resolved": "https://registry.npmjs.org/react-emotion/-/react-emotion-9.2.12.tgz", + "integrity": "sha512-qt7XbxnEKX5sZ73rERJ92JMbEOoyOwG3BuCRFRkXrsJhEe+rFBRTljRw7yOLHZUCQC4GBObZhjXIduQ8S0ZpYw==", + "requires": { + "babel-plugin-emotion": "^9.2.11", + "create-emotion-styled": "^9.2.8" + } + }, + "react-fast-compare": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", + "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==" + }, + "react-helmet": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/react-helmet/-/react-helmet-6.1.0.tgz", + "integrity": "sha512-4uMzEY9nlDlgxr61NL3XbKRy1hEkXmKNXhjbAIOVw5vcFrsdYbH2FEwcNyWvWinl103nXgzYNlns9ca+8kFiWw==", + "requires": { + "object-assign": "^4.1.1", + "prop-types": "^15.7.2", + "react-fast-compare": "^3.1.1", + "react-side-effect": "^2.1.0" + } + }, + "react-input-autosize": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/react-input-autosize/-/react-input-autosize-2.2.2.tgz", + "integrity": "sha512-jQJgYCA3S0j+cuOwzuCd1OjmBmnZLdqQdiLKRYrsMMzbjUrVDS5RvJUDwJqA7sKuksDuzFtm6hZGKFu7Mjk5aw==", + "requires": { + "prop-types": "^15.5.8" + } + }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "react-jss": { + "version": "8.6.1", + "resolved": "https://registry.npmjs.org/react-jss/-/react-jss-8.6.1.tgz", + "integrity": "sha512-SH6XrJDJkAphp602J14JTy3puB2Zxz1FkM3bKVE8wON+va99jnUTKWnzGECb3NfIn9JPR5vHykge7K3/A747xQ==", + "requires": { + "hoist-non-react-statics": "^2.5.0", + "jss": "^9.7.0", + "jss-preset-default": "^4.3.0", + "prop-types": "^15.6.0", + "theming": "^1.3.0" + } + }, + "react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" + }, + "react-popper": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-1.3.7.tgz", + "integrity": "sha512-nmqYTx7QVjCm3WUZLeuOomna138R1luC4EqkW3hxJUrAe+3eNz3oFCLYdnPwILfn0mX1Ew2c3wctrjlUMYYUww==", + "requires": { + "@babel/runtime": "^7.1.2", + "create-react-context": "^0.3.0", + "deep-equal": "^1.1.1", + "popper.js": "^1.14.4", + "prop-types": "^15.6.1", + "typed-styles": "^0.0.7", + "warning": "^4.0.2" + }, + "dependencies": { + "warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "requires": { + "loose-envify": "^1.0.0" + } + } + } + }, + "react-router": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz", + "integrity": "sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==", + "requires": { + "@babel/runtime": "^7.1.2", + "history": "^4.9.0", + "hoist-non-react-statics": "^3.1.0", + "loose-envify": "^1.3.1", + "mini-create-react-context": "^0.4.0", + "path-to-regexp": "^1.7.0", + "prop-types": "^15.6.2", + "react-is": "^16.6.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "dependencies": { + "hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "requires": { + "react-is": "^16.7.0" + } + } + } + }, + "react-router-dom": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.2.0.tgz", + "integrity": "sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==", + "requires": { + "@babel/runtime": "^7.1.2", + "history": "^4.9.0", + "loose-envify": "^1.3.1", + "prop-types": "^15.6.2", + "react-router": "5.2.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + } + }, + "react-select": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/react-select/-/react-select-3.1.0.tgz", + "integrity": "sha512-wBFVblBH1iuCBprtpyGtd1dGMadsG36W5/t2Aj8OE6WbByDg5jIFyT7X5gT+l0qmT5TqWhxX+VsKJvCEl2uL9g==", + "requires": { + "@babel/runtime": "^7.4.4", + "@emotion/cache": "^10.0.9", + "@emotion/core": "^10.0.9", + "@emotion/css": "^10.0.9", + "memoize-one": "^5.0.0", + "prop-types": "^15.6.0", + "react-input-autosize": "^2.2.2", + "react-transition-group": "^4.3.0" + } + }, + "react-side-effect": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/react-side-effect/-/react-side-effect-2.1.0.tgz", + "integrity": "sha512-IgmcegOSi5SNX+2Snh1vqmF0Vg/CbkycU9XZbOHJlZ6kMzTmi3yc254oB1WCkgA7OQtIAoLmcSFuHTc/tlcqXg==" + }, + "react-transition-group": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.1.tgz", + "integrity": "sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw==", + "requires": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + } + }, + "reactstrap": { + "version": "8.4.1", + "resolved": "https://registry.npmjs.org/reactstrap/-/reactstrap-8.4.1.tgz", + "integrity": "sha512-oAjp9PYYUGKl7SLXwrQ1oRIrYw0MqfO2mUqYgGapFKHG2uwjEtLip5rYxtMujkGx3COjH5FX1WtcfNU4oqpH0Q==", + "requires": { + "@babel/runtime": "^7.2.0", + "classnames": "^2.2.3", + "prop-types": "^15.5.8", + "react-lifecycles-compat": "^3.0.4", + "react-popper": "^1.3.6", + "react-transition-group": "^2.3.1" + }, + "dependencies": { + "dom-helpers": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz", + "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==", + "requires": { + "@babel/runtime": "^7.1.2" + } + }, + "react-transition-group": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz", + "integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==", + "requires": { + "dom-helpers": "^3.4.0", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2", + "react-lifecycles-compat": "^3.0.4" + } + } + } + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "readdirp": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", + "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", + "dev": true, + "optional": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "regenerate": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.1.tgz", + "integrity": "sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A==", + "dev": true + }, + "regenerate-unicode-properties": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz", + "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==", + "dev": true, + "requires": { + "regenerate": "^1.4.0" + } + }, + "regenerator-runtime": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==" + }, + "regenerator-transform": { + "version": "0.14.4", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.4.tgz", + "integrity": "sha512-EaJaKPBI9GvKpvUz2mz4fhx7WPgvwRLY9v3hlNHWmAuJHI13T4nwKnNvm5RWJzEdnI5g5UwtOww+S8IdoUC2bw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.8.4", + "private": "^0.1.8" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "regexp.prototype.flags": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", + "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, + "regexpu-core": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.0.tgz", + "integrity": "sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ==", + "dev": true, + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.2.0", + "regjsgen": "^0.5.1", + "regjsparser": "^0.6.4", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.2.0" + } + }, + "regjsgen": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", + "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", + "dev": true + }, + "regjsparser": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.4.tgz", + "integrity": "sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw==", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + } + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true, + "optional": true + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "dev": true, + "requires": { + "resolve-from": "^3.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + } + } + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "dependencies": { + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + } + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" + }, + "resolve-pathname": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", + "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "dev": true, + "requires": { + "aproba": "^1.1.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "scheduler": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", + "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "serialize-javascript": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz", + "integrity": "sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "ssri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1" + } + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "stream-each": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", + "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + }, + "dependencies": { + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + } + } + }, + "stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "string.prototype.trimend": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", + "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "string.prototype.trimleft": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz", + "integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5", + "string.prototype.trimstart": "^1.0.0" + } + }, + "string.prototype.trimright": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz", + "integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5", + "string.prototype.trimend": "^1.0.0" + } + }, + "string.prototype.trimstart": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", + "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "styled-components": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-4.4.1.tgz", + "integrity": "sha512-RNqj14kYzw++6Sr38n7197xG33ipEOktGElty4I70IKzQF1jzaD1U4xQ+Ny/i03UUhHlC5NWEO+d8olRCDji6g==", + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@emotion/is-prop-valid": "^0.8.1", + "@emotion/unitless": "^0.7.0", + "babel-plugin-styled-components": ">= 1", + "css-to-react-native": "^2.2.2", + "memoize-one": "^5.0.0", + "merge-anything": "^2.2.4", + "prop-types": "^15.5.4", + "react-is": "^16.6.0", + "stylis": "^3.5.0", + "stylis-rule-sheet": "^0.0.10", + "supports-color": "^5.5.0" + }, + "dependencies": { + "@emotion/is-prop-valid": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", + "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", + "requires": { + "@emotion/memoize": "0.7.4" + } + }, + "@emotion/memoize": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", + "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==" + }, + "@emotion/unitless": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" + } + } + }, + "stylis": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-3.5.4.tgz", + "integrity": "sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q==" + }, + "stylis-rule-sheet": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz", + "integrity": "sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + }, + "symbol-observable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz", + "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==" + }, + "tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "dev": true + }, + "terser": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.7.0.tgz", + "integrity": "sha512-Lfb0RiZcjRDXCC3OSHJpEkxJ9Qeqs6mp2v4jf2MHfy8vGERmVDuvjXdd/EnP5Deme5F2yBRBymKmKHCBg2echw==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "terser-webpack-plugin": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.4.tgz", + "integrity": "sha512-U4mACBHIegmfoEe5fdongHESNJWqsGU+W0S/9+BmYGVQDw1+c2Ow05TpMhxjPK1sRb7cuYq1BPl1e5YHJMTCqA==", + "dev": true, + "requires": { + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", + "is-wsl": "^1.1.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^3.1.0", + "source-map": "^0.6.1", + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", + "worker-farm": "^1.7.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "theming": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/theming/-/theming-1.3.0.tgz", + "integrity": "sha512-ya5Ef7XDGbTPBv5ENTwrwkPUexrlPeiAg/EI9kdlUAZhNlRbCdhMKRgjNX1IcmsmiPcqDQZE6BpSaH+cr31FKw==", + "requires": { + "brcast": "^3.0.1", + "is-function": "^1.0.1", + "is-plain-object": "^2.0.1", + "prop-types": "^15.5.8" + } + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "through2": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.4.2.tgz", + "integrity": "sha1-2/WGYDEVHsg1K7bE22SiKSqEC5s=", + "requires": { + "readable-stream": "~1.0.17", + "xtend": "~2.1.1" + } + }, + "timers-browserify": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", + "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", + "dev": true, + "requires": { + "setimmediate": "^1.0.4" + } + }, + "tiny-invariant": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz", + "integrity": "sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw==" + }, + "tiny-warning": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "touch": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/touch/-/touch-2.0.2.tgz", + "integrity": "sha512-qjNtvsFXTRq7IuMLweVgFxmEuQ6gLbRs2jQxL80TtZ31dEKWYIxRXquij6w6VimyDek5hD3PytljHmEtAs2u0A==", + "requires": { + "nopt": "~1.0.10" + } + }, + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "dev": true + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, + "typed-styles": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/typed-styles/-/typed-styles-0.0.7.tgz", + "integrity": "sha512-pzP0PWoZUhsECYjABgCGQlRGL1n7tOHsgwYv3oIiEpJwGhFTuty/YNeduxQYzXXa3Ge5BdT6sHYIQYpl4uJ+5Q==" + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "unicode-canonical-property-names-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", + "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", + "dev": true + }, + "unicode-match-property-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", + "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", + "dev": true, + "requires": { + "unicode-canonical-property-names-ecmascript": "^1.0.4", + "unicode-property-aliases-ecmascript": "^1.0.4" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz", + "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==", + "dev": true + }, + "unicode-property-aliases-ecmascript": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz", + "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==", + "dev": true + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dev": true, + "requires": { + "unique-slug": "^2.0.0" + } + }, + "unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + } + } + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true, + "optional": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "dev": true, + "requires": { + "inherits": "2.0.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "v8-compile-cache": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz", + "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==", + "dev": true + }, + "value-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", + "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" + }, + "vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true + }, + "warning": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz", + "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=", + "requires": { + "loose-envify": "^1.0.0" + } + }, + "watchpack": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.2.tgz", + "integrity": "sha512-ymVbbQP40MFTp+cNMvpyBpBtygHnPzPkHqoIwRRj/0B8KhqQwV8LaKjtbaxF2lK4vl8zN9wCxS46IFCU5K4W0g==", + "dev": true, + "requires": { + "chokidar": "^3.4.0", + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0", + "watchpack-chokidar2": "^2.0.0" + } + }, + "watchpack-chokidar2": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz", + "integrity": "sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA==", + "dev": true, + "optional": true, + "requires": { + "chokidar": "^2.1.8" + }, + "dependencies": { + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "optional": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "optional": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true, + "optional": true + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "dev": true, + "optional": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "dev": true, + "optional": true + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "optional": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "optional": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "optional": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true, + "optional": true + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "optional": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, + "webpack": { + "version": "4.43.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.43.0.tgz", + "integrity": "sha512-GW1LjnPipFW2Y78OOab8NJlCflB7EFskMih2AHdvjbpKMeDJqEgSx24cXXXiPS65+WSwVyxtDsJH6jGX2czy+g==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/wasm-edit": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "acorn": "^6.4.1", + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^4.1.0", + "eslint-scope": "^4.0.3", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^2.4.0", + "loader-utils": "^1.2.3", + "memory-fs": "^0.4.1", + "micromatch": "^3.1.10", + "mkdirp": "^0.5.3", + "neo-async": "^2.6.1", + "node-libs-browser": "^2.2.1", + "schema-utils": "^1.0.0", + "tapable": "^1.1.3", + "terser-webpack-plugin": "^1.4.3", + "watchpack": "^1.6.1", + "webpack-sources": "^1.4.1" + } + }, + "webpack-cli": { + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.12.tgz", + "integrity": "sha512-NVWBaz9k839ZH/sinurM+HcDvJOTXwSjYp1ku+5XKeOC03z8v5QitnK/x+lAxGXFyhdayoIf/GOpv85z3/xPag==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "cross-spawn": "^6.0.5", + "enhanced-resolve": "^4.1.1", + "findup-sync": "^3.0.0", + "global-modules": "^2.0.0", + "import-local": "^2.0.0", + "interpret": "^1.4.0", + "loader-utils": "^1.4.0", + "supports-color": "^6.1.0", + "v8-compile-cache": "^2.1.1", + "yargs": "^13.3.2" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "webpack-manifest-plugin": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/webpack-manifest-plugin/-/webpack-manifest-plugin-2.2.0.tgz", + "integrity": "sha512-9S6YyKKKh/Oz/eryM1RyLVDVmy3NSPV0JXMRhZ18fJsq+AwGxUY34X54VNwkzYcEmEkDwNxuEOboCZEebJXBAQ==", + "dev": true, + "requires": { + "fs-extra": "^7.0.0", + "lodash": ">=3.5 <5", + "object.entries": "^1.1.0", + "tapable": "^1.0.0" + } + }, + "webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dev": true, + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "worker-farm": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", + "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", + "dev": true, + "requires": { + "errno": "~0.1.7" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "xtend": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", + "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", + "requires": { + "object-keys": "~0.4.0" + } + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + }, + "yaml": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz", + "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==" + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + } + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } +} diff --git a/src/React.Template/reactnet-webpack/package.json b/src/React.Template/reactnet-webpack/package.json new file mode 100644 index 000000000..373958c21 --- /dev/null +++ b/src/React.Template/reactnet-webpack/package.json @@ -0,0 +1,36 @@ +{ + "name": "React.Sample.Webpack.CoreMvc", + "version": "1.0.0", + "main": "index.js", + "license": "MIT", + "scripts": { + "build": "rimraf wwwroot/dist && webpack" + }, + "dependencies": { + "emotion": "^9.2.12", + "emotion-server": "^9.2.12", + "react": "^16.8.2", + "react-dom": "^16.8.2", + "react-emotion": "^9.2.12", + "react-helmet": "^6.0.0", + "react-jss": "^8.6.1", + "react-router-dom": "^5.0.0", + "react-select": "^3.0.4", + "reactstrap": "^8.0.0", + "styled-components": "^4.0.0" + }, + "devDependencies": { + "@babel/core": "7.8.7", + "@babel/plugin-proposal-class-properties": "7.8.3", + "@babel/plugin-proposal-object-rest-spread": "7.8.3", + "@babel/plugin-syntax-dynamic-import": "7.8.3", + "@babel/preset-env": "7.8.7", + "@babel/preset-react": "7.8.3", + "babel-loader": "8.0.6", + "babel-runtime": "6.26.0", + "rimraf": "3.0.2", + "webpack": "4.43.0", + "webpack-cli": "3.3.12", + "webpack-manifest-plugin": "2.2.0" + } +} diff --git a/src/React.Template/reactnet-webpack/webpack.config.js b/src/React.Template/reactnet-webpack/webpack.config.js new file mode 100644 index 000000000..fa3b0108f --- /dev/null +++ b/src/React.Template/reactnet-webpack/webpack.config.js @@ -0,0 +1,54 @@ +const path = require('path'); +const ManifestPlugin = require('webpack-manifest-plugin'); + +module.exports = { + entry: './Content/components/expose-components.js', + output: { + filename: '[name].[contenthash:8].js', + globalObject: 'this', + path: path.resolve(__dirname, 'wwwroot/dist'), + publicPath: '/dist/' + }, + mode: process.env.NODE_ENV === 'production' ? 'production' : 'development', + optimization: { + runtimeChunk: { + name: 'runtime', // necessary when using multiple entrypoints on the same page + }, + splitChunks: { + cacheGroups: { + commons: { + test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/, + name: 'vendor', + chunks: 'all', + }, + }, + }, + }, + module: { + rules: [ + { + test: /\.jsx?$/, + exclude: /node_modules/, + loader: 'babel-loader', + }, + ], + }, + plugins: [ + new ManifestPlugin({ + fileName: 'asset-manifest.json', + generate: (seed, files) => { + const manifestFiles = files.reduce((manifest, file) => { + manifest[file.name] = file.path; + return manifest; + }, seed); + + const entrypointFiles = files.filter(x => x.isInitial && !x.name.endsWith('.map')).map(x => x.path); + + return { + files: manifestFiles, + entrypoints: entrypointFiles, + }; + }, + }), + ] +}; diff --git a/src/React.Template/reactnet-webpack/wwwroot/Sample.css b/src/React.Template/reactnet-webpack/wwwroot/Sample.css new file mode 100644 index 000000000..b02c980ca --- /dev/null +++ b/src/React.Template/reactnet-webpack/wwwroot/Sample.css @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2014-Present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +body { + font-family: Calibri, Verdana, sans-serif; +} + +.commentList { + list-style-type: none; + margin: 0; + padding: 0; +} + +.commentList li { + border-bottom: 1px solid #999; + padding: 0.5em 0; +} diff --git a/src/React.Tests/Core/FileCacheHashTests.cs b/src/React.Tests/Core/FileCacheHashTests.cs deleted file mode 100644 index b8fd5716e..000000000 --- a/src/React.Tests/Core/FileCacheHashTests.cs +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -using NUnit.Framework; - -namespace React.Tests.Core -{ - [TestFixture] - public class FileCacheHashTests - { - private const string SAMPLE_HASH = "B10A8DB164E0754105B7A99BE72E3FE5"; - - [Test] - public void TestCalculateHash() - { - var hash = new FileCacheHash(); - Assert.AreEqual(SAMPLE_HASH, hash.CalculateHash("Hello World")); - } - - [Test] - public void ValidateHashShouldReturnFalseForEmptyString() - { - var hash = new FileCacheHash(); - Assert.IsFalse(hash.ValidateHash(string.Empty, SAMPLE_HASH)); - } - - [Test] - public void ValidateHashShouldReturnFalseForNull() - { - var hash = new FileCacheHash(); - Assert.IsFalse(hash.ValidateHash(null, SAMPLE_HASH)); - } - - [Test] - public void ValidateHashShouldReturnFalseWhenNoHashPrefix() - { - var hash = new FileCacheHash(); - Assert.IsFalse(hash.ValidateHash("Hello World", SAMPLE_HASH)); - } - - [Test] - public void ValidateHashShouldReturnFalseWhenHashDoesNotMatch() - { - var hash = new FileCacheHash(); - Assert.IsFalse(hash.ValidateHash("// @hash NOTCORRECT\nHello World", SAMPLE_HASH)); - } - - [Test] - public void ValidateHashShouldReturnTrueWhenHashMatches() - { - var hash = new FileCacheHash(); - Assert.IsTrue(hash.ValidateHash("// @hash " + SAMPLE_HASH + "\nHello World", SAMPLE_HASH)); - } - } -} diff --git a/src/React.Tests/Core/JavaScriptEngineFactoryTest.cs b/src/React.Tests/Core/JavaScriptEngineFactoryTest.cs deleted file mode 100644 index f60327de0..000000000 --- a/src/React.Tests/Core/JavaScriptEngineFactoryTest.cs +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -using System.Threading; -using JavaScriptEngineSwitcher.Core; -using Moq; -using NUnit.Framework; - -namespace React.Tests.Core -{ - [TestFixture] - public class JavaScriptEngineFactoryTest - { - private JavaScriptEngineFactory CreateFactory() - { - var registration = new JavaScriptEngineFactory.Registration - { - Factory = () => - { - var mockJsEngine = new Mock(); - mockJsEngine.Setup(x => x.Evaluate("1 + 1")).Returns(2); - return mockJsEngine.Object; - }, - Priority = 1 - }; - return new JavaScriptEngineFactory(new[] { registration }); - } - - [Test] - public void ShouldCallOnNewEngineWhenCreatingNew() - { - var factory = CreateFactory(); - var called = false; - factory.GetEngineForCurrentThread(engine => - { - Assert.NotNull(engine); - called = true; - }); - factory.DisposeEngineForCurrentThread(); - - Assert.True(called); - } - - [Test] - public void ShouldNotCallOnNewEngineWhenUsingExisting() - { - var factory = CreateFactory(); - var called = false; - factory.GetEngineForCurrentThread(); - factory.GetEngineForCurrentThread(engine => { called = true; }); - factory.DisposeEngineForCurrentThread(); - - Assert.False(called); - } - - [Test] - public void ShouldReturnSameEngine() - { - var factory = CreateFactory(); - var engine1 = factory.GetEngineForCurrentThread(); - var engine2 = factory.GetEngineForCurrentThread(); - - Assert.AreEqual(engine1, engine2); - factory.DisposeEngineForCurrentThread(); - } - - [Test] - public void ShouldReturnNewEngineAfterDisposing() - { - var factory = CreateFactory(); - var engine1 = factory.GetEngineForCurrentThread(); - factory.DisposeEngineForCurrentThread(); - var engine2 = factory.GetEngineForCurrentThread(); - factory.DisposeEngineForCurrentThread(); - - Assert.AreNotEqual(engine1, engine2); - } - - [Test] - public void ShouldCreateNewEngineForNewThread() - { - var factory = CreateFactory(); - var engine1 = factory.GetEngineForCurrentThread(); - - IJsEngine engine2 = null; - var thread = new Thread(() => - { - engine2 = factory.GetEngineForCurrentThread(); - // Need to ensure engine is disposed in same thread as it was created in - factory.DisposeEngineForCurrentThread(); - }); - thread.Start(); - thread.Join(); - - var engine3 = factory.GetEngineForCurrentThread(); - - // Different threads should have different engines - Assert.AreNotEqual(engine1, engine2); - // Same thread should share same engine - Assert.AreEqual(engine1, engine3); - factory.DisposeEngineForCurrentThread(); - } - } -} diff --git a/src/React.Tests/Core/JsxTransformerTests.cs b/src/React.Tests/Core/JsxTransformerTests.cs deleted file mode 100644 index ba25d9142..000000000 --- a/src/React.Tests/Core/JsxTransformerTests.cs +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -using System; -using System.Collections.Generic; -using Moq; -using NUnit.Framework; -using React.Exceptions; - -namespace React.Tests.Core -{ - [TestFixture] - public class JsxTransformerTests - { - private Mock _environment; - private Mock _cache; - private Mock _fileSystem; - private Mock _fileCacheHash; - private JsxTransformer _jsxTransformer; - - [SetUp] - public void SetUp() - { - _environment = new Mock(); - _environment.Setup(x => x.EngineSupportsJsxTransformer).Returns(true); - - _cache = new Mock(); - _fileSystem = new Mock(); - _fileSystem.Setup(x => x.MapPath(It.IsAny())).Returns(x => x); - - _fileCacheHash = new Mock(); - - _jsxTransformer = new JsxTransformer( - _environment.Object, - _cache.Object, - _fileSystem.Object, - _fileCacheHash.Object, - ReactSiteConfiguration.Configuration - ); - } - - [Test] - public void ShouldNotTransformJsxIfNoAnnotationPresent() - { - const string input = "
    Hello World
    "; - - var output = _jsxTransformer.TransformJsx(input); - Assert.AreEqual(input, output); - } - - [Test] - public void ShouldTransformJsxIfAnnotationPresent() - { - const string input = "/** @jsx React.DOM */
    Hello World
    "; - _jsxTransformer.TransformJsx(input); - - _environment.Verify(x => x.ExecuteWithLargerStackIfRequired( - "ReactNET_transform", - "/** @jsx React.DOM */
    Hello World
    ", - false - )); - } - - [Test] - public void ShouldWrapExceptionsInJsxExeption() - { - _environment.Setup(x => x.ExecuteWithLargerStackIfRequired( - "ReactNET_transform", - "/** @jsx React.DOM */
    Hello World
    ", - false - )).Throws(new Exception("Something broke...")); - - const string input = "/** @jsx React.DOM */
    Hello World
    "; - Assert.Throws(() => _jsxTransformer.TransformJsx(input)); - } - - [Test] - public void ShouldThrowIfEngineNotSupported() - { - _environment.Setup(x => x.EngineSupportsJsxTransformer).Returns(false); - - Assert.Throws(() => - { - _jsxTransformer.TransformJsx("/** @jsx React.DOM */
    Hello world
    "); - }); - } - - [Test] - public void ShouldUseCacheProvider() - { - _cache.Setup(x => x.GetOrInsert( - /*key*/ "JSX_foo.jsx", - /*slidingExpiration*/ It.IsAny(), - /*getData*/ It.IsAny>(), - /*cacheDependencyKeys*/ It.IsAny>(), - /*cacheDependencyFiles*/ It.IsAny>() - )).Returns("/* cached */"); - - var result = _jsxTransformer.TransformJsxFile("foo.jsx"); - Assert.AreEqual("/* cached */", result); - } - - [Test] - public void ShouldUseFileSystemCacheIfHashValid() - { - SetUpEmptyCache(); - _fileSystem.Setup(x => x.FileExists("foo.generated.js")).Returns(true); - _fileSystem.Setup(x => x.ReadAsString("foo.generated.js")).Returns("/* filesystem cached */"); - _fileCacheHash.Setup(x => x.ValidateHash(It.IsAny(), It.IsAny())).Returns(true); - - var result = _jsxTransformer.TransformJsxFile("foo.jsx"); - Assert.AreEqual("/* filesystem cached */", result); - } - - [Test] - public void ShouldTransformJsxIfFileCacheHashInvalid() - { - SetUpEmptyCache(); - _fileSystem.Setup(x => x.FileExists("foo.generated.js")).Returns(true); - _fileSystem.Setup(x => x.ReadAsString("foo.generated.js")).Returns("/* filesystem cached invalid */"); - _fileSystem.Setup(x => x.ReadAsString("foo.jsx")).Returns("/** @jsx React.DOM */
    Hello World
    "); - _fileCacheHash.Setup(x => x.ValidateHash(It.IsAny(), It.IsAny())).Returns(false); - - _jsxTransformer.TransformJsxFile("foo.jsx"); - _environment.Verify(x => x.ExecuteWithLargerStackIfRequired( - "ReactNET_transform", - "/** @jsx React.DOM */
    Hello World
    ", - false - )); - } - - [Test] - public void ShouldTransformJsxIfNoCache() - { - SetUpEmptyCache(); - _fileSystem.Setup(x => x.FileExists("foo.generated.js")).Returns(false); - _fileSystem.Setup(x => x.ReadAsString("foo.jsx")).Returns("/** @jsx React.DOM */
    Hello World
    "); - - _jsxTransformer.TransformJsxFile("foo.jsx"); - _environment.Verify(x => x.ExecuteWithLargerStackIfRequired( - "ReactNET_transform", - "/** @jsx React.DOM */
    Hello World
    ", - false - )); - } - - [Test] - public void ShouldSaveTransformationResult() - { - _fileSystem.Setup(x => x.ReadAsString("foo.jsx")).Returns("/** @jsx React.DOM */
    Hello World
    "); - _environment.Setup(x => x.ExecuteWithLargerStackIfRequired( - "ReactNET_transform", - "/** @jsx React.DOM */
    Hello World
    ", - false - )).Returns("React.DOM.div('Hello World')"); - - string result = null; - _fileSystem.Setup(x => x.WriteAsString("foo.generated.js", It.IsAny())).Callback( - (string filename, string contents) => result = contents - ); - - var resultFilename = _jsxTransformer.TransformAndSaveJsxFile("foo.jsx"); - Assert.AreEqual("foo.generated.js", resultFilename); - StringAssert.EndsWith("React.DOM.div('Hello World')", result); - } - - private void SetUpEmptyCache() - { - _cache.Setup(x => x.GetOrInsert( - /*key*/ "JSX_foo.jsx", - /*slidingExpiration*/ It.IsAny(), - /*getData*/ It.IsAny>(), - /*cacheDependencyKeys*/ It.IsAny>(), - /*cacheDependencyFiles*/ It.IsAny>() - )) - .Returns(( - string key, - TimeSpan slidingExpiration, - Func getData, - IEnumerable cacheDependencyFiles, - IEnumerable cacheDependencyKeys - ) => getData()); - } - } -} diff --git a/src/React.Tests/Core/ReactComponentTest.cs b/src/React.Tests/Core/ReactComponentTest.cs deleted file mode 100644 index 72d48130f..000000000 --- a/src/React.Tests/Core/ReactComponentTest.cs +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -using Moq; -using NUnit.Framework; -using React.Exceptions; - -namespace React.Tests.Core -{ - [TestFixture] - public class ReactComponentTest - { - [Test] - public void RenderHtmlShouldThrowExceptionIfComponentDoesNotExist() - { - var environment = new Mock(); - environment.Setup(x => x.HasVariable("Foo")).Returns(false); - var component = new ReactComponent(environment.Object, "Foo", "container"); - - Assert.Throws(() => - { - component.RenderHtml(); - }); - } - - [Test] - public void RenderHtmlShouldCallRenderComponent() - { - var environment = new Mock(); - environment.Setup(x => x.HasVariable("Foo")).Returns(true); - - var component = new ReactComponent(environment.Object, "Foo", "container") - { - Props = new { hello = "World" } - }; - component.RenderHtml(); - - environment.Verify(x => x.Execute(@"React.renderComponentToString(Foo({""hello"":""World""}))")); - } - - [Test] - public void RenderHtmlShouldWrapComponentInDiv() - { - var environment = new Mock(); - environment.Setup(x => x.HasVariable("Foo")).Returns(true); - environment.Setup(x => x.Execute(@"React.renderComponentToString(Foo({""hello"":""World""}))")) - .Returns("[HTML]"); - - var component = new ReactComponent(environment.Object, "Foo", "container") - { - Props = new { hello = "World" } - }; - var result = component.RenderHtml(); - - Assert.AreEqual(@"
    [HTML]
    ", result); - } - - [Test] - public void RenderJavaScriptShouldCallRenderComponent() - { - var environment = new Mock(); - - var component = new ReactComponent(environment.Object, "Foo", "container") - { - Props = new { hello = "World" } - }; - var result = component.RenderJavaScript(); - - Assert.AreEqual( - @"React.renderComponent(Foo({""hello"":""World""}), document.getElementById(""container""))", - result - ); - } - } -} diff --git a/src/React.Tests/Core/ReactEnvironmentTest.cs b/src/React.Tests/Core/ReactEnvironmentTest.cs deleted file mode 100644 index 361594199..000000000 --- a/src/React.Tests/Core/ReactEnvironmentTest.cs +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -using System; -using JavaScriptEngineSwitcher.Core; -using Moq; -using NUnit.Framework; - -namespace React.Tests.Core -{ - [TestFixture] - public class ReactEnvironmentTest - { - [Test] - public void ExecuteWithLargerStackIfRequiredWithNoNewThread() - { - var mocks = new Mocks(); - var environment = mocks.CreateReactEnvironment(); - - environment.ExecuteWithLargerStackIfRequired("foo"); - mocks.Engine.Verify(x => x.CallFunction("foo"), Times.Exactly(1)); - } - - [Test] - public void ExecuteWithLargerStackIfRequiredWithNewThread() - { - var mocks = new Mocks(); - var environment = mocks.CreateReactEnvironment(); - // Fail the first time Evaluate is called, succeed the second - // http://stackoverflow.com/a/7045636 - mocks.Engine.Setup(x => x.CallFunction("foo")) - .Callback(() => mocks.Engine.Setup(x => x.CallFunction("foo"))) - .Throws(new Exception("Out of stack space")); - - environment.ExecuteWithLargerStackIfRequired("foo"); - mocks.EngineFactory.Verify( - x => x.GetEngineForCurrentThread(It.IsAny>()), - Times.Exactly(2), - "Two engines should be created (initial thread and new thread)" - ); - mocks.EngineFactory.Verify( - x => x.DisposeEngineForCurrentThread(), - Times.Exactly(1), - "Inner engine should be disposed" - ); - } - - [Test] - public void ExecuteWithLargerStackIfRequiredShouldBubbleExceptions() - { - var mocks = new Mocks(); - var environment = mocks.CreateReactEnvironment(); - // Always fail - mocks.Engine.Setup(x => x.CallFunction("foobar")) - .Throws(new Exception("Something bad happened :(")); - - Assert.Throws(() => - { - environment.ExecuteWithLargerStackIfRequired("foobar"); - }); - } - - private class Mocks - { - public Mock Engine { get; private set; } - public Mock EngineFactory { get; private set; } - public Mock Config { get; private set; } - public Mock Cache { get; private set; } - public Mock FileSystem { get; private set; } - public Mock FileCacheHash { get; private set; } - public Mocks() - { - Engine = new Mock(); - EngineFactory = new Mock(); - Config = new Mock(); - Cache = new Mock(); - FileSystem = new Mock(); - FileCacheHash = new Mock(); - - EngineFactory.Setup(x => x.GetEngineForCurrentThread(It.IsAny>())).Returns(Engine.Object); - } - - public ReactEnvironment CreateReactEnvironment() - { - return new ReactEnvironment( - EngineFactory.Object, - Config.Object, - Cache.Object, - FileSystem.Object, - FileCacheHash.Object - ); - } - } - } -} diff --git a/src/React.Tests/React.Tests.csproj b/src/React.Tests/React.Tests.csproj deleted file mode 100644 index a7f05afaa..000000000 --- a/src/React.Tests/React.Tests.csproj +++ /dev/null @@ -1,101 +0,0 @@ - - - - - Debug - AnyCPU - {D7C645EB-7B85-45D5-AAA6-CAD3DE704381} - Library - Properties - React.Tests - React.Tests - v4.0 - 512 - - - true - full - false - ..\..\bin\DebugTests\React.Tests\ - DEBUG;TRACE - prompt - 4 - false - 1607 - - - pdbonly - true - ..\..\bin\ReleaseTests\React.Tests\ - TRACE - prompt - 4 - true - 1607 - - - true - - - ..\Key.snk - - - - False - ..\packages\JavaScriptEngineSwitcher.Core.1.1.3\lib\net40\JavaScriptEngineSwitcher.Core.dll - - - False - ..\packages\Moq.4.2.1408.0717\lib\net40\Moq.dll - - - ..\packages\NUnit.2.6.3\lib\nunit.framework.dll - - - - - - - - - - - - - Properties\SharedAssemblyInfo.cs - - - Properties\SharedAssemblyVersionInfo.cs - - - - - - - - - - - - - - {134edd16-8dc8-4983-a2e0-b38dab1ecf1c} - React.Web - - - {d0cc8a22-cee6-485c-924b-1f94426fea59} - React - - - - - - - - \ No newline at end of file diff --git a/src/React.Tests/packages.config b/src/React.Tests/packages.config deleted file mode 100644 index 6ed66754a..000000000 --- a/src/React.Tests/packages.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/React.Web.Mvc3/Properties/AssemblyInfo.cs b/src/React.Web.Mvc3/Properties/AssemblyInfo.cs deleted file mode 100644 index eba2dce4d..000000000 --- a/src/React.Web.Mvc3/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,7 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -[assembly: AssemblyTitle("React.Mvc3")] -[assembly: AssemblyDescription("ASP.NET MVC 3 extensions for ReactJS.NET")] -[assembly: ComVisible(false)] -[assembly: Guid("CEAC08B2-5370-4DC6-82DA-5E9B8CD897A9")] \ No newline at end of file diff --git a/src/React.Web.Mvc3/React.Web.Mvc3.csproj b/src/React.Web.Mvc3/React.Web.Mvc3.csproj deleted file mode 100644 index 094e47742..000000000 --- a/src/React.Web.Mvc3/React.Web.Mvc3.csproj +++ /dev/null @@ -1,100 +0,0 @@ - - - - - Debug - AnyCPU - {6B05AF58-BA85-45A9-97AE-88B6B21317D7} - Library - Properties - React.Web.Mvc - React.Web.Mvc3 - v4.0 - 512 - - - true - full - false - ..\..\bin\Debug\React.Mvc3\ - DEBUG;TRACE - prompt - 4 - ..\..\bin\Debug\React.Mvc3\React.Web.Mvc3.XML - true - 1607 - - - pdbonly - true - ..\..\bin\Release\React.Mvc3\ - TRACE - prompt - 4 - true - 1607 - ..\..\bin\Release\React.Mvc3\React.Web.Mvc3.XML - - - true - - - ..\Key.snk - - - - - - - ..\..\lib\Mvc3\System.Web.Mvc.dll - False - - - ..\..\lib\Mvc3\System.Web.Razor.dll - False - - - ..\..\lib\Mvc3\System.Web.WebPages.dll - False - - - - ..\..\lib\Mvc3\System.Web.WebPages.Razor.dll - False - - - - - HtmlHelperExtensions.cs - - - Properties\SharedAssemblyInfo.cs - - - Properties\SharedAssemblyVersionInfo.cs - - - - - - - - - - {134edd16-8dc8-4983-a2e0-b38dab1ecf1c} - React.Web - - - {d0cc8a22-cee6-485c-924b-1f94426fea59} - React - - - - - \ No newline at end of file diff --git a/src/React.Web.Mvc3/React.Web.Mvc3.nutrans b/src/React.Web.Mvc3/React.Web.Mvc3.nutrans deleted file mode 100644 index 4d83dbd2f..000000000 --- a/src/React.Web.Mvc3/React.Web.Mvc3.nutrans +++ /dev/null @@ -1,22 +0,0 @@ - - - - - ReactJS.NET (MVC 3) - ReactJS tools for ASP.NET MVC 3 - ReactJS tools for ASP.NET MVC 3. -Please refer to project site (http://reactjs.net/) for more details, usage examples and sample code. - - - - - diff --git a/src/React.Web.Mvc4/HtmlHelperExtensions.cs b/src/React.Web.Mvc4/HtmlHelperExtensions.cs deleted file mode 100644 index 04bc2e0eb..000000000 --- a/src/React.Web.Mvc4/HtmlHelperExtensions.cs +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -using System.Web; -using System.Web.Mvc; - -namespace React.Web.Mvc -{ - using AssemblyRegistration = React.AssemblyRegistration; - - /// - /// HTML Helpers for utilising React from an ASP.NET MVC application. - /// - public static class HtmlHelperExtensions - { - /// - /// Gets the React environment - /// - private static IReactEnvironment Environment - { - // TODO: Figure out if this can be injected - get { return AssemblyRegistration.Container.Resolve(); } - } - - /// - /// Renders the specified React component - /// - /// Type of the props - /// HTML helper - /// Name of the component - /// Props to initialise the component with - /// The component's HTML - public static IHtmlString React( - this HtmlHelper htmlHelper, - string componentName, - T props - ) - { - var reactComponent = Environment.CreateComponent(componentName, props); - var result = reactComponent.RenderHtml(); - return new HtmlString(result); - } - - /// - /// Renders the JavaScript required to initialise all components client-side. This will - /// attach event handlers to the server-rendered HTML. - /// - /// JavaScript for all components - public static IHtmlString ReactInitJavaScript(this HtmlHelper htmlHelper) - { - var script = Environment.GetInitJavaScript(); - var tag = new TagBuilder("script") - { - InnerHtml = script - }; - return new HtmlString(tag.ToString()); - } - } -} diff --git a/src/React.Web.Mvc4/React.Web.Mvc4.csproj b/src/React.Web.Mvc4/React.Web.Mvc4.csproj index 3a05410c1..cf0b00cd1 100644 --- a/src/React.Web.Mvc4/React.Web.Mvc4.csproj +++ b/src/React.Web.Mvc4/React.Web.Mvc4.csproj @@ -1,115 +1,54 @@ - - - + + - Debug - AnyCPU - {662D52AC-1EE9-4372-BD74-379F9AC56451} - Library - Properties - React.Web.Mvc + ReactJS tools for ASP.NET MVC 4 and 5. For ASP.NET Core, install React.AspNet instead! Please refer to project site (http://reactjs.net/) for more details, usage examples and sample code. + Copyright 2014-Present Facebook, Inc + ReactJS.NET (MVC 4 and 5) + Daniel Lo Nigro + net40 + $(DefineConstants);LEGACYASPNET + true React.Web.Mvc4 - v4.0 - 512 - - - true - full - false - ..\..\bin\Debug\React.Mvc4\ - DEBUG;TRACE - prompt - 4 - ..\..\bin\Debug\React.Mvc4\React.Web.Mvc4.XML - true - 1607 - - - pdbonly - true - ..\..\bin\Release\React.Mvc4\ - TRACE - prompt - 4 - true - 1607 - ..\..\bin\Release\React.Mvc4\React.Web.Mvc4.XML - - + ../key.snk true + true + React.Web.Mvc4 + asp.net;mvc;asp;jquery;javascript;js;react;facebook;reactjs;babel + logo_64.png + https://github.com/reactjs/react.net + https://github.com/reactjs/React.NET/blob/main/LICENSE + true + true + $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb + false + true + snupkg - - ..\Key.snk - + - - True - ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll - - - - - - True - ..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.Helpers.dll - - - True - ..\packages\Microsoft.AspNet.Mvc.4.0.20710.0\lib\net40\System.Web.Mvc.dll - - - True - ..\packages\Microsoft.AspNet.Razor.2.0.30506.0\lib\net40\System.Web.Razor.dll - - - True - ..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.dll - - - True - ..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.Deployment.dll - - - True - ..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.WebPages.Razor.dll - - - - - - + + + + true + content\ + + + - - Properties\SharedAssemblyInfo.cs - - - Properties\SharedAssemblyVersionInfo.cs - - - + + + - - - + + - - - {134edd16-8dc8-4983-a2e0-b38dab1ecf1c} - React.Web - - - {d0cc8a22-cee6-485c-924b-1f94426fea59} - React - + + + + + - - - \ No newline at end of file + + diff --git a/src/React.Web.Mvc4/React.Web.Mvc4.nutrans b/src/React.Web.Mvc4/React.Web.Mvc4.nutrans deleted file mode 100644 index a714558e5..000000000 --- a/src/React.Web.Mvc4/React.Web.Mvc4.nutrans +++ /dev/null @@ -1,22 +0,0 @@ - - - - - ReactJS.NET (MVC 4 and 5) - ReactJS tools for ASP.NET MVC 4 and 5 - ReactJS tools for ASP.NET MVC 4 and 5. -Please refer to project site (http://reactjs.net/) for more details, usage examples and sample code. - - - - - diff --git a/src/React.Web.Mvc4/packages.config b/src/React.Web.Mvc4/packages.config deleted file mode 100644 index 12736f1da..000000000 --- a/src/React.Web.Mvc4/packages.config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/src/React.Web/AspNetCache.cs b/src/React.Web/AspNetCache.cs index 79099614c..9afc48b9c 100644 --- a/src/React.Web/AspNetCache.cs +++ b/src/React.Web/AspNetCache.cs @@ -1,16 +1,13 @@ /* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ using System; using System.Collections.Generic; using System.Linq; -using System.Web; using System.Web.Caching; namespace React.Web @@ -28,55 +25,50 @@ public class AspNetCache : ICache /// /// Initializes a new instance of the class. /// - /// The HTTP context - public AspNetCache(HttpContextBase context) + /// The Web application cache + public AspNetCache(Cache cache) { - _cache = context.Cache; + _cache = cache; } /// - /// Get an item from the cache. If it doesn't exist, call the function to load it + /// Get an item from the cache. Returns if the item does + /// not exist. /// /// Type of data - /// The cache key. + /// The cache key + /// Value to return if item is not in the cache + /// Data from cache, otherwise + public T Get(string key, T fallback = default(T)) + { + return (T)(_cache[key] ?? fallback); + } + + /// + /// Sets an item in the cache. + /// + /// Type of data + /// The cache key + /// Data to cache /// /// Sliding expiration, if cache key is not accessed in this time period it will /// automatically be removed from the cache /// - /// Function to load data to cache. Called if data isn't in the cache, or is stale /// /// Filenames this cached item is dependent on. If any of these files change, the cache /// will be cleared automatically /// - /// - /// Other cache keys this cached item is dependent on. If any of these keys change, the - /// cache will be cleared automatically - /// - /// Data - public T GetOrInsert( - string key, + public void Set( + string key, + T data, TimeSpan slidingExpiration, - Func getData, - IEnumerable cacheDependencyFiles = null, - IEnumerable cacheDependencyKeys = null + IEnumerable cacheDependencyFiles = null ) { - // Check for data in cache - var data = (T)(_cache[key] ?? default(T)); - - // http://stackoverflow.com/questions/65351/null-or-default-comparsion-of-generic-argument-in-c-sharp - if (object.Equals(data, default(T))) - { - // Load data and save into cache - data = getData(); - var cacheDependency = new CacheDependency( - (cacheDependencyFiles ?? Enumerable.Empty()).ToArray(), - (cacheDependencyKeys ?? Enumerable.Empty()).ToArray() - ); - _cache.Insert(key, data, cacheDependency, Cache.NoAbsoluteExpiration, slidingExpiration); - } - - return data; + var cacheDependency = new CacheDependency( + (cacheDependencyFiles ?? Enumerable.Empty()).ToArray() + ); + _cache.Insert(key, data, cacheDependency, Cache.NoAbsoluteExpiration, slidingExpiration); } } } diff --git a/src/React.Web/AspNetFileSystem.cs b/src/React.Web/AspNetFileSystem.cs index edcc3a2e0..a986e955d 100644 --- a/src/React.Web/AspNetFileSystem.cs +++ b/src/React.Web/AspNetFileSystem.cs @@ -1,13 +1,11 @@ /* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ -using System.Web; +using System.Web.Hosting; namespace React.Web { @@ -17,20 +15,6 @@ namespace React.Web ///
    public class AspNetFileSystem : FileSystemBase { - /// - /// The ASP.NET server utilities - /// - private readonly HttpServerUtilityBase _serverUtility; - - /// - /// Initializes a new instance of the class. - /// - /// The server utility. - public AspNetFileSystem(HttpServerUtilityBase serverUtility) - { - _serverUtility = serverUtility; - } - /// /// Converts a path from an application relative path (~/...) to a full filesystem path /// @@ -38,7 +22,7 @@ public AspNetFileSystem(HttpServerUtilityBase serverUtility) /// Full path of the file public override string MapPath(string relativePath) { - return _serverUtility.MapPath(relativePath); + return HostingEnvironment.MapPath(relativePath); } } } diff --git a/src/React.Web/AssemblyRegistration.cs b/src/React.Web/AssemblyRegistration.cs index 44640b72f..aadbc80a2 100644 --- a/src/React.Web/AssemblyRegistration.cs +++ b/src/React.Web/AssemblyRegistration.cs @@ -1,14 +1,13 @@ /* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ using System.Diagnostics; using System.Web; +using System.Web.Caching; using System.Web.Hosting; using React.TinyIoC; @@ -37,7 +36,7 @@ public void Register(TinyIoCContainer container) // Unique per request container.Register().AsPerRequestSingleton(); - container.Register().AsPerRequestSingleton(); + container.Register().AsPerRequestSingleton(); // Mono for Mac OS does not properly handle caching // TODO: Remove this once https://bugzilla.xamarin.com/show_bug.cgi?id=19071 is fixed @@ -47,7 +46,7 @@ public void Register(TinyIoCContainer container) } else { - container.Register().AsPerRequestSingleton(); + container.Register().AsPerRequestSingleton(); } // Wrappers for built-in objects @@ -55,6 +54,7 @@ public void Register(TinyIoCContainer container) container.Register((c, o) => c.Resolve().Server); container.Register((c, o) => c.Resolve().Request); container.Register((c, o) => c.Resolve().Response); + container.Register((c, o) => HttpRuntime.Cache); } /// diff --git a/src/React.Web/BabelHandler.cs b/src/React.Web/BabelHandler.cs new file mode 100644 index 000000000..ba670b008 --- /dev/null +++ b/src/React.Web/BabelHandler.cs @@ -0,0 +1,117 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System.Web; + +namespace React.Web +{ + /// + /// ASP.NET handler that transforms JavaScript via Babel + /// + public class BabelHandler : IBabelHandler + { + private readonly IReactEnvironment _environment; + private readonly IFileSystem _fileSystem; + private readonly HttpRequestBase _request; + private readonly HttpResponseBase _response; + + /// + /// Initializes a new instance of the class. + /// + /// The environment. + /// File system + /// HTTP request + /// HTTP response + public BabelHandler( + IReactEnvironment environment, + IFileSystem fileSystem, + HttpRequestBase request, + HttpResponseBase response + ) + { + _environment = environment; + _fileSystem = fileSystem; + _request = request; + _response = response; + } + + /// + /// Executes the handler. Outputs JavaScript to the response. + /// + public void Execute() + { + if (_request.QueryString["map"] != null) + { + RenderSourceMap(); + } + else + { + RenderFile(); + } + } + + /// + /// Renders the result of the tranformation via Babel. + /// + private void RenderFile() + { + var relativePath = _request.Url.LocalPath; + var result = _environment.Babel.TransformFileWithSourceMap(relativePath); + var sourceMapUri = GetSourceMapUri(relativePath, result.Hash); + ConfigureCaching(); + _response.ContentType = "text/javascript"; + // The sourcemap spec says to use SourceMap, but Firefox only accepts X-SourceMap + _response.AddHeader("SourceMap", sourceMapUri); + _response.AddHeader("X-SourceMap", sourceMapUri); + + _response.Write(result.Code); + } + + /// + /// Renders the source map for this file. + /// + private void RenderSourceMap() + { + var relativePath = _request.Url.LocalPath; + var result = _environment.Babel.TransformFileWithSourceMap(relativePath, forceGenerateSourceMap: true); + if (result.SourceMap == null) + { + _response.StatusCode = 500; + _response.StatusDescription = "Unable to generate source map"; + return; + } + var sourceMap = result.SourceMap.ToJson(); + + ConfigureCaching(); + _response.ContentType = "application/json"; + //_response.Write(")]}\n"); // Recommended by the spec but Firefox doesn't support it + _response.Write(sourceMap); + } + + /// + /// Send headers to cache the response. Only caches on the server-side for now + /// + private void ConfigureCaching() + { + _response.AddFileDependency(_fileSystem.MapPath(_request.Url.LocalPath)); + _response.Cache.SetCacheability(HttpCacheability.Server); + _response.Cache.SetLastModifiedFromFileDependencies(); + _response.Cache.SetETagFromFileDependencies(); + } + + /// + /// Gets the URI to the source map of the specified file + /// + /// Relative path to the JavaScript file + /// Hash of the file + /// URI to the file + private static string GetSourceMapUri(string relativePath, string hash) + { + return string.Format("{0}?map={1}", relativePath, hash); + } + } +} diff --git a/src/React.Web/JsxHandlerFactory.cs b/src/React.Web/BabelHandlerFactory.cs similarity index 55% rename from src/React.Web/JsxHandlerFactory.cs rename to src/React.Web/BabelHandlerFactory.cs index f682292d3..b96b6c47f 100644 --- a/src/React.Web/JsxHandlerFactory.cs +++ b/src/React.Web/BabelHandlerFactory.cs @@ -1,10 +1,8 @@ /* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ using System.Web; @@ -12,9 +10,9 @@ namespace React.Web { /// - /// Handles creation and execution of instances. + /// Handles creation and execution of instances. /// - public class JsxHandlerFactory : IHttpHandler + public class BabelHandlerFactory : IHttpHandler { /// /// Processes this request @@ -22,7 +20,7 @@ public class JsxHandlerFactory : IHttpHandler /// The request context public void ProcessRequest(HttpContext context) { - var handler = React.AssemblyRegistration.Container.Resolve(); + var handler = React.AssemblyRegistration.Container.Resolve(); handler.Execute(); } diff --git a/src/React.Web/Content/App_Start/ReactConfig.cs.pp b/src/React.Web/Content/App_Start/ReactConfig.cs.pp index 0f1a806fa..cfb409dfc 100644 --- a/src/React.Web/Content/App_Start/ReactConfig.cs.pp +++ b/src/React.Web/Content/App_Start/ReactConfig.cs.pp @@ -8,10 +8,6 @@ { public static void Configure() { - // If you want to use fancy new ES6 features, uncomment this line: - // See http://reactjs.net/guides/es6.html for more information. - //ReactSiteConfiguration.Configuration.SetUseHarmony(true); - // If you want to use server-side rendering of React components, // add all the necessary JavaScript files here. This includes // your components as well as all of their dependencies. @@ -19,6 +15,14 @@ //ReactSiteConfiguration.Configuration // .AddScript("~/Scripts/First.jsx") // .AddScript("~/Scripts/Second.jsx"); + + // If you use an external build too (for example, Babel, Webpack, + // Browserify or Gulp), you can improve performance by disabling + // ReactJS.NET's version of Babel and loading the pre-transpiled + // scripts. Example: + //ReactSiteConfiguration.Configuration + // .SetLoadBabel(false) + // .AddScriptWithoutTransform("~/Scripts/bundle.server.js") } } } \ No newline at end of file diff --git a/src/React.Web/Content/web.config.transform b/src/React.Web/Content/web.config.transform index d15f51d6c..4dc6721be 100644 --- a/src/React.Web/Content/web.config.transform +++ b/src/React.Web/Content/web.config.transform @@ -1,17 +1,8 @@ - - - - - - + - - + + - \ No newline at end of file + diff --git a/src/React.Web/Exceptions/ReactAspNetException.cs b/src/React.Web/Exceptions/ReactAspNetException.cs new file mode 100644 index 000000000..2b33b8c44 --- /dev/null +++ b/src/React.Web/Exceptions/ReactAspNetException.cs @@ -0,0 +1,40 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +using System; +using System.Runtime.Serialization; +using React.Exceptions; + +namespace React.Web.Exceptions +{ + /// + /// Thrown when an error occurs in ReactJS.NET's ASP.NET integration. + /// + [Serializable] + public class ReactAspNetException : ReactException + { + /// + /// Initializes a new instance of the class. + /// + /// The message that describes the error. + public ReactAspNetException(string message) : base(message) { } + + /// + /// Initializes a new instance of the class. + /// + /// The error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. + public ReactAspNetException(string message, Exception innerException) + : base(message, innerException) { } + + /// + /// Used by deserialization + /// + protected ReactAspNetException(SerializationInfo info, StreamingContext context) + : base(info, context) { } + } +} diff --git a/src/React.Web/IBabelHandler.cs b/src/React.Web/IBabelHandler.cs new file mode 100644 index 000000000..bd17f1d96 --- /dev/null +++ b/src/React.Web/IBabelHandler.cs @@ -0,0 +1,20 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +namespace React.Web +{ + /// + /// ASP.NET handler that transforms JavaScript via Babel + /// + public interface IBabelHandler + { + /// + /// Executes the handler. Outputs JavaScript to the response. + /// + void Execute(); + } +} diff --git a/src/React.Web/IJsxHandler.cs b/src/React.Web/IJsxHandler.cs deleted file mode 100644 index 88430543f..000000000 --- a/src/React.Web/IJsxHandler.cs +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -namespace React.Web -{ - /// - /// ASP.NET handler that transforms JSX into JavaScript. - /// - public interface IJsxHandler - { - /// - /// Executes the handler. Outputs JavaScript to the response. - /// - void Execute(); - } -} \ No newline at end of file diff --git a/src/React.Web/JsxHandler.cs b/src/React.Web/JsxHandler.cs deleted file mode 100644 index 1fa1606a3..000000000 --- a/src/React.Web/JsxHandler.cs +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -using System.Web; -using System.Web.Caching; - -namespace React.Web -{ - /// - /// ASP.NET handler that transforms JSX into JavaScript. - /// - public class JsxHandler : IJsxHandler - { - private readonly IReactEnvironment _environment; - private readonly IFileSystem _fileSystem; - private readonly HttpRequestBase _request; - private readonly HttpResponseBase _response; - - /// - /// Initializes a new instance of the class. - /// - /// The environment. - /// File system - /// HTTP request - /// HTTP response - public JsxHandler( - IReactEnvironment environment, - IFileSystem fileSystem, - HttpRequestBase request, - HttpResponseBase response - ) - { - _environment = environment; - _fileSystem = fileSystem; - _request = request; - _response = response; - } - - /// - /// Executes the handler. Outputs JavaScript to the response. - /// - public void Execute() - { - var relativePath = _request.Url.LocalPath; - var result = _environment.JsxTransformer.TransformJsxFile(relativePath); - - // Only cache on the server-side for now - _response.AddFileDependency(_fileSystem.MapPath(relativePath)); - _response.Cache.SetCacheability(HttpCacheability.Server); - _response.Cache.SetLastModifiedFromFileDependencies(); - _response.Cache.SetETagFromFileDependencies(); - - _response.ContentType = "text/javascript"; - _response.Write(result); - } - } -} diff --git a/src/React.Web/React.Web.csproj b/src/React.Web/React.Web.csproj index 3449bdb88..3b041eaff 100644 --- a/src/React.Web/React.Web.csproj +++ b/src/React.Web/React.Web.csproj @@ -1,94 +1,53 @@ - - - + + - Debug - AnyCPU - {134EDD16-8DC8-4983-A2E0-B38DAB1ECF1C} - Library - Properties - React.Web + ReactJS tools for ASP.NET. If using ASP.NET MVC, also install React.Web.Mvc4. For ASP.NET Core, install React.AspNet instead! Please refer to project site (http://reactjs.net/) for more details, usage examples and sample code. + Copyright 2014-Present Facebook, Inc + ReactJS.NET for ASP.NET 4 + Daniel Lo Nigro + net40 + true React.Web - v4.0 - 512 - - - true - full - false - ..\..\bin\Debug\React.Web\ - DEBUG;TRACE - prompt - 4 - ..\..\bin\Debug\React.Web\React.Web.XML - false - 1607 - - - pdbonly - true - ..\..\bin\Release\React.Web\ - TRACE - prompt - 4 - ..\..\bin\Release\React.Web\React.Web.XML - true - 1607 - - + ../key.snk true + true + React.Web + asp.net;mvc;asp;jquery;javascript;js;react;facebook;reactjs;babel + logo_64.png + https://github.com/reactjs/react.net + https://github.com/reactjs/React.NET#licence + true + true + $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb + false + true + snupkg - - ..\Key.snk - + - - True - ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll - - - - - - - ..\packages\WebActivatorEx.2.0.5\lib\net40\WebActivatorEx.dll - + + + + true + content\ + + + - - Properties\SharedAssemblyInfo.cs - - - Properties\SharedAssemblyVersionInfo.cs - - - - - - - - - - + + - - {d0cc8a22-cee6-485c-924b-1f94426fea59} - React - + + + - - - - - + + + + + - - - \ No newline at end of file + + diff --git a/src/React.Web/React.Web.nutrans b/src/React.Web/React.Web.nutrans deleted file mode 100644 index 05086a942..000000000 --- a/src/React.Web/React.Web.nutrans +++ /dev/null @@ -1,24 +0,0 @@ - - - - - ReactJS.NET for ASP.NET - ReactJS tools for ASP.NET - ReactJS tools for ASP.NET. If using ASP.NET MVC, also install React.Web.Mvc4. -Please refer to project site (http://reactjs.net/) for more details, usage examples and sample code. - - - - - - - diff --git a/src/React.Web/TinyIoCAspNetExtensions.cs b/src/React.Web/TinyIoCAspNetExtensions.cs index 822533c70..584b93f9d 100644 --- a/src/React.Web/TinyIoCAspNetExtensions.cs +++ b/src/React.Web/TinyIoCAspNetExtensions.cs @@ -1,16 +1,15 @@ /* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ using System; using System.Linq; using System.Web; using React.TinyIoC; +using React.Web.Exceptions; namespace React.Web.TinyIoC { @@ -35,7 +34,8 @@ public class HttpContextLifetimeProvider : TinyIoCContainer.ITinyIoCObjectLifeti /// Object instance or null public object GetObject() { - return HttpContext.Current.Items[_keyName]; + var context = HttpContext.Current; + return context == null ? null : context.Items[_keyName]; } /// @@ -44,7 +44,15 @@ public object GetObject() /// Object to store public void SetObject(object value) { - HttpContext.Current.Items[_keyName] = value; + var context = HttpContext.Current; + if (context == null) + { + throw new ReactAspNetException( + "Trying to store item in HttpContext.Current while not in an ASP.NET " + + "request!" + ); + } + context.Items[_keyName] = value; } /// @@ -55,9 +63,10 @@ public void ReleaseObject() var item = GetObject() as IDisposable; if (item != null) + { item.Dispose(); - - SetObject(null); + SetObject(null); + } } /// @@ -77,4 +86,4 @@ public static void DisposeAll() } } } -} \ No newline at end of file +} diff --git a/src/React.Web/WebInitializer.cs b/src/React.Web/WebInitializer.cs index 507c81bf7..6a919f5f2 100644 --- a/src/React.Web/WebInitializer.cs +++ b/src/React.Web/WebInitializer.cs @@ -1,10 +1,8 @@ /* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. + * Copyright (c) Facebook, Inc. and its affiliates. * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. */ using System.Web; diff --git a/src/React.Web/packages.config b/src/React.Web/packages.config deleted file mode 100644 index 193fb73d7..000000000 --- a/src/React.Web/packages.config +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/src/React.sln b/src/React.sln index accb7c363..594916e8e 100644 --- a/src/React.sln +++ b/src/React.sln @@ -1,25 +1,17 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.30110.0 +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27004.2002 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "React.Sample.Mvc4", "React.Sample.Mvc4\React.Sample.Mvc4.csproj", "{22796879-968A-4C26-9B4B-4C44792B36DB}" - ProjectSection(ProjectDependencies) = postProject - {AF531A37-B93F-4113-9C2C-4DB28064B926} = {AF531A37-B93F-4113-9C2C-4DB28064B926} - EndProjectSection -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{F567B25C-E869-4C93-9C96-077761250F87}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{A51CE5B6-294F-4D39-B32B-BF08DAF9B40B}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Library", "Library", "{681C45FB-103C-48BC-B992-20C5B6B78F92}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "React", "React\React.csproj", "{D0CC8A22-CEE6-485C-924B-1F94426FEA59}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "React.Tests", "React.Tests\React.Tests.csproj", "{D7C645EB-7B85-45D5-AAA6-CAD3DE704381}" -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{CB51F03F-49BD-4B79-8AD4-67962230E76B}" ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig + ..\.gitignore = ..\.gitignore ..\build.proj = ..\build.proj ..\dev-build-push.bat = ..\dev-build-push.bat ..\dev-build.bat = ..\dev-build.bat @@ -30,26 +22,53 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{CB51F03F template.nuspec = template.nuspec EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "React.Web", "React.Web\React.Web.csproj", "{134EDD16-8DC8-4983-A2E0-B38DAB1ECF1C}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "React.Sample.Mvc4", "React.Sample.Mvc4\React.Sample.Mvc4.csproj", "{22796879-968A-4C26-9B4B-4C44792B36DB}" + ProjectSection(ProjectDependencies) = postProject + {AF531A37-B93F-4113-9C2C-4DB28064B926} = {AF531A37-B93F-4113-9C2C-4DB28064B926} + {889CEF81-75D6-4BAB-8E2C-B64B7CA97C77} = {889CEF81-75D6-4BAB-8E2C-B64B7CA97C77} + {662D52AC-1EE9-4372-BD74-379F9AC56451} = {662D52AC-1EE9-4372-BD74-379F9AC56451} + EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "React.Web.Mvc4", "React.Web.Mvc4\React.Web.Mvc4.csproj", "{662D52AC-1EE9-4372-BD74-379F9AC56451}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "React.Sample.Cassette", "React.Sample.Cassette\React.Sample.Cassette.csproj", "{F1EB6834-80A5-411C-90FD-CECC05715A10}" + ProjectSection(ProjectDependencies) = postProject + {B7D39E1D-6CAA-4489-A03F-0C176402CFB2} = {B7D39E1D-6CAA-4489-A03F-0C176402CFB2} + EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Web.Optimization.React", "System.Web.Optimization.React\System.Web.Optimization.React.csproj", "{889CEF81-75D6-4BAB-8E2C-B64B7CA97C77}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "React.Core", "React.Core\React.Core.csproj", "{D0CC8A22-CEE6-485C-924B-1F94426FEA59}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "React.Sample.Cassette", "React.Sample.Cassette\React.Sample.Cassette.csproj", "{F1EB6834-80A5-411C-90FD-CECC05715A10}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Cassette.React", "Cassette.React\Cassette.React.csproj", "{B7D39E1D-6CAA-4489-A03F-0C176402CFB2}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Cassette.React", "Cassette.React\Cassette.React.csproj", "{F591F1E8-3D6B-494A-B72A-152FCCA6210D}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "React.Web", "React.Web\React.Web.csproj", "{134EDD16-8DC8-4983-A2E0-B38DAB1ECF1C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "React.Web.Mvc3", "React.Web.Mvc3\React.Web.Mvc3.csproj", "{6B05AF58-BA85-45A9-97AE-88B6B21317D7}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "React.Web.Mvc4", "React.Web.Mvc4\React.Web.Mvc4.csproj", "{662D52AC-1EE9-4372-BD74-379F9AC56451}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "React.MSBuild", "React.MSBuild\React.MSBuild.csproj", "{AF531A37-B93F-4113-9C2C-4DB28064B926}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Web.Optimization.React", "System.Web.Optimization.React\System.Web.Optimization.React.csproj", "{889CEF81-75D6-4BAB-8E2C-B64B7CA97C77}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{F2875D3A-0C8A-439B-B734-ECABA00AC629}" - ProjectSection(SolutionItems) = preProject - .nuget\packages.config = .nuget\packages.config - EndProjectSection +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "React.MSBuild", "React.MSBuild\React.MSBuild.csproj", "{AF531A37-B93F-4113-9C2C-4DB28064B926}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "React.Owin", "React.Owin\React.Owin.csproj", "{C3BF8D49-B7CC-4D7F-B0F0-A94347C595EA}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "React.Sample.Owin", "React.Sample.Owin\React.Sample.Owin.csproj", "{68F48008-ED43-4BDB-933D-D30D757F5EEA}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "React.JavaScriptEngine.VroomJs", "React.JavaScriptEngine.VroomJs\React.JavaScriptEngine.VroomJs.csproj", "{B4A5902A-70E2-4FA4-817D-DCC78D31E9B9}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "React.Sample.ConsoleApp", "React.Sample.ConsoleApp\React.Sample.ConsoleApp.csproj", "{350EFB8E-693C-4DFE-8162-C99C359CFC71}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "React.Tests", "..\tests\React.Tests\React.Tests.csproj", "{6AA0D75E-5797-4690-BEFC-098A60C511A3}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "React.AspNet", "React.AspNet\React.AspNet.csproj", "{631FCC55-0219-46DC-838A-C5A3E878943A}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "React.Router", "React.Router\React.Router.csproj", "{D076273B-C5EA-47C7-923D-523E4C5EE30D}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "React.AspNet.Middleware", "React.AspNet.Middleware\React.AspNet.Middleware.csproj", "{7E1C3999-1982-476D-9307-12B30737B41E}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "React.Router.Mvc4", "React.Router.Mvc4\React.Router.Mvc4.csproj", "{2170D912-86E9-4CE3-8DA4-E1DE8D958E63}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "React.Tests.Benchmarks", "..\tests\React.Tests.Benchmarks\React.Tests.Benchmarks.csproj", "{083462CB-2FC0-4508-A7ED-4B77B44C3E23}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "React.Tests.Integration", "..\tests\React.Tests.Integration\React.Tests.Integration.csproj", "{5EBC5EA6-7234-40E0-A07B-75D01385FAD2}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "React.Tests.Common", "..\tests\React.Tests.Common\React.Tests.Common.csproj", "{29F7122F-ECBB-4EBE-A2BB-3A00CED73C19}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "React.Template", "React.Template\React.Template.csproj", "{FE067035-C82A-49D4-BFBE-4B0AF82F0817}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -61,14 +80,18 @@ Global {22796879-968A-4C26-9B4B-4C44792B36DB}.Debug|Any CPU.Build.0 = Debug|Any CPU {22796879-968A-4C26-9B4B-4C44792B36DB}.Release|Any CPU.ActiveCfg = Release|Any CPU {22796879-968A-4C26-9B4B-4C44792B36DB}.Release|Any CPU.Build.0 = Release|Any CPU + {F1EB6834-80A5-411C-90FD-CECC05715A10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F1EB6834-80A5-411C-90FD-CECC05715A10}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F1EB6834-80A5-411C-90FD-CECC05715A10}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F1EB6834-80A5-411C-90FD-CECC05715A10}.Release|Any CPU.Build.0 = Release|Any CPU {D0CC8A22-CEE6-485C-924B-1F94426FEA59}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D0CC8A22-CEE6-485C-924B-1F94426FEA59}.Debug|Any CPU.Build.0 = Debug|Any CPU {D0CC8A22-CEE6-485C-924B-1F94426FEA59}.Release|Any CPU.ActiveCfg = Release|Any CPU {D0CC8A22-CEE6-485C-924B-1F94426FEA59}.Release|Any CPU.Build.0 = Release|Any CPU - {D7C645EB-7B85-45D5-AAA6-CAD3DE704381}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D7C645EB-7B85-45D5-AAA6-CAD3DE704381}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D7C645EB-7B85-45D5-AAA6-CAD3DE704381}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D7C645EB-7B85-45D5-AAA6-CAD3DE704381}.Release|Any CPU.Build.0 = Release|Any CPU + {B7D39E1D-6CAA-4489-A03F-0C176402CFB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B7D39E1D-6CAA-4489-A03F-0C176402CFB2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B7D39E1D-6CAA-4489-A03F-0C176402CFB2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B7D39E1D-6CAA-4489-A03F-0C176402CFB2}.Release|Any CPU.Build.0 = Release|Any CPU {134EDD16-8DC8-4983-A2E0-B38DAB1ECF1C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {134EDD16-8DC8-4983-A2E0-B38DAB1ECF1C}.Debug|Any CPU.Build.0 = Debug|Any CPU {134EDD16-8DC8-4983-A2E0-B38DAB1ECF1C}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -81,26 +104,58 @@ Global {889CEF81-75D6-4BAB-8E2C-B64B7CA97C77}.Debug|Any CPU.Build.0 = Debug|Any CPU {889CEF81-75D6-4BAB-8E2C-B64B7CA97C77}.Release|Any CPU.ActiveCfg = Release|Any CPU {889CEF81-75D6-4BAB-8E2C-B64B7CA97C77}.Release|Any CPU.Build.0 = Release|Any CPU - {F1EB6834-80A5-411C-90FD-CECC05715A10}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F1EB6834-80A5-411C-90FD-CECC05715A10}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F1EB6834-80A5-411C-90FD-CECC05715A10}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F1EB6834-80A5-411C-90FD-CECC05715A10}.Release|Any CPU.Build.0 = Release|Any CPU - {F591F1E8-3D6B-494A-B72A-152FCCA6210D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F591F1E8-3D6B-494A-B72A-152FCCA6210D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F591F1E8-3D6B-494A-B72A-152FCCA6210D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F591F1E8-3D6B-494A-B72A-152FCCA6210D}.Release|Any CPU.Build.0 = Release|Any CPU - {6B05AF58-BA85-45A9-97AE-88B6B21317D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6B05AF58-BA85-45A9-97AE-88B6B21317D7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6B05AF58-BA85-45A9-97AE-88B6B21317D7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6B05AF58-BA85-45A9-97AE-88B6B21317D7}.Release|Any CPU.Build.0 = Release|Any CPU {AF531A37-B93F-4113-9C2C-4DB28064B926}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {AF531A37-B93F-4113-9C2C-4DB28064B926}.Debug|Any CPU.Build.0 = Debug|Any CPU {AF531A37-B93F-4113-9C2C-4DB28064B926}.Release|Any CPU.ActiveCfg = Release|Any CPU {AF531A37-B93F-4113-9C2C-4DB28064B926}.Release|Any CPU.Build.0 = Release|Any CPU - {B4A5902A-70E2-4FA4-817D-DCC78D31E9B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B4A5902A-70E2-4FA4-817D-DCC78D31E9B9}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B4A5902A-70E2-4FA4-817D-DCC78D31E9B9}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B4A5902A-70E2-4FA4-817D-DCC78D31E9B9}.Release|Any CPU.Build.0 = Release|Any CPU + {C3BF8D49-B7CC-4D7F-B0F0-A94347C595EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C3BF8D49-B7CC-4D7F-B0F0-A94347C595EA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C3BF8D49-B7CC-4D7F-B0F0-A94347C595EA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C3BF8D49-B7CC-4D7F-B0F0-A94347C595EA}.Release|Any CPU.Build.0 = Release|Any CPU + {68F48008-ED43-4BDB-933D-D30D757F5EEA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {68F48008-ED43-4BDB-933D-D30D757F5EEA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {68F48008-ED43-4BDB-933D-D30D757F5EEA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {68F48008-ED43-4BDB-933D-D30D757F5EEA}.Release|Any CPU.Build.0 = Release|Any CPU + {350EFB8E-693C-4DFE-8162-C99C359CFC71}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {350EFB8E-693C-4DFE-8162-C99C359CFC71}.Debug|Any CPU.Build.0 = Debug|Any CPU + {350EFB8E-693C-4DFE-8162-C99C359CFC71}.Release|Any CPU.ActiveCfg = Release|Any CPU + {350EFB8E-693C-4DFE-8162-C99C359CFC71}.Release|Any CPU.Build.0 = Release|Any CPU + {6AA0D75E-5797-4690-BEFC-098A60C511A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6AA0D75E-5797-4690-BEFC-098A60C511A3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6AA0D75E-5797-4690-BEFC-098A60C511A3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6AA0D75E-5797-4690-BEFC-098A60C511A3}.Release|Any CPU.Build.0 = Release|Any CPU + {631FCC55-0219-46DC-838A-C5A3E878943A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {631FCC55-0219-46DC-838A-C5A3E878943A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {631FCC55-0219-46DC-838A-C5A3E878943A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {631FCC55-0219-46DC-838A-C5A3E878943A}.Release|Any CPU.Build.0 = Release|Any CPU + {D076273B-C5EA-47C7-923D-523E4C5EE30D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D076273B-C5EA-47C7-923D-523E4C5EE30D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D076273B-C5EA-47C7-923D-523E4C5EE30D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D076273B-C5EA-47C7-923D-523E4C5EE30D}.Release|Any CPU.Build.0 = Release|Any CPU + {7E1C3999-1982-476D-9307-12B30737B41E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7E1C3999-1982-476D-9307-12B30737B41E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7E1C3999-1982-476D-9307-12B30737B41E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7E1C3999-1982-476D-9307-12B30737B41E}.Release|Any CPU.Build.0 = Release|Any CPU + {2170D912-86E9-4CE3-8DA4-E1DE8D958E63}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2170D912-86E9-4CE3-8DA4-E1DE8D958E63}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2170D912-86E9-4CE3-8DA4-E1DE8D958E63}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2170D912-86E9-4CE3-8DA4-E1DE8D958E63}.Release|Any CPU.Build.0 = Release|Any CPU + {083462CB-2FC0-4508-A7ED-4B77B44C3E23}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {083462CB-2FC0-4508-A7ED-4B77B44C3E23}.Debug|Any CPU.Build.0 = Debug|Any CPU + {083462CB-2FC0-4508-A7ED-4B77B44C3E23}.Release|Any CPU.ActiveCfg = Release|Any CPU + {083462CB-2FC0-4508-A7ED-4B77B44C3E23}.Release|Any CPU.Build.0 = Release|Any CPU + {5EBC5EA6-7234-40E0-A07B-75D01385FAD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5EBC5EA6-7234-40E0-A07B-75D01385FAD2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5EBC5EA6-7234-40E0-A07B-75D01385FAD2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5EBC5EA6-7234-40E0-A07B-75D01385FAD2}.Release|Any CPU.Build.0 = Release|Any CPU + {29F7122F-ECBB-4EBE-A2BB-3A00CED73C19}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {29F7122F-ECBB-4EBE-A2BB-3A00CED73C19}.Debug|Any CPU.Build.0 = Debug|Any CPU + {29F7122F-ECBB-4EBE-A2BB-3A00CED73C19}.Release|Any CPU.ActiveCfg = Release|Any CPU + {29F7122F-ECBB-4EBE-A2BB-3A00CED73C19}.Release|Any CPU.Build.0 = Release|Any CPU + {FE067035-C82A-49D4-BFBE-4B0AF82F0817}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FE067035-C82A-49D4-BFBE-4B0AF82F0817}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FE067035-C82A-49D4-BFBE-4B0AF82F0817}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FE067035-C82A-49D4-BFBE-4B0AF82F0817}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -108,14 +163,25 @@ Global GlobalSection(NestedProjects) = preSolution {22796879-968A-4C26-9B4B-4C44792B36DB} = {A51CE5B6-294F-4D39-B32B-BF08DAF9B40B} {F1EB6834-80A5-411C-90FD-CECC05715A10} = {A51CE5B6-294F-4D39-B32B-BF08DAF9B40B} - {D7C645EB-7B85-45D5-AAA6-CAD3DE704381} = {F567B25C-E869-4C93-9C96-077761250F87} {D0CC8A22-CEE6-485C-924B-1F94426FEA59} = {681C45FB-103C-48BC-B992-20C5B6B78F92} + {B7D39E1D-6CAA-4489-A03F-0C176402CFB2} = {681C45FB-103C-48BC-B992-20C5B6B78F92} {134EDD16-8DC8-4983-A2E0-B38DAB1ECF1C} = {681C45FB-103C-48BC-B992-20C5B6B78F92} {662D52AC-1EE9-4372-BD74-379F9AC56451} = {681C45FB-103C-48BC-B992-20C5B6B78F92} {889CEF81-75D6-4BAB-8E2C-B64B7CA97C77} = {681C45FB-103C-48BC-B992-20C5B6B78F92} - {F591F1E8-3D6B-494A-B72A-152FCCA6210D} = {681C45FB-103C-48BC-B992-20C5B6B78F92} - {6B05AF58-BA85-45A9-97AE-88B6B21317D7} = {681C45FB-103C-48BC-B992-20C5B6B78F92} {AF531A37-B93F-4113-9C2C-4DB28064B926} = {681C45FB-103C-48BC-B992-20C5B6B78F92} - {B4A5902A-70E2-4FA4-817D-DCC78D31E9B9} = {681C45FB-103C-48BC-B992-20C5B6B78F92} + {C3BF8D49-B7CC-4D7F-B0F0-A94347C595EA} = {681C45FB-103C-48BC-B992-20C5B6B78F92} + {68F48008-ED43-4BDB-933D-D30D757F5EEA} = {A51CE5B6-294F-4D39-B32B-BF08DAF9B40B} + {350EFB8E-693C-4DFE-8162-C99C359CFC71} = {A51CE5B6-294F-4D39-B32B-BF08DAF9B40B} + {6AA0D75E-5797-4690-BEFC-098A60C511A3} = {F567B25C-E869-4C93-9C96-077761250F87} + {631FCC55-0219-46DC-838A-C5A3E878943A} = {681C45FB-103C-48BC-B992-20C5B6B78F92} + {D076273B-C5EA-47C7-923D-523E4C5EE30D} = {681C45FB-103C-48BC-B992-20C5B6B78F92} + {7E1C3999-1982-476D-9307-12B30737B41E} = {681C45FB-103C-48BC-B992-20C5B6B78F92} + {2170D912-86E9-4CE3-8DA4-E1DE8D958E63} = {681C45FB-103C-48BC-B992-20C5B6B78F92} + {083462CB-2FC0-4508-A7ED-4B77B44C3E23} = {F567B25C-E869-4C93-9C96-077761250F87} + {5EBC5EA6-7234-40E0-A07B-75D01385FAD2} = {F567B25C-E869-4C93-9C96-077761250F87} + {29F7122F-ECBB-4EBE-A2BB-3A00CED73C19} = {F567B25C-E869-4C93-9C96-077761250F87} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {DCF4A41E-C60D-4086-98A9-6F8508D7E8D0} EndGlobalSection EndGlobal diff --git a/src/React/Exceptions/JsxException.cs b/src/React/Exceptions/JsxException.cs deleted file mode 100644 index 0c376b1ef..000000000 --- a/src/React/Exceptions/JsxException.cs +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -using System; -using System.Runtime.Serialization; - -namespace React.Exceptions -{ - /// - /// Thrown when an error occurs with parsing JSX. - /// - [Serializable] - public class JsxException : ReactException - { - /// - /// Initializes a new instance of the class. - /// - /// The message that describes the error. - public JsxException(string message) : base(message) { } - /// - /// Initializes a new instance of the class. - /// - /// The error message that explains the reason for the exception. - /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified. - public JsxException(string message, Exception innerException) - : base(message, innerException) { } - - /// - /// Used by deserialization - /// - protected JsxException(SerializationInfo info, StreamingContext context) - : base(info, context) { } - } -} diff --git a/src/React/Exceptions/JsxUnsupportedEngineException.cs b/src/React/Exceptions/JsxUnsupportedEngineException.cs deleted file mode 100644 index 3320fe0cf..000000000 --- a/src/React/Exceptions/JsxUnsupportedEngineException.cs +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -using System; -using System.Runtime.Serialization; -using System.Text; - -namespace React.Exceptions -{ - /// - /// Thrown when the JavaScript engine does not support JSX transformation - /// - [Serializable] - public class JsxUnsupportedEngineException : ReactException - { - /// - /// Initializes a new instance of the class. - /// - public JsxUnsupportedEngineException() : base(GetMessage()) { } - - /// - /// Used by deserialization - /// - protected JsxUnsupportedEngineException(SerializationInfo info, StreamingContext context) - : base(info, context) { } - - /// - /// Gets a message that describes the current exception. - /// - private static string GetMessage() - { - return - "The current JavaScript engine does not support compilation of JSX files. If " + - "you are on Windows, try upgrading your version of Internet Explorer to 9 or " + - "above to use the updated engine. \n\nIf you are using Mono, ensure that you " + - "have installed the React.JavaScriptEngine.VroomJs package and V8 is installed " + - "correcty. Refer to the ReactJS.NET documentation for more details."; - } - } -} diff --git a/src/React/FileSystemBase.cs b/src/React/FileSystemBase.cs deleted file mode 100644 index f7b9b8a55..000000000 --- a/src/React/FileSystemBase.cs +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -using System.IO; -using System.Text; - -namespace React -{ - /// - /// Handles file system functionality, such as reading files. - /// - abstract public class FileSystemBase : IFileSystem - { - /// - /// Converts a path from an application relative path (~/...) to a full filesystem path - /// - /// App-relative path of the file - /// Full path of the file - public abstract string MapPath(string relativePath); - - /// - /// Reads the contents of a file as a string. - /// - /// App-relative path of the file - /// Contents of the file - public string ReadAsString(string relativePath) - { - return File.ReadAllText(MapPath(relativePath), Encoding.UTF8); - } - - /// - /// Writes a string to a file - /// - /// App-relative path of the file - /// Contents of the file - public void WriteAsString(string relativePath, string contents) - { - File.WriteAllText(MapPath(relativePath), contents, Encoding.UTF8); - } - - /// - /// Determines if the specified file exists - /// - /// App-relative path of the file - /// true if the file exists - public bool FileExists(string relativePath) - { - return File.Exists(MapPath(relativePath)); - } - } -} diff --git a/src/React/ICache.cs b/src/React/ICache.cs deleted file mode 100644 index 5f31d257d..000000000 --- a/src/React/ICache.cs +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -using System; -using System.Collections.Generic; - -namespace React -{ - /// - /// Handles caching of data and optionally tracking dependencies - /// - public interface ICache - { - /// - /// Get an item from the cache. If it doesn't exist, call the function to load it - /// - /// Type of data - /// The cache key. - /// - /// Sliding expiration, if cache key is not accessed in this time period it will - /// automatically be removed from the cache - /// - /// Function to load data to cache. Called if data isn't in the cache, or is stale - /// - /// Filenames this cached item is dependent on. If any of these files change, the cache - /// will be cleared automatically - /// - /// - /// Other cache keys this cached item is dependent on. If any of these keys change, the - /// cache will be cleared automatically - /// - /// Data - T GetOrInsert( - string key, - TimeSpan slidingExpiration, - Func getData, - IEnumerable cacheDependencyFiles = null, - IEnumerable cacheDependencyKeys = null - ); - } -} \ No newline at end of file diff --git a/src/React/IJavaScriptEngineFactory.cs b/src/React/IJavaScriptEngineFactory.cs deleted file mode 100644 index 7c4bc60aa..000000000 --- a/src/React/IJavaScriptEngineFactory.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using JavaScriptEngineSwitcher.Core; - -namespace React -{ - /// - /// Handles creation of JavaScript engines. All methods are thread-safe. - /// - public interface IJavaScriptEngineFactory - { - /// - /// Gets the JavaScript engine for the current thread - /// - /// - /// Called if a brand new JavaScript engine is being created for this thread. - /// Should handle initialisation. - /// - /// The JavaScript engine - IJsEngine GetEngineForCurrentThread(Action onNewEngine); - - /// - /// Disposes the JavaScript engine for the current thread. - /// - void DisposeEngineForCurrentThread(); - } -} \ No newline at end of file diff --git a/src/React/IJsxTransformer.cs b/src/React/IJsxTransformer.cs deleted file mode 100644 index 7764b88c8..000000000 --- a/src/React/IJsxTransformer.cs +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -namespace React -{ - /// - /// Handles compiling JSX to JavaScript. - /// - public interface IJsxTransformer - { - /// - /// Transforms a JSX file. Results of the JSX to JavaScript transformation are cached. - /// - /// Name of the file to load - /// true if support for es6 syntax should be rewritten. - /// JavaScript - string TransformJsxFile(string filename, bool? useHarmony = null); - - /// - /// Transforms JSX into regular JavaScript. The result is not cached. Use - /// if loading from a file since this will cache the result. - /// - /// JSX - /// true if support for es6 syntax should be rewritten. - /// JavaScript - string TransformJsx(string input, bool? useHarmony = null); - - /// - /// Transforms a JSX file to JavaScript, and saves the result into a ".generated.js" file - /// alongside the original file. - /// - /// Name of the file to load - /// true if support for es6 syntax should be rewritten. - /// File contents - string TransformAndSaveJsxFile(string filename, bool? useHarmony = null); - - /// - /// Returns the path the specified JSX file's compilation will be cached to - /// - /// Path of the JSX file - /// Output path of the compiled file - string GetJsxOutputPath(string path); - } -} \ No newline at end of file diff --git a/src/React/IReactComponent.cs b/src/React/IReactComponent.cs deleted file mode 100644 index ce2b9d862..000000000 --- a/src/React/IReactComponent.cs +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -namespace React -{ - /// - /// Represents a React JavaScript component. - /// - public interface IReactComponent - { - /// - /// Gets or sets the props for this component - /// - object Props { get; set; } - - /// - /// Renders the HTML for this component. This will execute the component server-side and - /// return the rendered HTML. - /// - /// HTML - string RenderHtml(); - - /// - /// Renders the JavaScript required to initialise this component client-side. This will - /// initialise the React component, which includes attach event handlers to the - /// server-rendered HTML. - /// - /// JavaScript - string RenderJavaScript(); - } -} \ No newline at end of file diff --git a/src/React/IReactEnvironment.cs b/src/React/IReactEnvironment.cs deleted file mode 100644 index 9fa518cd3..000000000 --- a/src/React/IReactEnvironment.cs +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -using System; - -namespace React -{ - /// - /// Request-specific ReactJS.NET environment. This is unique to the individual request and is - /// not shared. - /// - public interface IReactEnvironment - { - /// - /// Determines if this JavaScript engine supports the JSX transformer. - /// - bool EngineSupportsJsxTransformer { get; } - - /// - /// Gets the version number of ReactJS.NET - /// - string Version { get; } - - /// - /// Executes the provided JavaScript code. - /// - /// JavaScript to execute - void Execute(string code); - - /// - /// Executes the provided JavaScript code, returning a result of the specified type. - /// - /// Type to return - /// Code to execute - /// Result of the JavaScript code - T Execute(string code); - - /// - /// Attempts to execute the provided JavaScript code using the current engine. If an - /// exception is thrown, retries the execution using a new thread (and hence a new engine) - /// with a larger maximum stack size. - /// This is required because JSXTransformer uses a huge stack which ends up being larger - /// than what ASP.NET allows by default (256 KB). - /// - /// Type to return from JavaScript call - /// JavaScript function to execute - /// Arguments to pass to function - /// Result returned from JavaScript code - T ExecuteWithLargerStackIfRequired(string function, params object[] args); - - /// - /// Determines if the specified variable exists in the JavaScript engine - /// - /// Name of the variable - /// true if the variable exists; false otherwise - bool HasVariable(string name); - - /// - /// Creates an instance of the specified React JavaScript component. - /// - /// Type of the props - /// Name of the component - /// Props to use - /// The component - IReactComponent CreateComponent(string componentName, T props); - - /// - /// Renders the JavaScript required to initialise all components client-side. This will - /// attach event handlers to the server-rendered HTML. - /// - /// JavaScript for all components - string GetInitJavaScript(); - - /// - /// Loads a JSX file. Results of the JSX to JavaScript transformation are cached. - /// - /// Name of the file to load - /// File contents - [Obsolete("Use JsxTransformer.TransformJsxFile")] - string LoadJsxFile(string filename); - - /// - /// Transforms JSX into regular JavaScript. The result is not cached. Use - /// if loading from a file since this will cache the result. - /// - /// JSX - /// JavaScript - [Obsolete("Use JsxTransformer.TransformJsx")] - string TransformJsx(string input); - - /// - /// Gets the JSX Transformer for this environment. - /// - IJsxTransformer JsxTransformer { get; } - } -} diff --git a/src/React/IReactSiteConfiguration.cs b/src/React/IReactSiteConfiguration.cs deleted file mode 100644 index 43c1db33b..000000000 --- a/src/React/IReactSiteConfiguration.cs +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -using System.Collections.Generic; - -namespace React -{ - /// - /// Site-wide configuration for ReactJS.NET - /// - public interface IReactSiteConfiguration - { - /// - /// Adds a script to the list of scripts that are executed. This should be called for all - /// React components and their dependencies. - /// - /// - /// Name of the file to execute. Should be a server relative path starting with ~ (eg. - /// ~/Scripts/Awesome.js) - /// - /// This configuration, for chaining - IReactSiteConfiguration AddScript(string filename); - - /// - /// Gets a list of all the scripts that have been added to this configuration. - /// - IList Scripts { get; } - - /// - /// A value indicating if es6 syntax should be rewritten. - /// - /// true if support for es6 syntax should be rewritten. - bool UseHarmony { get; set; } - - /// - /// Specifies whether ES6 (harmony) syntax should be transformed - /// - IReactSiteConfiguration SetUseHarmony(bool useHarmony); - } -} diff --git a/src/React/JavaScriptEngineExtensions.cs b/src/React/JavaScriptEngineExtensions.cs deleted file mode 100644 index 7dbdca503..000000000 --- a/src/React/JavaScriptEngineExtensions.cs +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -using JavaScriptEngineSwitcher.Core; -using JavaScriptEngineSwitcher.Jint; - -namespace React -{ - /// - /// Extension methods for . - /// - public static class JavaScriptEngineExtensions - { - /// - /// Determines if this JavaScript engine supports the JSX transformer. - /// - /// JavaScript engine - /// true if JSXTransformer is supported - public static bool SupportsJsxTransformer(this IJsEngine jsEngine) - { - // Jint overflows the stack if you attempt to run the JSX Transformer :( - return !(jsEngine is JintJsEngine); - } - } -} diff --git a/src/React/JavaScriptEngineFactory.cs b/src/React/JavaScriptEngineFactory.cs deleted file mode 100644 index ef8e555b0..000000000 --- a/src/React/JavaScriptEngineFactory.cs +++ /dev/null @@ -1,143 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Threading; -using JavaScriptEngineSwitcher.Core; -using React.Exceptions; - -namespace React -{ - /// - /// Handles creation of JavaScript engines. All methods are thread-safe. - /// - public class JavaScriptEngineFactory : IDisposable, IJavaScriptEngineFactory - { - /// - /// Function used to create new JavaScript engine instances. - /// - private readonly Func _factory; - /// - /// Contains all current JavaScript engine instances. One per thread, keyed on thread ID. - /// - private readonly ConcurrentDictionary _engines - = new ConcurrentDictionary(); - - /// - /// Initializes a new instance of the class. - /// - public JavaScriptEngineFactory(IEnumerable availableFactories) - { - _factory = GetFactory(availableFactories); - } - - /// - /// Gets the JavaScript engine for the current thread - /// - /// - /// Called if a brand new JavaScript engine is being created for this thread. - /// Should handle initialisation. - /// - /// The JavaScript engine - public IJsEngine GetEngineForCurrentThread(Action onNewEngine = null) - { - return _engines.GetOrAdd(Thread.CurrentThread.ManagedThreadId, id => - { - var engine = _factory(); - if (onNewEngine != null) - { - onNewEngine(engine); - } - return engine; - }); - } - - /// - /// Disposes the JavaScript engine for the current thread. - /// - public void DisposeEngineForCurrentThread() - { - IJsEngine engine; - if (_engines.TryRemove(Thread.CurrentThread.ManagedThreadId, out engine)) - { - if (engine != null) - { - engine.Dispose(); - } - } - } - - /// - /// Gets a factory for the most appropriate JavaScript engine for the current environment. - /// The first functioning JavaScript engine with the lowest priority will be used. - /// - /// Function to create JavaScript engine - private static Func GetFactory(IEnumerable availableFactories) - { - var availableEngineFactories = availableFactories - .OrderBy(x => x.Priority) - .Select(x => x.Factory); - foreach (var engineFactory in availableEngineFactories) - { - IJsEngine engine = null; - try - { - engine = engineFactory(); - // Perform a sanity test to ensure this engine is usable - if (engine.Evaluate("1 + 1") == 2) - { - // Success! Use this one. - return engineFactory; - } - } - catch (Exception ex) - { - // This engine threw an exception, try the next one - Trace.WriteLine(string.Format("Error initialising {0}: {1}", engineFactory, ex)); - } - finally - { - if (engine != null) - { - engine.Dispose(); - } - } - } - - // Epic fail, none of the engines worked. Nothing we can do now. - throw new ReactException("No usable JavaScript engine found :("); - } - - /// - /// Clean up all engines - /// - public void Dispose() - { - foreach (var engine in _engines) - { - if (engine.Value != null) - { - engine.Value.Dispose(); - } - } - } - - /// - /// Represents a factory for a supported JavaScript engine. - /// - public class Registration - { - /// - /// Gets or sets the factory for this JavaScript engine - /// - public Func Factory { get; set; } - - /// - /// Gets or sets the priority for this JavaScript engine. Engines with lower priority - /// are preferred. - /// - public int Priority { get; set; } - } - } -} diff --git a/src/React/JsxTransformer.cs b/src/React/JsxTransformer.cs deleted file mode 100644 index 696f91f58..000000000 --- a/src/React/JsxTransformer.cs +++ /dev/null @@ -1,213 +0,0 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -using System; -using System.IO; -using React.Exceptions; - -namespace React -{ - /// - /// Handles compiling JSX to JavaScript. - /// - public class JsxTransformer : IJsxTransformer - { - /// - /// Cache key for JSX to JavaScript compilation - /// - private const string JSX_CACHE_KEY = "JSX_{0}"; - /// - /// Suffix to append to compiled files - /// - private const string COMPILED_FILE_SUFFIX = ".generated.js"; - - /// - /// Environment this JSX Transformer has been created in - /// - private readonly IReactEnvironment _environment; - /// - /// Cache used for storing compiled JSX - /// - private readonly ICache _cache; - /// - /// File system wrapper - /// - private readonly IFileSystem _fileSystem; - /// - /// Hash algorithm for file-based cache - /// - private readonly IFileCacheHash _fileCacheHash; - /// - /// Site-wide configuration - /// - private readonly IReactSiteConfiguration _config; - - /// - /// Initializes a new instance of the class. - /// - /// The ReactJS.NET environment - /// The cache to use for JSX compilation - /// File system wrapper - /// Hash algorithm for file-based cache - /// Site-wide configuration - public JsxTransformer(IReactEnvironment environment, ICache cache, IFileSystem fileSystem, IFileCacheHash fileCacheHash, IReactSiteConfiguration siteConfig) - { - _environment = environment; - _cache = cache; - _fileSystem = fileSystem; - _fileCacheHash = fileCacheHash; - _config = siteConfig; - } - - /// - /// Transforms a JSX file. Results of the JSX to JavaScript transformation are cached. - /// - /// Name of the file to load - /// true if support for es6 syntax should be rewritten. - /// JavaScript - public string TransformJsxFile(string filename, bool? useHarmony = null) - { - var fullPath = _fileSystem.MapPath(filename); - - // 1. Check in-memory cache - return _cache.GetOrInsert( - key: string.Format(JSX_CACHE_KEY, filename), - slidingExpiration: TimeSpan.FromMinutes(30), - cacheDependencyFiles: new[] { fullPath }, - getData: () => - { - // 2. Check on-disk cache - var contents = _fileSystem.ReadAsString(filename); - var hash = _fileCacheHash.CalculateHash(contents); - - var cacheFilename = GetJsxOutputPath(filename); - if (_fileSystem.FileExists(cacheFilename)) - { - var cacheContents = _fileSystem.ReadAsString(cacheFilename); - if (_fileCacheHash.ValidateHash(cacheContents, hash)) - { - // Cache is valid :D - return cacheContents; - } - } - - // 3. Not cached, perform the transformation - return TransformJsxWithHeader(contents, hash, useHarmony); - } - ); - } - - /// - /// Transforms JSX into regular JavaScript, and prepends a header used for caching - /// purposes. - /// - /// Contents of the input file - /// Hash of the input. If null, it will be calculated - /// true if support for es6 syntax should be rewritten. - /// JavaScript - private string TransformJsxWithHeader(string contents, string hash = null, bool? useHarmony = null) - { - if (string.IsNullOrEmpty(hash)) - { - hash = _fileCacheHash.CalculateHash(contents); - } - return GetFileHeader(hash) + TransformJsx(contents, useHarmony); - } - - /// - /// Transforms JSX into regular JavaScript. The result is not cached. Use - /// if loading from a file since this will cache the result. - /// - /// JSX - /// true if support for es6 syntax should be rewritten. - /// JavaScript - public string TransformJsx(string input, bool? useHarmony = null) - { - // Just return directly if there's no JSX annotation - if (!input.Contains("@jsx")) - { - return input; - } - - EnsureJsxTransformerSupported(); - try - { - var output = _environment.ExecuteWithLargerStackIfRequired( - "ReactNET_transform", - input, - useHarmony.HasValue ? useHarmony.Value : _config.UseHarmony - ); - return output; - } - catch (Exception ex) - { - throw new JsxException(ex.Message, ex); - } - } - - /// - /// Gets the header prepended to JSX transformed files. Contains a hash that is used to - /// validate the cache. - /// - /// Hash of the input - /// Header for the cache - private string GetFileHeader(string hash) - { - return string.Format( -@"{0} -// Automatically generated by ReactJS.NET. Do not edit, your changes will be overridden. -// Version: {1} -// Generated at: {2} -/////////////////////////////////////////////////////////////////////////////// -", _fileCacheHash.AddPrefix(hash), _environment.Version, DateTime.Now); - } - - /// - /// Returns the path the specified JSX file's compilation will be cached to if - /// is called. - /// - /// Path of the JSX file - /// Output path of the compiled file - public string GetJsxOutputPath(string path) - { - return Path.Combine( - Path.GetDirectoryName(path), - Path.GetFileNameWithoutExtension(path) + COMPILED_FILE_SUFFIX - ); - } - - /// - /// Transforms a JSX file to JavaScript, and saves the result into a ".generated.js" file - /// alongside the original file. - /// - /// Name of the file to load - /// true if support for es6 syntax should be rewritten. - /// File contents - public string TransformAndSaveJsxFile(string filename, bool? useHarmony = null) - { - var outputPath = GetJsxOutputPath(filename); - var contents = _fileSystem.ReadAsString(filename); - var result = TransformJsxWithHeader(contents, useHarmony: useHarmony); - _fileSystem.WriteAsString(outputPath, result); - return outputPath; - } - - /// - /// Ensures that the current JavaScript engine supports JSXTransformer. Throws an exception - /// if it doesn't. - /// - private void EnsureJsxTransformerSupported() - { - if (!_environment.EngineSupportsJsxTransformer) - { - throw new JsxUnsupportedEngineException(); - } - } - } -} diff --git a/src/React/NullCache.cs b/src/React/NullCache.cs deleted file mode 100644 index 79c0cc539..000000000 --- a/src/React/NullCache.cs +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -using System; -using System.Collections.Generic; - -namespace React -{ - /// - /// Implementation of that never caches. - /// - public class NullCache : ICache - { - /// - /// Get an item from the cache. If it doesn't exist, call the function to load it - /// - /// Type of data - /// The cache key. - /// - /// Sliding expiration, if cache key is not accessed in this time period it will - /// automatically be removed from the cache - /// - /// Function to load data to cache. Called if data isn't in the cache, or is stale - /// - /// Filenames this cached item is dependent on. If any of these files change, the cache - /// will be cleared automatically - /// - /// - /// Other cache keys this cached item is dependent on. If any of these keys change, the - /// cache will be cleared automatically - /// - /// Data - public T GetOrInsert(string key, TimeSpan slidingExpiration, Func getData, IEnumerable cacheDependencyFiles = null, - IEnumerable cacheDependencyKeys = null) - { - return getData(); - } - } -} \ No newline at end of file diff --git a/src/React/React.csproj b/src/React/React.csproj deleted file mode 100644 index cae539eac..000000000 --- a/src/React/React.csproj +++ /dev/null @@ -1,137 +0,0 @@ - - - - - Debug - AnyCPU - {D0CC8A22-CEE6-485C-924B-1F94426FEA59} - Library - Properties - React - React - v4.0 - 512 - - - true - full - false - ..\..\bin\Debug\React\ - DEBUG;TRACE - prompt - 4 - AnyCPU - ..\..\bin\Debug\React\React.XML - false - 1607 - - - pdbonly - true - ..\..\bin\Release\React\ - TRACE - prompt - 4 - ..\..\bin\Release\React\React.XML - true - 1607 - - - true - - - ..\Key.snk - - - - - - - False - ..\packages\JavaScriptEngineSwitcher.Core.1.1.3\lib\net40\JavaScriptEngineSwitcher.Core.dll - - - False - ..\packages\JavaScriptEngineSwitcher.Jint.1.1.12\lib\net40\JavaScriptEngineSwitcher.Jint.dll - - - False - ..\packages\JavaScriptEngineSwitcher.Msie.1.1.11\lib\net40\JavaScriptEngineSwitcher.Msie.dll - - - False - ..\packages\JavaScriptEngineSwitcher.Jint.1.1.12\lib\net40\Jint.dll - - - False - ..\packages\MsieJavaScriptEngine.1.4.4\lib\net40\MsieJavaScriptEngine.dll - - - False - ..\packages\Newtonsoft.Json.5.0.4\lib\net40\Newtonsoft.Json.dll - - - - - - - - - Properties\SharedAssemblyInfo.cs - - - Properties\SharedAssemblyVersionInfo.cs - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/React/React.nutrans b/src/React/React.nutrans deleted file mode 100644 index 2aec2b6d6..000000000 --- a/src/React/React.nutrans +++ /dev/null @@ -1,20 +0,0 @@ - - - - - React.Core - ReactJS.NET Core - ReactJS tools for .NET - ReactJS tools for .NET. -Important: This package does not do much on its own; you probably want an integration package (like React.Web.Mvc4) as well. Please refer to project site (http://reactjs.net/) for more details, usage examples and sample code. - - \ No newline at end of file diff --git a/src/React/ReactComponent.cs b/src/React/ReactComponent.cs deleted file mode 100644 index cbafaf959..000000000 --- a/src/React/ReactComponent.cs +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -using Newtonsoft.Json; -using React.Exceptions; - -namespace React -{ - /// - /// Represents a React JavaScript component. - /// - public class ReactComponent : IReactComponent - { - /// - /// Environment this component has been created in - /// - private readonly IReactEnvironment _environment; - - /// - /// Name of the component - /// - private readonly string _componentName; - - /// - /// Unique ID for the DIV container of this component - /// - private readonly string _containerId; - - /// - /// Gets or sets the props for this component - /// - public object Props { get; set; } - - /// - /// Initializes a new instance of the class. - /// - /// The environment. - /// Name of the component. - /// The ID of the container DIV for this component - public ReactComponent(IReactEnvironment environment, string componentName, string containerId) - { - _environment = environment; - _componentName = componentName; - _containerId = containerId; - } - - /// - /// Renders the HTML for this component. This will execute the component server-side and - /// return the rendered HTML. - /// - /// HTML - public string RenderHtml() - { - EnsureComponentExists(); - var html = _environment.Execute( - string.Format("React.renderComponentToString({0})", GetComponentInitialiser()) - ); - // TODO: Allow changing of the wrapper tag element from a DIV to something else - return string.Format( - "
    {1}
    ", - _containerId, - html - ); - } - - /// - /// Renders the JavaScript required to initialise this component client-side. This will - /// initialise the React component, which includes attach event handlers to the - /// server-rendered HTML. - /// - /// JavaScript - public string RenderJavaScript() - { - return string.Format( - "React.renderComponent({0}, document.getElementById({1}))", - GetComponentInitialiser(), - JsonConvert.SerializeObject(_containerId) - ); - } - - /// - /// Ensures that this component exists in global scope - /// - private void EnsureComponentExists() - { - if (!_environment.HasVariable(_componentName)) - { - throw new ReactInvalidComponentException(string.Format( - "Could not find a component named '{0}'. Did you forget to add it to " + - "App_Start\\ReactConfig.cs?", - _componentName - )); - } - } - - /// - /// Gets the JavaScript code to initialise the component - /// - /// JavaScript for component initialisation - private string GetComponentInitialiser() - { - var encodedProps = JsonConvert.SerializeObject(Props); - return string.Format( - "{0}({1})", - _componentName, - encodedProps - ); - } - } -} diff --git a/src/React/ReactEnvironment.cs b/src/React/ReactEnvironment.cs deleted file mode 100644 index 14f46b27d..000000000 --- a/src/React/ReactEnvironment.cs +++ /dev/null @@ -1,340 +0,0 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Reflection; -using System.Text; -using System.Threading; -using JavaScriptEngineSwitcher.Core; - -namespace React -{ - /// - /// Request-specific ReactJS.NET environment. This is unique to the individual request and is - /// not shared. - /// - public class ReactEnvironment : IReactEnvironment, IDisposable - { - /// - /// Format string used for React component container IDs - /// - private const string CONTAINER_ELEMENT_NAME = "react{0}"; - - /// - /// JavaScript variable set when user-provided scripts have been loaded - /// - private const string USER_SCRIPTS_LOADED_KEY = "_ReactNET_UserScripts_Loaded"; - /// - /// Stack size to use for JSXTransformer if the default stack is insufficient - /// - private const int LARGE_STACK_SIZE = 2 * 1024 * 1024; - - /// - /// Factory to create JavaScript engines - /// - private readonly IJavaScriptEngineFactory _engineFactory; - /// - /// Site-wide configuration - /// - private readonly IReactSiteConfiguration _config; - /// - /// Cache used for storing compiled JSX - /// - private readonly ICache _cache; - /// - /// File system wrapper - /// - private readonly IFileSystem _fileSystem; - /// - /// Hash algorithm for file-based cache - /// - private readonly IFileCacheHash _fileCacheHash; - - /// - /// JSX Transformer instance for this environment - /// - private readonly Lazy _jsxTransformer; - /// - /// Version number of ReactJS.NET - /// - private readonly Lazy _version = new Lazy(GetVersion); - - /// - /// Number of components instantiated in this environment - /// - private int _maxContainerId = 0; - /// - /// List of all components instantiated in this environment - /// - private readonly IList _components = new List(); - - /// - /// Initializes a new instance of the class. - /// - /// The JavaScript engine factory - /// The site-wide configuration - /// The cache to use for JSX compilation - /// File system wrapper - /// Hash algorithm for file-based cache - public ReactEnvironment( - IJavaScriptEngineFactory engineFactory, - IReactSiteConfiguration config, - ICache cache, - IFileSystem fileSystem, - IFileCacheHash fileCacheHash - ) - { - _engineFactory = engineFactory; - _config = config; - _cache = cache; - _fileSystem = fileSystem; - _fileCacheHash = fileCacheHash; - _jsxTransformer = new Lazy(() => - new JsxTransformer(this, _cache, _fileSystem, _fileCacheHash, _config) - ); - } - - /// - /// Gets the JavaScript engine for the current thread. If an engine has not yet been - /// created, create it and execute the startup scripts. - /// - private IJsEngine Engine - { - get - { - return _engineFactory.GetEngineForCurrentThread(InitialiseEngine); - } - } - - /// - /// Gets the JSX Transformer for this environment. - /// - public IJsxTransformer JsxTransformer - { - get { return _jsxTransformer.Value; } - } - - /// - /// Determines if this JavaScript engine supports the JSX transformer. - /// - public bool EngineSupportsJsxTransformer - { - get { return Engine.SupportsJsxTransformer(); } - } - - /// - /// Gets the version number of ReactJS.NET - /// - public string Version - { - get { return _version.Value; } - } - - /// - /// Loads standard React and JSXTransformer scripts into the engine. - /// - private void InitialiseEngine(IJsEngine engine) - { - var thisAssembly = GetType().Assembly; - engine.ExecuteResource("React.Resources.shims.js", thisAssembly); - engine.ExecuteResource("React.Resources.react-with-addons.js", thisAssembly); - engine.Execute("var React = global.React"); - - // Only load JSX Transformer if engine supports it - if (engine.SupportsJsxTransformer()) - { - engine.ExecuteResource("React.Resources.JSXTransformer.js", thisAssembly); - } - } - - /// - /// Ensures any user-provided scripts have been loaded - /// - private void EnsureUserScriptsLoaded() - { - // Scripts already loaded into this environment, don't load them again - if (Engine.HasVariable(USER_SCRIPTS_LOADED_KEY) || _config == null) - { - return; - } - - foreach (var file in _config.Scripts) - { - var contents = JsxTransformer.TransformJsxFile(file); - Execute(contents); - } - Engine.SetVariableValue(USER_SCRIPTS_LOADED_KEY, true); - } - - /// - /// Executes the provided JavaScript code. - /// - /// JavaScript to execute - public void Execute(string code) - { - Engine.Execute(code); - } - - /// - /// Executes the provided JavaScript code, returning a result of the specified type. - /// - /// Type to return - /// Code to execute - /// Result of the JavaScript code - public T Execute(string code) - { - return Engine.Evaluate(code); - } - - /// - /// Determines if the specified variable exists in the JavaScript engine - /// - /// Name of the variable - /// true if the variable exists; false otherwise - public bool HasVariable(string name) - { - return Engine.HasVariable(name); - } - - /// - /// Creates an instance of the specified React JavaScript component. - /// - /// Type of the props - /// Name of the component - /// Props to use - /// The component - public IReactComponent CreateComponent(string componentName, T props) - { - EnsureUserScriptsLoaded(); - _maxContainerId++; - var containerId = string.Format(CONTAINER_ELEMENT_NAME, _maxContainerId); - var component = new ReactComponent(this, componentName, containerId) - { - Props = props - }; - _components.Add(component); - return component; - } - - /// - /// Renders the JavaScript required to initialise all components client-side. This will - /// attach event handlers to the server-rendered HTML. - /// - /// JavaScript for all components - public string GetInitJavaScript() - { - var fullScript = new StringBuilder(); - foreach (var component in _components) - { - fullScript.Append(component.RenderJavaScript()); - fullScript.AppendLine(";"); - } - return fullScript.ToString(); - } - - /// - /// Loads a JSX file. Results of the JSX to JavaScript transformation are cached. - /// - /// Name of the file to load - /// File contents - [Obsolete("Use JsxTransformer.TransformJsxFile")] - public string LoadJsxFile(string filename) - { - return JsxTransformer.TransformJsxFile(filename); - } - - /// - /// Transforms JSX into regular JavaScript. The result is not cached. Use - /// if loading from a file since this will cache the result. - /// - /// JSX - /// JavaScript - [Obsolete("Use JsxTransformer.TransformJsx")] - public string TransformJsx(string input) - { - return JsxTransformer.TransformJsx(input); - } - - /// - /// Attempts to execute the provided JavaScript code using the current engine. If an - /// exception is thrown, retries the execution using a new thread (and hence a new engine) - /// with a larger maximum stack size. - /// This is required because JSXTransformer uses a huge stack which ends up being larger - /// than what ASP.NET allows by default (256 KB). - /// - /// Type to return from JavaScript call - /// JavaScript function to execute - /// Arguments to pass to function - /// Result returned from JavaScript code - public T ExecuteWithLargerStackIfRequired(string function, params object[] args) - { - try - { - return Engine.CallFunction(function, args); - } - catch (Exception) - { - // Assume the exception MAY be an "out of stack space" error. Try running the code - // in a different thread with larger stack. If the same exception occurs, we know - // it wasn't a stack space issue. - T result = default(T); - Exception innerEx = null; - var thread = new Thread(() => - { - try - { - // New engine will be created here (as this is a new thread) - result = Engine.CallFunction(function, args); - } - catch (Exception threadEx) - { - // Unhandled exceptions in threads kill the whole process. - // Pass the exception back to the parent thread to rethrow. - innerEx = threadEx; - } - finally - { - _engineFactory.DisposeEngineForCurrentThread(); - } - }, LARGE_STACK_SIZE); - thread.Start(); - thread.Join(); - // Rethrow any exceptions that occured in the thread - if (innerEx != null) - { - throw innerEx; - } - return result; - } - } - - /// - /// Gets the ReactJS.NET version number. Use instead. - /// - private static string GetVersion() - { - var assembly = Assembly.GetExecutingAssembly(); - var rawVersion = FileVersionInfo.GetVersionInfo(assembly.Location).FileVersion; - var lastDot = rawVersion.LastIndexOf('.'); - var version = rawVersion.Substring(0, lastDot); - var build = rawVersion.Substring(lastDot + 1); - return string.Format("{0} (build {1})", version, build); - } - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - public void Dispose() - { - _engineFactory.DisposeEngineForCurrentThread(); - } - } -} diff --git a/src/React/ReactSiteConfiguration.cs b/src/React/ReactSiteConfiguration.cs deleted file mode 100644 index 9ed0ea128..000000000 --- a/src/React/ReactSiteConfiguration.cs +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ - -using System.Collections.Generic; -using System.Collections.ObjectModel; - -namespace React -{ - /// - /// Site-wide configuration for ReactJS.NET - /// - public class ReactSiteConfiguration : IReactSiteConfiguration - { - /// - /// Gets or sets the site-side configuration - /// - public static IReactSiteConfiguration Configuration { get; set; } - - static ReactSiteConfiguration() - { - Configuration = new ReactSiteConfiguration(); - } - - /// - /// All the scripts that have been added to this configuration - /// - private readonly IList _scriptFiles = new List(); - - /// - /// Adds a script to the list of scripts that are executed. This should be called for all - /// React components and their dependencies. - /// - /// - /// Name of the file to execute. Should be a server relative path starting with ~ (eg. - /// ~/Scripts/Awesome.js) - /// - /// This configuration, for chaining - public IReactSiteConfiguration AddScript(string filename) - { - _scriptFiles.Add(filename); - return this; - } - - /// - /// Gets a list of all the scripts that have been added to this configuration. - /// - public IList Scripts - { - get { return new ReadOnlyCollection(_scriptFiles); } - } - - /// - /// A value indicating if es6 syntax should be rewritten. - /// - /// true if support for es6 syntax should be rewritten. - public bool UseHarmony { get; set; } - - /// - /// Specifies whether ES6 (harmony) syntax should be transformed - /// - public IReactSiteConfiguration SetUseHarmony(bool useHarmony) - { - UseHarmony = useHarmony; - return this; - } - } -} diff --git a/src/React/Resources/JSXTransformer.js b/src/React/Resources/JSXTransformer.js deleted file mode 100644 index 7aad3782a..000000000 --- a/src/React/Resources/JSXTransformer.js +++ /dev/null @@ -1,13446 +0,0 @@ -/** - * JSXTransformer v0.11.1 - */ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.JSXTransformer=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o - * @license MIT - */ - -var base64 = _dereq_('base64-js') -var ieee754 = _dereq_('ieee754') - -exports.Buffer = Buffer -exports.SlowBuffer = Buffer -exports.INSPECT_MAX_BYTES = 50 -Buffer.poolSize = 8192 - -/** - * If `Buffer._useTypedArrays`: - * === true Use Uint8Array implementation (fastest) - * === false Use Object implementation (compatible down to IE6) - */ -Buffer._useTypedArrays = (function () { - // Detect if browser supports Typed Arrays. Supported browsers are IE 10+, Firefox 4+, - // Chrome 7+, Safari 5.1+, Opera 11.6+, iOS 4.2+. If the browser does not support adding - // properties to `Uint8Array` instances, then that's the same as no `Uint8Array` support - // because we need to be able to add all the node Buffer API methods. This is an issue - // in Firefox 4-29. Now fixed: https://bugzilla.mozilla.org/show_bug.cgi?id=695438 - try { - var buf = new ArrayBuffer(0) - var arr = new Uint8Array(buf) - arr.foo = function () { return 42 } - return 42 === arr.foo() && - typeof arr.subarray === 'function' // Chrome 9-10 lack `subarray` - } catch (e) { - return false - } -})() - -/** - * Class: Buffer - * ============= - * - * The Buffer constructor returns instances of `Uint8Array` that are augmented - * with function properties for all the node `Buffer` API functions. We use - * `Uint8Array` so that square bracket notation works as expected -- it returns - * a single octet. - * - * By augmenting the instances, we can avoid modifying the `Uint8Array` - * prototype. - */ -function Buffer (subject, encoding, noZero) { - if (!(this instanceof Buffer)) - return new Buffer(subject, encoding, noZero) - - var type = typeof subject - - // Find the length - var length - if (type === 'number') - length = subject > 0 ? subject >>> 0 : 0 - else if (type === 'string') { - if (encoding === 'base64') - subject = base64clean(subject) - length = Buffer.byteLength(subject, encoding) - } else if (type === 'object' && subject !== null) { // assume object is array-like - if (subject.type === 'Buffer' && Array.isArray(subject.data)) - subject = subject.data - length = +subject.length > 0 ? Math.floor(+subject.length) : 0 - } else - throw new Error('First argument needs to be a number, array or string.') - - var buf - if (Buffer._useTypedArrays) { - // Preferred: Return an augmented `Uint8Array` instance for best performance - buf = Buffer._augment(new Uint8Array(length)) - } else { - // Fallback: Return THIS instance of Buffer (created by `new`) - buf = this - buf.length = length - buf._isBuffer = true - } - - var i - if (Buffer._useTypedArrays && typeof subject.byteLength === 'number') { - // Speed optimization -- use set if we're copying from a typed array - buf._set(subject) - } else if (isArrayish(subject)) { - // Treat array-ish objects as a byte array - if (Buffer.isBuffer(subject)) { - for (i = 0; i < length; i++) - buf[i] = subject.readUInt8(i) - } else { - for (i = 0; i < length; i++) - buf[i] = ((subject[i] % 256) + 256) % 256 - } - } else if (type === 'string') { - buf.write(subject, 0, encoding) - } else if (type === 'number' && !Buffer._useTypedArrays && !noZero) { - for (i = 0; i < length; i++) { - buf[i] = 0 - } - } - - return buf -} - -// STATIC METHODS -// ============== - -Buffer.isEncoding = function (encoding) { - switch (String(encoding).toLowerCase()) { - case 'hex': - case 'utf8': - case 'utf-8': - case 'ascii': - case 'binary': - case 'base64': - case 'raw': - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - return true - default: - return false - } -} - -Buffer.isBuffer = function (b) { - return !!(b != null && b._isBuffer) -} - -Buffer.byteLength = function (str, encoding) { - var ret - str = str.toString() - switch (encoding || 'utf8') { - case 'hex': - ret = str.length / 2 - break - case 'utf8': - case 'utf-8': - ret = utf8ToBytes(str).length - break - case 'ascii': - case 'binary': - case 'raw': - ret = str.length - break - case 'base64': - ret = base64ToBytes(str).length - break - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - ret = str.length * 2 - break - default: - throw new Error('Unknown encoding') - } - return ret -} - -Buffer.concat = function (list, totalLength) { - assert(isArray(list), 'Usage: Buffer.concat(list[, length])') - - if (list.length === 0) { - return new Buffer(0) - } else if (list.length === 1) { - return list[0] - } - - var i - if (totalLength === undefined) { - totalLength = 0 - for (i = 0; i < list.length; i++) { - totalLength += list[i].length - } - } - - var buf = new Buffer(totalLength) - var pos = 0 - for (i = 0; i < list.length; i++) { - var item = list[i] - item.copy(buf, pos) - pos += item.length - } - return buf -} - -Buffer.compare = function (a, b) { - assert(Buffer.isBuffer(a) && Buffer.isBuffer(b), 'Arguments must be Buffers') - var x = a.length - var y = b.length - for (var i = 0, len = Math.min(x, y); i < len && a[i] === b[i]; i++) {} - if (i !== len) { - x = a[i] - y = b[i] - } - if (x < y) { - return -1 - } - if (y < x) { - return 1 - } - return 0 -} - -// BUFFER INSTANCE METHODS -// ======================= - -function hexWrite (buf, string, offset, length) { - offset = Number(offset) || 0 - var remaining = buf.length - offset - if (!length) { - length = remaining - } else { - length = Number(length) - if (length > remaining) { - length = remaining - } - } - - // must be an even number of digits - var strLen = string.length - assert(strLen % 2 === 0, 'Invalid hex string') - - if (length > strLen / 2) { - length = strLen / 2 - } - for (var i = 0; i < length; i++) { - var byte = parseInt(string.substr(i * 2, 2), 16) - assert(!isNaN(byte), 'Invalid hex string') - buf[offset + i] = byte - } - return i -} - -function utf8Write (buf, string, offset, length) { - var charsWritten = blitBuffer(utf8ToBytes(string), buf, offset, length) - return charsWritten -} - -function asciiWrite (buf, string, offset, length) { - var charsWritten = blitBuffer(asciiToBytes(string), buf, offset, length) - return charsWritten -} - -function binaryWrite (buf, string, offset, length) { - return asciiWrite(buf, string, offset, length) -} - -function base64Write (buf, string, offset, length) { - var charsWritten = blitBuffer(base64ToBytes(string), buf, offset, length) - return charsWritten -} - -function utf16leWrite (buf, string, offset, length) { - var charsWritten = blitBuffer(utf16leToBytes(string), buf, offset, length) - return charsWritten -} - -Buffer.prototype.write = function (string, offset, length, encoding) { - // Support both (string, offset, length, encoding) - // and the legacy (string, encoding, offset, length) - if (isFinite(offset)) { - if (!isFinite(length)) { - encoding = length - length = undefined - } - } else { // legacy - var swap = encoding - encoding = offset - offset = length - length = swap - } - - offset = Number(offset) || 0 - var remaining = this.length - offset - if (!length) { - length = remaining - } else { - length = Number(length) - if (length > remaining) { - length = remaining - } - } - encoding = String(encoding || 'utf8').toLowerCase() - - var ret - switch (encoding) { - case 'hex': - ret = hexWrite(this, string, offset, length) - break - case 'utf8': - case 'utf-8': - ret = utf8Write(this, string, offset, length) - break - case 'ascii': - ret = asciiWrite(this, string, offset, length) - break - case 'binary': - ret = binaryWrite(this, string, offset, length) - break - case 'base64': - ret = base64Write(this, string, offset, length) - break - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - ret = utf16leWrite(this, string, offset, length) - break - default: - throw new Error('Unknown encoding') - } - return ret -} - -Buffer.prototype.toString = function (encoding, start, end) { - var self = this - - encoding = String(encoding || 'utf8').toLowerCase() - start = Number(start) || 0 - end = (end === undefined) ? self.length : Number(end) - - // Fastpath empty strings - if (end === start) - return '' - - var ret - switch (encoding) { - case 'hex': - ret = hexSlice(self, start, end) - break - case 'utf8': - case 'utf-8': - ret = utf8Slice(self, start, end) - break - case 'ascii': - ret = asciiSlice(self, start, end) - break - case 'binary': - ret = binarySlice(self, start, end) - break - case 'base64': - ret = base64Slice(self, start, end) - break - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - ret = utf16leSlice(self, start, end) - break - default: - throw new Error('Unknown encoding') - } - return ret -} - -Buffer.prototype.toJSON = function () { - return { - type: 'Buffer', - data: Array.prototype.slice.call(this._arr || this, 0) - } -} - -Buffer.prototype.equals = function (b) { - assert(Buffer.isBuffer(b), 'Argument must be a Buffer') - return Buffer.compare(this, b) === 0 -} - -Buffer.prototype.compare = function (b) { - assert(Buffer.isBuffer(b), 'Argument must be a Buffer') - return Buffer.compare(this, b) -} - -// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) -Buffer.prototype.copy = function (target, target_start, start, end) { - var source = this - - if (!start) start = 0 - if (!end && end !== 0) end = this.length - if (!target_start) target_start = 0 - - // Copy 0 bytes; we're done - if (end === start) return - if (target.length === 0 || source.length === 0) return - - // Fatal error conditions - assert(end >= start, 'sourceEnd < sourceStart') - assert(target_start >= 0 && target_start < target.length, - 'targetStart out of bounds') - assert(start >= 0 && start < source.length, 'sourceStart out of bounds') - assert(end >= 0 && end <= source.length, 'sourceEnd out of bounds') - - // Are we oob? - if (end > this.length) - end = this.length - if (target.length - target_start < end - start) - end = target.length - target_start + start - - var len = end - start - - if (len < 100 || !Buffer._useTypedArrays) { - for (var i = 0; i < len; i++) { - target[i + target_start] = this[i + start] - } - } else { - target._set(this.subarray(start, start + len), target_start) - } -} - -function base64Slice (buf, start, end) { - if (start === 0 && end === buf.length) { - return base64.fromByteArray(buf) - } else { - return base64.fromByteArray(buf.slice(start, end)) - } -} - -function utf8Slice (buf, start, end) { - var res = '' - var tmp = '' - end = Math.min(buf.length, end) - - for (var i = start; i < end; i++) { - if (buf[i] <= 0x7F) { - res += decodeUtf8Char(tmp) + String.fromCharCode(buf[i]) - tmp = '' - } else { - tmp += '%' + buf[i].toString(16) - } - } - - return res + decodeUtf8Char(tmp) -} - -function asciiSlice (buf, start, end) { - var ret = '' - end = Math.min(buf.length, end) - - for (var i = start; i < end; i++) { - ret += String.fromCharCode(buf[i]) - } - return ret -} - -function binarySlice (buf, start, end) { - return asciiSlice(buf, start, end) -} - -function hexSlice (buf, start, end) { - var len = buf.length - - if (!start || start < 0) start = 0 - if (!end || end < 0 || end > len) end = len - - var out = '' - for (var i = start; i < end; i++) { - out += toHex(buf[i]) - } - return out -} - -function utf16leSlice (buf, start, end) { - var bytes = buf.slice(start, end) - var res = '' - for (var i = 0; i < bytes.length; i += 2) { - res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256) - } - return res -} - -Buffer.prototype.slice = function (start, end) { - var len = this.length - start = ~~start - end = end === undefined ? len : ~~end - - if (start < 0) { - start += len; - if (start < 0) - start = 0 - } else if (start > len) { - start = len - } - - if (end < 0) { - end += len - if (end < 0) - end = 0 - } else if (end > len) { - end = len - } - - if (end < start) - end = start - - if (Buffer._useTypedArrays) { - return Buffer._augment(this.subarray(start, end)) - } else { - var sliceLen = end - start - var newBuf = new Buffer(sliceLen, undefined, true) - for (var i = 0; i < sliceLen; i++) { - newBuf[i] = this[i + start] - } - return newBuf - } -} - -// `get` will be removed in Node 0.13+ -Buffer.prototype.get = function (offset) { - console.log('.get() is deprecated. Access using array indexes instead.') - return this.readUInt8(offset) -} - -// `set` will be removed in Node 0.13+ -Buffer.prototype.set = function (v, offset) { - console.log('.set() is deprecated. Access using array indexes instead.') - return this.writeUInt8(v, offset) -} - -Buffer.prototype.readUInt8 = function (offset, noAssert) { - if (!noAssert) { - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset < this.length, 'Trying to read beyond buffer length') - } - - if (offset >= this.length) - return - - return this[offset] -} - -function readUInt16 (buf, offset, littleEndian, noAssert) { - if (!noAssert) { - assert(typeof littleEndian === 'boolean', 'missing or invalid endian') - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset + 1 < buf.length, 'Trying to read beyond buffer length') - } - - var len = buf.length - if (offset >= len) - return - - var val - if (littleEndian) { - val = buf[offset] - if (offset + 1 < len) - val |= buf[offset + 1] << 8 - } else { - val = buf[offset] << 8 - if (offset + 1 < len) - val |= buf[offset + 1] - } - return val -} - -Buffer.prototype.readUInt16LE = function (offset, noAssert) { - return readUInt16(this, offset, true, noAssert) -} - -Buffer.prototype.readUInt16BE = function (offset, noAssert) { - return readUInt16(this, offset, false, noAssert) -} - -function readUInt32 (buf, offset, littleEndian, noAssert) { - if (!noAssert) { - assert(typeof littleEndian === 'boolean', 'missing or invalid endian') - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset + 3 < buf.length, 'Trying to read beyond buffer length') - } - - var len = buf.length - if (offset >= len) - return - - var val - if (littleEndian) { - if (offset + 2 < len) - val = buf[offset + 2] << 16 - if (offset + 1 < len) - val |= buf[offset + 1] << 8 - val |= buf[offset] - if (offset + 3 < len) - val = val + (buf[offset + 3] << 24 >>> 0) - } else { - if (offset + 1 < len) - val = buf[offset + 1] << 16 - if (offset + 2 < len) - val |= buf[offset + 2] << 8 - if (offset + 3 < len) - val |= buf[offset + 3] - val = val + (buf[offset] << 24 >>> 0) - } - return val -} - -Buffer.prototype.readUInt32LE = function (offset, noAssert) { - return readUInt32(this, offset, true, noAssert) -} - -Buffer.prototype.readUInt32BE = function (offset, noAssert) { - return readUInt32(this, offset, false, noAssert) -} - -Buffer.prototype.readInt8 = function (offset, noAssert) { - if (!noAssert) { - assert(offset !== undefined && offset !== null, - 'missing offset') - assert(offset < this.length, 'Trying to read beyond buffer length') - } - - if (offset >= this.length) - return - - var neg = this[offset] & 0x80 - if (neg) - return (0xff - this[offset] + 1) * -1 - else - return this[offset] -} - -function readInt16 (buf, offset, littleEndian, noAssert) { - if (!noAssert) { - assert(typeof littleEndian === 'boolean', 'missing or invalid endian') - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset + 1 < buf.length, 'Trying to read beyond buffer length') - } - - var len = buf.length - if (offset >= len) - return - - var val = readUInt16(buf, offset, littleEndian, true) - var neg = val & 0x8000 - if (neg) - return (0xffff - val + 1) * -1 - else - return val -} - -Buffer.prototype.readInt16LE = function (offset, noAssert) { - return readInt16(this, offset, true, noAssert) -} - -Buffer.prototype.readInt16BE = function (offset, noAssert) { - return readInt16(this, offset, false, noAssert) -} - -function readInt32 (buf, offset, littleEndian, noAssert) { - if (!noAssert) { - assert(typeof littleEndian === 'boolean', 'missing or invalid endian') - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset + 3 < buf.length, 'Trying to read beyond buffer length') - } - - var len = buf.length - if (offset >= len) - return - - var val = readUInt32(buf, offset, littleEndian, true) - var neg = val & 0x80000000 - if (neg) - return (0xffffffff - val + 1) * -1 - else - return val -} - -Buffer.prototype.readInt32LE = function (offset, noAssert) { - return readInt32(this, offset, true, noAssert) -} - -Buffer.prototype.readInt32BE = function (offset, noAssert) { - return readInt32(this, offset, false, noAssert) -} - -function readFloat (buf, offset, littleEndian, noAssert) { - if (!noAssert) { - assert(typeof littleEndian === 'boolean', 'missing or invalid endian') - assert(offset + 3 < buf.length, 'Trying to read beyond buffer length') - } - - return ieee754.read(buf, offset, littleEndian, 23, 4) -} - -Buffer.prototype.readFloatLE = function (offset, noAssert) { - return readFloat(this, offset, true, noAssert) -} - -Buffer.prototype.readFloatBE = function (offset, noAssert) { - return readFloat(this, offset, false, noAssert) -} - -function readDouble (buf, offset, littleEndian, noAssert) { - if (!noAssert) { - assert(typeof littleEndian === 'boolean', 'missing or invalid endian') - assert(offset + 7 < buf.length, 'Trying to read beyond buffer length') - } - - return ieee754.read(buf, offset, littleEndian, 52, 8) -} - -Buffer.prototype.readDoubleLE = function (offset, noAssert) { - return readDouble(this, offset, true, noAssert) -} - -Buffer.prototype.readDoubleBE = function (offset, noAssert) { - return readDouble(this, offset, false, noAssert) -} - -Buffer.prototype.writeUInt8 = function (value, offset, noAssert) { - if (!noAssert) { - assert(value !== undefined && value !== null, 'missing value') - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset < this.length, 'trying to write beyond buffer length') - verifuint(value, 0xff) - } - - if (offset >= this.length) return - - this[offset] = value - return offset + 1 -} - -function writeUInt16 (buf, value, offset, littleEndian, noAssert) { - if (!noAssert) { - assert(value !== undefined && value !== null, 'missing value') - assert(typeof littleEndian === 'boolean', 'missing or invalid endian') - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset + 1 < buf.length, 'trying to write beyond buffer length') - verifuint(value, 0xffff) - } - - var len = buf.length - if (offset >= len) - return - - for (var i = 0, j = Math.min(len - offset, 2); i < j; i++) { - buf[offset + i] = - (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> - (littleEndian ? i : 1 - i) * 8 - } - return offset + 2 -} - -Buffer.prototype.writeUInt16LE = function (value, offset, noAssert) { - return writeUInt16(this, value, offset, true, noAssert) -} - -Buffer.prototype.writeUInt16BE = function (value, offset, noAssert) { - return writeUInt16(this, value, offset, false, noAssert) -} - -function writeUInt32 (buf, value, offset, littleEndian, noAssert) { - if (!noAssert) { - assert(value !== undefined && value !== null, 'missing value') - assert(typeof littleEndian === 'boolean', 'missing or invalid endian') - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset + 3 < buf.length, 'trying to write beyond buffer length') - verifuint(value, 0xffffffff) - } - - var len = buf.length - if (offset >= len) - return - - for (var i = 0, j = Math.min(len - offset, 4); i < j; i++) { - buf[offset + i] = - (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff - } - return offset + 4 -} - -Buffer.prototype.writeUInt32LE = function (value, offset, noAssert) { - return writeUInt32(this, value, offset, true, noAssert) -} - -Buffer.prototype.writeUInt32BE = function (value, offset, noAssert) { - return writeUInt32(this, value, offset, false, noAssert) -} - -Buffer.prototype.writeInt8 = function (value, offset, noAssert) { - if (!noAssert) { - assert(value !== undefined && value !== null, 'missing value') - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset < this.length, 'Trying to write beyond buffer length') - verifsint(value, 0x7f, -0x80) - } - - if (offset >= this.length) - return - - if (value >= 0) - this.writeUInt8(value, offset, noAssert) - else - this.writeUInt8(0xff + value + 1, offset, noAssert) - return offset + 1 -} - -function writeInt16 (buf, value, offset, littleEndian, noAssert) { - if (!noAssert) { - assert(value !== undefined && value !== null, 'missing value') - assert(typeof littleEndian === 'boolean', 'missing or invalid endian') - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset + 1 < buf.length, 'Trying to write beyond buffer length') - verifsint(value, 0x7fff, -0x8000) - } - - var len = buf.length - if (offset >= len) - return - - if (value >= 0) - writeUInt16(buf, value, offset, littleEndian, noAssert) - else - writeUInt16(buf, 0xffff + value + 1, offset, littleEndian, noAssert) - return offset + 2 -} - -Buffer.prototype.writeInt16LE = function (value, offset, noAssert) { - return writeInt16(this, value, offset, true, noAssert) -} - -Buffer.prototype.writeInt16BE = function (value, offset, noAssert) { - return writeInt16(this, value, offset, false, noAssert) -} - -function writeInt32 (buf, value, offset, littleEndian, noAssert) { - if (!noAssert) { - assert(value !== undefined && value !== null, 'missing value') - assert(typeof littleEndian === 'boolean', 'missing or invalid endian') - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset + 3 < buf.length, 'Trying to write beyond buffer length') - verifsint(value, 0x7fffffff, -0x80000000) - } - - var len = buf.length - if (offset >= len) - return - - if (value >= 0) - writeUInt32(buf, value, offset, littleEndian, noAssert) - else - writeUInt32(buf, 0xffffffff + value + 1, offset, littleEndian, noAssert) - return offset + 4 -} - -Buffer.prototype.writeInt32LE = function (value, offset, noAssert) { - return writeInt32(this, value, offset, true, noAssert) -} - -Buffer.prototype.writeInt32BE = function (value, offset, noAssert) { - return writeInt32(this, value, offset, false, noAssert) -} - -function writeFloat (buf, value, offset, littleEndian, noAssert) { - if (!noAssert) { - assert(value !== undefined && value !== null, 'missing value') - assert(typeof littleEndian === 'boolean', 'missing or invalid endian') - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset + 3 < buf.length, 'Trying to write beyond buffer length') - verifIEEE754(value, 3.4028234663852886e+38, -3.4028234663852886e+38) - } - - var len = buf.length - if (offset >= len) - return - - ieee754.write(buf, value, offset, littleEndian, 23, 4) - return offset + 4 -} - -Buffer.prototype.writeFloatLE = function (value, offset, noAssert) { - return writeFloat(this, value, offset, true, noAssert) -} - -Buffer.prototype.writeFloatBE = function (value, offset, noAssert) { - return writeFloat(this, value, offset, false, noAssert) -} - -function writeDouble (buf, value, offset, littleEndian, noAssert) { - if (!noAssert) { - assert(value !== undefined && value !== null, 'missing value') - assert(typeof littleEndian === 'boolean', 'missing or invalid endian') - assert(offset !== undefined && offset !== null, 'missing offset') - assert(offset + 7 < buf.length, - 'Trying to write beyond buffer length') - verifIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308) - } - - var len = buf.length - if (offset >= len) - return - - ieee754.write(buf, value, offset, littleEndian, 52, 8) - return offset + 8 -} - -Buffer.prototype.writeDoubleLE = function (value, offset, noAssert) { - return writeDouble(this, value, offset, true, noAssert) -} - -Buffer.prototype.writeDoubleBE = function (value, offset, noAssert) { - return writeDouble(this, value, offset, false, noAssert) -} - -// fill(value, start=0, end=buffer.length) -Buffer.prototype.fill = function (value, start, end) { - if (!value) value = 0 - if (!start) start = 0 - if (!end) end = this.length - - assert(end >= start, 'end < start') - - // Fill 0 bytes; we're done - if (end === start) return - if (this.length === 0) return - - assert(start >= 0 && start < this.length, 'start out of bounds') - assert(end >= 0 && end <= this.length, 'end out of bounds') - - var i - if (typeof value === 'number') { - for (i = start; i < end; i++) { - this[i] = value - } - } else { - var bytes = utf8ToBytes(value.toString()) - var len = bytes.length - for (i = start; i < end; i++) { - this[i] = bytes[i % len] - } - } - - return this -} - -Buffer.prototype.inspect = function () { - var out = [] - var len = this.length - for (var i = 0; i < len; i++) { - out[i] = toHex(this[i]) - if (i === exports.INSPECT_MAX_BYTES) { - out[i + 1] = '...' - break - } - } - return '' -} - -/** - * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance. - * Added in Node 0.12. Only available in browsers that support ArrayBuffer. - */ -Buffer.prototype.toArrayBuffer = function () { - if (typeof Uint8Array !== 'undefined') { - if (Buffer._useTypedArrays) { - return (new Buffer(this)).buffer - } else { - var buf = new Uint8Array(this.length) - for (var i = 0, len = buf.length; i < len; i += 1) { - buf[i] = this[i] - } - return buf.buffer - } - } else { - throw new Error('Buffer.toArrayBuffer not supported in this browser') - } -} - -// HELPER FUNCTIONS -// ================ - -var BP = Buffer.prototype - -/** - * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods - */ -Buffer._augment = function (arr) { - arr._isBuffer = true - - // save reference to original Uint8Array get/set methods before overwriting - arr._get = arr.get - arr._set = arr.set - - // deprecated, will be removed in node 0.13+ - arr.get = BP.get - arr.set = BP.set - - arr.write = BP.write - arr.toString = BP.toString - arr.toLocaleString = BP.toString - arr.toJSON = BP.toJSON - arr.equals = BP.equals - arr.compare = BP.compare - arr.copy = BP.copy - arr.slice = BP.slice - arr.readUInt8 = BP.readUInt8 - arr.readUInt16LE = BP.readUInt16LE - arr.readUInt16BE = BP.readUInt16BE - arr.readUInt32LE = BP.readUInt32LE - arr.readUInt32BE = BP.readUInt32BE - arr.readInt8 = BP.readInt8 - arr.readInt16LE = BP.readInt16LE - arr.readInt16BE = BP.readInt16BE - arr.readInt32LE = BP.readInt32LE - arr.readInt32BE = BP.readInt32BE - arr.readFloatLE = BP.readFloatLE - arr.readFloatBE = BP.readFloatBE - arr.readDoubleLE = BP.readDoubleLE - arr.readDoubleBE = BP.readDoubleBE - arr.writeUInt8 = BP.writeUInt8 - arr.writeUInt16LE = BP.writeUInt16LE - arr.writeUInt16BE = BP.writeUInt16BE - arr.writeUInt32LE = BP.writeUInt32LE - arr.writeUInt32BE = BP.writeUInt32BE - arr.writeInt8 = BP.writeInt8 - arr.writeInt16LE = BP.writeInt16LE - arr.writeInt16BE = BP.writeInt16BE - arr.writeInt32LE = BP.writeInt32LE - arr.writeInt32BE = BP.writeInt32BE - arr.writeFloatLE = BP.writeFloatLE - arr.writeFloatBE = BP.writeFloatBE - arr.writeDoubleLE = BP.writeDoubleLE - arr.writeDoubleBE = BP.writeDoubleBE - arr.fill = BP.fill - arr.inspect = BP.inspect - arr.toArrayBuffer = BP.toArrayBuffer - - return arr -} - -var INVALID_BASE64_RE = /[^+\/0-9A-z]/g - -function base64clean (str) { - // Node strips out invalid characters like \n and \t from the string, base64-js does not - str = stringtrim(str).replace(INVALID_BASE64_RE, '') - // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not - while (str.length % 4 !== 0) { - str = str + '=' - } - return str -} - -function stringtrim (str) { - if (str.trim) return str.trim() - return str.replace(/^\s+|\s+$/g, '') -} - -function isArray (subject) { - return (Array.isArray || function (subject) { - return Object.prototype.toString.call(subject) === '[object Array]' - })(subject) -} - -function isArrayish (subject) { - return isArray(subject) || Buffer.isBuffer(subject) || - subject && typeof subject === 'object' && - typeof subject.length === 'number' -} - -function toHex (n) { - if (n < 16) return '0' + n.toString(16) - return n.toString(16) -} - -function utf8ToBytes (str) { - var byteArray = [] - for (var i = 0; i < str.length; i++) { - var b = str.charCodeAt(i) - if (b <= 0x7F) { - byteArray.push(b) - } else { - var start = i - if (b >= 0xD800 && b <= 0xDFFF) i++ - var h = encodeURIComponent(str.slice(start, i+1)).substr(1).split('%') - for (var j = 0; j < h.length; j++) { - byteArray.push(parseInt(h[j], 16)) - } - } - } - return byteArray -} - -function asciiToBytes (str) { - var byteArray = [] - for (var i = 0; i < str.length; i++) { - // Node's code seems to be doing this and not & 0x7F.. - byteArray.push(str.charCodeAt(i) & 0xFF) - } - return byteArray -} - -function utf16leToBytes (str) { - var c, hi, lo - var byteArray = [] - for (var i = 0; i < str.length; i++) { - c = str.charCodeAt(i) - hi = c >> 8 - lo = c % 256 - byteArray.push(lo) - byteArray.push(hi) - } - - return byteArray -} - -function base64ToBytes (str) { - return base64.toByteArray(str) -} - -function blitBuffer (src, dst, offset, length) { - for (var i = 0; i < length; i++) { - if ((i + offset >= dst.length) || (i >= src.length)) - break - dst[i + offset] = src[i] - } - return i -} - -function decodeUtf8Char (str) { - try { - return decodeURIComponent(str) - } catch (err) { - return String.fromCharCode(0xFFFD) // UTF 8 invalid char - } -} - -/* - * We have to make sure that the value is a valid integer. This means that it - * is non-negative. It has no fractional component and that it does not - * exceed the maximum allowed value. - */ -function verifuint (value, max) { - assert(typeof value === 'number', 'cannot write a non-number as a number') - assert(value >= 0, 'specified a negative value for writing an unsigned value') - assert(value <= max, 'value is larger than maximum value for type') - assert(Math.floor(value) === value, 'value has a fractional component') -} - -function verifsint (value, max, min) { - assert(typeof value === 'number', 'cannot write a non-number as a number') - assert(value <= max, 'value larger than maximum allowed value') - assert(value >= min, 'value smaller than minimum allowed value') - assert(Math.floor(value) === value, 'value has a fractional component') -} - -function verifIEEE754 (value, max, min) { - assert(typeof value === 'number', 'cannot write a non-number as a number') - assert(value <= max, 'value larger than maximum allowed value') - assert(value >= min, 'value smaller than minimum allowed value') -} - -function assert (test, message) { - if (!test) throw new Error(message || 'Failed assertion') -} - -},{"base64-js":2,"ieee754":3}],2:[function(_dereq_,module,exports){ -var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; - -;(function (exports) { - 'use strict'; - - var Arr = (typeof Uint8Array !== 'undefined') - ? Uint8Array - : Array - - var PLUS = '+'.charCodeAt(0) - var SLASH = '/'.charCodeAt(0) - var NUMBER = '0'.charCodeAt(0) - var LOWER = 'a'.charCodeAt(0) - var UPPER = 'A'.charCodeAt(0) - - function decode (elt) { - var code = elt.charCodeAt(0) - if (code === PLUS) - return 62 // '+' - if (code === SLASH) - return 63 // '/' - if (code < NUMBER) - return -1 //no match - if (code < NUMBER + 10) - return code - NUMBER + 26 + 26 - if (code < UPPER + 26) - return code - UPPER - if (code < LOWER + 26) - return code - LOWER + 26 - } - - function b64ToByteArray (b64) { - var i, j, l, tmp, placeHolders, arr - - if (b64.length % 4 > 0) { - throw new Error('Invalid string. Length must be a multiple of 4') - } - - // the number of equal signs (place holders) - // if there are two placeholders, than the two characters before it - // represent one byte - // if there is only one, then the three characters before it represent 2 bytes - // this is just a cheap hack to not do indexOf twice - var len = b64.length - placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0 - - // base64 is 4/3 + up to two characters of the original data - arr = new Arr(b64.length * 3 / 4 - placeHolders) - - // if there are placeholders, only get up to the last complete 4 chars - l = placeHolders > 0 ? b64.length - 4 : b64.length - - var L = 0 - - function push (v) { - arr[L++] = v - } - - for (i = 0, j = 0; i < l; i += 4, j += 3) { - tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3)) - push((tmp & 0xFF0000) >> 16) - push((tmp & 0xFF00) >> 8) - push(tmp & 0xFF) - } - - if (placeHolders === 2) { - tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4) - push(tmp & 0xFF) - } else if (placeHolders === 1) { - tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2) - push((tmp >> 8) & 0xFF) - push(tmp & 0xFF) - } - - return arr - } - - function uint8ToBase64 (uint8) { - var i, - extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes - output = "", - temp, length - - function encode (num) { - return lookup.charAt(num) - } - - function tripletToBase64 (num) { - return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F) - } - - // go through the array every three bytes, we'll deal with trailing stuff later - for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) { - temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) - output += tripletToBase64(temp) - } - - // pad the end with zeros, but make sure to not forget the extra bytes - switch (extraBytes) { - case 1: - temp = uint8[uint8.length - 1] - output += encode(temp >> 2) - output += encode((temp << 4) & 0x3F) - output += '==' - break - case 2: - temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]) - output += encode(temp >> 10) - output += encode((temp >> 4) & 0x3F) - output += encode((temp << 2) & 0x3F) - output += '=' - break - } - - return output - } - - exports.toByteArray = b64ToByteArray - exports.fromByteArray = uint8ToBase64 -}(typeof exports === 'undefined' ? (this.base64js = {}) : exports)) - -},{}],3:[function(_dereq_,module,exports){ -exports.read = function(buffer, offset, isLE, mLen, nBytes) { - var e, m, - eLen = nBytes * 8 - mLen - 1, - eMax = (1 << eLen) - 1, - eBias = eMax >> 1, - nBits = -7, - i = isLE ? (nBytes - 1) : 0, - d = isLE ? -1 : 1, - s = buffer[offset + i]; - - i += d; - - e = s & ((1 << (-nBits)) - 1); - s >>= (-nBits); - nBits += eLen; - for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8); - - m = e & ((1 << (-nBits)) - 1); - e >>= (-nBits); - nBits += mLen; - for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8); - - if (e === 0) { - e = 1 - eBias; - } else if (e === eMax) { - return m ? NaN : ((s ? -1 : 1) * Infinity); - } else { - m = m + Math.pow(2, mLen); - e = e - eBias; - } - return (s ? -1 : 1) * m * Math.pow(2, e - mLen); -}; - -exports.write = function(buffer, value, offset, isLE, mLen, nBytes) { - var e, m, c, - eLen = nBytes * 8 - mLen - 1, - eMax = (1 << eLen) - 1, - eBias = eMax >> 1, - rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0), - i = isLE ? 0 : (nBytes - 1), - d = isLE ? 1 : -1, - s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; - - value = Math.abs(value); - - if (isNaN(value) || value === Infinity) { - m = isNaN(value) ? 1 : 0; - e = eMax; - } else { - e = Math.floor(Math.log(value) / Math.LN2); - if (value * (c = Math.pow(2, -e)) < 1) { - e--; - c *= 2; - } - if (e + eBias >= 1) { - value += rt / c; - } else { - value += rt * Math.pow(2, 1 - eBias); - } - if (value * c >= 2) { - e++; - c /= 2; - } - - if (e + eBias >= eMax) { - m = 0; - e = eMax; - } else if (e + eBias >= 1) { - m = (value * c - 1) * Math.pow(2, mLen); - e = e + eBias; - } else { - m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); - e = 0; - } - } - - for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8); - - e = (e << mLen) | m; - eLen += mLen; - for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8); - - buffer[offset + i - d] |= s * 128; -}; - -},{}],4:[function(_dereq_,module,exports){ -(function (process){ -// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. - -// resolves . and .. elements in a path array with directory names there -// must be no slashes, empty elements, or device names (c:\) in the array -// (so also no leading and trailing slashes - it does not distinguish -// relative and absolute paths) -function normalizeArray(parts, allowAboveRoot) { - // if the path tries to go above the root, `up` ends up > 0 - var up = 0; - for (var i = parts.length - 1; i >= 0; i--) { - var last = parts[i]; - if (last === '.') { - parts.splice(i, 1); - } else if (last === '..') { - parts.splice(i, 1); - up++; - } else if (up) { - parts.splice(i, 1); - up--; - } - } - - // if the path is allowed to go above the root, restore leading ..s - if (allowAboveRoot) { - for (; up--; up) { - parts.unshift('..'); - } - } - - return parts; -} - -// Split a filename into [root, dir, basename, ext], unix version -// 'root' is just a slash, or nothing. -var splitPathRe = - /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/; -var splitPath = function(filename) { - return splitPathRe.exec(filename).slice(1); -}; - -// path.resolve([from ...], to) -// posix version -exports.resolve = function() { - var resolvedPath = '', - resolvedAbsolute = false; - - for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) { - var path = (i >= 0) ? arguments[i] : process.cwd(); - - // Skip empty and invalid entries - if (typeof path !== 'string') { - throw new TypeError('Arguments to path.resolve must be strings'); - } else if (!path) { - continue; - } - - resolvedPath = path + '/' + resolvedPath; - resolvedAbsolute = path.charAt(0) === '/'; - } - - // At this point the path should be resolved to a full absolute path, but - // handle relative paths to be safe (might happen when process.cwd() fails) - - // Normalize the path - resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) { - return !!p; - }), !resolvedAbsolute).join('/'); - - return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.'; -}; - -// path.normalize(path) -// posix version -exports.normalize = function(path) { - var isAbsolute = exports.isAbsolute(path), - trailingSlash = substr(path, -1) === '/'; - - // Normalize the path - path = normalizeArray(filter(path.split('/'), function(p) { - return !!p; - }), !isAbsolute).join('/'); - - if (!path && !isAbsolute) { - path = '.'; - } - if (path && trailingSlash) { - path += '/'; - } - - return (isAbsolute ? '/' : '') + path; -}; - -// posix version -exports.isAbsolute = function(path) { - return path.charAt(0) === '/'; -}; - -// posix version -exports.join = function() { - var paths = Array.prototype.slice.call(arguments, 0); - return exports.normalize(filter(paths, function(p, index) { - if (typeof p !== 'string') { - throw new TypeError('Arguments to path.join must be strings'); - } - return p; - }).join('/')); -}; - - -// path.relative(from, to) -// posix version -exports.relative = function(from, to) { - from = exports.resolve(from).substr(1); - to = exports.resolve(to).substr(1); - - function trim(arr) { - var start = 0; - for (; start < arr.length; start++) { - if (arr[start] !== '') break; - } - - var end = arr.length - 1; - for (; end >= 0; end--) { - if (arr[end] !== '') break; - } - - if (start > end) return []; - return arr.slice(start, end - start + 1); - } - - var fromParts = trim(from.split('/')); - var toParts = trim(to.split('/')); - - var length = Math.min(fromParts.length, toParts.length); - var samePartsLength = length; - for (var i = 0; i < length; i++) { - if (fromParts[i] !== toParts[i]) { - samePartsLength = i; - break; - } - } - - var outputParts = []; - for (var i = samePartsLength; i < fromParts.length; i++) { - outputParts.push('..'); - } - - outputParts = outputParts.concat(toParts.slice(samePartsLength)); - - return outputParts.join('/'); -}; - -exports.sep = '/'; -exports.delimiter = ':'; - -exports.dirname = function(path) { - var result = splitPath(path), - root = result[0], - dir = result[1]; - - if (!root && !dir) { - // No dirname whatsoever - return '.'; - } - - if (dir) { - // It has a dirname, strip trailing slash - dir = dir.substr(0, dir.length - 1); - } - - return root + dir; -}; - - -exports.basename = function(path, ext) { - var f = splitPath(path)[2]; - // TODO: make this comparison case-insensitive on windows? - if (ext && f.substr(-1 * ext.length) === ext) { - f = f.substr(0, f.length - ext.length); - } - return f; -}; - - -exports.extname = function(path) { - return splitPath(path)[3]; -}; - -function filter (xs, f) { - if (xs.filter) return xs.filter(f); - var res = []; - for (var i = 0; i < xs.length; i++) { - if (f(xs[i], i, xs)) res.push(xs[i]); - } - return res; -} - -// String.prototype.substr - negative index don't work in IE8 -var substr = 'ab'.substr(-1) === 'b' - ? function (str, start, len) { return str.substr(start, len) } - : function (str, start, len) { - if (start < 0) start = str.length + start; - return str.substr(start, len); - } -; - -}).call(this,_dereq_("FWaASH")) -},{"FWaASH":5}],5:[function(_dereq_,module,exports){ -// shim for using process in browser - -var process = module.exports = {}; - -process.nextTick = (function () { - var canSetImmediate = typeof window !== 'undefined' - && window.setImmediate; - var canPost = typeof window !== 'undefined' - && window.postMessage && window.addEventListener - ; - - if (canSetImmediate) { - return function (f) { return window.setImmediate(f) }; - } - - if (canPost) { - var queue = []; - window.addEventListener('message', function (ev) { - var source = ev.source; - if ((source === window || source === null) && ev.data === 'process-tick') { - ev.stopPropagation(); - if (queue.length > 0) { - var fn = queue.shift(); - fn(); - } - } - }, true); - - return function nextTick(fn) { - queue.push(fn); - window.postMessage('process-tick', '*'); - }; - } - - return function nextTick(fn) { - setTimeout(fn, 0); - }; -})(); - -process.title = 'browser'; -process.browser = true; -process.env = {}; -process.argv = []; - -function noop() {} - -process.on = noop; -process.addListener = noop; -process.once = noop; -process.off = noop; -process.removeListener = noop; -process.removeAllListeners = noop; -process.emit = noop; - -process.binding = function (name) { - throw new Error('process.binding is not supported'); -} - -// TODO(shtylman) -process.cwd = function () { return '/' }; -process.chdir = function (dir) { - throw new Error('process.chdir is not supported'); -}; - -},{}],6:[function(_dereq_,module,exports){ -/* - Copyright (C) 2013 Ariya Hidayat - Copyright (C) 2013 Thaddee Tyl - Copyright (C) 2012 Ariya Hidayat - Copyright (C) 2012 Mathias Bynens - Copyright (C) 2012 Joost-Wim Boekesteijn - Copyright (C) 2012 Kris Kowal - Copyright (C) 2012 Yusuke Suzuki - Copyright (C) 2012 Arpad Borsos - Copyright (C) 2011 Ariya Hidayat - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/*jslint bitwise:true plusplus:true */ -/*global esprima:true, define:true, exports:true, window: true, -throwError: true, generateStatement: true, peek: true, -parseAssignmentExpression: true, parseBlock: true, -parseClassExpression: true, parseClassDeclaration: true, parseExpression: true, -parseForStatement: true, -parseFunctionDeclaration: true, parseFunctionExpression: true, -parseFunctionSourceElements: true, parseVariableIdentifier: true, -parseImportSpecifier: true, -parseLeftHandSideExpression: true, parseParams: true, validateParam: true, -parseSpreadOrAssignmentExpression: true, -parseStatement: true, parseSourceElement: true, parseModuleBlock: true, parseConciseBody: true, -advanceXJSChild: true, isXJSIdentifierStart: true, isXJSIdentifierPart: true, -scanXJSStringLiteral: true, scanXJSIdentifier: true, -parseXJSAttributeValue: true, parseXJSChild: true, parseXJSElement: true, parseXJSExpressionContainer: true, parseXJSEmptyExpression: true, -parseTypeAnnotation: true, parseTypeAnnotatableIdentifier: true, -parseYieldExpression: true -*/ - -(function (root, factory) { - 'use strict'; - - // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js, - // Rhino, and plain browser loading. - if (typeof define === 'function' && define.amd) { - define(['exports'], factory); - } else if (typeof exports !== 'undefined') { - factory(exports); - } else { - factory((root.esprima = {})); - } -}(this, function (exports) { - 'use strict'; - - var Token, - TokenName, - FnExprTokens, - Syntax, - PropertyKind, - Messages, - Regex, - SyntaxTreeDelegate, - XHTMLEntities, - ClassPropertyType, - source, - strict, - index, - lineNumber, - lineStart, - length, - delegate, - lookahead, - state, - extra; - - Token = { - BooleanLiteral: 1, - EOF: 2, - Identifier: 3, - Keyword: 4, - NullLiteral: 5, - NumericLiteral: 6, - Punctuator: 7, - StringLiteral: 8, - RegularExpression: 9, - Template: 10, - XJSIdentifier: 11, - XJSText: 12 - }; - - TokenName = {}; - TokenName[Token.BooleanLiteral] = 'Boolean'; - TokenName[Token.EOF] = ''; - TokenName[Token.Identifier] = 'Identifier'; - TokenName[Token.Keyword] = 'Keyword'; - TokenName[Token.NullLiteral] = 'Null'; - TokenName[Token.NumericLiteral] = 'Numeric'; - TokenName[Token.Punctuator] = 'Punctuator'; - TokenName[Token.StringLiteral] = 'String'; - TokenName[Token.XJSIdentifier] = 'XJSIdentifier'; - TokenName[Token.XJSText] = 'XJSText'; - TokenName[Token.RegularExpression] = 'RegularExpression'; - - // A function following one of those tokens is an expression. - FnExprTokens = ['(', '{', '[', 'in', 'typeof', 'instanceof', 'new', - 'return', 'case', 'delete', 'throw', 'void', - // assignment operators - '=', '+=', '-=', '*=', '/=', '%=', '<<=', '>>=', '>>>=', - '&=', '|=', '^=', ',', - // binary/unary operators - '+', '-', '*', '/', '%', '++', '--', '<<', '>>', '>>>', '&', - '|', '^', '!', '~', '&&', '||', '?', ':', '===', '==', '>=', - '<=', '<', '>', '!=', '!==']; - - Syntax = { - ArrayExpression: 'ArrayExpression', - ArrayPattern: 'ArrayPattern', - ArrowFunctionExpression: 'ArrowFunctionExpression', - AssignmentExpression: 'AssignmentExpression', - BinaryExpression: 'BinaryExpression', - BlockStatement: 'BlockStatement', - BreakStatement: 'BreakStatement', - CallExpression: 'CallExpression', - CatchClause: 'CatchClause', - ClassBody: 'ClassBody', - ClassDeclaration: 'ClassDeclaration', - ClassExpression: 'ClassExpression', - ClassProperty: 'ClassProperty', - ComprehensionBlock: 'ComprehensionBlock', - ComprehensionExpression: 'ComprehensionExpression', - ConditionalExpression: 'ConditionalExpression', - ContinueStatement: 'ContinueStatement', - DebuggerStatement: 'DebuggerStatement', - DoWhileStatement: 'DoWhileStatement', - EmptyStatement: 'EmptyStatement', - ExportDeclaration: 'ExportDeclaration', - ExportBatchSpecifier: 'ExportBatchSpecifier', - ExportSpecifier: 'ExportSpecifier', - ExpressionStatement: 'ExpressionStatement', - ForInStatement: 'ForInStatement', - ForOfStatement: 'ForOfStatement', - ForStatement: 'ForStatement', - FunctionDeclaration: 'FunctionDeclaration', - FunctionExpression: 'FunctionExpression', - Identifier: 'Identifier', - IfStatement: 'IfStatement', - ImportDeclaration: 'ImportDeclaration', - ImportSpecifier: 'ImportSpecifier', - LabeledStatement: 'LabeledStatement', - Literal: 'Literal', - LogicalExpression: 'LogicalExpression', - MemberExpression: 'MemberExpression', - MethodDefinition: 'MethodDefinition', - ModuleDeclaration: 'ModuleDeclaration', - NewExpression: 'NewExpression', - ObjectExpression: 'ObjectExpression', - ObjectPattern: 'ObjectPattern', - ObjectTypeAnnotation: 'ObjectTypeAnnotation', - OptionalParameter: 'OptionalParameter', - ParametricTypeAnnotation: 'ParametricTypeAnnotation', - ParametricallyTypedIdentifier: 'ParametricallyTypedIdentifier', - Program: 'Program', - Property: 'Property', - ReturnStatement: 'ReturnStatement', - SequenceExpression: 'SequenceExpression', - SpreadElement: 'SpreadElement', - SpreadProperty: 'SpreadProperty', - SwitchCase: 'SwitchCase', - SwitchStatement: 'SwitchStatement', - TaggedTemplateExpression: 'TaggedTemplateExpression', - TemplateElement: 'TemplateElement', - TemplateLiteral: 'TemplateLiteral', - ThisExpression: 'ThisExpression', - ThrowStatement: 'ThrowStatement', - TryStatement: 'TryStatement', - TypeAnnotatedIdentifier: 'TypeAnnotatedIdentifier', - TypeAnnotation: 'TypeAnnotation', - UnaryExpression: 'UnaryExpression', - UpdateExpression: 'UpdateExpression', - VariableDeclaration: 'VariableDeclaration', - VariableDeclarator: 'VariableDeclarator', - VoidTypeAnnotation: 'VoidTypeAnnotation', - WhileStatement: 'WhileStatement', - WithStatement: 'WithStatement', - XJSIdentifier: 'XJSIdentifier', - XJSNamespacedName: 'XJSNamespacedName', - XJSMemberExpression: 'XJSMemberExpression', - XJSEmptyExpression: 'XJSEmptyExpression', - XJSExpressionContainer: 'XJSExpressionContainer', - XJSElement: 'XJSElement', - XJSClosingElement: 'XJSClosingElement', - XJSOpeningElement: 'XJSOpeningElement', - XJSAttribute: 'XJSAttribute', - XJSSpreadAttribute: 'XJSSpreadAttribute', - XJSText: 'XJSText', - YieldExpression: 'YieldExpression' - }; - - PropertyKind = { - Data: 1, - Get: 2, - Set: 4 - }; - - ClassPropertyType = { - 'static': 'static', - prototype: 'prototype' - }; - - // Error messages should be identical to V8. - Messages = { - UnexpectedToken: 'Unexpected token %0', - UnexpectedNumber: 'Unexpected number', - UnexpectedString: 'Unexpected string', - UnexpectedIdentifier: 'Unexpected identifier', - UnexpectedReserved: 'Unexpected reserved word', - UnexpectedTemplate: 'Unexpected quasi %0', - UnexpectedEOS: 'Unexpected end of input', - NewlineAfterThrow: 'Illegal newline after throw', - InvalidRegExp: 'Invalid regular expression', - UnterminatedRegExp: 'Invalid regular expression: missing /', - InvalidLHSInAssignment: 'Invalid left-hand side in assignment', - InvalidLHSInFormalsList: 'Invalid left-hand side in formals list', - InvalidLHSInForIn: 'Invalid left-hand side in for-in', - MultipleDefaultsInSwitch: 'More than one default clause in switch statement', - NoCatchOrFinally: 'Missing catch or finally after try', - UnknownLabel: 'Undefined label \'%0\'', - Redeclaration: '%0 \'%1\' has already been declared', - IllegalContinue: 'Illegal continue statement', - IllegalBreak: 'Illegal break statement', - IllegalDuplicateClassProperty: 'Illegal duplicate property in class definition', - IllegalReturn: 'Illegal return statement', - IllegalYield: 'Illegal yield expression', - IllegalSpread: 'Illegal spread element', - StrictModeWith: 'Strict mode code may not include a with statement', - StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode', - StrictVarName: 'Variable name may not be eval or arguments in strict mode', - StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode', - StrictParamDupe: 'Strict mode function may not have duplicate parameter names', - ParameterAfterRestParameter: 'Rest parameter must be final parameter of an argument list', - DefaultRestParameter: 'Rest parameter can not have a default value', - ElementAfterSpreadElement: 'Spread must be the final element of an element list', - PropertyAfterSpreadProperty: 'A rest property must be the final property of an object literal', - ObjectPatternAsRestParameter: 'Invalid rest parameter', - ObjectPatternAsSpread: 'Invalid spread argument', - StrictFunctionName: 'Function name may not be eval or arguments in strict mode', - StrictOctalLiteral: 'Octal literals are not allowed in strict mode.', - StrictDelete: 'Delete of an unqualified identifier in strict mode.', - StrictDuplicateProperty: 'Duplicate data property in object literal not allowed in strict mode', - AccessorDataProperty: 'Object literal may not have data and accessor property with the same name', - AccessorGetSet: 'Object literal may not have multiple get/set accessors with the same name', - StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode', - StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode', - StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode', - StrictReservedWord: 'Use of future reserved word in strict mode', - NewlineAfterModule: 'Illegal newline after module', - NoFromAfterImport: 'Missing from after import', - InvalidModuleSpecifier: 'Invalid module specifier', - NestedModule: 'Module declaration can not be nested', - NoUnintializedConst: 'Const must be initialized', - ComprehensionRequiresBlock: 'Comprehension must have at least one block', - ComprehensionError: 'Comprehension Error', - EachNotAllowed: 'Each is not supported', - InvalidXJSAttributeValue: 'XJS value should be either an expression or a quoted XJS text', - ExpectedXJSClosingTag: 'Expected corresponding XJS closing tag for %0', - AdjacentXJSElements: 'Adjacent XJS elements must be wrapped in an enclosing tag' - }; - - // See also tools/generate-unicode-regex.py. - Regex = { - NonAsciiIdentifierStart: new RegExp('[\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05d0-\u05ea\u05f0-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u08a0\u08a2-\u08ac\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097f\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d\u0c58\u0c59\u0c60\u0c61\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d60\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1877\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191c\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19c1-\u19c7\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2e2f\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua697\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa80-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc]'), - NonAsciiIdentifierPart: new RegExp('[\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0300-\u0374\u0376\u0377\u037a-\u037d\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u0483-\u0487\u048a-\u0527\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u05d0-\u05ea\u05f0-\u05f2\u0610-\u061a\u0620-\u0669\u066e-\u06d3\u06d5-\u06dc\u06df-\u06e8\u06ea-\u06fc\u06ff\u0710-\u074a\u074d-\u07b1\u07c0-\u07f5\u07fa\u0800-\u082d\u0840-\u085b\u08a0\u08a2-\u08ac\u08e4-\u08fe\u0900-\u0963\u0966-\u096f\u0971-\u0977\u0979-\u097f\u0981-\u0983\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bc-\u09c4\u09c7\u09c8\u09cb-\u09ce\u09d7\u09dc\u09dd\u09df-\u09e3\u09e6-\u09f1\u0a01-\u0a03\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a59-\u0a5c\u0a5e\u0a66-\u0a75\u0a81-\u0a83\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abc-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ad0\u0ae0-\u0ae3\u0ae6-\u0aef\u0b01-\u0b03\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3c-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b5c\u0b5d\u0b5f-\u0b63\u0b66-\u0b6f\u0b71\u0b82\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd0\u0bd7\u0be6-\u0bef\u0c01-\u0c03\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c3d-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c58\u0c59\u0c60-\u0c63\u0c66-\u0c6f\u0c82\u0c83\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbc-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0cde\u0ce0-\u0ce3\u0ce6-\u0cef\u0cf1\u0cf2\u0d02\u0d03\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d-\u0d44\u0d46-\u0d48\u0d4a-\u0d4e\u0d57\u0d60-\u0d63\u0d66-\u0d6f\u0d7a-\u0d7f\u0d82\u0d83\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0df2\u0df3\u0e01-\u0e3a\u0e40-\u0e4e\u0e50-\u0e59\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb9\u0ebb-\u0ebd\u0ec0-\u0ec4\u0ec6\u0ec8-\u0ecd\u0ed0-\u0ed9\u0edc-\u0edf\u0f00\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e-\u0f47\u0f49-\u0f6c\u0f71-\u0f84\u0f86-\u0f97\u0f99-\u0fbc\u0fc6\u1000-\u1049\u1050-\u109d\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u135d-\u135f\u1380-\u138f\u13a0-\u13f4\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f0\u1700-\u170c\u170e-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176c\u176e-\u1770\u1772\u1773\u1780-\u17d3\u17d7\u17dc\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u1820-\u1877\u1880-\u18aa\u18b0-\u18f5\u1900-\u191c\u1920-\u192b\u1930-\u193b\u1946-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u19d0-\u19d9\u1a00-\u1a1b\u1a20-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1aa7\u1b00-\u1b4b\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1bf3\u1c00-\u1c37\u1c40-\u1c49\u1c4d-\u1c7d\u1cd0-\u1cd2\u1cd4-\u1cf6\u1d00-\u1de6\u1dfc-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u200c\u200d\u203f\u2040\u2054\u2071\u207f\u2090-\u209c\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2102\u2107\u210a-\u2113\u2115\u2119-\u211d\u2124\u2126\u2128\u212a-\u212d\u212f-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d7f-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u2de0-\u2dff\u2e2f\u3005-\u3007\u3021-\u302f\u3031-\u3035\u3038-\u303c\u3041-\u3096\u3099\u309a\u309d-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312d\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fcc\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua62b\ua640-\ua66f\ua674-\ua67d\ua67f-\ua697\ua69f-\ua6f1\ua717-\ua71f\ua722-\ua788\ua78b-\ua78e\ua790-\ua793\ua7a0-\ua7aa\ua7f8-\ua827\ua840-\ua873\ua880-\ua8c4\ua8d0-\ua8d9\ua8e0-\ua8f7\ua8fb\ua900-\ua92d\ua930-\ua953\ua960-\ua97c\ua980-\ua9c0\ua9cf-\ua9d9\uaa00-\uaa36\uaa40-\uaa4d\uaa50-\uaa59\uaa60-\uaa76\uaa7a\uaa7b\uaa80-\uaac2\uaadb-\uaadd\uaae0-\uaaef\uaaf2-\uaaf6\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uabc0-\uabea\uabec\uabed\uabf0-\uabf9\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe00-\ufe0f\ufe20-\ufe26\ufe33\ufe34\ufe4d-\ufe4f\ufe70-\ufe74\ufe76-\ufefc\uff10-\uff19\uff21-\uff3a\uff3f\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc]') - }; - - // Ensure the condition is true, otherwise throw an error. - // This is only to have a better contract semantic, i.e. another safety net - // to catch a logic error. The condition shall be fulfilled in normal case. - // Do NOT use this to enforce a certain condition on any user input. - - function assert(condition, message) { - if (!condition) { - throw new Error('ASSERT: ' + message); - } - } - - function isDecimalDigit(ch) { - return (ch >= 48 && ch <= 57); // 0..9 - } - - function isHexDigit(ch) { - return '0123456789abcdefABCDEF'.indexOf(ch) >= 0; - } - - function isOctalDigit(ch) { - return '01234567'.indexOf(ch) >= 0; - } - - - // 7.2 White Space - - function isWhiteSpace(ch) { - return (ch === 32) || // space - (ch === 9) || // tab - (ch === 0xB) || - (ch === 0xC) || - (ch === 0xA0) || - (ch >= 0x1680 && '\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\uFEFF'.indexOf(String.fromCharCode(ch)) > 0); - } - - // 7.3 Line Terminators - - function isLineTerminator(ch) { - return (ch === 10) || (ch === 13) || (ch === 0x2028) || (ch === 0x2029); - } - - // 7.6 Identifier Names and Identifiers - - function isIdentifierStart(ch) { - return (ch === 36) || (ch === 95) || // $ (dollar) and _ (underscore) - (ch >= 65 && ch <= 90) || // A..Z - (ch >= 97 && ch <= 122) || // a..z - (ch === 92) || // \ (backslash) - ((ch >= 0x80) && Regex.NonAsciiIdentifierStart.test(String.fromCharCode(ch))); - } - - function isIdentifierPart(ch) { - return (ch === 36) || (ch === 95) || // $ (dollar) and _ (underscore) - (ch >= 65 && ch <= 90) || // A..Z - (ch >= 97 && ch <= 122) || // a..z - (ch >= 48 && ch <= 57) || // 0..9 - (ch === 92) || // \ (backslash) - ((ch >= 0x80) && Regex.NonAsciiIdentifierPart.test(String.fromCharCode(ch))); - } - - // 7.6.1.2 Future Reserved Words - - function isFutureReservedWord(id) { - switch (id) { - case 'class': - case 'enum': - case 'export': - case 'extends': - case 'import': - case 'super': - return true; - default: - return false; - } - } - - function isStrictModeReservedWord(id) { - switch (id) { - case 'implements': - case 'interface': - case 'package': - case 'private': - case 'protected': - case 'public': - case 'static': - case 'yield': - case 'let': - return true; - default: - return false; - } - } - - function isRestrictedWord(id) { - return id === 'eval' || id === 'arguments'; - } - - // 7.6.1.1 Keywords - - function isKeyword(id) { - if (strict && isStrictModeReservedWord(id)) { - return true; - } - - // 'const' is specialized as Keyword in V8. - // 'yield' is only treated as a keyword in strict mode. - // 'let' is for compatiblity with SpiderMonkey and ES.next. - // Some others are from future reserved words. - - switch (id.length) { - case 2: - return (id === 'if') || (id === 'in') || (id === 'do'); - case 3: - return (id === 'var') || (id === 'for') || (id === 'new') || - (id === 'try') || (id === 'let'); - case 4: - return (id === 'this') || (id === 'else') || (id === 'case') || - (id === 'void') || (id === 'with') || (id === 'enum'); - case 5: - return (id === 'while') || (id === 'break') || (id === 'catch') || - (id === 'throw') || (id === 'const') || - (id === 'class') || (id === 'super'); - case 6: - return (id === 'return') || (id === 'typeof') || (id === 'delete') || - (id === 'switch') || (id === 'export') || (id === 'import'); - case 7: - return (id === 'default') || (id === 'finally') || (id === 'extends'); - case 8: - return (id === 'function') || (id === 'continue') || (id === 'debugger'); - case 10: - return (id === 'instanceof'); - default: - return false; - } - } - - // 7.4 Comments - - function skipComment() { - var ch, blockComment, lineComment; - - blockComment = false; - lineComment = false; - - while (index < length) { - ch = source.charCodeAt(index); - - if (lineComment) { - ++index; - if (isLineTerminator(ch)) { - lineComment = false; - if (ch === 13 && source.charCodeAt(index) === 10) { - ++index; - } - ++lineNumber; - lineStart = index; - } - } else if (blockComment) { - if (isLineTerminator(ch)) { - if (ch === 13 && source.charCodeAt(index + 1) === 10) { - ++index; - } - ++lineNumber; - ++index; - lineStart = index; - if (index >= length) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - } else { - ch = source.charCodeAt(index++); - if (index >= length) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - // Block comment ends with '*/' (char #42, char #47). - if (ch === 42) { - ch = source.charCodeAt(index); - if (ch === 47) { - ++index; - blockComment = false; - } - } - } - } else if (ch === 47) { - ch = source.charCodeAt(index + 1); - // Line comment starts with '//' (char #47, char #47). - if (ch === 47) { - index += 2; - lineComment = true; - } else if (ch === 42) { - // Block comment starts with '/*' (char #47, char #42). - index += 2; - blockComment = true; - if (index >= length) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - } else { - break; - } - } else if (isWhiteSpace(ch)) { - ++index; - } else if (isLineTerminator(ch)) { - ++index; - if (ch === 13 && source.charCodeAt(index) === 10) { - ++index; - } - ++lineNumber; - lineStart = index; - } else { - break; - } - } - } - - function scanHexEscape(prefix) { - var i, len, ch, code = 0; - - len = (prefix === 'u') ? 4 : 2; - for (i = 0; i < len; ++i) { - if (index < length && isHexDigit(source.charAt(index))) { - ch = source.charAt(index++); - code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase()); - } else { - return ''; - } - } - return String.fromCharCode(code); - } - - function scanUnicodeCodePointEscape() { - var ch, code, cu1, cu2; - - ch = source.charAt(index); - code = 0; - - // At least, one hex digit is required. - if (ch === '}') { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - - while (index < length) { - ch = source.charAt(index++); - if (!isHexDigit(ch)) { - break; - } - code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase()); - } - - if (code > 0x10FFFF || ch !== '}') { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - - // UTF-16 Encoding - if (code <= 0xFFFF) { - return String.fromCharCode(code); - } - cu1 = ((code - 0x10000) >> 10) + 0xD800; - cu2 = ((code - 0x10000) & 1023) + 0xDC00; - return String.fromCharCode(cu1, cu2); - } - - function getEscapedIdentifier() { - var ch, id; - - ch = source.charCodeAt(index++); - id = String.fromCharCode(ch); - - // '\u' (char #92, char #117) denotes an escaped character. - if (ch === 92) { - if (source.charCodeAt(index) !== 117) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - ++index; - ch = scanHexEscape('u'); - if (!ch || ch === '\\' || !isIdentifierStart(ch.charCodeAt(0))) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - id = ch; - } - - while (index < length) { - ch = source.charCodeAt(index); - if (!isIdentifierPart(ch)) { - break; - } - ++index; - id += String.fromCharCode(ch); - - // '\u' (char #92, char #117) denotes an escaped character. - if (ch === 92) { - id = id.substr(0, id.length - 1); - if (source.charCodeAt(index) !== 117) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - ++index; - ch = scanHexEscape('u'); - if (!ch || ch === '\\' || !isIdentifierPart(ch.charCodeAt(0))) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - id += ch; - } - } - - return id; - } - - function getIdentifier() { - var start, ch; - - start = index++; - while (index < length) { - ch = source.charCodeAt(index); - if (ch === 92) { - // Blackslash (char #92) marks Unicode escape sequence. - index = start; - return getEscapedIdentifier(); - } - if (isIdentifierPart(ch)) { - ++index; - } else { - break; - } - } - - return source.slice(start, index); - } - - function scanIdentifier() { - var start, id, type; - - start = index; - - // Backslash (char #92) starts an escaped character. - id = (source.charCodeAt(index) === 92) ? getEscapedIdentifier() : getIdentifier(); - - // There is no keyword or literal with only one character. - // Thus, it must be an identifier. - if (id.length === 1) { - type = Token.Identifier; - } else if (isKeyword(id)) { - type = Token.Keyword; - } else if (id === 'null') { - type = Token.NullLiteral; - } else if (id === 'true' || id === 'false') { - type = Token.BooleanLiteral; - } else { - type = Token.Identifier; - } - - return { - type: type, - value: id, - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - - // 7.7 Punctuators - - function scanPunctuator() { - var start = index, - code = source.charCodeAt(index), - code2, - ch1 = source.charAt(index), - ch2, - ch3, - ch4; - - switch (code) { - // Check for most common single-character punctuators. - case 40: // ( open bracket - case 41: // ) close bracket - case 59: // ; semicolon - case 44: // , comma - case 123: // { open curly brace - case 125: // } close curly brace - case 91: // [ - case 93: // ] - case 58: // : - case 63: // ? - case 126: // ~ - ++index; - if (extra.tokenize) { - if (code === 40) { - extra.openParenToken = extra.tokens.length; - } else if (code === 123) { - extra.openCurlyToken = extra.tokens.length; - } - } - return { - type: Token.Punctuator, - value: String.fromCharCode(code), - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - - default: - code2 = source.charCodeAt(index + 1); - - // '=' (char #61) marks an assignment or comparison operator. - if (code2 === 61) { - switch (code) { - case 37: // % - case 38: // & - case 42: // *: - case 43: // + - case 45: // - - case 47: // / - case 60: // < - case 62: // > - case 94: // ^ - case 124: // | - index += 2; - return { - type: Token.Punctuator, - value: String.fromCharCode(code) + String.fromCharCode(code2), - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - - case 33: // ! - case 61: // = - index += 2; - - // !== and === - if (source.charCodeAt(index) === 61) { - ++index; - } - return { - type: Token.Punctuator, - value: source.slice(start, index), - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - default: - break; - } - } - break; - } - - // Peek more characters. - - ch2 = source.charAt(index + 1); - ch3 = source.charAt(index + 2); - ch4 = source.charAt(index + 3); - - // 4-character punctuator: >>>= - - if (ch1 === '>' && ch2 === '>' && ch3 === '>') { - if (ch4 === '=') { - index += 4; - return { - type: Token.Punctuator, - value: '>>>=', - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - } - - // 3-character punctuators: === !== >>> <<= >>= - - if (ch1 === '>' && ch2 === '>' && ch3 === '>') { - index += 3; - return { - type: Token.Punctuator, - value: '>>>', - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - if (ch1 === '<' && ch2 === '<' && ch3 === '=') { - index += 3; - return { - type: Token.Punctuator, - value: '<<=', - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - if (ch1 === '>' && ch2 === '>' && ch3 === '=') { - index += 3; - return { - type: Token.Punctuator, - value: '>>=', - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - if (ch1 === '.' && ch2 === '.' && ch3 === '.') { - index += 3; - return { - type: Token.Punctuator, - value: '...', - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - // Other 2-character punctuators: ++ -- << >> && || - - if (ch1 === ch2 && ('+-<>&|'.indexOf(ch1) >= 0)) { - index += 2; - return { - type: Token.Punctuator, - value: ch1 + ch2, - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - if (ch1 === '=' && ch2 === '>') { - index += 2; - return { - type: Token.Punctuator, - value: '=>', - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - if ('<>=!+-*%&|^/'.indexOf(ch1) >= 0) { - ++index; - return { - type: Token.Punctuator, - value: ch1, - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - if (ch1 === '.') { - ++index; - return { - type: Token.Punctuator, - value: ch1, - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - - // 7.8.3 Numeric Literals - - function scanHexLiteral(start) { - var number = ''; - - while (index < length) { - if (!isHexDigit(source.charAt(index))) { - break; - } - number += source.charAt(index++); - } - - if (number.length === 0) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - - if (isIdentifierStart(source.charCodeAt(index))) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - - return { - type: Token.NumericLiteral, - value: parseInt('0x' + number, 16), - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - function scanOctalLiteral(prefix, start) { - var number, octal; - - if (isOctalDigit(prefix)) { - octal = true; - number = '0' + source.charAt(index++); - } else { - octal = false; - ++index; - number = ''; - } - - while (index < length) { - if (!isOctalDigit(source.charAt(index))) { - break; - } - number += source.charAt(index++); - } - - if (!octal && number.length === 0) { - // only 0o or 0O - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - - if (isIdentifierStart(source.charCodeAt(index)) || isDecimalDigit(source.charCodeAt(index))) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - - return { - type: Token.NumericLiteral, - value: parseInt(number, 8), - octal: octal, - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - function scanNumericLiteral() { - var number, start, ch, octal; - - ch = source.charAt(index); - assert(isDecimalDigit(ch.charCodeAt(0)) || (ch === '.'), - 'Numeric literal must start with a decimal digit or a decimal point'); - - start = index; - number = ''; - if (ch !== '.') { - number = source.charAt(index++); - ch = source.charAt(index); - - // Hex number starts with '0x'. - // Octal number starts with '0'. - // Octal number in ES6 starts with '0o'. - // Binary number in ES6 starts with '0b'. - if (number === '0') { - if (ch === 'x' || ch === 'X') { - ++index; - return scanHexLiteral(start); - } - if (ch === 'b' || ch === 'B') { - ++index; - number = ''; - - while (index < length) { - ch = source.charAt(index); - if (ch !== '0' && ch !== '1') { - break; - } - number += source.charAt(index++); - } - - if (number.length === 0) { - // only 0b or 0B - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - - if (index < length) { - ch = source.charCodeAt(index); - if (isIdentifierStart(ch) || isDecimalDigit(ch)) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - } - return { - type: Token.NumericLiteral, - value: parseInt(number, 2), - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - if (ch === 'o' || ch === 'O' || isOctalDigit(ch)) { - return scanOctalLiteral(ch, start); - } - // decimal number starts with '0' such as '09' is illegal. - if (ch && isDecimalDigit(ch.charCodeAt(0))) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - } - - while (isDecimalDigit(source.charCodeAt(index))) { - number += source.charAt(index++); - } - ch = source.charAt(index); - } - - if (ch === '.') { - number += source.charAt(index++); - while (isDecimalDigit(source.charCodeAt(index))) { - number += source.charAt(index++); - } - ch = source.charAt(index); - } - - if (ch === 'e' || ch === 'E') { - number += source.charAt(index++); - - ch = source.charAt(index); - if (ch === '+' || ch === '-') { - number += source.charAt(index++); - } - if (isDecimalDigit(source.charCodeAt(index))) { - while (isDecimalDigit(source.charCodeAt(index))) { - number += source.charAt(index++); - } - } else { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - } - - if (isIdentifierStart(source.charCodeAt(index))) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - - return { - type: Token.NumericLiteral, - value: parseFloat(number), - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - // 7.8.4 String Literals - - function scanStringLiteral() { - var str = '', quote, start, ch, code, unescaped, restore, octal = false; - - quote = source.charAt(index); - assert((quote === '\'' || quote === '"'), - 'String literal must starts with a quote'); - - start = index; - ++index; - - while (index < length) { - ch = source.charAt(index++); - - if (ch === quote) { - quote = ''; - break; - } else if (ch === '\\') { - ch = source.charAt(index++); - if (!ch || !isLineTerminator(ch.charCodeAt(0))) { - switch (ch) { - case 'n': - str += '\n'; - break; - case 'r': - str += '\r'; - break; - case 't': - str += '\t'; - break; - case 'u': - case 'x': - if (source.charAt(index) === '{') { - ++index; - str += scanUnicodeCodePointEscape(); - } else { - restore = index; - unescaped = scanHexEscape(ch); - if (unescaped) { - str += unescaped; - } else { - index = restore; - str += ch; - } - } - break; - case 'b': - str += '\b'; - break; - case 'f': - str += '\f'; - break; - case 'v': - str += '\x0B'; - break; - - default: - if (isOctalDigit(ch)) { - code = '01234567'.indexOf(ch); - - // \0 is not octal escape sequence - if (code !== 0) { - octal = true; - } - - if (index < length && isOctalDigit(source.charAt(index))) { - octal = true; - code = code * 8 + '01234567'.indexOf(source.charAt(index++)); - - // 3 digits are only allowed when string starts - // with 0, 1, 2, 3 - if ('0123'.indexOf(ch) >= 0 && - index < length && - isOctalDigit(source.charAt(index))) { - code = code * 8 + '01234567'.indexOf(source.charAt(index++)); - } - } - str += String.fromCharCode(code); - } else { - str += ch; - } - break; - } - } else { - ++lineNumber; - if (ch === '\r' && source.charAt(index) === '\n') { - ++index; - } - } - } else if (isLineTerminator(ch.charCodeAt(0))) { - break; - } else { - str += ch; - } - } - - if (quote !== '') { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - - return { - type: Token.StringLiteral, - value: str, - octal: octal, - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - function scanTemplate() { - var cooked = '', ch, start, terminated, tail, restore, unescaped, code, octal; - - terminated = false; - tail = false; - start = index; - - ++index; - - while (index < length) { - ch = source.charAt(index++); - if (ch === '`') { - tail = true; - terminated = true; - break; - } else if (ch === '$') { - if (source.charAt(index) === '{') { - ++index; - terminated = true; - break; - } - cooked += ch; - } else if (ch === '\\') { - ch = source.charAt(index++); - if (!isLineTerminator(ch.charCodeAt(0))) { - switch (ch) { - case 'n': - cooked += '\n'; - break; - case 'r': - cooked += '\r'; - break; - case 't': - cooked += '\t'; - break; - case 'u': - case 'x': - if (source.charAt(index) === '{') { - ++index; - cooked += scanUnicodeCodePointEscape(); - } else { - restore = index; - unescaped = scanHexEscape(ch); - if (unescaped) { - cooked += unescaped; - } else { - index = restore; - cooked += ch; - } - } - break; - case 'b': - cooked += '\b'; - break; - case 'f': - cooked += '\f'; - break; - case 'v': - cooked += '\v'; - break; - - default: - if (isOctalDigit(ch)) { - code = '01234567'.indexOf(ch); - - // \0 is not octal escape sequence - if (code !== 0) { - octal = true; - } - - if (index < length && isOctalDigit(source.charAt(index))) { - octal = true; - code = code * 8 + '01234567'.indexOf(source.charAt(index++)); - - // 3 digits are only allowed when string starts - // with 0, 1, 2, 3 - if ('0123'.indexOf(ch) >= 0 && - index < length && - isOctalDigit(source.charAt(index))) { - code = code * 8 + '01234567'.indexOf(source.charAt(index++)); - } - } - cooked += String.fromCharCode(code); - } else { - cooked += ch; - } - break; - } - } else { - ++lineNumber; - if (ch === '\r' && source.charAt(index) === '\n') { - ++index; - } - } - } else if (isLineTerminator(ch.charCodeAt(0))) { - ++lineNumber; - if (ch === '\r' && source.charAt(index) === '\n') { - ++index; - } - cooked += '\n'; - } else { - cooked += ch; - } - } - - if (!terminated) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - - return { - type: Token.Template, - value: { - cooked: cooked, - raw: source.slice(start + 1, index - ((tail) ? 1 : 2)) - }, - tail: tail, - octal: octal, - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - function scanTemplateElement(option) { - var startsWith, template; - - lookahead = null; - skipComment(); - - startsWith = (option.head) ? '`' : '}'; - - if (source.charAt(index) !== startsWith) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - - template = scanTemplate(); - - peek(); - - return template; - } - - function scanRegExp() { - var str, ch, start, pattern, flags, value, classMarker = false, restore, terminated = false; - - lookahead = null; - skipComment(); - - start = index; - ch = source.charAt(index); - assert(ch === '/', 'Regular expression literal must start with a slash'); - str = source.charAt(index++); - - while (index < length) { - ch = source.charAt(index++); - str += ch; - if (classMarker) { - if (ch === ']') { - classMarker = false; - } - } else { - if (ch === '\\') { - ch = source.charAt(index++); - // ECMA-262 7.8.5 - if (isLineTerminator(ch.charCodeAt(0))) { - throwError({}, Messages.UnterminatedRegExp); - } - str += ch; - } else if (ch === '/') { - terminated = true; - break; - } else if (ch === '[') { - classMarker = true; - } else if (isLineTerminator(ch.charCodeAt(0))) { - throwError({}, Messages.UnterminatedRegExp); - } - } - } - - if (!terminated) { - throwError({}, Messages.UnterminatedRegExp); - } - - // Exclude leading and trailing slash. - pattern = str.substr(1, str.length - 2); - - flags = ''; - while (index < length) { - ch = source.charAt(index); - if (!isIdentifierPart(ch.charCodeAt(0))) { - break; - } - - ++index; - if (ch === '\\' && index < length) { - ch = source.charAt(index); - if (ch === 'u') { - ++index; - restore = index; - ch = scanHexEscape('u'); - if (ch) { - flags += ch; - for (str += '\\u'; restore < index; ++restore) { - str += source.charAt(restore); - } - } else { - index = restore; - flags += 'u'; - str += '\\u'; - } - } else { - str += '\\'; - } - } else { - flags += ch; - str += ch; - } - } - - try { - value = new RegExp(pattern, flags); - } catch (e) { - throwError({}, Messages.InvalidRegExp); - } - - peek(); - - - if (extra.tokenize) { - return { - type: Token.RegularExpression, - value: value, - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - return { - literal: str, - value: value, - range: [start, index] - }; - } - - function isIdentifierName(token) { - return token.type === Token.Identifier || - token.type === Token.Keyword || - token.type === Token.BooleanLiteral || - token.type === Token.NullLiteral; - } - - function advanceSlash() { - var prevToken, - checkToken; - // Using the following algorithm: - // https://github.com/mozilla/sweet.js/wiki/design - prevToken = extra.tokens[extra.tokens.length - 1]; - if (!prevToken) { - // Nothing before that: it cannot be a division. - return scanRegExp(); - } - if (prevToken.type === 'Punctuator') { - if (prevToken.value === ')') { - checkToken = extra.tokens[extra.openParenToken - 1]; - if (checkToken && - checkToken.type === 'Keyword' && - (checkToken.value === 'if' || - checkToken.value === 'while' || - checkToken.value === 'for' || - checkToken.value === 'with')) { - return scanRegExp(); - } - return scanPunctuator(); - } - if (prevToken.value === '}') { - // Dividing a function by anything makes little sense, - // but we have to check for that. - if (extra.tokens[extra.openCurlyToken - 3] && - extra.tokens[extra.openCurlyToken - 3].type === 'Keyword') { - // Anonymous function. - checkToken = extra.tokens[extra.openCurlyToken - 4]; - if (!checkToken) { - return scanPunctuator(); - } - } else if (extra.tokens[extra.openCurlyToken - 4] && - extra.tokens[extra.openCurlyToken - 4].type === 'Keyword') { - // Named function. - checkToken = extra.tokens[extra.openCurlyToken - 5]; - if (!checkToken) { - return scanRegExp(); - } - } else { - return scanPunctuator(); - } - // checkToken determines whether the function is - // a declaration or an expression. - if (FnExprTokens.indexOf(checkToken.value) >= 0) { - // It is an expression. - return scanPunctuator(); - } - // It is a declaration. - return scanRegExp(); - } - return scanRegExp(); - } - if (prevToken.type === 'Keyword') { - return scanRegExp(); - } - return scanPunctuator(); - } - - function advance() { - var ch; - - if (!state.inXJSChild) { - skipComment(); - } - - if (index >= length) { - return { - type: Token.EOF, - lineNumber: lineNumber, - lineStart: lineStart, - range: [index, index] - }; - } - - if (state.inXJSChild) { - return advanceXJSChild(); - } - - ch = source.charCodeAt(index); - - // Very common: ( and ) and ; - if (ch === 40 || ch === 41 || ch === 58) { - return scanPunctuator(); - } - - // String literal starts with single quote (#39) or double quote (#34). - if (ch === 39 || ch === 34) { - if (state.inXJSTag) { - return scanXJSStringLiteral(); - } - return scanStringLiteral(); - } - - if (state.inXJSTag && isXJSIdentifierStart(ch)) { - return scanXJSIdentifier(); - } - - if (ch === 96) { - return scanTemplate(); - } - if (isIdentifierStart(ch)) { - return scanIdentifier(); - } - - // Dot (.) char #46 can also start a floating-point number, hence the need - // to check the next character. - if (ch === 46) { - if (isDecimalDigit(source.charCodeAt(index + 1))) { - return scanNumericLiteral(); - } - return scanPunctuator(); - } - - if (isDecimalDigit(ch)) { - return scanNumericLiteral(); - } - - // Slash (/) char #47 can also start a regex. - if (extra.tokenize && ch === 47) { - return advanceSlash(); - } - - return scanPunctuator(); - } - - function lex() { - var token; - - token = lookahead; - index = token.range[1]; - lineNumber = token.lineNumber; - lineStart = token.lineStart; - - lookahead = advance(); - - index = token.range[1]; - lineNumber = token.lineNumber; - lineStart = token.lineStart; - - return token; - } - - function peek() { - var pos, line, start; - - pos = index; - line = lineNumber; - start = lineStart; - lookahead = advance(); - index = pos; - lineNumber = line; - lineStart = start; - } - - function lookahead2() { - var adv, pos, line, start, result; - - // If we are collecting the tokens, don't grab the next one yet. - adv = (typeof extra.advance === 'function') ? extra.advance : advance; - - pos = index; - line = lineNumber; - start = lineStart; - - // Scan for the next immediate token. - if (lookahead === null) { - lookahead = adv(); - } - index = lookahead.range[1]; - lineNumber = lookahead.lineNumber; - lineStart = lookahead.lineStart; - - // Grab the token right after. - result = adv(); - index = pos; - lineNumber = line; - lineStart = start; - - return result; - } - - function markerCreate() { - if (!extra.loc && !extra.range) { - return undefined; - } - skipComment(); - return {offset: index, line: lineNumber, col: index - lineStart}; - } - - function markerCreatePreserveWhitespace() { - if (!extra.loc && !extra.range) { - return undefined; - } - return {offset: index, line: lineNumber, col: index - lineStart}; - } - - function markerApply(marker, node) { - if (extra.range) { - node.range = [marker.offset, index]; - } - if (extra.loc) { - node.loc = { - start: { - line: marker.line, - column: marker.col - }, - end: { - line: lineNumber, - column: index - lineStart - } - }; - node = delegate.postProcess(node); - } - return node; - } - - SyntaxTreeDelegate = { - - name: 'SyntaxTree', - - postProcess: function (node) { - return node; - }, - - createArrayExpression: function (elements) { - return { - type: Syntax.ArrayExpression, - elements: elements - }; - }, - - createAssignmentExpression: function (operator, left, right) { - return { - type: Syntax.AssignmentExpression, - operator: operator, - left: left, - right: right - }; - }, - - createBinaryExpression: function (operator, left, right) { - var type = (operator === '||' || operator === '&&') ? Syntax.LogicalExpression : - Syntax.BinaryExpression; - return { - type: type, - operator: operator, - left: left, - right: right - }; - }, - - createBlockStatement: function (body) { - return { - type: Syntax.BlockStatement, - body: body - }; - }, - - createBreakStatement: function (label) { - return { - type: Syntax.BreakStatement, - label: label - }; - }, - - createCallExpression: function (callee, args) { - return { - type: Syntax.CallExpression, - callee: callee, - 'arguments': args - }; - }, - - createCatchClause: function (param, body) { - return { - type: Syntax.CatchClause, - param: param, - body: body - }; - }, - - createConditionalExpression: function (test, consequent, alternate) { - return { - type: Syntax.ConditionalExpression, - test: test, - consequent: consequent, - alternate: alternate - }; - }, - - createContinueStatement: function (label) { - return { - type: Syntax.ContinueStatement, - label: label - }; - }, - - createDebuggerStatement: function () { - return { - type: Syntax.DebuggerStatement - }; - }, - - createDoWhileStatement: function (body, test) { - return { - type: Syntax.DoWhileStatement, - body: body, - test: test - }; - }, - - createEmptyStatement: function () { - return { - type: Syntax.EmptyStatement - }; - }, - - createExpressionStatement: function (expression) { - return { - type: Syntax.ExpressionStatement, - expression: expression - }; - }, - - createForStatement: function (init, test, update, body) { - return { - type: Syntax.ForStatement, - init: init, - test: test, - update: update, - body: body - }; - }, - - createForInStatement: function (left, right, body) { - return { - type: Syntax.ForInStatement, - left: left, - right: right, - body: body, - each: false - }; - }, - - createForOfStatement: function (left, right, body) { - return { - type: Syntax.ForOfStatement, - left: left, - right: right, - body: body - }; - }, - - createFunctionDeclaration: function (id, params, defaults, body, rest, generator, expression, - returnType, parametricType) { - return { - type: Syntax.FunctionDeclaration, - id: id, - params: params, - defaults: defaults, - body: body, - rest: rest, - generator: generator, - expression: expression, - returnType: returnType, - parametricType: parametricType - }; - }, - - createFunctionExpression: function (id, params, defaults, body, rest, generator, expression, - returnType, parametricType) { - return { - type: Syntax.FunctionExpression, - id: id, - params: params, - defaults: defaults, - body: body, - rest: rest, - generator: generator, - expression: expression, - returnType: returnType, - parametricType: parametricType - }; - }, - - createIdentifier: function (name) { - return { - type: Syntax.Identifier, - name: name, - // Only here to initialize the shape of the object to ensure - // that the 'typeAnnotation' key is ordered before others that - // are added later (like 'loc' and 'range'). This just helps - // keep the shape of Identifier nodes consistent with everything - // else. - typeAnnotation: undefined - }; - }, - - createTypeAnnotation: function (typeIdentifier, parametricType, params, returnType, nullable) { - return { - type: Syntax.TypeAnnotation, - id: typeIdentifier, - parametricType: parametricType, - params: params, - returnType: returnType, - nullable: nullable - }; - }, - - createParametricTypeAnnotation: function (parametricTypes) { - return { - type: Syntax.ParametricTypeAnnotation, - params: parametricTypes - }; - }, - - createVoidTypeAnnotation: function () { - return { - type: Syntax.VoidTypeAnnotation - }; - }, - - createObjectTypeAnnotation: function (properties) { - return { - type: Syntax.ObjectTypeAnnotation, - properties: properties - }; - }, - - createTypeAnnotatedIdentifier: function (identifier, annotation, isOptionalParam) { - return { - type: Syntax.TypeAnnotatedIdentifier, - id: identifier, - annotation: annotation - }; - }, - - createOptionalParameter: function (identifier) { - return { - type: Syntax.OptionalParameter, - id: identifier - }; - }, - - createXJSAttribute: function (name, value) { - return { - type: Syntax.XJSAttribute, - name: name, - value: value - }; - }, - - createXJSSpreadAttribute: function (argument) { - return { - type: Syntax.XJSSpreadAttribute, - argument: argument - }; - }, - - createXJSIdentifier: function (name) { - return { - type: Syntax.XJSIdentifier, - name: name - }; - }, - - createXJSNamespacedName: function (namespace, name) { - return { - type: Syntax.XJSNamespacedName, - namespace: namespace, - name: name - }; - }, - - createXJSMemberExpression: function (object, property) { - return { - type: Syntax.XJSMemberExpression, - object: object, - property: property - }; - }, - - createXJSElement: function (openingElement, closingElement, children) { - return { - type: Syntax.XJSElement, - openingElement: openingElement, - closingElement: closingElement, - children: children - }; - }, - - createXJSEmptyExpression: function () { - return { - type: Syntax.XJSEmptyExpression - }; - }, - - createXJSExpressionContainer: function (expression) { - return { - type: Syntax.XJSExpressionContainer, - expression: expression - }; - }, - - createXJSOpeningElement: function (name, attributes, selfClosing) { - return { - type: Syntax.XJSOpeningElement, - name: name, - selfClosing: selfClosing, - attributes: attributes - }; - }, - - createXJSClosingElement: function (name) { - return { - type: Syntax.XJSClosingElement, - name: name - }; - }, - - createIfStatement: function (test, consequent, alternate) { - return { - type: Syntax.IfStatement, - test: test, - consequent: consequent, - alternate: alternate - }; - }, - - createLabeledStatement: function (label, body) { - return { - type: Syntax.LabeledStatement, - label: label, - body: body - }; - }, - - createLiteral: function (token) { - return { - type: Syntax.Literal, - value: token.value, - raw: source.slice(token.range[0], token.range[1]) - }; - }, - - createMemberExpression: function (accessor, object, property) { - return { - type: Syntax.MemberExpression, - computed: accessor === '[', - object: object, - property: property - }; - }, - - createNewExpression: function (callee, args) { - return { - type: Syntax.NewExpression, - callee: callee, - 'arguments': args - }; - }, - - createObjectExpression: function (properties) { - return { - type: Syntax.ObjectExpression, - properties: properties - }; - }, - - createPostfixExpression: function (operator, argument) { - return { - type: Syntax.UpdateExpression, - operator: operator, - argument: argument, - prefix: false - }; - }, - - createProgram: function (body) { - return { - type: Syntax.Program, - body: body - }; - }, - - createProperty: function (kind, key, value, method, shorthand, computed) { - return { - type: Syntax.Property, - key: key, - value: value, - kind: kind, - method: method, - shorthand: shorthand, - computed: computed - }; - }, - - createReturnStatement: function (argument) { - return { - type: Syntax.ReturnStatement, - argument: argument - }; - }, - - createSequenceExpression: function (expressions) { - return { - type: Syntax.SequenceExpression, - expressions: expressions - }; - }, - - createSwitchCase: function (test, consequent) { - return { - type: Syntax.SwitchCase, - test: test, - consequent: consequent - }; - }, - - createSwitchStatement: function (discriminant, cases) { - return { - type: Syntax.SwitchStatement, - discriminant: discriminant, - cases: cases - }; - }, - - createThisExpression: function () { - return { - type: Syntax.ThisExpression - }; - }, - - createThrowStatement: function (argument) { - return { - type: Syntax.ThrowStatement, - argument: argument - }; - }, - - createTryStatement: function (block, guardedHandlers, handlers, finalizer) { - return { - type: Syntax.TryStatement, - block: block, - guardedHandlers: guardedHandlers, - handlers: handlers, - finalizer: finalizer - }; - }, - - createUnaryExpression: function (operator, argument) { - if (operator === '++' || operator === '--') { - return { - type: Syntax.UpdateExpression, - operator: operator, - argument: argument, - prefix: true - }; - } - return { - type: Syntax.UnaryExpression, - operator: operator, - argument: argument, - prefix: true - }; - }, - - createVariableDeclaration: function (declarations, kind) { - return { - type: Syntax.VariableDeclaration, - declarations: declarations, - kind: kind - }; - }, - - createVariableDeclarator: function (id, init) { - return { - type: Syntax.VariableDeclarator, - id: id, - init: init - }; - }, - - createWhileStatement: function (test, body) { - return { - type: Syntax.WhileStatement, - test: test, - body: body - }; - }, - - createWithStatement: function (object, body) { - return { - type: Syntax.WithStatement, - object: object, - body: body - }; - }, - - createTemplateElement: function (value, tail) { - return { - type: Syntax.TemplateElement, - value: value, - tail: tail - }; - }, - - createTemplateLiteral: function (quasis, expressions) { - return { - type: Syntax.TemplateLiteral, - quasis: quasis, - expressions: expressions - }; - }, - - createSpreadElement: function (argument) { - return { - type: Syntax.SpreadElement, - argument: argument - }; - }, - - createSpreadProperty: function (argument) { - return { - type: Syntax.SpreadProperty, - argument: argument - }; - }, - - createTaggedTemplateExpression: function (tag, quasi) { - return { - type: Syntax.TaggedTemplateExpression, - tag: tag, - quasi: quasi - }; - }, - - createArrowFunctionExpression: function (params, defaults, body, rest, expression) { - return { - type: Syntax.ArrowFunctionExpression, - id: null, - params: params, - defaults: defaults, - body: body, - rest: rest, - generator: false, - expression: expression - }; - }, - - createMethodDefinition: function (propertyType, kind, key, value) { - return { - type: Syntax.MethodDefinition, - key: key, - value: value, - kind: kind, - 'static': propertyType === ClassPropertyType["static"] - }; - }, - - createClassProperty: function (propertyIdentifier) { - return { - type: Syntax.ClassProperty, - id: propertyIdentifier - }; - }, - - createClassBody: function (body) { - return { - type: Syntax.ClassBody, - body: body - }; - }, - - createClassExpression: function (id, superClass, body, parametricType) { - return { - type: Syntax.ClassExpression, - id: id, - superClass: superClass, - body: body, - parametricType: parametricType - }; - }, - - createClassDeclaration: function (id, superClass, body, parametricType, superParametricType) { - return { - type: Syntax.ClassDeclaration, - id: id, - superClass: superClass, - body: body, - parametricType: parametricType, - superParametricType: superParametricType - }; - }, - - createExportSpecifier: function (id, name) { - return { - type: Syntax.ExportSpecifier, - id: id, - name: name - }; - }, - - createExportBatchSpecifier: function () { - return { - type: Syntax.ExportBatchSpecifier - }; - }, - - createExportDeclaration: function (declaration, specifiers, source) { - return { - type: Syntax.ExportDeclaration, - declaration: declaration, - specifiers: specifiers, - source: source - }; - }, - - createImportSpecifier: function (id, name) { - return { - type: Syntax.ImportSpecifier, - id: id, - name: name - }; - }, - - createImportDeclaration: function (specifiers, kind, source) { - return { - type: Syntax.ImportDeclaration, - specifiers: specifiers, - kind: kind, - source: source - }; - }, - - createYieldExpression: function (argument, delegate) { - return { - type: Syntax.YieldExpression, - argument: argument, - delegate: delegate - }; - }, - - createModuleDeclaration: function (id, source, body) { - return { - type: Syntax.ModuleDeclaration, - id: id, - source: source, - body: body - }; - }, - - createComprehensionExpression: function (filter, blocks, body) { - return { - type: Syntax.ComprehensionExpression, - filter: filter, - blocks: blocks, - body: body - }; - } - - }; - - // Return true if there is a line terminator before the next token. - - function peekLineTerminator() { - var pos, line, start, found; - - pos = index; - line = lineNumber; - start = lineStart; - skipComment(); - found = lineNumber !== line; - index = pos; - lineNumber = line; - lineStart = start; - - return found; - } - - // Throw an exception - - function throwError(token, messageFormat) { - var error, - args = Array.prototype.slice.call(arguments, 2), - msg = messageFormat.replace( - /%(\d)/g, - function (whole, index) { - assert(index < args.length, 'Message reference must be in range'); - return args[index]; - } - ); - - if (typeof token.lineNumber === 'number') { - error = new Error('Line ' + token.lineNumber + ': ' + msg); - error.index = token.range[0]; - error.lineNumber = token.lineNumber; - error.column = token.range[0] - lineStart + 1; - } else { - error = new Error('Line ' + lineNumber + ': ' + msg); - error.index = index; - error.lineNumber = lineNumber; - error.column = index - lineStart + 1; - } - - error.description = msg; - throw error; - } - - function throwErrorTolerant() { - try { - throwError.apply(null, arguments); - } catch (e) { - if (extra.errors) { - extra.errors.push(e); - } else { - throw e; - } - } - } - - - // Throw an exception because of the token. - - function throwUnexpected(token) { - if (token.type === Token.EOF) { - throwError(token, Messages.UnexpectedEOS); - } - - if (token.type === Token.NumericLiteral) { - throwError(token, Messages.UnexpectedNumber); - } - - if (token.type === Token.StringLiteral || token.type === Token.XJSText) { - throwError(token, Messages.UnexpectedString); - } - - if (token.type === Token.Identifier) { - throwError(token, Messages.UnexpectedIdentifier); - } - - if (token.type === Token.Keyword) { - if (isFutureReservedWord(token.value)) { - throwError(token, Messages.UnexpectedReserved); - } else if (strict && isStrictModeReservedWord(token.value)) { - throwErrorTolerant(token, Messages.StrictReservedWord); - return; - } - throwError(token, Messages.UnexpectedToken, token.value); - } - - if (token.type === Token.Template) { - throwError(token, Messages.UnexpectedTemplate, token.value.raw); - } - - // BooleanLiteral, NullLiteral, or Punctuator. - throwError(token, Messages.UnexpectedToken, token.value); - } - - // Expect the next token to match the specified punctuator. - // If not, an exception will be thrown. - - function expect(value) { - var token = lex(); - if (token.type !== Token.Punctuator || token.value !== value) { - throwUnexpected(token); - } - } - - // Expect the next token to match the specified keyword. - // If not, an exception will be thrown. - - function expectKeyword(keyword) { - var token = lex(); - if (token.type !== Token.Keyword || token.value !== keyword) { - throwUnexpected(token); - } - } - - // Return true if the next token matches the specified punctuator. - - function match(value) { - return lookahead.type === Token.Punctuator && lookahead.value === value; - } - - // Return true if the next token matches the specified keyword - - function matchKeyword(keyword) { - return lookahead.type === Token.Keyword && lookahead.value === keyword; - } - - - // Return true if the next token matches the specified contextual keyword - - function matchContextualKeyword(keyword) { - return lookahead.type === Token.Identifier && lookahead.value === keyword; - } - - // Return true if the next token is an assignment operator - - function matchAssign() { - var op; - - if (lookahead.type !== Token.Punctuator) { - return false; - } - op = lookahead.value; - return op === '=' || - op === '*=' || - op === '/=' || - op === '%=' || - op === '+=' || - op === '-=' || - op === '<<=' || - op === '>>=' || - op === '>>>=' || - op === '&=' || - op === '^=' || - op === '|='; - } - - function consumeSemicolon() { - var line; - - // Catch the very common case first: immediately a semicolon (char #59). - if (source.charCodeAt(index) === 59) { - lex(); - return; - } - - line = lineNumber; - skipComment(); - if (lineNumber !== line) { - return; - } - - if (match(';')) { - lex(); - return; - } - - if (lookahead.type !== Token.EOF && !match('}')) { - throwUnexpected(lookahead); - } - } - - // Return true if provided expression is LeftHandSideExpression - - function isLeftHandSide(expr) { - return expr.type === Syntax.Identifier || expr.type === Syntax.MemberExpression; - } - - function isAssignableLeftHandSide(expr) { - return isLeftHandSide(expr) || expr.type === Syntax.ObjectPattern || expr.type === Syntax.ArrayPattern; - } - - // 11.1.4 Array Initialiser - - function parseArrayInitialiser() { - var elements = [], blocks = [], filter = null, tmp, possiblecomprehension = true, body, - marker = markerCreate(); - - expect('['); - while (!match(']')) { - if (lookahead.value === 'for' && - lookahead.type === Token.Keyword) { - if (!possiblecomprehension) { - throwError({}, Messages.ComprehensionError); - } - matchKeyword('for'); - tmp = parseForStatement({ignoreBody: true}); - tmp.of = tmp.type === Syntax.ForOfStatement; - tmp.type = Syntax.ComprehensionBlock; - if (tmp.left.kind) { // can't be let or const - throwError({}, Messages.ComprehensionError); - } - blocks.push(tmp); - } else if (lookahead.value === 'if' && - lookahead.type === Token.Keyword) { - if (!possiblecomprehension) { - throwError({}, Messages.ComprehensionError); - } - expectKeyword('if'); - expect('('); - filter = parseExpression(); - expect(')'); - } else if (lookahead.value === ',' && - lookahead.type === Token.Punctuator) { - possiblecomprehension = false; // no longer allowed. - lex(); - elements.push(null); - } else { - tmp = parseSpreadOrAssignmentExpression(); - elements.push(tmp); - if (tmp && tmp.type === Syntax.SpreadElement) { - if (!match(']')) { - throwError({}, Messages.ElementAfterSpreadElement); - } - } else if (!(match(']') || matchKeyword('for') || matchKeyword('if'))) { - expect(','); // this lexes. - possiblecomprehension = false; - } - } - } - - expect(']'); - - if (filter && !blocks.length) { - throwError({}, Messages.ComprehensionRequiresBlock); - } - - if (blocks.length) { - if (elements.length !== 1) { - throwError({}, Messages.ComprehensionError); - } - return markerApply(marker, delegate.createComprehensionExpression(filter, blocks, elements[0])); - } - return markerApply(marker, delegate.createArrayExpression(elements)); - } - - // 11.1.5 Object Initialiser - - function parsePropertyFunction(options) { - var previousStrict, previousYieldAllowed, params, defaults, body, - marker = markerCreate(); - - previousStrict = strict; - previousYieldAllowed = state.yieldAllowed; - state.yieldAllowed = options.generator; - params = options.params || []; - defaults = options.defaults || []; - - body = parseConciseBody(); - if (options.name && strict && isRestrictedWord(params[0].name)) { - throwErrorTolerant(options.name, Messages.StrictParamName); - } - strict = previousStrict; - state.yieldAllowed = previousYieldAllowed; - - return markerApply(marker, delegate.createFunctionExpression( - null, - params, - defaults, - body, - options.rest || null, - options.generator, - body.type !== Syntax.BlockStatement, - options.returnType, - options.parametricType - )); - } - - - function parsePropertyMethodFunction(options) { - var previousStrict, tmp, method; - - previousStrict = strict; - strict = true; - - tmp = parseParams(); - - if (tmp.stricted) { - throwErrorTolerant(tmp.stricted, tmp.message); - } - - - method = parsePropertyFunction({ - params: tmp.params, - defaults: tmp.defaults, - rest: tmp.rest, - generator: options.generator, - returnType: tmp.returnType, - parametricType: options.parametricType - }); - - strict = previousStrict; - - return method; - } - - - function parseObjectPropertyKey() { - var marker = markerCreate(), - token = lex(), - propertyKey, - result; - - // Note: This function is called only from parseObjectProperty(), where - // EOF and Punctuator tokens are already filtered out. - - if (token.type === Token.StringLiteral || token.type === Token.NumericLiteral) { - if (strict && token.octal) { - throwErrorTolerant(token, Messages.StrictOctalLiteral); - } - return markerApply(marker, delegate.createLiteral(token)); - } - - if (token.type === Token.Punctuator && token.value === '[') { - // For computed properties we should skip the [ and ], and - // capture in marker only the assignment expression itself. - marker = markerCreate(); - propertyKey = parseAssignmentExpression(); - result = markerApply(marker, propertyKey); - expect(']'); - return result; - } - - return markerApply(marker, delegate.createIdentifier(token.value)); - } - - function parseObjectProperty() { - var token, key, id, value, param, expr, computed, - marker = markerCreate(); - - token = lookahead; - computed = (token.value === '['); - - if (token.type === Token.Identifier || computed) { - - id = parseObjectPropertyKey(); - - // Property Assignment: Getter and Setter. - - if (token.value === 'get' && !(match(':') || match('('))) { - computed = (lookahead.value === '['); - key = parseObjectPropertyKey(); - expect('('); - expect(')'); - return markerApply(marker, delegate.createProperty('get', key, parsePropertyFunction({ generator: false }), false, false, computed)); - } - if (token.value === 'set' && !(match(':') || match('('))) { - computed = (lookahead.value === '['); - key = parseObjectPropertyKey(); - expect('('); - token = lookahead; - param = [ parseTypeAnnotatableIdentifier() ]; - expect(')'); - return markerApply(marker, delegate.createProperty('set', key, parsePropertyFunction({ params: param, generator: false, name: token }), false, false, computed)); - } - if (match(':')) { - lex(); - return markerApply(marker, delegate.createProperty('init', id, parseAssignmentExpression(), false, false, computed)); - } - if (match('(')) { - return markerApply(marker, delegate.createProperty('init', id, parsePropertyMethodFunction({ generator: false }), true, false, computed)); - } - if (computed) { - // Computed properties can only be used with full notation. - throwUnexpected(lookahead); - } - return markerApply(marker, delegate.createProperty('init', id, id, false, true, false)); - } - if (token.type === Token.EOF || token.type === Token.Punctuator) { - if (!match('*')) { - throwUnexpected(token); - } - lex(); - - computed = (lookahead.type === Token.Punctuator && lookahead.value === '['); - - id = parseObjectPropertyKey(); - - if (!match('(')) { - throwUnexpected(lex()); - } - - return markerApply(marker, delegate.createProperty('init', id, parsePropertyMethodFunction({ generator: true }), true, false, computed)); - } - key = parseObjectPropertyKey(); - if (match(':')) { - lex(); - return markerApply(marker, delegate.createProperty('init', key, parseAssignmentExpression(), false, false, false)); - } - if (match('(')) { - return markerApply(marker, delegate.createProperty('init', key, parsePropertyMethodFunction({ generator: false }), true, false, false)); - } - throwUnexpected(lex()); - } - - function parseObjectSpreadProperty() { - var marker = markerCreate(); - expect('...'); - return markerApply(marker, delegate.createSpreadProperty(parseAssignmentExpression())); - } - - function parseObjectInitialiser() { - var properties = [], property, name, key, kind, map = {}, toString = String, - marker = markerCreate(); - - expect('{'); - - while (!match('}')) { - if (match('...')) { - property = parseObjectSpreadProperty(); - } else { - property = parseObjectProperty(); - - if (property.key.type === Syntax.Identifier) { - name = property.key.name; - } else { - name = toString(property.key.value); - } - kind = (property.kind === 'init') ? PropertyKind.Data : (property.kind === 'get') ? PropertyKind.Get : PropertyKind.Set; - - key = '$' + name; - if (Object.prototype.hasOwnProperty.call(map, key)) { - if (map[key] === PropertyKind.Data) { - if (strict && kind === PropertyKind.Data) { - throwErrorTolerant({}, Messages.StrictDuplicateProperty); - } else if (kind !== PropertyKind.Data) { - throwErrorTolerant({}, Messages.AccessorDataProperty); - } - } else { - if (kind === PropertyKind.Data) { - throwErrorTolerant({}, Messages.AccessorDataProperty); - } else if (map[key] & kind) { - throwErrorTolerant({}, Messages.AccessorGetSet); - } - } - map[key] |= kind; - } else { - map[key] = kind; - } - } - - properties.push(property); - - if (!match('}')) { - expect(','); - } - } - - expect('}'); - - return markerApply(marker, delegate.createObjectExpression(properties)); - } - - function parseTemplateElement(option) { - var marker = markerCreate(), - token = scanTemplateElement(option); - if (strict && token.octal) { - throwError(token, Messages.StrictOctalLiteral); - } - return markerApply(marker, delegate.createTemplateElement({ raw: token.value.raw, cooked: token.value.cooked }, token.tail)); - } - - function parseTemplateLiteral() { - var quasi, quasis, expressions, marker = markerCreate(); - - quasi = parseTemplateElement({ head: true }); - quasis = [ quasi ]; - expressions = []; - - while (!quasi.tail) { - expressions.push(parseExpression()); - quasi = parseTemplateElement({ head: false }); - quasis.push(quasi); - } - - return markerApply(marker, delegate.createTemplateLiteral(quasis, expressions)); - } - - // 11.1.6 The Grouping Operator - - function parseGroupExpression() { - var expr; - - expect('('); - - ++state.parenthesizedCount; - - expr = parseExpression(); - - expect(')'); - - return expr; - } - - - // 11.1 Primary Expressions - - function parsePrimaryExpression() { - var marker, type, token, expr; - - type = lookahead.type; - - if (type === Token.Identifier) { - marker = markerCreate(); - return markerApply(marker, delegate.createIdentifier(lex().value)); - } - - if (type === Token.StringLiteral || type === Token.NumericLiteral) { - if (strict && lookahead.octal) { - throwErrorTolerant(lookahead, Messages.StrictOctalLiteral); - } - marker = markerCreate(); - return markerApply(marker, delegate.createLiteral(lex())); - } - - if (type === Token.Keyword) { - if (matchKeyword('this')) { - marker = markerCreate(); - lex(); - return markerApply(marker, delegate.createThisExpression()); - } - - if (matchKeyword('function')) { - return parseFunctionExpression(); - } - - if (matchKeyword('class')) { - return parseClassExpression(); - } - - if (matchKeyword('super')) { - marker = markerCreate(); - lex(); - return markerApply(marker, delegate.createIdentifier('super')); - } - } - - if (type === Token.BooleanLiteral) { - marker = markerCreate(); - token = lex(); - token.value = (token.value === 'true'); - return markerApply(marker, delegate.createLiteral(token)); - } - - if (type === Token.NullLiteral) { - marker = markerCreate(); - token = lex(); - token.value = null; - return markerApply(marker, delegate.createLiteral(token)); - } - - if (match('[')) { - return parseArrayInitialiser(); - } - - if (match('{')) { - return parseObjectInitialiser(); - } - - if (match('(')) { - return parseGroupExpression(); - } - - if (match('/') || match('/=')) { - marker = markerCreate(); - return markerApply(marker, delegate.createLiteral(scanRegExp())); - } - - if (type === Token.Template) { - return parseTemplateLiteral(); - } - - if (match('<')) { - return parseXJSElement(); - } - - throwUnexpected(lex()); - } - - // 11.2 Left-Hand-Side Expressions - - function parseArguments() { - var args = [], arg; - - expect('('); - - if (!match(')')) { - while (index < length) { - arg = parseSpreadOrAssignmentExpression(); - args.push(arg); - - if (match(')')) { - break; - } else if (arg.type === Syntax.SpreadElement) { - throwError({}, Messages.ElementAfterSpreadElement); - } - - expect(','); - } - } - - expect(')'); - - return args; - } - - function parseSpreadOrAssignmentExpression() { - if (match('...')) { - var marker = markerCreate(); - lex(); - return markerApply(marker, delegate.createSpreadElement(parseAssignmentExpression())); - } - return parseAssignmentExpression(); - } - - function parseNonComputedProperty() { - var marker = markerCreate(), - token = lex(); - - if (!isIdentifierName(token)) { - throwUnexpected(token); - } - - return markerApply(marker, delegate.createIdentifier(token.value)); - } - - function parseNonComputedMember() { - expect('.'); - - return parseNonComputedProperty(); - } - - function parseComputedMember() { - var expr; - - expect('['); - - expr = parseExpression(); - - expect(']'); - - return expr; - } - - function parseNewExpression() { - var callee, args, marker = markerCreate(); - - expectKeyword('new'); - callee = parseLeftHandSideExpression(); - args = match('(') ? parseArguments() : []; - - return markerApply(marker, delegate.createNewExpression(callee, args)); - } - - function parseLeftHandSideExpressionAllowCall() { - var expr, args, marker = markerCreate(); - - expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression(); - - while (match('.') || match('[') || match('(') || lookahead.type === Token.Template) { - if (match('(')) { - args = parseArguments(); - expr = markerApply(marker, delegate.createCallExpression(expr, args)); - } else if (match('[')) { - expr = markerApply(marker, delegate.createMemberExpression('[', expr, parseComputedMember())); - } else if (match('.')) { - expr = markerApply(marker, delegate.createMemberExpression('.', expr, parseNonComputedMember())); - } else { - expr = markerApply(marker, delegate.createTaggedTemplateExpression(expr, parseTemplateLiteral())); - } - } - - return expr; - } - - function parseLeftHandSideExpression() { - var expr, marker = markerCreate(); - - expr = matchKeyword('new') ? parseNewExpression() : parsePrimaryExpression(); - - while (match('.') || match('[') || lookahead.type === Token.Template) { - if (match('[')) { - expr = markerApply(marker, delegate.createMemberExpression('[', expr, parseComputedMember())); - } else if (match('.')) { - expr = markerApply(marker, delegate.createMemberExpression('.', expr, parseNonComputedMember())); - } else { - expr = markerApply(marker, delegate.createTaggedTemplateExpression(expr, parseTemplateLiteral())); - } - } - - return expr; - } - - // 11.3 Postfix Expressions - - function parsePostfixExpression() { - var marker = markerCreate(), - expr = parseLeftHandSideExpressionAllowCall(), - token; - - if (lookahead.type !== Token.Punctuator) { - return expr; - } - - if ((match('++') || match('--')) && !peekLineTerminator()) { - // 11.3.1, 11.3.2 - if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) { - throwErrorTolerant({}, Messages.StrictLHSPostfix); - } - - if (!isLeftHandSide(expr)) { - throwError({}, Messages.InvalidLHSInAssignment); - } - - token = lex(); - expr = markerApply(marker, delegate.createPostfixExpression(token.value, expr)); - } - - return expr; - } - - // 11.4 Unary Operators - - function parseUnaryExpression() { - var marker, token, expr; - - if (lookahead.type !== Token.Punctuator && lookahead.type !== Token.Keyword) { - return parsePostfixExpression(); - } - - if (match('++') || match('--')) { - marker = markerCreate(); - token = lex(); - expr = parseUnaryExpression(); - // 11.4.4, 11.4.5 - if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) { - throwErrorTolerant({}, Messages.StrictLHSPrefix); - } - - if (!isLeftHandSide(expr)) { - throwError({}, Messages.InvalidLHSInAssignment); - } - - return markerApply(marker, delegate.createUnaryExpression(token.value, expr)); - } - - if (match('+') || match('-') || match('~') || match('!')) { - marker = markerCreate(); - token = lex(); - expr = parseUnaryExpression(); - return markerApply(marker, delegate.createUnaryExpression(token.value, expr)); - } - - if (matchKeyword('delete') || matchKeyword('void') || matchKeyword('typeof')) { - marker = markerCreate(); - token = lex(); - expr = parseUnaryExpression(); - expr = markerApply(marker, delegate.createUnaryExpression(token.value, expr)); - if (strict && expr.operator === 'delete' && expr.argument.type === Syntax.Identifier) { - throwErrorTolerant({}, Messages.StrictDelete); - } - return expr; - } - - return parsePostfixExpression(); - } - - function binaryPrecedence(token, allowIn) { - var prec = 0; - - if (token.type !== Token.Punctuator && token.type !== Token.Keyword) { - return 0; - } - - switch (token.value) { - case '||': - prec = 1; - break; - - case '&&': - prec = 2; - break; - - case '|': - prec = 3; - break; - - case '^': - prec = 4; - break; - - case '&': - prec = 5; - break; - - case '==': - case '!=': - case '===': - case '!==': - prec = 6; - break; - - case '<': - case '>': - case '<=': - case '>=': - case 'instanceof': - prec = 7; - break; - - case 'in': - prec = allowIn ? 7 : 0; - break; - - case '<<': - case '>>': - case '>>>': - prec = 8; - break; - - case '+': - case '-': - prec = 9; - break; - - case '*': - case '/': - case '%': - prec = 11; - break; - - default: - break; - } - - return prec; - } - - // 11.5 Multiplicative Operators - // 11.6 Additive Operators - // 11.7 Bitwise Shift Operators - // 11.8 Relational Operators - // 11.9 Equality Operators - // 11.10 Binary Bitwise Operators - // 11.11 Binary Logical Operators - - function parseBinaryExpression() { - var expr, token, prec, previousAllowIn, stack, right, operator, left, i, - marker, markers; - - previousAllowIn = state.allowIn; - state.allowIn = true; - - marker = markerCreate(); - left = parseUnaryExpression(); - - token = lookahead; - prec = binaryPrecedence(token, previousAllowIn); - if (prec === 0) { - return left; - } - token.prec = prec; - lex(); - - markers = [marker, markerCreate()]; - right = parseUnaryExpression(); - - stack = [left, token, right]; - - while ((prec = binaryPrecedence(lookahead, previousAllowIn)) > 0) { - - // Reduce: make a binary expression from the three topmost entries. - while ((stack.length > 2) && (prec <= stack[stack.length - 2].prec)) { - right = stack.pop(); - operator = stack.pop().value; - left = stack.pop(); - expr = delegate.createBinaryExpression(operator, left, right); - markers.pop(); - marker = markers.pop(); - markerApply(marker, expr); - stack.push(expr); - markers.push(marker); - } - - // Shift. - token = lex(); - token.prec = prec; - stack.push(token); - markers.push(markerCreate()); - expr = parseUnaryExpression(); - stack.push(expr); - } - - state.allowIn = previousAllowIn; - - // Final reduce to clean-up the stack. - i = stack.length - 1; - expr = stack[i]; - markers.pop(); - while (i > 1) { - expr = delegate.createBinaryExpression(stack[i - 1].value, stack[i - 2], expr); - i -= 2; - marker = markers.pop(); - markerApply(marker, expr); - } - - return expr; - } - - - // 11.12 Conditional Operator - - function parseConditionalExpression() { - var expr, previousAllowIn, consequent, alternate, marker = markerCreate(); - expr = parseBinaryExpression(); - - if (match('?')) { - lex(); - previousAllowIn = state.allowIn; - state.allowIn = true; - consequent = parseAssignmentExpression(); - state.allowIn = previousAllowIn; - expect(':'); - alternate = parseAssignmentExpression(); - - expr = markerApply(marker, delegate.createConditionalExpression(expr, consequent, alternate)); - } - - return expr; - } - - // 11.13 Assignment Operators - - function reinterpretAsAssignmentBindingPattern(expr) { - var i, len, property, element; - - if (expr.type === Syntax.ObjectExpression) { - expr.type = Syntax.ObjectPattern; - for (i = 0, len = expr.properties.length; i < len; i += 1) { - property = expr.properties[i]; - if (property.type === Syntax.SpreadProperty) { - if (i < len - 1) { - throwError({}, Messages.PropertyAfterSpreadProperty); - } - reinterpretAsAssignmentBindingPattern(property.argument); - } else { - if (property.kind !== 'init') { - throwError({}, Messages.InvalidLHSInAssignment); - } - reinterpretAsAssignmentBindingPattern(property.value); - } - } - } else if (expr.type === Syntax.ArrayExpression) { - expr.type = Syntax.ArrayPattern; - for (i = 0, len = expr.elements.length; i < len; i += 1) { - element = expr.elements[i]; - if (element) { - reinterpretAsAssignmentBindingPattern(element); - } - } - } else if (expr.type === Syntax.Identifier) { - if (isRestrictedWord(expr.name)) { - throwError({}, Messages.InvalidLHSInAssignment); - } - } else if (expr.type === Syntax.SpreadElement) { - reinterpretAsAssignmentBindingPattern(expr.argument); - if (expr.argument.type === Syntax.ObjectPattern) { - throwError({}, Messages.ObjectPatternAsSpread); - } - } else { - if (expr.type !== Syntax.MemberExpression && expr.type !== Syntax.CallExpression && expr.type !== Syntax.NewExpression) { - throwError({}, Messages.InvalidLHSInAssignment); - } - } - } - - - function reinterpretAsDestructuredParameter(options, expr) { - var i, len, property, element; - - if (expr.type === Syntax.ObjectExpression) { - expr.type = Syntax.ObjectPattern; - for (i = 0, len = expr.properties.length; i < len; i += 1) { - property = expr.properties[i]; - if (property.type === Syntax.SpreadProperty) { - if (i < len - 1) { - throwError({}, Messages.PropertyAfterSpreadProperty); - } - reinterpretAsDestructuredParameter(options, property.argument); - } else { - if (property.kind !== 'init') { - throwError({}, Messages.InvalidLHSInFormalsList); - } - reinterpretAsDestructuredParameter(options, property.value); - } - } - } else if (expr.type === Syntax.ArrayExpression) { - expr.type = Syntax.ArrayPattern; - for (i = 0, len = expr.elements.length; i < len; i += 1) { - element = expr.elements[i]; - if (element) { - reinterpretAsDestructuredParameter(options, element); - } - } - } else if (expr.type === Syntax.Identifier) { - validateParam(options, expr, expr.name); - } else { - if (expr.type !== Syntax.MemberExpression) { - throwError({}, Messages.InvalidLHSInFormalsList); - } - } - } - - function reinterpretAsCoverFormalsList(expressions) { - var i, len, param, params, defaults, defaultCount, options, rest; - - params = []; - defaults = []; - defaultCount = 0; - rest = null; - options = { - paramSet: {} - }; - - for (i = 0, len = expressions.length; i < len; i += 1) { - param = expressions[i]; - if (param.type === Syntax.Identifier) { - params.push(param); - defaults.push(null); - validateParam(options, param, param.name); - } else if (param.type === Syntax.ObjectExpression || param.type === Syntax.ArrayExpression) { - reinterpretAsDestructuredParameter(options, param); - params.push(param); - defaults.push(null); - } else if (param.type === Syntax.SpreadElement) { - assert(i === len - 1, 'It is guaranteed that SpreadElement is last element by parseExpression'); - reinterpretAsDestructuredParameter(options, param.argument); - rest = param.argument; - } else if (param.type === Syntax.AssignmentExpression) { - params.push(param.left); - defaults.push(param.right); - ++defaultCount; - validateParam(options, param.left, param.left.name); - } else { - return null; - } - } - - if (options.message === Messages.StrictParamDupe) { - throwError( - strict ? options.stricted : options.firstRestricted, - options.message - ); - } - - if (defaultCount === 0) { - defaults = []; - } - - return { - params: params, - defaults: defaults, - rest: rest, - stricted: options.stricted, - firstRestricted: options.firstRestricted, - message: options.message - }; - } - - function parseArrowFunctionExpression(options, marker) { - var previousStrict, previousYieldAllowed, body; - - expect('=>'); - - previousStrict = strict; - previousYieldAllowed = state.yieldAllowed; - state.yieldAllowed = false; - body = parseConciseBody(); - - if (strict && options.firstRestricted) { - throwError(options.firstRestricted, options.message); - } - if (strict && options.stricted) { - throwErrorTolerant(options.stricted, options.message); - } - - strict = previousStrict; - state.yieldAllowed = previousYieldAllowed; - - return markerApply(marker, delegate.createArrowFunctionExpression( - options.params, - options.defaults, - body, - options.rest, - body.type !== Syntax.BlockStatement - )); - } - - function parseAssignmentExpression() { - var marker, expr, token, params, oldParenthesizedCount; - - // Note that 'yield' is treated as a keyword in strict mode, but a - // contextual keyword (identifier) in non-strict mode, so we need - // to use matchKeyword and matchContextualKeyword appropriately. - if ((state.yieldAllowed && matchContextualKeyword('yield')) || (strict && matchKeyword('yield'))) { - return parseYieldExpression(); - } - - oldParenthesizedCount = state.parenthesizedCount; - - marker = markerCreate(); - - if (match('(')) { - token = lookahead2(); - if ((token.type === Token.Punctuator && token.value === ')') || token.value === '...') { - params = parseParams(); - if (!match('=>')) { - throwUnexpected(lex()); - } - return parseArrowFunctionExpression(params, marker); - } - } - - token = lookahead; - expr = parseConditionalExpression(); - - if (match('=>') && - (state.parenthesizedCount === oldParenthesizedCount || - state.parenthesizedCount === (oldParenthesizedCount + 1))) { - if (expr.type === Syntax.Identifier) { - params = reinterpretAsCoverFormalsList([ expr ]); - } else if (expr.type === Syntax.SequenceExpression) { - params = reinterpretAsCoverFormalsList(expr.expressions); - } - if (params) { - return parseArrowFunctionExpression(params, marker); - } - } - - if (matchAssign()) { - // 11.13.1 - if (strict && expr.type === Syntax.Identifier && isRestrictedWord(expr.name)) { - throwErrorTolerant(token, Messages.StrictLHSAssignment); - } - - // ES.next draf 11.13 Runtime Semantics step 1 - if (match('=') && (expr.type === Syntax.ObjectExpression || expr.type === Syntax.ArrayExpression)) { - reinterpretAsAssignmentBindingPattern(expr); - } else if (!isLeftHandSide(expr)) { - throwError({}, Messages.InvalidLHSInAssignment); - } - - expr = markerApply(marker, delegate.createAssignmentExpression(lex().value, expr, parseAssignmentExpression())); - } - - return expr; - } - - // 11.14 Comma Operator - - function parseExpression() { - var marker, expr, expressions, sequence, coverFormalsList, spreadFound, oldParenthesizedCount; - - oldParenthesizedCount = state.parenthesizedCount; - - marker = markerCreate(); - expr = parseAssignmentExpression(); - expressions = [ expr ]; - - if (match(',')) { - while (index < length) { - if (!match(',')) { - break; - } - - lex(); - expr = parseSpreadOrAssignmentExpression(); - expressions.push(expr); - - if (expr.type === Syntax.SpreadElement) { - spreadFound = true; - if (!match(')')) { - throwError({}, Messages.ElementAfterSpreadElement); - } - break; - } - } - - sequence = markerApply(marker, delegate.createSequenceExpression(expressions)); - } - - if (match('=>')) { - // Do not allow nested parentheses on the LHS of the =>. - if (state.parenthesizedCount === oldParenthesizedCount || state.parenthesizedCount === (oldParenthesizedCount + 1)) { - expr = expr.type === Syntax.SequenceExpression ? expr.expressions : expressions; - coverFormalsList = reinterpretAsCoverFormalsList(expr); - if (coverFormalsList) { - return parseArrowFunctionExpression(coverFormalsList, marker); - } - } - throwUnexpected(lex()); - } - - if (spreadFound && lookahead2().value !== '=>') { - throwError({}, Messages.IllegalSpread); - } - - return sequence || expr; - } - - // 12.1 Block - - function parseStatementList() { - var list = [], - statement; - - while (index < length) { - if (match('}')) { - break; - } - statement = parseSourceElement(); - if (typeof statement === 'undefined') { - break; - } - list.push(statement); - } - - return list; - } - - function parseBlock() { - var block, marker = markerCreate(); - - expect('{'); - - block = parseStatementList(); - - expect('}'); - - return markerApply(marker, delegate.createBlockStatement(block)); - } - - // 12.2 Variable Statement - - function parseObjectTypeAnnotation() { - var isMethod, marker, properties = [], property, propertyKey, - propertyTypeAnnotation; - - expect('{'); - - while (!match('}')) { - marker = markerCreate(); - propertyKey = parseObjectPropertyKey(); - isMethod = match('('); - propertyTypeAnnotation = parseTypeAnnotation(); - properties.push(markerApply(marker, delegate.createProperty( - 'init', - propertyKey, - propertyTypeAnnotation, - isMethod, - false - ))); - - if (!match('}')) { - if (match(',') || match(';')) { - lex(); - } else { - throwUnexpected(lookahead); - } - } - } - - expect('}'); - - return delegate.createObjectTypeAnnotation(properties); - } - - function parseVoidTypeAnnotation() { - var marker = markerCreate(); - expectKeyword('void'); - return markerApply(marker, delegate.createVoidTypeAnnotation()); - } - - function parseParametricTypeAnnotation() { - var marker = markerCreate(), typeIdentifier, paramTypes = []; - - expect('<'); - while (!match('>')) { - paramTypes.push(parseVariableIdentifier()); - if (!match('>')) { - expect(','); - } - } - expect('>'); - - return markerApply(marker, delegate.createParametricTypeAnnotation( - paramTypes - )); - } - - function parseTypeAnnotation(dontExpectColon) { - var typeIdentifier = null, params = null, returnType = null, - nullable = false, marker = markerCreate(), returnTypeMarker = null, - parametricType, annotation; - - if (!dontExpectColon) { - expect(':'); - } - - if (match('{')) { - return markerApply(marker, parseObjectTypeAnnotation()); - } - - if (match('?')) { - lex(); - nullable = true; - } - - if (lookahead.type === Token.Identifier) { - typeIdentifier = parseVariableIdentifier(); - if (match('<')) { - parametricType = parseParametricTypeAnnotation(); - } - } else if (match('(')) { - lex(); - params = []; - while (lookahead.type === Token.Identifier || match('?')) { - params.push(parseTypeAnnotatableIdentifier( - true, /* requireTypeAnnotation */ - true /* canBeOptionalParam */ - )); - if (!match(')')) { - expect(','); - } - } - expect(')'); - - returnTypeMarker = markerCreate(); - expect('=>'); - - returnType = parseTypeAnnotation(true); - } else { - if (!matchKeyword('void')) { - throwUnexpected(lookahead); - } else { - return parseVoidTypeAnnotation(); - } - } - - return markerApply(marker, delegate.createTypeAnnotation( - typeIdentifier, - parametricType, - params, - returnType, - nullable - )); - } - - function parseVariableIdentifier() { - var marker = markerCreate(), - token = lex(); - - if (token.type !== Token.Identifier) { - throwUnexpected(token); - } - - return markerApply(marker, delegate.createIdentifier(token.value)); - } - - function parseTypeAnnotatableIdentifier(requireTypeAnnotation, canBeOptionalParam) { - var marker = markerCreate(), - ident = parseVariableIdentifier(), - isOptionalParam = false; - - if (canBeOptionalParam && match('?')) { - expect('?'); - isOptionalParam = true; - } - - if (requireTypeAnnotation || match(':')) { - ident = markerApply(marker, delegate.createTypeAnnotatedIdentifier( - ident, - parseTypeAnnotation() - )); - } - - if (isOptionalParam) { - ident = markerApply(marker, delegate.createOptionalParameter(ident)); - } - - return ident; - } - - function parseVariableDeclaration(kind) { - var id, - marker = markerCreate(), - init = null; - if (match('{')) { - id = parseObjectInitialiser(); - reinterpretAsAssignmentBindingPattern(id); - } else if (match('[')) { - id = parseArrayInitialiser(); - reinterpretAsAssignmentBindingPattern(id); - } else { - id = state.allowKeyword ? parseNonComputedProperty() : parseTypeAnnotatableIdentifier(); - // 12.2.1 - if (strict && isRestrictedWord(id.name)) { - throwErrorTolerant({}, Messages.StrictVarName); - } - } - - if (kind === 'const') { - if (!match('=')) { - throwError({}, Messages.NoUnintializedConst); - } - expect('='); - init = parseAssignmentExpression(); - } else if (match('=')) { - lex(); - init = parseAssignmentExpression(); - } - - return markerApply(marker, delegate.createVariableDeclarator(id, init)); - } - - function parseVariableDeclarationList(kind) { - var list = []; - - do { - list.push(parseVariableDeclaration(kind)); - if (!match(',')) { - break; - } - lex(); - } while (index < length); - - return list; - } - - function parseVariableStatement() { - var declarations, marker = markerCreate(); - - expectKeyword('var'); - - declarations = parseVariableDeclarationList(); - - consumeSemicolon(); - - return markerApply(marker, delegate.createVariableDeclaration(declarations, 'var')); - } - - // kind may be `const` or `let` - // Both are experimental and not in the specification yet. - // see http://wiki.ecmascript.org/doku.php?id=harmony:const - // and http://wiki.ecmascript.org/doku.php?id=harmony:let - function parseConstLetDeclaration(kind) { - var declarations, marker = markerCreate(); - - expectKeyword(kind); - - declarations = parseVariableDeclarationList(kind); - - consumeSemicolon(); - - return markerApply(marker, delegate.createVariableDeclaration(declarations, kind)); - } - - // http://wiki.ecmascript.org/doku.php?id=harmony:modules - - function parseModuleDeclaration() { - var id, src, body, marker = markerCreate(); - - lex(); // 'module' - - if (peekLineTerminator()) { - throwError({}, Messages.NewlineAfterModule); - } - - switch (lookahead.type) { - - case Token.StringLiteral: - id = parsePrimaryExpression(); - body = parseModuleBlock(); - src = null; - break; - - case Token.Identifier: - id = parseVariableIdentifier(); - body = null; - if (!matchContextualKeyword('from')) { - throwUnexpected(lex()); - } - lex(); - src = parsePrimaryExpression(); - if (src.type !== Syntax.Literal) { - throwError({}, Messages.InvalidModuleSpecifier); - } - break; - } - - consumeSemicolon(); - return markerApply(marker, delegate.createModuleDeclaration(id, src, body)); - } - - function parseExportBatchSpecifier() { - var marker = markerCreate(); - expect('*'); - return markerApply(marker, delegate.createExportBatchSpecifier()); - } - - function parseExportSpecifier() { - var id, name = null, marker = markerCreate(); - - id = parseVariableIdentifier(); - if (matchContextualKeyword('as')) { - lex(); - name = parseNonComputedProperty(); - } - - return markerApply(marker, delegate.createExportSpecifier(id, name)); - } - - function parseExportDeclaration() { - var previousAllowKeyword, decl, def, src, specifiers, - marker = markerCreate(); - - expectKeyword('export'); - - if (lookahead.type === Token.Keyword) { - switch (lookahead.value) { - case 'let': - case 'const': - case 'var': - case 'class': - case 'function': - return markerApply(marker, delegate.createExportDeclaration(parseSourceElement(), null, null)); - } - } - - if (isIdentifierName(lookahead)) { - previousAllowKeyword = state.allowKeyword; - state.allowKeyword = true; - decl = parseVariableDeclarationList('let'); - state.allowKeyword = previousAllowKeyword; - return markerApply(marker, delegate.createExportDeclaration(decl, null, null)); - } - - specifiers = []; - src = null; - - if (match('*')) { - specifiers.push(parseExportBatchSpecifier()); - } else { - expect('{'); - do { - specifiers.push(parseExportSpecifier()); - } while (match(',') && lex()); - expect('}'); - } - - if (matchContextualKeyword('from')) { - lex(); - src = parsePrimaryExpression(); - if (src.type !== Syntax.Literal) { - throwError({}, Messages.InvalidModuleSpecifier); - } - } - - consumeSemicolon(); - - return markerApply(marker, delegate.createExportDeclaration(null, specifiers, src)); - } - - function parseImportDeclaration() { - var specifiers, kind, src, marker = markerCreate(); - - expectKeyword('import'); - specifiers = []; - - if (isIdentifierName(lookahead)) { - kind = 'default'; - specifiers.push(parseImportSpecifier()); - - if (!matchContextualKeyword('from')) { - throwError({}, Messages.NoFromAfterImport); - } - lex(); - } else if (match('{')) { - kind = 'named'; - lex(); - do { - specifiers.push(parseImportSpecifier()); - } while (match(',') && lex()); - expect('}'); - - if (!matchContextualKeyword('from')) { - throwError({}, Messages.NoFromAfterImport); - } - lex(); - } - - src = parsePrimaryExpression(); - if (src.type !== Syntax.Literal) { - throwError({}, Messages.InvalidModuleSpecifier); - } - - consumeSemicolon(); - - return markerApply(marker, delegate.createImportDeclaration(specifiers, kind, src)); - } - - function parseImportSpecifier() { - var id, name = null, marker = markerCreate(); - - id = parseNonComputedProperty(); - if (matchContextualKeyword('as')) { - lex(); - name = parseVariableIdentifier(); - } - - return markerApply(marker, delegate.createImportSpecifier(id, name)); - } - - // 12.3 Empty Statement - - function parseEmptyStatement() { - var marker = markerCreate(); - expect(';'); - return markerApply(marker, delegate.createEmptyStatement()); - } - - // 12.4 Expression Statement - - function parseExpressionStatement() { - var marker = markerCreate(), expr = parseExpression(); - consumeSemicolon(); - return markerApply(marker, delegate.createExpressionStatement(expr)); - } - - // 12.5 If statement - - function parseIfStatement() { - var test, consequent, alternate, marker = markerCreate(); - - expectKeyword('if'); - - expect('('); - - test = parseExpression(); - - expect(')'); - - consequent = parseStatement(); - - if (matchKeyword('else')) { - lex(); - alternate = parseStatement(); - } else { - alternate = null; - } - - return markerApply(marker, delegate.createIfStatement(test, consequent, alternate)); - } - - // 12.6 Iteration Statements - - function parseDoWhileStatement() { - var body, test, oldInIteration, marker = markerCreate(); - - expectKeyword('do'); - - oldInIteration = state.inIteration; - state.inIteration = true; - - body = parseStatement(); - - state.inIteration = oldInIteration; - - expectKeyword('while'); - - expect('('); - - test = parseExpression(); - - expect(')'); - - if (match(';')) { - lex(); - } - - return markerApply(marker, delegate.createDoWhileStatement(body, test)); - } - - function parseWhileStatement() { - var test, body, oldInIteration, marker = markerCreate(); - - expectKeyword('while'); - - expect('('); - - test = parseExpression(); - - expect(')'); - - oldInIteration = state.inIteration; - state.inIteration = true; - - body = parseStatement(); - - state.inIteration = oldInIteration; - - return markerApply(marker, delegate.createWhileStatement(test, body)); - } - - function parseForVariableDeclaration() { - var marker = markerCreate(), - token = lex(), - declarations = parseVariableDeclarationList(); - - return markerApply(marker, delegate.createVariableDeclaration(declarations, token.value)); - } - - function parseForStatement(opts) { - var init, test, update, left, right, body, operator, oldInIteration, - marker = markerCreate(); - init = test = update = null; - expectKeyword('for'); - - // http://wiki.ecmascript.org/doku.php?id=proposals:iterators_and_generators&s=each - if (matchContextualKeyword('each')) { - throwError({}, Messages.EachNotAllowed); - } - - expect('('); - - if (match(';')) { - lex(); - } else { - if (matchKeyword('var') || matchKeyword('let') || matchKeyword('const')) { - state.allowIn = false; - init = parseForVariableDeclaration(); - state.allowIn = true; - - if (init.declarations.length === 1) { - if (matchKeyword('in') || matchContextualKeyword('of')) { - operator = lookahead; - if (!((operator.value === 'in' || init.kind !== 'var') && init.declarations[0].init)) { - lex(); - left = init; - right = parseExpression(); - init = null; - } - } - } - } else { - state.allowIn = false; - init = parseExpression(); - state.allowIn = true; - - if (matchContextualKeyword('of')) { - operator = lex(); - left = init; - right = parseExpression(); - init = null; - } else if (matchKeyword('in')) { - // LeftHandSideExpression - if (!isAssignableLeftHandSide(init)) { - throwError({}, Messages.InvalidLHSInForIn); - } - operator = lex(); - left = init; - right = parseExpression(); - init = null; - } - } - - if (typeof left === 'undefined') { - expect(';'); - } - } - - if (typeof left === 'undefined') { - - if (!match(';')) { - test = parseExpression(); - } - expect(';'); - - if (!match(')')) { - update = parseExpression(); - } - } - - expect(')'); - - oldInIteration = state.inIteration; - state.inIteration = true; - - if (!(opts !== undefined && opts.ignoreBody)) { - body = parseStatement(); - } - - state.inIteration = oldInIteration; - - if (typeof left === 'undefined') { - return markerApply(marker, delegate.createForStatement(init, test, update, body)); - } - - if (operator.value === 'in') { - return markerApply(marker, delegate.createForInStatement(left, right, body)); - } - return markerApply(marker, delegate.createForOfStatement(left, right, body)); - } - - // 12.7 The continue statement - - function parseContinueStatement() { - var label = null, key, marker = markerCreate(); - - expectKeyword('continue'); - - // Optimize the most common form: 'continue;'. - if (source.charCodeAt(index) === 59) { - lex(); - - if (!state.inIteration) { - throwError({}, Messages.IllegalContinue); - } - - return markerApply(marker, delegate.createContinueStatement(null)); - } - - if (peekLineTerminator()) { - if (!state.inIteration) { - throwError({}, Messages.IllegalContinue); - } - - return markerApply(marker, delegate.createContinueStatement(null)); - } - - if (lookahead.type === Token.Identifier) { - label = parseVariableIdentifier(); - - key = '$' + label.name; - if (!Object.prototype.hasOwnProperty.call(state.labelSet, key)) { - throwError({}, Messages.UnknownLabel, label.name); - } - } - - consumeSemicolon(); - - if (label === null && !state.inIteration) { - throwError({}, Messages.IllegalContinue); - } - - return markerApply(marker, delegate.createContinueStatement(label)); - } - - // 12.8 The break statement - - function parseBreakStatement() { - var label = null, key, marker = markerCreate(); - - expectKeyword('break'); - - // Catch the very common case first: immediately a semicolon (char #59). - if (source.charCodeAt(index) === 59) { - lex(); - - if (!(state.inIteration || state.inSwitch)) { - throwError({}, Messages.IllegalBreak); - } - - return markerApply(marker, delegate.createBreakStatement(null)); - } - - if (peekLineTerminator()) { - if (!(state.inIteration || state.inSwitch)) { - throwError({}, Messages.IllegalBreak); - } - - return markerApply(marker, delegate.createBreakStatement(null)); - } - - if (lookahead.type === Token.Identifier) { - label = parseVariableIdentifier(); - - key = '$' + label.name; - if (!Object.prototype.hasOwnProperty.call(state.labelSet, key)) { - throwError({}, Messages.UnknownLabel, label.name); - } - } - - consumeSemicolon(); - - if (label === null && !(state.inIteration || state.inSwitch)) { - throwError({}, Messages.IllegalBreak); - } - - return markerApply(marker, delegate.createBreakStatement(label)); - } - - // 12.9 The return statement - - function parseReturnStatement() { - var argument = null, marker = markerCreate(); - - expectKeyword('return'); - - if (!state.inFunctionBody) { - throwErrorTolerant({}, Messages.IllegalReturn); - } - - // 'return' followed by a space and an identifier is very common. - if (source.charCodeAt(index) === 32) { - if (isIdentifierStart(source.charCodeAt(index + 1))) { - argument = parseExpression(); - consumeSemicolon(); - return markerApply(marker, delegate.createReturnStatement(argument)); - } - } - - if (peekLineTerminator()) { - return markerApply(marker, delegate.createReturnStatement(null)); - } - - if (!match(';')) { - if (!match('}') && lookahead.type !== Token.EOF) { - argument = parseExpression(); - } - } - - consumeSemicolon(); - - return markerApply(marker, delegate.createReturnStatement(argument)); - } - - // 12.10 The with statement - - function parseWithStatement() { - var object, body, marker = markerCreate(); - - if (strict) { - throwErrorTolerant({}, Messages.StrictModeWith); - } - - expectKeyword('with'); - - expect('('); - - object = parseExpression(); - - expect(')'); - - body = parseStatement(); - - return markerApply(marker, delegate.createWithStatement(object, body)); - } - - // 12.10 The swith statement - - function parseSwitchCase() { - var test, - consequent = [], - sourceElement, - marker = markerCreate(); - - if (matchKeyword('default')) { - lex(); - test = null; - } else { - expectKeyword('case'); - test = parseExpression(); - } - expect(':'); - - while (index < length) { - if (match('}') || matchKeyword('default') || matchKeyword('case')) { - break; - } - sourceElement = parseSourceElement(); - if (typeof sourceElement === 'undefined') { - break; - } - consequent.push(sourceElement); - } - - return markerApply(marker, delegate.createSwitchCase(test, consequent)); - } - - function parseSwitchStatement() { - var discriminant, cases, clause, oldInSwitch, defaultFound, marker = markerCreate(); - - expectKeyword('switch'); - - expect('('); - - discriminant = parseExpression(); - - expect(')'); - - expect('{'); - - cases = []; - - if (match('}')) { - lex(); - return markerApply(marker, delegate.createSwitchStatement(discriminant, cases)); - } - - oldInSwitch = state.inSwitch; - state.inSwitch = true; - defaultFound = false; - - while (index < length) { - if (match('}')) { - break; - } - clause = parseSwitchCase(); - if (clause.test === null) { - if (defaultFound) { - throwError({}, Messages.MultipleDefaultsInSwitch); - } - defaultFound = true; - } - cases.push(clause); - } - - state.inSwitch = oldInSwitch; - - expect('}'); - - return markerApply(marker, delegate.createSwitchStatement(discriminant, cases)); - } - - // 12.13 The throw statement - - function parseThrowStatement() { - var argument, marker = markerCreate(); - - expectKeyword('throw'); - - if (peekLineTerminator()) { - throwError({}, Messages.NewlineAfterThrow); - } - - argument = parseExpression(); - - consumeSemicolon(); - - return markerApply(marker, delegate.createThrowStatement(argument)); - } - - // 12.14 The try statement - - function parseCatchClause() { - var param, body, marker = markerCreate(); - - expectKeyword('catch'); - - expect('('); - if (match(')')) { - throwUnexpected(lookahead); - } - - param = parseExpression(); - // 12.14.1 - if (strict && param.type === Syntax.Identifier && isRestrictedWord(param.name)) { - throwErrorTolerant({}, Messages.StrictCatchVariable); - } - - expect(')'); - body = parseBlock(); - return markerApply(marker, delegate.createCatchClause(param, body)); - } - - function parseTryStatement() { - var block, handlers = [], finalizer = null, marker = markerCreate(); - - expectKeyword('try'); - - block = parseBlock(); - - if (matchKeyword('catch')) { - handlers.push(parseCatchClause()); - } - - if (matchKeyword('finally')) { - lex(); - finalizer = parseBlock(); - } - - if (handlers.length === 0 && !finalizer) { - throwError({}, Messages.NoCatchOrFinally); - } - - return markerApply(marker, delegate.createTryStatement(block, [], handlers, finalizer)); - } - - // 12.15 The debugger statement - - function parseDebuggerStatement() { - var marker = markerCreate(); - expectKeyword('debugger'); - - consumeSemicolon(); - - return markerApply(marker, delegate.createDebuggerStatement()); - } - - // 12 Statements - - function parseStatement() { - var type = lookahead.type, - marker, - expr, - labeledBody, - key; - - if (type === Token.EOF) { - throwUnexpected(lookahead); - } - - if (type === Token.Punctuator) { - switch (lookahead.value) { - case ';': - return parseEmptyStatement(); - case '{': - return parseBlock(); - case '(': - return parseExpressionStatement(); - default: - break; - } - } - - if (type === Token.Keyword) { - switch (lookahead.value) { - case 'break': - return parseBreakStatement(); - case 'continue': - return parseContinueStatement(); - case 'debugger': - return parseDebuggerStatement(); - case 'do': - return parseDoWhileStatement(); - case 'for': - return parseForStatement(); - case 'function': - return parseFunctionDeclaration(); - case 'class': - return parseClassDeclaration(); - case 'if': - return parseIfStatement(); - case 'return': - return parseReturnStatement(); - case 'switch': - return parseSwitchStatement(); - case 'throw': - return parseThrowStatement(); - case 'try': - return parseTryStatement(); - case 'var': - return parseVariableStatement(); - case 'while': - return parseWhileStatement(); - case 'with': - return parseWithStatement(); - default: - break; - } - } - - marker = markerCreate(); - expr = parseExpression(); - - // 12.12 Labelled Statements - if ((expr.type === Syntax.Identifier) && match(':')) { - lex(); - - key = '$' + expr.name; - if (Object.prototype.hasOwnProperty.call(state.labelSet, key)) { - throwError({}, Messages.Redeclaration, 'Label', expr.name); - } - - state.labelSet[key] = true; - labeledBody = parseStatement(); - delete state.labelSet[key]; - return markerApply(marker, delegate.createLabeledStatement(expr, labeledBody)); - } - - consumeSemicolon(); - - return markerApply(marker, delegate.createExpressionStatement(expr)); - } - - // 13 Function Definition - - function parseConciseBody() { - if (match('{')) { - return parseFunctionSourceElements(); - } - return parseAssignmentExpression(); - } - - function parseFunctionSourceElements() { - var sourceElement, sourceElements = [], token, directive, firstRestricted, - oldLabelSet, oldInIteration, oldInSwitch, oldInFunctionBody, oldParenthesizedCount, - marker = markerCreate(); - - expect('{'); - - while (index < length) { - if (lookahead.type !== Token.StringLiteral) { - break; - } - token = lookahead; - - sourceElement = parseSourceElement(); - sourceElements.push(sourceElement); - if (sourceElement.expression.type !== Syntax.Literal) { - // this is not directive - break; - } - directive = source.slice(token.range[0] + 1, token.range[1] - 1); - if (directive === 'use strict') { - strict = true; - if (firstRestricted) { - throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral); - } - } else { - if (!firstRestricted && token.octal) { - firstRestricted = token; - } - } - } - - oldLabelSet = state.labelSet; - oldInIteration = state.inIteration; - oldInSwitch = state.inSwitch; - oldInFunctionBody = state.inFunctionBody; - oldParenthesizedCount = state.parenthesizedCount; - - state.labelSet = {}; - state.inIteration = false; - state.inSwitch = false; - state.inFunctionBody = true; - state.parenthesizedCount = 0; - - while (index < length) { - if (match('}')) { - break; - } - sourceElement = parseSourceElement(); - if (typeof sourceElement === 'undefined') { - break; - } - sourceElements.push(sourceElement); - } - - expect('}'); - - state.labelSet = oldLabelSet; - state.inIteration = oldInIteration; - state.inSwitch = oldInSwitch; - state.inFunctionBody = oldInFunctionBody; - state.parenthesizedCount = oldParenthesizedCount; - - return markerApply(marker, delegate.createBlockStatement(sourceElements)); - } - - function validateParam(options, param, name) { - var key = '$' + name; - if (strict) { - if (isRestrictedWord(name)) { - options.stricted = param; - options.message = Messages.StrictParamName; - } - if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) { - options.stricted = param; - options.message = Messages.StrictParamDupe; - } - } else if (!options.firstRestricted) { - if (isRestrictedWord(name)) { - options.firstRestricted = param; - options.message = Messages.StrictParamName; - } else if (isStrictModeReservedWord(name)) { - options.firstRestricted = param; - options.message = Messages.StrictReservedWord; - } else if (Object.prototype.hasOwnProperty.call(options.paramSet, key)) { - options.firstRestricted = param; - options.message = Messages.StrictParamDupe; - } - } - options.paramSet[key] = true; - } - - function parseParam(options) { - var token, rest, param, def; - - token = lookahead; - if (token.value === '...') { - token = lex(); - rest = true; - } - - if (match('[')) { - param = parseArrayInitialiser(); - reinterpretAsDestructuredParameter(options, param); - } else if (match('{')) { - if (rest) { - throwError({}, Messages.ObjectPatternAsRestParameter); - } - param = parseObjectInitialiser(); - reinterpretAsDestructuredParameter(options, param); - } else { - // Typing rest params is awkward, so punting on that for now - param = - rest - ? parseVariableIdentifier() - : parseTypeAnnotatableIdentifier( - false, /* requireTypeAnnotation */ - true /* canBeOptionalParam */ - ); - - validateParam(options, token, token.value); - } - - if (match('=')) { - if (rest) { - throwErrorTolerant(lookahead, Messages.DefaultRestParameter); - } - lex(); - def = parseAssignmentExpression(); - ++options.defaultCount; - } - - if (rest) { - if (!match(')')) { - throwError({}, Messages.ParameterAfterRestParameter); - } - options.rest = param; - return false; - } - - options.params.push(param); - options.defaults.push(def); - return !match(')'); - } - - function parseParams(firstRestricted) { - var options, marker = markerCreate(); - - options = { - params: [], - defaultCount: 0, - defaults: [], - rest: null, - firstRestricted: firstRestricted - }; - - expect('('); - - if (!match(')')) { - options.paramSet = {}; - while (index < length) { - if (!parseParam(options)) { - break; - } - expect(','); - } - } - - expect(')'); - - if (options.defaultCount === 0) { - options.defaults = []; - } - - if (match(':')) { - options.returnType = parseTypeAnnotation(); - } - - return markerApply(marker, options); - } - - function parseFunctionDeclaration() { - var id, body, token, tmp, firstRestricted, message, previousStrict, previousYieldAllowed, generator, - marker = markerCreate(), parametricType; - - expectKeyword('function'); - - generator = false; - if (match('*')) { - lex(); - generator = true; - } - - token = lookahead; - - id = parseVariableIdentifier(); - - if (match('<')) { - parametricType = parseParametricTypeAnnotation(); - } - - if (strict) { - if (isRestrictedWord(token.value)) { - throwErrorTolerant(token, Messages.StrictFunctionName); - } - } else { - if (isRestrictedWord(token.value)) { - firstRestricted = token; - message = Messages.StrictFunctionName; - } else if (isStrictModeReservedWord(token.value)) { - firstRestricted = token; - message = Messages.StrictReservedWord; - } - } - - tmp = parseParams(firstRestricted); - firstRestricted = tmp.firstRestricted; - if (tmp.message) { - message = tmp.message; - } - - previousStrict = strict; - previousYieldAllowed = state.yieldAllowed; - state.yieldAllowed = generator; - - body = parseFunctionSourceElements(); - - if (strict && firstRestricted) { - throwError(firstRestricted, message); - } - if (strict && tmp.stricted) { - throwErrorTolerant(tmp.stricted, message); - } - strict = previousStrict; - state.yieldAllowed = previousYieldAllowed; - - return markerApply(marker, delegate.createFunctionDeclaration(id, tmp.params, tmp.defaults, body, tmp.rest, generator, false, - tmp.returnType, parametricType)); - } - - function parseFunctionExpression() { - var token, id = null, firstRestricted, message, tmp, body, previousStrict, previousYieldAllowed, generator, - marker = markerCreate(), parametricType; - - expectKeyword('function'); - - generator = false; - - if (match('*')) { - lex(); - generator = true; - } - - if (!match('(')) { - if (!match('<')) { - token = lookahead; - id = parseVariableIdentifier(); - - if (strict) { - if (isRestrictedWord(token.value)) { - throwErrorTolerant(token, Messages.StrictFunctionName); - } - } else { - if (isRestrictedWord(token.value)) { - firstRestricted = token; - message = Messages.StrictFunctionName; - } else if (isStrictModeReservedWord(token.value)) { - firstRestricted = token; - message = Messages.StrictReservedWord; - } - } - } - - if (match('<')) { - parametricType = parseParametricTypeAnnotation(); - } - } - - tmp = parseParams(firstRestricted); - firstRestricted = tmp.firstRestricted; - if (tmp.message) { - message = tmp.message; - } - - previousStrict = strict; - previousYieldAllowed = state.yieldAllowed; - state.yieldAllowed = generator; - - body = parseFunctionSourceElements(); - - if (strict && firstRestricted) { - throwError(firstRestricted, message); - } - if (strict && tmp.stricted) { - throwErrorTolerant(tmp.stricted, message); - } - strict = previousStrict; - state.yieldAllowed = previousYieldAllowed; - - return markerApply(marker, delegate.createFunctionExpression(id, tmp.params, tmp.defaults, body, tmp.rest, generator, false, - tmp.returnType, parametricType)); - } - - function parseYieldExpression() { - var yieldToken, delegateFlag, expr, marker = markerCreate(); - - yieldToken = lex(); - assert(yieldToken.value === 'yield', 'Called parseYieldExpression with non-yield lookahead.'); - - if (!state.yieldAllowed) { - throwErrorTolerant({}, Messages.IllegalYield); - } - - delegateFlag = false; - if (match('*')) { - lex(); - delegateFlag = true; - } - - expr = parseAssignmentExpression(); - - return markerApply(marker, delegate.createYieldExpression(expr, delegateFlag)); - } - - // 14 Classes - - function parseMethodDefinition(existingPropNames) { - var token, key, param, propType, isValidDuplicateProp = false, - marker = markerCreate(), token2, parametricType, - parametricTypeMarker, annotationMarker; - - if (lookahead.value === 'static') { - propType = ClassPropertyType["static"]; - lex(); - } else { - propType = ClassPropertyType.prototype; - } - - if (match('*')) { - lex(); - return markerApply(marker, delegate.createMethodDefinition( - propType, - '', - parseObjectPropertyKey(), - parsePropertyMethodFunction({ generator: true }) - )); - } - - token = lookahead; - //parametricTypeMarker = markerCreate(); - key = parseObjectPropertyKey(); - - if (token.value === 'get' && !match('(')) { - key = parseObjectPropertyKey(); - - // It is a syntax error if any other properties have a name - // duplicating this one unless they are a setter - if (existingPropNames[propType].hasOwnProperty(key.name)) { - isValidDuplicateProp = - // There isn't already a getter for this prop - existingPropNames[propType][key.name].get === undefined - // There isn't already a data prop by this name - && existingPropNames[propType][key.name].data === undefined - // The only existing prop by this name is a setter - && existingPropNames[propType][key.name].set !== undefined; - if (!isValidDuplicateProp) { - throwError(key, Messages.IllegalDuplicateClassProperty); - } - } else { - existingPropNames[propType][key.name] = {}; - } - existingPropNames[propType][key.name].get = true; - - expect('('); - expect(')'); - return markerApply(marker, delegate.createMethodDefinition( - propType, - 'get', - key, - parsePropertyFunction({ generator: false }) - )); - } - if (token.value === 'set' && !match('(')) { - key = parseObjectPropertyKey(); - - // It is a syntax error if any other properties have a name - // duplicating this one unless they are a getter - if (existingPropNames[propType].hasOwnProperty(key.name)) { - isValidDuplicateProp = - // There isn't already a setter for this prop - existingPropNames[propType][key.name].set === undefined - // There isn't already a data prop by this name - && existingPropNames[propType][key.name].data === undefined - // The only existing prop by this name is a getter - && existingPropNames[propType][key.name].get !== undefined; - if (!isValidDuplicateProp) { - throwError(key, Messages.IllegalDuplicateClassProperty); - } - } else { - existingPropNames[propType][key.name] = {}; - } - existingPropNames[propType][key.name].set = true; - - expect('('); - token = lookahead; - param = [ parseTypeAnnotatableIdentifier() ]; - expect(')'); - return markerApply(marker, delegate.createMethodDefinition( - propType, - 'set', - key, - parsePropertyFunction({ params: param, generator: false, name: token }) - )); - } - - if (match('<')) { - parametricType = parseParametricTypeAnnotation(); - } - - // It is a syntax error if any other properties have the same name as a - // non-getter, non-setter method - if (existingPropNames[propType].hasOwnProperty(key.name)) { - throwError(key, Messages.IllegalDuplicateClassProperty); - } else { - existingPropNames[propType][key.name] = {}; - } - existingPropNames[propType][key.name].data = true; - - return markerApply(marker, delegate.createMethodDefinition( - propType, - '', - key, - parsePropertyMethodFunction({ - generator: false, - parametricType: parametricType - }) - )); - } - - function parseClassProperty(existingPropNames) { - var marker = markerCreate(), propertyIdentifier; - - propertyIdentifier = parseTypeAnnotatableIdentifier(); - expect(';'); - - return markerApply(marker, delegate.createClassProperty( - propertyIdentifier - )); - } - - function parseClassElement(existingProps) { - if (match(';')) { - lex(); - return; - } - - var doubleLookahead = lookahead2(); - if (doubleLookahead.type === Token.Punctuator) { - if (doubleLookahead.value === ':') { - return parseClassProperty(existingProps); - } - } - - return parseMethodDefinition(existingProps); - } - - function parseClassBody() { - var classElement, classElements = [], existingProps = {}, marker = markerCreate(); - - existingProps[ClassPropertyType["static"]] = {}; - existingProps[ClassPropertyType.prototype] = {}; - - expect('{'); - - while (index < length) { - if (match('}')) { - break; - } - classElement = parseClassElement(existingProps); - - if (typeof classElement !== 'undefined') { - classElements.push(classElement); - } - } - - expect('}'); - - return markerApply(marker, delegate.createClassBody(classElements)); - } - - function parseClassExpression() { - var id, previousYieldAllowed, superClass = null, marker = markerCreate(), - parametricType; - - expectKeyword('class'); - - if (!matchKeyword('extends') && !match('{')) { - id = parseVariableIdentifier(); - } - - if (match('<')) { - parametricType = parseParametricTypeAnnotation(); - } - - if (matchKeyword('extends')) { - expectKeyword('extends'); - previousYieldAllowed = state.yieldAllowed; - state.yieldAllowed = false; - superClass = parseAssignmentExpression(); - state.yieldAllowed = previousYieldAllowed; - } - - return markerApply(marker, delegate.createClassExpression(id, superClass, parseClassBody(), parametricType)); - } - - function parseClassDeclaration() { - var id, previousYieldAllowed, superClass = null, marker = markerCreate(), - parametricType, superParametricType; - - expectKeyword('class'); - - id = parseVariableIdentifier(); - - if (match('<')) { - parametricType = parseParametricTypeAnnotation(); - } - - if (matchKeyword('extends')) { - expectKeyword('extends'); - previousYieldAllowed = state.yieldAllowed; - state.yieldAllowed = false; - superClass = parseAssignmentExpression(); - state.yieldAllowed = previousYieldAllowed; - } - - return markerApply(marker, delegate.createClassDeclaration(id, superClass, parseClassBody(), parametricType, superParametricType)); - } - - // 15 Program - - function matchModuleDeclaration() { - var id; - if (matchContextualKeyword('module')) { - id = lookahead2(); - return id.type === Token.StringLiteral || id.type === Token.Identifier; - } - return false; - } - - function parseSourceElement() { - if (lookahead.type === Token.Keyword) { - switch (lookahead.value) { - case 'const': - case 'let': - return parseConstLetDeclaration(lookahead.value); - case 'function': - return parseFunctionDeclaration(); - case 'export': - return parseExportDeclaration(); - case 'import': - return parseImportDeclaration(); - default: - return parseStatement(); - } - } - - if (matchModuleDeclaration()) { - throwError({}, Messages.NestedModule); - } - - if (lookahead.type !== Token.EOF) { - return parseStatement(); - } - } - - function parseProgramElement() { - if (lookahead.type === Token.Keyword) { - switch (lookahead.value) { - case 'export': - return parseExportDeclaration(); - case 'import': - return parseImportDeclaration(); - } - } - - if (matchModuleDeclaration()) { - return parseModuleDeclaration(); - } - - return parseSourceElement(); - } - - function parseProgramElements() { - var sourceElement, sourceElements = [], token, directive, firstRestricted; - - while (index < length) { - token = lookahead; - if (token.type !== Token.StringLiteral) { - break; - } - - sourceElement = parseProgramElement(); - sourceElements.push(sourceElement); - if (sourceElement.expression.type !== Syntax.Literal) { - // this is not directive - break; - } - directive = source.slice(token.range[0] + 1, token.range[1] - 1); - if (directive === 'use strict') { - strict = true; - if (firstRestricted) { - throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral); - } - } else { - if (!firstRestricted && token.octal) { - firstRestricted = token; - } - } - } - - while (index < length) { - sourceElement = parseProgramElement(); - if (typeof sourceElement === 'undefined') { - break; - } - sourceElements.push(sourceElement); - } - return sourceElements; - } - - function parseModuleElement() { - return parseSourceElement(); - } - - function parseModuleElements() { - var list = [], - statement; - - while (index < length) { - if (match('}')) { - break; - } - statement = parseModuleElement(); - if (typeof statement === 'undefined') { - break; - } - list.push(statement); - } - - return list; - } - - function parseModuleBlock() { - var block, marker = markerCreate(); - - expect('{'); - - block = parseModuleElements(); - - expect('}'); - - return markerApply(marker, delegate.createBlockStatement(block)); - } - - function parseProgram() { - var body, marker = markerCreate(); - strict = false; - peek(); - body = parseProgramElements(); - return markerApply(marker, delegate.createProgram(body)); - } - - // The following functions are needed only when the option to preserve - // the comments is active. - - function addComment(type, value, start, end, loc) { - var comment; - - assert(typeof start === 'number', 'Comment must have valid position'); - - // Because the way the actual token is scanned, often the comments - // (if any) are skipped twice during the lexical analysis. - // Thus, we need to skip adding a comment if the comment array already - // handled it. - if (state.lastCommentStart >= start) { - return; - } - state.lastCommentStart = start; - - comment = { - type: type, - value: value - }; - if (extra.range) { - comment.range = [start, end]; - } - if (extra.loc) { - comment.loc = loc; - } - extra.comments.push(comment); - } - - function scanComment() { - var comment, ch, loc, start, blockComment, lineComment; - - comment = ''; - blockComment = false; - lineComment = false; - - while (index < length) { - ch = source.charAt(index); - - if (lineComment) { - ch = source.charAt(index++); - if (isLineTerminator(ch.charCodeAt(0))) { - loc.end = { - line: lineNumber, - column: index - lineStart - 1 - }; - lineComment = false; - addComment('Line', comment, start, index - 1, loc); - if (ch === '\r' && source.charAt(index) === '\n') { - ++index; - } - ++lineNumber; - lineStart = index; - comment = ''; - } else if (index >= length) { - lineComment = false; - comment += ch; - loc.end = { - line: lineNumber, - column: length - lineStart - }; - addComment('Line', comment, start, length, loc); - } else { - comment += ch; - } - } else if (blockComment) { - if (isLineTerminator(ch.charCodeAt(0))) { - if (ch === '\r' && source.charAt(index + 1) === '\n') { - ++index; - comment += '\r\n'; - } else { - comment += ch; - } - ++lineNumber; - ++index; - lineStart = index; - if (index >= length) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - } else { - ch = source.charAt(index++); - if (index >= length) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - comment += ch; - if (ch === '*') { - ch = source.charAt(index); - if (ch === '/') { - comment = comment.substr(0, comment.length - 1); - blockComment = false; - ++index; - loc.end = { - line: lineNumber, - column: index - lineStart - }; - addComment('Block', comment, start, index, loc); - comment = ''; - } - } - } - } else if (ch === '/') { - ch = source.charAt(index + 1); - if (ch === '/') { - loc = { - start: { - line: lineNumber, - column: index - lineStart - } - }; - start = index; - index += 2; - lineComment = true; - if (index >= length) { - loc.end = { - line: lineNumber, - column: index - lineStart - }; - lineComment = false; - addComment('Line', comment, start, index, loc); - } - } else if (ch === '*') { - start = index; - index += 2; - blockComment = true; - loc = { - start: { - line: lineNumber, - column: index - lineStart - 2 - } - }; - if (index >= length) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - } else { - break; - } - } else if (isWhiteSpace(ch.charCodeAt(0))) { - ++index; - } else if (isLineTerminator(ch.charCodeAt(0))) { - ++index; - if (ch === '\r' && source.charAt(index) === '\n') { - ++index; - } - ++lineNumber; - lineStart = index; - } else { - break; - } - } - } - - // 16 XJS - - XHTMLEntities = { - quot: '\u0022', - amp: '&', - apos: '\u0027', - lt: '<', - gt: '>', - nbsp: '\u00A0', - iexcl: '\u00A1', - cent: '\u00A2', - pound: '\u00A3', - curren: '\u00A4', - yen: '\u00A5', - brvbar: '\u00A6', - sect: '\u00A7', - uml: '\u00A8', - copy: '\u00A9', - ordf: '\u00AA', - laquo: '\u00AB', - not: '\u00AC', - shy: '\u00AD', - reg: '\u00AE', - macr: '\u00AF', - deg: '\u00B0', - plusmn: '\u00B1', - sup2: '\u00B2', - sup3: '\u00B3', - acute: '\u00B4', - micro: '\u00B5', - para: '\u00B6', - middot: '\u00B7', - cedil: '\u00B8', - sup1: '\u00B9', - ordm: '\u00BA', - raquo: '\u00BB', - frac14: '\u00BC', - frac12: '\u00BD', - frac34: '\u00BE', - iquest: '\u00BF', - Agrave: '\u00C0', - Aacute: '\u00C1', - Acirc: '\u00C2', - Atilde: '\u00C3', - Auml: '\u00C4', - Aring: '\u00C5', - AElig: '\u00C6', - Ccedil: '\u00C7', - Egrave: '\u00C8', - Eacute: '\u00C9', - Ecirc: '\u00CA', - Euml: '\u00CB', - Igrave: '\u00CC', - Iacute: '\u00CD', - Icirc: '\u00CE', - Iuml: '\u00CF', - ETH: '\u00D0', - Ntilde: '\u00D1', - Ograve: '\u00D2', - Oacute: '\u00D3', - Ocirc: '\u00D4', - Otilde: '\u00D5', - Ouml: '\u00D6', - times: '\u00D7', - Oslash: '\u00D8', - Ugrave: '\u00D9', - Uacute: '\u00DA', - Ucirc: '\u00DB', - Uuml: '\u00DC', - Yacute: '\u00DD', - THORN: '\u00DE', - szlig: '\u00DF', - agrave: '\u00E0', - aacute: '\u00E1', - acirc: '\u00E2', - atilde: '\u00E3', - auml: '\u00E4', - aring: '\u00E5', - aelig: '\u00E6', - ccedil: '\u00E7', - egrave: '\u00E8', - eacute: '\u00E9', - ecirc: '\u00EA', - euml: '\u00EB', - igrave: '\u00EC', - iacute: '\u00ED', - icirc: '\u00EE', - iuml: '\u00EF', - eth: '\u00F0', - ntilde: '\u00F1', - ograve: '\u00F2', - oacute: '\u00F3', - ocirc: '\u00F4', - otilde: '\u00F5', - ouml: '\u00F6', - divide: '\u00F7', - oslash: '\u00F8', - ugrave: '\u00F9', - uacute: '\u00FA', - ucirc: '\u00FB', - uuml: '\u00FC', - yacute: '\u00FD', - thorn: '\u00FE', - yuml: '\u00FF', - OElig: '\u0152', - oelig: '\u0153', - Scaron: '\u0160', - scaron: '\u0161', - Yuml: '\u0178', - fnof: '\u0192', - circ: '\u02C6', - tilde: '\u02DC', - Alpha: '\u0391', - Beta: '\u0392', - Gamma: '\u0393', - Delta: '\u0394', - Epsilon: '\u0395', - Zeta: '\u0396', - Eta: '\u0397', - Theta: '\u0398', - Iota: '\u0399', - Kappa: '\u039A', - Lambda: '\u039B', - Mu: '\u039C', - Nu: '\u039D', - Xi: '\u039E', - Omicron: '\u039F', - Pi: '\u03A0', - Rho: '\u03A1', - Sigma: '\u03A3', - Tau: '\u03A4', - Upsilon: '\u03A5', - Phi: '\u03A6', - Chi: '\u03A7', - Psi: '\u03A8', - Omega: '\u03A9', - alpha: '\u03B1', - beta: '\u03B2', - gamma: '\u03B3', - delta: '\u03B4', - epsilon: '\u03B5', - zeta: '\u03B6', - eta: '\u03B7', - theta: '\u03B8', - iota: '\u03B9', - kappa: '\u03BA', - lambda: '\u03BB', - mu: '\u03BC', - nu: '\u03BD', - xi: '\u03BE', - omicron: '\u03BF', - pi: '\u03C0', - rho: '\u03C1', - sigmaf: '\u03C2', - sigma: '\u03C3', - tau: '\u03C4', - upsilon: '\u03C5', - phi: '\u03C6', - chi: '\u03C7', - psi: '\u03C8', - omega: '\u03C9', - thetasym: '\u03D1', - upsih: '\u03D2', - piv: '\u03D6', - ensp: '\u2002', - emsp: '\u2003', - thinsp: '\u2009', - zwnj: '\u200C', - zwj: '\u200D', - lrm: '\u200E', - rlm: '\u200F', - ndash: '\u2013', - mdash: '\u2014', - lsquo: '\u2018', - rsquo: '\u2019', - sbquo: '\u201A', - ldquo: '\u201C', - rdquo: '\u201D', - bdquo: '\u201E', - dagger: '\u2020', - Dagger: '\u2021', - bull: '\u2022', - hellip: '\u2026', - permil: '\u2030', - prime: '\u2032', - Prime: '\u2033', - lsaquo: '\u2039', - rsaquo: '\u203A', - oline: '\u203E', - frasl: '\u2044', - euro: '\u20AC', - image: '\u2111', - weierp: '\u2118', - real: '\u211C', - trade: '\u2122', - alefsym: '\u2135', - larr: '\u2190', - uarr: '\u2191', - rarr: '\u2192', - darr: '\u2193', - harr: '\u2194', - crarr: '\u21B5', - lArr: '\u21D0', - uArr: '\u21D1', - rArr: '\u21D2', - dArr: '\u21D3', - hArr: '\u21D4', - forall: '\u2200', - part: '\u2202', - exist: '\u2203', - empty: '\u2205', - nabla: '\u2207', - isin: '\u2208', - notin: '\u2209', - ni: '\u220B', - prod: '\u220F', - sum: '\u2211', - minus: '\u2212', - lowast: '\u2217', - radic: '\u221A', - prop: '\u221D', - infin: '\u221E', - ang: '\u2220', - and: '\u2227', - or: '\u2228', - cap: '\u2229', - cup: '\u222A', - 'int': '\u222B', - there4: '\u2234', - sim: '\u223C', - cong: '\u2245', - asymp: '\u2248', - ne: '\u2260', - equiv: '\u2261', - le: '\u2264', - ge: '\u2265', - sub: '\u2282', - sup: '\u2283', - nsub: '\u2284', - sube: '\u2286', - supe: '\u2287', - oplus: '\u2295', - otimes: '\u2297', - perp: '\u22A5', - sdot: '\u22C5', - lceil: '\u2308', - rceil: '\u2309', - lfloor: '\u230A', - rfloor: '\u230B', - lang: '\u2329', - rang: '\u232A', - loz: '\u25CA', - spades: '\u2660', - clubs: '\u2663', - hearts: '\u2665', - diams: '\u2666' - }; - - function getQualifiedXJSName(object) { - if (object.type === Syntax.XJSIdentifier) { - return object.name; - } - if (object.type === Syntax.XJSNamespacedName) { - return object.namespace.name + ':' + object.name.name; - } - if (object.type === Syntax.XJSMemberExpression) { - return ( - getQualifiedXJSName(object.object) + '.' + - getQualifiedXJSName(object.property) - ); - } - } - - function isXJSIdentifierStart(ch) { - // exclude backslash (\) - return (ch !== 92) && isIdentifierStart(ch); - } - - function isXJSIdentifierPart(ch) { - // exclude backslash (\) and add hyphen (-) - return (ch !== 92) && (ch === 45 || isIdentifierPart(ch)); - } - - function scanXJSIdentifier() { - var ch, start, value = ''; - - start = index; - while (index < length) { - ch = source.charCodeAt(index); - if (!isXJSIdentifierPart(ch)) { - break; - } - value += source.charAt(index++); - } - - return { - type: Token.XJSIdentifier, - value: value, - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - function scanXJSEntity() { - var ch, str = '', count = 0, entity; - ch = source.charAt(index); - assert(ch === '&', 'Entity must start with an ampersand'); - index++; - while (index < length && count++ < 10) { - ch = source.charAt(index++); - if (ch === ';') { - break; - } - str += ch; - } - - if (str[0] === '#' && str[1] === 'x') { - entity = String.fromCharCode(parseInt(str.substr(2), 16)); - } else if (str[0] === '#') { - entity = String.fromCharCode(parseInt(str.substr(1), 10)); - } else { - entity = XHTMLEntities[str]; - } - return entity; - } - - function scanXJSText(stopChars) { - var ch, str = '', start; - start = index; - while (index < length) { - ch = source.charAt(index); - if (stopChars.indexOf(ch) !== -1) { - break; - } - if (ch === '&') { - str += scanXJSEntity(); - } else { - index++; - if (isLineTerminator(ch.charCodeAt(0))) { - ++lineNumber; - lineStart = index; - } - str += ch; - } - } - return { - type: Token.XJSText, - value: str, - lineNumber: lineNumber, - lineStart: lineStart, - range: [start, index] - }; - } - - function scanXJSStringLiteral() { - var innerToken, quote, start; - - quote = source.charAt(index); - assert((quote === '\'' || quote === '"'), - 'String literal must starts with a quote'); - - start = index; - ++index; - - innerToken = scanXJSText([quote]); - - if (quote !== source.charAt(index)) { - throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); - } - - ++index; - - innerToken.range = [start, index]; - - return innerToken; - } - - /** - * Between XJS opening and closing tags (e.g. HERE), anything that - * is not another XJS tag and is not an expression wrapped by {} is text. - */ - function advanceXJSChild() { - var ch = source.charCodeAt(index); - - // { (123) and < (60) - if (ch !== 123 && ch !== 60) { - return scanXJSText(['<', '{']); - } - - return scanPunctuator(); - } - - function parseXJSIdentifier() { - var token, marker = markerCreate(); - - if (lookahead.type !== Token.XJSIdentifier) { - throwUnexpected(lookahead); - } - - token = lex(); - return markerApply(marker, delegate.createXJSIdentifier(token.value)); - } - - function parseXJSNamespacedName() { - var namespace, name, marker = markerCreate(); - - namespace = parseXJSIdentifier(); - expect(':'); - name = parseXJSIdentifier(); - - return markerApply(marker, delegate.createXJSNamespacedName(namespace, name)); - } - - function parseXJSMemberExpression() { - var marker = markerCreate(), - expr = parseXJSIdentifier(); - - while (match('.')) { - lex(); - expr = markerApply(marker, delegate.createXJSMemberExpression(expr, parseXJSIdentifier())); - } - - return expr; - } - - function parseXJSElementName() { - if (lookahead2().value === ':') { - return parseXJSNamespacedName(); - } - if (lookahead2().value === '.') { - return parseXJSMemberExpression(); - } - - return parseXJSIdentifier(); - } - - function parseXJSAttributeName() { - if (lookahead2().value === ':') { - return parseXJSNamespacedName(); - } - - return parseXJSIdentifier(); - } - - function parseXJSAttributeValue() { - var value, marker; - if (match('{')) { - value = parseXJSExpressionContainer(); - if (value.expression.type === Syntax.XJSEmptyExpression) { - throwError( - value, - 'XJS attributes must only be assigned a non-empty ' + - 'expression' - ); - } - } else if (match('<')) { - value = parseXJSElement(); - } else if (lookahead.type === Token.XJSText) { - marker = markerCreate(); - value = markerApply(marker, delegate.createLiteral(lex())); - } else { - throwError({}, Messages.InvalidXJSAttributeValue); - } - return value; - } - - function parseXJSEmptyExpression() { - var marker = markerCreatePreserveWhitespace(); - while (source.charAt(index) !== '}') { - index++; - } - return markerApply(marker, delegate.createXJSEmptyExpression()); - } - - function parseXJSExpressionContainer() { - var expression, origInXJSChild, origInXJSTag, marker = markerCreate(); - - origInXJSChild = state.inXJSChild; - origInXJSTag = state.inXJSTag; - state.inXJSChild = false; - state.inXJSTag = false; - - expect('{'); - - if (match('}')) { - expression = parseXJSEmptyExpression(); - } else { - expression = parseExpression(); - } - - state.inXJSChild = origInXJSChild; - state.inXJSTag = origInXJSTag; - - expect('}'); - - return markerApply(marker, delegate.createXJSExpressionContainer(expression)); - } - - function parseXJSSpreadAttribute() { - var expression, origInXJSChild, origInXJSTag, marker = markerCreate(); - - origInXJSChild = state.inXJSChild; - origInXJSTag = state.inXJSTag; - state.inXJSChild = false; - state.inXJSTag = false; - - expect('{'); - expect('...'); - - expression = parseAssignmentExpression(); - - state.inXJSChild = origInXJSChild; - state.inXJSTag = origInXJSTag; - - expect('}'); - - return markerApply(marker, delegate.createXJSSpreadAttribute(expression)); - } - - function parseXJSAttribute() { - var name, marker; - - if (match('{')) { - return parseXJSSpreadAttribute(); - } - - marker = markerCreate(); - - name = parseXJSAttributeName(); - - // HTML empty attribute - if (match('=')) { - lex(); - return markerApply(marker, delegate.createXJSAttribute(name, parseXJSAttributeValue())); - } - - return markerApply(marker, delegate.createXJSAttribute(name)); - } - - function parseXJSChild() { - var token, marker; - if (match('{')) { - token = parseXJSExpressionContainer(); - } else if (lookahead.type === Token.XJSText) { - marker = markerCreatePreserveWhitespace(); - token = markerApply(marker, delegate.createLiteral(lex())); - } else { - token = parseXJSElement(); - } - return token; - } - - function parseXJSClosingElement() { - var name, origInXJSChild, origInXJSTag, marker = markerCreate(); - origInXJSChild = state.inXJSChild; - origInXJSTag = state.inXJSTag; - state.inXJSChild = false; - state.inXJSTag = true; - expect('<'); - expect('/'); - name = parseXJSElementName(); - // Because advance() (called by lex() called by expect()) expects there - // to be a valid token after >, it needs to know whether to look for a - // standard JS token or an XJS text node - state.inXJSChild = origInXJSChild; - state.inXJSTag = origInXJSTag; - expect('>'); - return markerApply(marker, delegate.createXJSClosingElement(name)); - } - - function parseXJSOpeningElement() { - var name, attribute, attributes = [], selfClosing = false, origInXJSChild, origInXJSTag, marker = markerCreate(); - - origInXJSChild = state.inXJSChild; - origInXJSTag = state.inXJSTag; - state.inXJSChild = false; - state.inXJSTag = true; - - expect('<'); - - name = parseXJSElementName(); - - while (index < length && - lookahead.value !== '/' && - lookahead.value !== '>') { - attributes.push(parseXJSAttribute()); - } - - state.inXJSTag = origInXJSTag; - - if (lookahead.value === '/') { - expect('/'); - // Because advance() (called by lex() called by expect()) expects - // there to be a valid token after >, it needs to know whether to - // look for a standard JS token or an XJS text node - state.inXJSChild = origInXJSChild; - expect('>'); - selfClosing = true; - } else { - state.inXJSChild = true; - expect('>'); - } - return markerApply(marker, delegate.createXJSOpeningElement(name, attributes, selfClosing)); - } - - function parseXJSElement() { - var openingElement, closingElement, children = [], origInXJSChild, origInXJSTag, marker = markerCreate(); - - origInXJSChild = state.inXJSChild; - origInXJSTag = state.inXJSTag; - openingElement = parseXJSOpeningElement(); - - if (!openingElement.selfClosing) { - while (index < length) { - state.inXJSChild = false; // Call lookahead2() with inXJSChild = false because one
    two
    ; - // - // the default error message is a bit incomprehensible. Since it's - // rarely (never?) useful to write a less-than sign after an XJS - // element, we disallow it here in the parser in order to provide a - // better error message. (In the rare case that the less-than operator - // was intended, the left tag can be wrapped in parentheses.) - if (!origInXJSChild && match('<')) { - throwError(lookahead, Messages.AdjacentXJSElements); - } - - return markerApply(marker, delegate.createXJSElement(openingElement, closingElement, children)); - } - - function collectToken() { - var start, loc, token, range, value; - - if (!state.inXJSChild) { - skipComment(); - } - - start = index; - loc = { - start: { - line: lineNumber, - column: index - lineStart - } - }; - - token = extra.advance(); - loc.end = { - line: lineNumber, - column: index - lineStart - }; - - if (token.type !== Token.EOF) { - range = [token.range[0], token.range[1]]; - value = source.slice(token.range[0], token.range[1]); - extra.tokens.push({ - type: TokenName[token.type], - value: value, - range: range, - loc: loc - }); - } - - return token; - } - - function collectRegex() { - var pos, loc, regex, token; - - skipComment(); - - pos = index; - loc = { - start: { - line: lineNumber, - column: index - lineStart - } - }; - - regex = extra.scanRegExp(); - loc.end = { - line: lineNumber, - column: index - lineStart - }; - - if (!extra.tokenize) { - // Pop the previous token, which is likely '/' or '/=' - if (extra.tokens.length > 0) { - token = extra.tokens[extra.tokens.length - 1]; - if (token.range[0] === pos && token.type === 'Punctuator') { - if (token.value === '/' || token.value === '/=') { - extra.tokens.pop(); - } - } - } - - extra.tokens.push({ - type: 'RegularExpression', - value: regex.literal, - range: [pos, index], - loc: loc - }); - } - - return regex; - } - - function filterTokenLocation() { - var i, entry, token, tokens = []; - - for (i = 0; i < extra.tokens.length; ++i) { - entry = extra.tokens[i]; - token = { - type: entry.type, - value: entry.value - }; - if (extra.range) { - token.range = entry.range; - } - if (extra.loc) { - token.loc = entry.loc; - } - tokens.push(token); - } - - extra.tokens = tokens; - } - - function patch() { - if (extra.comments) { - extra.skipComment = skipComment; - skipComment = scanComment; - } - - if (typeof extra.tokens !== 'undefined') { - extra.advance = advance; - extra.scanRegExp = scanRegExp; - - advance = collectToken; - scanRegExp = collectRegex; - } - } - - function unpatch() { - if (typeof extra.skipComment === 'function') { - skipComment = extra.skipComment; - } - - if (typeof extra.scanRegExp === 'function') { - advance = extra.advance; - scanRegExp = extra.scanRegExp; - } - } - - // This is used to modify the delegate. - - function extend(object, properties) { - var entry, result = {}; - - for (entry in object) { - if (object.hasOwnProperty(entry)) { - result[entry] = object[entry]; - } - } - - for (entry in properties) { - if (properties.hasOwnProperty(entry)) { - result[entry] = properties[entry]; - } - } - - return result; - } - - function tokenize(code, options) { - var toString, - token, - tokens; - - toString = String; - if (typeof code !== 'string' && !(code instanceof String)) { - code = toString(code); - } - - delegate = SyntaxTreeDelegate; - source = code; - index = 0; - lineNumber = (source.length > 0) ? 1 : 0; - lineStart = 0; - length = source.length; - lookahead = null; - state = { - allowKeyword: true, - allowIn: true, - labelSet: {}, - inFunctionBody: false, - inIteration: false, - inSwitch: false, - lastCommentStart: -1 - }; - - extra = {}; - - // Options matching. - options = options || {}; - - // Of course we collect tokens here. - options.tokens = true; - extra.tokens = []; - extra.tokenize = true; - // The following two fields are necessary to compute the Regex tokens. - extra.openParenToken = -1; - extra.openCurlyToken = -1; - - extra.range = (typeof options.range === 'boolean') && options.range; - extra.loc = (typeof options.loc === 'boolean') && options.loc; - - if (typeof options.comment === 'boolean' && options.comment) { - extra.comments = []; - } - if (typeof options.tolerant === 'boolean' && options.tolerant) { - extra.errors = []; - } - - if (length > 0) { - if (typeof source[0] === 'undefined') { - // Try first to convert to a string. This is good as fast path - // for old IE which understands string indexing for string - // literals only and not for string object. - if (code instanceof String) { - source = code.valueOf(); - } - } - } - - patch(); - - try { - peek(); - if (lookahead.type === Token.EOF) { - return extra.tokens; - } - - token = lex(); - while (lookahead.type !== Token.EOF) { - try { - token = lex(); - } catch (lexError) { - token = lookahead; - if (extra.errors) { - extra.errors.push(lexError); - // We have to break on the first error - // to avoid infinite loops. - break; - } else { - throw lexError; - } - } - } - - filterTokenLocation(); - tokens = extra.tokens; - if (typeof extra.comments !== 'undefined') { - tokens.comments = extra.comments; - } - if (typeof extra.errors !== 'undefined') { - tokens.errors = extra.errors; - } - } catch (e) { - throw e; - } finally { - unpatch(); - extra = {}; - } - return tokens; - } - - function parse(code, options) { - var program, toString; - - toString = String; - if (typeof code !== 'string' && !(code instanceof String)) { - code = toString(code); - } - - delegate = SyntaxTreeDelegate; - source = code; - index = 0; - lineNumber = (source.length > 0) ? 1 : 0; - lineStart = 0; - length = source.length; - lookahead = null; - state = { - allowKeyword: false, - allowIn: true, - labelSet: {}, - parenthesizedCount: 0, - inFunctionBody: false, - inIteration: false, - inSwitch: false, - inXJSChild: false, - inXJSTag: false, - lastCommentStart: -1, - yieldAllowed: false - }; - - extra = {}; - if (typeof options !== 'undefined') { - extra.range = (typeof options.range === 'boolean') && options.range; - extra.loc = (typeof options.loc === 'boolean') && options.loc; - - if (extra.loc && options.source !== null && options.source !== undefined) { - delegate = extend(delegate, { - 'postProcess': function (node) { - node.loc.source = toString(options.source); - return node; - } - }); - } - - if (typeof options.tokens === 'boolean' && options.tokens) { - extra.tokens = []; - } - if (typeof options.comment === 'boolean' && options.comment) { - extra.comments = []; - } - if (typeof options.tolerant === 'boolean' && options.tolerant) { - extra.errors = []; - } - } - - if (length > 0) { - if (typeof source[0] === 'undefined') { - // Try first to convert to a string. This is good as fast path - // for old IE which understands string indexing for string - // literals only and not for string object. - if (code instanceof String) { - source = code.valueOf(); - } - } - } - - patch(); - try { - program = parseProgram(); - if (typeof extra.comments !== 'undefined') { - program.comments = extra.comments; - } - if (typeof extra.tokens !== 'undefined') { - filterTokenLocation(); - program.tokens = extra.tokens; - } - if (typeof extra.errors !== 'undefined') { - program.errors = extra.errors; - } - } catch (e) { - throw e; - } finally { - unpatch(); - extra = {}; - } - - return program; - } - - // Sync with *.json manifests. - exports.version = '4001.3001.0000-dev-harmony-fb'; - - exports.tokenize = tokenize; - - exports.parse = parse; - - // Deep copy. - exports.Syntax = (function () { - var name, types = {}; - - if (typeof Object.create === 'function') { - types = Object.create(null); - } - - for (name in Syntax) { - if (Syntax.hasOwnProperty(name)) { - types[name] = Syntax[name]; - } - } - - if (typeof Object.freeze === 'function') { - Object.freeze(types); - } - - return types; - }()); - -})); -/* vim: set sw=4 ts=4 et tw=80 : */ - -},{}],7:[function(_dereq_,module,exports){ -var Base62 = (function (my) { - my.chars = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"] - - my.encode = function(i){ - if (i === 0) {return '0'} - var s = '' - while (i > 0) { - s = this.chars[i % 62] + s - i = Math.floor(i/62) - } - return s - }; - my.decode = function(a,b,c,d){ - for ( - b = c = ( - a === (/\W|_|^$/.test(a += "") || a) - ) - 1; - d = a.charCodeAt(c++); - ) - b = b * 62 + d - [, 48, 29, 87][d >> 5]; - return b - }; - - return my; -}({})); - -module.exports = Base62 -},{}],8:[function(_dereq_,module,exports){ -/* - * Copyright 2009-2011 Mozilla Foundation and contributors - * Licensed under the New BSD license. See LICENSE.txt or: - * http://opensource.org/licenses/BSD-3-Clause - */ -exports.SourceMapGenerator = _dereq_('./source-map/source-map-generator').SourceMapGenerator; -exports.SourceMapConsumer = _dereq_('./source-map/source-map-consumer').SourceMapConsumer; -exports.SourceNode = _dereq_('./source-map/source-node').SourceNode; - -},{"./source-map/source-map-consumer":13,"./source-map/source-map-generator":14,"./source-map/source-node":15}],9:[function(_dereq_,module,exports){ -/* -*- Mode: js; js-indent-level: 2; -*- */ -/* - * Copyright 2011 Mozilla Foundation and contributors - * Licensed under the New BSD license. See LICENSE or: - * http://opensource.org/licenses/BSD-3-Clause - */ -if (typeof define !== 'function') { - var define = _dereq_('amdefine')(module, _dereq_); -} -define(function (_dereq_, exports, module) { - - var util = _dereq_('./util'); - - /** - * A data structure which is a combination of an array and a set. Adding a new - * member is O(1), testing for membership is O(1), and finding the index of an - * element is O(1). Removing elements from the set is not supported. Only - * strings are supported for membership. - */ - function ArraySet() { - this._array = []; - this._set = {}; - } - - /** - * Static method for creating ArraySet instances from an existing array. - */ - ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) { - var set = new ArraySet(); - for (var i = 0, len = aArray.length; i < len; i++) { - set.add(aArray[i], aAllowDuplicates); - } - return set; - }; - - /** - * Add the given string to this set. - * - * @param String aStr - */ - ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) { - var isDuplicate = this.has(aStr); - var idx = this._array.length; - if (!isDuplicate || aAllowDuplicates) { - this._array.push(aStr); - } - if (!isDuplicate) { - this._set[util.toSetString(aStr)] = idx; - } - }; - - /** - * Is the given string a member of this set? - * - * @param String aStr - */ - ArraySet.prototype.has = function ArraySet_has(aStr) { - return Object.prototype.hasOwnProperty.call(this._set, - util.toSetString(aStr)); - }; - - /** - * What is the index of the given string in the array? - * - * @param String aStr - */ - ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) { - if (this.has(aStr)) { - return this._set[util.toSetString(aStr)]; - } - throw new Error('"' + aStr + '" is not in the set.'); - }; - - /** - * What is the element at the given index? - * - * @param Number aIdx - */ - ArraySet.prototype.at = function ArraySet_at(aIdx) { - if (aIdx >= 0 && aIdx < this._array.length) { - return this._array[aIdx]; - } - throw new Error('No element indexed by ' + aIdx); - }; - - /** - * Returns the array representation of this set (which has the proper indices - * indicated by indexOf). Note that this is a copy of the internal array used - * for storing the members so that no one can mess with internal state. - */ - ArraySet.prototype.toArray = function ArraySet_toArray() { - return this._array.slice(); - }; - - exports.ArraySet = ArraySet; - -}); - -},{"./util":16,"amdefine":17}],10:[function(_dereq_,module,exports){ -/* -*- Mode: js; js-indent-level: 2; -*- */ -/* - * Copyright 2011 Mozilla Foundation and contributors - * Licensed under the New BSD license. See LICENSE or: - * http://opensource.org/licenses/BSD-3-Clause - * - * Based on the Base 64 VLQ implementation in Closure Compiler: - * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java - * - * Copyright 2011 The Closure Compiler Authors. All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -if (typeof define !== 'function') { - var define = _dereq_('amdefine')(module, _dereq_); -} -define(function (_dereq_, exports, module) { - - var base64 = _dereq_('./base64'); - - // A single base 64 digit can contain 6 bits of data. For the base 64 variable - // length quantities we use in the source map spec, the first bit is the sign, - // the next four bits are the actual value, and the 6th bit is the - // continuation bit. The continuation bit tells us whether there are more - // digits in this value following this digit. - // - // Continuation - // | Sign - // | | - // V V - // 101011 - - var VLQ_BASE_SHIFT = 5; - - // binary: 100000 - var VLQ_BASE = 1 << VLQ_BASE_SHIFT; - - // binary: 011111 - var VLQ_BASE_MASK = VLQ_BASE - 1; - - // binary: 100000 - var VLQ_CONTINUATION_BIT = VLQ_BASE; - - /** - * Converts from a two-complement value to a value where the sign bit is - * is placed in the least significant bit. For example, as decimals: - * 1 becomes 2 (10 binary), -1 becomes 3 (11 binary) - * 2 becomes 4 (100 binary), -2 becomes 5 (101 binary) - */ - function toVLQSigned(aValue) { - return aValue < 0 - ? ((-aValue) << 1) + 1 - : (aValue << 1) + 0; - } - - /** - * Converts to a two-complement value from a value where the sign bit is - * is placed in the least significant bit. For example, as decimals: - * 2 (10 binary) becomes 1, 3 (11 binary) becomes -1 - * 4 (100 binary) becomes 2, 5 (101 binary) becomes -2 - */ - function fromVLQSigned(aValue) { - var isNegative = (aValue & 1) === 1; - var shifted = aValue >> 1; - return isNegative - ? -shifted - : shifted; - } - - /** - * Returns the base 64 VLQ encoded value. - */ - exports.encode = function base64VLQ_encode(aValue) { - var encoded = ""; - var digit; - - var vlq = toVLQSigned(aValue); - - do { - digit = vlq & VLQ_BASE_MASK; - vlq >>>= VLQ_BASE_SHIFT; - if (vlq > 0) { - // There are still more digits in this value, so we must make sure the - // continuation bit is marked. - digit |= VLQ_CONTINUATION_BIT; - } - encoded += base64.encode(digit); - } while (vlq > 0); - - return encoded; - }; - - /** - * Decodes the next base 64 VLQ value from the given string and returns the - * value and the rest of the string. - */ - exports.decode = function base64VLQ_decode(aStr) { - var i = 0; - var strLen = aStr.length; - var result = 0; - var shift = 0; - var continuation, digit; - - do { - if (i >= strLen) { - throw new Error("Expected more digits in base 64 VLQ value."); - } - digit = base64.decode(aStr.charAt(i++)); - continuation = !!(digit & VLQ_CONTINUATION_BIT); - digit &= VLQ_BASE_MASK; - result = result + (digit << shift); - shift += VLQ_BASE_SHIFT; - } while (continuation); - - return { - value: fromVLQSigned(result), - rest: aStr.slice(i) - }; - }; - -}); - -},{"./base64":11,"amdefine":17}],11:[function(_dereq_,module,exports){ -/* -*- Mode: js; js-indent-level: 2; -*- */ -/* - * Copyright 2011 Mozilla Foundation and contributors - * Licensed under the New BSD license. See LICENSE or: - * http://opensource.org/licenses/BSD-3-Clause - */ -if (typeof define !== 'function') { - var define = _dereq_('amdefine')(module, _dereq_); -} -define(function (_dereq_, exports, module) { - - var charToIntMap = {}; - var intToCharMap = {}; - - 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' - .split('') - .forEach(function (ch, index) { - charToIntMap[ch] = index; - intToCharMap[index] = ch; - }); - - /** - * Encode an integer in the range of 0 to 63 to a single base 64 digit. - */ - exports.encode = function base64_encode(aNumber) { - if (aNumber in intToCharMap) { - return intToCharMap[aNumber]; - } - throw new TypeError("Must be between 0 and 63: " + aNumber); - }; - - /** - * Decode a single base 64 digit to an integer. - */ - exports.decode = function base64_decode(aChar) { - if (aChar in charToIntMap) { - return charToIntMap[aChar]; - } - throw new TypeError("Not a valid base 64 digit: " + aChar); - }; - -}); - -},{"amdefine":17}],12:[function(_dereq_,module,exports){ -/* -*- Mode: js; js-indent-level: 2; -*- */ -/* - * Copyright 2011 Mozilla Foundation and contributors - * Licensed under the New BSD license. See LICENSE or: - * http://opensource.org/licenses/BSD-3-Clause - */ -if (typeof define !== 'function') { - var define = _dereq_('amdefine')(module, _dereq_); -} -define(function (_dereq_, exports, module) { - - /** - * Recursive implementation of binary search. - * - * @param aLow Indices here and lower do not contain the needle. - * @param aHigh Indices here and higher do not contain the needle. - * @param aNeedle The element being searched for. - * @param aHaystack The non-empty array being searched. - * @param aCompare Function which takes two elements and returns -1, 0, or 1. - */ - function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare) { - // This function terminates when one of the following is true: - // - // 1. We find the exact element we are looking for. - // - // 2. We did not find the exact element, but we can return the next - // closest element that is less than that element. - // - // 3. We did not find the exact element, and there is no next-closest - // element which is less than the one we are searching for, so we - // return null. - var mid = Math.floor((aHigh - aLow) / 2) + aLow; - var cmp = aCompare(aNeedle, aHaystack[mid], true); - if (cmp === 0) { - // Found the element we are looking for. - return aHaystack[mid]; - } - else if (cmp > 0) { - // aHaystack[mid] is greater than our needle. - if (aHigh - mid > 1) { - // The element is in the upper half. - return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare); - } - // We did not find an exact match, return the next closest one - // (termination case 2). - return aHaystack[mid]; - } - else { - // aHaystack[mid] is less than our needle. - if (mid - aLow > 1) { - // The element is in the lower half. - return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare); - } - // The exact needle element was not found in this haystack. Determine if - // we are in termination case (2) or (3) and return the appropriate thing. - return aLow < 0 - ? null - : aHaystack[aLow]; - } - } - - /** - * This is an implementation of binary search which will always try and return - * the next lowest value checked if there is no exact hit. This is because - * mappings between original and generated line/col pairs are single points, - * and there is an implicit region between each of them, so a miss just means - * that you aren't on the very start of a region. - * - * @param aNeedle The element you are looking for. - * @param aHaystack The array that is being searched. - * @param aCompare A function which takes the needle and an element in the - * array and returns -1, 0, or 1 depending on whether the needle is less - * than, equal to, or greater than the element, respectively. - */ - exports.search = function search(aNeedle, aHaystack, aCompare) { - return aHaystack.length > 0 - ? recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack, aCompare) - : null; - }; - -}); - -},{"amdefine":17}],13:[function(_dereq_,module,exports){ -/* -*- Mode: js; js-indent-level: 2; -*- */ -/* - * Copyright 2011 Mozilla Foundation and contributors - * Licensed under the New BSD license. See LICENSE or: - * http://opensource.org/licenses/BSD-3-Clause - */ -if (typeof define !== 'function') { - var define = _dereq_('amdefine')(module, _dereq_); -} -define(function (_dereq_, exports, module) { - - var util = _dereq_('./util'); - var binarySearch = _dereq_('./binary-search'); - var ArraySet = _dereq_('./array-set').ArraySet; - var base64VLQ = _dereq_('./base64-vlq'); - - /** - * A SourceMapConsumer instance represents a parsed source map which we can - * query for information about the original file positions by giving it a file - * position in the generated source. - * - * The only parameter is the raw source map (either as a JSON string, or - * already parsed to an object). According to the spec, source maps have the - * following attributes: - * - * - version: Which version of the source map spec this map is following. - * - sources: An array of URLs to the original source files. - * - names: An array of identifiers which can be referrenced by individual mappings. - * - sourceRoot: Optional. The URL root from which all sources are relative. - * - sourcesContent: Optional. An array of contents of the original source files. - * - mappings: A string of base64 VLQs which contain the actual mappings. - * - file: The generated file this source map is associated with. - * - * Here is an example source map, taken from the source map spec[0]: - * - * { - * version : 3, - * file: "out.js", - * sourceRoot : "", - * sources: ["foo.js", "bar.js"], - * names: ["src", "maps", "are", "fun"], - * mappings: "AA,AB;;ABCDE;" - * } - * - * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1# - */ - function SourceMapConsumer(aSourceMap) { - var sourceMap = aSourceMap; - if (typeof aSourceMap === 'string') { - sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, '')); - } - - var version = util.getArg(sourceMap, 'version'); - var sources = util.getArg(sourceMap, 'sources'); - // Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which - // requires the array) to play nice here. - var names = util.getArg(sourceMap, 'names', []); - var sourceRoot = util.getArg(sourceMap, 'sourceRoot', null); - var sourcesContent = util.getArg(sourceMap, 'sourcesContent', null); - var mappings = util.getArg(sourceMap, 'mappings'); - var file = util.getArg(sourceMap, 'file', null); - - // Once again, Sass deviates from the spec and supplies the version as a - // string rather than a number, so we use loose equality checking here. - if (version != this._version) { - throw new Error('Unsupported version: ' + version); - } - - // Pass `true` below to allow duplicate names and sources. While source maps - // are intended to be compressed and deduplicated, the TypeScript compiler - // sometimes generates source maps with duplicates in them. See Github issue - // #72 and bugzil.la/889492. - this._names = ArraySet.fromArray(names, true); - this._sources = ArraySet.fromArray(sources, true); - - this.sourceRoot = sourceRoot; - this.sourcesContent = sourcesContent; - this._mappings = mappings; - this.file = file; - } - - /** - * Create a SourceMapConsumer from a SourceMapGenerator. - * - * @param SourceMapGenerator aSourceMap - * The source map that will be consumed. - * @returns SourceMapConsumer - */ - SourceMapConsumer.fromSourceMap = - function SourceMapConsumer_fromSourceMap(aSourceMap) { - var smc = Object.create(SourceMapConsumer.prototype); - - smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true); - smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true); - smc.sourceRoot = aSourceMap._sourceRoot; - smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(), - smc.sourceRoot); - smc.file = aSourceMap._file; - - smc.__generatedMappings = aSourceMap._mappings.slice() - .sort(util.compareByGeneratedPositions); - smc.__originalMappings = aSourceMap._mappings.slice() - .sort(util.compareByOriginalPositions); - - return smc; - }; - - /** - * The version of the source mapping spec that we are consuming. - */ - SourceMapConsumer.prototype._version = 3; - - /** - * The list of original sources. - */ - Object.defineProperty(SourceMapConsumer.prototype, 'sources', { - get: function () { - return this._sources.toArray().map(function (s) { - return this.sourceRoot ? util.join(this.sourceRoot, s) : s; - }, this); - } - }); - - // `__generatedMappings` and `__originalMappings` are arrays that hold the - // parsed mapping coordinates from the source map's "mappings" attribute. They - // are lazily instantiated, accessed via the `_generatedMappings` and - // `_originalMappings` getters respectively, and we only parse the mappings - // and create these arrays once queried for a source location. We jump through - // these hoops because there can be many thousands of mappings, and parsing - // them is expensive, so we only want to do it if we must. - // - // Each object in the arrays is of the form: - // - // { - // generatedLine: The line number in the generated code, - // generatedColumn: The column number in the generated code, - // source: The path to the original source file that generated this - // chunk of code, - // originalLine: The line number in the original source that - // corresponds to this chunk of generated code, - // originalColumn: The column number in the original source that - // corresponds to this chunk of generated code, - // name: The name of the original symbol which generated this chunk of - // code. - // } - // - // All properties except for `generatedLine` and `generatedColumn` can be - // `null`. - // - // `_generatedMappings` is ordered by the generated positions. - // - // `_originalMappings` is ordered by the original positions. - - SourceMapConsumer.prototype.__generatedMappings = null; - Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', { - get: function () { - if (!this.__generatedMappings) { - this.__generatedMappings = []; - this.__originalMappings = []; - this._parseMappings(this._mappings, this.sourceRoot); - } - - return this.__generatedMappings; - } - }); - - SourceMapConsumer.prototype.__originalMappings = null; - Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', { - get: function () { - if (!this.__originalMappings) { - this.__generatedMappings = []; - this.__originalMappings = []; - this._parseMappings(this._mappings, this.sourceRoot); - } - - return this.__originalMappings; - } - }); - - /** - * Parse the mappings in a string in to a data structure which we can easily - * query (the ordered arrays in the `this.__generatedMappings` and - * `this.__originalMappings` properties). - */ - SourceMapConsumer.prototype._parseMappings = - function SourceMapConsumer_parseMappings(aStr, aSourceRoot) { - var generatedLine = 1; - var previousGeneratedColumn = 0; - var previousOriginalLine = 0; - var previousOriginalColumn = 0; - var previousSource = 0; - var previousName = 0; - var mappingSeparator = /^[,;]/; - var str = aStr; - var mapping; - var temp; - - while (str.length > 0) { - if (str.charAt(0) === ';') { - generatedLine++; - str = str.slice(1); - previousGeneratedColumn = 0; - } - else if (str.charAt(0) === ',') { - str = str.slice(1); - } - else { - mapping = {}; - mapping.generatedLine = generatedLine; - - // Generated column. - temp = base64VLQ.decode(str); - mapping.generatedColumn = previousGeneratedColumn + temp.value; - previousGeneratedColumn = mapping.generatedColumn; - str = temp.rest; - - if (str.length > 0 && !mappingSeparator.test(str.charAt(0))) { - // Original source. - temp = base64VLQ.decode(str); - mapping.source = this._sources.at(previousSource + temp.value); - previousSource += temp.value; - str = temp.rest; - if (str.length === 0 || mappingSeparator.test(str.charAt(0))) { - throw new Error('Found a source, but no line and column'); - } - - // Original line. - temp = base64VLQ.decode(str); - mapping.originalLine = previousOriginalLine + temp.value; - previousOriginalLine = mapping.originalLine; - // Lines are stored 0-based - mapping.originalLine += 1; - str = temp.rest; - if (str.length === 0 || mappingSeparator.test(str.charAt(0))) { - throw new Error('Found a source and line, but no column'); - } - - // Original column. - temp = base64VLQ.decode(str); - mapping.originalColumn = previousOriginalColumn + temp.value; - previousOriginalColumn = mapping.originalColumn; - str = temp.rest; - - if (str.length > 0 && !mappingSeparator.test(str.charAt(0))) { - // Original name. - temp = base64VLQ.decode(str); - mapping.name = this._names.at(previousName + temp.value); - previousName += temp.value; - str = temp.rest; - } - } - - this.__generatedMappings.push(mapping); - if (typeof mapping.originalLine === 'number') { - this.__originalMappings.push(mapping); - } - } - } - - this.__originalMappings.sort(util.compareByOriginalPositions); - }; - - /** - * Find the mapping that best matches the hypothetical "needle" mapping that - * we are searching for in the given "haystack" of mappings. - */ - SourceMapConsumer.prototype._findMapping = - function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName, - aColumnName, aComparator) { - // To return the position we are searching for, we must first find the - // mapping for the given position and then return the opposite position it - // points to. Because the mappings are sorted, we can use binary search to - // find the best mapping. - - if (aNeedle[aLineName] <= 0) { - throw new TypeError('Line must be greater than or equal to 1, got ' - + aNeedle[aLineName]); - } - if (aNeedle[aColumnName] < 0) { - throw new TypeError('Column must be greater than or equal to 0, got ' - + aNeedle[aColumnName]); - } - - return binarySearch.search(aNeedle, aMappings, aComparator); - }; - - /** - * Returns the original source, line, and column information for the generated - * source's line and column positions provided. The only argument is an object - * with the following properties: - * - * - line: The line number in the generated source. - * - column: The column number in the generated source. - * - * and an object is returned with the following properties: - * - * - source: The original source file, or null. - * - line: The line number in the original source, or null. - * - column: The column number in the original source, or null. - * - name: The original identifier, or null. - */ - SourceMapConsumer.prototype.originalPositionFor = - function SourceMapConsumer_originalPositionFor(aArgs) { - var needle = { - generatedLine: util.getArg(aArgs, 'line'), - generatedColumn: util.getArg(aArgs, 'column') - }; - - var mapping = this._findMapping(needle, - this._generatedMappings, - "generatedLine", - "generatedColumn", - util.compareByGeneratedPositions); - - if (mapping) { - var source = util.getArg(mapping, 'source', null); - if (source && this.sourceRoot) { - source = util.join(this.sourceRoot, source); - } - return { - source: source, - line: util.getArg(mapping, 'originalLine', null), - column: util.getArg(mapping, 'originalColumn', null), - name: util.getArg(mapping, 'name', null) - }; - } - - return { - source: null, - line: null, - column: null, - name: null - }; - }; - - /** - * Returns the original source content. The only argument is the url of the - * original source file. Returns null if no original source content is - * availible. - */ - SourceMapConsumer.prototype.sourceContentFor = - function SourceMapConsumer_sourceContentFor(aSource) { - if (!this.sourcesContent) { - return null; - } - - if (this.sourceRoot) { - aSource = util.relative(this.sourceRoot, aSource); - } - - if (this._sources.has(aSource)) { - return this.sourcesContent[this._sources.indexOf(aSource)]; - } - - var url; - if (this.sourceRoot - && (url = util.urlParse(this.sourceRoot))) { - // XXX: file:// URIs and absolute paths lead to unexpected behavior for - // many users. We can help them out when they expect file:// URIs to - // behave like it would if they were running a local HTTP server. See - // https://bugzilla.mozilla.org/show_bug.cgi?id=885597. - var fileUriAbsPath = aSource.replace(/^file:\/\//, ""); - if (url.scheme == "file" - && this._sources.has(fileUriAbsPath)) { - return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)] - } - - if ((!url.path || url.path == "/") - && this._sources.has("/" + aSource)) { - return this.sourcesContent[this._sources.indexOf("/" + aSource)]; - } - } - - throw new Error('"' + aSource + '" is not in the SourceMap.'); - }; - - /** - * Returns the generated line and column information for the original source, - * line, and column positions provided. The only argument is an object with - * the following properties: - * - * - source: The filename of the original source. - * - line: The line number in the original source. - * - column: The column number in the original source. - * - * and an object is returned with the following properties: - * - * - line: The line number in the generated source, or null. - * - column: The column number in the generated source, or null. - */ - SourceMapConsumer.prototype.generatedPositionFor = - function SourceMapConsumer_generatedPositionFor(aArgs) { - var needle = { - source: util.getArg(aArgs, 'source'), - originalLine: util.getArg(aArgs, 'line'), - originalColumn: util.getArg(aArgs, 'column') - }; - - if (this.sourceRoot) { - needle.source = util.relative(this.sourceRoot, needle.source); - } - - var mapping = this._findMapping(needle, - this._originalMappings, - "originalLine", - "originalColumn", - util.compareByOriginalPositions); - - if (mapping) { - return { - line: util.getArg(mapping, 'generatedLine', null), - column: util.getArg(mapping, 'generatedColumn', null) - }; - } - - return { - line: null, - column: null - }; - }; - - SourceMapConsumer.GENERATED_ORDER = 1; - SourceMapConsumer.ORIGINAL_ORDER = 2; - - /** - * Iterate over each mapping between an original source/line/column and a - * generated line/column in this source map. - * - * @param Function aCallback - * The function that is called with each mapping. - * @param Object aContext - * Optional. If specified, this object will be the value of `this` every - * time that `aCallback` is called. - * @param aOrder - * Either `SourceMapConsumer.GENERATED_ORDER` or - * `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to - * iterate over the mappings sorted by the generated file's line/column - * order or the original's source/line/column order, respectively. Defaults to - * `SourceMapConsumer.GENERATED_ORDER`. - */ - SourceMapConsumer.prototype.eachMapping = - function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) { - var context = aContext || null; - var order = aOrder || SourceMapConsumer.GENERATED_ORDER; - - var mappings; - switch (order) { - case SourceMapConsumer.GENERATED_ORDER: - mappings = this._generatedMappings; - break; - case SourceMapConsumer.ORIGINAL_ORDER: - mappings = this._originalMappings; - break; - default: - throw new Error("Unknown order of iteration."); - } - - var sourceRoot = this.sourceRoot; - mappings.map(function (mapping) { - var source = mapping.source; - if (source && sourceRoot) { - source = util.join(sourceRoot, source); - } - return { - source: source, - generatedLine: mapping.generatedLine, - generatedColumn: mapping.generatedColumn, - originalLine: mapping.originalLine, - originalColumn: mapping.originalColumn, - name: mapping.name - }; - }).forEach(aCallback, context); - }; - - exports.SourceMapConsumer = SourceMapConsumer; - -}); - -},{"./array-set":9,"./base64-vlq":10,"./binary-search":12,"./util":16,"amdefine":17}],14:[function(_dereq_,module,exports){ -/* -*- Mode: js; js-indent-level: 2; -*- */ -/* - * Copyright 2011 Mozilla Foundation and contributors - * Licensed under the New BSD license. See LICENSE or: - * http://opensource.org/licenses/BSD-3-Clause - */ -if (typeof define !== 'function') { - var define = _dereq_('amdefine')(module, _dereq_); -} -define(function (_dereq_, exports, module) { - - var base64VLQ = _dereq_('./base64-vlq'); - var util = _dereq_('./util'); - var ArraySet = _dereq_('./array-set').ArraySet; - - /** - * An instance of the SourceMapGenerator represents a source map which is - * being built incrementally. To create a new one, you must pass an object - * with the following properties: - * - * - file: The filename of the generated source. - * - sourceRoot: An optional root for all URLs in this source map. - */ - function SourceMapGenerator(aArgs) { - this._file = util.getArg(aArgs, 'file'); - this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null); - this._sources = new ArraySet(); - this._names = new ArraySet(); - this._mappings = []; - this._sourcesContents = null; - } - - SourceMapGenerator.prototype._version = 3; - - /** - * Creates a new SourceMapGenerator based on a SourceMapConsumer - * - * @param aSourceMapConsumer The SourceMap. - */ - SourceMapGenerator.fromSourceMap = - function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) { - var sourceRoot = aSourceMapConsumer.sourceRoot; - var generator = new SourceMapGenerator({ - file: aSourceMapConsumer.file, - sourceRoot: sourceRoot - }); - aSourceMapConsumer.eachMapping(function (mapping) { - var newMapping = { - generated: { - line: mapping.generatedLine, - column: mapping.generatedColumn - } - }; - - if (mapping.source) { - newMapping.source = mapping.source; - if (sourceRoot) { - newMapping.source = util.relative(sourceRoot, newMapping.source); - } - - newMapping.original = { - line: mapping.originalLine, - column: mapping.originalColumn - }; - - if (mapping.name) { - newMapping.name = mapping.name; - } - } - - generator.addMapping(newMapping); - }); - aSourceMapConsumer.sources.forEach(function (sourceFile) { - var content = aSourceMapConsumer.sourceContentFor(sourceFile); - if (content) { - generator.setSourceContent(sourceFile, content); - } - }); - return generator; - }; - - /** - * Add a single mapping from original source line and column to the generated - * source's line and column for this source map being created. The mapping - * object should have the following properties: - * - * - generated: An object with the generated line and column positions. - * - original: An object with the original line and column positions. - * - source: The original source file (relative to the sourceRoot). - * - name: An optional original token name for this mapping. - */ - SourceMapGenerator.prototype.addMapping = - function SourceMapGenerator_addMapping(aArgs) { - var generated = util.getArg(aArgs, 'generated'); - var original = util.getArg(aArgs, 'original', null); - var source = util.getArg(aArgs, 'source', null); - var name = util.getArg(aArgs, 'name', null); - - this._validateMapping(generated, original, source, name); - - if (source && !this._sources.has(source)) { - this._sources.add(source); - } - - if (name && !this._names.has(name)) { - this._names.add(name); - } - - this._mappings.push({ - generatedLine: generated.line, - generatedColumn: generated.column, - originalLine: original != null && original.line, - originalColumn: original != null && original.column, - source: source, - name: name - }); - }; - - /** - * Set the source content for a source file. - */ - SourceMapGenerator.prototype.setSourceContent = - function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) { - var source = aSourceFile; - if (this._sourceRoot) { - source = util.relative(this._sourceRoot, source); - } - - if (aSourceContent !== null) { - // Add the source content to the _sourcesContents map. - // Create a new _sourcesContents map if the property is null. - if (!this._sourcesContents) { - this._sourcesContents = {}; - } - this._sourcesContents[util.toSetString(source)] = aSourceContent; - } else { - // Remove the source file from the _sourcesContents map. - // If the _sourcesContents map is empty, set the property to null. - delete this._sourcesContents[util.toSetString(source)]; - if (Object.keys(this._sourcesContents).length === 0) { - this._sourcesContents = null; - } - } - }; - - /** - * Applies the mappings of a sub-source-map for a specific source file to the - * source map being generated. Each mapping to the supplied source file is - * rewritten using the supplied source map. Note: The resolution for the - * resulting mappings is the minimium of this map and the supplied map. - * - * @param aSourceMapConsumer The source map to be applied. - * @param aSourceFile Optional. The filename of the source file. - * If omitted, SourceMapConsumer's file property will be used. - */ - SourceMapGenerator.prototype.applySourceMap = - function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile) { - // If aSourceFile is omitted, we will use the file property of the SourceMap - if (!aSourceFile) { - aSourceFile = aSourceMapConsumer.file; - } - var sourceRoot = this._sourceRoot; - // Make "aSourceFile" relative if an absolute Url is passed. - if (sourceRoot) { - aSourceFile = util.relative(sourceRoot, aSourceFile); - } - // Applying the SourceMap can add and remove items from the sources and - // the names array. - var newSources = new ArraySet(); - var newNames = new ArraySet(); - - // Find mappings for the "aSourceFile" - this._mappings.forEach(function (mapping) { - if (mapping.source === aSourceFile && mapping.originalLine) { - // Check if it can be mapped by the source map, then update the mapping. - var original = aSourceMapConsumer.originalPositionFor({ - line: mapping.originalLine, - column: mapping.originalColumn - }); - if (original.source !== null) { - // Copy mapping - if (sourceRoot) { - mapping.source = util.relative(sourceRoot, original.source); - } else { - mapping.source = original.source; - } - mapping.originalLine = original.line; - mapping.originalColumn = original.column; - if (original.name !== null && mapping.name !== null) { - // Only use the identifier name if it's an identifier - // in both SourceMaps - mapping.name = original.name; - } - } - } - - var source = mapping.source; - if (source && !newSources.has(source)) { - newSources.add(source); - } - - var name = mapping.name; - if (name && !newNames.has(name)) { - newNames.add(name); - } - - }, this); - this._sources = newSources; - this._names = newNames; - - // Copy sourcesContents of applied map. - aSourceMapConsumer.sources.forEach(function (sourceFile) { - var content = aSourceMapConsumer.sourceContentFor(sourceFile); - if (content) { - if (sourceRoot) { - sourceFile = util.relative(sourceRoot, sourceFile); - } - this.setSourceContent(sourceFile, content); - } - }, this); - }; - - /** - * A mapping can have one of the three levels of data: - * - * 1. Just the generated position. - * 2. The Generated position, original position, and original source. - * 3. Generated and original position, original source, as well as a name - * token. - * - * To maintain consistency, we validate that any new mapping being added falls - * in to one of these categories. - */ - SourceMapGenerator.prototype._validateMapping = - function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource, - aName) { - if (aGenerated && 'line' in aGenerated && 'column' in aGenerated - && aGenerated.line > 0 && aGenerated.column >= 0 - && !aOriginal && !aSource && !aName) { - // Case 1. - return; - } - else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated - && aOriginal && 'line' in aOriginal && 'column' in aOriginal - && aGenerated.line > 0 && aGenerated.column >= 0 - && aOriginal.line > 0 && aOriginal.column >= 0 - && aSource) { - // Cases 2 and 3. - return; - } - else { - throw new Error('Invalid mapping: ' + JSON.stringify({ - generated: aGenerated, - source: aSource, - orginal: aOriginal, - name: aName - })); - } - }; - - /** - * Serialize the accumulated mappings in to the stream of base 64 VLQs - * specified by the source map format. - */ - SourceMapGenerator.prototype._serializeMappings = - function SourceMapGenerator_serializeMappings() { - var previousGeneratedColumn = 0; - var previousGeneratedLine = 1; - var previousOriginalColumn = 0; - var previousOriginalLine = 0; - var previousName = 0; - var previousSource = 0; - var result = ''; - var mapping; - - // The mappings must be guaranteed to be in sorted order before we start - // serializing them or else the generated line numbers (which are defined - // via the ';' separators) will be all messed up. Note: it might be more - // performant to maintain the sorting as we insert them, rather than as we - // serialize them, but the big O is the same either way. - this._mappings.sort(util.compareByGeneratedPositions); - - for (var i = 0, len = this._mappings.length; i < len; i++) { - mapping = this._mappings[i]; - - if (mapping.generatedLine !== previousGeneratedLine) { - previousGeneratedColumn = 0; - while (mapping.generatedLine !== previousGeneratedLine) { - result += ';'; - previousGeneratedLine++; - } - } - else { - if (i > 0) { - if (!util.compareByGeneratedPositions(mapping, this._mappings[i - 1])) { - continue; - } - result += ','; - } - } - - result += base64VLQ.encode(mapping.generatedColumn - - previousGeneratedColumn); - previousGeneratedColumn = mapping.generatedColumn; - - if (mapping.source) { - result += base64VLQ.encode(this._sources.indexOf(mapping.source) - - previousSource); - previousSource = this._sources.indexOf(mapping.source); - - // lines are stored 0-based in SourceMap spec version 3 - result += base64VLQ.encode(mapping.originalLine - 1 - - previousOriginalLine); - previousOriginalLine = mapping.originalLine - 1; - - result += base64VLQ.encode(mapping.originalColumn - - previousOriginalColumn); - previousOriginalColumn = mapping.originalColumn; - - if (mapping.name) { - result += base64VLQ.encode(this._names.indexOf(mapping.name) - - previousName); - previousName = this._names.indexOf(mapping.name); - } - } - } - - return result; - }; - - SourceMapGenerator.prototype._generateSourcesContent = - function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) { - return aSources.map(function (source) { - if (!this._sourcesContents) { - return null; - } - if (aSourceRoot) { - source = util.relative(aSourceRoot, source); - } - var key = util.toSetString(source); - return Object.prototype.hasOwnProperty.call(this._sourcesContents, - key) - ? this._sourcesContents[key] - : null; - }, this); - }; - - /** - * Externalize the source map. - */ - SourceMapGenerator.prototype.toJSON = - function SourceMapGenerator_toJSON() { - var map = { - version: this._version, - file: this._file, - sources: this._sources.toArray(), - names: this._names.toArray(), - mappings: this._serializeMappings() - }; - if (this._sourceRoot) { - map.sourceRoot = this._sourceRoot; - } - if (this._sourcesContents) { - map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot); - } - - return map; - }; - - /** - * Render the source map being generated to a string. - */ - SourceMapGenerator.prototype.toString = - function SourceMapGenerator_toString() { - return JSON.stringify(this); - }; - - exports.SourceMapGenerator = SourceMapGenerator; - -}); - -},{"./array-set":9,"./base64-vlq":10,"./util":16,"amdefine":17}],15:[function(_dereq_,module,exports){ -/* -*- Mode: js; js-indent-level: 2; -*- */ -/* - * Copyright 2011 Mozilla Foundation and contributors - * Licensed under the New BSD license. See LICENSE or: - * http://opensource.org/licenses/BSD-3-Clause - */ -if (typeof define !== 'function') { - var define = _dereq_('amdefine')(module, _dereq_); -} -define(function (_dereq_, exports, module) { - - var SourceMapGenerator = _dereq_('./source-map-generator').SourceMapGenerator; - var util = _dereq_('./util'); - - /** - * SourceNodes provide a way to abstract over interpolating/concatenating - * snippets of generated JavaScript source code while maintaining the line and - * column information associated with the original source code. - * - * @param aLine The original line number. - * @param aColumn The original column number. - * @param aSource The original source's filename. - * @param aChunks Optional. An array of strings which are snippets of - * generated JS, or other SourceNodes. - * @param aName The original identifier. - */ - function SourceNode(aLine, aColumn, aSource, aChunks, aName) { - this.children = []; - this.sourceContents = {}; - this.line = aLine === undefined ? null : aLine; - this.column = aColumn === undefined ? null : aColumn; - this.source = aSource === undefined ? null : aSource; - this.name = aName === undefined ? null : aName; - if (aChunks != null) this.add(aChunks); - } - - /** - * Creates a SourceNode from generated code and a SourceMapConsumer. - * - * @param aGeneratedCode The generated code - * @param aSourceMapConsumer The SourceMap for the generated code - */ - SourceNode.fromStringWithSourceMap = - function SourceNode_fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer) { - // The SourceNode we want to fill with the generated code - // and the SourceMap - var node = new SourceNode(); - - // The generated code - // Processed fragments are removed from this array. - var remainingLines = aGeneratedCode.split('\n'); - - // We need to remember the position of "remainingLines" - var lastGeneratedLine = 1, lastGeneratedColumn = 0; - - // The generate SourceNodes we need a code range. - // To extract it current and last mapping is used. - // Here we store the last mapping. - var lastMapping = null; - - aSourceMapConsumer.eachMapping(function (mapping) { - if (lastMapping === null) { - // We add the generated code until the first mapping - // to the SourceNode without any mapping. - // Each line is added as separate string. - while (lastGeneratedLine < mapping.generatedLine) { - node.add(remainingLines.shift() + "\n"); - lastGeneratedLine++; - } - if (lastGeneratedColumn < mapping.generatedColumn) { - var nextLine = remainingLines[0]; - node.add(nextLine.substr(0, mapping.generatedColumn)); - remainingLines[0] = nextLine.substr(mapping.generatedColumn); - lastGeneratedColumn = mapping.generatedColumn; - } - } else { - // We add the code from "lastMapping" to "mapping": - // First check if there is a new line in between. - if (lastGeneratedLine < mapping.generatedLine) { - var code = ""; - // Associate full lines with "lastMapping" - do { - code += remainingLines.shift() + "\n"; - lastGeneratedLine++; - lastGeneratedColumn = 0; - } while (lastGeneratedLine < mapping.generatedLine); - // When we reached the correct line, we add code until we - // reach the correct column too. - if (lastGeneratedColumn < mapping.generatedColumn) { - var nextLine = remainingLines[0]; - code += nextLine.substr(0, mapping.generatedColumn); - remainingLines[0] = nextLine.substr(mapping.generatedColumn); - lastGeneratedColumn = mapping.generatedColumn; - } - // Create the SourceNode. - addMappingWithCode(lastMapping, code); - } else { - // There is no new line in between. - // Associate the code between "lastGeneratedColumn" and - // "mapping.generatedColumn" with "lastMapping" - var nextLine = remainingLines[0]; - var code = nextLine.substr(0, mapping.generatedColumn - - lastGeneratedColumn); - remainingLines[0] = nextLine.substr(mapping.generatedColumn - - lastGeneratedColumn); - lastGeneratedColumn = mapping.generatedColumn; - addMappingWithCode(lastMapping, code); - } - } - lastMapping = mapping; - }, this); - // We have processed all mappings. - // Associate the remaining code in the current line with "lastMapping" - // and add the remaining lines without any mapping - addMappingWithCode(lastMapping, remainingLines.join("\n")); - - // Copy sourcesContent into SourceNode - aSourceMapConsumer.sources.forEach(function (sourceFile) { - var content = aSourceMapConsumer.sourceContentFor(sourceFile); - if (content) { - node.setSourceContent(sourceFile, content); - } - }); - - return node; - - function addMappingWithCode(mapping, code) { - if (mapping === null || mapping.source === undefined) { - node.add(code); - } else { - node.add(new SourceNode(mapping.originalLine, - mapping.originalColumn, - mapping.source, - code, - mapping.name)); - } - } - }; - - /** - * Add a chunk of generated JS to this source node. - * - * @param aChunk A string snippet of generated JS code, another instance of - * SourceNode, or an array where each member is one of those things. - */ - SourceNode.prototype.add = function SourceNode_add(aChunk) { - if (Array.isArray(aChunk)) { - aChunk.forEach(function (chunk) { - this.add(chunk); - }, this); - } - else if (aChunk instanceof SourceNode || typeof aChunk === "string") { - if (aChunk) { - this.children.push(aChunk); - } - } - else { - throw new TypeError( - "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk - ); - } - return this; - }; - - /** - * Add a chunk of generated JS to the beginning of this source node. - * - * @param aChunk A string snippet of generated JS code, another instance of - * SourceNode, or an array where each member is one of those things. - */ - SourceNode.prototype.prepend = function SourceNode_prepend(aChunk) { - if (Array.isArray(aChunk)) { - for (var i = aChunk.length-1; i >= 0; i--) { - this.prepend(aChunk[i]); - } - } - else if (aChunk instanceof SourceNode || typeof aChunk === "string") { - this.children.unshift(aChunk); - } - else { - throw new TypeError( - "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk - ); - } - return this; - }; - - /** - * Walk over the tree of JS snippets in this node and its children. The - * walking function is called once for each snippet of JS and is passed that - * snippet and the its original associated source's line/column location. - * - * @param aFn The traversal function. - */ - SourceNode.prototype.walk = function SourceNode_walk(aFn) { - var chunk; - for (var i = 0, len = this.children.length; i < len; i++) { - chunk = this.children[i]; - if (chunk instanceof SourceNode) { - chunk.walk(aFn); - } - else { - if (chunk !== '') { - aFn(chunk, { source: this.source, - line: this.line, - column: this.column, - name: this.name }); - } - } - } - }; - - /** - * Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between - * each of `this.children`. - * - * @param aSep The separator. - */ - SourceNode.prototype.join = function SourceNode_join(aSep) { - var newChildren; - var i; - var len = this.children.length; - if (len > 0) { - newChildren = []; - for (i = 0; i < len-1; i++) { - newChildren.push(this.children[i]); - newChildren.push(aSep); - } - newChildren.push(this.children[i]); - this.children = newChildren; - } - return this; - }; - - /** - * Call String.prototype.replace on the very right-most source snippet. Useful - * for trimming whitespace from the end of a source node, etc. - * - * @param aPattern The pattern to replace. - * @param aReplacement The thing to replace the pattern with. - */ - SourceNode.prototype.replaceRight = function SourceNode_replaceRight(aPattern, aReplacement) { - var lastChild = this.children[this.children.length - 1]; - if (lastChild instanceof SourceNode) { - lastChild.replaceRight(aPattern, aReplacement); - } - else if (typeof lastChild === 'string') { - this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement); - } - else { - this.children.push(''.replace(aPattern, aReplacement)); - } - return this; - }; - - /** - * Set the source content for a source file. This will be added to the SourceMapGenerator - * in the sourcesContent field. - * - * @param aSourceFile The filename of the source file - * @param aSourceContent The content of the source file - */ - SourceNode.prototype.setSourceContent = - function SourceNode_setSourceContent(aSourceFile, aSourceContent) { - this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent; - }; - - /** - * Walk over the tree of SourceNodes. The walking function is called for each - * source file content and is passed the filename and source content. - * - * @param aFn The traversal function. - */ - SourceNode.prototype.walkSourceContents = - function SourceNode_walkSourceContents(aFn) { - for (var i = 0, len = this.children.length; i < len; i++) { - if (this.children[i] instanceof SourceNode) { - this.children[i].walkSourceContents(aFn); - } - } - - var sources = Object.keys(this.sourceContents); - for (var i = 0, len = sources.length; i < len; i++) { - aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]); - } - }; - - /** - * Return the string representation of this source node. Walks over the tree - * and concatenates all the various snippets together to one string. - */ - SourceNode.prototype.toString = function SourceNode_toString() { - var str = ""; - this.walk(function (chunk) { - str += chunk; - }); - return str; - }; - - /** - * Returns the string representation of this source node along with a source - * map. - */ - SourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSourceMap(aArgs) { - var generated = { - code: "", - line: 1, - column: 0 - }; - var map = new SourceMapGenerator(aArgs); - var sourceMappingActive = false; - var lastOriginalSource = null; - var lastOriginalLine = null; - var lastOriginalColumn = null; - var lastOriginalName = null; - this.walk(function (chunk, original) { - generated.code += chunk; - if (original.source !== null - && original.line !== null - && original.column !== null) { - if(lastOriginalSource !== original.source - || lastOriginalLine !== original.line - || lastOriginalColumn !== original.column - || lastOriginalName !== original.name) { - map.addMapping({ - source: original.source, - original: { - line: original.line, - column: original.column - }, - generated: { - line: generated.line, - column: generated.column - }, - name: original.name - }); - } - lastOriginalSource = original.source; - lastOriginalLine = original.line; - lastOriginalColumn = original.column; - lastOriginalName = original.name; - sourceMappingActive = true; - } else if (sourceMappingActive) { - map.addMapping({ - generated: { - line: generated.line, - column: generated.column - } - }); - lastOriginalSource = null; - sourceMappingActive = false; - } - chunk.split('').forEach(function (ch) { - if (ch === '\n') { - generated.line++; - generated.column = 0; - } else { - generated.column++; - } - }); - }); - this.walkSourceContents(function (sourceFile, sourceContent) { - map.setSourceContent(sourceFile, sourceContent); - }); - - return { code: generated.code, map: map }; - }; - - exports.SourceNode = SourceNode; - -}); - -},{"./source-map-generator":14,"./util":16,"amdefine":17}],16:[function(_dereq_,module,exports){ -/* -*- Mode: js; js-indent-level: 2; -*- */ -/* - * Copyright 2011 Mozilla Foundation and contributors - * Licensed under the New BSD license. See LICENSE or: - * http://opensource.org/licenses/BSD-3-Clause - */ -if (typeof define !== 'function') { - var define = _dereq_('amdefine')(module, _dereq_); -} -define(function (_dereq_, exports, module) { - - /** - * This is a helper function for getting values from parameter/options - * objects. - * - * @param args The object we are extracting values from - * @param name The name of the property we are getting. - * @param defaultValue An optional value to return if the property is missing - * from the object. If this is not specified and the property is missing, an - * error will be thrown. - */ - function getArg(aArgs, aName, aDefaultValue) { - if (aName in aArgs) { - return aArgs[aName]; - } else if (arguments.length === 3) { - return aDefaultValue; - } else { - throw new Error('"' + aName + '" is a required argument.'); - } - } - exports.getArg = getArg; - - var urlRegexp = /([\w+\-.]+):\/\/((\w+:\w+)@)?([\w.]+)?(:(\d+))?(\S+)?/; - var dataUrlRegexp = /^data:.+\,.+/; - - function urlParse(aUrl) { - var match = aUrl.match(urlRegexp); - if (!match) { - return null; - } - return { - scheme: match[1], - auth: match[3], - host: match[4], - port: match[6], - path: match[7] - }; - } - exports.urlParse = urlParse; - - function urlGenerate(aParsedUrl) { - var url = aParsedUrl.scheme + "://"; - if (aParsedUrl.auth) { - url += aParsedUrl.auth + "@" - } - if (aParsedUrl.host) { - url += aParsedUrl.host; - } - if (aParsedUrl.port) { - url += ":" + aParsedUrl.port - } - if (aParsedUrl.path) { - url += aParsedUrl.path; - } - return url; - } - exports.urlGenerate = urlGenerate; - - function join(aRoot, aPath) { - var url; - - if (aPath.match(urlRegexp) || aPath.match(dataUrlRegexp)) { - return aPath; - } - - if (aPath.charAt(0) === '/' && (url = urlParse(aRoot))) { - url.path = aPath; - return urlGenerate(url); - } - - return aRoot.replace(/\/$/, '') + '/' + aPath; - } - exports.join = join; - - /** - * Because behavior goes wacky when you set `__proto__` on objects, we - * have to prefix all the strings in our set with an arbitrary character. - * - * See https://github.com/mozilla/source-map/pull/31 and - * https://github.com/mozilla/source-map/issues/30 - * - * @param String aStr - */ - function toSetString(aStr) { - return '$' + aStr; - } - exports.toSetString = toSetString; - - function fromSetString(aStr) { - return aStr.substr(1); - } - exports.fromSetString = fromSetString; - - function relative(aRoot, aPath) { - aRoot = aRoot.replace(/\/$/, ''); - - var url = urlParse(aRoot); - if (aPath.charAt(0) == "/" && url && url.path == "/") { - return aPath.slice(1); - } - - return aPath.indexOf(aRoot + '/') === 0 - ? aPath.substr(aRoot.length + 1) - : aPath; - } - exports.relative = relative; - - function strcmp(aStr1, aStr2) { - var s1 = aStr1 || ""; - var s2 = aStr2 || ""; - return (s1 > s2) - (s1 < s2); - } - - /** - * Comparator between two mappings where the original positions are compared. - * - * Optionally pass in `true` as `onlyCompareGenerated` to consider two - * mappings with the same original source/line/column, but different generated - * line and column the same. Useful when searching for a mapping with a - * stubbed out mapping. - */ - function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) { - var cmp; - - cmp = strcmp(mappingA.source, mappingB.source); - if (cmp) { - return cmp; - } - - cmp = mappingA.originalLine - mappingB.originalLine; - if (cmp) { - return cmp; - } - - cmp = mappingA.originalColumn - mappingB.originalColumn; - if (cmp || onlyCompareOriginal) { - return cmp; - } - - cmp = strcmp(mappingA.name, mappingB.name); - if (cmp) { - return cmp; - } - - cmp = mappingA.generatedLine - mappingB.generatedLine; - if (cmp) { - return cmp; - } - - return mappingA.generatedColumn - mappingB.generatedColumn; - }; - exports.compareByOriginalPositions = compareByOriginalPositions; - - /** - * Comparator between two mappings where the generated positions are - * compared. - * - * Optionally pass in `true` as `onlyCompareGenerated` to consider two - * mappings with the same generated line and column, but different - * source/name/original line and column the same. Useful when searching for a - * mapping with a stubbed out mapping. - */ - function compareByGeneratedPositions(mappingA, mappingB, onlyCompareGenerated) { - var cmp; - - cmp = mappingA.generatedLine - mappingB.generatedLine; - if (cmp) { - return cmp; - } - - cmp = mappingA.generatedColumn - mappingB.generatedColumn; - if (cmp || onlyCompareGenerated) { - return cmp; - } - - cmp = strcmp(mappingA.source, mappingB.source); - if (cmp) { - return cmp; - } - - cmp = mappingA.originalLine - mappingB.originalLine; - if (cmp) { - return cmp; - } - - cmp = mappingA.originalColumn - mappingB.originalColumn; - if (cmp) { - return cmp; - } - - return strcmp(mappingA.name, mappingB.name); - }; - exports.compareByGeneratedPositions = compareByGeneratedPositions; - -}); - -},{"amdefine":17}],17:[function(_dereq_,module,exports){ -(function (process,__filename){ -/** vim: et:ts=4:sw=4:sts=4 - * @license amdefine 0.1.0 Copyright (c) 2011, The Dojo Foundation All Rights Reserved. - * Available via the MIT or new BSD license. - * see: http://github.com/jrburke/amdefine for details - */ - -/*jslint node: true */ -/*global module, process */ -'use strict'; - -/** - * Creates a define for node. - * @param {Object} module the "module" object that is defined by Node for the - * current module. - * @param {Function} [requireFn]. Node's require function for the current module. - * It only needs to be passed in Node versions before 0.5, when module.require - * did not exist. - * @returns {Function} a define function that is usable for the current node - * module. - */ -function amdefine(module, requireFn) { - 'use strict'; - var defineCache = {}, - loaderCache = {}, - alreadyCalled = false, - path = _dereq_('path'), - makeRequire, stringRequire; - - /** - * Trims the . and .. from an array of path segments. - * It will keep a leading path segment if a .. will become - * the first path segment, to help with module name lookups, - * which act like paths, but can be remapped. But the end result, - * all paths that use this function should look normalized. - * NOTE: this method MODIFIES the input array. - * @param {Array} ary the array of path segments. - */ - function trimDots(ary) { - var i, part; - for (i = 0; ary[i]; i+= 1) { - part = ary[i]; - if (part === '.') { - ary.splice(i, 1); - i -= 1; - } else if (part === '..') { - if (i === 1 && (ary[2] === '..' || ary[0] === '..')) { - //End of the line. Keep at least one non-dot - //path segment at the front so it can be mapped - //correctly to disk. Otherwise, there is likely - //no path mapping for a path starting with '..'. - //This can still fail, but catches the most reasonable - //uses of .. - break; - } else if (i > 0) { - ary.splice(i - 1, 2); - i -= 2; - } - } - } - } - - function normalize(name, baseName) { - var baseParts; - - //Adjust any relative paths. - if (name && name.charAt(0) === '.') { - //If have a base name, try to normalize against it, - //otherwise, assume it is a top-level require that will - //be relative to baseUrl in the end. - if (baseName) { - baseParts = baseName.split('/'); - baseParts = baseParts.slice(0, baseParts.length - 1); - baseParts = baseParts.concat(name.split('/')); - trimDots(baseParts); - name = baseParts.join('/'); - } - } - - return name; - } - - /** - * Create the normalize() function passed to a loader plugin's - * normalize method. - */ - function makeNormalize(relName) { - return function (name) { - return normalize(name, relName); - }; - } - - function makeLoad(id) { - function load(value) { - loaderCache[id] = value; - } - - load.fromText = function (id, text) { - //This one is difficult because the text can/probably uses - //define, and any relative paths and requires should be relative - //to that id was it would be found on disk. But this would require - //bootstrapping a module/require fairly deeply from node core. - //Not sure how best to go about that yet. - throw new Error('amdefine does not implement load.fromText'); - }; - - return load; - } - - makeRequire = function (systemRequire, exports, module, relId) { - function amdRequire(deps, callback) { - if (typeof deps === 'string') { - //Synchronous, single module require('') - return stringRequire(systemRequire, exports, module, deps, relId); - } else { - //Array of dependencies with a callback. - - //Convert the dependencies to modules. - deps = deps.map(function (depName) { - return stringRequire(systemRequire, exports, module, depName, relId); - }); - - //Wait for next tick to call back the require call. - process.nextTick(function () { - callback.apply(null, deps); - }); - } - } - - amdRequire.toUrl = function (filePath) { - if (filePath.indexOf('.') === 0) { - return normalize(filePath, path.dirname(module.filename)); - } else { - return filePath; - } - }; - - return amdRequire; - }; - - //Favor explicit value, passed in if the module wants to support Node 0.4. - requireFn = requireFn || function req() { - return module.require.apply(module, arguments); - }; - - function runFactory(id, deps, factory) { - var r, e, m, result; - - if (id) { - e = loaderCache[id] = {}; - m = { - id: id, - uri: __filename, - exports: e - }; - r = makeRequire(requireFn, e, m, id); - } else { - //Only support one define call per file - if (alreadyCalled) { - throw new Error('amdefine with no module ID cannot be called more than once per file.'); - } - alreadyCalled = true; - - //Use the real variables from node - //Use module.exports for exports, since - //the exports in here is amdefine exports. - e = module.exports; - m = module; - r = makeRequire(requireFn, e, m, module.id); - } - - //If there are dependencies, they are strings, so need - //to convert them to dependency values. - if (deps) { - deps = deps.map(function (depName) { - return r(depName); - }); - } - - //Call the factory with the right dependencies. - if (typeof factory === 'function') { - result = factory.apply(m.exports, deps); - } else { - result = factory; - } - - if (result !== undefined) { - m.exports = result; - if (id) { - loaderCache[id] = m.exports; - } - } - } - - stringRequire = function (systemRequire, exports, module, id, relId) { - //Split the ID by a ! so that - var index = id.indexOf('!'), - originalId = id, - prefix, plugin; - - if (index === -1) { - id = normalize(id, relId); - - //Straight module lookup. If it is one of the special dependencies, - //deal with it, otherwise, delegate to node. - if (id === 'require') { - return makeRequire(systemRequire, exports, module, relId); - } else if (id === 'exports') { - return exports; - } else if (id === 'module') { - return module; - } else if (loaderCache.hasOwnProperty(id)) { - return loaderCache[id]; - } else if (defineCache[id]) { - runFactory.apply(null, defineCache[id]); - return loaderCache[id]; - } else { - if(systemRequire) { - return systemRequire(originalId); - } else { - throw new Error('No module with ID: ' + id); - } - } - } else { - //There is a plugin in play. - prefix = id.substring(0, index); - id = id.substring(index + 1, id.length); - - plugin = stringRequire(systemRequire, exports, module, prefix, relId); - - if (plugin.normalize) { - id = plugin.normalize(id, makeNormalize(relId)); - } else { - //Normalize the ID normally. - id = normalize(id, relId); - } - - if (loaderCache[id]) { - return loaderCache[id]; - } else { - plugin.load(id, makeRequire(systemRequire, exports, module, relId), makeLoad(id), {}); - - return loaderCache[id]; - } - } - }; - - //Create a define function specific to the module asking for amdefine. - function define(id, deps, factory) { - if (Array.isArray(id)) { - factory = deps; - deps = id; - id = undefined; - } else if (typeof id !== 'string') { - factory = id; - id = deps = undefined; - } - - if (deps && !Array.isArray(deps)) { - factory = deps; - deps = undefined; - } - - if (!deps) { - deps = ['require', 'exports', 'module']; - } - - //Set up properties for this module. If an ID, then use - //internal cache. If no ID, then use the external variables - //for this node module. - if (id) { - //Put the module in deep freeze until there is a - //require call for it. - defineCache[id] = [id, deps, factory]; - } else { - runFactory(id, deps, factory); - } - } - - //define.require, which has access to all the values in the - //cache. Useful for AMD modules that all have IDs in the file, - //but need to finally export a value to node based on one of those - //IDs. - define.require = function (id) { - if (loaderCache[id]) { - return loaderCache[id]; - } - - if (defineCache[id]) { - runFactory.apply(null, defineCache[id]); - return loaderCache[id]; - } - }; - - define.amd = {}; - - return define; -} - -module.exports = amdefine; - -}).call(this,_dereq_("FWaASH"),"/../node_modules/jstransform/node_modules/source-map/node_modules/amdefine/amdefine.js") -},{"FWaASH":5,"path":4}],18:[function(_dereq_,module,exports){ -/** - * Copyright 2013 Facebook, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -var docblockRe = /^\s*(\/\*\*(.|\r?\n)*?\*\/)/; -var ltrimRe = /^\s*/; -/** - * @param {String} contents - * @return {String} - */ -function extract(contents) { - var match = contents.match(docblockRe); - if (match) { - return match[0].replace(ltrimRe, '') || ''; - } - return ''; -} - - -var commentStartRe = /^\/\*\*?/; -var commentEndRe = /\*+\/$/; -var wsRe = /[\t ]+/g; -var stringStartRe = /(\r?\n|^) *\*/g; -var multilineRe = /(?:^|\r?\n) *(@[^\r\n]*?) *\r?\n *([^@\r\n\s][^@\r\n]+?) *\r?\n/g; -var propertyRe = /(?:^|\r?\n) *@(\S+) *([^\r\n]*)/g; - -/** - * @param {String} contents - * @return {Array} - */ -function parse(docblock) { - docblock = docblock - .replace(commentStartRe, '') - .replace(commentEndRe, '') - .replace(wsRe, ' ') - .replace(stringStartRe, '$1'); - - // Normalize multi-line directives - var prev = ''; - while (prev != docblock) { - prev = docblock; - docblock = docblock.replace(multilineRe, "\n$1 $2\n"); - } - docblock = docblock.trim(); - - var result = []; - var match; - while (match = propertyRe.exec(docblock)) { - result.push([match[1], match[2]]); - } - - return result; -} - -/** - * Same as parse but returns an object of prop: value instead of array of paris - * If a property appers more than once the last one will be returned - * - * @param {String} contents - * @return {Object} - */ -function parseAsObject(docblock) { - var pairs = parse(docblock); - var result = {}; - for (var i = 0; i < pairs.length; i++) { - result[pairs[i][0]] = pairs[i][1]; - } - return result; -} - - -exports.extract = extract; -exports.parse = parse; -exports.parseAsObject = parseAsObject; - -},{}],19:[function(_dereq_,module,exports){ -/** - * Copyright 2013 Facebook, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -/*jslint node: true*/ -"use strict"; - -var esprima = _dereq_('esprima-fb'); -var utils = _dereq_('./utils'); - -var getBoundaryNode = utils.getBoundaryNode; -var declareIdentInScope = utils.declareIdentInLocalScope; -var initScopeMetadata = utils.initScopeMetadata; -var Syntax = esprima.Syntax; - -/** - * @param {object} node - * @param {object} parentNode - * @return {boolean} - */ -function _nodeIsClosureScopeBoundary(node, parentNode) { - if (node.type === Syntax.Program) { - return true; - } - - var parentIsFunction = - parentNode.type === Syntax.FunctionDeclaration - || parentNode.type === Syntax.FunctionExpression - || parentNode.type === Syntax.ArrowFunctionExpression; - - return node.type === Syntax.BlockStatement && parentIsFunction; -} - -function _nodeIsBlockScopeBoundary(node, parentNode) { - if (node.type === Syntax.Program) { - return false; - } - - return node.type === Syntax.BlockStatement - && parentNode.type === Syntax.CatchClause; -} - -/** - * @param {object} node - * @param {function} visitor - * @param {array} path - * @param {object} state - */ -function traverse(node, path, state) { - // Create a scope stack entry if this is the first node we've encountered in - // its local scope - var parentNode = path[0]; - if (!Array.isArray(node) && state.localScope.parentNode !== parentNode) { - if (_nodeIsClosureScopeBoundary(node, parentNode)) { - var scopeIsStrict = - state.scopeIsStrict - || node.body.length > 0 - && node.body[0].type === Syntax.ExpressionStatement - && node.body[0].expression.type === Syntax.Literal - && node.body[0].expression.value === 'use strict'; - - if (node.type === Syntax.Program) { - state = utils.updateState(state, { - scopeIsStrict: scopeIsStrict - }); - } else { - state = utils.updateState(state, { - localScope: { - parentNode: parentNode, - parentScope: state.localScope, - identifiers: {}, - tempVarIndex: 0 - }, - scopeIsStrict: scopeIsStrict - }); - - // All functions have an implicit 'arguments' object in scope - declareIdentInScope('arguments', initScopeMetadata(node), state); - - // Include function arg identifiers in the scope boundaries of the - // function - if (parentNode.params.length > 0) { - var param; - for (var i = 0; i < parentNode.params.length; i++) { - param = parentNode.params[i]; - if (param.type === Syntax.Identifier) { - declareIdentInScope( - param.name, initScopeMetadata(parentNode), state - ); - } - } - } - - // Named FunctionExpressions scope their name within the body block of - // themselves only - if (parentNode.type === Syntax.FunctionExpression && parentNode.id) { - var metaData = - initScopeMetadata(parentNode, path.parentNodeslice, parentNode); - declareIdentInScope(parentNode.id.name, metaData, state); - } - } - - // Traverse and find all local identifiers in this closure first to - // account for function/variable declaration hoisting - collectClosureIdentsAndTraverse(node, path, state); - } - - if (_nodeIsBlockScopeBoundary(node, parentNode)) { - state = utils.updateState(state, { - localScope: { - parentNode: parentNode, - parentScope: state.localScope, - identifiers: {} - } - }); - - if (parentNode.type === Syntax.CatchClause) { - declareIdentInScope( - parentNode.param.name, initScopeMetadata(parentNode), state - ); - } - collectBlockIdentsAndTraverse(node, path, state); - } - } - - // Only catchup() before and after traversing a child node - function traverser(node, path, state) { - node.range && utils.catchup(node.range[0], state); - traverse(node, path, state); - node.range && utils.catchup(node.range[1], state); - } - - utils.analyzeAndTraverse(walker, traverser, node, path, state); -} - -function collectClosureIdentsAndTraverse(node, path, state) { - utils.analyzeAndTraverse( - visitLocalClosureIdentifiers, - collectClosureIdentsAndTraverse, - node, - path, - state - ); -} - -function collectBlockIdentsAndTraverse(node, path, state) { - utils.analyzeAndTraverse( - visitLocalBlockIdentifiers, - collectBlockIdentsAndTraverse, - node, - path, - state - ); -} - -function visitLocalClosureIdentifiers(node, path, state) { - var metaData; - switch (node.type) { - case Syntax.FunctionExpression: - // Function expressions don't get their names (if there is one) added to - // the closure scope they're defined in - return false; - case Syntax.ClassDeclaration: - case Syntax.ClassExpression: - case Syntax.FunctionDeclaration: - if (node.id) { - metaData = initScopeMetadata(getBoundaryNode(path), path.slice(), node); - declareIdentInScope(node.id.name, metaData, state); - } - return false; - case Syntax.VariableDeclarator: - // Variables have function-local scope - if (path[0].kind === 'var') { - metaData = initScopeMetadata(getBoundaryNode(path), path.slice(), node); - declareIdentInScope(node.id.name, metaData, state); - } - break; - } -} - -function visitLocalBlockIdentifiers(node, path, state) { - // TODO: Support 'let' here...maybe...one day...or something... - if (node.type === Syntax.CatchClause) { - return false; - } -} - -function walker(node, path, state) { - var visitors = state.g.visitors; - for (var i = 0; i < visitors.length; i++) { - if (visitors[i].test(node, path, state)) { - return visitors[i](traverse, node, path, state); - } - } -} - -var _astCache = {}; - -/** - * Applies all available transformations to the source - * @param {array} visitors - * @param {string} source - * @param {?object} options - * @return {object} - */ -function transform(visitors, source, options) { - options = options || {}; - var ast; - try { - var cachedAst = _astCache[source]; - ast = cachedAst || - (_astCache[source] = esprima.parse(source, { - comment: true, - loc: true, - range: true - })); - } catch (e) { - e.message = 'Parse Error: ' + e.message; - throw e; - } - var state = utils.createState(source, ast, options); - state.g.visitors = visitors; - - if (options.sourceMap) { - var SourceMapGenerator = _dereq_('source-map').SourceMapGenerator; - state.g.sourceMap = new SourceMapGenerator({file: options.filename || 'transformed.js'}); - } - - traverse(ast, [], state); - utils.catchup(source.length, state); - - var ret = {code: state.g.buffer, extra: state.g.extra}; - if (options.sourceMap) { - ret.sourceMap = state.g.sourceMap; - ret.sourceMapFilename = options.filename || 'source.js'; - } - return ret; -} - -exports.transform = transform; - -},{"./utils":20,"esprima-fb":6,"source-map":8}],20:[function(_dereq_,module,exports){ -/** - * Copyright 2013 Facebook, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -/*jslint node: true*/ -var Syntax = _dereq_('esprima-fb').Syntax; -var leadingIndentRegexp = /(^|\n)( {2}|\t)/g; -var nonWhiteRegexp = /(\S)/g; - -/** - * A `state` object represents the state of the parser. It has "local" and - * "global" parts. Global contains parser position, source, etc. Local contains - * scope based properties like current class name. State should contain all the - * info required for transformation. It's the only mandatory object that is - * being passed to every function in transform chain. - * - * @param {string} source - * @param {object} transformOptions - * @return {object} - */ -function createState(source, rootNode, transformOptions) { - return { - /** - * A tree representing the current local scope (and its lexical scope chain) - * Useful for tracking identifiers from parent scopes, etc. - * @type {Object} - */ - localScope: { - parentNode: rootNode, - parentScope: null, - identifiers: {}, - tempVarIndex: 0 - }, - /** - * The name (and, if applicable, expression) of the super class - * @type {Object} - */ - superClass: null, - /** - * The namespace to use when munging identifiers - * @type {String} - */ - mungeNamespace: '', - /** - * Ref to the node for the current MethodDefinition - * @type {Object} - */ - methodNode: null, - /** - * Ref to the node for the FunctionExpression of the enclosing - * MethodDefinition - * @type {Object} - */ - methodFuncNode: null, - /** - * Name of the enclosing class - * @type {String} - */ - className: null, - /** - * Whether we're currently within a `strict` scope - * @type {Bool} - */ - scopeIsStrict: null, - /** - * Indentation offset - * @type {Number} - */ - indentBy: 0, - /** - * Global state (not affected by updateState) - * @type {Object} - */ - g: { - /** - * A set of general options that transformations can consider while doing - * a transformation: - * - * - minify - * Specifies that transformation steps should do their best to minify - * the output source when possible. This is useful for places where - * minification optimizations are possible with higher-level context - * info than what jsxmin can provide. - * - * For example, the ES6 class transform will minify munged private - * variables if this flag is set. - */ - opts: transformOptions, - /** - * Current position in the source code - * @type {Number} - */ - position: 0, - /** - * Auxiliary data to be returned by transforms - * @type {Object} - */ - extra: {}, - /** - * Buffer containing the result - * @type {String} - */ - buffer: '', - /** - * Source that is being transformed - * @type {String} - */ - source: source, - - /** - * Cached parsed docblock (see getDocblock) - * @type {object} - */ - docblock: null, - - /** - * Whether the thing was used - * @type {Boolean} - */ - tagNamespaceUsed: false, - - /** - * If using bolt xjs transformation - * @type {Boolean} - */ - isBolt: undefined, - - /** - * Whether to record source map (expensive) or not - * @type {SourceMapGenerator|null} - */ - sourceMap: null, - - /** - * Filename of the file being processed. Will be returned as a source - * attribute in the source map - */ - sourceMapFilename: 'source.js', - - /** - * Only when source map is used: last line in the source for which - * source map was generated - * @type {Number} - */ - sourceLine: 1, - - /** - * Only when source map is used: last line in the buffer for which - * source map was generated - * @type {Number} - */ - bufferLine: 1, - - /** - * The top-level Program AST for the original file. - */ - originalProgramAST: null, - - sourceColumn: 0, - bufferColumn: 0 - } - }; -} - -/** - * Updates a copy of a given state with "update" and returns an updated state. - * - * @param {object} state - * @param {object} update - * @return {object} - */ -function updateState(state, update) { - var ret = Object.create(state); - Object.keys(update).forEach(function(updatedKey) { - ret[updatedKey] = update[updatedKey]; - }); - return ret; -} - -/** - * Given a state fill the resulting buffer from the original source up to - * the end - * - * @param {number} end - * @param {object} state - * @param {?function} contentTransformer Optional callback to transform newly - * added content. - */ -function catchup(end, state, contentTransformer) { - if (end < state.g.position) { - // cannot move backwards - return; - } - var source = state.g.source.substring(state.g.position, end); - var transformed = updateIndent(source, state); - if (state.g.sourceMap && transformed) { - // record where we are - state.g.sourceMap.addMapping({ - generated: { line: state.g.bufferLine, column: state.g.bufferColumn }, - original: { line: state.g.sourceLine, column: state.g.sourceColumn }, - source: state.g.sourceMapFilename - }); - - // record line breaks in transformed source - var sourceLines = source.split('\n'); - var transformedLines = transformed.split('\n'); - // Add line break mappings between last known mapping and the end of the - // added piece. So for the code piece - // (foo, bar); - // > var x = 2; - // > var b = 3; - // var c = - // only add lines marked with ">": 2, 3. - for (var i = 1; i < sourceLines.length - 1; i++) { - state.g.sourceMap.addMapping({ - generated: { line: state.g.bufferLine, column: 0 }, - original: { line: state.g.sourceLine, column: 0 }, - source: state.g.sourceMapFilename - }); - state.g.sourceLine++; - state.g.bufferLine++; - } - // offset for the last piece - if (sourceLines.length > 1) { - state.g.sourceLine++; - state.g.bufferLine++; - state.g.sourceColumn = 0; - state.g.bufferColumn = 0; - } - state.g.sourceColumn += sourceLines[sourceLines.length - 1].length; - state.g.bufferColumn += - transformedLines[transformedLines.length - 1].length; - } - state.g.buffer += - contentTransformer ? contentTransformer(transformed) : transformed; - state.g.position = end; -} - -/** - * Returns original source for an AST node. - * @param {object} node - * @param {object} state - * @return {string} - */ -function getNodeSourceText(node, state) { - return state.g.source.substring(node.range[0], node.range[1]); -} - -function replaceNonWhite(value) { - return value.replace(nonWhiteRegexp, ' '); -} - -/** - * Removes all non-whitespace characters - */ -function stripNonWhite(value) { - return value.replace(nonWhiteRegexp, ''); -} - -/** - * Catches up as `catchup` but replaces non-whitespace chars with spaces. - */ -function catchupWhiteOut(end, state) { - catchup(end, state, replaceNonWhite); -} - -/** - * Catches up as `catchup` but removes all non-whitespace characters. - */ -function catchupWhiteSpace(end, state) { - catchup(end, state, stripNonWhite); -} - -/** - * Removes all non-newline characters - */ -var reNonNewline = /[^\n]/g; -function stripNonNewline(value) { - return value.replace(reNonNewline, function() { - return ''; - }); -} - -/** - * Catches up as `catchup` but removes all non-newline characters. - * - * Equivalent to appending as many newlines as there are in the original source - * between the current position and `end`. - */ -function catchupNewlines(end, state) { - catchup(end, state, stripNonNewline); -} - - -/** - * Same as catchup but does not touch the buffer - * - * @param {number} end - * @param {object} state - */ -function move(end, state) { - // move the internal cursors - if (state.g.sourceMap) { - if (end < state.g.position) { - state.g.position = 0; - state.g.sourceLine = 1; - state.g.sourceColumn = 0; - } - - var source = state.g.source.substring(state.g.position, end); - var sourceLines = source.split('\n'); - if (sourceLines.length > 1) { - state.g.sourceLine += sourceLines.length - 1; - state.g.sourceColumn = 0; - } - state.g.sourceColumn += sourceLines[sourceLines.length - 1].length; - } - state.g.position = end; -} - -/** - * Appends a string of text to the buffer - * - * @param {string} str - * @param {object} state - */ -function append(str, state) { - if (state.g.sourceMap && str) { - state.g.sourceMap.addMapping({ - generated: { line: state.g.bufferLine, column: state.g.bufferColumn }, - original: { line: state.g.sourceLine, column: state.g.sourceColumn }, - source: state.g.sourceMapFilename - }); - var transformedLines = str.split('\n'); - if (transformedLines.length > 1) { - state.g.bufferLine += transformedLines.length - 1; - state.g.bufferColumn = 0; - } - state.g.bufferColumn += - transformedLines[transformedLines.length - 1].length; - } - state.g.buffer += str; -} - -/** - * Update indent using state.indentBy property. Indent is measured in - * double spaces. Updates a single line only. - * - * @param {string} str - * @param {object} state - * @return {string} - */ -function updateIndent(str, state) { - var indentBy = state.indentBy; - if (indentBy < 0) { - for (var i = 0; i < -indentBy; i++) { - str = str.replace(leadingIndentRegexp, '$1'); - } - } else { - for (var i = 0; i < indentBy; i++) { - str = str.replace(leadingIndentRegexp, '$1$2$2'); - } - } - return str; -} - -/** - * Calculates indent from the beginning of the line until "start" or the first - * character before start. - * @example - * " foo.bar()" - * ^ - * start - * indent will be " " - * - * @param {number} start - * @param {object} state - * @return {string} - */ -function indentBefore(start, state) { - var end = start; - start = start - 1; - - while (start > 0 && state.g.source.charAt(start) != '\n') { - if (!state.g.source.charAt(start).match(/[ \t]/)) { - end = start; - } - start--; - } - return state.g.source.substring(start + 1, end); -} - -function getDocblock(state) { - if (!state.g.docblock) { - var docblock = _dereq_('./docblock'); - state.g.docblock = - docblock.parseAsObject(docblock.extract(state.g.source)); - } - return state.g.docblock; -} - -function identWithinLexicalScope(identName, state, stopBeforeNode) { - var currScope = state.localScope; - while (currScope) { - if (currScope.identifiers[identName] !== undefined) { - return true; - } - - if (stopBeforeNode && currScope.parentNode === stopBeforeNode) { - break; - } - - currScope = currScope.parentScope; - } - return false; -} - -function identInLocalScope(identName, state) { - return state.localScope.identifiers[identName] !== undefined; -} - -/** - * @param {object} boundaryNode - * @param {?array} path - * @return {?object} node - */ -function initScopeMetadata(boundaryNode, path, node) { - return { - boundaryNode: boundaryNode, - bindingPath: path, - bindingNode: node - }; -} - -function declareIdentInLocalScope(identName, metaData, state) { - state.localScope.identifiers[identName] = { - boundaryNode: metaData.boundaryNode, - path: metaData.path, - node: metaData.node, - state: Object.create(state) - }; -} - -function getLexicalBindingMetadata(identName, state) { - return state.localScope.identifiers[identName]; -} - -/** - * Apply the given analyzer function to the current node. If the analyzer - * doesn't return false, traverse each child of the current node using the given - * traverser function. - * - * @param {function} analyzer - * @param {function} traverser - * @param {object} node - * @param {function} visitor - * @param {array} path - * @param {object} state - */ -function analyzeAndTraverse(analyzer, traverser, node, path, state) { - if (node.type) { - if (analyzer(node, path, state) === false) { - return; - } - path.unshift(node); - } - - getOrderedChildren(node).forEach(function(child) { - traverser(child, path, state); - }); - - node.type && path.shift(); -} - -/** - * It is crucial that we traverse in order, or else catchup() on a later - * node that is processed out of order can move the buffer past a node - * that we haven't handled yet, preventing us from modifying that node. - * - * This can happen when a node has multiple properties containing children. - * For example, XJSElement nodes have `openingElement`, `closingElement` and - * `children`. If we traverse `openingElement`, then `closingElement`, then - * when we get to `children`, the buffer has already caught up to the end of - * the closing element, after the children. - * - * This is basically a Schwartzian transform. Collects an array of children, - * each one represented as [child, startIndex]; sorts the array by start - * index; then traverses the children in that order. - */ -function getOrderedChildren(node) { - var queue = []; - for (var key in node) { - if (node.hasOwnProperty(key)) { - enqueueNodeWithStartIndex(queue, node[key]); - } - } - queue.sort(function(a, b) { return a[1] - b[1]; }); - return queue.map(function(pair) { return pair[0]; }); -} - -/** - * Helper function for analyzeAndTraverse which queues up all of the children - * of the given node. - * - * Children can also be found in arrays, so we basically want to merge all of - * those arrays together so we can sort them and then traverse the children - * in order. - * - * One example is the Program node. It contains `body` and `comments`, both - * arrays. Lexographically, comments are interspersed throughout the body - * nodes, but esprima's AST groups them together. - */ -function enqueueNodeWithStartIndex(queue, node) { - if (typeof node !== 'object' || node === null) { - return; - } - if (node.range) { - queue.push([node, node.range[0]]); - } else if (Array.isArray(node)) { - for (var ii = 0; ii < node.length; ii++) { - enqueueNodeWithStartIndex(queue, node[ii]); - } - } -} - -/** - * Checks whether a node or any of its sub-nodes contains - * a syntactic construct of the passed type. - * @param {object} node - AST node to test. - * @param {string} type - node type to lookup. - */ -function containsChildOfType(node, type) { - var foundMatchingChild = false; - function nodeTypeAnalyzer(node) { - if (node.type === type) { - foundMatchingChild = true; - return false; - } - } - function nodeTypeTraverser(child, path, state) { - if (!foundMatchingChild) { - foundMatchingChild = containsChildOfType(child, type); - } - } - analyzeAndTraverse( - nodeTypeAnalyzer, - nodeTypeTraverser, - node, - [] - ); - return foundMatchingChild; -} - -var scopeTypes = {}; -scopeTypes[Syntax.FunctionExpression] = true; -scopeTypes[Syntax.FunctionDeclaration] = true; -scopeTypes[Syntax.Program] = true; - -function getBoundaryNode(path) { - for (var ii = 0; ii < path.length; ++ii) { - if (scopeTypes[path[ii].type]) { - return path[ii]; - } - } - throw new Error( - 'Expected to find a node with one of the following types in path:\n' + - JSON.stringify(Object.keys(scopeTypes)) - ); -} - -exports.append = append; -exports.catchup = catchup; -exports.catchupWhiteOut = catchupWhiteOut; -exports.catchupWhiteSpace = catchupWhiteSpace; -exports.catchupNewlines = catchupNewlines; -exports.containsChildOfType = containsChildOfType; -exports.createState = createState; -exports.declareIdentInLocalScope = declareIdentInLocalScope; -exports.getBoundaryNode = getBoundaryNode; -exports.getDocblock = getDocblock; -exports.getLexicalBindingMetadata = getLexicalBindingMetadata; -exports.initScopeMetadata = initScopeMetadata; -exports.identWithinLexicalScope = identWithinLexicalScope; -exports.identInLocalScope = identInLocalScope; -exports.indentBefore = indentBefore; -exports.move = move; -exports.scopeTypes = scopeTypes; -exports.updateIndent = updateIndent; -exports.updateState = updateState; -exports.analyzeAndTraverse = analyzeAndTraverse; -exports.getOrderedChildren = getOrderedChildren; -exports.getNodeSourceText = getNodeSourceText; - -},{"./docblock":18,"esprima-fb":6}],21:[function(_dereq_,module,exports){ -/** - * Copyright 2013 Facebook, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*global exports:true*/ - -/** - * Desugars ES6 Arrow functions to ES3 function expressions. - * If the function contains `this` expression -- automatically - * binds the function to current value of `this`. - * - * Single parameter, simple expression: - * - * [1, 2, 3].map(x => x * x); - * - * [1, 2, 3].map(function(x) { return x * x; }); - * - * Several parameters, complex block: - * - * this.users.forEach((user, idx) => { - * return this.isActive(idx) && this.send(user); - * }); - * - * this.users.forEach(function(user, idx) { - * return this.isActive(idx) && this.send(user); - * }.bind(this)); - * - */ -var restParamVisitors = _dereq_('./es6-rest-param-visitors'); -var destructuringVisitors = _dereq_('./es6-destructuring-visitors'); - -var Syntax = _dereq_('esprima-fb').Syntax; -var utils = _dereq_('../src/utils'); - -/** - * @public - */ -function visitArrowFunction(traverse, node, path, state) { - var notInExpression = (path[0].type === Syntax.ExpressionStatement); - - // Wrap a function into a grouping operator, if it's not - // in the expression position. - if (notInExpression) { - utils.append('(', state); - } - - utils.append('function', state); - renderParams(traverse, node, path, state); - - // Skip arrow. - utils.catchupWhiteSpace(node.body.range[0], state); - - var renderBody = node.body.type == Syntax.BlockStatement - ? renderStatementBody - : renderExpressionBody; - - path.unshift(node); - renderBody(traverse, node, path, state); - path.shift(); - - // Bind the function only if `this` value is used - // inside it or inside any sub-expression. - if (utils.containsChildOfType(node.body, Syntax.ThisExpression)) { - utils.append('.bind(this)', state); - } - - utils.catchupWhiteSpace(node.range[1], state); - - // Close wrapper if not in the expression. - if (notInExpression) { - utils.append(')', state); - } - - return false; -} - -function renderParams(traverse, node, path, state) { - // To preserve inline typechecking directives, we - // distinguish between parens-free and paranthesized single param. - if (isParensFreeSingleParam(node, state) || !node.params.length) { - utils.append('(', state); - } - if (node.params.length !== 0) { - path.unshift(node); - traverse(node.params, path, state); - path.unshift(); - } - utils.append(')', state); -} - -function isParensFreeSingleParam(node, state) { - return node.params.length === 1 && - state.g.source.charAt(state.g.position) !== '('; -} - -function renderExpressionBody(traverse, node, path, state) { - // Wrap simple expression bodies into a block - // with explicit return statement. - utils.append('{', state); - - // Special handling of rest param. - if (node.rest) { - utils.append( - restParamVisitors.renderRestParamSetup(node), - state - ); - } - - // Special handling of destructured params. - destructuringVisitors.renderDestructuredComponents( - node, - utils.updateState(state, { - localScope: { - parentNode: state.parentNode, - parentScope: state.parentScope, - identifiers: state.identifiers, - tempVarIndex: 0 - } - }) - ); - - utils.append('return ', state); - renderStatementBody(traverse, node, path, state); - utils.append(';}', state); -} - -function renderStatementBody(traverse, node, path, state) { - traverse(node.body, path, state); - utils.catchup(node.body.range[1], state); -} - -visitArrowFunction.test = function(node, path, state) { - return node.type === Syntax.ArrowFunctionExpression; -}; - -exports.visitorList = [ - visitArrowFunction -]; - - -},{"../src/utils":20,"./es6-destructuring-visitors":23,"./es6-rest-param-visitors":26,"esprima-fb":6}],22:[function(_dereq_,module,exports){ -/** - * Copyright 2013 Facebook, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*jslint node:true*/ - -/** - * @typechecks - */ -'use strict'; - -var base62 = _dereq_('base62'); -var Syntax = _dereq_('esprima-fb').Syntax; -var utils = _dereq_('../src/utils'); - -var declareIdentInLocalScope = utils.declareIdentInLocalScope; -var initScopeMetadata = utils.initScopeMetadata; - -var SUPER_PROTO_IDENT_PREFIX = '____SuperProtoOf'; - -var _anonClassUUIDCounter = 0; -var _mungedSymbolMaps = {}; - -function resetSymbols() { - _anonClassUUIDCounter = 0; - _mungedSymbolMaps = {}; -} - -/** - * Used to generate a unique class for use with code-gens for anonymous class - * expressions. - * - * @param {object} state - * @return {string} - */ -function _generateAnonymousClassName(state) { - var mungeNamespace = state.mungeNamespace || ''; - return '____Class' + mungeNamespace + base62.encode(_anonClassUUIDCounter++); -} - -/** - * Given an identifier name, munge it using the current state's mungeNamespace. - * - * @param {string} identName - * @param {object} state - * @return {string} - */ -function _getMungedName(identName, state) { - var mungeNamespace = state.mungeNamespace; - var shouldMinify = state.g.opts.minify; - - if (shouldMinify) { - if (!_mungedSymbolMaps[mungeNamespace]) { - _mungedSymbolMaps[mungeNamespace] = { - symbolMap: {}, - identUUIDCounter: 0 - }; - } - - var symbolMap = _mungedSymbolMaps[mungeNamespace].symbolMap; - if (!symbolMap[identName]) { - symbolMap[identName] = - base62.encode(_mungedSymbolMaps[mungeNamespace].identUUIDCounter++); - } - identName = symbolMap[identName]; - } - return '$' + mungeNamespace + identName; -} - -/** - * Extracts super class information from a class node. - * - * Information includes name of the super class and/or the expression string - * (if extending from an expression) - * - * @param {object} node - * @param {object} state - * @return {object} - */ -function _getSuperClassInfo(node, state) { - var ret = { - name: null, - expression: null - }; - if (node.superClass) { - if (node.superClass.type === Syntax.Identifier) { - ret.name = node.superClass.name; - } else { - // Extension from an expression - ret.name = _generateAnonymousClassName(state); - ret.expression = state.g.source.substring( - node.superClass.range[0], - node.superClass.range[1] - ); - } - } - return ret; -} - -/** - * Used with .filter() to find the constructor method in a list of - * MethodDefinition nodes. - * - * @param {object} classElement - * @return {boolean} - */ -function _isConstructorMethod(classElement) { - return classElement.type === Syntax.MethodDefinition && - classElement.key.type === Syntax.Identifier && - classElement.key.name === 'constructor'; -} - -/** - * @param {object} node - * @param {object} state - * @return {boolean} - */ -function _shouldMungeIdentifier(node, state) { - return ( - !!state.methodFuncNode && - !utils.getDocblock(state).hasOwnProperty('preventMunge') && - /^_(?!_)/.test(node.name) - ); -} - -/** - * @param {function} traverse - * @param {object} node - * @param {array} path - * @param {object} state - */ -function visitClassMethod(traverse, node, path, state) { - if (node.kind === 'get' || node.kind === 'set') { - throw new Error( - 'This transform does not support ' + node.kind + 'ter methods for ES6 ' + - 'classes. (line: ' + node.loc.start.line + ', col: ' + - node.loc.start.column + ')' - ); - } - state = utils.updateState(state, { - methodNode: node - }); - utils.catchup(node.range[0], state); - path.unshift(node); - traverse(node.value, path, state); - path.shift(); - return false; -} -visitClassMethod.test = function(node, path, state) { - return node.type === Syntax.MethodDefinition; -}; - -/** - * @param {function} traverse - * @param {object} node - * @param {array} path - * @param {object} state - */ -function visitClassFunctionExpression(traverse, node, path, state) { - var methodNode = path[0]; - - state = utils.updateState(state, { - methodFuncNode: node - }); - - if (methodNode.key.name === 'constructor') { - utils.append('function ' + state.className, state); - } else { - var methodAccessor; - var prototypeOrStatic = methodNode["static"] ? '' : '.prototype'; - - if (methodNode.key.type === Syntax.Identifier) { - // foo() {} - methodAccessor = methodNode.key.name; - if (_shouldMungeIdentifier(methodNode.key, state)) { - methodAccessor = _getMungedName(methodAccessor, state); - } - methodAccessor = '.' + methodAccessor; - } else if (methodNode.key.type === Syntax.Literal) { - // 'foo bar'() {} - methodAccessor = '[' + JSON.stringify(methodNode.key.value) + ']'; - } - - utils.append( - state.className + prototypeOrStatic + - methodAccessor + '=function', - state - ); - } - utils.move(methodNode.key.range[1], state); - utils.append('(', state); - - var params = node.params; - if (params.length > 0) { - utils.move(params[0].range[0], state); - for (var i = 0; i < params.length; i++) { - utils.catchup(node.params[i].range[0], state); - path.unshift(node); - traverse(params[i], path, state); - path.shift(); - } - } - utils.append(')', state); - utils.catchupWhiteSpace(node.body.range[0], state); - utils.append('{', state); - if (!state.scopeIsStrict) { - utils.append('"use strict";', state); - state = utils.updateState(state, { - scopeIsStrict: true - }); - } - utils.move(node.body.range[0] + '{'.length, state); - - path.unshift(node); - traverse(node.body, path, state); - path.shift(); - utils.catchup(node.body.range[1], state); - - if (methodNode.key.name !== 'constructor') { - utils.append(';', state); - } - return false; -} -visitClassFunctionExpression.test = function(node, path, state) { - return node.type === Syntax.FunctionExpression - && path[0].type === Syntax.MethodDefinition; -}; - -function visitClassMethodParam(traverse, node, path, state) { - var paramName = node.name; - if (_shouldMungeIdentifier(node, state)) { - paramName = _getMungedName(node.name, state); - } - utils.append(paramName, state); - utils.move(node.range[1], state); -} -visitClassMethodParam.test = function(node, path, state) { - if (!path[0] || !path[1]) { - return; - } - - var parentFuncExpr = path[0]; - var parentClassMethod = path[1]; - - return parentFuncExpr.type === Syntax.FunctionExpression - && parentClassMethod.type === Syntax.MethodDefinition - && node.type === Syntax.Identifier; -}; - -/** - * @param {function} traverse - * @param {object} node - * @param {array} path - * @param {object} state - */ -function _renderClassBody(traverse, node, path, state) { - var className = state.className; - var superClass = state.superClass; - - // Set up prototype of constructor on same line as `extends` for line-number - // preservation. This relies on function-hoisting if a constructor function is - // defined in the class body. - if (superClass.name) { - // If the super class is an expression, we need to memoize the output of the - // expression into the generated class name variable and use that to refer - // to the super class going forward. Example: - // - // class Foo extends mixin(Bar, Baz) {} - // --transforms to-- - // function Foo() {} var ____Class0Blah = mixin(Bar, Baz); - if (superClass.expression !== null) { - utils.append( - 'var ' + superClass.name + '=' + superClass.expression + ';', - state - ); - } - - var keyName = superClass.name + '____Key'; - var keyNameDeclarator = ''; - if (!utils.identWithinLexicalScope(keyName, state)) { - keyNameDeclarator = 'var '; - declareIdentInLocalScope(keyName, initScopeMetadata(node), state); - } - utils.append( - 'for(' + keyNameDeclarator + keyName + ' in ' + superClass.name + '){' + - 'if(' + superClass.name + '.hasOwnProperty(' + keyName + ')){' + - className + '[' + keyName + ']=' + - superClass.name + '[' + keyName + '];' + - '}' + - '}', - state - ); - - var superProtoIdentStr = SUPER_PROTO_IDENT_PREFIX + superClass.name; - if (!utils.identWithinLexicalScope(superProtoIdentStr, state)) { - utils.append( - 'var ' + superProtoIdentStr + '=' + superClass.name + '===null?' + - 'null:' + superClass.name + '.prototype;', - state - ); - declareIdentInLocalScope(superProtoIdentStr, initScopeMetadata(node), state); - } - - utils.append( - className + '.prototype=Object.create(' + superProtoIdentStr + ');', - state - ); - utils.append( - className + '.prototype.constructor=' + className + ';', - state - ); - utils.append( - className + '.__superConstructor__=' + superClass.name + ';', - state - ); - } - - // If there's no constructor method specified in the class body, create an - // empty constructor function at the top (same line as the class keyword) - if (!node.body.body.filter(_isConstructorMethod).pop()) { - utils.append('function ' + className + '(){', state); - if (!state.scopeIsStrict) { - utils.append('"use strict";', state); - } - if (superClass.name) { - utils.append( - 'if(' + superClass.name + '!==null){' + - superClass.name + '.apply(this,arguments);}', - state - ); - } - utils.append('}', state); - } - - utils.move(node.body.range[0] + '{'.length, state); - traverse(node.body, path, state); - utils.catchupWhiteSpace(node.range[1], state); -} - -/** - * @param {function} traverse - * @param {object} node - * @param {array} path - * @param {object} state - */ -function visitClassDeclaration(traverse, node, path, state) { - var className = node.id.name; - var superClass = _getSuperClassInfo(node, state); - - state = utils.updateState(state, { - mungeNamespace: className, - className: className, - superClass: superClass - }); - - _renderClassBody(traverse, node, path, state); - - return false; -} -visitClassDeclaration.test = function(node, path, state) { - return node.type === Syntax.ClassDeclaration; -}; - -/** - * @param {function} traverse - * @param {object} node - * @param {array} path - * @param {object} state - */ -function visitClassExpression(traverse, node, path, state) { - var className = node.id && node.id.name || _generateAnonymousClassName(state); - var superClass = _getSuperClassInfo(node, state); - - utils.append('(function(){', state); - - state = utils.updateState(state, { - mungeNamespace: className, - className: className, - superClass: superClass - }); - - _renderClassBody(traverse, node, path, state); - - utils.append('return ' + className + ';})()', state); - return false; -} -visitClassExpression.test = function(node, path, state) { - return node.type === Syntax.ClassExpression; -}; - -/** - * @param {function} traverse - * @param {object} node - * @param {array} path - * @param {object} state - */ -function visitPrivateIdentifier(traverse, node, path, state) { - utils.append(_getMungedName(node.name, state), state); - utils.move(node.range[1], state); -} -visitPrivateIdentifier.test = function(node, path, state) { - if (node.type === Syntax.Identifier && _shouldMungeIdentifier(node, state)) { - // Always munge non-computed properties of MemberExpressions - // (a la preventing access of properties of unowned objects) - if (path[0].type === Syntax.MemberExpression && path[0].object !== node - && path[0].computed === false) { - return true; - } - - // Always munge identifiers that were declared within the method function - // scope - if (utils.identWithinLexicalScope(node.name, state, state.methodFuncNode)) { - return true; - } - - // Always munge private keys on object literals defined within a method's - // scope. - if (path[0].type === Syntax.Property - && path[1].type === Syntax.ObjectExpression) { - return true; - } - - // Always munge function parameters - if (path[0].type === Syntax.FunctionExpression - || path[0].type === Syntax.FunctionDeclaration - || path[0].type === Syntax.ArrowFunctionExpression) { - for (var i = 0; i < path[0].params.length; i++) { - if (path[0].params[i] === node) { - return true; - } - } - } - } - return false; -}; - -/** - * @param {function} traverse - * @param {object} node - * @param {array} path - * @param {object} state - */ -function visitSuperCallExpression(traverse, node, path, state) { - var superClassName = state.superClass.name; - - if (node.callee.type === Syntax.Identifier) { - if (_isConstructorMethod(state.methodNode)) { - utils.append(superClassName + '.call(', state); - } else { - var protoProp = SUPER_PROTO_IDENT_PREFIX + superClassName; - if (state.methodNode.key.type === Syntax.Identifier) { - protoProp += '.' + state.methodNode.key.name; - } else if (state.methodNode.key.type === Syntax.Literal) { - protoProp += '[' + JSON.stringify(state.methodNode.key.value) + ']'; - } - utils.append(protoProp + ".call(", state); - } - utils.move(node.callee.range[1], state); - } else if (node.callee.type === Syntax.MemberExpression) { - utils.append(SUPER_PROTO_IDENT_PREFIX + superClassName, state); - utils.move(node.callee.object.range[1], state); - - if (node.callee.computed) { - // ["a" + "b"] - utils.catchup(node.callee.property.range[1] + ']'.length, state); - } else { - // .ab - utils.append('.' + node.callee.property.name, state); - } - - utils.append('.call(', state); - utils.move(node.callee.range[1], state); - } - - utils.append('this', state); - if (node.arguments.length > 0) { - utils.append(',', state); - utils.catchupWhiteSpace(node.arguments[0].range[0], state); - traverse(node.arguments, path, state); - } - - utils.catchupWhiteSpace(node.range[1], state); - utils.append(')', state); - return false; -} -visitSuperCallExpression.test = function(node, path, state) { - if (state.superClass && node.type === Syntax.CallExpression) { - var callee = node.callee; - if (callee.type === Syntax.Identifier && callee.name === 'super' - || callee.type == Syntax.MemberExpression - && callee.object.name === 'super') { - return true; - } - } - return false; -}; - -/** - * @param {function} traverse - * @param {object} node - * @param {array} path - * @param {object} state - */ -function visitSuperMemberExpression(traverse, node, path, state) { - var superClassName = state.superClass.name; - - utils.append(SUPER_PROTO_IDENT_PREFIX + superClassName, state); - utils.move(node.object.range[1], state); -} -visitSuperMemberExpression.test = function(node, path, state) { - return state.superClass - && node.type === Syntax.MemberExpression - && node.object.type === Syntax.Identifier - && node.object.name === 'super'; -}; - -exports.resetSymbols = resetSymbols; - -exports.visitorList = [ - visitClassDeclaration, - visitClassExpression, - visitClassFunctionExpression, - visitClassMethod, - visitClassMethodParam, - visitPrivateIdentifier, - visitSuperCallExpression, - visitSuperMemberExpression -]; - -},{"../src/utils":20,"base62":7,"esprima-fb":6}],23:[function(_dereq_,module,exports){ -/** - * Copyright 2014 Facebook, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/*global exports:true*/ - -/** - * Implements ES6 destructuring assignment and pattern matchng. - * - * function init({port, ip, coords: [x, y]}) { - * return (x && y) ? {id, port} : {ip}; - * }; - * - * function init($__0) { - * var - * port = $__0.port, - * ip = $__0.ip, - * $__1 = $__0.coords, - * x = $__1[0], - * y = $__1[1]; - * return (x && y) ? {id, port} : {ip}; - * } - * - * var x, {ip, port} = init({ip, port}); - * - * var x, $__0 = init({ip, port}), ip = $__0.ip, port = $__0.port; - * - */ -var Syntax = _dereq_('esprima-fb').Syntax; -var utils = _dereq_('../src/utils'); - -var restParamVisitors = _dereq_('./es6-rest-param-visitors'); - -// ------------------------------------------------------- -// 1. Structured variable declarations. -// -// var [a, b] = [b, a]; -// var {x, y} = {y, x}; -// ------------------------------------------------------- - -function visitStructuredVariable(traverse, node, path, state) { - // Allocate new temp for the pattern. - utils.append(getTmpVar(state.localScope.tempVarIndex) + '=', state); - // Skip the pattern and assign the init to the temp. - utils.catchupWhiteSpace(node.init.range[0], state); - traverse(node.init, path, state); - utils.catchup(node.init.range[1], state); - // Render the destructured data. - utils.append(',' + getDestructuredComponents(node.id, state), state); - state.localScope.tempVarIndex++; - return false; -} - -visitStructuredVariable.test = function(node, path, state) { - return node.type === Syntax.VariableDeclarator && - isStructuredPattern(node.id); -}; - -function isStructuredPattern(node) { - return node.type === Syntax.ObjectPattern || - node.type === Syntax.ArrayPattern; -} - -// Main function which does actual recursive destructuring -// of nested complex structures. -function getDestructuredComponents(node, state) { - var tmpIndex = state.localScope.tempVarIndex; - var components = []; - var patternItems = getPatternItems(node); - - for (var idx = 0; idx < patternItems.length; idx++) { - var item = patternItems[idx]; - if (!item) { - continue; - } - - // Depending on pattern type (Array or Object), we get - // corresponding pattern item parts. - var accessor = getPatternItemAccessor(node, item, tmpIndex, idx); - var value = getPatternItemValue(node, item); - - // TODO(dmitrys): implement default values: {x, y=5} - if (value.type === Syntax.Identifier) { - // Simple pattern item. - components.push(value.name + '=' + accessor); - } else if (value.type === Syntax.SpreadElement) { - // Spread/rest of an array. - // TODO(dmitrys): support spread in the middle of a pattern - // and also for function param patterns: [x, ...xs, y] - components.push(value.argument.name + - '=Array.prototype.slice.call(' + - getTmpVar(tmpIndex) + ',' + idx + ')' - ); - } else { - // Complex sub-structure. - components.push( - getInitialValue(++state.localScope.tempVarIndex, accessor) + ',' + - getDestructuredComponents(value, state) - ); - } - } - - return components.join(','); -} - -function getPatternItems(node) { - return node.properties || node.elements; -} - -function getPatternItemAccessor(node, patternItem, tmpIndex, idx) { - var tmpName = getTmpVar(tmpIndex); - return node.type === Syntax.ObjectPattern - ? tmpName + '.' + patternItem.key.name - : tmpName + '[' + idx + ']'; -} - -function getPatternItemValue(node, patternItem) { - return node.type === Syntax.ObjectPattern - ? patternItem.value - : patternItem; -} - -function getInitialValue(index, value) { - return getTmpVar(index) + '=' + value; -} - -function getTmpVar(index) { - return '$__' + index; -} - -// ------------------------------------------------------- -// 2. Assignment expression. -// -// [a, b] = [b, a]; -// ({x, y} = {y, x}); -// ------------------------------------------------------- - -function visitStructuredAssignment(traverse, node, path, state) { - var exprNode = node.expression; - utils.append('var ' + getTmpVar(state.localScope.tempVarIndex) + '=', state); - - utils.catchupWhiteSpace(exprNode.right.range[0], state); - traverse(exprNode.right, path, state); - utils.catchup(exprNode.right.range[1], state); - - utils.append( - ',' + getDestructuredComponents(exprNode.left, state) + ';', - state - ); - - utils.catchupWhiteSpace(node.range[1], state); - state.localScope.tempVarIndex++; - return false; -} - -visitStructuredAssignment.test = function(node, path, state) { - // We consider the expression statement rather than just assignment - // expression to cover case with object patters which should be - // wrapped in grouping operator: ({x, y} = {y, x}); - return node.type === Syntax.ExpressionStatement && - node.expression.type === Syntax.AssignmentExpression && - isStructuredPattern(node.expression.left); -}; - -// ------------------------------------------------------- -// 3. Structured parameter. -// -// function foo({x, y}) { ... } -// ------------------------------------------------------- - -function visitStructuredParameter(traverse, node, path, state) { - utils.append(getTmpVar(getParamIndex(node, path)), state); - utils.catchupWhiteSpace(node.range[1], state); - return true; -} - -function getParamIndex(paramNode, path) { - var funcNode = path[0]; - var tmpIndex = 0; - for (var k = 0; k < funcNode.params.length; k++) { - var param = funcNode.params[k]; - if (param === paramNode) { - break; - } - if (isStructuredPattern(param)) { - tmpIndex++; - } - } - return tmpIndex; -} - -visitStructuredParameter.test = function(node, path, state) { - return isStructuredPattern(node) && isFunctionNode(path[0]); -}; - -function isFunctionNode(node) { - return (node.type == Syntax.FunctionDeclaration || - node.type == Syntax.FunctionExpression || - node.type == Syntax.MethodDefinition || - node.type == Syntax.ArrowFunctionExpression); -} - -// ------------------------------------------------------- -// 4. Function body for structured parameters. -// -// function foo({x, y}) { x; y; } -// ------------------------------------------------------- - -function visitFunctionBodyForStructuredParameter(traverse, node, path, state) { - var funcNode = path[0]; - - utils.catchup(funcNode.body.range[0] + 1, state); - renderDestructuredComponents(funcNode, state); - - if (funcNode.rest) { - utils.append( - restParamVisitors.renderRestParamSetup(funcNode), - state - ); - } - - return true; -} - -function renderDestructuredComponents(funcNode, state) { - var destructuredComponents = []; - - for (var k = 0; k < funcNode.params.length; k++) { - var param = funcNode.params[k]; - if (isStructuredPattern(param)) { - destructuredComponents.push( - getDestructuredComponents(param, state) - ); - state.localScope.tempVarIndex++; - } - } - - if (destructuredComponents.length) { - utils.append('var ' + destructuredComponents.join(',') + ';', state); - } -} - -visitFunctionBodyForStructuredParameter.test = function(node, path, state) { - return node.type === Syntax.BlockStatement && isFunctionNode(path[0]); -}; - -exports.visitorList = [ - visitStructuredVariable, - visitStructuredAssignment, - visitStructuredParameter, - visitFunctionBodyForStructuredParameter -]; - -exports.renderDestructuredComponents = renderDestructuredComponents; - - -},{"../src/utils":20,"./es6-rest-param-visitors":26,"esprima-fb":6}],24:[function(_dereq_,module,exports){ -/** - * Copyright 2013 Facebook, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*jslint node:true*/ - -/** - * Desugars concise methods of objects to ES3 function expressions. - * - * var foo = { - * method(x, y) { ... } - * }; - * - * var foo = { - * method: function(x, y) { ... } - * }; - * - */ - -var Syntax = _dereq_('esprima-fb').Syntax; -var utils = _dereq_('../src/utils'); - -function visitObjectConciseMethod(traverse, node, path, state) { - utils.catchup(node.key.range[1], state); - utils.append(':function', state); - path.unshift(node); - traverse(node.value, path, state); - path.shift(); - return false; -} - -visitObjectConciseMethod.test = function(node, path, state) { - return node.type === Syntax.Property && - node.value.type === Syntax.FunctionExpression && - node.method === true; -}; - -exports.visitorList = [ - visitObjectConciseMethod -]; - -},{"../src/utils":20,"esprima-fb":6}],25:[function(_dereq_,module,exports){ -/** - * Copyright 2013 Facebook, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*jslint node: true*/ - -/** - * Desugars ES6 Object Literal short notations into ES3 full notation. - * - * // Easier return values. - * function foo(x, y) { - * return {x, y}; // {x: x, y: y} - * }; - * - * // Destrucruting. - * function init({port, ip, coords: {x, y}}) { ... } - * - */ -var Syntax = _dereq_('esprima-fb').Syntax; -var utils = _dereq_('../src/utils'); - -/** - * @public - */ -function visitObjectLiteralShortNotation(traverse, node, path, state) { - utils.catchup(node.key.range[1], state); - utils.append(':' + node.key.name, state); - return false; -} - -visitObjectLiteralShortNotation.test = function(node, path, state) { - return node.type === Syntax.Property && - node.kind === 'init' && - node.shorthand === true && - path[0].type !== Syntax.ObjectPattern; -}; - -exports.visitorList = [ - visitObjectLiteralShortNotation -]; - - -},{"../src/utils":20,"esprima-fb":6}],26:[function(_dereq_,module,exports){ -/** - * Copyright 2013 Facebook, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*jslint node:true*/ - -/** - * Desugars ES6 rest parameters into ES3 arguments slicing. - * - * function printf(template, ...args) { - * args.forEach(...); - * }; - * - * function printf(template) { - * var args = [].slice.call(arguments, 1); - * args.forEach(...); - * }; - * - */ -var Syntax = _dereq_('esprima-fb').Syntax; -var utils = _dereq_('../src/utils'); - - - -function _nodeIsFunctionWithRestParam(node) { - return (node.type === Syntax.FunctionDeclaration - || node.type === Syntax.FunctionExpression - || node.type === Syntax.ArrowFunctionExpression) - && node.rest; -} - -function visitFunctionParamsWithRestParam(traverse, node, path, state) { - if (node.parametricType) { - utils.catchup(node.parametricType.range[0], state); - path.unshift(node); - traverse(node.parametricType, path, state); - path.shift(); - } - - // Render params. - if (node.params.length) { - path.unshift(node); - traverse(node.params, path, state); - path.shift(); - } else { - // -3 is for ... of the rest. - utils.catchup(node.rest.range[0] - 3, state); - } - utils.catchupWhiteSpace(node.rest.range[1], state); - - path.unshift(node); - traverse(node.body, path, state); - path.shift(); - - return false; -} - -visitFunctionParamsWithRestParam.test = function(node, path, state) { - return _nodeIsFunctionWithRestParam(node); -}; - -function renderRestParamSetup(functionNode) { - return 'var ' + functionNode.rest.name + '=Array.prototype.slice.call(' + - 'arguments,' + - functionNode.params.length + - ');'; -} - -function visitFunctionBodyWithRestParam(traverse, node, path, state) { - utils.catchup(node.range[0] + 1, state); - var parentNode = path[0]; - utils.append(renderRestParamSetup(parentNode), state); - return true; -} - -visitFunctionBodyWithRestParam.test = function(node, path, state) { - return node.type === Syntax.BlockStatement - && _nodeIsFunctionWithRestParam(path[0]); -}; - -exports.renderRestParamSetup = renderRestParamSetup; -exports.visitorList = [ - visitFunctionParamsWithRestParam, - visitFunctionBodyWithRestParam -]; - -},{"../src/utils":20,"esprima-fb":6}],27:[function(_dereq_,module,exports){ -/** - * Copyright 2013 Facebook, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/*jslint node:true*/ - -/** - * @typechecks - */ -'use strict'; - -var Syntax = _dereq_('esprima-fb').Syntax; -var utils = _dereq_('../src/utils'); - -/** - * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-12.1.9 - */ -function visitTemplateLiteral(traverse, node, path, state) { - var templateElements = node.quasis; - - utils.append('(', state); - for (var ii = 0; ii < templateElements.length; ii++) { - var templateElement = templateElements[ii]; - if (templateElement.value.raw !== '') { - utils.append(getCookedValue(templateElement), state); - if (!templateElement.tail) { - // + between element and substitution - utils.append(' + ', state); - } - // maintain line numbers - utils.move(templateElement.range[0], state); - utils.catchupNewlines(templateElement.range[1], state); - } else { // templateElement.value.raw === '' - // Concatenat adjacent substitutions, e.g. `${x}${y}`. Empty templates - // appear before the first and after the last element - nothing to add in - // those cases. - if (ii > 0 && !templateElement.tail) { - // + between substitution and substitution - utils.append(' + ', state); - } - } - - utils.move(templateElement.range[1], state); - if (!templateElement.tail) { - var substitution = node.expressions[ii]; - if (substitution.type === Syntax.Identifier || - substitution.type === Syntax.MemberExpression || - substitution.type === Syntax.CallExpression) { - utils.catchup(substitution.range[1], state); - } else { - utils.append('(', state); - traverse(substitution, path, state); - utils.catchup(substitution.range[1], state); - utils.append(')', state); - } - // if next templateElement isn't empty... - if (templateElements[ii + 1].value.cooked !== '') { - utils.append(' + ', state); - } - } - } - utils.move(node.range[1], state); - utils.append(')', state); - return false; -} - -visitTemplateLiteral.test = function(node, path, state) { - return node.type === Syntax.TemplateLiteral; -}; - -/** - * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-12.2.6 - */ -function visitTaggedTemplateExpression(traverse, node, path, state) { - var template = node.quasi; - var numQuasis = template.quasis.length; - - // print the tag - utils.move(node.tag.range[0], state); - traverse(node.tag, path, state); - utils.catchup(node.tag.range[1], state); - - // print array of template elements - utils.append('(function() { var siteObj = [', state); - for (var ii = 0; ii < numQuasis; ii++) { - utils.append(getCookedValue(template.quasis[ii]), state); - if (ii !== numQuasis - 1) { - utils.append(', ', state); - } - } - utils.append(']; siteObj.raw = [', state); - for (ii = 0; ii < numQuasis; ii++) { - utils.append(getRawValue(template.quasis[ii]), state); - if (ii !== numQuasis - 1) { - utils.append(', ', state); - } - } - utils.append( - ']; Object.freeze(siteObj.raw); Object.freeze(siteObj); return siteObj; }()', - state - ); - - // print substitutions - if (numQuasis > 1) { - for (ii = 0; ii < template.expressions.length; ii++) { - var expression = template.expressions[ii]; - utils.append(', ', state); - - // maintain line numbers by calling catchupWhiteSpace over the whole - // previous TemplateElement - utils.move(template.quasis[ii].range[0], state); - utils.catchupNewlines(template.quasis[ii].range[1], state); - - utils.move(expression.range[0], state); - traverse(expression, path, state); - utils.catchup(expression.range[1], state); - } - } - - // print blank lines to push the closing ) down to account for the final - // TemplateElement. - utils.catchupNewlines(node.range[1], state); - - utils.append(')', state); - - return false; -} - -visitTaggedTemplateExpression.test = function(node, path, state) { - return node.type === Syntax.TaggedTemplateExpression; -}; - -function getCookedValue(templateElement) { - return JSON.stringify(templateElement.value.cooked); -} - -function getRawValue(templateElement) { - return JSON.stringify(templateElement.value.raw); -} - -exports.visitorList = [ - visitTemplateLiteral, - visitTaggedTemplateExpression -]; - -},{"../src/utils":20,"esprima-fb":6}],28:[function(_dereq_,module,exports){ -/** - * Copyright 2013-2014 Facebook, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/* jshint browser: true */ -/* jslint evil: true */ - -'use strict'; - -var buffer = _dereq_('buffer'); -var docblock = _dereq_('jstransform/src/docblock'); -var transform = _dereq_('jstransform').transform; -var visitors = _dereq_('./fbtransform/visitors'); - -var headEl; -var dummyAnchor; -var inlineScriptCount = 0; - -// The source-map library relies on Object.defineProperty, but IE8 doesn't -// support it fully even with es5-sham. Indeed, es5-sham's defineProperty -// throws when Object.prototype.__defineGetter__ is missing, so we skip building -// the source map in that case. -var supportsAccessors = Object.prototype.hasOwnProperty('__defineGetter__'); - -/** - * Run provided code through jstransform. - * - * @param {string} source Original source code - * @param {object?} options Options to pass to jstransform - * @return {object} object as returned from jstransform - */ -function transformReact(source, options) { - // TODO: just use react-tools - var visitorList; - if (options && options.harmony) { - visitorList = visitors.getAllVisitors(); - } else { - visitorList = visitors.transformVisitors.react; - } - - return transform(visitorList, source, { - sourceMap: supportsAccessors - }); -} - -/** - * Eval provided source after transforming it. - * - * @param {string} source Original source code - * @param {object?} options Options to pass to jstransform - */ -function exec(source, options) { - return eval(transformReact(source, options).code); -} - -/** - * This method returns a nicely formated line of code pointing to the exact - * location of the error `e`. The line is limited in size so big lines of code - * are also shown in a readable way. - * - * Example: - * ... x', overflow:'scroll'}} id={} onScroll={this.scroll} class=" ... - * ^ - * - * @param {string} code The full string of code - * @param {Error} e The error being thrown - * @return {string} formatted message - * @internal - */ -function createSourceCodeErrorMessage(code, e) { - var sourceLines = code.split('\n'); - var erroneousLine = sourceLines[e.lineNumber - 1]; - - // Removes any leading indenting spaces and gets the number of - // chars indenting the `erroneousLine` - var indentation = 0; - erroneousLine = erroneousLine.replace(/^\s+/, function(leadingSpaces) { - indentation = leadingSpaces.length; - return ''; - }); - - // Defines the number of characters that are going to show - // before and after the erroneous code - var LIMIT = 30; - var errorColumn = e.column - indentation; - - if (errorColumn > LIMIT) { - erroneousLine = '... ' + erroneousLine.slice(errorColumn - LIMIT); - errorColumn = 4 + LIMIT; - } - if (erroneousLine.length - errorColumn > LIMIT) { - erroneousLine = erroneousLine.slice(0, errorColumn + LIMIT) + ' ...'; - } - var message = '\n\n' + erroneousLine + '\n'; - message += new Array(errorColumn - 1).join(' ') + '^'; - return message; -} - -/** - * Actually transform the code. - * - * @param {string} code - * @param {string?} url - * @param {object?} options - * @return {string} The transformed code. - * @internal - */ -function transformCode(code, url, options) { - var jsx = docblock.parseAsObject(docblock.extract(code)).jsx; - - if (jsx) { - try { - var transformed = transformReact(code, options); - } catch(e) { - e.message += '\n at '; - if (url) { - if ('fileName' in e) { - // We set `fileName` if it's supported by this error object and - // a `url` was provided. - // The error will correctly point to `url` in Firefox. - e.fileName = url; - } - e.message += url + ':' + e.lineNumber + ':' + e.column; - } else { - e.message += location.href; - } - e.message += createSourceCodeErrorMessage(code, e); - throw e; - } - - if (!transformed.sourceMap) { - return transformed.code; - } - - var map = transformed.sourceMap.toJSON(); - var source; - if (url == null) { - source = "Inline JSX script"; - inlineScriptCount++; - if (inlineScriptCount > 1) { - source += ' (' + inlineScriptCount + ')'; - } - } else if (dummyAnchor) { - // Firefox has problems when the sourcemap source is a proper URL with a - // protocol and hostname, so use the pathname. We could use just the - // filename, but hopefully using the full path will prevent potential - // issues where the same filename exists in multiple directories. - dummyAnchor.href = url; - source = dummyAnchor.pathname.substr(1); - } - map.sources = [source]; - map.sourcesContent = [code]; - - return ( - transformed.code + - '\n//# sourceMappingURL=data:application/json;base64,' + - buffer.Buffer(JSON.stringify(map)).toString('base64') - ); - } else { - // TODO: warn that we found a script tag missing the docblock? - // or warn and proceed anyway? - // or warn, add it ourselves, and proceed anyway? - return code; - } -} - - -/** - * Appends a script element at the end of the with the content of code, - * after transforming it. - * - * @param {string} code The original source code - * @param {string?} url Where the code came from. null if inline - * @param {object?} options Options to pass to jstransform - * @internal - */ -function run(code, url, options) { - var scriptEl = document.createElement('script'); - scriptEl.text = transformCode(code, url, options); - headEl.appendChild(scriptEl); -} - -/** - * Load script from the provided url and pass the content to the callback. - * - * @param {string} url The location of the script src - * @param {function} callback Function to call with the content of url - * @internal - */ -function load(url, callback) { - var xhr; - xhr = window.ActiveXObject ? new window.ActiveXObject('Microsoft.XMLHTTP') - : new XMLHttpRequest(); - - // async, however scripts will be executed in the order they are in the - // DOM to mirror normal script loading. - xhr.open('GET', url, true); - if ('overrideMimeType' in xhr) { - xhr.overrideMimeType('text/plain'); - } - xhr.onreadystatechange = function() { - if (xhr.readyState === 4) { - if (xhr.status === 0 || xhr.status === 200) { - callback(xhr.responseText, url); - } else { - throw new Error("Could not load " + url); - } - } - }; - return xhr.send(null); -} - -/** - * Loop over provided script tags and get the content, via innerHTML if an - * inline script, or by using XHR. Transforms are applied if needed. The scripts - * are executed in the order they are found on the page. - * - * @param {array} scripts The ", + result.ToString() + ); + } + + [Fact] + public void GetInitJavaScriptReturns() + { + var component = new Mock(); + + var environment = ConfigureMockEnvironment(); + + environment.Setup(x => x.GetInitJavaScript(It.IsAny(), It.IsAny())).Callback((TextWriter writer, bool clientOnly) => writer.Write("JS")); + + var renderJSResult = HtmlHelperExtensions.ReactInitJavaScript(htmlHelper: null, clientOnly: false); + + Assert.Equal( + "", + renderJSResult.ToString() + ); + } + + [Fact] + public void ScriptNonceIsReturned() + { + string nonce; + using (var random = new RNGCryptoServiceProvider()) + { + byte[] nonceBytes = new byte[16]; + random.GetBytes(nonceBytes); + nonce = Convert.ToBase64String(nonceBytes); + } + + var component = new Mock(); + component.Setup(x => x.RenderHtml(It.IsAny(), false, false, null, null)) + .Callback((TextWriter writer, bool renderContainerOnly, bool renderServerOnly, Action exceptionHandle, IRenderFunctions renderFunctions) => writer.Write("HTML")).Verifiable(); + + component.Setup(x => x.RenderJavaScript(It.IsAny(), It.IsAny())).Callback((TextWriter writer, bool waitForDOMContentLoad) => writer.Write(waitForDOMContentLoad ? "waiting for page load JS" : "JS")).Verifiable(); + + var config = new Mock(); + + var environment = ConfigureMockEnvironment(config.Object); + + environment.Setup(x => x.Configuration).Returns(config.Object); + environment.Setup(x => x.CreateComponent( + "ComponentName", + new { }, + null, + false, + false, + false + )).Returns(component.Object); + + // without nonce + var result = HtmlHelperExtensions.ReactWithInit( + htmlHelper: null, + componentName: "ComponentName", + props: new { }, + htmlTag: "span" + ).ToHtmlString(); + + Assert.Equal( + "HTML" + System.Environment.NewLine + "", + result.ToString() + ); + + config.Setup(x => x.ScriptNonceProvider).Returns(() => nonce); + + // with nonce + result = HtmlHelperExtensions.ReactWithInit( + htmlHelper: null, + componentName: "ComponentName", + props: new { }, + htmlTag: "span" + ).ToHtmlString(); + + Assert.Equal( + "HTML" + System.Environment.NewLine + "", + result.ToString() + ); + } + + [Fact] + public void EngineIsReturnedToPoolAfterRender() + { + var component = new Mock(); + component.Setup(x => x.RenderHtml(It.IsAny(), false, false, null, null)) + .Callback((TextWriter writer, bool renderContainerOnly, bool renderServerOnly, Action exceptionHandler, IRenderFunctions renderFunctions) => writer.Write("HTML")).Verifiable(); + + var environment = ConfigureMockEnvironment(); + environment.Setup(x => x.CreateComponent( + "ComponentName", + new { }, + null, + true, + false, + false + )).Returns(component.Object); + + environment.Verify(x => x.ReturnEngineToPool(), Times.Never); + var result = HtmlHelperExtensions.React( + htmlHelper: null, + componentName: "ComponentName", + props: new { }, + htmlTag: "span", + clientOnly: true, + serverOnly: false + ).ToHtmlString(); + + component.Verify(x => x.RenderHtml(It.IsAny(), It.Is(y => y == true), It.Is(z => z == false), null, null), Times.Once); + environment.Verify(x => x.ReturnEngineToPool(), Times.Once); + } + + [Fact] + public void ReactWithClientOnlyTrueShouldCallRenderHtmlWithTrue() + { + var component = new Mock(); + component.Setup(x => x.RenderHtml(It.IsAny(), false, false, null, null)) + .Callback((TextWriter writer, bool renderContainerOnly, bool renderServerOnly, Action exceptionHandler, IRenderFunctions renderFunctions) => writer.Write("HTML")).Verifiable(); + + var environment = ConfigureMockEnvironment(); + environment.Setup(x => x.CreateComponent( + "ComponentName", + new { }, + null, + true, + false, + false + )).Returns(component.Object); + + var result = HtmlHelperExtensions.React( + htmlHelper: null, + componentName: "ComponentName", + props: new { }, + htmlTag: "span", + clientOnly: true, + serverOnly: false + ).ToHtmlString(); + + component.Verify(x => x.RenderHtml(It.IsAny(), It.Is(y => y == true), It.Is(z => z == false), null, null), Times.Once); + } + + [Fact] + public void ReactWithServerOnlyTrueShouldCallRenderHtmlWithTrue() + { + var component = new Mock(); + component.Setup(x => x.RenderHtml(It.IsAny(), false, false, null, null)) + .Callback((TextWriter writer, bool renderContainerOnly, bool renderServerOnly, Action exceptionHandler, IRenderFunctions renderFunctions) => writer.Write("HTML")).Verifiable(); + + var environment = ConfigureMockEnvironment(); + environment.Setup(x => x.CreateComponent( + "ComponentName", + new { }, + null, + false, + true, + false + )).Returns(component.Object); + + var result = HtmlHelperExtensions.React( + htmlHelper: null, + componentName: "ComponentName", + props: new { }, + htmlTag: "span", + clientOnly: false, + serverOnly: true + ).ToHtmlString(); + + component.Verify(x => x.RenderHtml(It.IsAny(), It.Is(y => y == false), It.Is(z => z == true), null, null), Times.Once); + } + + [Fact] + public void RenderFunctionsCalledNonLazily() + { + var component = new Mock(); + var fakeRenderFunctions = new Mock(); + fakeRenderFunctions.Setup(x => x.PreRender(It.IsAny>())).Verifiable(); + fakeRenderFunctions.Setup(x => x.PostRender(It.IsAny>())).Verifiable(); + fakeRenderFunctions.Setup(x => x.TransformRenderedHtml(It.IsAny())).Returns("HTML"); + + component.Setup(x => x.RenderHtml(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny>(), It.IsAny())) + .Callback((TextWriter writer, bool renderContainerOnly, bool renderServerOnly, Action exceptionHandler, IRenderFunctions renderFunctions) => + { + renderFunctions.PreRender(_ => "one"); + writer.Write(renderFunctions.TransformRenderedHtml("HTML")); + renderFunctions.PostRender(_ => "two"); + }).Verifiable(); + + var environment = ConfigureMockEnvironment(); + environment.Setup(x => x.CreateComponent( + "ComponentName", + new { }, + null, + false, + true, + false + )).Returns(component.Object); + + var result = HtmlHelperExtensions.React( + htmlHelper: null, + componentName: "ComponentName", + props: new { }, + htmlTag: "span", + clientOnly: false, + serverOnly: true, + renderFunctions: fakeRenderFunctions.Object + ); + + // JS calls must happen right away so thrown exceptions do not crash the app. + component.Verify(x => x.RenderHtml(It.IsAny(), It.Is(y => y == false), It.Is(z => z == true), It.IsAny>(), It.IsAny()), Times.Once); + fakeRenderFunctions.Verify(x => x.PreRender(It.IsAny>()), Times.Once); + fakeRenderFunctions.Verify(x => x.PostRender(It.IsAny>()), Times.Once); + + Assert.Equal("HTML", result.ToHtmlString()); + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public void ReactGetScriptPaths(bool withNonce) + { + var config = new Mock(); + var environment = ConfigureMockEnvironment(config.Object); + + if (withNonce) + { + config.Setup(x => x.ScriptNonceProvider).Returns(() => "test1234"); + } + + environment.Setup(x => x.GetScriptPaths()).Returns(new[] { "/dist/vendor.js", "/dist/app.js" }); + + var result = HtmlHelperExtensions.ReactGetScriptPaths(null); + + if (withNonce) + { + Assert.Equal("", result.ToHtmlString()); + } + else + { + Assert.Equal("", result.ToHtmlString()); + } + } + + [Fact] + public void ReactGetStylePaths() + { + var environment = ConfigureMockEnvironment(); + + environment.Setup(x => x.GetStylePaths()).Returns(new[] { "/dist/vendor.css", "/dist/app.css" }); + + var result = HtmlHelperExtensions.ReactGetStylePaths(null); + + Assert.Equal("", result.ToHtmlString()); + } + } +} diff --git a/tests/React.Tests/Mvc/TestUtilities.cs b/tests/React.Tests/Mvc/TestUtilities.cs new file mode 100644 index 000000000..4cbd052a4 --- /dev/null +++ b/tests/React.Tests/Mvc/TestUtilities.cs @@ -0,0 +1,21 @@ +#if !NET452 +using System.IO; +using System.Text.Encodings.Web; +using Microsoft.AspNetCore.Html; + +namespace React.Tests.Mvc +{ + public static class TestUtilities + { + public static string ToHtmlString(this IHtmlContent source) + { + using (var writer = new StringWriter()) + { + source.WriteTo(writer, HtmlEncoder.Default); + return writer.ToString(); + } + } + } +} + +#endif diff --git a/tests/React.Tests/Owin/EntryAssemblyFileSystemTests.cs b/tests/React.Tests/Owin/EntryAssemblyFileSystemTests.cs new file mode 100644 index 000000000..7f5e6c3d2 --- /dev/null +++ b/tests/React.Tests/Owin/EntryAssemblyFileSystemTests.cs @@ -0,0 +1,27 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +#if NET452 + +using Xunit; +using React.Owin; + +namespace React.Tests.Owin +{ + public class EntryAssemblyFileSystemTests + { + [Theory] + [InlineData("C:\\", "~/", "C:\\")] + [InlineData("C:\\", "~/foo/bar.js", "C:\\foo\\bar.js")] + public void MapPath(string rootPath, string relativePath, string expected) + { + var fileSystem = new EntryAssemblyFileSystem(rootPath); + var result = fileSystem.MapPath(relativePath); + Assert.Equal(expected, result); + } + } +} +#endif diff --git a/src/React.Tests/Properties/AssemblyInfo.cs b/tests/React.Tests/Properties/AssemblyInfo.cs similarity index 52% rename from src/React.Tests/Properties/AssemblyInfo.cs rename to tests/React.Tests/Properties/AssemblyInfo.cs index 0019ea1b9..d7dc747f0 100644 --- a/src/React.Tests/Properties/AssemblyInfo.cs +++ b/tests/React.Tests/Properties/AssemblyInfo.cs @@ -1,7 +1,9 @@ -using System.Reflection; +using System.Reflection; using System.Runtime.InteropServices; +using Xunit; [assembly: AssemblyTitle("React.Tests.Core")] [assembly: AssemblyDescription("Unit tests for ReactJS.NET")] [assembly: ComVisible(false)] -[assembly: Guid("30a20b1c-18fd-4c3c-a18d-44875dba0c73")] \ No newline at end of file +[assembly: Guid("30a20b1c-18fd-4c3c-a18d-44875dba0c73")] +[assembly: CollectionBehavior(DisableTestParallelization = true)] diff --git a/tests/React.Tests/React.Tests.csproj b/tests/React.Tests/React.Tests.csproj new file mode 100644 index 000000000..00e4990b5 --- /dev/null +++ b/tests/React.Tests/React.Tests.csproj @@ -0,0 +1,54 @@ + + + + Copyright 2014-Present Facebook, Inc + ReactJS.NET Unit Tests + Daniel Lo Nigro + net452;netcoreapp3.1 + React.Tests + ../../src/key.snk + true + true + React.Tests + true + false + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/React.Tests/Router/HtmlHelperExtensionsTest.cs b/tests/React.Tests/Router/HtmlHelperExtensionsTest.cs new file mode 100644 index 000000000..e869e4392 --- /dev/null +++ b/tests/React.Tests/Router/HtmlHelperExtensionsTest.cs @@ -0,0 +1,371 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +#if NET452 + +using System.Collections.Specialized; +using System.Web; +using System.Web.Mvc; +using Moq; +using React.Router; +using React.Tests.Core; +using Xunit; + +namespace React.Tests.Router +{ + public class HtmlHelperExtensionsTest + { + /// + /// Creates a mock and registers it with the IoC container + /// This is only required because can not be + /// injected :( + /// + private ReactEnvironmentTest.Mocks ConfigureMockReactEnvironment() + { + var mocks = new ReactEnvironmentTest.Mocks(); + + mocks.Engine.Setup(x => x.Evaluate("typeof ComponentName !== 'undefined'")).Returns(true); + + var environment = mocks.CreateReactEnvironment(); + AssemblyRegistration.Container.Register(environment); + return mocks; + } + + private Mock ConfigureMockEnvironment() + { + var environment = new Mock(); + AssemblyRegistration.Container.Register(environment.Object); + return environment; + } + + private Mock ConfigureMockConfiguration() + { + var config = new Mock(); + config.SetupGet(x => x.UseServerSideRendering).Returns(true); + AssemblyRegistration.Container.Register(config.Object); + return config; + } + + private Mock ConfigureReactIdGenerator() + { + var reactIdGenerator = new Mock(); + AssemblyRegistration.Container.Register(reactIdGenerator.Object); + return reactIdGenerator; + } + + /// + /// Mock an html helper with a mocked response object. + /// Used when testing for server response modification. + /// + class HtmlHelperMocks + { + public Mock htmlHelper; + public Mock httpResponse; + + public HtmlHelperMocks(HttpRequestBase request = null) + { + var viewDataContainer = new Mock(); + var viewContext = new Mock(); + httpResponse = new Mock(); + htmlHelper = new Mock(viewContext.Object, viewDataContainer.Object); + var httpContextBase = new Mock(); + viewContext.Setup(x => x.HttpContext).Returns(httpContextBase.Object); + httpContextBase.Setup(x => x.Request).Returns(request); + httpContextBase.Setup(x => x.Response).Returns(httpResponse.Object); + } + } + + /// + /// Mocks alot of common functionality related to rendering a + /// React Router component. + /// + class ReactRouterMocks + { + public Mock config; + public Mock environment; + public Mock component; + public Mock reactIdGenerator; + + public ReactRouterMocks( + Mock conf, + Mock env, + Mock idGenerator, + bool clientOnly = false + ) + { + config = conf; + environment = env; + reactIdGenerator = idGenerator; + + component = new Mock( + environment.Object, + config.Object, + reactIdGenerator.Object, + "ComponentName", + "", + "/" + ); + var execResult = new Mock(); + + component.Setup(x => x.RenderRouterWithContext(It.IsAny(), It.IsAny(), null)) + .Returns(execResult.Object); + environment.Setup(x => x.CreateComponent( + It.IsAny(), + It.IsAny() + )).Returns(component.Object); + environment.Setup(x => x.Execute("JSON.stringify(context);")) + .Returns("{ }"); + } + } + + [Fact] + public void EngineIsReturnedToPoolAfterRender() + { + var config = ConfigureMockConfiguration(); + var environment = ConfigureMockEnvironment(); + var reactIdGenerator = ConfigureReactIdGenerator(); + var routerMocks = new ReactRouterMocks(config, environment, reactIdGenerator, true); + var htmlHelperMock = new HtmlHelperMocks(); + + environment.Verify(x => x.ReturnEngineToPool(), Times.Never); + var result = HtmlHelperExtensions.ReactRouter( + htmlHelper: htmlHelperMock.htmlHelper.Object, + componentName: "ComponentName", + props: new { }, + path: "/", + htmlTag: "span", + clientOnly: true, + serverOnly: true + ); + environment.Verify(x => x.ReturnEngineToPool(), Times.Once); + } + + [Fact] + public void ReactWithClientOnlyTrueShouldCallRenderHtmlWithTrue() + { + var config = ConfigureMockConfiguration(); + + var htmlHelperMock = new HtmlHelperMocks(); + var environment = ConfigureMockEnvironment(); + var reactIdGenerator = ConfigureReactIdGenerator(); + var routerMocks = new ReactRouterMocks(config, environment, reactIdGenerator, true); + + var result = HtmlHelperExtensions.ReactRouter( + htmlHelper: htmlHelperMock.htmlHelper.Object, + componentName: "ComponentName", + props: new { }, + path: "/", + htmlTag: "span", + clientOnly: true, + serverOnly: false + ); + routerMocks.component.Verify(x => x.RenderRouterWithContext(It.Is(y => y == true), It.Is(z => z == false), null), Times.Once); + } + + [Fact] + public void ReactWithServerOnlyTrueShouldCallRenderHtmlWithTrue() + { + var config = ConfigureMockConfiguration(); + + var htmlHelperMock = new HtmlHelperMocks(); + var environment = ConfigureMockEnvironment(); + var reactIdGenerator = ConfigureReactIdGenerator(); + var routerMocks = new ReactRouterMocks(config, environment, reactIdGenerator); + + var result = HtmlHelperExtensions.ReactRouter( + htmlHelper: htmlHelperMock.htmlHelper.Object, + componentName: "ComponentName", + props: new { }, + path: "/", + htmlTag: "span", + clientOnly: false, + serverOnly: true + ); + routerMocks.component.Verify(x => x.RenderRouterWithContext(It.Is(y => y == false), It.Is(z => z == true), null), Times.Once); + } + + [Fact] + public void ShouldModifyStatusCode() + { + var mocks = ConfigureMockReactEnvironment(); + ConfigureMockConfiguration(); + ConfigureReactIdGenerator(); + + mocks.Engine.Setup(x => x.Evaluate("JSON.stringify(context);")) + .Returns("{ status: 200 }"); + + var htmlHelperMock = new HtmlHelperMocks(); + + HtmlHelperExtensions.ReactRouter( + htmlHelper: htmlHelperMock.htmlHelper.Object, + componentName: "ComponentName", + props: new { }, + path: "/" + ); + htmlHelperMock.httpResponse.VerifySet(x => x.StatusCode = 200); + } + + [Fact] + public void ShouldRunCustomContextHandler() + { + var mocks = ConfigureMockReactEnvironment(); + ConfigureMockConfiguration(); + ConfigureReactIdGenerator(); + + mocks.Engine.Setup(x => x.Evaluate("JSON.stringify(context);")) + .Returns("{ status: 200 }"); + + var htmlHelperMock = new HtmlHelperMocks(); + + HtmlHelperExtensions.ReactRouter( + htmlHelper: htmlHelperMock.htmlHelper.Object, + componentName: "ComponentName", + props: new { }, + path: "/", + contextHandler: (response, context) => response.StatusCode = context.status.Value + ); + htmlHelperMock.httpResponse.VerifySet(x => x.StatusCode = 200); + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public void ShouldHandleQueryParams(bool withOverriddenPath) + { + var mocks = ConfigureMockReactEnvironment(); + ConfigureMockConfiguration(); + ConfigureReactIdGenerator(); + + mocks.Engine.Setup(x => x.Evaluate("JSON.stringify(context);")) + .Returns("{ status: 200 }"); + + var requestMock = new Mock(); + requestMock.SetupGet(x => x.Path).Returns("/test"); + var queryStringMock = new Mock(); + queryStringMock.Setup(x => x.ToString()).Returns("?a=1&b=2"); + requestMock.SetupGet(x => x.QueryString).Returns(queryStringMock.Object); + + var htmlHelperMock = new HtmlHelperMocks(requestMock.Object); + + var result = HtmlHelperExtensions.ReactRouter( + htmlHelper: htmlHelperMock.htmlHelper.Object, + componentName: "ComponentName", + props: new { }, + path: withOverriddenPath ? "/test2?b=1&c=2" : null, + contextHandler: (response, context) => response.StatusCode = context.status.Value + ); + + htmlHelperMock.httpResponse.VerifySet(x => x.StatusCode = 200); + + if (withOverriddenPath) + { + mocks.Engine.Verify(x => x.Evaluate(@"ReactDOMServer.renderToString(React.createElement(ComponentName, Object.assign({}, { location: ""/test2?b=1&c=2"", context: context })))")); + } + else + { + mocks.Engine.Verify(x => x.Evaluate(@"ReactDOMServer.renderToString(React.createElement(ComponentName, Object.assign({}, { location: ""/test?a=1&b=2"", context: context })))")); + } + } + + [Theory] + [InlineData("?a='\"1", "?a='\\\"1")] + public void ShouldEscapeQuery(string query, string expected) + { + var mocks = ConfigureMockReactEnvironment(); + ConfigureMockConfiguration(); + ConfigureReactIdGenerator(); + + mocks.Engine.Setup(x => x.Evaluate("JSON.stringify(context);")) + .Returns("{ status: 200 }"); + + var requestMock = new Mock(); + requestMock.SetupGet(x => x.Path).Returns("/test"); + var queryStringMock = new Mock(); + queryStringMock.Setup(x => x.ToString()).Returns(query); + requestMock.SetupGet(x => x.QueryString).Returns(queryStringMock.Object); + + var htmlHelperMock = new HtmlHelperMocks(requestMock.Object); + + var result = HtmlHelperExtensions.ReactRouter( + htmlHelper: htmlHelperMock.htmlHelper.Object, + componentName: "ComponentName", + props: new { }, + path: null, + contextHandler: (response, context) => response.StatusCode = context.status.Value + ); + + htmlHelperMock.httpResponse.VerifySet(x => x.StatusCode = 200); + + mocks.Engine.Verify(x => x.Evaluate(@"ReactDOMServer.renderToString(React.createElement(ComponentName, Object.assign({}, { location: ""/test" + expected + @""", context: context })))")); + } + + [Fact] + public void ShouldRedirectPermanent() + { + var mocks = ConfigureMockReactEnvironment(); + ConfigureMockConfiguration(); + ConfigureReactIdGenerator(); + + mocks.Engine.Setup(x => x.Evaluate("JSON.stringify(context);")) + .Returns(@"{ status: 301, url: ""/foo"" }"); + + var htmlHelperMock = new HtmlHelperMocks(); + + HtmlHelperExtensions.ReactRouter( + htmlHelper: htmlHelperMock.htmlHelper.Object, + componentName: "ComponentName", + props: new { }, + path: "/" + ); + htmlHelperMock.httpResponse.Verify(x => x.RedirectPermanent(It.IsAny())); + } + + [Fact] + public void ShouldRedirectWithJustUrl() + { + var mocks = ConfigureMockReactEnvironment(); + ConfigureMockConfiguration(); + ConfigureReactIdGenerator(); + + mocks.Engine.Setup(x => x.Evaluate("JSON.stringify(context);")) + .Returns(@"{ url: ""/foo"" }"); + + var htmlHelperMock = new HtmlHelperMocks(); + + HtmlHelperExtensions.ReactRouter( + htmlHelper: htmlHelperMock.htmlHelper.Object, + componentName: "ComponentName", + props: new { }, + path: "/" + ); + htmlHelperMock.httpResponse.Verify(x => x.Redirect(It.IsAny())); + } + + [Fact] + public void ShouldFailRedirectWithNoUrl() + { + var mocks = ConfigureMockReactEnvironment(); + ConfigureMockConfiguration(); + ConfigureReactIdGenerator(); + + mocks.Engine.Setup(x => x.Evaluate("JSON.stringify(context);")) + .Returns("{ status: 301 }"); + + var htmlHelperMock = new HtmlHelperMocks(); + + Assert.Throws(() => + + HtmlHelperExtensions.ReactRouter( + htmlHelper: htmlHelperMock.htmlHelper.Object, + componentName: "ComponentName", + props: new { }, + path: "/" + ) + ); + } + } +} +#endif diff --git a/tests/React.Tests/Router/ReactEnvironmentExtensionsTest.cs b/tests/React.Tests/Router/ReactEnvironmentExtensionsTest.cs new file mode 100644 index 000000000..ad9bd550d --- /dev/null +++ b/tests/React.Tests/Router/ReactEnvironmentExtensionsTest.cs @@ -0,0 +1,42 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +#if NET452 || NETCOREAPP + +using Moq; +using Xunit; +using React.Exceptions; +using React.Router; +using React.Tests.Core; + +namespace React.Tests.Router +{ + public class ReactEnvironmentExtensionsTest + { + [Fact] + public void EnvironmentShouldGetCalledClientOnly() + { + var environment = new Mock(); + AssemblyRegistration.Container.Register(environment.Object); + var config = new Mock(); + AssemblyRegistration.Container.Register(config.Object); + var reactIdGenerator = new Mock(); + AssemblyRegistration.Container.Register(reactIdGenerator.Object); + + var component = ReactEnvironmentExtensions.CreateRouterComponent( + environment.Object, + "ComponentName", + new { }, + "/", + null, + true + ); + + environment.Verify(x => x.CreateComponent(It.IsAny(), true)); + } + } +} +#endif diff --git a/tests/React.Tests/Router/ReactRouterComponentTest.cs b/tests/React.Tests/Router/ReactRouterComponentTest.cs new file mode 100644 index 000000000..f939eaf1d --- /dev/null +++ b/tests/React.Tests/Router/ReactRouterComponentTest.cs @@ -0,0 +1,89 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +#if NET452 || NETCOREAPP + +using Moq; +using Xunit; +using React.Router; + +namespace React.Tests.Router +{ + public class ReactRouterComponentTest + { + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void RenderJavaScriptShouldNotIncludeContextOrPath(bool clientOnly, bool useServerSideRendering) + { + var environment = new Mock(); + var config = new Mock(); + config.Setup(x => x.UseServerSideRendering).Returns(useServerSideRendering); + var reactIdGenerator = new Mock(); + + var component = new ReactRouterComponent(environment.Object, config.Object, reactIdGenerator.Object, "Foo", "container", "/bar") + { + Props = new { hello = "World" }, + ClientOnly = clientOnly, + }; + var result = component.RenderJavaScript(false); + + if (clientOnly || !useServerSideRendering) + { + Assert.Equal( + @"ReactDOM.render(React.createElement(Foo, {""hello"":""World""}), document.getElementById(""container""))", + result + ); + } + else + { + Assert.Equal( + @"ReactDOM.hydrate(React.createElement(Foo, {""hello"":""World""}), document.getElementById(""container""))", + result + ); + } + + } + + [Theory] + [InlineData(true, true)] + [InlineData(true, false)] + [InlineData(false, true)] + [InlineData(false, false)] + public void RenderJavaScriptShouldHandleWaitForContentLoad(bool clientOnly, bool useServerSideRendering) + { + var environment = new Mock(); + var config = new Mock(); + config.Setup(x => x.UseServerSideRendering).Returns(useServerSideRendering); + var reactIdGenerator = new Mock(); + + var component = new ReactRouterComponent(environment.Object, config.Object, reactIdGenerator.Object, "Foo", "container", "/bar") + { + Props = new { hello = "World" }, + ClientOnly = clientOnly + }; + var result = component.RenderJavaScript(true); + + if (clientOnly || !useServerSideRendering) + { + Assert.Equal( + @"window.addEventListener('DOMContentLoaded', function() {ReactDOM.render(React.createElement(Foo, {""hello"":""World""}), document.getElementById(""container""))});", + result + ); + } + else + { + Assert.Equal( + @"window.addEventListener('DOMContentLoaded', function() {ReactDOM.hydrate(React.createElement(Foo, {""hello"":""World""}), document.getElementById(""container""))});", + result + ); + } + } + } +} +#endif diff --git a/tools/MSBuildTasks/MSBuild.Community.Tasks.targets b/tools/MSBuildTasks/MSBuild.Community.Tasks.Targets similarity index 85% rename from tools/MSBuildTasks/MSBuild.Community.Tasks.targets rename to tools/MSBuildTasks/MSBuild.Community.Tasks.Targets index be807d884..dfc77e892 100644 --- a/tools/MSBuildTasks/MSBuild.Community.Tasks.targets +++ b/tools/MSBuildTasks/MSBuild.Community.Tasks.Targets @@ -1,10 +1,12 @@ - - $(MSBuildExtensionsPath)\MSBuildCommunityTasks - $([MSBUILD]::Unescape($(MSBuildCommunityTasksPath)\MSBuild.Community.Tasks.dll)) + $(MSBuildThisFileDirectory) + $(MSBuildThisFileDirectory)\..\tools + $([MSBUILD]::Unescape($(MSBuildCommunityTasksPath)\MSBuild.Community.Tasks.dll)) + $(MSBuildCommunityTasksPath)\MSBuild.Community.Tasks.dll + MSBuild.Community.Tasks.dll @@ -37,6 +39,7 @@ + @@ -80,7 +83,8 @@ - + + @@ -101,6 +105,7 @@ + @@ -111,6 +116,7 @@ + @@ -129,13 +135,21 @@ + + + + + + + + diff --git a/tools/MSBuildTasks/MSBuild.Community.Tasks.dll b/tools/MSBuildTasks/MSBuild.Community.Tasks.dll index 3f6c06da1..eac2f117d 100644 Binary files a/tools/MSBuildTasks/MSBuild.Community.Tasks.dll and b/tools/MSBuildTasks/MSBuild.Community.Tasks.dll differ diff --git a/tools/NuGet/nuget.exe b/tools/NuGet/nuget.exe index 9cba6edbf..fb4eb39f0 100644 Binary files a/tools/NuGet/nuget.exe and b/tools/NuGet/nuget.exe differ diff --git a/tutorial-code/README.md b/tutorial-code/README.md new file mode 100644 index 000000000..0e745ceff --- /dev/null +++ b/tutorial-code/README.md @@ -0,0 +1 @@ +The tutorial source has been moved to .NET Core templates [here](../src/React.Template) diff --git a/webhooks/NetlifyHook.cs b/webhooks/NetlifyHook.cs new file mode 100644 index 000000000..66221553a --- /dev/null +++ b/webhooks/NetlifyHook.cs @@ -0,0 +1,94 @@ +using System.Configuration; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.Azure.WebJobs; +using Microsoft.Azure.WebJobs.Extensions.Http; +using Microsoft.Azure.WebJobs.Host; +using Octokit; + +namespace React.Site.Hooks +{ + /// + /// Webhook for Netlify website builds + /// + public static class NetlifyHook + { + [FunctionName("NetlifyHook")] + public static async Task Run( + [HttpTrigger(AuthorizationLevel.Function, WebHookType = "genericJson")]HttpRequestMessage req, + TraceWriter log) + { + log.Info("Netlify webhook triggered"); + + string jsonContent = await req.Content.ReadAsStringAsync(); + var data = NetlifyHookBody.CreateFromRequest(jsonContent); + + if (!data.ReviewId.HasValue) + { + log.Info("Build is not for a PR. Ignoring."); + return req.CreateResponse(HttpStatusCode.NoContent); + } + + var client = new GitHubClient(new ProductHeaderValue("reactjs-net-webhooks")) + { + Credentials = new Credentials(ConfigurationManager.AppSettings["GitHubToken"]) + }; + + // Determine if the PR modified any site files + var githubOwner = ConfigurationManager.AppSettings["GitHubOwner"]; + var githubRepo = ConfigurationManager.AppSettings["GitHubRepo"]; + var pullRequestFiles = await client.PullRequest.Files(githubOwner, githubRepo, data.ReviewId.Value); + if (!pullRequestFiles.Any(IsWebsiteFile)) + { + log.Info("PR did not modify the site. Ignoring."); + return req.CreateResponse(HttpStatusCode.NoContent); + } + + var body = BuildCommentBody(data); + + // Check if a comment already exists + var existingComments = await client.Issue.Comment.GetAllForIssue(githubOwner, githubRepo, data.ReviewId.Value); + var existingComment = existingComments.FirstOrDefault( + comment => comment.User.Login == ConfigurationManager.AppSettings["GitHubBotUser"] + ); + if (existingComment != null) + { + // There's already an existing comment, so we'll just edit that one + // rather than posting a brand new comment. + await client.Issue.Comment.Update(githubOwner, githubRepo, existingComment.Id, body); + log.Info($"Updated existing commment {existingComment.Id}"); + } + else + { + await client.Issue.Comment.Create(githubOwner, githubRepo, data.ReviewId.Value, body); + log.Info("Posted commment"); + } + + return req.CreateResponse(HttpStatusCode.NoContent); + } + + private static bool IsWebsiteFile(PullRequestFile file) + { + return file.FileName.StartsWith("site/"); + } + + private static string BuildCommentBody(NetlifyHookBody data) + { + switch (data.State) + { + case "ready": + return $"Website preview is ready!\nBuilt with commit {data.CommitRef}\n{data.DeploySslUrl}"; + + case "error": + var netlifySite = ConfigurationManager.AppSettings["NetlifySite"]; + var buildUrl = $"https://app.netlify.com/sites/{netlifySite}/deploys/{data.BuildId}"; + return $"Failed to build the site :(\n\n```\n{data.ErrorMessage}\n```\n\nBuild log: {buildUrl}"; + + default: + return $"Unknown build state: {data.State}\n{data.DeploySslUrl}"; + } + } + } +} diff --git a/webhooks/NetlifyHookBody.cs b/webhooks/NetlifyHookBody.cs new file mode 100644 index 000000000..855f9989d --- /dev/null +++ b/webhooks/NetlifyHookBody.cs @@ -0,0 +1,44 @@ +using System; +using Newtonsoft.Json; +using Newtonsoft.Json.Serialization; + +namespace React.Site.Hooks +{ + /// + /// Body of Netlify webhook requests + /// + public class NetlifyHookBody + { + public string Id { get; set; } + public string SiteId { get; set; } + public string BuildId { get; set; } + public string State { get; set; } + public string Name { get; set; } + public Uri Url { get; set; } + public Uri SslUrl { get; set; } + public Uri AdminUrl { get; set; } + public Uri DeployUrl { get; set; } + public Uri DeploySslUrl { get; set; } + public DateTime CreatedAt { get; set; } + public DateTime UpdatedAt { get; set; } + public string UserId { get; set; } + public string ErrorMessage { get; set; } + public string CommitRef { get; set; } + public int? ReviewId { get; set; } + public string Branch { get; set; } + public Uri CommitUrl { get; set; } + public string Title { get; set; } + public int? DeployTime { get; set; } + + public static NetlifyHookBody CreateFromRequest(string request) + { + return JsonConvert.DeserializeObject(request, new JsonSerializerSettings + { + ContractResolver = new DefaultContractResolver + { + NamingStrategy = new SnakeCaseNamingStrategy() + } + }); + } + } +} diff --git a/webhooks/React.Site.Hooks.csproj b/webhooks/React.Site.Hooks.csproj new file mode 100644 index 000000000..fd9214a09 --- /dev/null +++ b/webhooks/React.Site.Hooks.csproj @@ -0,0 +1,25 @@ + + + net461 + + + + + + + + + + + + PreserveNewest + + + PreserveNewest + Never + + + + + + diff --git a/webhooks/React.Site.Hooks.sln b/webhooks/React.Site.Hooks.sln new file mode 100644 index 000000000..636fd9e5a --- /dev/null +++ b/webhooks/React.Site.Hooks.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27703.2035 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "React.Site.Hooks", "React.Site.Hooks.csproj", "{2E2F78B4-2B07-41C9-B7DE-FB15373773BA}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2E2F78B4-2B07-41C9-B7DE-FB15373773BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2E2F78B4-2B07-41C9-B7DE-FB15373773BA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2E2F78B4-2B07-41C9-B7DE-FB15373773BA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2E2F78B4-2B07-41C9-B7DE-FB15373773BA}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {EB3FA88F-C3DC-4BB3-907F-D38D058A1B46} + EndGlobalSection +EndGlobal diff --git a/webhooks/host.json b/webhooks/host.json new file mode 100644 index 000000000..7a73a41bf --- /dev/null +++ b/webhooks/host.json @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/webhooks/local.settings.json b/webhooks/local.settings.json new file mode 100644 index 000000000..8cc59c400 --- /dev/null +++ b/webhooks/local.settings.json @@ -0,0 +1,13 @@ +{ + "IsEncrypted": false, + "Values": { + "AzureWebJobsStorage": "UseDevelopmentStorage=true", + "AzureWebJobsDashboard": "UseDevelopmentStorage=true", + + "GitHubOwner": "Daniel15", + "GitHubRepo": "React.NET", + "GitHubBotUser": "DanBuild", + "GitHubToken": "CHANGEME", + "NetlifySite": "reactnet-test" + } +}