diff --git a/.eslintrc.json b/.eslintrc.json index f900d96..9ac4855 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -10,7 +10,6 @@ "__": true }, "rules": { - "no-console": 2, "no-multi-spaces": 0, "new-cap": 0, "prefer-promise-reject-errors": 0, diff --git a/.gitignore b/.gitignore index 2c351d3..af2308a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,66 +1,4 @@ -# OSX -# -.DS_Store - -# Xcode -# -build/ -*.pbxuser -!default.pbxuser -*.mode1v3 -!default.mode1v3 -*.mode2v3 -!default.mode2v3 -*.perspectivev3 -!default.perspectivev3 -xcuserdata -*.xccheckout -*.moved-aside -DerivedData -*.hmap -*.ipa -*.xcuserstate - -# Android/IntelliJ -# -build/ -.idea -.gradle -local.properties -*.iml - -# node.js -# node_modules/ -npm-debug.log -yarn-error.log - -# BUCK -buck-out/ -\.buckd/ -*.keystore -!debug.keystore - -# fastlane -# -# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the -# screenshots whenever they are needed. -# For more information about the recommended setup visit: -# https://docs.fastlane.tools/best-practices/source-control/ - -*/fastlane/report.xml -*/fastlane/Preview.html -*/fastlane/screenshots - -# Bundle artifact -*.jsbundle - -# CocoaPods -/ios/Pods/ - -# Other Files -android/app/google-services.json *.log .vagrant -android/app/build/* -android/bin + diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml deleted file mode 100644 index b0b2e39..0000000 --- a/.gitlab-ci.yml +++ /dev/null @@ -1,8 +0,0 @@ -stages: - - build - -build: - variables: - REACT_NATIVE_BRANCH: $CI_COMMIT_REF_NAME - stage: build - trigger: lbry/lbry-android diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 07444fe..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "android"] - path = android - url = https://github.com/lbryio/lbry-android diff --git a/LICENSE b/LICENSE index a293e51..08b5886 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2017-2020 LBRY Inc +Copyright (c) 2017-2018 LBRY Inc 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: diff --git a/README.md b/README.md index 8599854..08d9f8f 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -# LBRY React Native +# LBRY Android [](https://ci.lbry.tech/lbry/lbry-android/commits/master) -A mobile browser and wallet for the [LBRY](https://lbry.com) network. This app bundles [LBRY SDK](https://github.com/lbryio/lbry) as a background service with a UI layer built with React Native. +An Android browser and wallet for the [LBRY](https://lbry.com) network. This app bundles [lbrynet-daemon](https://github.com/lbryio/lbry) as a background service with a UI layer built with React Native. The APK is built using buildozer and the Gradle build tool. <img src="https://spee.ch/8/lbry-android.png" alt="LBRY Android Screenshot" width="384px" /> @@ -12,41 +12,10 @@ The minimum supported Android version is 5.0 Lollipop. There are two ways to ins 1. Direct APK install available at [http://build.lbry.io/android/latest.apk](http://build.lbry.io/android/latest.apk). You will need to enable installation from third-party sources on your device in order to install from this source. ## Usage -The app can be launched by opening **LBRY** from the device's app drawer or via the shortcut on the home screen if that was created upon installation. +The app can be launched by opening **LBRY Browser** from the device's app drawer or via the shortcut on the home screen if that was created upon installation. ## Running from Source -### Software Requirements -* Android Studio -* WebStorm (or other IDE for editing React Native / JavaScript code) -* npm -* yarn - -### Android Steps -* Clone the repository using `git clone https://github.com/lbryio/lbry-react-native` -* Initialise the submodules. -``` -cd lbry-react-native -git submodule update --init --recursive -``` -* Install `react-native-cli` globally using `npm install -g react-native-cli`. -* Install the required package modules by running `yarn` in the cloned repository folder. -* Download a `google-services.json` from the Firebase console (https://console.firebase.google.com/) and place it in the `android/app` folder. Alternatively, use the included sample JSON file. -``` -cp android/app/google-services.sample.json android/app/google-services.json -``` -* Open Android Studio and click File > Open... -* Navigate to the cloned repository on your local filesystem and select the `android` subfolder. -* Connect your Android device in USB debugging mode, or create an ARM emulator (slower) to run the app. -* Click Run > Run... and select the corresponding app configuration. Note that it may take a while for the project files to sync before you can run the app -* In order to edit the React Native / JavaScript files, open the cloned repository folder using WebStorm (or your favourite IDE). - -### React Native Fast Refresh -In order to enable fast refresh when updating React Native code -* Connect your Android device in USB debugging mode, or create an ARM emulator -* Run `adb reverse tcp:8081 tcp:8081` (`adb` can be found in the `platform-tools` folder of your Android SDK installation) -* Run `yarn start` -* Press `r` to reload the app. -* Anytime you make an update to the React Native code, the app should automatically refresh. +The app is built from source via [Buildozer](https://github.com/kivy/buildozer). After cloning the repository, copy `buildozer.spec.sample` to `buildozer.spec` and modify this file as necessary for your environment. Please see [BUILD.md](BUILD.md) for detailed build instructions. ## Contributing Contributions to this project are welcome, encouraged, and compensated. For more details, see https://lbry.io/faq/contributing diff --git a/__tests__/App-test.js b/__tests__/App-test.js deleted file mode 100644 index 1784766..0000000 --- a/__tests__/App-test.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - * @format - */ - -import 'react-native'; -import React from 'react'; -import App from '../App'; - -// Note: test renderer must be required after react-native. -import renderer from 'react-test-renderer'; - -it('renders correctly', () => { - renderer.create(<App />); -}); diff --git a/android b/android deleted file mode 160000 index ff30e7f..0000000 --- a/android +++ /dev/null @@ -1 +0,0 @@ -Subproject commit ff30e7f6a4358fd997a9e6d9f75bfe6959eafcb6 diff --git a/bundle-android.sh b/bundle-android.sh deleted file mode 100644 index 37d41d4..0000000 --- a/bundle-android.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -react-native bundle --platform android --dev false --entry-file src/index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res/ diff --git a/index.js b/index.js index cdbce82..84a5965 100644 --- a/index.js +++ b/index.js @@ -1,7 +1,3 @@ -if (__DEV__) { - import('./reactotron').then(() => console.log('Reactotron Configured')); -} - import LBRYApp from './src/index'; export default LBRYApp; diff --git a/ios/LbryApp-tvOS/Info.plist b/ios/LbryApp-tvOS/Info.plist deleted file mode 100644 index ecbd496..0000000 --- a/ios/LbryApp-tvOS/Info.plist +++ /dev/null @@ -1,53 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>CFBundleDevelopmentRegion</key> - <string>en</string> - <key>CFBundleExecutable</key> - <string>$(EXECUTABLE_NAME)</string> - <key>CFBundleIdentifier</key> - <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundleName</key> - <string>$(PRODUCT_NAME)</string> - <key>CFBundlePackageType</key> - <string>APPL</string> - <key>CFBundleShortVersionString</key> - <string>1.0</string> - <key>CFBundleSignature</key> - <string>????</string> - <key>CFBundleVersion</key> - <string>1</string> - <key>LSRequiresIPhoneOS</key> - <true/> - <key>NSAppTransportSecurity</key> - <dict> - <key>NSExceptionDomains</key> - <dict> - <key>localhost</key> - <dict> - <key>NSExceptionAllowsInsecureHTTPLoads</key> - <true/> - </dict> - </dict> - </dict> - <key>NSLocationWhenInUseUsageDescription</key> - <string></string> - <key>UILaunchStoryboardName</key> - <string>LaunchScreen</string> - <key>UIRequiredDeviceCapabilities</key> - <array> - <string>armv7</string> - </array> - <key>UISupportedInterfaceOrientations</key> - <array> - <string>UIInterfaceOrientationPortrait</string> - <string>UIInterfaceOrientationLandscapeLeft</string> - <string>UIInterfaceOrientationLandscapeRight</string> - </array> - <key>UIViewControllerBasedStatusBarAppearance</key> - <false/> -</dict> -</plist> diff --git a/ios/LbryApp-tvOSTests/Info.plist b/ios/LbryApp-tvOSTests/Info.plist deleted file mode 100644 index 886825c..0000000 --- a/ios/LbryApp-tvOSTests/Info.plist +++ /dev/null @@ -1,24 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>CFBundleDevelopmentRegion</key> - <string>en</string> - <key>CFBundleExecutable</key> - <string>$(EXECUTABLE_NAME)</string> - <key>CFBundleIdentifier</key> - <string>org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)</string> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundleName</key> - <string>$(PRODUCT_NAME)</string> - <key>CFBundlePackageType</key> - <string>BNDL</string> - <key>CFBundleShortVersionString</key> - <string>1.0</string> - <key>CFBundleSignature</key> - <string>????</string> - <key>CFBundleVersion</key> - <string>1</string> -</dict> -</plist> diff --git a/ios/LbryApp.xcodeproj/project.pbxproj b/ios/LbryApp.xcodeproj/project.pbxproj deleted file mode 100644 index 267742d..0000000 --- a/ios/LbryApp.xcodeproj/project.pbxproj +++ /dev/null @@ -1,782 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 00E356F31AD99517003FC87E /* LbryAppTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* LbryAppTests.m */; }; - 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; }; - 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; }; - 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; - 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; - 2D02E4BC1E0B4A80006451C7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; }; - 2D02E4BD1E0B4A84006451C7 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; - 2D02E4BF1E0B4AB3006451C7 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; - 2DCD954D1E0B4F2C00145EB5 /* LbryAppTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* LbryAppTests.m */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 00E356F41AD99517003FC87E /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 13B07F861A680F5B00A75B9A; - remoteInfo = LbryApp; - }; - 2D02E4911E0B4A5D006451C7 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 2D02E47A1E0B4A5D006451C7; - remoteInfo = "LbryApp-tvOS"; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXFileReference section */ - 008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = main.jsbundle; sourceTree = "<group>"; }; - 00E356EE1AD99517003FC87E /* LbryAppTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = LbryAppTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; - 00E356F21AD99517003FC87E /* LbryAppTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LbryAppTests.m; sourceTree = "<group>"; }; - 13B07F961A680F5B00A75B9A /* LbryApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LbryApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = LbryApp/AppDelegate.h; sourceTree = "<group>"; }; - 13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = LbryApp/AppDelegate.m; sourceTree = "<group>"; }; - 13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; }; - 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = LbryApp/Images.xcassets; sourceTree = "<group>"; }; - 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = LbryApp/Info.plist; sourceTree = "<group>"; }; - 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = LbryApp/main.m; sourceTree = "<group>"; }; - 2D02E47B1E0B4A5D006451C7 /* LbryApp-tvOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "LbryApp-tvOS.app"; sourceTree = BUILT_PRODUCTS_DIR; }; - 2D02E4901E0B4A5D006451C7 /* LbryApp-tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "LbryApp-tvOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; - ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; - ED2971642150620600B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS12.0.sdk/System/Library/Frameworks/JavaScriptCore.framework; sourceTree = DEVELOPER_DIR; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 00E356EB1AD99517003FC87E /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 13B07F8C1A680F5B00A75B9A /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 2D02E4781E0B4A5D006451C7 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 2D02E48D1E0B4A5D006451C7 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 00E356EF1AD99517003FC87E /* LbryAppTests */ = { - isa = PBXGroup; - children = ( - 00E356F21AD99517003FC87E /* LbryAppTests.m */, - 00E356F01AD99517003FC87E /* Supporting Files */, - ); - path = LbryAppTests; - sourceTree = "<group>"; - }; - 00E356F01AD99517003FC87E /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 00E356F11AD99517003FC87E /* Info.plist */, - ); - name = "Supporting Files"; - sourceTree = "<group>"; - }; - 13B07FAE1A68108700A75B9A /* LbryApp */ = { - isa = PBXGroup; - children = ( - 008F07F21AC5B25A0029DE68 /* main.jsbundle */, - 13B07FAF1A68108700A75B9A /* AppDelegate.h */, - 13B07FB01A68108700A75B9A /* AppDelegate.m */, - 13B07FB51A68108700A75B9A /* Images.xcassets */, - 13B07FB61A68108700A75B9A /* Info.plist */, - 13B07FB11A68108700A75B9A /* LaunchScreen.xib */, - 13B07FB71A68108700A75B9A /* main.m */, - ); - name = LbryApp; - sourceTree = "<group>"; - }; - 2D16E6871FA4F8E400B85C8A /* Frameworks */ = { - isa = PBXGroup; - children = ( - ED297162215061F000B7C4FE /* JavaScriptCore.framework */, - ED2971642150620600B7C4FE /* JavaScriptCore.framework */, - ); - name = Frameworks; - sourceTree = "<group>"; - }; - 832341AE1AAA6A7D00B99B32 /* Libraries */ = { - isa = PBXGroup; - children = ( - ); - name = Libraries; - sourceTree = "<group>"; - }; - 83CBB9F61A601CBA00E9B192 = { - isa = PBXGroup; - children = ( - 13B07FAE1A68108700A75B9A /* LbryApp */, - 832341AE1AAA6A7D00B99B32 /* Libraries */, - 00E356EF1AD99517003FC87E /* LbryAppTests */, - 83CBBA001A601CBA00E9B192 /* Products */, - 2D16E6871FA4F8E400B85C8A /* Frameworks */, - ); - indentWidth = 2; - sourceTree = "<group>"; - tabWidth = 2; - usesTabs = 0; - }; - 83CBBA001A601CBA00E9B192 /* Products */ = { - isa = PBXGroup; - children = ( - 13B07F961A680F5B00A75B9A /* LbryApp.app */, - 00E356EE1AD99517003FC87E /* LbryAppTests.xctest */, - 2D02E47B1E0B4A5D006451C7 /* LbryApp-tvOS.app */, - 2D02E4901E0B4A5D006451C7 /* LbryApp-tvOSTests.xctest */, - ); - name = Products; - sourceTree = "<group>"; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 00E356ED1AD99517003FC87E /* LbryAppTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "LbryAppTests" */; - buildPhases = ( - 00E356EA1AD99517003FC87E /* Sources */, - 00E356EB1AD99517003FC87E /* Frameworks */, - 00E356EC1AD99517003FC87E /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 00E356F51AD99517003FC87E /* PBXTargetDependency */, - ); - name = LbryAppTests; - productName = LbryAppTests; - productReference = 00E356EE1AD99517003FC87E /* LbryAppTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - 13B07F861A680F5B00A75B9A /* LbryApp */ = { - isa = PBXNativeTarget; - buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "LbryApp" */; - buildPhases = ( - FD10A7F022414F080027D42C /* Start Packager */, - 13B07F871A680F5B00A75B9A /* Sources */, - 13B07F8C1A680F5B00A75B9A /* Frameworks */, - 13B07F8E1A680F5B00A75B9A /* Resources */, - 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = LbryApp; - productName = "LbryApp"; - productReference = 13B07F961A680F5B00A75B9A /* LbryApp.app */; - productType = "com.apple.product-type.application"; - }; - 2D02E47A1E0B4A5D006451C7 /* LbryApp-tvOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = 2D02E4BA1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "LbryApp-tvOS" */; - buildPhases = ( - FD10A7F122414F3F0027D42C /* Start Packager */, - 2D02E4771E0B4A5D006451C7 /* Sources */, - 2D02E4781E0B4A5D006451C7 /* Frameworks */, - 2D02E4791E0B4A5D006451C7 /* Resources */, - 2D02E4CB1E0B4B27006451C7 /* Bundle React Native Code And Images */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "LbryApp-tvOS"; - productName = "LbryApp-tvOS"; - productReference = 2D02E47B1E0B4A5D006451C7 /* LbryApp-tvOS.app */; - productType = "com.apple.product-type.application"; - }; - 2D02E48F1E0B4A5D006451C7 /* LbryApp-tvOSTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 2D02E4BB1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "LbryApp-tvOSTests" */; - buildPhases = ( - 2D02E48C1E0B4A5D006451C7 /* Sources */, - 2D02E48D1E0B4A5D006451C7 /* Frameworks */, - 2D02E48E1E0B4A5D006451C7 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 2D02E4921E0B4A5D006451C7 /* PBXTargetDependency */, - ); - name = "LbryApp-tvOSTests"; - productName = "LbryApp-tvOSTests"; - productReference = 2D02E4901E0B4A5D006451C7 /* LbryApp-tvOSTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 83CBB9F71A601CBA00E9B192 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0940; - ORGANIZATIONNAME = Facebook; - TargetAttributes = { - 00E356ED1AD99517003FC87E = { - CreatedOnToolsVersion = 6.2; - TestTargetID = 13B07F861A680F5B00A75B9A; - }; - 2D02E47A1E0B4A5D006451C7 = { - CreatedOnToolsVersion = 8.2.1; - ProvisioningStyle = Automatic; - }; - 2D02E48F1E0B4A5D006451C7 = { - CreatedOnToolsVersion = 8.2.1; - ProvisioningStyle = Automatic; - TestTargetID = 2D02E47A1E0B4A5D006451C7; - }; - }; - }; - buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "LbryApp" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 83CBB9F61A601CBA00E9B192; - productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 13B07F861A680F5B00A75B9A /* LbryApp */, - 00E356ED1AD99517003FC87E /* LbryAppTests */, - 2D02E47A1E0B4A5D006451C7 /* LbryApp-tvOS */, - 2D02E48F1E0B4A5D006451C7 /* LbryApp-tvOSTests */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 00E356EC1AD99517003FC87E /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 13B07F8E1A680F5B00A75B9A /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, - 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 2D02E4791E0B4A5D006451C7 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 2D02E4BD1E0B4A84006451C7 /* Images.xcassets in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 2D02E48E1E0B4A5D006451C7 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Bundle React Native code and images"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh"; - }; - 2D02E4CB1E0B4B27006451C7 /* Bundle React Native Code And Images */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Bundle React Native Code And Images"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "export NODE_BINARY=node\n../node_modules/react-native/scripts/react-native-xcode.sh"; - }; - FD10A7F022414F080027D42C /* Start Packager */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - ); - name = "Start Packager"; - outputFileListPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "export RCT_METRO_PORT=\"${RCT_METRO_PORT:=8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > \"${SRCROOT}/../node_modules/react-native/scripts/.packager.env\"\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../node_modules/react-native/scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi\n"; - showEnvVarsInLog = 0; - }; - FD10A7F122414F3F0027D42C /* Start Packager */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - ); - name = "Start Packager"; - outputFileListPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "export RCT_METRO_PORT=\"${RCT_METRO_PORT:=8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > \"${SRCROOT}/../node_modules/react-native/scripts/.packager.env\"\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open \"$SRCROOT/../node_modules/react-native/scripts/launchPackager.command\" || echo \"Can't start packager automatically\"\n fi\nfi\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 00E356EA1AD99517003FC87E /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 00E356F31AD99517003FC87E /* LbryAppTests.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 13B07F871A680F5B00A75B9A /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */, - 13B07FC11A68108700A75B9A /* main.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 2D02E4771E0B4A5D006451C7 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 2D02E4BF1E0B4AB3006451C7 /* main.m in Sources */, - 2D02E4BC1E0B4A80006451C7 /* AppDelegate.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 2D02E48C1E0B4A5D006451C7 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 2DCD954D1E0B4F2C00145EB5 /* LbryAppTests.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 00E356F51AD99517003FC87E /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 13B07F861A680F5B00A75B9A /* LbryApp */; - targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */; - }; - 2D02E4921E0B4A5D006451C7 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 2D02E47A1E0B4A5D006451C7 /* LbryApp-tvOS */; - targetProxy = 2D02E4911E0B4A5D006451C7 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin PBXVariantGroup section */ - 13B07FB11A68108700A75B9A /* LaunchScreen.xib */ = { - isa = PBXVariantGroup; - children = ( - 13B07FB21A68108700A75B9A /* Base */, - ); - name = LaunchScreen.xib; - path = LbryApp; - sourceTree = "<group>"; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 00E356F61AD99517003FC87E /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - INFOPLIST_FILE = LbryAppTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - OTHER_LDFLAGS = ( - "-ObjC", - "-lc++", - "$(inherited)", - ); - PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; - PRODUCT_NAME = "$(TARGET_NAME)"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/LbryApp.app/LbryApp"; - }; - name = Debug; - }; - 00E356F71AD99517003FC87E /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - COPY_PHASE_STRIP = NO; - INFOPLIST_FILE = LbryAppTests/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - OTHER_LDFLAGS = ( - "-ObjC", - "-lc++", - "$(inherited)", - ); - PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; - PRODUCT_NAME = "$(TARGET_NAME)"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/LbryApp.app/LbryApp"; - }; - name = Release; - }; - 13B07F941A680F5B00A75B9A /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CURRENT_PROJECT_VERSION = 1; - DEAD_CODE_STRIPPING = NO; - INFOPLIST_FILE = LbryApp/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - OTHER_LDFLAGS = ( - "$(inherited)", - "-ObjC", - "-lc++", - ); - PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; - PRODUCT_NAME = LbryApp; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Debug; - }; - 13B07F951A680F5B00A75B9A /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CURRENT_PROJECT_VERSION = 1; - INFOPLIST_FILE = LbryApp/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - OTHER_LDFLAGS = ( - "$(inherited)", - "-ObjC", - "-lc++", - ); - PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; - PRODUCT_NAME = LbryApp; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Release; - }; - 2D02E4971E0B4A5E006451C7 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; - CLANG_ANALYZER_NONNULL = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - GCC_NO_COMMON_BLOCKS = YES; - INFOPLIST_FILE = "LbryApp-tvOS/Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - OTHER_LDFLAGS = ( - "$(inherited)", - "-ObjC", - "-lc++", - ); - PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.LbryApp-tvOS"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = appletvos; - TARGETED_DEVICE_FAMILY = 3; - TVOS_DEPLOYMENT_TARGET = 9.2; - }; - name = Debug; - }; - 2D02E4981E0B4A5E006451C7 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image"; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; - CLANG_ANALYZER_NONNULL = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_NO_COMMON_BLOCKS = YES; - INFOPLIST_FILE = "LbryApp-tvOS/Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - OTHER_LDFLAGS = ( - "$(inherited)", - "-ObjC", - "-lc++", - ); - PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.LbryApp-tvOS"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = appletvos; - TARGETED_DEVICE_FAMILY = 3; - TVOS_DEPLOYMENT_TARGET = 9.2; - }; - name = Release; - }; - 2D02E4991E0B4A5E006451C7 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CLANG_ANALYZER_NONNULL = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_TESTABILITY = YES; - GCC_NO_COMMON_BLOCKS = YES; - INFOPLIST_FILE = "LbryApp-tvOSTests/Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - OTHER_LDFLAGS = ( - "$(inherited)", - "-ObjC", - "-lc++", - ); - PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.LbryApp-tvOSTests"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = appletvos; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/LbryApp-tvOS.app/LbryApp-tvOS"; - TVOS_DEPLOYMENT_TARGET = 10.1; - }; - name = Debug; - }; - 2D02E49A1E0B4A5E006451C7 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - BUNDLE_LOADER = "$(TEST_HOST)"; - CLANG_ANALYZER_NONNULL = YES; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_NO_COMMON_BLOCKS = YES; - INFOPLIST_FILE = "LbryApp-tvOSTests/Info.plist"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - OTHER_LDFLAGS = ( - "$(inherited)", - "-ObjC", - "-lc++", - ); - PRODUCT_BUNDLE_IDENTIFIER = "com.facebook.REACT.LbryApp-tvOSTests"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = appletvos; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/LbryApp-tvOS.app/LbryApp-tvOS"; - TVOS_DEPLOYMENT_TARGET = 10.1; - }; - name = Release; - }; - 83CBBA201A601CBA00E9B192 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - }; - name = Debug; - }; - 83CBBA211A601CBA00E9B192 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = YES; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "LbryAppTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 00E356F61AD99517003FC87E /* Debug */, - 00E356F71AD99517003FC87E /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "LbryApp" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 13B07F941A680F5B00A75B9A /* Debug */, - 13B07F951A680F5B00A75B9A /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 2D02E4BA1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "LbryApp-tvOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 2D02E4971E0B4A5E006451C7 /* Debug */, - 2D02E4981E0B4A5E006451C7 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 2D02E4BB1E0B4A5E006451C7 /* Build configuration list for PBXNativeTarget "LbryApp-tvOSTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 2D02E4991E0B4A5E006451C7 /* Debug */, - 2D02E49A1E0B4A5E006451C7 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "LbryApp" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 83CBBA201A601CBA00E9B192 /* Debug */, - 83CBBA211A601CBA00E9B192 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */; -} diff --git a/ios/LbryApp.xcodeproj/xcshareddata/xcschemes/LbryApp-tvOS.xcscheme b/ios/LbryApp.xcodeproj/xcshareddata/xcschemes/LbryApp-tvOS.xcscheme deleted file mode 100644 index c322e95..0000000 --- a/ios/LbryApp.xcodeproj/xcshareddata/xcschemes/LbryApp-tvOS.xcscheme +++ /dev/null @@ -1,129 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<Scheme - LastUpgradeVersion = "0940" - version = "1.3"> - <BuildAction - parallelizeBuildables = "NO" - buildImplicitDependencies = "YES"> - <BuildActionEntries> - <BuildActionEntry - buildForTesting = "YES" - buildForRunning = "YES" - buildForProfiling = "YES" - buildForArchiving = "YES" - buildForAnalyzing = "YES"> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "2D2A28121D9B038B00D4039D" - BuildableName = "libReact.a" - BlueprintName = "React-tvOS" - ReferencedContainer = "container:../node_modules/react-native/React/React.xcodeproj"> - </BuildableReference> - </BuildActionEntry> - <BuildActionEntry - buildForTesting = "YES" - buildForRunning = "YES" - buildForProfiling = "YES" - buildForArchiving = "YES" - buildForAnalyzing = "YES"> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "2D02E47A1E0B4A5D006451C7" - BuildableName = "LbryApp-tvOS.app" - BlueprintName = "LbryApp-tvOS" - ReferencedContainer = "container:LbryApp.xcodeproj"> - </BuildableReference> - </BuildActionEntry> - <BuildActionEntry - buildForTesting = "YES" - buildForRunning = "YES" - buildForProfiling = "NO" - buildForArchiving = "NO" - buildForAnalyzing = "YES"> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "2D02E48F1E0B4A5D006451C7" - BuildableName = "LbryApp-tvOSTests.xctest" - BlueprintName = "LbryApp-tvOSTests" - ReferencedContainer = "container:LbryApp.xcodeproj"> - </BuildableReference> - </BuildActionEntry> - </BuildActionEntries> - </BuildAction> - <TestAction - buildConfiguration = "Debug" - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - shouldUseLaunchSchemeArgsEnv = "YES"> - <Testables> - <TestableReference - skipped = "NO"> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "2D02E48F1E0B4A5D006451C7" - BuildableName = "LbryApp-tvOSTests.xctest" - BlueprintName = "LbryApp-tvOSTests" - ReferencedContainer = "container:LbryApp.xcodeproj"> - </BuildableReference> - </TestableReference> - </Testables> - <MacroExpansion> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "2D02E47A1E0B4A5D006451C7" - BuildableName = "LbryApp-tvOS.app" - BlueprintName = "LbryApp-tvOS" - ReferencedContainer = "container:LbryApp.xcodeproj"> - </BuildableReference> - </MacroExpansion> - <AdditionalOptions> - </AdditionalOptions> - </TestAction> - <LaunchAction - buildConfiguration = "Debug" - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - launchStyle = "0" - useCustomWorkingDirectory = "NO" - ignoresPersistentStateOnLaunch = "NO" - debugDocumentVersioning = "YES" - debugServiceExtension = "internal" - allowLocationSimulation = "YES"> - <BuildableProductRunnable - runnableDebuggingMode = "0"> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "2D02E47A1E0B4A5D006451C7" - BuildableName = "LbryApp-tvOS.app" - BlueprintName = "LbryApp-tvOS" - ReferencedContainer = "container:LbryApp.xcodeproj"> - </BuildableReference> - </BuildableProductRunnable> - <AdditionalOptions> - </AdditionalOptions> - </LaunchAction> - <ProfileAction - buildConfiguration = "Release" - shouldUseLaunchSchemeArgsEnv = "YES" - savedToolIdentifier = "" - useCustomWorkingDirectory = "NO" - debugDocumentVersioning = "YES"> - <BuildableProductRunnable - runnableDebuggingMode = "0"> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "2D02E47A1E0B4A5D006451C7" - BuildableName = "LbryApp-tvOS.app" - BlueprintName = "LbryApp-tvOS" - ReferencedContainer = "container:LbryApp.xcodeproj"> - </BuildableReference> - </BuildableProductRunnable> - </ProfileAction> - <AnalyzeAction - buildConfiguration = "Debug"> - </AnalyzeAction> - <ArchiveAction - buildConfiguration = "Release" - revealArchiveInOrganizer = "YES"> - </ArchiveAction> -</Scheme> diff --git a/ios/LbryApp.xcodeproj/xcshareddata/xcschemes/LbryApp.xcscheme b/ios/LbryApp.xcodeproj/xcshareddata/xcschemes/LbryApp.xcscheme deleted file mode 100644 index d3785d0..0000000 --- a/ios/LbryApp.xcodeproj/xcshareddata/xcschemes/LbryApp.xcscheme +++ /dev/null @@ -1,129 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<Scheme - LastUpgradeVersion = "0940" - version = "1.3"> - <BuildAction - parallelizeBuildables = "NO" - buildImplicitDependencies = "YES"> - <BuildActionEntries> - <BuildActionEntry - buildForTesting = "YES" - buildForRunning = "YES" - buildForProfiling = "YES" - buildForArchiving = "YES" - buildForAnalyzing = "YES"> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "83CBBA2D1A601D0E00E9B192" - BuildableName = "libReact.a" - BlueprintName = "React" - ReferencedContainer = "container:../node_modules/react-native/React/React.xcodeproj"> - </BuildableReference> - </BuildActionEntry> - <BuildActionEntry - buildForTesting = "YES" - buildForRunning = "YES" - buildForProfiling = "YES" - buildForArchiving = "YES" - buildForAnalyzing = "YES"> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "13B07F861A680F5B00A75B9A" - BuildableName = "LbryApp.app" - BlueprintName = "LbryApp" - ReferencedContainer = "container:LbryApp.xcodeproj"> - </BuildableReference> - </BuildActionEntry> - <BuildActionEntry - buildForTesting = "YES" - buildForRunning = "YES" - buildForProfiling = "NO" - buildForArchiving = "NO" - buildForAnalyzing = "YES"> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "00E356ED1AD99517003FC87E" - BuildableName = "LbryAppTests.xctest" - BlueprintName = "LbryAppTests" - ReferencedContainer = "container:LbryApp.xcodeproj"> - </BuildableReference> - </BuildActionEntry> - </BuildActionEntries> - </BuildAction> - <TestAction - buildConfiguration = "Debug" - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - shouldUseLaunchSchemeArgsEnv = "YES"> - <Testables> - <TestableReference - skipped = "NO"> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "00E356ED1AD99517003FC87E" - BuildableName = "LbryAppTests.xctest" - BlueprintName = "LbryAppTests" - ReferencedContainer = "container:LbryApp.xcodeproj"> - </BuildableReference> - </TestableReference> - </Testables> - <MacroExpansion> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "13B07F861A680F5B00A75B9A" - BuildableName = "LbryApp.app" - BlueprintName = "LbryApp" - ReferencedContainer = "container:LbryApp.xcodeproj"> - </BuildableReference> - </MacroExpansion> - <AdditionalOptions> - </AdditionalOptions> - </TestAction> - <LaunchAction - buildConfiguration = "Debug" - selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" - selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" - launchStyle = "0" - useCustomWorkingDirectory = "NO" - ignoresPersistentStateOnLaunch = "NO" - debugDocumentVersioning = "YES" - debugServiceExtension = "internal" - allowLocationSimulation = "YES"> - <BuildableProductRunnable - runnableDebuggingMode = "0"> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "13B07F861A680F5B00A75B9A" - BuildableName = "LbryApp.app" - BlueprintName = "LbryApp" - ReferencedContainer = "container:LbryApp.xcodeproj"> - </BuildableReference> - </BuildableProductRunnable> - <AdditionalOptions> - </AdditionalOptions> - </LaunchAction> - <ProfileAction - buildConfiguration = "Release" - shouldUseLaunchSchemeArgsEnv = "YES" - savedToolIdentifier = "" - useCustomWorkingDirectory = "NO" - debugDocumentVersioning = "YES"> - <BuildableProductRunnable - runnableDebuggingMode = "0"> - <BuildableReference - BuildableIdentifier = "primary" - BlueprintIdentifier = "13B07F861A680F5B00A75B9A" - BuildableName = "LbryApp.app" - BlueprintName = "LbryApp" - ReferencedContainer = "container:LbryApp.xcodeproj"> - </BuildableReference> - </BuildableProductRunnable> - </ProfileAction> - <AnalyzeAction - buildConfiguration = "Debug"> - </AnalyzeAction> - <ArchiveAction - buildConfiguration = "Release" - revealArchiveInOrganizer = "YES"> - </ArchiveAction> -</Scheme> diff --git a/ios/LbryApp/AppDelegate.h b/ios/LbryApp/AppDelegate.h deleted file mode 100644 index 2726d5e..0000000 --- a/ios/LbryApp/AppDelegate.h +++ /dev/null @@ -1,15 +0,0 @@ -/** - * 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 <React/RCTBridgeDelegate.h> -#import <UIKit/UIKit.h> - -@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate> - -@property (nonatomic, strong) UIWindow *window; - -@end diff --git a/ios/LbryApp/AppDelegate.m b/ios/LbryApp/AppDelegate.m deleted file mode 100644 index 030d148..0000000 --- a/ios/LbryApp/AppDelegate.m +++ /dev/null @@ -1,42 +0,0 @@ -/** - * 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 "AppDelegate.h" - -#import <React/RCTBridge.h> -#import <React/RCTBundleURLProvider.h> -#import <React/RCTRootView.h> - -@implementation AppDelegate - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions -{ - RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions]; - RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge - moduleName:@"LbryApp" - initialProperties:nil]; - - rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; - - self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; - UIViewController *rootViewController = [UIViewController new]; - rootViewController.view = rootView; - self.window.rootViewController = rootViewController; - [self.window makeKeyAndVisible]; - return YES; -} - -- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge -{ -#if DEBUG - return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; -#else - return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; -#endif -} - -@end diff --git a/ios/LbryApp/Base.lproj/LaunchScreen.xib b/ios/LbryApp/Base.lproj/LaunchScreen.xib deleted file mode 100644 index ef5e981..0000000 --- a/ios/LbryApp/Base.lproj/LaunchScreen.xib +++ /dev/null @@ -1,42 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="7702" systemVersion="14D136" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES"> - <dependencies> - <deployment identifier="iOS"/> - <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7701"/> - <capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/> - </dependencies> - <objects> - <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/> - <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> - <view contentMode="scaleToFill" id="iN0-l3-epB"> - <rect key="frame" x="0.0" y="0.0" width="480" height="480"/> - <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> - <subviews> - <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Powered by React Native" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye"> - <rect key="frame" x="20" y="439" width="441" height="21"/> - <fontDescription key="fontDescription" type="system" pointSize="17"/> - <color key="textColor" cocoaTouchSystemColor="darkTextColor"/> - <nil key="highlightedColor"/> - </label> - <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="LbryApp" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX"> - <rect key="frame" x="20" y="140" width="441" height="43"/> - <fontDescription key="fontDescription" type="boldSystem" pointSize="36"/> - <color key="textColor" cocoaTouchSystemColor="darkTextColor"/> - <nil key="highlightedColor"/> - </label> - </subviews> - <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/> - <constraints> - <constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC"/> - <constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/> - <constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/> - <constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0"/> - <constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/> - <constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/> - </constraints> - <nil key="simulatedStatusBarMetrics"/> - <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/> - <point key="canvasLocation" x="548" y="455"/> - </view> - </objects> -</document> diff --git a/ios/LbryApp/Images.xcassets/AppIcon.appiconset/Contents.json b/ios/LbryApp/Images.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 118c98f..0000000 --- a/ios/LbryApp/Images.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "60x60", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "60x60", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/ios/LbryApp/Images.xcassets/Contents.json b/ios/LbryApp/Images.xcassets/Contents.json deleted file mode 100644 index 2d92bd5..0000000 --- a/ios/LbryApp/Images.xcassets/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/ios/LbryApp/Info.plist b/ios/LbryApp/Info.plist deleted file mode 100644 index 80128ad..0000000 --- a/ios/LbryApp/Info.plist +++ /dev/null @@ -1,57 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>CFBundleDevelopmentRegion</key> - <string>en</string> - <key>CFBundleDisplayName</key> - <string>LbryApp</string> - <key>CFBundleExecutable</key> - <string>$(EXECUTABLE_NAME)</string> - <key>CFBundleIdentifier</key> - <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundleName</key> - <string>$(PRODUCT_NAME)</string> - <key>CFBundlePackageType</key> - <string>APPL</string> - <key>CFBundleShortVersionString</key> - <string>1.0</string> - <key>CFBundleSignature</key> - <string>????</string> - <key>CFBundleVersion</key> - <string>1</string> - <key>LSRequiresIPhoneOS</key> - <true/> - <key>NSAppTransportSecurity</key> - <dict> - <key>NSAllowsArbitraryLoads</key> - <true/> - <key>NSExceptionDomains</key> - <dict> - <key>localhost</key> - <dict> - <key>NSExceptionAllowsInsecureHTTPLoads</key> - <true/> - </dict> - </dict> - </dict> - <key>NSLocationWhenInUseUsageDescription</key> - <string></string> - <key>UILaunchStoryboardName</key> - <string>LaunchScreen</string> - <key>UIRequiredDeviceCapabilities</key> - <array> - <string>armv7</string> - </array> - <key>UISupportedInterfaceOrientations</key> - <array> - <string>UIInterfaceOrientationPortrait</string> - <string>UIInterfaceOrientationLandscapeLeft</string> - <string>UIInterfaceOrientationLandscapeRight</string> - </array> - <key>UIViewControllerBasedStatusBarAppearance</key> - <false/> -</dict> -</plist> diff --git a/ios/LbryApp/main.m b/ios/LbryApp/main.m deleted file mode 100644 index c316cf8..0000000 --- a/ios/LbryApp/main.m +++ /dev/null @@ -1,16 +0,0 @@ -/** - * 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 <UIKit/UIKit.h> - -#import "AppDelegate.h" - -int main(int argc, char * argv[]) { - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } -} diff --git a/ios/LbryAppTests/Info.plist b/ios/LbryAppTests/Info.plist deleted file mode 100644 index ba72822..0000000 --- a/ios/LbryAppTests/Info.plist +++ /dev/null @@ -1,24 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>CFBundleDevelopmentRegion</key> - <string>en</string> - <key>CFBundleExecutable</key> - <string>$(EXECUTABLE_NAME)</string> - <key>CFBundleIdentifier</key> - <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundleName</key> - <string>$(PRODUCT_NAME)</string> - <key>CFBundlePackageType</key> - <string>BNDL</string> - <key>CFBundleShortVersionString</key> - <string>1.0</string> - <key>CFBundleSignature</key> - <string>????</string> - <key>CFBundleVersion</key> - <string>1</string> -</dict> -</plist> diff --git a/ios/LbryAppTests/LbryAppTests.m b/ios/LbryAppTests/LbryAppTests.m deleted file mode 100644 index cecbde9..0000000 --- a/ios/LbryAppTests/LbryAppTests.m +++ /dev/null @@ -1,72 +0,0 @@ -/** - * 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 <UIKit/UIKit.h> -#import <XCTest/XCTest.h> - -#import <React/RCTLog.h> -#import <React/RCTRootView.h> - -#define TIMEOUT_SECONDS 600 -#define TEXT_TO_LOOK_FOR @"Welcome to React" - -@interface LbryAppTests : XCTestCase - -@end - -@implementation LbryAppTests - -- (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test -{ - if (test(view)) { - return YES; - } - for (UIView *subview in [view subviews]) { - if ([self findSubviewInView:subview matching:test]) { - return YES; - } - } - return NO; -} - -- (void)testRendersWelcomeScreen -{ - UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController]; - NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; - BOOL foundElement = NO; - - __block NSString *redboxError = nil; -#ifdef DEBUG - RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) { - if (level >= RCTLogLevelError) { - redboxError = message; - } - }); -#endif - - while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { - [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; - [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; - - foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) { - if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { - return YES; - } - return NO; - }]; - } - -#ifdef DEBUG - RCTSetLogFunction(RCTDefaultLogFunction); -#endif - - XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); - XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); -} - - -@end diff --git a/ios/Podfile b/ios/Podfile deleted file mode 100644 index fda3e9b..0000000 --- a/ios/Podfile +++ /dev/null @@ -1,53 +0,0 @@ -platform :ios, '9.0' -require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules' - -target 'LbryApp' do - # Pods for LbryAndroid - pod 'FBLazyVector', :path => "../node_modules/react-native/Libraries/FBLazyVector" - pod 'FBReactNativeSpec', :path => "../node_modules/react-native/Libraries/FBReactNativeSpec" - pod 'RCTRequired', :path => "../node_modules/react-native/Libraries/RCTRequired" - pod 'RCTTypeSafety', :path => "../node_modules/react-native/Libraries/TypeSafety" - pod 'React', :path => '../node_modules/react-native/' - pod 'React-Core', :path => '../node_modules/react-native/' - pod 'React-CoreModules', :path => '../node_modules/react-native/React/CoreModules' - pod 'React-Core/DevSupport', :path => '../node_modules/react-native/' - pod 'React-RCTActionSheet', :path => '../node_modules/react-native/Libraries/ActionSheetIOS' - pod 'React-RCTAnimation', :path => '../node_modules/react-native/Libraries/NativeAnimation' - pod 'React-RCTBlob', :path => '../node_modules/react-native/Libraries/Blob' - pod 'React-RCTImage', :path => '../node_modules/react-native/Libraries/Image' - pod 'React-RCTLinking', :path => '../node_modules/react-native/Libraries/LinkingIOS' - pod 'React-RCTNetwork', :path => '../node_modules/react-native/Libraries/Network' - pod 'React-RCTSettings', :path => '../node_modules/react-native/Libraries/Settings' - pod 'React-RCTText', :path => '../node_modules/react-native/Libraries/Text' - pod 'React-RCTVibration', :path => '../node_modules/react-native/Libraries/Vibration' - pod 'React-Core/RCTWebSocket', :path => '../node_modules/react-native/' - - pod 'React-cxxreact', :path => '../node_modules/react-native/ReactCommon/cxxreact' - pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi' - pod 'React-jsiexecutor', :path => '../node_modules/react-native/ReactCommon/jsiexecutor' - pod 'React-jsinspector', :path => '../node_modules/react-native/ReactCommon/jsinspector' - pod 'ReactCommon/jscallinvoker', :path => "../node_modules/react-native/ReactCommon" - pod 'ReactCommon/turbomodule/core', :path => "../node_modules/react-native/ReactCommon" - pod 'Yoga', :path => '../node_modules/react-native/ReactCommon/yoga' - - pod 'DoubleConversion', :podspec => '../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec' - pod 'glog', :podspec => '../node_modules/react-native/third-party-podspecs/glog.podspec' - pod 'Folly', :podspec => '../node_modules/react-native/third-party-podspecs/Folly.podspec' - - target 'LbryAndroidTests' do - inherit! :search_paths - # Pods for testing - end - - use_native_modules! -end - -target 'LbryAndroid-tvOS' do - # Pods for LbryAndroid-tvOS - - target 'LbryAndroid-tvOSTests' do - inherit! :search_paths - # Pods for testing - end - -end diff --git a/lbry-app-strings.json b/lbry-app-strings.json deleted file mode 100644 index 47795ae..0000000 --- a/lbry-app-strings.json +++ /dev/null @@ -1,326 +0,0 @@ -{ - "Please wait while we get some things ready...": "Please wait while we get some things ready...", - "Welcome to LBRY.": "Welcome to LBRY.", - "LBRY is a community-controlled content platform where you can find and publish videos, music, books, and more.": "LBRY is a community-controlled content platform where you can find and publish videos, music, books, and more.", - "Continue": "Continue", - "Setup account": "Setup account", - "A lbry.tv account allows you to earn rewards, backup your wallet, and keep everything in sync.": "A lbry.tv account allows you to earn rewards, backup your wallet, and keep everything in sync.", - "This information is disclosed only to LBRY, Inc. and not to the LBRY network.": "This information is disclosed only to LBRY, Inc. and not to the LBRY network.", - "No, thanks": "No, thanks", - "Use LBRY": "Use LBRY", - "Are you sure?": "Are you sure?", - "Without an account, you will not receive rewards, sync and backup services, or security updates.": "Without an account, you will not receive rewards, sync and backup services, or security updates.", - "I understand that by uninstalling LBRY I will lose any balances or published content with no recovery option if it is not backed up manually (see wallet page)": "I understand that by uninstalling LBRY I will lose any balances or published content with no recovery option if it is not backed up manually (see wallet page)", - "Starting up": "Starting up", - "Connecting": "Connecting", - "Testing network": "Testing network", - "Waiting for name resolution": "Waiting for name resolution", - "Search movies, music, and more": "Search movies, music, and more", - "Your Tags": "Your Tags", - "Trending": "Trending", - "Customize": "Customize", - "Sign In": "Sign In", - "SIGN IN": "SIGN IN", - "Find content": "Find content", - "Subscriptions": "Subscriptions", - "All Content": "All Content", - "Your content": "Your content", - "Channels": "Channels", - "Library": "Library", - "Publishes": "Publishes", - "New Publish": "New Publish", - "Wallet": "Wallet", - "Rewards": "Rewards", - "Settings": "Settings", - "About": "About", - "All tags you follow": "All tags you follow", - "More tags you follow": "More tags you follow", - "FREE": "FREE", - "more": "more", - "You have not created a channel.\nStart now by creating a new channel!": "You have not created a channel.\nStart now by creating a new channel!", - "Create a channel": "Create a channel", - "CONTENT": "CONTENT", - "ABOUT": "ABOUT", - "Follow": "Follow", - "No content to display at this time. Please check back later.": "No content to display at this time. Please check back later.", - "New": "New", - "Share": "Share", - "Tip": "Tip", - "Report": "Report", - "Fetching cost info...": "Fetching cost info...", - "Play": "Play", - "Connecting...": "Connecting...", - "Related Content": "Related Content", - "Loading...": "Loading...", - "Content Freedom": "Content Freedom", - "LBRY is a free, open, and community-run digital marketplace. It is a decentralized peer-to-peer content distribution platform for creators to upload and share content, and earn LBRY credits for their effort. Users will be able to find a wide selection of videos, music, ebooks and other digital content they are interested in.": "LBRY is a free, open, and community-run digital marketplace. It is a decentralized peer-to-peer content distribution platform for creators to upload and share content, and earn LBRY credits for their effort. Users will be able to find a wide selection of videos, music, ebooks and other digital content they are interested in.", - "What is LBRY?": "What is LBRY?", - "Android App Basics": "Android App Basics", - "Frequently Asked Questions": "Frequently Asked Questions", - "Get Social": "Get Social", - "You can interact with the LBRY team and members of the community on Discord, Facebook, Instagram, Twitter or Reddit.": "You can interact with the LBRY team and members of the community on Discord, Facebook, Instagram, Twitter or Reddit.", - "App info": "App info", - "App version": "App version", - "LBRY SDK": "LBRY SDK", - "Platform": "Platform", - "Installation ID": "Installation ID", - "Logs": "Logs", - "Send log": "Send log", - "Account Recommended": "Account Recommended", - "Without an account, you assume all responsibility for securing your wallet and LBRY data.": "Without an account, you assume all responsibility for securing your wallet and LBRY data.", - "Skip Account": "Skip Account", - "Sign Up": "Sign Up", - "Blockchain Sync": "Blockchain Sync", - "Catching up with the blockchain (%progress%%)": "Catching up with the blockchain (%progress%%)", - "Network Loading": "Network Loading", - "Initializing LBRY service": "Initializing LBRY service", - "%amount% available credits": "%amount% available credits", - "LBRY credits allow you to purchase content, publish content, and influence the network.": "LBRY credits allow you to purchase content, publish content, and influence the network.", - "You get credits for free for providing an email address and taking other basic actions.": "You get credits for free for providing an email address and taking other basic actions.", - "Learn more": "Learn more", - "Not interested": "Not interested", - "Get started": "Get started", - "Get %amount% free credits after creating an account.": "Get %amount% free credits after creating an account.", - "Balance": "Balance", - "You currently have": "You currently have", - "Receive Credits": "Receive Credits", - "Use this wallet address to receive credits sent by another user (or yourself).": "Use this wallet address to receive credits sent by another user (or yourself).", - "Get new address": "Get new address", - "You can generate a new address at any time, and any previous addresses will continue to work. Using multiple addresses can be helpful for keeping track of incoming payments from multiple sources.": "You can generate a new address at any time, and any previous addresses will continue to work. Using multiple addresses can be helpful for keeping track of incoming payments from multiple sources.", - "Send Credits": "Send Credits", - "Recipient address": "Recipient address", - "Amount": "Amount", - "Send": "Send", - "Recent Transactions": "Recent Transactions", - "View All": "View All", - "Looks like you don't have any recent transactions.": "Looks like you don't have any recent transactions.", - "Wallet Sync": "Wallet Sync", - "Sync status": "Sync status", - "Off": "Off", - "Manual backup": "Manual backup", - "Sync FAQ": "Sync FAQ", - "Fetching transactions...": "Fetching transactions...", - "Anonymous": "Anonymous", - "Delete": "Delete", - "Title": "Title", - "Channel": "Channel", - "Deposit": "Deposit", - "This LBC remains yours. It is a deposit to reserve the name and can be undone at any time.": "This LBC remains yours. It is a deposit to reserve the name and can be undone at any time.", - "Show optional fields": "Show optional fields", - "Cancel": "Cancel", - "Create": "Create", - "Channel creation requires credits.": "Channel creation requires credits.", - "Tap here to get some for free.": "Tap here to get some for free.", - "%balance% available": "%balance% available", - "Bal: %balance%": "Bal: %balance%", - "Send a tip": "Send a tip", - "Record": "Record", - "Take a photo": "Take a photo", - "Upload a file": "Upload a file", - "Please wait while we load your videos...": "Please wait while we load your videos...", - "Description": "Description", - "Tags": "Tags", - "Price": "Price", - "Your content will be free. Press the toggle to set a price.": "Your content will be free. Press the toggle to set a price.", - "Content address": "Content address", - "The address where people can find your content (ex. lbry://myvideo). ": "The address where people can find your content (ex. lbry://myvideo). ", - "This LBC remains yours and the deposit can be undone at any time.": "This LBC remains yours and the deposit can be undone at any time.", - "Show extra fields": "Show extra fields", - "Publish": "Publish", - "Publishing requires credits.": "Publishing requires credits.", - "Search for more tags": "Search for more tags", - "Mature tags": "Mature tags", - "Publish anonymously": "Publish anonymously", - "Create a channel...": "Create a channel...", - "Uploading thumbnail...": "Uploading thumbnail...", - "Channel name": "Channel name", - "Deposit cannot be higher than your balance": "Deposit cannot be higher than your balance", - "There are no results to display for \"%query%\". Please try a different search term.": "There are no results to display for \"%query%\". Please try a different search term.", - "Nothing here. Publish something!": "Nothing here. Publish something!", - "Explore content for this tag": "Explore content for this tag", - "URL does not include name.": "URL does not include name.", - "Loading decentralized data...": "Loading decentralized data...", - "View": "View", - "Additional Options": "Additional Options", - "Language": "Language", - "English": "English", - "Chinese": "Chinese", - "French": "French", - "German": "German", - "Japanese": "Japanese", - "Russian": "Russian", - "Spanish": "Spanish", - "Indonesian": "Indonesian", - "Italian": "Italian", - "Dutch": "Dutch", - "Turkish": "Turkish", - "Polish": "Polish", - "Malay": "Malay", - "Portuguese": "Portuguese", - "Vietnamese": "Vietnamese", - "Thai": "Thai", - "Arabic": "Arabic", - "Czech": "Czech", - "Croatian": "Croatian", - "Cambodian": "Cambodian", - "Korean": "Korean", - "Norwegian": "Norwegian", - "Romanian": "Romanian", - "Hindi": "Hindi", - "Greek": "Greek", - "License": "License", - "None": "None", - "Public Domain": "Public Domain", - "Copyrighted...": "Copyrighted...", - "Other...": "Other...", - "Hide extra fields": "Hide extra fields", - "Download": "Download", - "%progress%% complete": "%progress%% complete", - "Email": "Email", - "Please provide an email address.": "Please provide an email address.", - "An email has been sent to": "An email has been sent to", - "Please click the link in the message to complete signing in.": "Please click the link in the message to complete signing in.", - "Resend": "Resend", - "Edit": "Edit", - "Your email address was successfully verified.": "Your email address was successfully verified.", - "password": "password", - "Please enter a password to secure your account and wallet.": "Please enter a password to secure your account and wallet.", - "Retrieving your account information...": "Retrieving your account information...", - "Please enter the password you used to secure your wallet.": "Please enter the password you used to secure your wallet.", - "Note: for wallet security purposes, LBRY is unable to reset your password.": "Note: for wallet security purposes, LBRY is unable to reset your password.", - "On": "On", - "Connected email": "Connected email", - "Address copied": "Address copied", - "Unlocking account": "Unlocking account", - "Decrypting wallet": "Decrypting wallet", - "used": "used", - "Stats": "Stats", - "Channels you follow": "Channels you follow", - "Suggested": "Suggested", - "ALL": "ALL", - "Customize your tags": "Customize your tags", - "Done": "Done", - "Unfollow": "Unfollow", - "This content is Not Safe For Work. To view adult content, please change your Settings.": "This content is Not Safe For Work. To view adult content, please change your Settings.", - "No views": "No views", - "%view% views": "%view% views", - "Content": "Content", - "Enable background media playback": "Enable background media playback", - "Enable this option to play audio or video in the background when the app is suspended.": "Enable this option to play audio or video in the background when the app is suspended.", - "Choose language": "Choose language", - "Use device language": "Use device language", - "Gujarati": "Gujarati", - "Show mature content": "Show mature content", - "Notifications": "Notifications", - "Choose the notifications you would like to receive.": "Choose the notifications you would like to receive.", - "Content Interests": "Content Interests", - "Search": "Search", - "Show URL suggestions": "Show URL suggestions", - "Other": "Other", - "Keep the SDK background service running after closing the app": "Keep the SDK background service running after closing the app", - "Enable this option for quicker app launch and to keep the synchronisation with the blockchain up to date.": "Enable this option for quicker app launch and to keep the synchronisation with the blockchain up to date.", - "There's nothing here yet.\nPlease check back later.": "There's nothing here yet.\nPlease check back later.", - "%follower% followers": "%follower% followers", - "Are you sure you want to tip %amount% credits": "Are you sure you want to tip %amount% credits", - "Send tip": "Send tip", - "No": "No", - "Yes": "Yes", - "History": "History", - "/wallet": "/wallet", - "Are you sure you want to tip %amount% credit": "Are you sure you want to tip %amount% credit", - "Enjoying LBRY?": "Enjoying LBRY?", - "Are you enjoying your experience with the LBRY app? You can leave a review for us on the Play Store.": "Are you enjoying your experience with the LBRY app? You can leave a review for us on the Play Store.", - "Never ask again": "Never ask again", - "Maybe later": "Maybe later", - "Rate app": "Rate app", - "This will appear as a tip for %content%, which will boost its ability to be discovered while active.": "This will appear as a tip for %content%, which will boost its ability to be discovered while active.", - "Learn more.": "Learn more.", - "Send a tip to %channel%": "Send a tip to %channel%", - "The transaction URL could not be opened": "The transaction URL could not be opened", - "Show All": "Show All", - "Fetching rewards...": "Fetching rewards...", - "Custom Code": "Custom Code", - "Are you a supermodel or rockstar that received a custom reward code? Claim it here.": "Are you a supermodel or rockstar that received a custom reward code? Claim it here.", - "Redeem": "Redeem", - "Please confirm that you want to use LBRY without creating an account.": "Please confirm that you want to use LBRY without creating an account.", - "You sent %amount% LBC as a tip, Mahalo!": "You sent %amount% LBC as a tip, Mahalo!", - "%follower% follower": "%follower% follower", - "Authenticating": "Authenticating", - "Waiting for authentication": "Waiting for authentication", - "Delete file": "Delete file", - "Are you sure you want to remove this file from your device?": "Are you sure you want to remove this file from your device?", - "Following": "Following", - "Update mailing preferences": "Update mailing preferences", - "Please confirm you want to tip %amount% credits": "Please confirm you want to tip %amount% credits", - "Send Tip": "Send Tip", - "You do not have any\ndownloaded content on this device.": "You do not have any\ndownloaded content on this device.", - "%view% view": "%view% view", - "No channel name after @.": "No channel name after @.", - "Loading transactions...": "Loading transactions...", - "Pending": "Pending", - "Phone Number": "Phone Number", - "Please provide a phone number to prevent fraud.": "Please provide a phone number to prevent fraud.", - "Send verification text": "Send verification text", - "Open": "Open", - "for": "for", - "Everyone": "Everyone", - "Suggested channels": "Suggested channels", - "You might also like": "You might also like", - "Publish something new": "Publish something new", - "Filter for": "Filter for", - "Tags you follow": "Tags you follow", - "Sort content by": "Sort content by", - "Trending content": "Trending content", - "New content": "New content", - "Top content": "Top content", - "Top": "Top", - "Past week": "Past week", - "It looks like you have not\npublished any content to LBRY yet.": "It looks like you have not\npublished any content to LBRY yet.", - "Stop": "Stop", - "Unsupported Content": "Unsupported Content", - "all tags you follow": "all tags you follow", - "Send LBC": "Send LBC", - "from": "from", - "This file cannot be displayed in the LBRY app.": "This file cannot be displayed in the LBRY app.", - "Please press the Play button.": "Please press the Play button.", - "Stop download": "Stop download", - "Are you sure you want to stop downloading this file?": "Are you sure you want to stop downloading this file?", - "The download will stop momentarily. You do not need to wait to discover something else.": "The download will stop momentarily. You do not need to wait to discover something else.", - "Connection Failure": "Connection Failure", - "We could not establish a connection to the SDK. Your data connection may be preventing LBRY from connecting. Contact hello@lbry.com if you think this is a software bug.": "We could not establish a connection to the SDK. Your data connection may be preventing LBRY from connecting. Contact hello@lbry.com if you think this is a software bug.", - "%num% block behind": "%num% block behind", - "Delete files": "Delete files", - "Are you sure you want to delete the selected content?": "Are you sure you want to delete the selected content?", - "We could not find any videos on your device. Take a photo or record a video to get started.": "We could not find any videos on your device. Take a photo or record a video to get started.", - "You have already published to the specified content address. Please enter a new address.": "You have already published to the specified content address. Please enter a new address.", - "Camera": "Camera", - "Please grant access to make use of your camera": "Please grant access to make use of your camera", - "OK": "OK", - "Audio": "Audio", - "Please grant access to record audio": "Please grant access to record audio", - "Camera not authorized": "Camera not authorized", - "There's nothing at this location.": "There's nothing at this location.", - "Publish something here": "Publish something here", - "This content cannot be viewed at this time. Please try again in a bit.": "This content cannot be viewed at this time. Please try again in a bit.", - "Download file": "Download file", - "Save %title% (%size%) to your device": "Save %title% (%size%) to your device", - "Save \"%title%\" (%size%) to your device": "Save \"%title%\" (%size%) to your device", - "Find Channels to follow": "Find Channels to follow", - "LBRY works better if you follow at least 5 creators you like. Sign in to show creators you follow if you already have an account.": "LBRY works better if you follow at least 5 creators you like. Sign in to show creators you follow if you already have an account.", - "%remaining% more...": "%remaining% more...", - "Did you know that you can earn free credits worth up to %amount%?": "Did you know that you can earn free credits worth up to %amount%?", - "SHOW ME": "SHOW ME", - "Convert credits to USD on Bittrex": "Convert credits to USD on Bittrex", - "You also have": "You also have", - "in tips": "in tips", - "Earn more tips by uploading cool videos": "Earn more tips by uploading cool videos", - "You staked": "You staked", - "in your publishes": "in your publishes", - "in your supports": "in your supports", - "Your wallet is not currently synced with lbry.tv. You are responsible for backing up your wallet.": "Your wallet is not currently synced with lbry.tv. You are responsible for backing up your wallet.", - "A backup of your wallet is synced with lbry.tv": "A backup of your wallet is synced with lbry.tv", - "What does this mean?": "What does this mean?", - "LBRY credits allow you to publish or purchase content.": "LBRY credits allow you to publish or purchase content.", - "You can obtain free credits worth %amount% after you provide an email address.": "You can obtain free credits worth %amount% after you provide an email address.", - "up to": "up to" -} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..e61e763 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,10421 @@ +{ + "name": "LBRYApp", + "version": "0.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", + "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/core": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.5.4.tgz", + "integrity": "sha512-+DaeBEpYq6b2+ZmHx3tHspC+ZRflrvLqwfv8E3hNr5LVQoyBnL8RPKSBCg+rK2W2My9PWlujBiqd0ZPsR9Q6zQ==", + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.5.0", + "@babel/helpers": "^7.5.4", + "@babel/parser": "^7.5.0", + "@babel/template": "^7.4.4", + "@babel/traverse": "^7.5.0", + "@babel/types": "^7.5.0", + "convert-source-map": "^1.1.0", + "debug": "^4.1.0", + "json5": "^2.1.0", + "lodash": "^4.17.11", + "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==", + "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==" + } + } + }, + "@babel/generator": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.5.0.tgz", + "integrity": "sha512-1TTVrt7J9rcG5PMjvO7VEG3FrEoEJNHxumRq66GemPmzboLWtIjjcJgk8rokuAS7IiRSpgVSu5Vb9lc99iJkOA==", + "requires": { + "@babel/types": "^7.5.0", + "jsesc": "^2.5.1", + "lodash": "^4.17.11", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz", + "integrity": "sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q==", + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz", + "integrity": "sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w==", + "requires": { + "@babel/helper-explode-assignable-expression": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-builder-react-jsx": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.3.0.tgz", + "integrity": "sha512-MjA9KgwCuPEkQd9ncSXvSyJ5y+j2sICHyrI0M3L+6fnS4wMSNDc1ARXsbTfbb2cXHn17VisSnU/sHFTCxVxSMw==", + "requires": { + "@babel/types": "^7.3.0", + "esutils": "^2.0.0" + } + }, + "@babel/helper-call-delegate": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.4.4.tgz", + "integrity": "sha512-l79boDFJ8S1c5hvQvG+rc+wHw6IuH7YldmRKsYtpbawsxURu/paVy57FZMomGK22/JckepaikOkY0MoAmdyOlQ==", + "requires": { + "@babel/helper-hoist-variables": "^7.4.4", + "@babel/traverse": "^7.4.4", + "@babel/types": "^7.4.4" + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.5.0.tgz", + "integrity": "sha512-EAoMc3hE5vE5LNhMqDOwB1usHvmRjCDAnH8CD4PVkX9/Yr3W/tcz8xE8QvdZxfsFBDICwZnF2UTHIqslRpvxmA==", + "requires": { + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-member-expression-to-functions": "^7.0.0", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.4.4", + "@babel/helper-split-export-declaration": "^7.4.4" + } + }, + "@babel/helper-define-map": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.4.4.tgz", + "integrity": "sha512-IX3Ln8gLhZpSuqHJSnTNBWGDE9kdkTEWl21A/K7PQ00tseBwbqCHTvNLHSBd9M0R5rER4h5Rsvj9vw0R5SieBg==", + "requires": { + "@babel/helper-function-name": "^7.1.0", + "@babel/types": "^7.4.4", + "lodash": "^4.17.11" + } + }, + "@babel/helper-explode-assignable-expression": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz", + "integrity": "sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA==", + "requires": { + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-function-name": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", + "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", + "requires": { + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", + "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.4.4.tgz", + "integrity": "sha512-VYk2/H/BnYbZDDg39hr3t2kKyifAm1W6zHRfhx8jGjIHpQEBv9dry7oQ2f3+J703TLu69nYdxsovl0XYfcnK4w==", + "requires": { + "@babel/types": "^7.4.4" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz", + "integrity": "sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg==", + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-module-imports": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz", + "integrity": "sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A==", + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-module-transforms": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.4.4.tgz", + "integrity": "sha512-3Z1yp8TVQf+B4ynN7WoHPKS8EkdTbgAEy0nU0rs/1Kw4pDgmvYH3rz3aI11KgxKCba2cn7N+tqzV1mY2HMN96w==", + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-simple-access": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.4.4", + "@babel/template": "^7.4.4", + "@babel/types": "^7.4.4", + "lodash": "^4.17.11" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz", + "integrity": "sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g==", + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz", + "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==" + }, + "@babel/helper-regex": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.4.4.tgz", + "integrity": "sha512-Y5nuB/kESmR3tKjU8Nkn1wMGEx1tjJX076HBMeL3XLQCu6vA/YRzuTW0bbb+qRnXvQGn+d6Rx953yffl8vEy7Q==", + "requires": { + "lodash": "^4.17.11" + } + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz", + "integrity": "sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-wrap-function": "^7.1.0", + "@babel/template": "^7.1.0", + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-replace-supers": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.4.4.tgz", + "integrity": "sha512-04xGEnd+s01nY1l15EuMS1rfKktNF+1CkKmHoErDppjAAZL+IUBZpzT748x262HF7fibaQPhbvWUl5HeSt1EXg==", + "requires": { + "@babel/helper-member-expression-to-functions": "^7.0.0", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/traverse": "^7.4.4", + "@babel/types": "^7.4.4" + } + }, + "@babel/helper-simple-access": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz", + "integrity": "sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w==", + "requires": { + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", + "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", + "requires": { + "@babel/types": "^7.4.4" + } + }, + "@babel/helper-wrap-function": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz", + "integrity": "sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ==", + "requires": { + "@babel/helper-function-name": "^7.1.0", + "@babel/template": "^7.1.0", + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.2.0" + } + }, + "@babel/helpers": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.5.4.tgz", + "integrity": "sha512-6LJ6xwUEJP51w0sIgKyfvFMJvIb9mWAfohJp0+m6eHJigkFdcH8duZ1sfhn0ltJRzwUIT/yqqhdSfRpCpL7oow==", + "requires": { + "@babel/template": "^7.4.4", + "@babel/traverse": "^7.5.0", + "@babel/types": "^7.5.0" + } + }, + "@babel/highlight": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", + "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.5.0.tgz", + "integrity": "sha512-I5nW8AhGpOXGCCNYGc+p7ExQIBxRFnS2fd/d862bNOKvmoEPjYPcfIjsfdy0ujagYOIYPczKgD9l3FsgTkAzKA==" + }, + "@babel/plugin-external-helpers": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-external-helpers/-/plugin-external-helpers-7.2.0.tgz", + "integrity": "sha512-QFmtcCShFkyAsNtdCM3lJPmRe1iB+vPZymlB4LnDIKEBj2yKQLQKtoxXxJ8ePT5fwMl4QGg303p4mB0UsSI2/g==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-proposal-class-properties": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.5.0.tgz", + "integrity": "sha512-9L/JfPCT+kShiiTTzcnBJ8cOwdKVmlC1RcCf9F0F9tERVrM4iWtWnXtjWCRqNm2la2BxO1MPArWNsU9zsSJWSQ==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.5.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-proposal-export-default-from": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.5.2.tgz", + "integrity": "sha512-wr9Itk05L1/wyyZKVEmXWCdcsp/e185WUNl6AfYZeEKYaUPPvHXRDqO5K1VH7/UamYqGJowFRuCv30aDYZawsg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-export-default-from": "^7.2.0" + } + }, + "@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.4.4.tgz", + "integrity": "sha512-Amph7Epui1Dh/xxUxS2+K22/MUi6+6JVTvy3P58tja3B6yKTSjwwx0/d83rF7551D6PVSSoplQb8GCwqec7HRw==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.2.0" + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.4.tgz", + "integrity": "sha512-KCx0z3y7y8ipZUMAEEJOyNi11lMb/FOPUjjB113tfowgw0c16EGYos7worCKBcUAh2oG+OBnoUhsnTSoLpV9uA==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-object-rest-spread": "^7.2.0" + } + }, + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz", + "integrity": "sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.2.0" + } + }, + "@babel/plugin-proposal-optional-chaining": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.2.0.tgz", + "integrity": "sha512-ea3Q6edZC/55wEBVZAEz42v528VulyO0eir+7uky/sT4XRcdkWJcFi1aPtitTlwUzGnECWJNExWww1SStt+yWw==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-optional-chaining": "^7.2.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.2.0.tgz", + "integrity": "sha512-UxYaGXYQ7rrKJS/PxIKRkv3exi05oH7rokBAsmCSsCxz1sVPZ7Fu6FzKoGgUvmY+0YgSkYHgUoCh5R5bCNBQlw==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-dynamic-import": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.2.0.tgz", + "integrity": "sha512-mVxuJ0YroI/h/tbFTPGZR8cv6ai+STMKNBq0f8hFxsxWjl94qqhsb+wXbpNMDPU3cfR1TIsVFzU3nXyZMqyK4w==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-export-default-from": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.2.0.tgz", + "integrity": "sha512-c7nqUnNST97BWPtoe+Ssi+fJukc9P9/JMZ71IOMNQWza2E+Psrd46N6AEvtw6pqK+gt7ChjXyrw4SPDO79f3Lw==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-flow": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.2.0.tgz", + "integrity": "sha512-r6YMuZDWLtLlu0kqIim5o/3TNRAlWb073HwT3e2nKf9I8IIvOggPrnILYPsrrKilmn/mYEMCf/Z07w3yQJF6dg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-jsx": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.2.0.tgz", + "integrity": "sha512-VyN4QANJkRW6lDBmENzRszvZf3/4AXaj9YR7GwrWeeN9tEBPuXbmDYVU9bYBN0D70zCWVwUy0HWq2553VCb6Hw==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.2.0.tgz", + "integrity": "sha512-lRCEaKE+LTxDQtgbYajI04ddt6WW0WJq57xqkAZ+s11h4YgfRHhVA/Y2VhfPzzFD4qeLHWg32DMp9HooY4Kqlg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz", + "integrity": "sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz", + "integrity": "sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.2.0.tgz", + "integrity": "sha512-HtGCtvp5Uq/jH/WNUPkK6b7rufnCPLLlDAFN7cmACoIjaOOiXxUt3SswU5loHqrhtqTsa/WoLQ1OQ1AGuZqaWA==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-typescript": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.3.3.tgz", + "integrity": "sha512-dGwbSMA1YhVS8+31CnPR7LB4pcbrzcV99wQzby4uAfrkZPYZlQ7ImwdpzLqi6Z6IL02b8IAL379CaMwo0x5Lag==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz", + "integrity": "sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.5.0.tgz", + "integrity": "sha512-mqvkzwIGkq0bEF1zLRRiTdjfomZJDV33AH3oQzHVGkI2VzEmXLpKKOBvEVaFZBJdN0XTyH38s9j/Kiqr68dggg==", + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-remap-async-to-generator": "^7.1.0" + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz", + "integrity": "sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.4.4.tgz", + "integrity": "sha512-jkTUyWZcTrwxu5DD4rWz6rDB5Cjdmgz6z7M7RLXOJyCUkFBawssDGcGh8M/0FTSB87avyJI1HsTwUXp9nKA1PA==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "lodash": "^4.17.11" + } + }, + "@babel/plugin-transform-classes": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.4.4.tgz", + "integrity": "sha512-/e44eFLImEGIpL9qPxSRat13I5QNRgBLu2hOQJCF7VLy/otSM/sypV1+XaIw5+502RX/+6YaSAPmldk+nhHDPw==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-define-map": "^7.4.4", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.4.4", + "@babel/helper-split-export-declaration": "^7.4.4", + "globals": "^11.1.0" + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz", + "integrity": "sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.5.0.tgz", + "integrity": "sha512-YbYgbd3TryYYLGyC7ZR+Tq8H/+bCmwoaxHfJHupom5ECstzbRLTch6gOQbhEY9Z4hiCNHEURgq06ykFv9JZ/QQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz", + "integrity": "sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A==", + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-flow-strip-types": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.4.4.tgz", + "integrity": "sha512-WyVedfeEIILYEaWGAUWzVNyqG4sfsNooMhXWsu/YzOvVGcsnPb5PguysjJqI3t3qiaYj0BR8T2f5njdjTGe44Q==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-flow": "^7.2.0" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.4.tgz", + "integrity": "sha512-9T/5Dlr14Z9TIEXLXkt8T1DU7F24cbhwhMNUziN3hB1AXoZcdzPcTiKGRn/6iOymDqtTKWnr/BtRKN9JwbKtdQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.4.4.tgz", + "integrity": "sha512-iU9pv7U+2jC9ANQkKeNF6DrPy4GBa4NWQtl6dHB4Pb3izX2JOEvDTFarlNsBj/63ZEzNNIAMs3Qw4fNCcSOXJA==", + "requires": { + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-literals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz", + "integrity": "sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-member-expression-literals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.2.0.tgz", + "integrity": "sha512-HiU3zKkSU6scTidmnFJ0bMX8hz5ixC93b4MHMiYebmk2lUVNGOboPsqQvx5LzooihijUoLR/v7Nc1rbBtnc7FA==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.5.0.tgz", + "integrity": "sha512-xmHq0B+ytyrWJvQTc5OWAC4ii6Dhr0s22STOoydokG51JjWhyYo5mRPXoi+ZmtHQhZZwuXNN+GG5jy5UZZJxIQ==", + "requires": { + "@babel/helper-module-transforms": "^7.4.4", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-simple-access": "^7.1.0", + "babel-plugin-dynamic-import-node": "^2.3.0" + } + }, + "@babel/plugin-transform-object-assign": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.2.0.tgz", + "integrity": "sha512-nmE55cZBPFgUktbF2OuoZgPRadfxosLOpSgzEPYotKSls9J4pEPcembi8r78RU37Rph6UApCpNmsQA4QMWK9Ng==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.2.0.tgz", + "integrity": "sha512-VMyhPYZISFZAqAPVkiYb7dUe2AsVi2/wCT5+wZdsNO31FojQJa9ns40hzZ6U9f50Jlq4w6qwzdBB2uwqZ00ebg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.1.0" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.4.tgz", + "integrity": "sha512-oMh5DUO1V63nZcu/ZVLQFqiihBGo4OpxJxR1otF50GMeCLiRx5nUdtokd+u9SuVJrvvuIh9OosRFPP4pIPnwmw==", + "requires": { + "@babel/helper-call-delegate": "^7.4.4", + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-property-literals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.2.0.tgz", + "integrity": "sha512-9q7Dbk4RhgcLp8ebduOpCbtjh7C0itoLYHXd9ueASKAG/is5PQtMR5VJGka9NKqGhYEGn5ITahd4h9QeBMylWQ==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-react-display-name": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.2.0.tgz", + "integrity": "sha512-Htf/tPa5haZvRMiNSQSFifK12gtr/8vwfr+A9y69uF0QcU77AVu4K7MiHEkTxF7lQoHOL0F9ErqgfNEAKgXj7A==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-react-jsx": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.3.0.tgz", + "integrity": "sha512-a/+aRb7R06WcKvQLOu4/TpjKOdvVEKRLWFpKcNuHhiREPgGRB4TQJxq07+EZLS8LFVYpfq1a5lDUnuMdcCpBKg==", + "requires": { + "@babel/helper-builder-react-jsx": "^7.3.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.2.0" + } + }, + "@babel/plugin-transform-react-jsx-source": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.5.0.tgz", + "integrity": "sha512-58Q+Jsy4IDCZx7kqEZuSDdam/1oW8OdDX8f+Loo6xyxdfg1yF0GE2XNJQSTZCaMol93+FBzpWiPEwtbMloAcPg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.2.0" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.5.tgz", + "integrity": "sha512-gBKRh5qAaCWntnd09S8QC7r3auLCqq5DI6O0DlfoyDjslSBVqBibrMdsqO+Uhmx3+BlOmE/Kw1HFxmGbv0N9dA==", + "requires": { + "regenerator-transform": "^0.14.0" + } + }, + "@babel/plugin-transform-runtime": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.5.0.tgz", + "integrity": "sha512-LmPIZOAgTLl+86gR9KjLXex6P/lRz1fWEjTz6V6QZMmKie51ja3tvzdwORqhHc4RWR8TcZ5pClpRWs0mlaA2ng==", + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "resolve": "^1.8.1", + "semver": "^5.5.1" + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz", + "integrity": "sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-spread": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz", + "integrity": "sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz", + "integrity": "sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.0.0" + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.4.4.tgz", + "integrity": "sha512-mQrEC4TWkhLN0z8ygIvEL9ZEToPhG5K7KDW3pzGqOfIGZ28Jb0POUkeWcoz8HnHvhFy6dwAT1j8OzqN8s804+g==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-typescript": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.5.2.tgz", + "integrity": "sha512-r4zJOMbKY5puETm8+cIpaa0RQZG/sSASW1u0pj8qYklcERgVIbxVbP2wyJA7zI1//h7lEagQmXi9IL9iI5rfsA==", + "requires": { + "@babel/helper-create-class-features-plugin": "^7.5.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-typescript": "^7.2.0" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.4.4.tgz", + "integrity": "sha512-il+/XdNw01i93+M9J9u4T7/e/Ue/vWfNZE4IRUQjplu2Mqb/AFTDimkw2tdEdSH50wuQXZAbXSql0UphQke+vA==", + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.4.4", + "regexpu-core": "^4.5.4" + } + }, + "@babel/register": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/register/-/register-7.4.4.tgz", + "integrity": "sha512-sn51H88GRa00+ZoMqCVgOphmswG4b7mhf9VOB0LUBAieykq2GnRFerlN+JQkO/ntT7wz4jaHNSRPg9IdMPEUkA==", + "requires": { + "core-js": "^3.0.0", + "find-cache-dir": "^2.0.0", + "lodash": "^4.17.11", + "mkdirp": "^0.5.1", + "pirates": "^4.0.0", + "source-map-support": "^0.5.9" + }, + "dependencies": { + "core-js": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.1.4.tgz", + "integrity": "sha512-YNZN8lt82XIMLnLirj9MhKDFZHalwzzrL9YLt6eb0T5D0EDl4IQ90IGkua8mHbnxNrkj1d8hbdizMc0Qmg1WnQ==" + } + } + }, + "@babel/runtime": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.5.4.tgz", + "integrity": "sha512-Na84uwyImZZc3FKf4aUF1tysApzwf3p2yuFBIyBfbzT5glzKTdvYI4KVW4kcgjrzoGUjC7w3YyCHcJKaRxsr2Q==", + "requires": { + "regenerator-runtime": "^0.13.2" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz", + "integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==" + } + } + }, + "@babel/template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", + "integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==", + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.4.4", + "@babel/types": "^7.4.4" + } + }, + "@babel/traverse": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.5.0.tgz", + "integrity": "sha512-SnA9aLbyOCcnnbQEGwdfBggnc142h/rbqqsXcaATj2hZcegCl903pUD/lfpsNBlBSuWow/YDfRyJuWi2EPR5cg==", + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.5.0", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.4.4", + "@babel/parser": "^7.5.0", + "@babel/types": "^7.5.0", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.11" + }, + "dependencies": { + "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" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "@babel/types": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.5.0.tgz", + "integrity": "sha512-UFpDVqRABKsW01bvw7/wSUe56uy6RXM5+VJibVVAybDGxEW25jdwiFJEf7ASvSaC7sN7rbE/l3cLp2izav+CtQ==", + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.11", + "to-fast-properties": "^2.0.0" + } + }, + "@expo/vector-icons": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@expo/vector-icons/-/vector-icons-8.1.0.tgz", + "integrity": "sha512-/aKa+bgp3LIcTKJWPLRYTYCL0wf/Fr4dwl4XYmNGFG092pK3McuBoDk3b8tWyZnXBnEiqnMLd6Qwr+LEX6Jc0Q==", + "requires": { + "lodash": "^4.17.4", + "react-native-vector-icons": "6.0.0" + }, + "dependencies": { + "react-native-vector-icons": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/react-native-vector-icons/-/react-native-vector-icons-6.0.0.tgz", + "integrity": "sha512-uF3oWb3TV42uXi2apVOZHw9oy9Nr5SXDVwOo1umQWo/yYCrDzXyVfq14DzezgEbJ9jfc/yghBelj0agkXmOKlg==", + "requires": { + "lodash": "^4.0.0", + "prop-types": "^15.6.2", + "yargs": "^8.0.2" + } + } + } + }, + "@react-native-community/async-storage": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@react-native-community/async-storage/-/async-storage-1.5.1.tgz", + "integrity": "sha512-Ssfx2uLYPnsuqIvDCuUOEZT6jh5AVy0U0mr2eHxNO2Syor1nfOrR/n4hTOFcBWc1wamDTGCqo+UHJpxURVXd2Q==" + }, + "@react-native-community/cli": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-1.10.0.tgz", + "integrity": "sha512-48tIWsMKhwbDsKhe5tYcsspsAy7aR3J/yRjdsVh+M2qkKEASe66Xbhiw5RK2nhfzd1IdOdlIxNMiC+9uad6NMQ==", + "requires": { + "chalk": "^1.1.1", + "commander": "^2.19.0", + "compression": "^1.7.1", + "connect": "^3.6.5", + "denodeify": "^1.2.1", + "envinfo": "^5.7.0", + "errorhandler": "^1.5.0", + "escape-string-regexp": "^1.0.5", + "execa": "^1.0.0", + "fs-extra": "^7.0.1", + "glob": "^7.1.1", + "graceful-fs": "^4.1.3", + "inquirer": "^3.0.6", + "lodash": "^4.17.5", + "metro": "^0.51.0", + "metro-config": "^0.51.0", + "metro-core": "^0.51.0", + "metro-memory-fs": "^0.51.0", + "metro-react-native-babel-transformer": "^0.51.0", + "mime": "^1.3.4", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "morgan": "^1.9.0", + "node-fetch": "^2.2.0", + "node-notifier": "^5.2.1", + "opn": "^3.0.2", + "plist": "^3.0.0", + "semver": "^5.0.3", + "serve-static": "^1.13.1", + "shell-quote": "1.6.1", + "slash": "^2.0.0", + "ws": "^1.1.0", + "xcode": "^2.0.0", + "xmldoc": "^0.4.0" + }, + "dependencies": { + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "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" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.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==", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "requires": { + "pump": "^3.0.0" + } + } + } + }, + "@react-navigation/core": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-3.4.2.tgz", + "integrity": "sha512-7G+iDzLSTeOUU4vVZeRZKJ+Bd7ds7ZxYNqZcB8i0KlBeQEQfR74Ounfu/p0KIEq2RiNnaE3QT7WVP3C87sebzw==", + "requires": { + "hoist-non-react-statics": "^3.3.0", + "path-to-regexp": "^1.7.0", + "query-string": "^6.4.2", + "react-is": "^16.8.6" + }, + "dependencies": { + "hoist-non-react-statics": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.0.tgz", + "integrity": "sha512-0XsbTXxgiaCDYDIWFcwkmerZPSwywfUqYmwT4jzewKTQSWoE6FCMoUVOeBJWK3E/CrWbxRG3m5GzY4lnIwGRBA==", + "requires": { + "react-is": "^16.7.0" + } + } + } + }, + "@react-navigation/native": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-3.5.0.tgz", + "integrity": "sha512-TmGOis++ejEXG3sqNJhCSKqB0/qLu3FQgDtO959qpqif36R/diR8SQwJqeSdofoEiK3CepdhFlTCeHdS1/+MsQ==", + "requires": { + "hoist-non-react-statics": "^3.0.1", + "react-native-safe-area-view": "^0.14.1", + "react-native-screens": "^1.0.0 || ^1.0.0-alpha" + }, + "dependencies": { + "hoist-non-react-statics": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.0.tgz", + "integrity": "sha512-0XsbTXxgiaCDYDIWFcwkmerZPSwywfUqYmwT4jzewKTQSWoE6FCMoUVOeBJWK3E/CrWbxRG3m5GzY4lnIwGRBA==", + "requires": { + "react-is": "^16.7.0" + } + }, + "react-native-safe-area-view": { + "version": "0.14.6", + "resolved": "https://registry.npmjs.org/react-native-safe-area-view/-/react-native-safe-area-view-0.14.6.tgz", + "integrity": "sha512-dbzuvaeHFV1VBpyMaC0gtJ2BqFt6ls/405A0t78YN1sXiTrVr3ki86Ysct8mzifWqLdvWzcWagE5wfMtdxnqoA==", + "requires": { + "hoist-non-react-statics": "^2.3.1" + }, + "dependencies": { + "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==" + } + } + } + } + }, + "@samverschueren/stream-to-observable": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz", + "integrity": "sha512-MI4Xx6LHs4Webyvi6EbspgyAb4D2Q2VtnCQ1blOJcoLS6mVa8lNN2rkIy1CVxfTUpoyIbCTkXES1rLXztFD1lg==", + "dev": true, + "requires": { + "any-observable": "^0.3.0" + } + }, + "@types/node": { + "version": "8.10.51", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.51.tgz", + "integrity": "sha512-cArrlJp3Yv6IyFT/DYe+rlO8o3SIHraALbBW/+CcCYW/a9QucpLI+n2p4sRxAvl2O35TiecpX2heSZtJjvEO+Q==", + "dev": true + }, + "absolute-path": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/absolute-path/-/absolute-path-0.0.0.tgz", + "integrity": "sha1-p4di+9rftSl76ZsV01p4Wy8JW/c=" + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "acorn": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.2.0.tgz", + "integrity": "sha512-8oe72N3WPMjA+2zVG71Ia0nXZ8DpQH+QyyHO+p06jT8eg8FGG3FbcUIi8KziHlAfheJQZeoqbvq1mQSQHXKYLw==", + "dev": true + }, + "acorn-jsx": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz", + "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==", + "dev": true + }, + "ajv": { + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.1.tgz", + "integrity": "sha512-w1YQaVGNC6t2UCPjEawK/vo/dG8OOrVtUmhBT1uJJYxbl5kU2Tj3v6LGqBcsysN1yhuCStJCCA3GqdvKY8sqXQ==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/ansi/-/ansi-0.3.1.tgz", + "integrity": "sha1-DELU+xcWDVqa8eSEus4cZpIsGyE=" + }, + "ansi-align": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", + "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", + "dev": true, + "requires": { + "string-width": "^2.0.0" + } + }, + "ansi-colors": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", + "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==", + "requires": { + "ansi-wrap": "^0.1.0" + } + }, + "ansi-cyan": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-cyan/-/ansi-cyan-0.1.1.tgz", + "integrity": "sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM=", + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==" + }, + "ansi-gray": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", + "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=", + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-red": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz", + "integrity": "sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw=", + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + }, + "ansi-wrap": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", + "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=" + }, + "any-observable": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/any-observable/-/any-observable-0.3.0.tgz", + "integrity": "sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog==", + "dev": true + }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "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=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "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=", + "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=", + "requires": { + "is-extendable": "^0.1.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=", + "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=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "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=", + "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=", + "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==", + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "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==" + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "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=", + "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=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "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=", + "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==", + "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==", + "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==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "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=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "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" + } + } + } + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arr-diff": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", + "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "requires": { + "arr-flatten": "^1.0.1" + } + }, + "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==" + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" + }, + "array-filter": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz", + "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=" + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, + "array-includes": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", + "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.7.0" + } + }, + "array-map": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", + "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=" + }, + "array-reduce": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz", + "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=" + }, + "array-slice": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", + "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=" + }, + "array-unique": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", + "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=" + }, + "art": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/art/-/art-0.10.3.tgz", + "integrity": "sha512-HXwbdofRTiJT6qZX/FnchtldzJjS3vkLJxQilc3Xj+ma2MXjY4UAyQ0ls1XZYVnDvVIBiFZbC6QsvtW86TD6tQ==" + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=" + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, + "async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", + "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", + "requires": { + "lodash": "^4.17.11" + } + }, + "async-limiter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "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==" + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "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": { + "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" + } + }, + "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 + } + } + }, + "babel-eslint": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.0.2.tgz", + "integrity": "sha512-UdsurWPtgiPgpJ06ryUnuaSXC2s0WoSZnQmEpbAH65XZSdwowgN5MvyP7e88nW07FYXv72erVtpBkxyDVKhH1Q==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "eslint-scope": "3.7.1", + "eslint-visitor-keys": "^1.0.0" + }, + "dependencies": { + "eslint-scope": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", + "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.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-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-dynamic-import-node": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz", + "integrity": "sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==", + "requires": { + "object.assign": "^4.1.0" + } + }, + "babel-plugin-module-resolver": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-3.2.0.tgz", + "integrity": "sha512-tjR0GvSndzPew/Iayf4uICWZqjBwnlMWjSx6brryfQ81F9rxBVqwDJtFCV8oOs0+vJeefK9TmdZtkIFdFe1UnA==", + "dev": true, + "requires": { + "find-babel-config": "^1.1.0", + "glob": "^7.1.2", + "pkg-up": "^2.0.0", + "reselect": "^3.0.1", + "resolve": "^1.4.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-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-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-flow": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz", + "integrity": "sha1-TDqyCiryaqIM0lmVw5jE63AxDI0=", + "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": "7.0.0-beta.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-7.0.0-beta.0.tgz", + "integrity": "sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ==" + }, + "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-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-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" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + }, + "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" + } + } + } + }, + "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-flow-comments": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-comments/-/babel-plugin-transform-flow-comments-6.22.0.tgz", + "integrity": "sha1-jZSREy8rSKvQZW+Wwg87vW/BdSk=", + "dev": true, + "requires": { + "babel-plugin-syntax-flow": "^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" + }, + "dependencies": { + "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" + } + } + } + }, + "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-env": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz", + "integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==", + "dev": true, + "requires": { + "babel-plugin-check-es2015-constants": "^6.22.0", + "babel-plugin-syntax-trailing-function-commas": "^6.22.0", + "babel-plugin-transform-async-to-generator": "^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.23.0", + "babel-plugin-transform-es2015-classes": "^6.23.0", + "babel-plugin-transform-es2015-computed-properties": "^6.22.0", + "babel-plugin-transform-es2015-destructuring": "^6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", + "babel-plugin-transform-es2015-for-of": "^6.23.0", + "babel-plugin-transform-es2015-function-name": "^6.22.0", + "babel-plugin-transform-es2015-literals": "^6.22.0", + "babel-plugin-transform-es2015-modules-amd": "^6.22.0", + "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-umd": "^6.23.0", + "babel-plugin-transform-es2015-object-super": "^6.22.0", + "babel-plugin-transform-es2015-parameters": "^6.23.0", + "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", + "babel-plugin-transform-es2015-spread": "^6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", + "babel-plugin-transform-es2015-template-literals": "^6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", + "babel-plugin-transform-exponentiation-operator": "^6.22.0", + "babel-plugin-transform-regenerator": "^6.22.0", + "browserslist": "^3.2.6", + "invariant": "^2.2.2", + "semver": "^5.3.0" + }, + "dependencies": { + "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-preset-fbjs": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-fbjs/-/babel-preset-fbjs-3.2.0.tgz", + "integrity": "sha512-5Jo+JeWiVz2wHUUyAlvb/sSYnXNig9r+HqGAOSfh5Fzxp7SnAaR/tEGRJ1ZX7C77kfk82658w6R5Z+uPATTD9g==", + "requires": { + "@babel/plugin-proposal-class-properties": "^7.0.0", + "@babel/plugin-proposal-object-rest-spread": "^7.0.0", + "@babel/plugin-syntax-class-properties": "^7.0.0", + "@babel/plugin-syntax-flow": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.0.0", + "@babel/plugin-syntax-object-rest-spread": "^7.0.0", + "@babel/plugin-transform-arrow-functions": "^7.0.0", + "@babel/plugin-transform-block-scoped-functions": "^7.0.0", + "@babel/plugin-transform-block-scoping": "^7.0.0", + "@babel/plugin-transform-classes": "^7.0.0", + "@babel/plugin-transform-computed-properties": "^7.0.0", + "@babel/plugin-transform-destructuring": "^7.0.0", + "@babel/plugin-transform-flow-strip-types": "^7.0.0", + "@babel/plugin-transform-for-of": "^7.0.0", + "@babel/plugin-transform-function-name": "^7.0.0", + "@babel/plugin-transform-literals": "^7.0.0", + "@babel/plugin-transform-member-expression-literals": "^7.0.0", + "@babel/plugin-transform-modules-commonjs": "^7.0.0", + "@babel/plugin-transform-object-super": "^7.0.0", + "@babel/plugin-transform-parameters": "^7.0.0", + "@babel/plugin-transform-property-literals": "^7.0.0", + "@babel/plugin-transform-react-display-name": "^7.0.0", + "@babel/plugin-transform-react-jsx": "^7.0.0", + "@babel/plugin-transform-shorthand-properties": "^7.0.0", + "@babel/plugin-transform-spread": "^7.0.0", + "@babel/plugin-transform-template-literals": "^7.0.0", + "babel-plugin-syntax-trailing-function-commas": "^7.0.0-beta.0" + } + }, + "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" + }, + "dependencies": { + "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-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-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" + }, + "dependencies": { + "globals": { + "version": "9.18.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", + "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "dev": true + } + } + }, + "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" + }, + "dependencies": { + "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 + } + } + }, + "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=" + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "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=", + "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==", + "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==", + "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==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + } + } + }, + "base-64": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/base-64/-/base-64-0.1.0.tgz", + "integrity": "sha1-eAqZyE59YAJgNhURxId2E78k9rs=" + }, + "base64-js": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==" + }, + "basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "requires": { + "safe-buffer": "5.1.2" + } + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "big-integer": { + "version": "1.6.44", + "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.44.tgz", + "integrity": "sha512-7MzElZPTyJ2fNvBkPxtFQ2fWIkVmuzw41+BZHSzpEq3ymB2MfeKp1+yXl/tS75xCx+WnyV+yb0kp+K1C3UNwmQ==" + }, + "boxen": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", + "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", + "dev": true, + "requires": { + "ansi-align": "^2.0.0", + "camelcase": "^4.0.0", + "chalk": "^2.0.1", + "cli-boxes": "^1.0.0", + "string-width": "^2.0.0", + "term-size": "^1.2.0", + "widest-line": "^2.0.0" + } + }, + "bplist-creator": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.0.7.tgz", + "integrity": "sha1-N98VNgkoJLh8QvlXsBNEEXNyrkU=", + "requires": { + "stream-buffers": "~2.2.0" + } + }, + "bplist-parser": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.1.1.tgz", + "integrity": "sha1-1g1dzCDLptx+HymbNdPh+V2vuuY=", + "requires": { + "big-integer": "^1.6.7" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", + "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "requires": { + "expand-range": "^1.8.1", + "preserve": "^0.2.0", + "repeat-element": "^1.1.2" + } + }, + "browserslist": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", + "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30000844", + "electron-to-chromium": "^1.3.47" + } + }, + "bser": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.0.tgz", + "integrity": "sha512-8zsjWrQkkBoLK6uxASk1nJ2SKv97ltiGDo6A3wA0/yRPz+CwmEyDo0hUrhIuukG2JHpAl3bvFIixw2/3Hi0DOg==", + "requires": { + "node-int64": "^0.4.0" + } + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" + }, + "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==" + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "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" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + } + } + }, + "caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "requires": { + "callsites": "^2.0.0" + } + }, + "caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "requires": { + "caller-callsite": "^2.0.0" + } + }, + "callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=" + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" + }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "dev": true, + "requires": { + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" + }, + "dependencies": { + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "dev": true + } + } + }, + "caniuse-lite": { + "version": "1.0.30000983", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000983.tgz", + "integrity": "sha512-/llD1bZ6qwNkt41AsvjsmwNOoA4ZB+8iqmf5LVyeSXuBODT/hAMFNVOh84NdUzoiYiSKqo5vQ3ZzeYHSi/olDQ==", + "dev": true + }, + "capture-exit": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-1.2.0.tgz", + "integrity": "sha1-HF/MSJ/QqwDU8ax64QcuMXP7q28=", + "requires": { + "rsvp": "^3.3.3" + } + }, + "capture-stack-trace": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz", + "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "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" + }, + "dependencies": { + "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" + } + }, + "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" + } + } + } + }, + "chardet": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", + "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=" + }, + "ci-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "dev": true + }, + "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==", + "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=", + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + } + } + }, + "cli-boxes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", + "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=", + "dev": true + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "cli-truncate": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz", + "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=", + "dev": true, + "requires": { + "slice-ansi": "0.0.4", + "string-width": "^1.0.1" + }, + "dependencies": { + "slice-ansi": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", + "dev": true + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" + }, + "cliui": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", + "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wrap-ansi": "^2.0.0" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "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=" + }, + "color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==" + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" + }, + "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==" + }, + "compressible": { + "version": "2.0.17", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.17.tgz", + "integrity": "sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw==", + "requires": { + "mime-db": ">= 1.40.0 < 2" + } + }, + "compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "requires": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "configstore": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", + "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", + "dev": true, + "requires": { + "dot-prop": "^4.1.0", + "graceful-fs": "^4.1.2", + "make-dir": "^1.0.0", + "unique-string": "^1.0.0", + "write-file-atomic": "^2.0.0", + "xdg-basedir": "^3.0.0" + }, + "dependencies": { + "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" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "write-file-atomic": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", + "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + } + } + }, + "connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "requires": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + } + }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "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==", + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" + }, + "core-js": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz", + "integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==" + }, + "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": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + }, + "dependencies": { + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + } + } + }, + "create-error-class": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", + "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", + "dev": true, + "requires": { + "capture-stack-trace": "^1.0.0" + } + }, + "create-react-class": { + "version": "15.6.3", + "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.6.3.tgz", + "integrity": "sha512-M+/3Q6E6DLO6Yx3OwrWjwHBnvfXXYA7W+dFjt/ZDBemHO1DDZhsalX/NUtnTYclN6GfnBDRh4qRHjcDHmlJBJg==", + "requires": { + "fbjs": "^0.8.9", + "loose-envify": "^1.3.1", + "object-assign": "^4.1.1" + }, + "dependencies": { + "core-js": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", + "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=" + }, + "fbjs": { + "version": "0.8.17", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz", + "integrity": "sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=", + "requires": { + "core-js": "^1.0.0", + "isomorphic-fetch": "^2.1.1", + "loose-envify": "^1.0.0", + "object-assign": "^4.1.0", + "promise": "^7.1.1", + "setimmediate": "^1.0.5", + "ua-parser-js": "^0.7.18" + } + } + } + }, + "cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "requires": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "crypto-random-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", + "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", + "dev": true + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "requires": { + "array-find-index": "^1.0.1" + } + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "date-fns": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz", + "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==", + "dev": true + }, + "debounce": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.0.tgz", + "integrity": "sha512-mYtLl1xfZLi1m4RtQYlZgJUNQjl4ZxVnHzIR8nLLgi4q1YT8o/WM+MK/f8yfcc9s5Ir5zRaPZyZU6xs1Syoocg==" + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "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=" + }, + "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=" + }, + "dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "dev": true + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "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" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "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==", + "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==", + "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==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + }, + "denodeify": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/denodeify/-/denodeify-1.2.1.tgz", + "integrity": "sha1-OjYof1A05pnnV3kBBSwubJQlFjE=" + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dom-walk": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz", + "integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=" + }, + "dot-prop": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", + "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", + "dev": true, + "requires": { + "is-obj": "^1.0.0" + } + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" + }, + "electron": { + "version": "1.8.8", + "resolved": "https://registry.npmjs.org/electron/-/electron-1.8.8.tgz", + "integrity": "sha512-1f9zJehcTTGjrkb06o6ds+gsRq6SYhZJyxOk6zIWjRH8hVy03y/RzUDELzNas71f5vcvXmfGVvyjeEsadDI8tg==", + "dev": true, + "requires": { + "@types/node": "^8.0.24", + "electron-download": "^3.0.1", + "extract-zip": "^1.0.3" + } + }, + "electron-download": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/electron-download/-/electron-download-3.3.0.tgz", + "integrity": "sha1-LP1U1pZsAZxNSa1l++Zcyc3vaMg=", + "dev": true, + "requires": { + "debug": "^2.2.0", + "fs-extra": "^0.30.0", + "home-path": "^1.0.1", + "minimist": "^1.2.0", + "nugget": "^2.0.0", + "path-exists": "^2.1.0", + "rc": "^1.1.2", + "semver": "^5.3.0", + "sumchecker": "^1.2.0" + }, + "dependencies": { + "fs-extra": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + }, + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + } + } + }, + "electron-to-chromium": { + "version": "1.3.190", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.190.tgz", + "integrity": "sha512-cs9WnTnGBGnYYVFMCtLmr9jXNTOkdp95RLz5VhwzDn7dErg1Lnt9o4d01gEH69XlmRKWUr91Yu1hA+Hi8qW0PA==", + "dev": true + }, + "elegant-spinner": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz", + "integrity": "sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=", + "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==" + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" + }, + "encoding": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", + "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "requires": { + "iconv-lite": "~0.4.13" + } + }, + "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==", + "requires": { + "once": "^1.4.0" + } + }, + "envinfo": { + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-5.12.1.tgz", + "integrity": "sha512-pwdo0/G3CIkQ0y6PCXq4RdkvId2elvtPCJMG0konqlrfkWQbf1DWeH9K2b/cvu2YgGvPPTOnonZxXM1gikFu1w==" + }, + "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" + } + }, + "errorhandler": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/errorhandler/-/errorhandler-1.5.1.tgz", + "integrity": "sha512-rcOwbfvP1WTViVoUjcfZicVzjhjTuhSMntHh6mW3IrEiyE6mJyXvsToJUJGlGlw/2xU9P5whlWNGlIDVeCiT4A==", + "requires": { + "accepts": "~1.3.7", + "escape-html": "~1.0.3" + } + }, + "es-abstract": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", + "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-keys": "^1.0.12" + } + }, + "es-to-primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", + "dev": true + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" + }, + "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": { + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", + "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.9.1", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^4.0.3", + "eslint-utils": "^1.3.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^5.0.1", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^6.2.2", + "js-yaml": "^3.13.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.11", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^5.5.1", + "strip-ansi": "^4.0.0", + "strip-json-comments": "^2.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0" + }, + "dependencies": { + "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 + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "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" + } + }, + "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" + } + }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, + "import-fresh": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz", + "integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "inquirer": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.0.tgz", + "integrity": "sha512-scfHejeG/lVZSpvCXpsB4j/wQNPM5JC8kiElOI0OUTwmc1RTpXr4H32/HOlQHcZiYl2z2VElwuCVDRG8vFmbnA==", + "dev": true, + "requires": { + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^2.0.0", + "lodash": "^4.17.12", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" + }, + "dependencies": { + "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" + } + } + } + }, + "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 + }, + "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==", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + } + } + } + } + }, + "eslint-config-standard": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-12.0.0.tgz", + "integrity": "sha512-COUz8FnXhqFitYj4DTqHzidjIL/t4mumGZto5c7DrBpvWoie+Sn3P4sLEzUGeYhRElWuFEf8K1S1EfvD1vixCQ==", + "dev": true + }, + "eslint-config-standard-jsx": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-6.0.2.tgz", + "integrity": "sha512-D+YWAoXw+2GIdbMBRAzWwr1ZtvnSf4n4yL0gKGg7ShUOGXkSOLerI17K4F6LdQMJPNMoWYqepzQD/fKY+tXNSg==", + "dev": true + }, + "eslint-import-resolver-node": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", + "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "resolve": "^1.5.0" + } + }, + "eslint-module-utils": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.4.0.tgz", + "integrity": "sha512-14tltLm38Eu3zS+mt0KvILC3q8jyIAH518MlG+HO0p+yK885Lb1UHTY/UgR91eOyGdmxAPb+OLoW4znqIT6Ndw==", + "dev": true, + "requires": { + "debug": "^2.6.8", + "pkg-dir": "^2.0.0" + }, + "dependencies": { + "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" + } + } + } + }, + "eslint-plugin-es": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-1.4.0.tgz", + "integrity": "sha512-XfFmgFdIUDgvaRAlaXUkxrRg5JSADoRC8IkKLc/cISeR3yHVMefFHQZpcyXXEUUPHfy5DwviBcrfqlyqEwlQVw==", + "dev": true, + "requires": { + "eslint-utils": "^1.3.0", + "regexpp": "^2.0.1" + } + }, + "eslint-plugin-flowtype": { + "version": "2.50.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.50.3.tgz", + "integrity": "sha512-X+AoKVOr7Re0ko/yEXyM5SSZ0tazc6ffdIOocp2fFUlWoDt7DV0Bz99mngOkAFLOAWjqRA5jPwqUCbrx13XoxQ==", + "dev": true, + "requires": { + "lodash": "^4.17.10" + } + }, + "eslint-plugin-import": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.18.0.tgz", + "integrity": "sha512-PZpAEC4gj/6DEMMoU2Df01C5c50r7zdGIN52Yfi7CvvWaYssG7Jt5R9nFG5gmqodxNOz9vQS87xk6Izdtpdrig==", + "dev": true, + "requires": { + "array-includes": "^3.0.3", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.2", + "eslint-module-utils": "^2.4.0", + "has": "^1.0.3", + "lodash": "^4.17.11", + "minimatch": "^3.0.4", + "read-pkg-up": "^2.0.0", + "resolve": "^1.11.0" + }, + "dependencies": { + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + } + } + }, + "eslint-plugin-node": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-8.0.1.tgz", + "integrity": "sha512-ZjOjbjEi6jd82rIpFSgagv4CHWzG9xsQAVp1ZPlhRnnYxcTgENUVBvhYmkQ7GvT1QFijUSo69RaiOJKhMu6i8w==", + "dev": true, + "requires": { + "eslint-plugin-es": "^1.3.1", + "eslint-utils": "^1.3.1", + "ignore": "^5.0.2", + "minimatch": "^3.0.4", + "resolve": "^1.8.1", + "semver": "^5.5.0" + }, + "dependencies": { + "ignore": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.2.tgz", + "integrity": "sha512-vdqWBp7MyzdmHkkRWV5nY+PfGRbYbahfuvsBCh277tq+w9zyNi7h5CYJCK0kmzti9kU+O/cB7sE8HvKv6aXAKQ==", + "dev": true + } + } + }, + "eslint-plugin-promise": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz", + "integrity": "sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw==", + "dev": true + }, + "eslint-plugin-react": { + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.14.2.tgz", + "integrity": "sha512-jZdnKe3ip7FQOdjxks9XPN0pjUKZYq48OggNMd16Sk+8VXx6JOvXmlElxROCgp7tiUsTsze3jd78s/9AFJP2mA==", + "dev": true, + "requires": { + "array-includes": "^3.0.3", + "doctrine": "^2.1.0", + "has": "^1.0.3", + "jsx-ast-utils": "^2.1.0", + "object.entries": "^1.1.0", + "object.fromentries": "^2.0.0", + "object.values": "^1.1.0", + "prop-types": "^15.7.2", + "resolve": "^1.10.1" + }, + "dependencies": { + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + } + } + }, + "eslint-plugin-standard": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.0.0.tgz", + "integrity": "sha512-OwxJkR6TQiYMmt1EsNRMe5qG3GsbjlcOhbGUBY4LtavF9DsLaTcoR+j2Tdjqi23oUwKNUqX7qcn5fPStafMdlA==", + "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" + } + }, + "eslint-utils": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", + "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", + "dev": true + }, + "eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", + "dev": true + }, + "espree": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", + "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", + "dev": true, + "requires": { + "acorn": "^6.0.7", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "dev": true, + "requires": { + "estraverse": "^4.0.0" + } + }, + "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.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" + }, + "event-target-shim": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-1.1.1.tgz", + "integrity": "sha1-qG5e5r2qFgVEddp5fM3fDFVphJE=" + }, + "eventemitter3": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", + "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" + }, + "exec-sh": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.2.2.tgz", + "integrity": "sha512-FIUCJz1RbuS0FKTdaAafAByGS0CPvU3R0MeHxgtl+djzCc//F8HakL8GzmVNZanasTbTAY/3DRFA0KpVqj/eAw==", + "requires": { + "merge": "^1.2.0" + } + }, + "execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "expand-brackets": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", + "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", + "requires": { + "is-posix-bracket": "^0.1.0" + } + }, + "expand-range": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", + "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", + "requires": { + "fill-range": "^2.1.0" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "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==", + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "external-editor": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", + "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", + "requires": { + "chardet": "^0.4.0", + "iconv-lite": "^0.4.17", + "tmp": "^0.0.33" + } + }, + "extglob": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", + "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", + "requires": { + "is-extglob": "^1.0.0" + } + }, + "extract-zip": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz", + "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=", + "dev": true, + "requires": { + "concat-stream": "1.6.2", + "debug": "2.6.9", + "mkdirp": "0.5.1", + "yauzl": "2.4.1" + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "fancy-log": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz", + "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==", + "requires": { + "ansi-gray": "^0.1.1", + "color-support": "^1.1.3", + "parse-node-version": "^1.0.0", + "time-stamp": "^1.0.0" + } + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fb-watchman": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.0.tgz", + "integrity": "sha1-VOmr99+i8mzZsWNsWIwa/AXeXVg=", + "requires": { + "bser": "^2.0.0" + } + }, + "fbjs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-1.0.0.tgz", + "integrity": "sha512-MUgcMEJaFhCaF1QtWGnmq9ZDRAzECTCRAF7O6UZIlAlkTs1SasiX9aP0Iw7wfD2mJ7wDTNfg2w7u5fSCwJk1OA==", + "requires": { + "core-js": "^2.4.1", + "fbjs-css-vars": "^1.0.0", + "isomorphic-fetch": "^2.1.1", + "loose-envify": "^1.0.0", + "object-assign": "^4.1.0", + "promise": "^7.1.1", + "setimmediate": "^1.0.5", + "ua-parser-js": "^0.7.18" + } + }, + "fbjs-css-vars": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz", + "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==" + }, + "fbjs-scripts": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fbjs-scripts/-/fbjs-scripts-1.2.0.tgz", + "integrity": "sha512-5krZ8T0Bf8uky0abPoCLrfa7Orxd8UH4Qq8hRUF2RZYNMu+FmEOrBc7Ib3YVONmxTXTlLAvyrrdrVmksDb2OqQ==", + "requires": { + "@babel/core": "^7.0.0", + "ansi-colors": "^1.0.1", + "babel-preset-fbjs": "^3.2.0", + "core-js": "^2.4.1", + "cross-spawn": "^5.1.0", + "fancy-log": "^1.3.2", + "object-assign": "^4.0.1", + "plugin-error": "^0.1.2", + "semver": "^5.1.0", + "through2": "^2.0.0" + } + }, + "fd-slicer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", + "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "requires": { + "flat-cache": "^2.0.1" + } + }, + "filename-regex": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", + "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=" + }, + "fill-range": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", + "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", + "requires": { + "is-number": "^2.1.0", + "isobject": "^2.0.0", + "randomatic": "^3.0.0", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + } + }, + "find-babel-config": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/find-babel-config/-/find-babel-config-1.2.0.tgz", + "integrity": "sha512-jB2CHJeqy6a820ssiqwrKMeyC6nNdmrcgkKWJWmpoxpE8RKciYJXCcXRq1h2AzCo5I5BJeN2tkGEO3hLTuePRA==", + "dev": true, + "requires": { + "json5": "^0.5.1", + "path-exists": "^3.0.0" + }, + "dependencies": { + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true + } + } + }, + "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==", + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-parent-dir": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/find-parent-dir/-/find-parent-dir-0.3.0.tgz", + "integrity": "sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ=", + "dev": true + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "requires": { + "locate-path": "^2.0.0" + } + }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + } + }, + "flatted": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", + "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", + "dev": true + }, + "flow-babel-webpack-plugin": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flow-babel-webpack-plugin/-/flow-babel-webpack-plugin-1.1.1.tgz", + "integrity": "sha512-xgZt6sWUWMek1P+rdzJqXG9OaWCUqTfaDb1OoEVh2mXFb7Nppcd4Rm9WW9Dz4uS5T3MTe/BFVH0ZjUX8Oxh1JQ==", + "dev": true, + "requires": { + "babel-plugin-transform-flow-comments": "^6.17.0", + "flow-bin": ">=0.44.2 <1", + "lodash.merge": "^4.6.0" + } + }, + "flow-bin": { + "version": "0.102.0", + "resolved": "https://registry.npmjs.org/flow-bin/-/flow-bin-0.102.0.tgz", + "integrity": "sha512-mYon6noeLO0Q5SbiWULLQeM1L96iuXnRtYMd47j3bEWXAwUW9EnwNWcn+cZg/jC/Dg4Wj/jnkdTDEuFtbeu1ww==", + "dev": true + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" + }, + "for-own": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", + "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", + "requires": { + "for-in": "^1.0.1" + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "requires": { + "map-cache": "^0.2.2" + } + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" + }, + "fs-extra": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz", + "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0" + }, + "dependencies": { + "jsonfile": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "requires": { + "graceful-fs": "^4.1.6" + } + } + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", + "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", + "optional": true, + "requires": { + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.1", + "bundled": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "debug": { + "version": "4.1.1", + "bundled": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": 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.3", + "bundled": 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, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "optional": true + }, + "minipass": { + "version": "2.3.5", + "bundled": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.2.1", + "bundled": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "optional": true + }, + "needle": { + "version": "2.3.0", + "bundled": true, + "optional": true, + "requires": { + "debug": "^4.1.0", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.12.0", + "bundled": 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" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.6", + "bundled": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.1", + "bundled": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": 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, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": 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.6.3", + "bundled": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "optional": true + }, + "semver": { + "version": "5.7.0", + "bundled": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": 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, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "optional": true + }, + "tar": { + "version": "4.4.8", + "bundled": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "optional": true + }, + "yallist": { + "version": "3.0.3", + "bundled": 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==" + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "fuse.js": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-2.6.2.tgz", + "integrity": "sha1-1dmU/alvVDtaUd84tyzsnMYNneo=" + }, + "gauge": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-1.2.7.tgz", + "integrity": "sha1-6c7FSD09TuDvRLYKfZnkk14TbZM=", + "requires": { + "ansi": "^0.3.0", + "has-unicode": "^2.0.0", + "lodash.pad": "^4.1.0", + "lodash.padend": "^4.1.0", + "lodash.padstart": "^4.1.0" + } + }, + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" + }, + "get-own-enumerable-property-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.0.tgz", + "integrity": "sha512-CIJYJC4GGF06TakLg8z4GQKvDsx9EMspVxOYih7LerEL/WosUnFIww45CGfxfeKHqlg3twgUrYRT1O3WQqjGCg==", + "dev": true + }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "gfycat-style-urls": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/gfycat-style-urls/-/gfycat-style-urls-1.0.3.tgz", + "integrity": "sha512-HirQ+dsQWChjnfwZXB07ytzh3eZQFVlOdO2ML1YvpHBOXplumtzGIAejVu91wmj4Cw7t4760M2fKtgI+NAi/2w==" + }, + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "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-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "requires": { + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" + } + }, + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "requires": { + "is-glob": "^2.0.0" + } + }, + "global": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/global/-/global-4.4.0.tgz", + "integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==", + "requires": { + "min-document": "^2.19.0", + "process": "^0.11.10" + } + }, + "global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", + "dev": true, + "requires": { + "ini": "^1.3.4" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + }, + "google-libphonenumber": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/google-libphonenumber/-/google-libphonenumber-2.0.19.tgz", + "integrity": "sha512-kwtbruT+eyiof081cxT1tltMTxgTOq3CQhUoEYBROC+vNf+COPqzfKJtVnDvgXQe4SzfbnAYkP8KoSpbJBIlSg==" + }, + "got": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", + "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", + "dev": true, + "requires": { + "create-error-class": "^3.0.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-redirect": "^1.0.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "lowercase-keys": "^1.0.0", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "unzip-response": "^2.0.1", + "url-parse-lax": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz", + "integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==" + }, + "growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=" + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dev": true, + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "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.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=" + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + } + } + }, + "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=", + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "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=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "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==" + }, + "home-path": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/home-path/-/home-path-1.0.6.tgz", + "integrity": "sha512-wo+yjrdAtoXt43Vy92a+0IPCYViiyLAHyp0QVS4xL/tfvVz5sXIW1ubLZk3nhVkD92fQpUMKX+fzMjr5F489vw==", + "dev": true + }, + "hosted-git-info": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", + "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==" + }, + "http-errors": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", + "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "husky": { + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/husky/-/husky-0.14.3.tgz", + "integrity": "sha512-e21wivqHpstpoiWA/Yi8eFti8E+sQDSS53cpJsPptPs295QTOQR0ZwnHo2TXy1XOpZFD9rPOd3NpmqTK6uMLJA==", + "dev": true, + "requires": { + "is-ci": "^1.0.10", + "normalize-path": "^1.0.0", + "strip-indent": "^2.0.0" + }, + "dependencies": { + "normalize-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-1.0.0.tgz", + "integrity": "sha1-MtDkcvkf80VwHBWoMRAY07CpA3k=", + "dev": true + } + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "image-size": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.6.3.tgz", + "integrity": "sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA==" + }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, + "import-lazy": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", + "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + }, + "indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "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 + }, + "inquirer": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", + "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", + "requires": { + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.0", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^2.0.4", + "figures": "^2.0.0", + "lodash": "^4.3.0", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rx-lite": "^4.0.8", + "rx-lite-aggregates": "^4.0.8", + "string-width": "^2.1.0", + "strip-ansi": "^4.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "requires": { + "loose-envify": "^1.0.0" + } + }, + "invert-kv": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" + }, + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "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=", + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true + }, + "is-ci": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", + "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", + "dev": true, + "requires": { + "ci-info": "^1.5.0" + } + }, + "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=", + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "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==" + } + } + }, + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=" + }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=" + }, + "is-equal-shallow": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", + "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "requires": { + "is-primitive": "^2.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + }, + "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": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "requires": { + "is-extglob": "^1.0.0" + } + }, + "is-installed-globally": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", + "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", + "dev": true, + "requires": { + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" + } + }, + "is-npm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", + "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=", + "dev": true + }, + "is-number": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", + "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true + }, + "is-observable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-1.1.0.tgz", + "integrity": "sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA==", + "dev": true, + "requires": { + "symbol-observable": "^1.1.0" + } + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "^1.0.1" + } + }, + "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" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + } + } + }, + "is-posix-bracket": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", + "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=" + }, + "is-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", + "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=" + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" + }, + "is-redirect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", + "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=", + "dev": true + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "^1.0.1" + } + }, + "is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", + "dev": true + }, + "is-retry-allowed": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", + "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" + }, + "is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.0" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "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==" + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=" + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + }, + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "requires": { + "isarray": "1.0.0" + } + }, + "isomorphic-fetch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", + "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", + "requires": { + "node-fetch": "^1.0.1", + "whatwg-fetch": ">=0.10.0" + }, + "dependencies": { + "node-fetch": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", + "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", + "requires": { + "encoding": "^0.1.11", + "is-stream": "^1.0.1" + } + } + } + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "jest-get-type": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-22.4.3.tgz", + "integrity": "sha512-/jsz0Y+V29w1chdXVygEKSz2nBoHoYqNShPe+QgxSNjAuP1i8+k4LbQNrfoliKej0P45sivkSCh7yiD6ubHS3w==", + "dev": true + }, + "jest-haste-map": { + "version": "24.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-24.0.0-alpha.6.tgz", + "integrity": "sha512-+NO2HMbjvrG8BC39ieLukdpFrcPhhjCJGhpbHodHNZygH1Tt06WrlNYGpZtWKx/zpf533tCtMQXO/q59JenjNw==", + "requires": { + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.1.11", + "invariant": "^2.2.4", + "jest-serializer": "^24.0.0-alpha.6", + "jest-worker": "^24.0.0-alpha.6", + "micromatch": "^2.3.11", + "sane": "^3.0.0" + } + }, + "jest-serializer": { + "version": "24.4.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-24.4.0.tgz", + "integrity": "sha512-k//0DtglVstc1fv+GY/VHDIjrtNjdYvYjMlbLUed4kxrE92sIUewOi5Hj3vrpB8CXfkJntRPDRjCrCvUhBdL8Q==" + }, + "jest-validate": { + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-23.6.0.tgz", + "integrity": "sha512-OFKapYxe72yz7agrDAWi8v2WL8GIfVqcbKRCLbRG9PAxtzF9b1SEDdTpytNDN12z2fJynoBwpMpvj2R39plI2A==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "jest-get-type": "^22.1.0", + "leven": "^2.1.0", + "pretty-format": "^23.6.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "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" + } + }, + "pretty-format": { + "version": "23.6.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-23.6.0.tgz", + "integrity": "sha512-zf9NV1NSlDLDjycnwm6hpFATCGl/K1lt0R/GdkAK2O5LN/rwJoB+Mh93gGJjut4YbmecbfgLWVGSTCr0Ewvvbw==", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0", + "ansi-styles": "^3.2.0" + } + } + } + }, + "jest-worker": { + "version": "24.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-24.0.0-alpha.6.tgz", + "integrity": "sha512-iXtH7MR9bjWlNnlnRBcrBRrb4cSVxML96La5vsnmBvDI+mJnkP5uEt6Fgpo5Y8f3z9y2Rd7wuPnKRxqQsiU/dA==", + "requires": { + "merge-stream": "^1.0.1" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "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": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "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 + }, + "json-stable-stringify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", + "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "requires": { + "jsonify": "~0.0.0" + } + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "json5": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", + "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", + "requires": { + "minimist": "^1.2.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "jsx-ast-utils": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.2.1.tgz", + "integrity": "sha512-v3FxCcAf20DayI+uxnCuw795+oOIkVu6EnJ1+kSzhqqTZHNkTZ7B66ZgLp4oLJ/gbA64cI0B7WRoHZMSRdyVRQ==", + "dev": true, + "requires": { + "array-includes": "^3.0.3", + "object.assign": "^4.1.0" + } + }, + "keymirror": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/keymirror/-/keymirror-0.1.1.tgz", + "integrity": "sha1-kYiJ6hP40KQufFVyUO7nE63JXDU=" + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "requires": { + "is-buffer": "^1.1.5" + } + }, + "klaw": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", + "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "requires": { + "graceful-fs": "^4.1.9" + } + }, + "latest-version": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", + "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", + "dev": true, + "requires": { + "package-json": "^4.0.0" + } + }, + "lbry-redux": { + "version": "github:lbryio/lbry-redux#cd23c12fb7fd541d28d7cbf3874b1058b036fd13", + "from": "github:lbryio/lbry-redux#cd23c12fb7fd541d28d7cbf3874b1058b036fd13", + "requires": { + "proxy-polyfill": "0.1.6", + "reselect": "^3.0.0", + "uuid": "^3.3.2" + } + }, + "lbryinc": { + "version": "github:lbryio/lbryinc#2cc861145e79ed59478c150ac63f5ffc5fc2ad28", + "from": "github:lbryio/lbryinc", + "requires": { + "reselect": "^3.0.0" + } + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "requires": { + "invert-kv": "^1.0.0" + } + }, + "leven": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", + "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=", + "dev": true + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "lint-staged": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-7.3.0.tgz", + "integrity": "sha512-AXk40M9DAiPi7f4tdJggwuKIViUplYtVj1os1MVEteW7qOkU50EOehayCfO9TsoGK24o/EsWb41yrEgfJDDjCw==", + "dev": true, + "requires": { + "chalk": "^2.3.1", + "commander": "^2.14.1", + "cosmiconfig": "^5.0.2", + "debug": "^3.1.0", + "dedent": "^0.7.0", + "execa": "^0.9.0", + "find-parent-dir": "^0.3.0", + "is-glob": "^4.0.0", + "is-windows": "^1.0.2", + "jest-validate": "^23.5.0", + "listr": "^0.14.1", + "lodash": "^4.17.5", + "log-symbols": "^2.2.0", + "micromatch": "^3.1.8", + "npm-which": "^3.0.1", + "p-map": "^1.1.1", + "path-is-inside": "^1.0.2", + "pify": "^3.0.0", + "please-upgrade-node": "^3.0.2", + "staged-git-files": "1.1.1", + "string-argv": "^0.0.2", + "stringify-object": "^3.2.2" + }, + "dependencies": { + "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 + }, + "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 + }, + "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" + } + } + } + }, + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "execa": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.9.0.tgz", + "integrity": "sha512-BbUMBiX4hqiHZUA5+JujIjNb6TyAlp2D5KLheMjMluwOuzcnylDL4AxZYLLn1n2AGB49eSWwyKvvEQoRpnAtmA==", + "dev": true, + "requires": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "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" + } + }, + "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-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" + } + }, + "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 + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "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" + } + } + } + }, + "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" + } + } + } + }, + "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" + } + }, + "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-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" + } + } + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "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 + }, + "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" + } + }, + "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 + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, + "listr": { + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/listr/-/listr-0.14.3.tgz", + "integrity": "sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA==", + "dev": true, + "requires": { + "@samverschueren/stream-to-observable": "^0.3.0", + "is-observable": "^1.1.0", + "is-promise": "^2.1.0", + "is-stream": "^1.1.0", + "listr-silent-renderer": "^1.1.1", + "listr-update-renderer": "^0.5.0", + "listr-verbose-renderer": "^0.5.0", + "p-map": "^2.0.0", + "rxjs": "^6.3.3" + }, + "dependencies": { + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true + } + } + }, + "listr-silent-renderer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz", + "integrity": "sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4=", + "dev": true + }, + "listr-update-renderer": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz", + "integrity": "sha512-tKRsZpKz8GSGqoI/+caPmfrypiaq+OQCbd+CovEC24uk1h952lVj5sC7SqyFUm+OaJ5HN/a1YLt5cit2FMNsFA==", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "cli-truncate": "^0.2.1", + "elegant-spinner": "^1.0.1", + "figures": "^1.7.0", + "indent-string": "^3.0.0", + "log-symbols": "^1.0.2", + "log-update": "^2.3.0", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "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" + } + }, + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" + } + }, + "log-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", + "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", + "dev": true, + "requires": { + "chalk": "^1.0.0" + } + } + } + }, + "listr-verbose-renderer": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz", + "integrity": "sha512-04PDPqSlsqIOaaaGZ+41vq5FejI9auqTInicFRndCBgE3bXG8D6W1I+mWhk+1nqbHmyhla/6BUrd5OSiHwKRXw==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "cli-cursor": "^2.1.0", + "date-fns": "^1.27.2", + "figures": "^2.0.0" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.14", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.14.tgz", + "integrity": "sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw==" + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" + }, + "lodash.forin": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.forin/-/lodash.forin-4.4.0.tgz", + "integrity": "sha1-XT8grlZAEfvog4H32YlJyclRlzE=" + }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" + }, + "lodash.isempty": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz", + "integrity": "sha1-b4bL7di+TsmHvpqvM8loTbGzHn4=" + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "lodash.pad": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/lodash.pad/-/lodash.pad-4.5.1.tgz", + "integrity": "sha1-QzCUmoM6fI2iLMIPaibE1Z3runA=" + }, + "lodash.padend": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz", + "integrity": "sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4=" + }, + "lodash.padstart": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.padstart/-/lodash.padstart-4.6.1.tgz", + "integrity": "sha1-0uPuv/DZ05rVD1y9G1KnvOa7YRs=" + }, + "lodash.pickby": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.pickby/-/lodash.pickby-4.6.0.tgz", + "integrity": "sha1-feoh2MGNdwOifHBMFdO4SmfjOv8=" + }, + "lodash.set": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", + "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=" + }, + "lodash.throttle": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", + "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=" + }, + "lodash.toarray": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz", + "integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE=" + }, + "lodash.unset": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/lodash.unset/-/lodash.unset-4.5.2.tgz", + "integrity": "sha1-Nw0dPoW3Kn4bDN8tJyEhMG8j5O0=" + }, + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "requires": { + "chalk": "^2.0.1" + } + }, + "log-update": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-2.3.0.tgz", + "integrity": "sha1-iDKP19HOeTiykoN0bwsbwSayRwg=", + "dev": true, + "requires": { + "ansi-escapes": "^3.0.0", + "cli-cursor": "^2.0.0", + "wrap-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "wrap-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-3.0.1.tgz", + "integrity": "sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo=", + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0" + } + } + } + }, + "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" + } + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true, + "requires": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + } + }, + "lowercase-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", + "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "dev": true + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "lz-string": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", + "integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=" + }, + "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==", + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "dependencies": { + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" + } + } + }, + "makeerror": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "requires": { + "tmpl": "1.0.x" + } + }, + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "requires": { + "p-defer": "^1.0.0" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "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=", + "requires": { + "object-visit": "^1.0.0" + } + }, + "math-random": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.4.tgz", + "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==" + }, + "mem": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", + "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "dev": true, + "requires": { + "camelcase-keys": "^2.0.0", + "decamelize": "^1.1.2", + "loud-rejection": "^1.0.0", + "map-obj": "^1.0.1", + "minimist": "^1.1.3", + "normalize-package-data": "^2.3.4", + "object-assign": "^4.0.1", + "read-pkg-up": "^1.0.1", + "redent": "^1.0.0", + "trim-newlines": "^1.0.0" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "dev": true, + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "^0.2.0" + } + } + } + }, + "merge": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.1.tgz", + "integrity": "sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==" + }, + "merge-stream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", + "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", + "requires": { + "readable-stream": "^2.0.1" + } + }, + "metro": { + "version": "0.51.1", + "resolved": "https://registry.npmjs.org/metro/-/metro-0.51.1.tgz", + "integrity": "sha512-nM0dqn8LQlMjhChl2fzTUq2EWiUebZM7nkesD9vQe47W10bj/tbRLPiIIAxht6SRDbPd/hRA+t39PxLhPSKEKg==", + "requires": { + "@babel/core": "^7.0.0", + "@babel/generator": "^7.0.0", + "@babel/parser": "^7.0.0", + "@babel/plugin-external-helpers": "^7.0.0", + "@babel/template": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "absolute-path": "^0.0.0", + "async": "^2.4.0", + "babel-preset-fbjs": "^3.0.1", + "buffer-crc32": "^0.2.13", + "chalk": "^2.4.1", + "concat-stream": "^1.6.0", + "connect": "^3.6.5", + "debug": "^2.2.0", + "denodeify": "^1.2.1", + "eventemitter3": "^3.0.0", + "fbjs": "^1.0.0", + "fs-extra": "^1.0.0", + "graceful-fs": "^4.1.3", + "image-size": "^0.6.0", + "invariant": "^2.2.4", + "jest-haste-map": "24.0.0-alpha.6", + "jest-worker": "24.0.0-alpha.6", + "json-stable-stringify": "^1.0.1", + "lodash.throttle": "^4.1.1", + "merge-stream": "^1.0.1", + "metro-babel-transformer": "0.51.1", + "metro-cache": "0.51.1", + "metro-config": "0.51.1", + "metro-core": "0.51.1", + "metro-minify-uglify": "0.51.1", + "metro-react-native-babel-preset": "0.51.1", + "metro-resolver": "0.51.1", + "metro-source-map": "0.51.1", + "mime-types": "2.1.11", + "mkdirp": "^0.5.1", + "node-fetch": "^2.2.0", + "nullthrows": "^1.1.0", + "react-transform-hmr": "^1.0.4", + "resolve": "^1.5.0", + "rimraf": "^2.5.4", + "serialize-error": "^2.1.0", + "source-map": "^0.5.6", + "temp": "0.8.3", + "throat": "^4.1.0", + "wordwrap": "^1.0.0", + "write-file-atomic": "^1.2.0", + "ws": "^1.1.5", + "xpipe": "^1.0.5", + "yargs": "^9.0.0" + }, + "dependencies": { + "metro-react-native-babel-preset": { + "version": "0.51.1", + "resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.51.1.tgz", + "integrity": "sha512-e9tsYDFhU70gar0jQWcZXRPJVCv4k7tEs6Pm74wXO2OO/T1MEumbvniDIGwGG8bG8RUnYdHhjcaiub2Vc5BRWw==", + "requires": { + "@babel/plugin-proposal-class-properties": "^7.0.0", + "@babel/plugin-proposal-export-default-from": "^7.0.0", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0", + "@babel/plugin-proposal-object-rest-spread": "^7.0.0", + "@babel/plugin-proposal-optional-catch-binding": "^7.0.0", + "@babel/plugin-proposal-optional-chaining": "^7.0.0", + "@babel/plugin-syntax-dynamic-import": "^7.0.0", + "@babel/plugin-syntax-export-default-from": "^7.0.0", + "@babel/plugin-transform-arrow-functions": "^7.0.0", + "@babel/plugin-transform-block-scoping": "^7.0.0", + "@babel/plugin-transform-classes": "^7.0.0", + "@babel/plugin-transform-computed-properties": "^7.0.0", + "@babel/plugin-transform-destructuring": "^7.0.0", + "@babel/plugin-transform-exponentiation-operator": "^7.0.0", + "@babel/plugin-transform-flow-strip-types": "^7.0.0", + "@babel/plugin-transform-for-of": "^7.0.0", + "@babel/plugin-transform-function-name": "^7.0.0", + "@babel/plugin-transform-literals": "^7.0.0", + "@babel/plugin-transform-modules-commonjs": "^7.0.0", + "@babel/plugin-transform-object-assign": "^7.0.0", + "@babel/plugin-transform-parameters": "^7.0.0", + "@babel/plugin-transform-react-display-name": "^7.0.0", + "@babel/plugin-transform-react-jsx": "^7.0.0", + "@babel/plugin-transform-react-jsx-source": "^7.0.0", + "@babel/plugin-transform-regenerator": "^7.0.0", + "@babel/plugin-transform-runtime": "^7.0.0", + "@babel/plugin-transform-shorthand-properties": "^7.0.0", + "@babel/plugin-transform-spread": "^7.0.0", + "@babel/plugin-transform-sticky-regex": "^7.0.0", + "@babel/plugin-transform-template-literals": "^7.0.0", + "@babel/plugin-transform-typescript": "^7.0.0", + "@babel/plugin-transform-unicode-regex": "^7.0.0", + "@babel/template": "^7.0.0", + "metro-babel7-plugin-react-transform": "0.51.1", + "react-transform-hmr": "^1.0.4" + } + }, + "mime-db": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.23.0.tgz", + "integrity": "sha1-oxtAcK2uon1zLqMzdApk0OyaZlk=" + }, + "mime-types": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.11.tgz", + "integrity": "sha1-wlnEcb2oCKhdbNGTtDCl+uRHOzw=", + "requires": { + "mime-db": "~1.23.0" + } + }, + "yargs": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-9.0.1.tgz", + "integrity": "sha1-UqzCP+7Kw0BCB47njAwAf1CF20w=", + "requires": { + "camelcase": "^4.1.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^2.0.0", + "read-pkg-up": "^2.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^7.0.0" + } + } + } + }, + "metro-babel-register": { + "version": "0.51.0", + "resolved": "https://registry.npmjs.org/metro-babel-register/-/metro-babel-register-0.51.0.tgz", + "integrity": "sha512-rhdvHFOZ7/ub019A3+aYs8YeLydb02/FAMsKr2Nz2Jlf6VUxWrMnrcT0NYX16F9TGdi2ulRlJ9dwvUmdhkk+Bw==", + "requires": { + "@babel/core": "^7.0.0", + "@babel/plugin-proposal-class-properties": "^7.0.0", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0", + "@babel/plugin-proposal-object-rest-spread": "^7.0.0", + "@babel/plugin-proposal-optional-catch-binding": "^7.0.0", + "@babel/plugin-proposal-optional-chaining": "^7.0.0", + "@babel/plugin-transform-async-to-generator": "^7.0.0", + "@babel/plugin-transform-flow-strip-types": "^7.0.0", + "@babel/plugin-transform-modules-commonjs": "^7.0.0", + "@babel/register": "^7.0.0", + "core-js": "^2.2.2", + "escape-string-regexp": "^1.0.5" + } + }, + "metro-babel-transformer": { + "version": "0.51.1", + "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.51.1.tgz", + "integrity": "sha512-+tOnZZzOzufB86ASdfimUEGB1jBKsdsVpPdjNJZkueTFyvYlGqWDQKHM1w9bwKMeM/czPQ48Y6m8Bou6le0X4w==", + "requires": { + "@babel/core": "^7.0.0" + } + }, + "metro-babel7-plugin-react-transform": { + "version": "0.51.1", + "resolved": "https://registry.npmjs.org/metro-babel7-plugin-react-transform/-/metro-babel7-plugin-react-transform-0.51.1.tgz", + "integrity": "sha512-wzn4X9KgmAMZ7Bi6v9KxA7dw+AHGL0RODPxU5NDJ3A6d0yERvzfZ3qkzWhz8jbFkVBK12cu5DTho3HBazKQDOw==", + "requires": { + "@babel/helper-module-imports": "^7.0.0" + } + }, + "metro-cache": { + "version": "0.51.1", + "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.51.1.tgz", + "integrity": "sha512-0m1+aicsw77LVAehNuTxDpE1c/7Xv/ajRD+UL/lFCWUxnrjSbxVtIKr8l5DxEY11082c1axVRuaV9e436W+eXg==", + "requires": { + "jest-serializer": "24.0.0-alpha.6", + "metro-core": "0.51.1", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4" + }, + "dependencies": { + "jest-serializer": { + "version": "24.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-24.0.0-alpha.6.tgz", + "integrity": "sha512-IPA5T6/GhlE6dedSk7Cd7YfuORnYjN0VD5iJVFn1Q81RJjpj++Hen5kJbKcg547vXsQ1TddV15qOA/zeIfOCLw==" + } + } + }, + "metro-config": { + "version": "0.51.1", + "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.51.1.tgz", + "integrity": "sha512-WCNd0tTI9gb/ubgTqK1+ljZL4b3hsXVinsOAtep4nHiVb6DSDdbO2yXDD2rpYx3NE6hDRMFS9HHg6G0139pAqQ==", + "requires": { + "cosmiconfig": "^5.0.5", + "metro": "0.51.1", + "metro-cache": "0.51.1", + "metro-core": "0.51.1", + "pretty-format": "24.0.0-alpha.6" + } + }, + "metro-core": { + "version": "0.51.1", + "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.51.1.tgz", + "integrity": "sha512-sG1yACjdFqmIzZN50HqLTKUMp1oy0AehHhmIuYeIllo1DjX6Y2o3UAT3rGP8U+SAqJGXf/OWzl6VNyRPGDENfA==", + "requires": { + "jest-haste-map": "24.0.0-alpha.6", + "lodash.throttle": "^4.1.1", + "metro-resolver": "0.51.1", + "wordwrap": "^1.0.0" + } + }, + "metro-memory-fs": { + "version": "0.51.1", + "resolved": "https://registry.npmjs.org/metro-memory-fs/-/metro-memory-fs-0.51.1.tgz", + "integrity": "sha512-dXVUpLPLwfQcYHd1HlqHGVzBsiwvUdT92TDSbdc10152TP+iynHBqLDWbxt0MAtd6c/QXwOuGZZ1IcX3+lv5iw==" + }, + "metro-minify-uglify": { + "version": "0.51.1", + "resolved": "https://registry.npmjs.org/metro-minify-uglify/-/metro-minify-uglify-0.51.1.tgz", + "integrity": "sha512-HAqd/rFrQ6mnbqVAszDXIKTg2rqHlY9Fm8DReakgbkAeyMbF2mH3kEgtesPmTrhajdFk81UZcNSm6wxj1JMgVg==", + "requires": { + "uglify-es": "^3.1.9" + } + }, + "metro-react-native-babel-preset": { + "version": "0.55.0", + "resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.55.0.tgz", + "integrity": "sha512-HUI+dEiVym8f1NYIF1grY9PdoY0d3SSS/HED2dDDvTORwndsAEWuXiUgKFOGWX18+RUAQog8obVQuBMgrr8ZBQ==", + "dev": true, + "requires": { + "@babel/plugin-proposal-class-properties": "^7.0.0", + "@babel/plugin-proposal-export-default-from": "^7.0.0", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0", + "@babel/plugin-proposal-object-rest-spread": "^7.0.0", + "@babel/plugin-proposal-optional-catch-binding": "^7.0.0", + "@babel/plugin-proposal-optional-chaining": "^7.0.0", + "@babel/plugin-syntax-dynamic-import": "^7.0.0", + "@babel/plugin-syntax-export-default-from": "^7.0.0", + "@babel/plugin-syntax-flow": "^7.2.0", + "@babel/plugin-transform-arrow-functions": "^7.0.0", + "@babel/plugin-transform-block-scoping": "^7.0.0", + "@babel/plugin-transform-classes": "^7.0.0", + "@babel/plugin-transform-computed-properties": "^7.0.0", + "@babel/plugin-transform-destructuring": "^7.0.0", + "@babel/plugin-transform-exponentiation-operator": "^7.0.0", + "@babel/plugin-transform-flow-strip-types": "^7.0.0", + "@babel/plugin-transform-for-of": "^7.0.0", + "@babel/plugin-transform-function-name": "^7.0.0", + "@babel/plugin-transform-literals": "^7.0.0", + "@babel/plugin-transform-modules-commonjs": "^7.0.0", + "@babel/plugin-transform-object-assign": "^7.0.0", + "@babel/plugin-transform-parameters": "^7.0.0", + "@babel/plugin-transform-react-display-name": "^7.0.0", + "@babel/plugin-transform-react-jsx": "^7.0.0", + "@babel/plugin-transform-react-jsx-source": "^7.0.0", + "@babel/plugin-transform-regenerator": "^7.0.0", + "@babel/plugin-transform-runtime": "^7.0.0", + "@babel/plugin-transform-shorthand-properties": "^7.0.0", + "@babel/plugin-transform-spread": "^7.0.0", + "@babel/plugin-transform-sticky-regex": "^7.0.0", + "@babel/plugin-transform-template-literals": "^7.0.0", + "@babel/plugin-transform-typescript": "^7.0.0", + "@babel/plugin-transform-unicode-regex": "^7.0.0", + "@babel/template": "^7.0.0", + "react-refresh": "^0.2.0" + } + }, + "metro-react-native-babel-transformer": { + "version": "0.51.0", + "resolved": "https://registry.npmjs.org/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.51.0.tgz", + "integrity": "sha512-VFnqtE0qrVmU1HV9B04o53+NZHvDwR+CWCoEx4+7vCqJ9Tvas741biqCjah9xtifoKdElQELk6x0soOAWCDFJA==", + "requires": { + "@babel/core": "^7.0.0", + "babel-preset-fbjs": "^3.0.1", + "metro-babel-transformer": "0.51.0", + "metro-react-native-babel-preset": "0.51.0" + }, + "dependencies": { + "metro-babel-transformer": { + "version": "0.51.0", + "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.51.0.tgz", + "integrity": "sha512-M7KEY/hjD3E8tJEliWgI0VOSaJtqaznC0ItM6FiMrhoGDqqa1BvGofl+EPcKqjBSOV1UgExua/T1VOIWbjwQsw==", + "requires": { + "@babel/core": "^7.0.0" + } + }, + "metro-babel7-plugin-react-transform": { + "version": "0.51.0", + "resolved": "https://registry.npmjs.org/metro-babel7-plugin-react-transform/-/metro-babel7-plugin-react-transform-0.51.0.tgz", + "integrity": "sha512-dZ95kXcE2FJMoRsYhxr7YLCbOlHWKwe0bOpihRhfImDTgFfuKIzU4ROQwMUbE0NCbzB+ATFsa2FZ3pHDJ5GI0w==", + "requires": { + "@babel/helper-module-imports": "^7.0.0" + } + }, + "metro-react-native-babel-preset": { + "version": "0.51.0", + "resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.51.0.tgz", + "integrity": "sha512-Y/aPeLl4RzY8IEAneOyDcpdjto/8yjIuX9eUWRngjSqdHYhGQtqiSBpfTpo0BvXpwNRLwCLHyXo58gNpckTJFw==", + "requires": { + "@babel/plugin-proposal-class-properties": "^7.0.0", + "@babel/plugin-proposal-export-default-from": "^7.0.0", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0", + "@babel/plugin-proposal-object-rest-spread": "^7.0.0", + "@babel/plugin-proposal-optional-catch-binding": "^7.0.0", + "@babel/plugin-proposal-optional-chaining": "^7.0.0", + "@babel/plugin-syntax-dynamic-import": "^7.0.0", + "@babel/plugin-syntax-export-default-from": "^7.0.0", + "@babel/plugin-transform-arrow-functions": "^7.0.0", + "@babel/plugin-transform-block-scoping": "^7.0.0", + "@babel/plugin-transform-classes": "^7.0.0", + "@babel/plugin-transform-computed-properties": "^7.0.0", + "@babel/plugin-transform-destructuring": "^7.0.0", + "@babel/plugin-transform-exponentiation-operator": "^7.0.0", + "@babel/plugin-transform-flow-strip-types": "^7.0.0", + "@babel/plugin-transform-for-of": "^7.0.0", + "@babel/plugin-transform-function-name": "^7.0.0", + "@babel/plugin-transform-literals": "^7.0.0", + "@babel/plugin-transform-modules-commonjs": "^7.0.0", + "@babel/plugin-transform-object-assign": "^7.0.0", + "@babel/plugin-transform-parameters": "^7.0.0", + "@babel/plugin-transform-react-display-name": "^7.0.0", + "@babel/plugin-transform-react-jsx": "^7.0.0", + "@babel/plugin-transform-react-jsx-source": "^7.0.0", + "@babel/plugin-transform-regenerator": "^7.0.0", + "@babel/plugin-transform-runtime": "^7.0.0", + "@babel/plugin-transform-shorthand-properties": "^7.0.0", + "@babel/plugin-transform-spread": "^7.0.0", + "@babel/plugin-transform-sticky-regex": "^7.0.0", + "@babel/plugin-transform-template-literals": "^7.0.0", + "@babel/plugin-transform-typescript": "^7.0.0", + "@babel/plugin-transform-unicode-regex": "^7.0.0", + "@babel/template": "^7.0.0", + "metro-babel7-plugin-react-transform": "0.51.0", + "react-transform-hmr": "^1.0.4" + } + } + } + }, + "metro-resolver": { + "version": "0.51.1", + "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.51.1.tgz", + "integrity": "sha512-zmWbD/287NDA/jLPuPV0hne/YMMSG0dljzu21TYMg2lXRLur/zROJHHhyepZvuBHgInXBi4Vhr2wvuSnY39SuA==", + "requires": { + "absolute-path": "^0.0.0" + } + }, + "metro-source-map": { + "version": "0.51.1", + "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.51.1.tgz", + "integrity": "sha512-JyrE+RV4YumrboHPHTGsUUGERjQ681ImRLrSYDGcmNv4tfpk9nvAK26UAas4IvBYFCC9oW90m0udt3kaQGv59Q==", + "requires": { + "source-map": "^0.5.6" + } + }, + "micromatch": { + "version": "2.3.11", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", + "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", + "requires": { + "arr-diff": "^2.0.0", + "array-unique": "^0.2.1", + "braces": "^1.8.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" + }, + "mime-db": { + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" + }, + "mime-types": { + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "requires": { + "mime-db": "1.40.0" + } + }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" + }, + "min-document": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", + "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", + "requires": { + "dom-walk": "^0.1.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "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=" + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "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==", + "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=", + "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=" + } + } + }, + "moment": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", + "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" + }, + "morgan": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz", + "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==", + "requires": { + "basic-auth": "~2.0.0", + "debug": "2.6.9", + "depd": "~1.1.2", + "on-finished": "~2.3.0", + "on-headers": "~1.0.1" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "optional": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "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" + }, + "dependencies": { + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + } + } + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" + }, + "node-emoji": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.8.1.tgz", + "integrity": "sha512-+ktMAh1Jwas+TnGodfCfjUbJKoANqPaJFN0z0iqh41eqD8dvguNzcitVSBSVK1pidz0AqGbLKcoVuVLRVZ/aVg==", + "requires": { + "lodash.toarray": "^4.4.0" + } + }, + "node-fetch": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", + "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" + }, + "node-modules-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", + "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=" + }, + "node-notifier": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.0.tgz", + "integrity": "sha512-SUDEb+o71XR5lXSTyivXd9J7fCloE3SyP4lSgt3lU2oSANiox+SxlNRGPjDKrwU1YN3ix2KN/VGGCg0t01rttQ==", + "requires": { + "growly": "^1.3.0", + "is-wsl": "^1.1.0", + "semver": "^5.5.0", + "shellwords": "^0.1.1", + "which": "^1.3.0" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "npm-path": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/npm-path/-/npm-path-2.0.4.tgz", + "integrity": "sha512-IFsj0R9C7ZdR5cP+ET342q77uSRdtWOlWpih5eC+lu29tIDbNEgDbzgVJ5UFvYHWhxDZ5TFkJafFioO0pPQjCw==", + "dev": true, + "requires": { + "which": "^1.2.10" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "requires": { + "path-key": "^2.0.0" + } + }, + "npm-which": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/npm-which/-/npm-which-3.0.1.tgz", + "integrity": "sha1-kiXybsOihcIJyuZ8OxGmtKtxQKo=", + "dev": true, + "requires": { + "commander": "^2.9.0", + "npm-path": "^2.0.2", + "which": "^1.2.10" + } + }, + "npmlog": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-2.0.4.tgz", + "integrity": "sha1-mLUlMPJRTKkNCexbIsiEZyI3VpI=", + "requires": { + "ansi": "~0.3.1", + "are-we-there-yet": "~1.1.2", + "gauge": "~1.2.5" + } + }, + "nugget": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/nugget/-/nugget-2.0.1.tgz", + "integrity": "sha1-IBCVpIfhrTYIGzQy+jytpPjQcbA=", + "dev": true, + "requires": { + "debug": "^2.1.3", + "minimist": "^1.1.0", + "pretty-bytes": "^1.0.2", + "progress-stream": "^1.1.0", + "request": "^2.45.0", + "single-line-log": "^1.1.2", + "throttleit": "0.0.2" + } + }, + "nullthrows": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz", + "integrity": "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==" + }, + "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=" + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "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=" + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "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=", + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "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-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "requires": { + "isobject": "^3.0.0" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + } + } + }, + "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" + } + }, + "object.entries": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.0.tgz", + "integrity": "sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.12.0", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "object.fromentries": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.0.tgz", + "integrity": "sha512-9iLiI6H083uiqUuvzyY6qrlmc/Gz8hLQFOcb/Ri/0xXFkSNS3ctV+CbE6yM2+AnkYfOB3dGjdzC0wrMLIhQICA==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.11.0", + "function-bind": "^1.1.1", + "has": "^1.0.1" + } + }, + "object.omit": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", + "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "requires": { + "for-own": "^0.1.4", + "is-extendable": "^0.1.1" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "requires": { + "isobject": "^3.0.1" + }, + "dependencies": { + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + } + } + }, + "object.values": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.0.tgz", + "integrity": "sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.12.0", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "opn": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/opn/-/opn-3.0.3.tgz", + "integrity": "sha1-ttmec5n3jWXDuq/+8fsojpuFJDo=", + "requires": { + "object-assign": "^4.0.1" + } + }, + "optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + }, + "dependencies": { + "minimist": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=" + }, + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" + } + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + } + }, + "options": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz", + "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=" + }, + "os-locale": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", + "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "requires": { + "execa": "^0.7.0", + "lcid": "^1.0.0", + "mem": "^1.1.0" + } + }, + "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=" + }, + "p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=" + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" + }, + "p-is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", + "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==" + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "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=", + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-map": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz", + "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==", + "dev": true + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" + }, + "package-json": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", + "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", + "dev": true, + "requires": { + "got": "^6.7.1", + "registry-auth-token": "^3.0.1", + "registry-url": "^3.0.3", + "semver": "^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==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + }, + "dependencies": { + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + } + } + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "requires": { + "glob-base": "^0.3.0", + "is-dotfile": "^1.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "requires": { + "error-ex": "^1.2.0" + } + }, + "parse-node-version": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==" + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" + }, + "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=" + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + }, + "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.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "requires": { + "isarray": "0.0.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + } + } + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "requires": { + "pify": "^2.0.0" + } + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, + "pirates": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", + "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", + "requires": { + "node-modules-regexp": "^1.0.0" + } + }, + "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==", + "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==", + "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==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "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==", + "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==", + "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==" + } + } + }, + "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" + } + }, + "please-upgrade-node": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.1.1.tgz", + "integrity": "sha512-KY1uHnQ2NlQHqIJQpnh/i54rKkuxCEBx+voJIS/Mvb+L2iYd2NMotwduhKTMjfC1uKoX3VXOxLjIYG66dfJTVQ==", + "dev": true, + "requires": { + "semver-compare": "^1.0.0" + } + }, + "plist": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.1.tgz", + "integrity": "sha512-GpgvHHocGRyQm74b6FWEZZVRroHKE1I0/BTjAmySaohK+cUn+hZpbqXkc3KWgW3gQYkqcQej35FohcT0FRlkRQ==", + "requires": { + "base64-js": "^1.2.3", + "xmlbuilder": "^9.0.7", + "xmldom": "0.1.x" + } + }, + "plugin-error": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz", + "integrity": "sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4=", + "requires": { + "ansi-cyan": "^0.1.1", + "ansi-red": "^0.1.1", + "arr-diff": "^1.0.1", + "arr-union": "^2.0.1", + "extend-shallow": "^1.1.2" + }, + "dependencies": { + "arr-diff": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz", + "integrity": "sha1-aHwydYFjWI/vfeezb6vklesaOZo=", + "requires": { + "arr-flatten": "^1.0.1", + "array-slice": "^0.2.3" + } + }, + "arr-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-2.1.0.tgz", + "integrity": "sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0=" + }, + "extend-shallow": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz", + "integrity": "sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=", + "requires": { + "kind-of": "^1.1.0" + } + }, + "kind-of": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz", + "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=" + } + } + }, + "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=" + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "prepend-http": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "dev": true + }, + "preserve": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", + "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=" + }, + "prettier": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.18.2.tgz", + "integrity": "sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw==", + "dev": true + }, + "pretty-bytes": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-1.0.4.tgz", + "integrity": "sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ=", + "dev": true, + "requires": { + "get-stdin": "^4.0.1", + "meow": "^3.1.0" + } + }, + "pretty-format": { + "version": "24.0.0-alpha.6", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.0.0-alpha.6.tgz", + "integrity": "sha512-zG2m6YJeuzwBFqb5EIdmwYVf30sap+iMRuYNPytOccEXZMAJbPIFGKVJ/U0WjQegmnQbRo9CI7j6j3HtDaifiA==", + "requires": { + "ansi-regex": "^4.0.0", + "ansi-styles": "^3.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "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" + } + } + } + }, + "private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==" + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=" + }, + "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==" + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "progress-stream": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/progress-stream/-/progress-stream-1.2.0.tgz", + "integrity": "sha1-LNPP6jO6OonJwSHsM0er6asSX3c=", + "dev": true, + "requires": { + "speedometer": "~0.1.2", + "through2": "~0.2.3" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "object-keys": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", + "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=", + "dev": true + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "through2": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.2.3.tgz", + "integrity": "sha1-6zKE2k6jEbbMis42U3SKUqvyWj8=", + "dev": true, + "requires": { + "readable-stream": "~1.1.9", + "xtend": "~2.1.1" + } + }, + "xtend": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", + "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", + "dev": true, + "requires": { + "object-keys": "~0.4.0" + } + } + } + }, + "promise": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", + "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "requires": { + "asap": "~2.0.3" + } + }, + "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" + } + }, + "proxy-polyfill": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/proxy-polyfill/-/proxy-polyfill-0.1.6.tgz", + "integrity": "sha1-70HsbGb1NNsV2zbFRJOmLRhLNk4=" + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + }, + "psl": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz", + "integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag==", + "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==", + "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 + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "query-string": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.8.1.tgz", + "integrity": "sha512-g6y0Lbq10a5pPQpjlFuojfMfV1Pd2Jw9h75ypiYPPia3Gcq2rgkKiIwbkS6JxH7c5f5u/B/sB+d13PU+g1eu4Q==", + "requires": { + "decode-uri-component": "^0.2.0", + "split-on-first": "^1.0.0", + "strict-uri-encode": "^2.0.0" + } + }, + "randomatic": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.1.1.tgz", + "integrity": "sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==", + "requires": { + "is-number": "^4.0.0", + "kind-of": "^6.0.0", + "math-random": "^1.0.1" + }, + "dependencies": { + "is-number": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==" + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + } + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" + }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, + "react": { + "version": "16.8.6", + "resolved": "https://registry.npmjs.org/react/-/react-16.8.6.tgz", + "integrity": "sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.13.6" + } + }, + "react-clone-referenced-element": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/react-clone-referenced-element/-/react-clone-referenced-element-1.1.0.tgz", + "integrity": "sha512-FKOsfKbBkPxYE8576EM6uAfHC4rnMpLyH6/TJUL4WcHUEB3EUn8AxPjnnV/IiwSSzsClvHYK+sDELKN/EJ0WYg==" + }, + "react-deep-force-update": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/react-deep-force-update/-/react-deep-force-update-1.1.2.tgz", + "integrity": "sha512-WUSQJ4P/wWcusaH+zZmbECOk7H5N2pOIl0vzheeornkIMhu+qrNdGFm0bDZLCb0hSF0jf/kH1SgkNGfBdTc4wA==" + }, + "react-devtools": { + "version": "3.6.3", + "resolved": "https://registry.npmjs.org/react-devtools/-/react-devtools-3.6.3.tgz", + "integrity": "sha512-7JrGlKHvyamqDfDi7EEoIC8BHygKC1Mc8PmAAYm0aokwYuam/42bO1gnF5y2K7K1MbO+6f7J93s1N4VK0YdmEw==", + "dev": true, + "requires": { + "cross-spawn": "^5.0.1", + "electron": "^1.8.7", + "ip": "^1.1.4", + "minimist": "^1.2.0", + "react-devtools-core": "^3.6.0", + "update-notifier": "^2.1.0" + } + }, + "react-devtools-core": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-3.6.1.tgz", + "integrity": "sha512-I/LSX+tpeTrGKaF1wXSfJ/kP+6iaP2JfshEjW8LtQBdz6c6HhzOJtjZXhqOUrAdysuey8M1/JgPY1flSVVt8Ig==", + "requires": { + "shell-quote": "^1.6.1", + "ws": "^3.3.1" + }, + "dependencies": { + "ultron": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==" + }, + "ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "requires": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" + } + } + } + }, + "react-is": { + "version": "16.8.6", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz", + "integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==" + }, + "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-native": { + "version": "0.59.10", + "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.59.10.tgz", + "integrity": "sha512-guB9YW+pBqS1dnfZ4ntzjINopiCUAbdmshU2wMWD1W32fRczLAopi/7Q2iHKP8LTCdxuYZV3fa9Mew5PSuANAw==", + "requires": { + "@babel/runtime": "^7.0.0", + "@react-native-community/cli": "^1.2.1", + "absolute-path": "^0.0.0", + "art": "^0.10.0", + "base64-js": "^1.1.2", + "chalk": "^2.4.1", + "commander": "^2.9.0", + "compression": "^1.7.1", + "connect": "^3.6.5", + "create-react-class": "^15.6.3", + "debug": "^2.2.0", + "denodeify": "^1.2.1", + "errorhandler": "^1.5.0", + "escape-string-regexp": "^1.0.5", + "event-target-shim": "^1.0.5", + "fbjs": "^1.0.0", + "fbjs-scripts": "^1.0.0", + "fs-extra": "^1.0.0", + "glob": "^7.1.1", + "graceful-fs": "^4.1.3", + "inquirer": "^3.0.6", + "invariant": "^2.2.4", + "lodash": "^4.17.5", + "metro-babel-register": "0.51.0", + "metro-react-native-babel-transformer": "0.51.0", + "mime": "^1.3.4", + "minimist": "^1.2.0", + "mkdirp": "^0.5.1", + "morgan": "^1.9.0", + "node-fetch": "^2.2.0", + "node-notifier": "^5.2.1", + "npmlog": "^2.0.4", + "nullthrows": "^1.1.0", + "opn": "^3.0.2", + "optimist": "^0.6.1", + "plist": "^3.0.0", + "pretty-format": "24.0.0-alpha.6", + "promise": "^7.1.1", + "prop-types": "^15.5.8", + "react-clone-referenced-element": "^1.0.1", + "react-devtools-core": "^3.6.0", + "regenerator-runtime": "^0.11.0", + "rimraf": "^2.5.4", + "semver": "^5.0.3", + "serve-static": "^1.13.1", + "shell-quote": "1.6.1", + "stacktrace-parser": "^0.1.3", + "ws": "^1.1.5", + "xmldoc": "^0.4.0", + "yargs": "^9.0.0" + }, + "dependencies": { + "yargs": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-9.0.1.tgz", + "integrity": "sha1-UqzCP+7Kw0BCB47njAwAf1CF20w=", + "requires": { + "camelcase": "^4.1.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^2.0.0", + "read-pkg-up": "^2.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^7.0.0" + } + } + } + }, + "react-native-camera": { + "version": "2.11.1", + "resolved": "https://registry.npmjs.org/react-native-camera/-/react-native-camera-2.11.1.tgz", + "integrity": "sha512-ZmPZHcY7UXEf7Z8PoJX/WhFtmLFtdRPBGDwemOLlPRVwTVyu/OXVINDUWCug4daBqV8Fs3X1O6V927+K2u2GfA==", + "requires": { + "prop-types": "^15.6.2" + } + }, + "react-native-country-picker-modal": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/react-native-country-picker-modal/-/react-native-country-picker-modal-0.6.2.tgz", + "integrity": "sha1-upcRi+Q3O+DBHNUeRF5r1Eji8co=", + "requires": { + "fuse.js": "2.6.2", + "lodash": "4.12.0", + "node-emoji": "1.8.1", + "prop-types": "15.6.0", + "react-native-safe-area-view": "^0.7.0", + "world-countries": "1.8.0" + }, + "dependencies": { + "core-js": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", + "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=" + }, + "fbjs": { + "version": "0.8.17", + "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz", + "integrity": "sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=", + "requires": { + "core-js": "^1.0.0", + "isomorphic-fetch": "^2.1.1", + "loose-envify": "^1.0.0", + "object-assign": "^4.1.0", + "promise": "^7.1.1", + "setimmediate": "^1.0.5", + "ua-parser-js": "^0.7.18" + } + }, + "lodash": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.12.0.tgz", + "integrity": "sha1-K9bcRqBA9Z5obJcu0h2T3FkFMlg=" + }, + "prop-types": { + "version": "15.6.0", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.0.tgz", + "integrity": "sha1-zq8IMCL8RrSjX2nhPvda7Q1jmFY=", + "requires": { + "fbjs": "^0.8.16", + "loose-envify": "^1.3.1", + "object-assign": "^4.1.1" + } + } + } + }, + "react-native-document-picker": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/react-native-document-picker/-/react-native-document-picker-2.3.0.tgz", + "integrity": "sha512-bHMyAOzFl+II0ZdfzobKsZKvTErmXfmQGalpxpGbeN8+/uhfhUcdp4WuIMecZhFyX6rbj3h3XXLdA12hVlGgmw==" + }, + "react-native-exception-handler": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/react-native-exception-handler/-/react-native-exception-handler-2.9.0.tgz", + "integrity": "sha512-XRHhGH5aM4lSenX4zZBa07JaszJGXeF8cv1KY314Q4qJWOihKWLpkdvwqwsBieZ2iy8DPhdAVioQzw8JLD/Okw==" + }, + "react-native-fast-image": { + "version": "5.4.2", + "resolved": "https://registry.npmjs.org/react-native-fast-image/-/react-native-fast-image-5.4.2.tgz", + "integrity": "sha512-S4E96Lwmx6z6QD3MaAuP7cNcXRLfgEUYU2GB694TbGEoOjk/FO1OnfbxfFp0vUs/klr4HJwACcwihPPxrFTt8w==" + }, + "react-native-fs": { + "version": "2.13.3", + "resolved": "https://registry.npmjs.org/react-native-fs/-/react-native-fs-2.13.3.tgz", + "integrity": "sha512-B62LSSAEYQGItg7KVTzTVVCxezOYFBYp4DMVFbdoZUd1mZVFdqR2sy1HY1mye1VI/Lf3IbxSyZEQ0GmrrdwLjg==", + "requires": { + "base-64": "^0.1.0", + "utf8": "^2.1.1" + } + }, + "react-native-gesture-handler": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-1.3.0.tgz", + "integrity": "sha512-ASRFIXBuKRvqlmwkWJhV8yP2dTpvcqVrLNpd7FKVBFHYWr6SAxjGyO9Ik8w1lAxDhMlRP2IcJ9p9eq5X2WWeLQ==", + "requires": { + "hoist-non-react-statics": "^2.3.1", + "invariant": "^2.2.2", + "prop-types": "^15.5.10" + } + }, + "react-native-image-pan-zoom": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/react-native-image-pan-zoom/-/react-native-image-pan-zoom-2.1.11.tgz", + "integrity": "sha512-ZCisGUFpPchHXsjT7ZI0anlSLPgcTmjRKXqpVnPu3RDWFXfKjuL4zpY57DX4Y8YgGZCpbf9fApN7KjVYody2Mw==" + }, + "react-native-image-zoom-viewer": { + "version": "2.2.26", + "resolved": "https://registry.npmjs.org/react-native-image-zoom-viewer/-/react-native-image-zoom-viewer-2.2.26.tgz", + "integrity": "sha512-Mh4+CJQCDcAumLFXLlDk8nQ5iMxNnupc9HwktsZ3I/v4HULcFPmTLDQ0HGAxjLa5foZRPnKDN06iKGsEb9raoA==", + "requires": { + "react-native-image-pan-zoom": "^2.1.9" + } + }, + "react-native-password-strength-meter": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/react-native-password-strength-meter/-/react-native-password-strength-meter-0.0.2.tgz", + "integrity": "sha512-jONkwnbznl2xJnJK3/eGa/EL87darI6n+/FtVFXRdyGqypWy6lFJALn/C6m9FyodVArrrpXJ60Ke8nWaGmPALw==", + "requires": { + "prop-types": "^15.6.2", + "react-native-speedometer": "^1.0.0" + } + }, + "react-native-phone-input": { + "version": "github:lbryio/react-native-phone-input#60fdef484e8bf27328c7fb6a203baab9eb9cd4a1", + "from": "github:lbryio/react-native-phone-input", + "requires": { + "google-libphonenumber": "^2.0.9", + "lodash": "^4.17.4", + "prop-types": "^15.5.10" + } + }, + "react-native-safe-area-view": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/react-native-safe-area-view/-/react-native-safe-area-view-0.7.0.tgz", + "integrity": "sha512-SjLdW/Th0WVMhyngH4O6yC21S+O4U4AAG3QxBr7fZ2ftgjXSpKbDHAhEpxBdFwei6HsnsC2h9oYMtPpaW9nfGg==", + "requires": { + "hoist-non-react-statics": "^2.3.1" + } + }, + "react-native-screens": { + "version": "1.0.0-alpha.23", + "resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-1.0.0-alpha.23.tgz", + "integrity": "sha512-tOxHGQUN83MTmQB4ghoQkibqOdGiX4JQEmeyEv96MKWO/x8T2PJv84ECUos9hD3blPRQwVwSpAid1PPPhrVEaw==", + "requires": { + "debounce": "^1.2.0" + } + }, + "react-native-speedometer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/react-native-speedometer/-/react-native-speedometer-1.0.3.tgz", + "integrity": "sha512-34Ne/ptaWv97jbSOq87b+gKHvGKeZ4AjYXZvovbEnQMnYNzCBWZbQNJqWWzOxyFZXbzeDsfiQ6d4xpq2pc1Tfw==", + "requires": { + "prop-types": "^15.6.2" + } + }, + "react-native-super-grid": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/react-native-super-grid/-/react-native-super-grid-3.0.7.tgz", + "integrity": "sha512-cjsEJ536kmWRv9UFjqer7vNLbmMYHetsOXSez8CREUknBP4z+wAUfejDwbUy/iyksK+vrQCII6dn+pUNiSkMxw==", + "requires": { + "prop-types": "^15.6.0" + } + }, + "react-native-tab-view": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/react-native-tab-view/-/react-native-tab-view-1.4.1.tgz", + "integrity": "sha512-Bke8KkDcDhvB/z0AS7MnQKMD2p6Kwfc1rSKlMOvg9CC5CnClQ2QEnhPSbwegKDYhUkBI92iH/BYy7hNSm5kbUQ==", + "requires": { + "prop-types": "^15.6.1" + } + }, + "react-native-vector-icons": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/react-native-vector-icons/-/react-native-vector-icons-6.6.0.tgz", + "integrity": "sha512-MImKVx8JEvVVBnaShMr7/yTX4Y062JZMupht1T+IEgbqBj4aQeQ1z2SH4VHWKNtWtppk4kz9gYyUiMWqx6tNSw==", + "requires": { + "lodash": "^4.0.0", + "prop-types": "^15.6.2", + "yargs": "^13.2.2" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "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" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.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==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "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==" + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "requires": { + "pump": "^3.0.0" + } + }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==" + }, + "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=" + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "requires": { + "invert-kv": "^2.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==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "mem": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "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==", + "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==", + "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==" + }, + "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==" + }, + "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==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^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==", + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "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==", + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.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==" + }, + "yargs": { + "version": "13.2.4", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.4.tgz", + "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==", + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "os-locale": "^3.1.0", + "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.0" + } + }, + "yargs-parser": { + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", + "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "react-native-video": { + "version": "github:lbryio/react-native-video#7366652125f1e08c5ab128da630af0420357d33c", + "from": "github:lbryio/react-native-video#exoplayer-lbry-android", + "requires": { + "keymirror": "^0.1.1", + "prop-types": "^15.5.10", + "shaka-player": "^2.4.4" + } + }, + "react-navigation": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/react-navigation/-/react-navigation-3.11.0.tgz", + "integrity": "sha512-wlPcDtNiIdPeYxNQ/MN4arY5Xe9EphD2QVpRuvvuPWW+BamF3AJaIy060r3Yz59DODAoWllscabat/yqnih8Tg==", + "requires": { + "@react-navigation/core": "~3.4.1", + "@react-navigation/native": "~3.5.0", + "react-navigation-drawer": "~1.2.1", + "react-navigation-stack": "~1.4.0", + "react-navigation-tabs": "~1.1.4" + } + }, + "react-navigation-drawer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/react-navigation-drawer/-/react-navigation-drawer-1.2.1.tgz", + "integrity": "sha512-T2kaBjY2c4/3I6noWFnaf/c18ntNH5DsST38i+pdc2NPxn5Yi5lkK+ZZTeKuHSFD4a7G0jWY9OGf1iRkHWLMAQ==", + "requires": { + "react-native-tab-view": "^1.2.0" + } + }, + "react-navigation-redux-helpers": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/react-navigation-redux-helpers/-/react-navigation-redux-helpers-3.0.2.tgz", + "integrity": "sha512-+z7/eBGBpws/W3ffu7ayEl1YFMAbXO3Sgul3KIDyESI1BbmfSvKD2aRMEfE7AlO+58fJJsqWUMhNw+VACAdHjw==", + "requires": { + "invariant": "^2.2.2" + } + }, + "react-navigation-stack": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/react-navigation-stack/-/react-navigation-stack-1.4.0.tgz", + "integrity": "sha512-zEe9wCA0Ot8agarYb//0nSWYW1GM+1R0tY/nydUV0EizeJ27At0EklYVWvYEuYU6C48va6cu8OPL7QD/CcJACw==" + }, + "react-navigation-tabs": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/react-navigation-tabs/-/react-navigation-tabs-1.1.4.tgz", + "integrity": "sha512-py2hLCRxPwXOzmY1W9XcY1rWXxdK6RGW/aXh56G9gIf8cpHNDhy/bJV4e46/JrVcse3ybFaN0liT09/DM/NdwQ==", + "requires": { + "hoist-non-react-statics": "^2.5.0", + "prop-types": "^15.6.1", + "react-lifecycles-compat": "^3.0.4", + "react-native-tab-view": "^1.4.1" + } + }, + "react-proxy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/react-proxy/-/react-proxy-1.1.8.tgz", + "integrity": "sha1-nb/Z2SdSjDqp9ETkVYw3gwq4wmo=", + "requires": { + "lodash": "^4.6.1", + "react-deep-force-update": "^1.0.0" + } + }, + "react-redux": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-5.1.1.tgz", + "integrity": "sha512-LE7Ned+cv5qe7tMV5BPYkGQ5Lpg8gzgItK07c67yHvJ8t0iaD9kPFPAli/mYkiyJYrs2pJgExR2ZgsGqlrOApg==", + "requires": { + "@babel/runtime": "^7.1.2", + "hoist-non-react-statics": "^3.1.0", + "invariant": "^2.2.4", + "loose-envify": "^1.1.0", + "prop-types": "^15.6.1", + "react-is": "^16.6.0", + "react-lifecycles-compat": "^3.0.0" + }, + "dependencies": { + "hoist-non-react-statics": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.0.tgz", + "integrity": "sha512-0XsbTXxgiaCDYDIWFcwkmerZPSwywfUqYmwT4jzewKTQSWoE6FCMoUVOeBJWK3E/CrWbxRG3m5GzY4lnIwGRBA==", + "requires": { + "react-is": "^16.7.0" + } + } + } + }, + "react-refresh": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.2.0.tgz", + "integrity": "sha512-ITw8t/HOFNose2yf1y9pPFSSeB9ISOq2JdHpuZvj/Qb+iSsLml8GkkHdDlURzieO7B3dFDtMrrneZLl3N5z/hg==", + "dev": true + }, + "react-transform-hmr": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/react-transform-hmr/-/react-transform-hmr-1.0.4.tgz", + "integrity": "sha1-4aQL0Krvxy6N/Xp82gmvhQZjl7s=", + "requires": { + "global": "^4.3.0", + "react-proxy": "^1.1.7" + } + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.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==", + "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" + } + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "dev": true, + "requires": { + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" + }, + "dependencies": { + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "dev": true, + "requires": { + "repeating": "^2.0.0" + } + }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "dev": true, + "requires": { + "get-stdin": "^4.0.1" + } + } + } + }, + "redux": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.0.4.tgz", + "integrity": "sha512-vKv4WdiJxOWKxK0yRoaK3Y4pxxB0ilzVx6dszU2W8wLxlb2yikRph4iV/ymtdJ6ZxpBLFbyrxklnT5yBbQSl3Q==", + "requires": { + "loose-envify": "^1.4.0", + "symbol-observable": "^1.2.0" + } + }, + "redux-persist": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/redux-persist/-/redux-persist-5.10.0.tgz", + "integrity": "sha512-sSJAzNq7zka3qVHKce1hbvqf0Vf5DuTVm7dr4GtsqQVOexnrvbV47RWFiPxQ8fscnyiuWyD2O92DOxPl0tGCRg==" + }, + "redux-persist-filesystem-storage": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/redux-persist-filesystem-storage/-/redux-persist-filesystem-storage-1.4.1.tgz", + "integrity": "sha512-QDBlRWdFpn4JMrdLZcimwT7d3yc0xkSnA5j9xKWAY2Qw9rd3Uzlt76qXwEuuQ4M3qgKu/nLE8Roazl5BUcxfcA==", + "requires": { + "rn-fetch-blob": "0.10.15" + } + }, + "redux-persist-transform-compress": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/redux-persist-transform-compress/-/redux-persist-transform-compress-4.2.0.tgz", + "integrity": "sha1-UInimd9xMIePykX5f/6CiIugJpA=", + "requires": { + "json-stringify-safe": "^5.0.1", + "lz-string": "^1.4.4" + } + }, + "redux-persist-transform-filter": { + "version": "0.0.18", + "resolved": "https://registry.npmjs.org/redux-persist-transform-filter/-/redux-persist-transform-filter-0.0.18.tgz", + "integrity": "sha512-x9NxuHNDnK/THLLBqwP1tqw0yIcuxuVYXBssgGcmm5anxL0flbpLQGB5CbFYHWGG68VdQKr1vUneVnttxWJDtA==", + "requires": { + "lodash.clonedeep": "^4.5.0", + "lodash.forin": "^4.4.0", + "lodash.get": "^4.4.2", + "lodash.isempty": "^4.4.0", + "lodash.pickby": "^4.6.0", + "lodash.set": "^4.3.2", + "lodash.unset": "^4.5.2" + } + }, + "redux-thunk": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.3.0.tgz", + "integrity": "sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw==" + }, + "regenerate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==" + }, + "regenerate-unicode-properties": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz", + "integrity": "sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA==", + "requires": { + "regenerate": "^1.4.0" + } + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + }, + "regenerator-transform": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.0.tgz", + "integrity": "sha512-rtOelq4Cawlbmq9xuMR5gdFmv7ku/sFoB7sRiywx7aq53bc52b4j6zvH7Te1Vt/X2YveDKnCGUbioieU7FEL3w==", + "requires": { + "private": "^0.1.6" + } + }, + "regex-cache": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", + "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "requires": { + "is-equal-shallow": "^0.1.3" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true + }, + "regexpu-core": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.5.4.tgz", + "integrity": "sha512-BtizvGtFQKGPUcTy56o3nk1bGRp4SZOTYrDtGNlqCQufptV5IkkLN6Emw+yunAJjzf+C9FQFtvq7IoA3+oMYHQ==", + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.0.2", + "regjsgen": "^0.5.0", + "regjsparser": "^0.6.0", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.1.0" + } + }, + "registry-auth-token": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz", + "integrity": "sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==", + "dev": true, + "requires": { + "rc": "^1.1.6", + "safe-buffer": "^5.0.1" + } + }, + "registry-url": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", + "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", + "dev": true, + "requires": { + "rc": "^1.0.1" + } + }, + "regjsgen": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.0.tgz", + "integrity": "sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA==" + }, + "regjsparser": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.0.tgz", + "integrity": "sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==", + "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=" + } + } + }, + "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=" + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==" + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" + }, + "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" + } + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" + }, + "reselect": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-3.0.1.tgz", + "integrity": "sha1-79qpjqdFEyTQkrKyFjpqHXqaIUc=" + }, + "resolve": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz", + "integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==", + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=" + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "requires": { + "glob": "^7.1.3" + } + }, + "rn-fetch-blob": { + "version": "0.10.15", + "resolved": "https://registry.npmjs.org/rn-fetch-blob/-/rn-fetch-blob-0.10.15.tgz", + "integrity": "sha512-/m/gurTaPAvR3J843uehHhznj5k89x7XClyO5ejmbspNLNQ4ByF+kZs80wiiKGWntj+Wqo0jJu1goArXEfc0kA==", + "requires": { + "base-64": "0.1.0", + "glob": "7.0.6" + }, + "dependencies": { + "glob": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz", + "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.2", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, + "rsvp": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-3.6.2.tgz", + "integrity": "sha512-OfWGQTb9vnwRjwtA2QwpG2ICclHC3pgXZO5xt8H2EfgDquO0qVdSb5T88L4qJVAEugbS56pAuV4XZM58UX8ulw==" + }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "requires": { + "is-promise": "^2.1.0" + } + }, + "rx-lite": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", + "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=" + }, + "rx-lite-aggregates": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", + "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", + "requires": { + "rx-lite": "*" + } + }, + "rxjs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz", + "integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "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=", + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "sane": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/sane/-/sane-3.1.0.tgz", + "integrity": "sha512-G5GClRRxT1cELXfdAq7UKtUsv8q/ZC5k8lQGmjEm4HcAl3HzBy68iglyNCmw4+0tiXPCBZntslHlRhbnsSws+Q==", + "requires": { + "anymatch": "^2.0.0", + "capture-exit": "^1.2.0", + "exec-sh": "^0.2.0", + "execa": "^1.0.0", + "fb-watchman": "^2.0.0", + "fsevents": "^1.2.3", + "micromatch": "^3.1.4", + "minimist": "^1.1.1", + "walker": "~1.0.5", + "watch": "~0.18.0" + }, + "dependencies": { + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "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=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "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=", + "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=", + "requires": { + "is-extendable": "^0.1.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=", + "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=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "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=", + "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=", + "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==", + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "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==" + } + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "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=", + "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=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "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=", + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "requires": { + "pump": "^3.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==", + "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==", + "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==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "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=", + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "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" + } + } + } + }, + "sax": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.1.6.tgz", + "integrity": "sha1-XWFr6KXmB9VOEUr65Vt+ry/MMkA=" + }, + "scheduler": { + "version": "0.13.6", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.13.6.tgz", + "integrity": "sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ==", + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" + }, + "semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", + "dev": true + }, + "semver-diff": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", + "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", + "dev": true, + "requires": { + "semver": "^5.0.3" + } + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + } + } + }, + "serialize-error": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-2.1.0.tgz", + "integrity": "sha1-ULZ51WNc34Rme9yOWa9OW4HV9go=" + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "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==", + "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=", + "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=" + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "shaka-player": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/shaka-player/-/shaka-player-2.5.3.tgz", + "integrity": "sha512-9HwdBXiMNglq2IcjTWCMIwv4s1gucyHEOYWc6YX5NcxyiyQfVP+VG3eADWJXgFv3RF3mma1YPKX83q0PbyxoAQ==" + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "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=" + }, + "shell-quote": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz", + "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=", + "requires": { + "array-filter": "~0.0.0", + "array-map": "~0.0.0", + "array-reduce": "~0.0.0", + "jsonify": "~0.0.0" + } + }, + "shellwords": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==" + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" + }, + "simple-plist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/simple-plist/-/simple-plist-1.0.0.tgz", + "integrity": "sha512-043L2rO80LVF7zfZ+fqhsEkoJFvW8o59rt/l4ctx1TJWoTx7/jkiS1R5TatD15Z1oYnuLJytzE7gcnnBuIPL2g==", + "requires": { + "bplist-creator": "0.0.7", + "bplist-parser": "0.1.1", + "plist": "^3.0.1" + } + }, + "single-line-log": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/single-line-log/-/single-line-log-1.1.2.tgz", + "integrity": "sha1-wvg/Jzo+GhbtsJlWYdoO1e8DM2Q=", + "dev": true, + "requires": { + "string-width": "^1.0.1" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } + } + }, + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==" + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + }, + "dependencies": { + "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" + } + }, + "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 + } + } + }, + "slide": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", + "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=" + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "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=", + "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=", + "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==", + "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=", + "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==", + "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==", + "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==", + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "requires": { + "kind-of": "^3.2.0" + } + }, + "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.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "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.12", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz", + "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==", + "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==" + } + } + }, + "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=" + }, + "spdx-correct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==" + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==" + }, + "speedometer": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/speedometer/-/speedometer-0.1.4.tgz", + "integrity": "sha1-mHbb0qFp0xFUAtSObqYynIgWpQ0=", + "dev": true + }, + "split-on-first": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", + "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==" + }, + "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==", + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "stacktrace-parser": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.6.tgz", + "integrity": "sha512-wXhu0Z8YgCGigUtHQq+J7pjXCppk3Um5DwH4qskOKHMlJmKwuuUSm+wDAgU7t4sbVjvuDTNGwOfFKgjMEqSflA==", + "requires": { + "type-fest": "^0.3.0" + } + }, + "staged-git-files": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/staged-git-files/-/staged-git-files-1.1.1.tgz", + "integrity": "sha512-H89UNKr1rQJvI1c/PIR3kiAMBV23yvR7LItZiV74HWZwzt7f3YHuujJ9nJZlt58WlFox7XQsOahexwk7nTe69A==", + "dev": true + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "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=", + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" + }, + "stream-buffers": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz", + "integrity": "sha1-kdX1Ew0c75bc+n9yaUUYh0HQnuQ=" + }, + "strict-uri-encode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", + "integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY=" + }, + "string-argv": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.0.2.tgz", + "integrity": "sha1-2sMECGkMIfPDYwo/86BYd73L1zY=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + }, + "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=" + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "requires": { + "ansi-regex": "^3.0.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==", + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dev": true, + "requires": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.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=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" + }, + "strip-indent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", + "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "sumchecker": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-1.3.1.tgz", + "integrity": "sha1-ebs7RFbdBPGOvbwNcDodHa7FEF0=", + "dev": true, + "requires": { + "debug": "^2.2.0", + "es6-promise": "^4.0.5" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + }, + "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==" + }, + "table": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.1.tgz", + "integrity": "sha512-E6CK1/pZe2N75rGZQotFOdmzWQ1AILtgYbMAbAjvms0S1l5IDB47zG3nCnFGB/w+7nB3vKofbLXCH7HPBo864w==", + "dev": true, + "requires": { + "ajv": "^6.9.1", + "lodash": "^4.17.11", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "dependencies": { + "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 + }, + "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 + }, + "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" + } + }, + "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" + } + } + } + }, + "temp": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz", + "integrity": "sha1-4Ma8TSa5AxJEEOT+2BEDAU38H1k=", + "requires": { + "os-tmpdir": "^1.0.0", + "rimraf": "~2.2.6" + }, + "dependencies": { + "rimraf": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", + "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=" + } + } + }, + "term-size": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", + "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", + "dev": true, + "requires": { + "execa": "^0.7.0" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "throat": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz", + "integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=" + }, + "throttleit": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz", + "integrity": "sha1-z+34jmDADdlpe2H90qg0OptoDq8=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "time-stamp": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", + "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=" + }, + "timed-out": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", + "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "tmpl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", + "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=" + }, + "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=", + "requires": { + "kind-of": "^3.0.2" + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "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=", + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "requires": { + "kind-of": "^3.0.2" + } + } + } + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "dev": true, + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + } + } + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "dev": true + }, + "trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=" + }, + "tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", + "dev": true + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-fest": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", + "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==" + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" + }, + "ua-parser-js": { + "version": "0.7.20", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.20.tgz", + "integrity": "sha512-8OaIKfzL5cpx8eCMAhhvTlft8GYF8b2eQr6JkCyVdrgjcytyOmPCXrqXFcUnhonRpLlh5yxEZVohm6mzaowUOw==" + }, + "uglify-es": { + "version": "3.3.9", + "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", + "integrity": "sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ==", + "requires": { + "commander": "~2.13.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "commander": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz", + "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "ultron": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz", + "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=" + }, + "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==" + }, + "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==", + "requires": { + "unicode-canonical-property-names-ecmascript": "^1.0.4", + "unicode-property-aliases-ecmascript": "^1.0.4" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz", + "integrity": "sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g==" + }, + "unicode-property-aliases-ecmascript": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz", + "integrity": "sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw==" + }, + "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==", + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + } + }, + "unique-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", + "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", + "dev": true, + "requires": { + "crypto-random-string": "^1.0.0" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "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=", + "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=", + "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=" + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + } + } + }, + "unzip-response": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", + "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=", + "dev": true + }, + "update-notifier": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz", + "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", + "dev": true, + "requires": { + "boxen": "^1.2.1", + "chalk": "^2.0.1", + "configstore": "^3.0.0", + "import-lazy": "^2.1.0", + "is-ci": "^1.0.10", + "is-installed-globally": "^0.1.0", + "is-npm": "^1.0.0", + "latest-version": "^3.0.0", + "semver-diff": "^2.0.0", + "xdg-basedir": "^3.0.0" + } + }, + "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=" + }, + "url-parse-lax": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", + "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", + "dev": true, + "requires": { + "prepend-http": "^1.0.1" + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" + }, + "utf8": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.2.tgz", + "integrity": "sha1-H6DZJw6b6FDZsFAn9jUZv0ZFfZY=" + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "walker": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", + "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "requires": { + "makeerror": "1.0.x" + } + }, + "watch": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/watch/-/watch-0.18.0.tgz", + "integrity": "sha1-KAlUdsbffJDJYxOJkMClQj60uYY=", + "requires": { + "exec-sh": "^0.2.0", + "minimist": "^1.2.0" + } + }, + "whatwg-fetch": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz", + "integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==" + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "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=" + }, + "widest-line": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", + "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", + "dev": true, + "requires": { + "string-width": "^2.1.1" + } + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" + }, + "world-countries": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/world-countries/-/world-countries-1.8.0.tgz", + "integrity": "sha1-F/SOfoRwrFohNq1pON/GVvwry5U=" + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, + "write-file-atomic": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.3.4.tgz", + "integrity": "sha1-+Aek8LHZ6ROuekgRLmzDrxmRtF8=", + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "slide": "^1.1.5" + } + }, + "ws": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz", + "integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==", + "requires": { + "options": ">=0.0.5", + "ultron": "1.0.x" + } + }, + "xcode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xcode/-/xcode-2.0.0.tgz", + "integrity": "sha512-5xF6RCjAdDEiEsbbZaS/gBRt3jZ/177otZcpoLCjGN/u1LrfgH7/Sgeeavpr/jELpyDqN2im3AKosl2G2W8hfw==", + "requires": { + "simple-plist": "^1.0.0", + "uuid": "^3.3.2" + } + }, + "xdg-basedir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", + "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", + "dev": true + }, + "xmlbuilder": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=" + }, + "xmldoc": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/xmldoc/-/xmldoc-0.4.0.tgz", + "integrity": "sha1-0lciS+g5PqrL+DfvIn/Y7CWzaIg=", + "requires": { + "sax": "~1.1.1" + } + }, + "xmldom": { + "version": "0.1.27", + "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", + "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" + }, + "xpipe": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/xpipe/-/xpipe-1.0.5.tgz", + "integrity": "sha1-jdi/Rfw/f1Xw4FS4ePQ6YmFNr98=" + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + }, + "yargs": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz", + "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=", + "requires": { + "camelcase": "^4.1.0", + "cliui": "^3.2.0", + "decamelize": "^1.1.1", + "get-caller-file": "^1.0.1", + "os-locale": "^2.0.0", + "read-pkg-up": "^2.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^7.0.0" + } + }, + "yargs-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", + "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", + "requires": { + "camelcase": "^4.1.0" + } + }, + "yauzl": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", + "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", + "dev": true, + "requires": { + "fd-slicer": "~1.0.1" + } + } + } +} diff --git a/package.json b/package.json index 0338f00..608ad18 100644 --- a/package.json +++ b/package.json @@ -1,90 +1,70 @@ { - "name": "LBRYApp", - "version": "0.0.1", - "private": true, - "scripts": { - "android": "react-native run-android", - "ios": "react-native run-ios", - "start": "react-native start", - "test": "jest", - "lint": "eslint .", - "format": "prettier 'src/**/*.{js,json}' --write", - "precommit": "lint-staged" - }, - "dependencies": { - "base-64": "^0.1.0", - "@expo/vector-icons": "^8.1.0", - "gfycat-style-urls": "^1.0.3", - "lbry-redux": "lbryio/lbry-redux#69ffd110dbf3633e5847f61f008751edec033017", - "lbryinc": "lbryio/lbryinc#667024ebb7cb207609273174ca422cee47469270", - "lodash": ">=4.17.11", - "merge": ">=1.2.1", - "moment": "^2.22.1", - "react": "16.9.0", - "react-native": "0.61.5", - "@react-native-community/async-storage": "^1.5.1", - "@react-native-community/masked-view": "^0.1.5", - "react-native-camera": "^3.15.0", - "react-native-country-picker-modal": "^1.10.0", - "react-native-exception-handler": "2.10.8", - "react-native-fast-image": "^7.0.2", - "react-native-fs": "^2.16.6", - "react-native-gesture-handler": "1.5.2", - "react-native-image-zoom-viewer": "^2.2.5", - "react-native-password-strength-meter": "^0.0.2", - "react-native-phone-input": "lbryio/react-native-phone-input", - "react-native-progress-circle": "2.1.0", - "react-native-reanimated": "1.4.0", - "react-native-safe-area-context": "^0.6.2", - "react-native-screens": "^2.0.0", - "react-native-snackbar": "2.0.4", - "react-native-super-grid": "^3.0.4", - "react-native-vector-icons": "^6.6.0", - "react-native-video": "lbryio/react-native-video#7992ff945872f9bd00a3736d9ff1318f343abf47", - "react-native-webview": "^8.0.2", - "react-navigation": "^4.0.10", - "react-navigation-drawer": "2.3.3", - "react-navigation-redux-helpers": "^3.0.2", - "react-navigation-tabs": "^2.7.0", - "react-navigation-stack": "^1.10.3", - "react-redux": "^5.0.3", - "redux": "^4.0.4", - "redux-persist": "^6.0.0", - "redux-persist-filesystem-storage": "^2.1.0", - "redux-persist-transform-compress": "^4.2.0", - "redux-persist-transform-filter": "0.0.18", - "redux-thunk": "^2.3.0", - "rn-fetch-blob": "0.12.0", - "seedrandom": "3.0.3", - "showdown": "1.9.1" - }, - "devDependencies": { - "@babel/core": "^7.6.2", - "babel-eslint": "10.0.2", - "@babel/plugin-proposal-object-rest-spread": "^7.5.4", - "babel-preset-env": "^1.6.1", - "babel-preset-stage-2": "^6.18.0", - "babel-plugin-module-resolver": "^3.1.1", - "eslint": "^6.5.1", - "eslint-config-standard": "^12.0.0", - "eslint-config-standard-jsx": "^6.0.2", - "eslint-plugin-flowtype": "^2.46.1", - "eslint-plugin-import": "^2.17.2", - "eslint-plugin-node": "^8.0.1", - "eslint-plugin-promise": "^4.1.1", - "eslint-plugin-react": "^7.12.4", - "eslint-plugin-standard": "^4.0.0", - "flow-babel-webpack-plugin": "^1.1.1", - "husky": "^0.14.3", - "lint-staged": "^7.0.4", - "metro-react-native-babel-preset": "0.56.3", - "prettier": "^1.11.1", - "@react-native-community/eslint-config": "^0.0.5", - "react-devtools": "^3.6.3", - "reactotron-react-native": "4.0.2", - "reactotron-redux": "3.1.2" - }, - "jest": { - "preset": "react-native" - } + "name": "LBRYApp", + "version": "0.0.1", + "private": "true", + "scripts": { + "start": "node node_modules/react-native/local-cli/cli.js start", + "devtools": "react-devtools", + "format": "prettier 'src/**/*.{js,json}' --write", + "precommit": "lint-staged" + }, + "dependencies": { + "base-64": "^0.1.0", + "@expo/vector-icons": "^8.1.0", + "gfycat-style-urls": "^1.0.3", + "lbry-redux": "lbryio/lbry-redux#67a654f60630710cae72419448a73a18d076d18a", + "lbryinc": "lbryio/lbryinc", + "lodash": ">=4.17.11", + "merge": ">=1.2.1", + "moment": "^2.22.1", + "react": "16.8.6", + "react-native": "0.59.10", + "@react-native-community/async-storage": "^1.5.1", + "react-native-camera": "^2.11.0", + "react-native-country-picker-modal": "^0.6.2", + "react-native-document-picker": "^2.3.0", + "react-native-exception-handler": "2.9.0", + "react-native-fast-image": "^5.0.3", + "react-native-fs": "^2.13.3", + "react-native-gesture-handler": "^1.1.0", + "react-native-image-zoom-viewer": "^2.2.5", + "react-native-password-strength-meter": "^0.0.2", + "react-native-phone-input": "lbryio/react-native-phone-input", + "react-native-super-grid": "^3.0.4", + "react-native-vector-icons": "^6.4.2", + "react-native-video": "lbryio/react-native-video#exoplayer-lbry-android", + "react-navigation": "^3.11.0", + "react-navigation-redux-helpers": "^3.0.2", + "react-redux": "^5.0.3", + "redux": "^4.0.4", + "redux-persist": "^5.10.0", + "redux-persist-filesystem-storage": "^1.3.2", + "redux-persist-transform-compress": "^4.2.0", + "redux-persist-transform-filter": "0.0.18", + "redux-thunk": "^2.3.0", + "rn-fetch-blob": "0.10.15" + }, + "devDependencies": { + "@babel/core": "^7.5.4", + "babel-eslint": "10.0.2", + "@babel/plugin-proposal-object-rest-spread": "^7.5.4", + "babel-preset-env": "^1.6.1", + "babel-preset-stage-2": "^6.18.0", + "babel-plugin-module-resolver": "^3.1.1", + "eslint": "^5.16.0", + "eslint-config-standard": "^12.0.0", + "eslint-config-standard-jsx": "^6.0.2", + "eslint-plugin-flowtype": "^2.46.1", + "eslint-plugin-import": "^2.17.2", + "eslint-plugin-node": "^8.0.1", + "eslint-plugin-promise": "^4.1.1", + "eslint-plugin-react": "^7.12.4", + "eslint-plugin-standard": "^4.0.0", + "flow-babel-webpack-plugin": "^1.1.1", + "husky": "^0.14.3", + "lint-staged": "^7.0.4", + "metro-react-native-babel-preset": "^0.55.0", + "prettier": "^1.11.1", + "react-devtools": "^3.6.3" + } } diff --git a/reactotron.js b/reactotron.js deleted file mode 100644 index 4e8ff1a..0000000 --- a/reactotron.js +++ /dev/null @@ -1,12 +0,0 @@ -import AsyncStorage from '@react-native-community/async-storage'; -import Reactotron from 'reactotron-react-native'; -import { reactotronRedux } from 'reactotron-redux'; - -const reactotron = Reactotron - .setAsyncStorageHandler(AsyncStorage) // AsyncStorage would either come from `react-native` or `@react-native-community/async-storage` depending on where you get it from - .configure() // controls connection & communication settings - .useReactNative() // add all built-in react native plugins - .use(reactotronRedux()) - .connect(); - -export default reactotron; \ No newline at end of file diff --git a/src/assets/gerbil-happy.png b/src/assets/gerbil-happy.png deleted file mode 100644 index 4247f83..0000000 Binary files a/src/assets/gerbil-happy.png and /dev/null differ diff --git a/src/assets/gerbil-sad.png b/src/assets/gerbil-sad.png deleted file mode 100644 index 153d4ad..0000000 Binary files a/src/assets/gerbil-sad.png and /dev/null differ diff --git a/src/component/AppNavigator.js b/src/component/AppNavigator.js index d003376..4db09a6 100644 --- a/src/component/AppNavigator.js +++ b/src/component/AppNavigator.js @@ -1,13 +1,10 @@ import React from 'react'; import AboutPage from 'page/about'; -import ChannelCreatorPage from 'page/channelCreator'; import DiscoverPage from 'page/discover'; import DownloadsPage from 'page/downloads'; import DrawerContent from 'component/drawerContent'; import FilePage from 'page/file'; -import LiteFilePage from 'page/liteFile'; import FirstRunScreen from 'page/firstRun'; -import InvitesPage from 'page/invites'; import PublishPage from 'page/publish'; import PublishesPage from 'page/publishes'; import RewardsPage from 'page/rewards'; @@ -20,44 +17,17 @@ import SubscriptionsPage from 'page/subscriptions'; import TransactionHistoryPage from 'page/transactionHistory'; import VerificationScreen from 'page/verification'; import WalletPage from 'page/wallet'; -import { NavigationActions, StackActions } from 'react-navigation'; -import { createDrawerNavigator } from 'react-navigation-drawer'; -import { createStackNavigator } from 'react-navigation-stack'; +import { createDrawerNavigator, createStackNavigator, NavigationActions } from 'react-navigation'; import { createReduxContainer, createReactNavigationReduxMiddleware, createNavigationReducer, } from 'react-navigation-redux-helpers'; import { connect } from 'react-redux'; -import { - AppState, - Alert, - BackHandler, - DeviceEventEmitter, - Linking, - NativeModules, - StatusBar, - TextInput, - ToastAndroid, -} from 'react-native'; +import { AppState, BackHandler, Linking, NativeModules, TextInput, ToastAndroid } from 'react-native'; import { selectDrawerStack } from 'redux/selectors/drawer'; +import { SETTINGS, doDismissToast, doToast, selectToast } from 'lbry-redux'; import { - Lbry, - ACTIONS, - SETTINGS, - doBalanceSubscribe, - doDismissToast, - doPopulateSharedUserState, - doPreferenceGet, - doToast, - selectToast, -} from 'lbry-redux'; -import { - Lbryio, - rewards as REWARD_TYPES, - doBlackListedOutpointsSubscribe, - doClaimRewardType, - doFilteredOutpointsSubscribe, doGetSync, doUserCheckEmailVerified, doUserEmailVerify, @@ -65,13 +35,11 @@ import { selectEmailToVerify, selectEmailVerifyIsPending, selectEmailVerifyErrorMessage, - selectHashChanged, selectUser, } from 'lbryinc'; -import { doStartDownload, doUpdateDownload, doCompleteDownload } from 'redux/actions/file'; -import { makeSelectClientSetting, selectFullscreenMode } from 'redux/selectors/settings'; +import { makeSelectClientSetting } from 'redux/selectors/settings'; import { decode as atob } from 'base-64'; -import { dispatchNavigateBack, dispatchNavigateToUri, transformUrl } from 'utils/helper'; +import { dispatchNavigateBack, dispatchNavigateToUri } from 'utils/helper'; import AsyncStorage from '@react-native-community/async-storage'; import Colors from 'styles/colors'; import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api @@ -80,20 +48,25 @@ import NavigationButton from 'component/navigationButton'; import discoverStyle from 'styles/discover'; import searchStyle from 'styles/search'; import SearchRightHeaderIcon from 'component/searchRightHeaderIcon'; -import Snackbar from 'react-native-snackbar'; -import { doSetSdkReady } from 'redux/actions/settings'; -const SYNC_GET_INTERVAL = 1000 * 60 * 5; // every 5 minutes +const menuNavigationButton = navigation => ( + <NavigationButton + name="bars" + size={24} + style={discoverStyle.drawerMenuButton} + iconStyle={discoverStyle.drawerHamburger} + onPress={() => navigation.openDrawer()} + /> +); const discoverStack = createStackNavigator( { - Subscriptions: { - screen: SubscriptionsPage, - navigationOptions: { - title: 'Following', + Discover: { + screen: DiscoverPage, + navigationOptions: ({ navigation }) => ({ + title: 'Explore', header: null, - drawerIcon: ({ tintColor }) => <Icon name="heart" solid size={drawerIconSize} style={{ color: tintColor }} />, - }, + }), }, File: { screen: FilePage, @@ -117,7 +90,7 @@ const discoverStack = createStackNavigator( { headerMode: 'screen', transitionConfig: () => ({ screenInterpolator: () => null }), - }, + } ); discoverStack.navigationOptions = ({ navigation }) => { @@ -151,107 +124,88 @@ const walletStack = createStackNavigator( { headerMode: 'screen', transitionConfig: () => ({ screenInterpolator: () => null }), - }, + } ); -const drawerIconSize = 18; const drawer = createDrawerNavigator( { DiscoverStack: { screen: discoverStack, navigationOptions: { - title: 'Following', - drawerIcon: ({ tintColor }) => <Icon name="home" size={drawerIconSize} style={{ color: tintColor }} />, + title: 'Explore', + drawerIcon: ({ tintColor }) => <Icon name="home" size={20} style={{ color: tintColor }} />, }, }, - Discover: { - screen: DiscoverPage, - navigationOptions: ({ navigation }) => ({ - title: 'Your Tags', - header: null, - }), - }, - Trending: { + TrendingStack: { screen: TrendingPage, navigationOptions: { - title: 'All Content', - drawerIcon: ({ tintColor }) => <Icon name="fire" size={drawerIconSize} style={{ color: tintColor }} />, + title: 'Trending', + drawerIcon: ({ tintColor }) => <Icon name="fire" size={20} style={{ color: tintColor }} />, + }, + }, + MySubscriptionsStack: { + screen: SubscriptionsPage, + navigationOptions: { + title: 'Subscriptions', + drawerIcon: ({ tintColor }) => <Icon name="heart" solid size={20} style={{ color: tintColor }} />, }, }, WalletStack: { screen: walletStack, navigationOptions: { title: 'Wallet', - drawerIcon: ({ tintColor }) => <Icon name="wallet" size={drawerIconSize} style={{ color: tintColor }} />, - }, - }, - ChannelCreator: { - screen: ChannelCreatorPage, - navigationOptions: { - drawerIcon: ({ tintColor }) => <Icon name="at" size={drawerIconSize} style={{ color: tintColor }} />, + drawerIcon: ({ tintColor }) => <Icon name="wallet" size={20} style={{ color: tintColor }} />, }, }, Publish: { screen: PublishPage, navigationOptions: { - drawerIcon: ({ tintColor }) => <Icon name="upload" size={drawerIconSize} style={{ color: tintColor }} />, + drawerIcon: ({ tintColor }) => <Icon name="upload" size={20} style={{ color: tintColor }} />, }, }, Publishes: { screen: PublishesPage, navigationOptions: { - drawerIcon: ({ tintColor }) => ( - <Icon name="cloud-upload-alt" size={drawerIconSize} style={{ color: tintColor }} /> - ), + drawerIcon: ({ tintColor }) => <Icon name="cloud-upload-alt" size={20} style={{ color: tintColor }} />, }, }, Rewards: { screen: RewardsPage, navigationOptions: { - drawerIcon: ({ tintColor }) => <Icon name="award" size={drawerIconSize} style={{ color: tintColor }} />, + drawerIcon: ({ tintColor }) => <Icon name="award" size={20} style={{ color: tintColor }} />, }, }, - Invites: { - screen: InvitesPage, - navigationOptions: { - drawerIcon: ({ tintColor }) => <Icon name="user-friends" size={drawerIconSize} style={{ color: tintColor }} />, - }, - }, - Downloads: { + MyLBRYStack: { screen: DownloadsPage, navigationOptions: { title: 'Library', - drawerIcon: ({ tintColor }) => <Icon name="download" size={drawerIconSize} style={{ color: tintColor }} />, + drawerIcon: ({ tintColor }) => <Icon name="download" size={20} style={{ color: tintColor }} />, }, }, Settings: { screen: SettingsPage, navigationOptions: { drawerLockMode: 'locked-closed', - drawerIcon: ({ tintColor }) => <Icon name="cog" size={drawerIconSize} style={{ color: tintColor }} />, + drawerIcon: ({ tintColor }) => <Icon name="cog" size={20} style={{ color: tintColor }} />, }, }, About: { screen: AboutPage, navigationOptions: { drawerLockMode: 'locked-closed', - drawerIcon: ({ tintColor }) => <Icon name="info" size={drawerIconSize} style={{ color: tintColor }} />, + drawerIcon: ({ tintColor }) => <Icon name="info" size={20} style={{ color: tintColor }} />, }, }, }, { - drawerWidth: 299, - drawerBackgroundColor: 'transparent', + drawerWidth: 300, headerMode: 'none', - backBehavior: 'none', - unmountInactiveRoutes: true, contentComponent: DrawerContent, - overlayColor: 'rgba(0, 0, 0, 0.7)', contentOptions: { activeTintColor: Colors.LbryGreen, labelStyle: discoverStyle.menuText, }, - }, + } ); const mainStackNavigator = new createStackNavigator( @@ -277,16 +231,10 @@ const mainStackNavigator = new createStackNavigator( drawerLockMode: 'locked-closed', }, }, - LiteFile: { - screen: LiteFilePage, - navigationOptions: { - drawerLockMode: 'locked-closed', - }, - }, }, { headerMode: 'none', - }, + } ); export const AppNavigator = mainStackNavigator; @@ -305,11 +253,9 @@ class AppWithNavigationState extends React.Component { constructor() { super(); this.emailVerifyCheckInterval = null; - this.syncGetInterval = null; this.state = { emailVerifyDone: false, verifyPending: false, - syncHashChanged: false, }; } @@ -319,36 +265,29 @@ class AppWithNavigationState extends React.Component { 'hardwareBackPress', function() { const { dispatch, nav, drawerStack } = this.props; - if (drawerStack.length > 1) { - dispatchNavigateBack(dispatch, nav, drawerStack); - return true; + // There should be a better way to check this + if (nav.routes.length > 0) { + if (nav.routes[0].routeName === 'Main') { + const mainRoute = nav.routes[0]; + if ( + mainRoute.index > 0 || + mainRoute.routes[0].index > 0 /* Discover stack index */ || + mainRoute.routes[4].index > 0 /* Wallet stack index */ || + mainRoute.index >= 5 /* Settings and About screens */ + ) { + dispatchNavigateBack(dispatch, nav, drawerStack); + return true; + } + } } - return false; - }.bind(this), + }.bind(this) ); } componentDidMount() { - const { dispatch, user } = this.props; this.emailVerifyCheckInterval = setInterval(() => this.checkEmailVerification(), 5000); Linking.addEventListener('url', this._handleUrl); - - DeviceEventEmitter.addListener('onSdkReady', this.handleSdkReady); - DeviceEventEmitter.addListener('onDownloadAborted', this.handleDownloadAborted); - DeviceEventEmitter.addListener('onDownloadStarted', this.handleDownloadStarted); - DeviceEventEmitter.addListener('onDownloadUpdated', this.handleDownloadUpdated); - DeviceEventEmitter.addListener('onDownloadCompleted', this.handleDownloadCompleted); - - // call /sync/get with interval - this.syncGetInterval = setInterval(() => { - this.setState({ syncHashChanged: false }); // reset local state - if (user && user.has_verified_email) { - NativeModules.UtilityModule.getSecureValue(Constants.KEY_WALLET_PASSWORD).then(walletPassword => { - dispatch(doGetSync(walletPassword, () => this.getUserSettings())); - }); - } - }, SYNC_GET_INTERVAL); } checkEmailVerification = () => { @@ -361,152 +300,27 @@ class AppWithNavigationState extends React.Component { }); }; - getUserSettings = () => { - const { dispatch } = this.props; - doPreferenceGet( - 'shared', - preference => { - dispatch(doPopulateSharedUserState(preference)); - }, - error => { - /* failed */ - }, - ); - }; - - checkNewAndroidReward = () => { - const { dispatch, doToast } = this.props; - const claimRewardCallback = err => { - if (err) { - // an error occurred, do not display anything - return; - } - // reward successfully claimed - NativeModules.UtilityModule.setNativeBooleanSetting(Constants.SETTING_NEW_ANDROID_REWARD_CLAIMED, true); - }; - - NativeModules.UtilityModule.getNativeBooleanSetting(Constants.SETTING_NEW_ANDROID_REWARD_CLAIMED, false).then( - rewardClaimed => { - if (!rewardClaimed) { - dispatch( - doClaimRewardType(REWARD_TYPES.TYPE_NEW_ANDROID, { notifyError: false, callback: claimRewardCallback }), - ); - } - }, - ); - }; - - handleSdkReady = () => { - const { dispatch } = this.props; - dispatch(doSetSdkReady()); - dispatch(doBalanceSubscribe()); - dispatch(doBlackListedOutpointsSubscribe()); - dispatch(doFilteredOutpointsSubscribe()); - - Lbry.wallet_status().then(secureWalletStatus => { - // For now, automatically unlock the wallet if a password is set so that downloads work - NativeModules.UtilityModule.getSecureValue(Constants.KEY_WALLET_PASSWORD).then(password => { - if ((secureWalletStatus.is_encrypted && !secureWalletStatus.is_locked) || secureWalletStatus.is_locked) { - this.setState({ - message: __('Unlocking account'), - details: __('Decrypting wallet'), - }); - - // unlock the wallet and then finish the splash screen - Lbry.wallet_unlock({ password: password || '' }).then(unlocked => { - if (unlocked) { - } else { - // this.handleAccountUnlockFailed(); - } - }); - } - }); - }); - - this.checkNewAndroidReward(); - }; - - handleAccountUnlockFailed() { - const { dispatch } = this.props; - dispatch( - doToast({ - message: __( - 'Your wallet failed to unlock, which means you may not be able to play any videos or access your funds. Restart the app to fix this.', - ), - isError: true, - }), - ); - } - - handleDownloadStarted = evt => { - const { dispatch } = this.props; - const { uri, outpoint, fileInfo } = evt; - dispatch(doStartDownload(uri, outpoint, fileInfo)); - }; - - handleDownloadUpdated = evt => { - const { dispatch } = this.props; - const { uri, outpoint, fileInfo, progress } = evt; - dispatch(doUpdateDownload(uri, outpoint, fileInfo, progress)); - }; - - handleDownloadCompleted = evt => { - const { dispatch } = this.props; - const { uri, outpoint, fileInfo } = evt; - dispatch(doCompleteDownload(uri, outpoint, fileInfo)); - }; - - handleDownloadAborted = evt => { - const { dispatch } = this.props; - const { uri, outpoint } = evt; - dispatch({ - type: ACTIONS.DOWNLOADING_CANCELED, - data: { uri, outpoint }, - }); - - dispatch({ - type: ACTIONS.FILE_DELETE, - data: { - outpoint, - }, - }); - }; - componentWillUnmount() { - DeviceEventEmitter.removeListener('onSdkReady', this.handleSdkReady); - DeviceEventEmitter.removeListener('onDownloadAborted', this.handleDownloadAborted); - DeviceEventEmitter.removeListener('onDownloadStarted', this.handleDownloadStarted); - DeviceEventEmitter.removeListener('onDownloadUpdated', this.handleDownloadUpdated); - DeviceEventEmitter.removeListener('onDownloadCompleted', this.handleDownloadCompleted); - AppState.removeEventListener('change', this._handleAppStateChange); BackHandler.removeEventListener('hardwareBackPress'); Linking.removeEventListener('url', this._handleUrl); - if (this.emailVerifyCheckInterval > -1) { - clearInterval(this.emailVerifyCheckInterval); - } - if (this.syncGetInterval > -1) { - clearInterval(this.syncGetInterval); - } } componentDidUpdate() { - const { dispatch, user, hashChanged } = this.props; + const { dispatch, user } = this.props; if (this.state.verifyPending && this.emailVerifyCheckInterval > 0 && user && user.has_verified_email) { clearInterval(this.emailVerifyCheckInterval); AsyncStorage.setItem(Constants.KEY_EMAIL_VERIFY_PENDING, 'false'); this.setState({ verifyPending: false }); - NativeModules.Firebase.track('email_verified', { email: user.primary_email }); - Snackbar.show({ title: __('Your email address was successfully verified.'), duration: Snackbar.LENGTH_LONG }); + ToastAndroid.show('Your email address was successfully verified.', ToastAndroid.LONG); - // get user settings after email verification - this.getUserSettings(); - } - - if (hashChanged && !this.state.syncHashChanged) { - this.setState({ syncHashChanged: true }); - this.getUserSettings(); + // upon successful email verification, do wallet sync (if password has been set) + NativeModules.UtilityModule.getSecureValue(Constants.KEY_FIRST_RUN_PASSWORD).then(walletPassword => { + if (walletPassword && walletPassword.trim().length > 0) { + dispatch(doGetSync(walletPassword)); + } + }); } } @@ -515,7 +329,7 @@ class AppWithNavigationState extends React.Component { const { toast, emailToVerify, emailVerifyPending, emailVerifyErrorMessage, user } = nextProps; if (toast) { - const { message, isError } = toast; + const { message } = toast; let currentDisplayType; if (!currentDisplayType && message) { // default to toast if no display type set and there is a message specified @@ -523,14 +337,7 @@ class AppWithNavigationState extends React.Component { } if (currentDisplayType === 'toast') { - const props = { - title: message, - duration: Snackbar.LENGTH_LONG, - }; - if (isError) { - props.backgroundColor = Colors.Red; - } - Snackbar.show(props); + ToastAndroid.show(message, ToastAndroid.LONG); } dispatch(doDismissToast()); @@ -542,7 +349,7 @@ class AppWithNavigationState extends React.Component { this.setState({ emailVerifyDone: true }); const message = emailVerifyErrorMessage ? String(emailVerifyErrorMessage) - : __('Your email address was successfully verified.'); + : 'Your email address was successfully verified.'; if (!emailVerifyErrorMessage) { AsyncStorage.removeItem(Constants.KEY_FIRST_RUN_EMAIL); } @@ -577,26 +384,6 @@ class AppWithNavigationState extends React.Component { if (backgroundPlayEnabled || NativeModules.BackgroundMedia) { NativeModules.BackgroundMedia.hidePlaybackNotification(); } - - // check fullscreen mode and show / hide navigation bar accordingly - this.checkFullscreenMode(); - } - }; - - checkFullscreenMode = () => { - const { fullscreenMode } = this.props; - StatusBar.setHidden(fullscreenMode); - - if (fullscreenMode) { - // fullscreen, so change orientation to landscape mode - NativeModules.ScreenOrientation.lockOrientationLandscape(); - // hide the navigation bar (on devices that have the soft navigation bar) - NativeModules.UtilityModule.hideNavigationBar(); - } else { - // Switch back to portrait mode when the media is not fullscreen - NativeModules.ScreenOrientation.lockOrientationPortrait(); - // hide the navigation bar (on devices that have the soft navigation bar) - NativeModules.UtilityModule.showNavigationBar(); } }; @@ -609,7 +396,7 @@ class AppWithNavigationState extends React.Component { try { verification = JSON.parse(atob(evt.url.substring(15))); } catch (error) { - // console.log(error); + console.log(error); } if (verification.token && verification.recaptcha) { @@ -617,7 +404,7 @@ class AppWithNavigationState extends React.Component { try { dispatch(doUserEmailVerify(verification.token, verification.recaptcha)); } catch (error) { - const message = __('Invalid Verification Token'); + const message = 'Invalid Verification Token'; dispatch(doUserEmailVerifyFailure(message)); dispatch(doToast({ message })); } @@ -625,11 +412,11 @@ class AppWithNavigationState extends React.Component { dispatch( doToast({ message: 'Invalid Verification URI', - }), + }) ); } } else { - dispatchNavigateToUri(dispatch, nav, transformUrl(evt.url)); + dispatchNavigateToUri(dispatch, nav, evt.url); } } }; @@ -641,7 +428,6 @@ class AppWithNavigationState extends React.Component { const mapStateToProps = state => ({ backgroundPlayEnabled: makeSelectClientSetting(SETTINGS.BACKGROUND_PLAY_ENABLED)(state), - hashChanged: selectHashChanged(state), keepDaemonRunning: makeSelectClientSetting(SETTINGS.KEEP_DAEMON_RUNNING)(state), nav: state.nav, toast: selectToast(state), @@ -651,7 +437,6 @@ const mapStateToProps = state => ({ emailVerifyErrorMessage: selectEmailVerifyErrorMessage(state), showNsfw: makeSelectClientSetting(SETTINGS.SHOW_NSFW)(state), user: selectUser(state), - fullscreenMode: selectFullscreenMode(state), }); export default connect(mapStateToProps)(AppWithNavigationState); diff --git a/src/component/address/view.js b/src/component/address/view.js index 0f66b77..36fe8f0 100644 --- a/src/component/address/view.js +++ b/src/component/address/view.js @@ -15,7 +15,7 @@ export default class Address extends React.PureComponent<Props> { return ( <View style={[walletStyle.row, style]}> - <Text selectable numberOfLines={1} style={walletStyle.address}> + <Text selectable={true} numberOfLines={1} style={walletStyle.address}> {address || ''} </Text> <Button @@ -24,7 +24,7 @@ export default class Address extends React.PureComponent<Props> { onPress={() => { Clipboard.setString(address); doToast({ - message: __('Address copied'), + message: 'Address copied', }); }} /> diff --git a/src/component/button/view.js b/src/component/button/view.js index b71ecc9..3fdc26f 100644 --- a/src/component/button/view.js +++ b/src/component/button/view.js @@ -34,11 +34,16 @@ export default class Button extends React.PureComponent { } let renderIcon = ( - <Icon name={icon} size={16} color={iconColor || (theme === 'light' ? Colors.DarkGrey : Colors.White)} /> + <Icon name={icon} size={18} color={iconColor ? iconColor : 'light' === theme ? Colors.DarkGrey : Colors.White} /> ); if (solid) { renderIcon = ( - <Icon name={icon} size={16} color={iconColor || (theme === 'light' ? Colors.DarkGrey : Colors.White)} solid /> + <Icon + name={icon} + size={18} + color={iconColor ? iconColor : 'light' === theme ? Colors.DarkGrey : Colors.White} + solid + /> ); } diff --git a/src/component/categoryList/index.js b/src/component/categoryList/index.js new file mode 100644 index 0000000..2d87b90 --- /dev/null +++ b/src/component/categoryList/index.js @@ -0,0 +1,4 @@ +import { connect } from 'react-redux'; +import CategoryList from './view'; + +export default connect()(CategoryList); diff --git a/src/component/categoryList/view.js b/src/component/categoryList/view.js new file mode 100644 index 0000000..61aca52 --- /dev/null +++ b/src/component/categoryList/view.js @@ -0,0 +1,39 @@ +import React from 'react'; +import NavigationActions from 'react-navigation'; +import { FlatList, Text, View } from 'react-native'; +import { normalizeURI } from 'lbry-redux'; +import FileItem from '/component/fileItem'; +import discoverStyle from 'styles/discover'; + +class CategoryList extends React.PureComponent { + render() { + const { category, categoryMap, navigation } = this.props; + + return ( + <FlatList + style={discoverStyle.horizontalScrollContainer} + contentContainerStyle={discoverStyle.horizontalScrollPadding} + initialNumToRender={3} + maxToRenderPerBatch={3} + removeClippedSubviews={true} + renderItem={({ item }) => ( + <FileItem + style={discoverStyle.fileItem} + mediaStyle={discoverStyle.fileItemMedia} + key={item} + uri={normalizeURI(item)} + navigation={navigation} + showDetails={true} + compactView={false} + /> + )} + horizontal={true} + showsHorizontalScrollIndicator={false} + data={categoryMap[category]} + keyExtractor={(item, index) => item} + /> + ); + } +} + +export default CategoryList; diff --git a/src/component/channelIconItem/index.js b/src/component/channelIconItem/index.js index 5c3f56c..0096792 100644 --- a/src/component/channelIconItem/index.js +++ b/src/component/channelIconItem/index.js @@ -1,17 +1,10 @@ import { connect } from 'react-redux'; -import { - doResolveUri, - makeSelectClaimForUri, - makeSelectThumbnailForUri, - makeSelectTitleForUri, - makeSelectIsUriResolving, -} from 'lbry-redux'; +import { doResolveUri, makeSelectClaimForUri, makeSelectThumbnailForUri, makeSelectIsUriResolving } from 'lbry-redux'; import ChannelIconItem from './view'; const select = (state, props) => ({ thumbnail: makeSelectThumbnailForUri(props.uri)(state), claim: makeSelectClaimForUri(props.uri)(state), - title: makeSelectTitleForUri(props.uri)(state), isResolvingUri: makeSelectIsUriResolving(props.uri)(state), }); @@ -19,4 +12,7 @@ const perform = dispatch => ({ resolveUri: uri => dispatch(doResolveUri(uri)), }); -export default connect(select, perform)(ChannelIconItem); +export default connect( + select, + perform +)(ChannelIconItem); diff --git a/src/component/channelIconItem/view.js b/src/component/channelIconItem/view.js index bf6dbdb..73eba59 100644 --- a/src/component/channelIconItem/view.js +++ b/src/component/channelIconItem/view.js @@ -1,40 +1,9 @@ import React from 'react'; import { ActivityIndicator, Image, Text, TouchableOpacity, View } from 'react-native'; import Colors from 'styles/colors'; -import autothumbStyle from 'styles/autothumb'; import channelIconStyle from 'styles/channelIcon'; export default class ChannelIconItem extends React.PureComponent { - static AUTO_THUMB_STYLES = [ - autothumbStyle.autothumbPurple, - autothumbStyle.autothumbRed, - autothumbStyle.autothumbPink, - autothumbStyle.autothumbIndigo, - autothumbStyle.autothumbBlue, - autothumbStyle.autothumbLightBlue, - autothumbStyle.autothumbCyan, - autothumbStyle.autothumbGreen, - autothumbStyle.autothumbYellow, - autothumbStyle.autothumbOrange, - autothumbStyle.autothumbDeepPurple, - autothumbStyle.autothumbAmber, - autothumbStyle.autothumbLime, - autothumbStyle.autothumbLightGreen, - autothumbStyle.autothumbDeepOrange, - autothumbStyle.autothumbBrown, - ]; - - state = { - autoStyle: null, - }; - - componentWillMount() { - this.setState({ - autoStyle: - ChannelIconItem.AUTO_THUMB_STYLES[Math.floor(Math.random() * ChannelIconItem.AUTO_THUMB_STYLES.length)], - }); - } - componentDidMount() { const { claim, isPlaceholder, uri, resolveUri } = this.props; if (!claim && !isPlaceholder) { @@ -44,40 +13,36 @@ export default class ChannelIconItem extends React.PureComponent { render() { const { claim, isPlaceholder, isResolvingUri, onPress, thumbnail, title } = this.props; - const displayName = title || (claim ? claim.name : ''); - const substrIndex = displayName.startsWith('@') ? 1 : 0; return ( <TouchableOpacity style={channelIconStyle.container} onPress={onPress}> {isResolvingUri && ( <View style={channelIconStyle.centered}> - <ActivityIndicator size={'small'} color={Colors.NextLbryGreen} /> + <ActivityIndicator size={'small'} color={Colors.LbryGreen} /> </View> )} <View style={[ channelIconStyle.thumbnailContainer, isPlaceholder ? channelIconStyle.borderedThumbnailContainer : null, - isPlaceholder ? null : this.state.autoStyle, ]} > {isPlaceholder && ( <View style={channelIconStyle.centered}> - <Text style={channelIconStyle.placeholderText}>{__('ALL')}</Text> + <Text style={channelIconStyle.placeholderText}>ALL</Text> </View> )} - {!isPlaceholder && thumbnail && ( - <Image style={channelIconStyle.thumbnail} resizeMode={'cover'} source={{ uri: thumbnail }} /> - )} - {!isPlaceholder && !thumbnail && ( - <Text style={channelIconStyle.autothumbCharacter}> - {displayName.substring(substrIndex, substrIndex + 1).toUpperCase()} - </Text> + {!isPlaceholder && ( + <Image + style={channelIconStyle.thumbnail} + resizeMode={'cover'} + source={thumbnail ? { uri: thumbnail } : require('../../assets/default_avatar.jpg')} + /> )} </View> {!isPlaceholder && ( <Text style={channelIconStyle.title} numberOfLines={1}> - {displayName} + {title || (claim ? claim.name : '')} </Text> )} </TouchableOpacity> diff --git a/src/component/channelRewardsDriver/index.js b/src/component/channelRewardsDriver/index.js deleted file mode 100644 index bcdde9c..0000000 --- a/src/component/channelRewardsDriver/index.js +++ /dev/null @@ -1,4 +0,0 @@ -import { connect } from 'react-redux'; -import ChannelRewardsDriver from './view'; - -export default connect()(ChannelRewardsDriver); diff --git a/src/component/channelRewardsDriver/view.js b/src/component/channelRewardsDriver/view.js deleted file mode 100644 index 003bf9b..0000000 --- a/src/component/channelRewardsDriver/view.js +++ /dev/null @@ -1,24 +0,0 @@ -import React from 'react'; -import { Text, TouchableOpacity } from 'react-native'; -import Colors from 'styles/colors'; -import Icon from 'react-native-vector-icons/FontAwesome5'; -import publishStyle from 'styles/publish'; - -class ChannelRewardsDriver extends React.PureComponent<Props> { - render() { - const { navigation } = this.props; - - return ( - <TouchableOpacity style={publishStyle.rewardDriverCard} onPress={() => navigation.navigate('Rewards')}> - <Icon name="award" size={16} style={publishStyle.rewardIcon} /> - <Text style={publishStyle.rewardDriverText}> - {__('Channel creation requires credits.')} - {'\n'} - {__('Tap here to get some for free.')} - </Text> - </TouchableOpacity> - ); - } -} - -export default ChannelRewardsDriver; diff --git a/src/component/channelSelector/index.js b/src/component/channelSelector/index.js index 5bbb154..daee8c7 100644 --- a/src/component/channelSelector/index.js +++ b/src/component/channelSelector/index.js @@ -7,7 +7,6 @@ import { doCreateChannel, doToast, } from 'lbry-redux'; -import { doGetSync } from 'lbryinc'; import ChannelSelector from './view'; const select = state => ({ @@ -19,11 +18,10 @@ const select = state => ({ const perform = dispatch => ({ notify: data => dispatch(doToast(data)), createChannel: (name, amount) => dispatch(doCreateChannel(name, amount)), - fetchChannelListMine: () => dispatch(doFetchChannelListMine(1, 99999, true)), - getSync: (password, callback) => dispatch(doGetSync(password, callback)), + fetchChannelListMine: () => dispatch(doFetchChannelListMine()), }); export default connect( select, - perform, + perform )(ChannelSelector); diff --git a/src/component/channelSelector/view.js b/src/component/channelSelector/view.js index 952447d..b93d651 100644 --- a/src/component/channelSelector/view.js +++ b/src/component/channelSelector/view.js @@ -1,10 +1,9 @@ import React from 'react'; -import { CLAIM_VALUES, formatCredits, isNameValid } from 'lbry-redux'; -import { ActivityIndicator, NativeModules, Picker, Text, TextInput, TouchableOpacity, View } from 'react-native'; -import { logPublish } from 'utils/helper'; +import { CLAIM_VALUES, isNameValid } from 'lbry-redux'; +import { ActivityIndicator, Picker, Text, TextInput, TouchableOpacity, View } from 'react-native'; import Button from 'component/button'; import Colors from 'styles/colors'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api +import Constants from 'constants'; import Icon from 'react-native-vector-icons/FontAwesome5'; import Link from 'component/link'; import channelSelectorStyle from 'styles/channelSelector'; @@ -14,7 +13,6 @@ export default class ChannelSelector extends React.PureComponent { super(props); this.state = { - creditsInputFocused: false, currentSelectedValue: Constants.ITEM_ANONYMOUS, newChannelName: '', newChannelBid: 0.1, @@ -28,24 +26,10 @@ export default class ChannelSelector extends React.PureComponent { } componentDidMount() { - const { channels = [], channelName, fetchChannelListMine, fetchingChannels } = this.props; - if ((!channels || channels.length === 0) && !fetchingChannels) { + const { channels, fetchChannelListMine, fetchingChannels } = this.props; + if (!channels.length && !fetchingChannels) { fetchChannelListMine(); } - this.setState({ currentSelectedValue: channelName }); - } - - componentWillReceiveProps(nextProps) { - const { channels: prevChannels = [], channelName: prevChannelName } = this.props; - const { channels = [], channelName } = nextProps; - - if (channels && channels.length !== prevChannels.length && channelName !== this.state.currentSelectedValue) { - this.setState({ currentSelectedValue: prevChannelName }); - } - - if (channelName !== prevChannelName) { - this.setState({ currentSelectedValue: channelName }); - } } handleCreateCancel = () => { @@ -70,13 +54,13 @@ export default class ChannelSelector extends React.PureComponent { if (channel === CLAIM_VALUES.CHANNEL_NEW) { this.setState({ addingChannel: true }); if (onChannelChange) { - onChannelChange(value); + onChannelChange(channel); } this.handleNewChannelBidChange(newChannelBid); } else { this.setState({ addingChannel: false }); if (onChannelChange) { - onChannelChange(value); + onChannelChange(channel); } } }; @@ -84,22 +68,14 @@ export default class ChannelSelector extends React.PureComponent { handleNewChannelNameChange = value => { const { notify } = this.props; - let newChannelName = value, - newChannelNameError = ''; + let newChannelName = value; if (newChannelName.startsWith('@')) { newChannelName = newChannelName.slice(1); } - if (newChannelName.trim().length > 0 && !isNameValid(newChannelName)) { - newChannelNameError = __('Your channel name contains invalid characters.'); - } else if (this.channelExists(newChannelName)) { - newChannelNameError = __('You have already created a channel with the same name.'); - } - this.setState({ newChannelName, - newChannelNameError, }); }; @@ -123,21 +99,21 @@ export default class ChannelSelector extends React.PureComponent { }; handleCreateChannelClick = () => { - const { balance, createChannel, getSync, onChannelChange, notify } = this.props; + const { balance, createChannel, onChannelChange, notify } = this.props; const { newChannelBid, newChannelName } = this.state; if (newChannelName.trim().length === 0 || !isNameValid(newChannelName.substr(1), false)) { - notify({ message: __('Your channel name contains invalid characters.') }); + notify({ message: 'Your channel name contains invalid characters.' }); return; } if (this.channelExists(newChannelName)) { - notify({ message: __('You have already created a channel with the same name.') }); + notify({ message: 'You have already created a channel with the same name.' }); return; } if (newChannelBid > balance) { - notify({ message: __('Deposit cannot be higher than your balance') }); + notify({ message: 'Deposit cannot be higher than your balance' }); return; } @@ -148,25 +124,21 @@ export default class ChannelSelector extends React.PureComponent { createChannelError: undefined, }); - const success = channelClaim => { + const success = () => { this.setState({ creatingChannel: false, addingChannel: false, currentSelectedValue: channelName, showCreateChannel: false, }); - logPublish(channelClaim); if (onChannelChange) { onChannelChange(channelName); } - - // sync wallet - NativeModules.UtilityModule.getSecureValue(Constants.KEY_WALLET_PASSWORD).then(password => getSync(password)); }; const failure = () => { - notify({ message: __('Unable to create channel due to an internal error.') }); + notify({ message: 'Unable to create channel due to an internal error.' }); this.setState({ creatingChannel: false, }); @@ -177,14 +149,12 @@ export default class ChannelSelector extends React.PureComponent { channelExists = name => { const { channels = [] } = this.props; - if (channels) { - for (let channel of channels) { - if ( - name.toLowerCase() === channel.name.toLowerCase() || - `@${name}`.toLowerCase() === channel.name.toLowerCase() - ) { - return true; - } + for (let channel of channels) { + if ( + name.toLowerCase() === channel.name.toLowerCase() || + `@${name}`.toLowerCase() === channel.name.toLowerCase() + ) { + return true; } } @@ -193,12 +163,10 @@ export default class ChannelSelector extends React.PureComponent { render() { const channel = this.state.addingChannel ? 'new' : this.props.channel; - const { balance, enabled, fetchingChannels, channels = [], showAnonymous } = this.props; - const pickerItems = (showAnonymous - ? [Constants.ITEM_ANONYMOUS, Constants.ITEM_CREATE_A_CHANNEL] - : [Constants.ITEM_CREATE_A_CHANNEL] - ).concat(channels ? channels.map(ch => ch.name) : []); - + const { fetchingChannels, channels = [] } = this.props; + const pickerItems = [{ name: Constants.ITEM_ANONYMOUS }, { name: Constants.ITEM_CREATE_A_CHANNEL }].concat( + channels + ); const { newChannelName, newChannelNameError, @@ -207,28 +175,22 @@ export default class ChannelSelector extends React.PureComponent { creatingChannel, createChannelError, addingChannel, - showCreateChannel, } = this.state; return ( <View style={channelSelectorStyle.container}> <Picker - enabled={enabled} selectedValue={this.state.currentSelectedValue} style={channelSelectorStyle.channelPicker} itemStyle={channelSelectorStyle.channelPickerItem} onValueChange={this.handlePickerValueChange} > {pickerItems.map(item => ( - <Picker.Item - label={[Constants.ITEM_ANONYMOUS, Constants.ITEM_CREATE_A_CHANNEL].includes(item) ? __(item) : item} - value={item} - key={item} - /> + <Picker.Item label={item.name} value={item.name} key={item.name} /> ))} </Picker> - {showCreateChannel && ( + {this.state.showCreateChannel && ( <View style={channelSelectorStyle.createChannelContainer}> <View style={channelSelectorStyle.channelInputContainer}> <Text style={channelSelectorStyle.channelAt}>@</Text> @@ -237,46 +199,35 @@ export default class ChannelSelector extends React.PureComponent { style={channelSelectorStyle.channelNameInput} value={this.state.newChannelName} onChangeText={this.handleNewChannelNameChange} - placeholder={__('Channel name')} + placeholder={'Channel name'} underlineColorAndroid={Colors.NextLbryGreen} /> </View> - {newChannelNameError.length > 0 && ( - <Text style={channelSelectorStyle.inlineError}>{newChannelNameError}</Text> - )} <View style={channelSelectorStyle.bidRow}> - <Text style={channelSelectorStyle.label}>{__('Deposit')}</Text> + <Text style={channelSelectorStyle.label}>Deposit</Text> <TextInput style={channelSelectorStyle.bidAmountInput} - value={String(newChannelBid)} + value={String(this.state.newChannelBid)} onChangeText={this.handleNewChannelBidChange} - onFocus={() => this.setState({ creditsInputFocused: true })} - onBlur={() => this.setState({ creditsInputFocused: false })} placeholder={'0.00'} keyboardType={'number-pad'} underlineColorAndroid={Colors.NextLbryGreen} /> <Text style={channelSelectorStyle.currency}>LBC</Text> - <View style={channelSelectorStyle.balance}> - {this.state.creditsInputFocused && <Icon name="coins" size={12} />} - {this.state.creditsInputFocused && ( - <Text style={channelSelectorStyle.balanceText}>{formatCredits(parseFloat(balance), 1, true)}</Text> - )} - </View> </View> <Text style={channelSelectorStyle.helpText}> - {__('This LBC remains yours. It is a deposit to reserve the name and can be undone at any time.')} + This LBC remains yours. It is a deposit to reserve the name and can be undone at any time. </Text> <View style={channelSelectorStyle.buttonContainer}> - {creatingChannel && <ActivityIndicator size={'small'} color={Colors.NextLbryGreen} />} + {creatingChannel && <ActivityIndicator size={'small'} color={Colors.LbryGreen} />} {!creatingChannel && ( <View style={channelSelectorStyle.buttons}> - <Link style={channelSelectorStyle.cancelLink} text={__('Cancel')} onPress={this.handleCreateCancel} /> + <Link style={channelSelectorStyle.cancelLink} text="Cancel" onPress={this.handleCreateCancel} /> <Button style={channelSelectorStyle.createButton} - disabled={!(newChannelName.trim().length > 0 && newChannelBid > 0)} - text={__('Create')} + disabled={!(this.state.newChannelName.trim().length > 0 && this.state.newChannelBid > 0)} + text="Create" onPress={this.handleCreateChannelClick} /> </View> diff --git a/src/component/claimList/index.js b/src/component/claimList/index.js index 21ee91b..a621546 100644 --- a/src/component/claimList/index.js +++ b/src/component/claimList/index.js @@ -2,25 +2,47 @@ import { connect } from 'react-redux'; import { MATURE_TAGS, doClaimSearch, - selectClaimSearchByQuery, - selectClaimSearchByQueryLastPageReached, - selectFetchingClaimSearchByQuery, + doClaimSearchByTags, + makeSelectClaimSearchUrisForTags, + makeSelectFetchingClaimSearchForTags, selectFetchingClaimSearch, + selectLastClaimSearchUris, } from 'lbry-redux'; -import { selectShowNsfw } from 'redux/selectors/settings'; import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api import ClaimList from './view'; -const select = state => ({ - claimSearchByQuery: selectClaimSearchByQuery(state), - lastPageReached: selectClaimSearchByQueryLastPageReached(state), - loadingByQuery: selectFetchingClaimSearchByQuery(state), - loading: selectFetchingClaimSearch(state), - showNsfwContent: selectShowNsfw(state), -}); +const select = (state, props) => { + return { + loading: makeSelectFetchingClaimSearchForTags(props.tags)(state), + uris: makeSelectClaimSearchUrisForTags(props.tags)(state), + // for subscriptions + claimSearchLoading: selectFetchingClaimSearch(state), + claimSearchUris: selectLastClaimSearchUris(state), + }; +}; const perform = dispatch => ({ - claimSearch: options => dispatch(doClaimSearch(options)), + claimSearch: options => dispatch(doClaimSearch(Constants.DEFAULT_PAGE_SIZE, options)), + searchByTags: (tags, orderBy = Constants.DEFAULT_ORDER_BY, page = 1, additionalOptions = {}) => + dispatch( + doClaimSearchByTags( + tags, + Constants.DEFAULT_PAGE_SIZE, + Object.assign( + {}, + { + no_totals: true, + order_by: orderBy, + page, + not_tags: MATURE_TAGS, + }, + additionalOptions + ) + ) + ), }); -export default connect(select, perform)(ClaimList); +export default connect( + select, + perform +)(ClaimList); diff --git a/src/component/claimList/view.js b/src/component/claimList/view.js index e985067..d74e01a 100644 --- a/src/component/claimList/view.js +++ b/src/component/claimList/view.js @@ -1,7 +1,7 @@ import React from 'react'; import NavigationActions from 'react-navigation'; import { ActivityIndicator, FlatList, Text, TouchableOpacity, View } from 'react-native'; -import { MATURE_TAGS, normalizeURI, createNormalizedClaimSearchKey } from 'lbry-redux'; +import { MATURE_TAGS, normalizeURI } from 'lbry-redux'; import _ from 'lodash'; import FileItem from 'component/fileItem'; import FileListItem from 'component/fileListItem'; @@ -12,7 +12,7 @@ import claimListStyle from 'styles/claimList'; import discoverStyle from 'styles/discover'; import moment from 'moment'; -const horizontalLimit = 10; +const horizontalLimit = 7; const softLimit = 500; class ClaimList extends React.PureComponent { @@ -21,82 +21,94 @@ class ClaimList extends React.PureComponent { state = { currentPage: 1, // initial page load is page 1 subscriptionsView: false, // whether or not this claim list is for subscriptions - lastPageReached: false, + trendingForAllView: false, }; componentDidMount() { - const { channelIds } = this.props; + const { + channelIds, + trendingForAll, + claimSearch, + orderBy = Constants.DEFAULT_ORDER_BY, + searchByTags, + tags, + time, + } = this.props; + if (channelIds || trendingForAll) { + const options = { + order_by: orderBy, + no_totals: true, + not_tags: MATURE_TAGS, + page: this.state.currentPage, + }; + if (channelIds) { + this.setState({ subscriptionsView: true }); + options.channel_ids = channelIds; + } else if (trendingForAll) { + this.setState({ trendingForAllView: true }); + } - if (channelIds) { - this.setState({ subscriptionsView: true }); + claimSearch(options); + } else if (tags && tags.length > 0) { + const additionalOptions = {}; + if (orderBy && orderBy[0] === Constants.ORDER_BY_EFFECTIVE_AMOUNT && Constants.TIME_ALL !== time) { + additionalOptions.release_time = this.getReleaseTimeOption(time); + } + searchByTags(tags, orderBy, this.state.currentPage, additionalOptions); } - - this.doClaimSearch(); } - componentDidUpdate(prevProps) { + componentWillReceiveProps(nextProps) { const { - claimSearchByQuery: prevClaimSearchByQuery, + claimSearch, orderBy: prevOrderBy, searchByTags, tags: prevTags, channelIds: prevChannelIds, + trendingForAll: prevTrendingForAll, time: prevTime, - } = prevProps; - const { claimSearchByQuery, orderBy, tags, channelIds, time } = this.props; - + } = this.props; + const { orderBy, tags, channelIds, trendingForAll, time } = nextProps; if ( !_.isEqual(orderBy, prevOrderBy) || !_.isEqual(tags, prevTags) || !_.isEqual(channelIds, prevChannelIds) || - time !== prevTime + time !== prevTime || + trendingForAll !== prevTrendingForAll ) { // reset to page 1 because the order, tags or channelIds changed this.setState({ currentPage: 1 }, () => { if (this.scrollView) { this.scrollView.scrollToOffset({ animated: true, offset: 0 }); } - - if (prevChannelIds && channelIds) { + if (trendingForAll || (prevChannelIds && channelIds)) { + const options = { + order_by: orderBy, + no_totals: true, + not_tags: MATURE_TAGS, + page: this.state.currentPage, + }; if (channelIds) { this.setState({ subscriptionsView: true }); + options.channel_ids = channelIds; + } + if (trendingForAll) { + this.setState({ trendingForAllView: true }); } - } else if (tags && tags.length > 0) { - this.setState({ subscriptionsView: false }); - } - this.doClaimSearch(); + claimSearch(options); + } else if (tags && tags.length > 0) { + this.setState({ subscriptionsView: false, trendingForAllView: false }); + const additionalOptions = {}; + if (orderBy && orderBy[0] === Constants.ORDER_BY_EFFECTIVE_AMOUNT && Constants.TIME_ALL !== time) { + additionalOptions.release_time = this.getReleaseTimeOption(time); + } + searchByTags(tags, orderBy, this.state.currentPage, additionalOptions); + } }); } } - buildClaimSearchOptions() { - const { orderBy, channelIds, showNsfwContent, tags, time } = this.props; - const { currentPage, subscriptionsView } = this.state; - - const options = { - order_by: orderBy, - no_totals: true, - page: currentPage, - page_size: Constants.DEFAULT_PAGE_SIZE, - }; - - if (channelIds) { - options.channel_ids = channelIds; - } else if (tags && tags.length > 0) { - options.any_tags = tags; - } - if (!showNsfwContent) { - options.not_tags = MATURE_TAGS; - } - - if (orderBy && orderBy[0] === Constants.ORDER_BY_EFFECTIVE_AMOUNT && Constants.TIME_ALL !== time) { - options.release_time = this.getReleaseTimeOption(time); - } - - return options; - } - getReleaseTimeOption = time => { return `>${Math.floor( moment() @@ -105,27 +117,36 @@ class ClaimList extends React.PureComponent { )}`; }; - doClaimSearch() { - const { claimSearch } = this.props; - const options = this.buildClaimSearchOptions(); - claimSearch(options); - } - handleVerticalEndReached = () => { // fetch more content - const { claimSearchByQuery, lastPageReached } = this.props; - - const options = this.buildClaimSearchOptions(); - const claimSearchKey = createNormalizedClaimSearchKey(options); - const uris = claimSearchByQuery[claimSearchKey]; - if ( - lastPageReached[claimSearchKey] || - ((uris.length > 0 && uris.length < Constants.DEFAULT_PAGE_SIZE) || uris.length >= softLimit) - ) { + const { channelIds, claimSearch, claimSearchUris, orderBy, searchByTags, tags, time, uris } = this.props; + const { subscriptionsView, trendingForAllView } = this.state; + if ((claimSearchUris && claimSearchUris.length >= softLimit) || (uris && uris.length >= softLimit)) { + // don't fetch more than the specified limit to be displayed return; } - this.setState({ currentPage: this.state.currentPage + 1 }, () => this.doClaimSearch()); + this.setState({ currentPage: this.state.currentPage + 1 }, () => { + if (subscriptionsView || trendingForAllView) { + const options = { + order_by: orderBy, + no_totals: true, + not_tags: MATURE_TAGS, + page: this.state.currentPage, + }; + if (subscriptionsView) { + options.channel_ids = channelIds; + } + + claimSearch(options); + } else { + const additionalOptions = {}; + if (orderBy && orderBy[0] === Constants.ORDER_BY_EFFECTIVE_AMOUNT && Constants.TIME_ALL !== time) { + additionalOptions.release_time = this.getReleaseTimeOption(time); + } + searchByTags(tags, orderBy, this.state.currentPage, additionalOptions); + } + }); }; appendMorePlaceholder = items => { @@ -140,79 +161,35 @@ class ClaimList extends React.PureComponent { if (tags.length === 1) { navigation.navigate({ routeName: Constants.DRAWER_ROUTE_TAG, key: 'tagPage', params: { tag: tags[0] } }); } else { - navigation.navigate({ routeName: Constants.DRAWER_ROUTE_TRENDING, params: { filterForTags: true } }); + navigation.navigate({ routeName: Constants.FULL_ROUTE_NAME_TRENDING }); } }; renderMorePlaceholder = () => { return ( <TouchableOpacity style={discoverStyle.fileItemMore} onPress={this.onMorePressed}> - <Text style={discoverStyle.moreText}>{__('more')}</Text> + <Text style={discoverStyle.moreText}>more</Text> <Icon style={discoverStyle.moreIcon} name={'angle-double-down'} color={Colors.White} size={16} /> </TouchableOpacity> ); }; - verticalListEmptyComponent = () => { - return ( - <Text style={claimListStyle.noContentText}> - {__('No content to display at this time. Please check back later.')} - </Text> - ); - }; - - renderVerticalItem = ({ item }) => { - const { hideChannel, navigation } = this.props; - return ( - <FileListItem - key={item} - uri={item} - hideChannel={hideChannel} - style={claimListStyle.verticalListItem} - navigation={navigation} - /> - ); - }; - - renderHorizontalItem = ({ item }) => { - const { navigation } = this.props; - - return item === Constants.MORE_PLACEHOLDER ? ( - this.renderMorePlaceholder() - ) : ( - <FileItem - style={discoverStyle.fileItem} - mediaStyle={discoverStyle.fileItemMedia} - key={item} - uri={normalizeURI(item)} - navigation={navigation} - showDetails - compactView={false} - /> - ); - }; - render() { const { ListHeaderComponent, loading, + claimSearchLoading, + claimSearchUris, morePlaceholder, navigation, orientation = Constants.ORIENTATION_VERTICAL, style, - claimSearchByQuery, + uris, } = this.props; - const { subscriptionsView } = this.state; - - const options = this.buildClaimSearchOptions(); - const claimSearchKey = createNormalizedClaimSearchKey(options); - let uris = claimSearchByQuery[claimSearchKey]; - - if (uris) { - uris = uris.filter(uri => uri && uri.length > 0); - } + const { subscriptionsView, trendingForAllView } = this.state; if (Constants.ORIENTATION_VERTICAL === orientation) { + const data = subscriptionsView || trendingForAllView ? claimSearchUris : uris; return ( <View style={style}> <FlatList @@ -220,21 +197,22 @@ class ClaimList extends React.PureComponent { this.scrollView = ref; }} ListHeaderComponent={ListHeaderComponent} - ListEmptyComponent={loading ? null : this.verticalListEmptyComponent} style={claimListStyle.verticalScrollContainer} contentContainerStyle={claimListStyle.verticalScrollPadding} initialNumToRender={10} maxToRenderPerBatch={20} removeClippedSubviews - renderItem={this.renderVerticalItem} - data={uris} + renderItem={({ item }) => ( + <FileListItem key={item} uri={item} style={claimListStyle.verticalListItem} navigation={navigation} /> + )} + data={data} keyExtractor={(item, index) => item} onEndReached={this.handleVerticalEndReached} onEndReachedThreshold={0.2} /> - {loading && ( + {(((subscriptionsView || trendingForAllView) && claimSearchLoading) || loading) && ( <View style={claimListStyle.verticalLoading}> - <ActivityIndicator size={'small'} color={Colors.NextLbryGreen} /> + <ActivityIndicator size={'small'} color={Colors.LbryGreen} /> </View> )} </View> @@ -245,7 +223,7 @@ class ClaimList extends React.PureComponent { if (loading) { return ( <View style={discoverStyle.listLoading}> - <ActivityIndicator size={'small'} color={Colors.NextLbryGreen} /> + <ActivityIndicator size={'small'} color={Colors.LbryGreen} /> </View> ); } @@ -257,7 +235,21 @@ class ClaimList extends React.PureComponent { initialNumToRender={3} maxToRenderPerBatch={3} removeClippedSubviews - renderItem={this.renderHorizontalItem} + renderItem={({ item }) => { + return item === Constants.MORE_PLACEHOLDER ? ( + this.renderMorePlaceholder() + ) : ( + <FileItem + style={discoverStyle.fileItem} + mediaStyle={discoverStyle.fileItemMedia} + key={item} + uri={normalizeURI(item)} + navigation={navigation} + showDetails + compactView={false} + /> + ); + }} horizontal showsHorizontalScrollIndicator={false} data={uris ? this.appendMorePlaceholder(uris.slice(0, horizontalLimit)) : []} diff --git a/src/component/claimResultItem/index.js b/src/component/claimResultItem/index.js deleted file mode 100644 index 7eb7346..0000000 --- a/src/component/claimResultItem/index.js +++ /dev/null @@ -1,39 +0,0 @@ -import { connect } from 'react-redux'; -import { - doResolveUri, - makeSelectClaimForUri, - makeSelectMetadataForUri, - makeSelectFileInfoForUri, - makeSelectIsUriResolving, - makeSelectClaimIsNsfw, - makeSelectShortUrlForUri, - makeSelectTitleForUri, - makeSelectThumbnailForUri, -} from 'lbry-redux'; -import { doSetPlayerVisible } from 'redux/actions/drawer'; -import { selectBlackListedOutpoints, selectFilteredOutpoints, selectRewardContentClaimIds } from 'lbryinc'; -import { selectShowNsfw } from 'redux/selectors/settings'; -import ClaimResultItem from './view'; - -const select = (state, props) => ({ - blackListedOutpoints: selectBlackListedOutpoints(state), - claim: makeSelectClaimForUri(props.uri)(state), - fileInfo: makeSelectFileInfoForUri(props.uri)(state), - filteredOutpoints: selectFilteredOutpoints(state), - isDownloaded: !!makeSelectFileInfoForUri(props.uri)(state), - metadata: makeSelectMetadataForUri(props.uri)(state), - nsfw: makeSelectClaimIsNsfw(props.uri)(state), - isResolvingUri: makeSelectIsUriResolving(props.uri)(state), - obscureNsfw: !selectShowNsfw(state), - rewardedContentClaimIds: selectRewardContentClaimIds(state), - shortUrl: makeSelectShortUrlForUri(props.uri)(state), - title: makeSelectTitleForUri(props.uri)(state), - thumbnail: makeSelectThumbnailForUri(props.uri)(state), -}); - -const perform = dispatch => ({ - resolveUri: uri => dispatch(doResolveUri(uri)), - setPlayerVisible: (visible, uri) => dispatch(doSetPlayerVisible(visible, uri)), -}); - -export default connect(select, perform)(ClaimResultItem); diff --git a/src/component/claimResultItem/view.js b/src/component/claimResultItem/view.js deleted file mode 100644 index c34a1fb..0000000 --- a/src/component/claimResultItem/view.js +++ /dev/null @@ -1,180 +0,0 @@ -import React from 'react'; -import { normalizeURI, parseURI } from 'lbry-redux'; -import { ActivityIndicator, Platform, Text, TouchableOpacity, View } from 'react-native'; -import { navigateToUri, getDownloadProgress, getStorageForFileInfo } from 'utils/helper'; -import Colors from 'styles/colors'; -import ChannelIconItem from 'component/channelIconItem'; -import channelIconStyle from 'styles/channelIcon'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api -import DateTime from 'component/dateTime'; -import FastImage from 'react-native-fast-image'; -import FileItemMedia from 'component/fileItemMedia'; -import FilePrice from 'component/filePrice'; -import Icon from 'react-native-vector-icons/FontAwesome5'; -import Link from 'component/link'; -import NsfwOverlay from 'component/nsfwOverlay'; -import ProgressBar from 'component/progressBar'; -import fileListStyle from 'styles/fileList'; -import seedrandom from 'seedrandom'; - -class ClaimResultItem extends React.PureComponent { - state = { - autoStyle: null, - }; - - componentDidMount() { - const { result } = this.props; - - if (!result || !result.name || !result.claimId) { - this.setState({ - autoStyle: - ChannelIconItem.AUTO_THUMB_STYLES[Math.floor(Math.random() * ChannelIconItem.AUTO_THUMB_STYLES.length)], - }); - } else { - // result property set, use deterministic random style - const rng = seedrandom(normalizeURI(`${result.name}#${result.claimId}`)); - const index = Math.floor(rng.quick() * ChannelIconItem.AUTO_THUMB_STYLES.length); - this.setState({ autoStyle: ChannelIconItem.AUTO_THUMB_STYLES[index] }); - } - } - - onPressHandler = () => { - const { autoplay, navigation, result, urlOpenHandler, setPlayerVisible } = this.props; - const { claimId, name } = result; - const url = normalizeURI(`${name}#${claimId}`); - if (urlOpenHandler) { - urlOpenHandler(url); - } else { - navigateToUri(navigation, url, { autoplay }, false, url, setPlayerVisible); - } - }; - - render() { - const { fileInfo, navigation, obscureNsfw, result, rewardedContentClaimIds, setPlayerVisible, style } = this.props; - const { - channel, - channel_claim_id: channelClaimId, - claimId, - duration, - fee, - name, - nsfw, - release_time: releaseTime, - thumbnail_url: thumbnailUrl, - title, - } = result; - - const isChannel = name && name.startsWith('@'); - const hasThumbnail = !!thumbnailUrl; - const obscure = obscureNsfw && nsfw; - const url = normalizeURI(`${name}#${claimId}`); - const hasChannel = !!channel; - const channelUrl = hasChannel ? normalizeURI(`${channel}#${channelClaimId}`) : null; - const isRewardContent = rewardedContentClaimIds.includes(claimId); - - return ( - <View style={style}> - <TouchableOpacity - style={[style, isChannel ? fileListStyle.channelContainer : null]} - onPress={this.onPressHandler} - > - {!isChannel && ( - <FileItemMedia - style={fileListStyle.thumbnail} - duration={duration} - resizeMode="cover" - title={title || name || normalizeURI(url).substring(7)} - thumbnail={thumbnailUrl} - /> - )} - - {isChannel && ( - <View style={fileListStyle.channelThumbnailView}> - <View style={[fileListStyle.channelThumbnailContainer, this.state.autoStyle]}> - {hasThumbnail && ( - <FastImage - style={fileListStyle.channelThumbnail} - resizeMode={FastImage.resizeMode.cover} - source={{ uri: thumbnailUrl }} - /> - )} - {!hasThumbnail && ( - <Text style={channelIconStyle.autothumbCharacter}> - {title ? title.substring(0, 1).toUpperCase() : name.substring(1, 2).toUpperCase()} - </Text> - )} - </View> - </View> - )} - - {fileInfo && fileInfo.completed && fileInfo.download_path && ( - <Icon style={fileListStyle.downloadedIcon} solid color={Colors.NextLbryGreen} name={'folder'} size={16} /> - )} - <FilePrice - cost={fee ? parseFloat(fee) / 100000000 : 0} - uri={url} - style={fileListStyle.filePriceContainer} - iconStyle={fileListStyle.filePriceIcon} - textStyle={fileListStyle.filePriceText} - /> - <View style={fileListStyle.detailsContainer}> - {(title || name) && ( - <View style={fileListStyle.titleContainer}> - <Text style={fileListStyle.title} numberOfLines={3}> - {title || name} - </Text> - {isRewardContent && <Icon style={fileListStyle.rewardIcon} name="award" size={12} />} - </View> - )} - - {(hasChannel || isChannel) && ( - <Link - style={fileListStyle.publisher} - text={isChannel ? name : channel} - onPress={() => { - navigateToUri( - navigation, - normalizeURI(isChannel ? url : channelUrl), - null, - false, - isChannel ? url : channelUrl, - setPlayerVisible, - ); - }} - /> - )} - - <View style={fileListStyle.info}> - {fileInfo && !isNaN(fileInfo.written_bytes) && fileInfo.written_bytes > 0 && ( - <Text style={fileListStyle.infoText}>{getStorageForFileInfo(fileInfo)}</Text> - )} - <DateTime - style={fileListStyle.publishInfo} - textStyle={fileListStyle.infoText} - timeAgo - date={releaseTime} - /> - </View> - - {fileInfo && fileInfo.download_path && ( - <View style={fileListStyle.downloadInfo}> - {!fileInfo.completed && ( - <ProgressBar - borderRadius={3} - color={Colors.NextLbryGreen} - height={3} - style={fileListStyle.progress} - progress={getDownloadProgress(fileInfo)} - /> - )} - </View> - )} - </View> - </TouchableOpacity> - {obscure && <NsfwOverlay onPress={() => navigation.navigate({ routeName: 'Settings', key: 'settingsPage' })} />} - </View> - ); - } -} - -export default ClaimResultItem; diff --git a/src/component/customRewardCard/view.js b/src/component/customRewardCard/view.js index 38abf29..2e8a826 100644 --- a/src/component/customRewardCard/view.js +++ b/src/component/customRewardCard/view.js @@ -20,7 +20,7 @@ class CustomRewardCard extends React.PureComponent<Props> { if (error && error.trim().length > 0) { notify({ message: error }); } else { - notify({ message: __('Reward successfully claimed!') }); + notify({ message: 'Reward successfully claimed!' }); this.setState({ rewardCode: '' }); } this.setState({ claimStarted: false }); @@ -37,12 +37,12 @@ class CustomRewardCard extends React.PureComponent<Props> { if (showVerification) { showVerification(); } - notify({ message: __('Unfortunately, you are not eligible to claim this reward at this time.') }); + notify({ message: 'Unfortunately, you are not eligible to claim this reward at this time.' }); return; } if (!rewardCode || rewardCode.trim().length === 0) { - notify({ message: __('Please enter a reward code to claim.') }); + notify({ message: 'Please enter a reward code to claim.' }); return; } @@ -60,9 +60,9 @@ class CustomRewardCard extends React.PureComponent<Props> { {rewardIsPending && <ActivityIndicator size="small" color={Colors.NextLbryGreen} />} </View> <View style={rewardStyle.midCol}> - <Text style={rewardStyle.rewardTitle}>{__('Custom Code')}</Text> + <Text style={rewardStyle.rewardTitle}>Custom Code</Text> <Text style={rewardStyle.rewardDescription}> - {__('Are you a supermodel or rockstar that received a custom reward code? Claim it here.')} + Are you a supermodel or rockstar that received a custom reward code? Claim it here. </Text> <View> @@ -74,7 +74,7 @@ class CustomRewardCard extends React.PureComponent<Props> { /> <Button style={rewardStyle.redeemButton} - text={__('Redeem')} + text={'Redeem'} disabled={!this.state.rewardCode || this.state.rewardCode.trim().length === 0 || rewardIsPending} onPress={() => { if (!rewardIsPending) { diff --git a/src/component/drawerContent/index.js b/src/component/drawerContent/index.js index e4a5531..3df7cec 100644 --- a/src/component/drawerContent/index.js +++ b/src/component/drawerContent/index.js @@ -1,19 +1,4 @@ import { connect } from 'react-redux'; -import { doToast, selectBalance, selectMyChannelClaims } from 'lbry-redux'; -import { selectUnclaimedRewardValue, selectUser } from 'lbryinc'; -import { selectSdkReady } from 'redux/selectors/settings'; import DrawerContent from './view'; -const select = state => ({ - balance: selectBalance(state), - channels: selectMyChannelClaims(state), - sdkReady: selectSdkReady(state), - unclaimedRewardAmount: selectUnclaimedRewardValue(state), - user: selectUser(state), -}); - -const perform = dispatch => ({ - notify: data => dispatch(doToast(data)), -}); - -export default connect(select, perform)(DrawerContent); +export default connect()(DrawerContent); diff --git a/src/component/drawerContent/view.js b/src/component/drawerContent/view.js index cf224c2..f0e4fc1 100644 --- a/src/component/drawerContent/view.js +++ b/src/component/drawerContent/view.js @@ -1,227 +1,36 @@ import React from 'react'; import { DrawerItems, SafeAreaView } from 'react-navigation'; -import { Image, ScrollView, Text, TouchableOpacity, View } from 'react-native'; -import Button from 'component/button'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api -import Icon from 'react-native-vector-icons/FontAwesome5'; -import channelIconStyle from 'styles/channelIcon'; +import { ScrollView } from 'react-native'; +import Constants from 'constants'; import discoverStyle from 'styles/discover'; -import { Lbryio } from 'lbryinc'; -import { formatUsd } from 'utils/helper'; - -const groupedMenuItems = { - 'Find content': [ - { icon: 'heart', solid: true, label: 'Following', route: Constants.DRAWER_ROUTE_SUBSCRIPTIONS }, - { icon: 'hashtag', label: 'Your Tags', route: Constants.DRAWER_ROUTE_DISCOVER }, - { icon: 'globe-americas', label: 'All Content', route: Constants.DRAWER_ROUTE_TRENDING }, - ], - 'Your content': [ - { icon: 'at', label: 'Channels', route: Constants.DRAWER_ROUTE_CHANNEL_CREATOR }, - { icon: 'download', label: 'Library', route: Constants.DRAWER_ROUTE_MY_LBRY }, - { icon: 'cloud-upload-alt', label: 'Publishes', route: Constants.DRAWER_ROUTE_PUBLISHES }, - { icon: 'upload', label: 'New Publish', route: Constants.DRAWER_ROUTE_PUBLISH }, - ], - Wallet: [ - { icon: 'wallet', label: 'Wallet', route: Constants.DRAWER_ROUTE_WALLET }, - { icon: 'award', label: 'Rewards', route: Constants.DRAWER_ROUTE_REWARDS }, - { icon: 'user-friends', label: 'Invites', route: Constants.DRAWER_ROUTE_INVITES }, - ], - Settings: [ - { icon: 'cog', label: 'Settings', route: Constants.DRAWER_ROUTE_SETTINGS }, - { icon: 'info', label: 'About', route: Constants.DRAWER_ROUTE_ABOUT }, - ], -}; - -const groupNames = Object.keys(groupedMenuItems); -const routesRequiringSdkReady = [ - Constants.DRAWER_ROUTE_CHANNEL_CREATOR, - Constants.DRAWER_ROUTE_MY_LBRY, - Constants.DRAWER_ROUTE_PUBLISHES, - Constants.DRAWER_ROUTE_PUBLISH, - Constants.DRAWER_ROUTE_WALLET, - Constants.DRAWER_ROUTE_REWARDS, - Constants.DRAWER_ROUTE_INVITES, -]; class DrawerContent extends React.PureComponent { - state = { - usdExchangeRate: 0, - }; - - componentDidMount() { - Lbryio.getExchangeRates().then(rates => { - if (!isNaN(rates.LBC_USD)) { - this.setState({ usdExchangeRate: rates.LBC_USD }); - } - }); - } - - getAvatarImageUrl = () => { - const { channels = [] } = this.props; - if (channels) { - // get the first channel thumbnail found. In the future, allow the user to select a default channel thumbnail? - for (let i = 0; i < channels.length; i++) { - if (channels[i].value && channels[i].value.thumbnail) { - return channels[i].value.thumbnail.url; - } - } - } - - return null; - }; - - launchSignInFlow = () => { - // for now, sync flow (email, then password input) will be the default sign in flow - const { navigation } = this.props; - navigation.navigate({ - routeName: 'Verification', - key: 'verification', - params: { syncFlow: true, signInFlow: true }, - }); - }; - - handleItemPress = routeName => { - const { navigation, notify, sdkReady } = this.props; - if (!sdkReady && routesRequiringSdkReady.includes(routeName)) { - if (navigation.closeDrawer) { - navigation.closeDrawer(); - } - notify({ - message: __('The background service is still initializing. Please try again when initialization is complete.'), - }); - return; - } - - navigation.navigate({ routeName: routeName }); - }; - render() { - const { activeTintColor, balance, navigation, unclaimedRewardAmount, user, onItemPress } = this.props; - const { state } = navigation; - - const activeItemKey = state.routes[state.index] ? state.routes[state.index].key : null; - const signedIn = user && user.has_verified_email; - const avatarImageUrl = this.getAvatarImageUrl(); + const props = this.props; + const { navigation, onItemPress } = props; return ( - <View style={discoverStyle.drawerContentArea}> - {false && ( - <View style={discoverStyle.signInContainer}> - {!signedIn && ( - <Button - style={discoverStyle.signInButton} - theme={'light'} - text={__('Sign in')} - onPress={this.launchSignInFlow} - /> - )} - {signedIn && ( - <View style={discoverStyle.signedIn}> - <View style={discoverStyle.signedInAvatar}> - {avatarImageUrl && ( - <Image - style={discoverStyle.signedInAvatarImage} - resizeMode={'cover'} - source={{ uri: avatarImageUrl }} - /> - )} - {!avatarImageUrl && ( - <Text style={channelIconStyle.autothumbCharacter}> - {user.primary_email.substring(0, 1).toUpperCase()} - </Text> - )} - </View> - <Text style={discoverStyle.signedInEmail} numberOfLines={1}> - {user.primary_email} - </Text> - </View> - )} - </View> - )} + <ScrollView> + <SafeAreaView style={discoverStyle.drawerContentContainer} forceInset={{ top: 'always', horizontal: 'never' }}> + <DrawerItems + {...props} + onItemPress={route => { + const { routeName } = route.route; + if (Constants.FULL_ROUTE_NAME_DISCOVER === routeName) { + navigation.navigate({ routeName: Constants.DRAWER_ROUTE_DISCOVER }); + return; + } - <ScrollView contentContainerStyle={discoverStyle.menuScrollContent}> - <SafeAreaView - style={discoverStyle.drawerContentContainer} - forceInset={{ top: 'always', horizontal: 'never' }} - > - {!signedIn && ( - <TouchableOpacity - accessible - accessibilityLabel={__('Sign In')} - onPress={this.launchSignInFlow} - delayPressIn={0} - style={[discoverStyle.signInMenuItem, discoverStyle.signInMenuItemButton]} - > - <Text style={discoverStyle.signInMenuItemButtonText}>{__('SIGN IN')}</Text> - </TouchableOpacity> - )} + if (Constants.FULL_ROUTE_NAME_WALLET === routeName) { + navigation.navigate({ routeName: Constants.DRAWER_ROUTE_WALLET }); + return; + } - {signedIn && ( - <View style={[discoverStyle.signInMenuItem, discoverStyle.signInMenuItemBorder]}> - <Text style={discoverStyle.signInMenuItemText} numberOfLines={1}> - {user.primary_email.toUpperCase()} - </Text> - </View> - )} - - {groupNames.map(groupName => { - const menuItems = groupedMenuItems[groupName]; - - return ( - <View key={groupName} style={discoverStyle.menuGroup}> - {groupNames[3] !== groupName && ( - <Text key={`${groupName}-title`} style={discoverStyle.menuGroupName}> - {__(groupName)} - </Text> - )} - {menuItems.map(item => { - const focused = - activeItemKey === item.route || - (activeItemKey === Constants.FULL_ROUTE_NAME_DISCOVER && - item.route === Constants.DRAWER_ROUTE_SUBSCRIPTIONS) || - (activeItemKey === Constants.FULL_ROUTE_NAME_WALLET && - item.route === Constants.DRAWER_ROUTE_WALLET); - return ( - <TouchableOpacity - accessible - accessibilityLabel={__(item.label)} - style={[ - discoverStyle.menuItemTouchArea, - focused ? discoverStyle.menuItemTouchAreaFocused : null, - ]} - key={item.label} - onPress={() => this.handleItemPress(item.route)} - delayPressIn={0} - > - <View style={discoverStyle.menuItemIcon}> - <Icon - name={item.icon} - size={16} - solid={item.solid} - color={focused ? activeTintColor : null} - /> - </View> - <Text style={[discoverStyle.menuItem, focused ? discoverStyle.menuItemFocused : null]}> - {__(item.label)} - {item.label === 'Wallet' && this.state.usdExchangeRate > 0 && ( - <Text> ({formatUsd(parseFloat(balance) * parseFloat(this.state.usdExchangeRate))})</Text> - )} - {item.label === 'Rewards' && this.state.usdExchangeRate > 0 && ( - <Text> - {' '} - ({formatUsd(parseFloat(unclaimedRewardAmount) * parseFloat(this.state.usdExchangeRate))}) - </Text> - )} - </Text> - </TouchableOpacity> - ); - })} - </View> - ); - })} - </SafeAreaView> - </ScrollView> - </View> + onItemPress(route); + }} + /> + </SafeAreaView> + </ScrollView> ); } } diff --git a/src/component/emptyStateView/index.js b/src/component/emptyStateView/index.js deleted file mode 100644 index 53e1c84..0000000 --- a/src/component/emptyStateView/index.js +++ /dev/null @@ -1,4 +0,0 @@ -import { connect } from 'react-redux'; -import EmptyStateView from './view'; - -export default connect()(EmptyStateView); diff --git a/src/component/emptyStateView/view.js b/src/component/emptyStateView/view.js deleted file mode 100644 index e69ceda..0000000 --- a/src/component/emptyStateView/view.js +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react'; -import { NativeModules, Text, View, Image, TouchableOpacity } from 'react-native'; -import Button from '../button'; -import emptyStateStyle from 'styles/emptyState'; - -class EmptyStateView extends React.PureComponent { - render() { - const { message, buttonText, inner, onButtonPress } = this.props; - - return ( - <View - style={[emptyStateStyle.container, inner ? emptyStateStyle.innerContainer : emptyStateStyle.outerContainer]} - > - <Image style={emptyStateStyle.image} resizeMode={'stretch'} source={require('../../assets/gerbil-happy.png')} /> - <Text style={emptyStateStyle.message}>{message}</Text> - {buttonText && ( - <View style={emptyStateStyle.buttonContainer}> - <Button style={emptyStateStyle.button} text={buttonText} onPress={onButtonPress} /> - </View> - )} - </View> - ); - } -} - -export default EmptyStateView; diff --git a/src/component/fileDownloadButton/view.js b/src/component/fileDownloadButton/view.js index 019a489..2834b38 100644 --- a/src/component/fileDownloadButton/view.js +++ b/src/component/fileDownloadButton/view.js @@ -11,6 +11,11 @@ class FileDownloadButton extends React.PureComponent { } } + componentWillReceiveProps(nextProps) { + //this.checkAvailability(nextProps.uri); + //this.restartDownload(nextProps); + } + restartDownload(props) { const { downloading, fileInfo, uri, restartDownload } = props; @@ -30,6 +35,7 @@ class FileDownloadButton extends React.PureComponent { fileInfo, downloading, uri, + purchaseUri, costInfo, isPlayable, isViewable, @@ -39,27 +45,18 @@ class FileDownloadButton extends React.PureComponent { doPause, style, openFile, - onFileActionPress, onButtonLayout, } = this.props; - if (fileInfo && fileInfo.download_path && fileInfo.completed) { - return ( - <TouchableOpacity - onLayout={onButtonLayout} - style={[style, fileDownloadButtonStyle.container]} - onPress={openFile} - > - <Text style={fileDownloadButtonStyle.text}>{isViewable ? __('View') : __('Open')}</Text> - </TouchableOpacity> - ); - } else if ((fileInfo && !fileInfo.stopped) || loading || downloading) { + if ((fileInfo && !fileInfo.stopped) || loading || downloading) { const progress = fileInfo && fileInfo.written_bytes ? (fileInfo.written_bytes / fileInfo.total_bytes) * 100 : 0, - label = fileInfo ? __('%progress%% complete', { progress: progress.toFixed(0) }) : __('Connecting...'); + label = fileInfo ? progress.toFixed(0) + '% complete' : 'Connecting...'; return ( <View style={[style, fileDownloadButtonStyle.container]}> - <View style={{ width: `${progress}%`, backgroundColor: '#ff0000', position: 'absolute', left: 0, top: 0 }} /> + <View + style={{ width: `${progress}%`, backgroundColor: '#ff0000', position: 'absolute', left: 0, top: 0 }} + ></View> <Text style={fileDownloadButtonStyle.text}>{label}</Text> </View> ); @@ -67,19 +64,43 @@ class FileDownloadButton extends React.PureComponent { if (!costInfo) { return ( <View style={[style, fileDownloadButtonStyle.container]}> - <Text style={fileDownloadButtonStyle.text}>{__('Fetching cost info...')}</Text> + <Text style={fileDownloadButtonStyle.text}>Fetching cost info...</Text> </View> ); } return ( <Button icon={isPlayable ? 'play' : null} - text={isPlayable ? __('Play') : isViewable ? __('View') : __('Download')} + text={isPlayable ? 'Play' : isViewable ? 'View' : 'Download'} onLayout={onButtonLayout} style={[style, fileDownloadButtonStyle.container]} - onPress={onFileActionPress} + onPress={() => { + if (NativeModules.Firebase) { + NativeModules.Firebase.track('purchase_uri', { uri: uri }); + } + purchaseUri(uri, costInfo, !isPlayable); + if (NativeModules.UtilityModule) { + NativeModules.UtilityModule.checkDownloads(); + } + if (isPlayable && onPlay) { + this.props.onPlay(); + } + if (isViewable && onView) { + this.props.onView(); + } + }} /> ); + } else if (fileInfo && fileInfo.download_path) { + return ( + <TouchableOpacity + onLayout={onButtonLayout} + style={[style, fileDownloadButtonStyle.container]} + onPress={openFile} + > + <Text style={fileDownloadButtonStyle.text}>{isViewable ? 'View' : 'Open'}</Text> + </TouchableOpacity> + ); } return null; diff --git a/src/component/fileItem/index.js b/src/component/fileItem/index.js index fd9a61d..1db058c 100644 --- a/src/component/fileItem/index.js +++ b/src/component/fileItem/index.js @@ -8,23 +8,18 @@ import { makeSelectTitleForUri, makeSelectIsUriResolving, makeSelectClaimIsNsfw, - makeSelectShortUrlForUri, } from 'lbry-redux'; -import { doSetPlayerVisible } from 'redux/actions/drawer'; -import { selectBlackListedOutpoints, selectFilteredOutpoints, selectRewardContentClaimIds } from 'lbryinc'; +import { selectRewardContentClaimIds } from 'lbryinc'; import { selectShowNsfw } from 'redux/selectors/settings'; import FileItem from './view'; const select = (state, props) => ({ - blackListedOutpoints: selectBlackListedOutpoints(state), claim: makeSelectClaimForUri(props.uri)(state), fileInfo: makeSelectFileInfoForUri(props.uri)(state), - filteredOutpoints: selectFilteredOutpoints(state), metadata: makeSelectMetadataForUri(props.uri)(state), - rewardedContentClaimIds: selectRewardContentClaimIds(state), + rewardedContentClaimIds: selectRewardContentClaimIds(state, props), isResolvingUri: makeSelectIsUriResolving(props.uri)(state), obscureNsfw: !selectShowNsfw(state), - shortUrl: makeSelectShortUrlForUri(props.uri)(state), thumbnail: makeSelectThumbnailForUri(props.uri)(state), title: makeSelectTitleForUri(props.uri)(state), nsfw: makeSelectClaimIsNsfw(props.uri)(state), @@ -32,7 +27,9 @@ const select = (state, props) => ({ const perform = dispatch => ({ resolveUri: uri => dispatch(doResolveUri(uri)), - setPlayerVisible: (visible, uri) => dispatch(doSetPlayerVisible(visible, uri)), }); -export default connect(select, perform)(FileItem); +export default connect( + select, + perform +)(FileItem); diff --git a/src/component/fileItem/view.js b/src/component/fileItem/view.js index c2066a5..8cc0237 100644 --- a/src/component/fileItem/view.js +++ b/src/component/fileItem/view.js @@ -30,65 +30,39 @@ class FileItem extends React.PureComponent { } navigateToFileUri = () => { - const { claim, navigation, uri, shortUrl } = this.props; + const { navigation, uri } = this.props; const normalizedUri = normalizeURI(uri); if (NativeModules.Firebase) { - NativeModules.Firebase.track('explore_click', { uri: normalizedUri, short_url: shortUrl }); + NativeModules.Firebase.track('explore_click', { uri: normalizedUri }); } - navigateToUri(navigation, shortUrl || uri, null, false, claim ? claim.permanent_url : null); + navigateToUri(navigation, normalizedUri); }; render() { const { - blackListedOutpoints, claim, title, thumbnail, fileInfo, - filteredOutpoints, metadata, isResolvingUri, rewardedContentClaimIds, style, mediaStyle, navigation, - nsfw, - obscureNsfw, showDetails, compactView, - setPlayerVisible, titleBeforeThumbnail, } = this.props; - if (claim && claim.value_type === 'channel') { - // don't display channels in the lists on the Your tags page - return null; - } - - let shouldHide = false; - if (blackListedOutpoints || filteredOutpoints) { - const outpointsToHide = !blackListedOutpoints - ? filteredOutpoints - : blackListedOutpoints.concat(filteredOutpoints); - shouldHide = outpointsToHide.some( - outpoint => outpoint && outpoint.txid === claim.txid && outpoint.nout === claim.nout, - ); - } - if (shouldHide) { - // don't display blacklisted or filtered outpoints on the Your tags page - return null; - } - const uri = normalizeURI(this.props.uri); - const obscure = obscureNsfw && nsfw; + const obscureNsfw = this.props.obscureNsfw && metadata && metadata.nsfw; const isRewardContent = claim && rewardedContentClaimIds.includes(claim.claim_id); const signingChannel = claim ? claim.signing_channel : null; const channelName = signingChannel ? signingChannel.name : null; const channelClaimId = signingChannel ? signingChannel.claim_id : null; const fullChannelUri = channelClaimId ? `${channelName}#${channelClaimId}` : channelName; - const shortChannelUri = signingChannel ? signingChannel.short_url : null; const height = claim ? claim.height : null; - const duration = claim && claim.value && claim.value.video ? claim.value.video.duration : null; return ( <View style={style}> @@ -99,23 +73,19 @@ class FileItem extends React.PureComponent { </Text> )} <FileItemMedia - duration={duration} title={title} thumbnail={thumbnail} + blurRadius={obscureNsfw ? 15 : 0} resizeMode="cover" isResolvingUri={isResolvingUri} style={mediaStyle} /> + {!compactView && fileInfo && fileInfo.completed && fileInfo.download_path && ( <Icon style={discoverStyle.downloadedIcon} solid color={Colors.NextLbryGreen} name={'folder'} size={16} /> )} {!compactView && (!fileInfo || !fileInfo.completed || !fileInfo.download_path) && ( - <FilePrice - uri={uri} - style={discoverStyle.filePriceContainer} - iconStyle={discoverStyle.filePriceIcon} - textStyle={discoverStyle.filePriceText} - /> + <FilePrice uri={uri} style={discoverStyle.filePriceContainer} textStyle={discoverStyle.filePriceText} /> )} {!compactView && ( <View style={isRewardContent ? discoverStyle.rewardTitleContainer : null}> @@ -132,23 +102,17 @@ class FileItem extends React.PureComponent { style={discoverStyle.channelName} text={channelName} onPress={() => { - navigateToUri( - navigation, - normalizeURI(shortChannelUri || fullChannelUri), - null, - false, - fullChannelUri, - setPlayerVisible, - ); + navigateToUri(navigation, normalizeURI(fullChannelUri)); }} /> )} - {!channelName && !isResolvingUri && <Text style={discoverStyle.anonChannelName}>{__('Anonymous')}</Text>} <DateTime style={discoverStyle.dateTime} textStyle={discoverStyle.dateTimeText} timeAgo uri={uri} /> </View> )} </TouchableOpacity> - {obscure && <NsfwOverlay onPress={() => navigation.navigate({ routeName: 'Settings', key: 'settingsPage' })} />} + {obscureNsfw && ( + <NsfwOverlay onPress={() => navigation.navigate({ routeName: 'Settings', key: 'settingsPage' })} /> + )} </View> ); } diff --git a/src/component/fileItemMedia/view.js b/src/component/fileItemMedia/view.js index 371cef7..ac01667 100644 --- a/src/component/fileItemMedia/view.js +++ b/src/component/fileItemMedia/view.js @@ -2,26 +2,24 @@ import React from 'react'; import { ActivityIndicator, Image, Text, View } from 'react-native'; import Colors from 'styles/colors'; import FastImage from 'react-native-fast-image'; -import VideoDuration from 'component/videoDuration'; -import autothumbStyle from 'styles/autothumb'; import fileItemMediaStyle from 'styles/fileItemMedia'; class FileItemMedia extends React.PureComponent { static AUTO_THUMB_STYLES = [ - autothumbStyle.autothumbPurple, - autothumbStyle.autothumbRed, - autothumbStyle.autothumbPink, - autothumbStyle.autothumbIndigo, - autothumbStyle.autothumbBlue, - autothumbStyle.autothumbLightBlue, - autothumbStyle.autothumbCyan, - autothumbStyle.autothumbTeal, - autothumbStyle.autothumbGreen, - autothumbStyle.autothumbYellow, - autothumbStyle.autothumbOrange, + fileItemMediaStyle.autothumbPurple, + fileItemMediaStyle.autothumbRed, + fileItemMediaStyle.autothumbPink, + fileItemMediaStyle.autothumbIndigo, + fileItemMediaStyle.autothumbBlue, + fileItemMediaStyle.autothumbLightBlue, + fileItemMediaStyle.autothumbCyan, + fileItemMediaStyle.autothumbTeal, + fileItemMediaStyle.autothumbGreen, + fileItemMediaStyle.autothumbYellow, + fileItemMediaStyle.autothumbOrange, ]; - state = { + state: { imageLoadFailed: false, }; @@ -50,7 +48,7 @@ class FileItemMedia extends React.PureComponent { return false; } - if (thumbnail.substring(0, 7) !== 'http://' && thumbnail.substring(0, 8) !== 'https://') { + if (thumbnail.substring(0, 7) != 'http://' && thumbnail.substring(0, 8) != 'https://') { return false; } @@ -59,36 +57,37 @@ class FileItemMedia extends React.PureComponent { render() { let style = this.props.style; - const { duration, isResolvingUri, thumbnail, title, resizeMode } = this.props; + const { blurRadius, isResolvingUri, thumbnail, title, resizeMode } = this.props; const atStyle = this.state.autoThumbStyle; - const hasDuration = !!duration; - if (this.isThumbnailValid(thumbnail) && !this.state.imageLoadFailed) { if (style == null) { style = fileItemMediaStyle.thumbnail; } - return ( - <View style={style}> - <FastImage + if (blurRadius > 0) { + // No blur radius support in FastImage yet + return ( + <Image source={{ uri: thumbnail }} - onError={() => this.setState({ imageLoadFailed: true })} - resizeMode={this.getFastImageResizeMode(resizeMode)} - style={fileItemMediaStyle.image} + blurRadius={blurRadius} + resizeMode={resizeMode ? resizeMode : 'cover'} + style={style} /> - {duration > 0 && ( - <VideoDuration - duration={duration} - style={fileItemMediaStyle.duration} - textStyle={fileItemMediaStyle.durationText} - /> - )} - </View> + ); + } + + return ( + <FastImage + source={{ uri: thumbnail }} + onError={() => this.setState({ imageLoadFailed: true })} + resizeMode={this.getFastImageResizeMode(resizeMode)} + style={style} + /> ); } return ( - <View style={[style || fileItemMediaStyle.autothumb, atStyle]}> + <View style={[style ? style : fileItemMediaStyle.autothumb, atStyle]}> {isResolvingUri && ( <View style={fileItemMediaStyle.resolving}> <ActivityIndicator color={Colors.White} size={'large'} /> @@ -105,13 +104,6 @@ class FileItemMedia extends React.PureComponent { .toUpperCase()} </Text> )} - {duration > 0 && ( - <VideoDuration - duration={duration} - style={fileItemMediaStyle.duration} - textStyle={fileItemMediaStyle.durationText} - /> - )} </View> ); } diff --git a/src/component/fileList/view.js b/src/component/fileList/view.js index e1a7add..68ad848 100644 --- a/src/component/fileList/view.js +++ b/src/component/fileList/view.js @@ -53,39 +53,39 @@ class FileList extends React.PureComponent<Props, State> { dateNew: fileInfos => this.props.sortByHeight ? fileInfos.slice().sort((fileInfo1, fileInfo2) => { - if (fileInfo1.pending) { - return -1; - } - const height1 = this.props.claimsById[fileInfo1.claim_id] - ? this.props.claimsById[fileInfo1.claim_id].height - : 0; - const height2 = this.props.claimsById[fileInfo2.claim_id] - ? this.props.claimsById[fileInfo2.claim_id].height - : 0; - if (height1 > height2) { - return -1; - } else if (height1 < height2) { - return 1; - } - return 0; - }) + if (fileInfo1.pending) { + return -1; + } + const height1 = this.props.claimsById[fileInfo1.claim_id] + ? this.props.claimsById[fileInfo1.claim_id].height + : 0; + const height2 = this.props.claimsById[fileInfo2.claim_id] + ? this.props.claimsById[fileInfo2.claim_id].height + : 0; + if (height1 > height2) { + return -1; + } else if (height1 < height2) { + return 1; + } + return 0; + }) : [...fileInfos].reverse(), dateOld: fileInfos => this.props.sortByHeight ? fileInfos.slice().sort((fileInfo1, fileInfo2) => { - const height1 = this.props.claimsById[fileInfo1.claim_id] - ? this.props.claimsById[fileInfo1.claim_id].height - : 999999; - const height2 = this.props.claimsById[fileInfo2.claim_id] - ? this.props.claimsById[fileInfo2.claim_id].height - : 999999; - if (height1 < height2) { - return -1; - } else if (height1 > height2) { - return 1; - } - return 0; - }) + const height1 = this.props.claimsById[fileInfo1.claim_id] + ? this.props.claimsById[fileInfo1.claim_id].height + : 999999; + const height2 = this.props.claimsById[fileInfo2.claim_id] + ? this.props.claimsById[fileInfo2.claim_id].height + : 999999; + if (height1 < height2) { + return -1; + } else if (height1 > height2) { + return 1; + } + return 0; + }) : fileInfos, title: fileInfos => fileInfos.slice().sort((fileInfo1, fileInfo2) => { @@ -160,7 +160,7 @@ class FileList extends React.PureComponent<Props, State> { // This is unfortunate // https://github.com/lbryio/lbry/issues/1159 const name = claimName || claimNameDownloaded; - uriParams.claimName = name; + uriParams.contentName = name; uriParams.claimId = claimId; const uri = buildURI(uriParams); @@ -179,7 +179,7 @@ class FileList extends React.PureComponent<Props, State> { style={fileListStyle.fileItem} uri={item} navigation={navigation} - showDetails + showDetails={true} compactView={false} /> )} diff --git a/src/component/fileListItem/index.js b/src/component/fileListItem/index.js index 78e0e0a..b514ad9 100644 --- a/src/component/fileListItem/index.js +++ b/src/component/fileListItem/index.js @@ -5,13 +5,10 @@ import { makeSelectMetadataForUri, makeSelectFileInfoForUri, makeSelectIsUriResolving, - makeSelectClaimIsNsfw, - makeSelectShortUrlForUri, makeSelectTitleForUri, makeSelectThumbnailForUri, } from 'lbry-redux'; -import { doSetPlayerVisible } from 'redux/actions/drawer'; -import { selectBlackListedOutpoints, selectFilteredOutpoints, selectRewardContentClaimIds } from 'lbryinc'; +import { selectBlackListedOutpoints, selectFilteredOutpoints } from 'lbryinc'; import { selectShowNsfw } from 'redux/selectors/settings'; import FileListItem from './view'; @@ -22,18 +19,17 @@ const select = (state, props) => ({ filteredOutpoints: selectFilteredOutpoints(state), isDownloaded: !!makeSelectFileInfoForUri(props.uri)(state), metadata: makeSelectMetadataForUri(props.uri)(state), - nsfw: makeSelectClaimIsNsfw(props.uri)(state), isResolvingUri: makeSelectIsUriResolving(props.uri)(state), obscureNsfw: !selectShowNsfw(state), - rewardedContentClaimIds: selectRewardContentClaimIds(state), - shortUrl: makeSelectShortUrlForUri(props.uri)(state), title: makeSelectTitleForUri(props.uri)(state), thumbnail: makeSelectThumbnailForUri(props.uri)(state), }); const perform = dispatch => ({ resolveUri: uri => dispatch(doResolveUri(uri)), - setPlayerVisible: (visible, uri) => dispatch(doSetPlayerVisible(visible, uri)), }); -export default connect(select, perform)(FileListItem); +export default connect( + select, + perform +)(FileListItem); diff --git a/src/component/fileListItem/view.js b/src/component/fileListItem/view.js index 498a18b..90088cf 100644 --- a/src/component/fileListItem/view.js +++ b/src/component/fileListItem/view.js @@ -1,15 +1,10 @@ import React from 'react'; import { normalizeURI, parseURI } from 'lbry-redux'; import { ActivityIndicator, Platform, Text, TouchableOpacity, View } from 'react-native'; -import { navigateToUri, getDownloadProgress, getStorageForFileInfo } from 'utils/helper'; +import { navigateToUri, formatBytes } from 'utils/helper'; import Colors from 'styles/colors'; -import ChannelIconItem from 'component/channelIconItem'; -import channelIconStyle from 'styles/channelIcon'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api import DateTime from 'component/dateTime'; -import FastImage from 'react-native-fast-image'; import FileItemMedia from 'component/fileItemMedia'; -import FilePrice from 'component/filePrice'; import Icon from 'react-native-vector-icons/FontAwesome5'; import Link from 'component/link'; import NsfwOverlay from 'component/nsfwOverlay'; @@ -17,9 +12,22 @@ import ProgressBar from 'component/progressBar'; import fileListStyle from 'styles/fileList'; class FileListItem extends React.PureComponent { - state = { - autoStyle: null, - url: null, + getStorageForFileInfo = fileInfo => { + if (!fileInfo.completed) { + const written = formatBytes(fileInfo.written_bytes); + const total = formatBytes(fileInfo.total_bytes); + return `(${written} / ${total})`; + } + + return formatBytes(fileInfo.written_bytes); + }; + + formatTitle = title => { + if (!title) { + return title; + } + + return title.length > 80 ? title.substring(0, 77).trim() + '...' : title; }; getDownloadProgress = fileInfo => { @@ -27,41 +35,15 @@ class FileListItem extends React.PureComponent { }; componentDidMount() { - const { claim, resolveUri, uri, batchResolve } = this.props; - if (!claim && !batchResolve) { + const { claim, resolveUri, uri } = this.props; + if (!claim) { resolveUri(uri); } - - this.setState({ - autoStyle: - ChannelIconItem.AUTO_THUMB_STYLES[Math.floor(Math.random() * ChannelIconItem.AUTO_THUMB_STYLES.length)], - }); - } - - componentDidUpdate() { - const { claim, resolveUri, uri, batchResolve } = this.props; - if (!claim && uri !== this.state.url && !batchResolve) { - this.setState({ url: uri }, () => resolveUri(uri)); - } } defaultOnPress = () => { - const { autoplay, claim, featuredResult, navigation, uri, shortUrl } = this.props; - - if (featuredResult && !claim) { - navigation.navigate({ routeName: Constants.DRAWER_ROUTE_PUBLISH, params: { vanityUrl: uri.trim() } }); - } else { - navigateToUri(navigation, shortUrl || uri, { autoplay }, false, claim ? claim.permanent_url : null); - } - }; - - onPressHandler = () => { - const { claim, onPress } = this.props; - if (onPress) { - onPress(claim); - } else { - this.defaultOnPress(); - } + const { navigation, uri } = this.props; + navigateToUri(navigation, uri); }; render() { @@ -71,160 +53,53 @@ class FileListItem extends React.PureComponent { fileInfo, filteredOutpoints, metadata, - nsfw, featuredResult, isResolvingUri, isDownloaded, style, - obscureNsfw, onPress, navigation, - rewardedContentClaimIds, - setPlayerVisible, thumbnail, hideChannel, - onLongPress, - selected, title, } = this.props; const uri = normalizeURI(this.props.uri); - const obscure = obscureNsfw && nsfw; + const obscureNsfw = this.props.obscureNsfw && metadata && metadata.nsfw; const isResolving = !fileInfo && isResolvingUri; - const duration = claim && claim.value && claim.value.video ? claim.value.video.duration : null; - let name, - channel, - height, - isRewardContent, - channelClaimId, - fullChannelUri, - repostUrl, - repostChannel, - repostChannelUrl, - shortChannelUri, - shouldHide, - signingChannel, - isRepost; + let name, channel, height, channelClaimId, fullChannelUri, shouldHide, signingChannel; if (claim) { name = claim.name; signingChannel = claim.signing_channel; channel = signingChannel ? signingChannel.name : null; height = claim.height; - isRewardContent = rewardedContentClaimIds.includes(claim.claim_id); channelClaimId = signingChannel ? signingChannel.claim_id : null; fullChannelUri = channelClaimId ? `${channel}#${channelClaimId}` : channel; - shortChannelUri = signingChannel ? signingChannel.short_url : null; - repostUrl = claim.repost_url; - repostChannelUrl = claim.repost_channel_url; - if (repostUrl) { - const { claimName: repostName, channelName } = parseURI(repostUrl); - repostChannel = channelName; - } - isRepost = !!repostUrl; if (blackListedOutpoints || filteredOutpoints) { - const outpointsToHide = !blackListedOutpoints - ? filteredOutpoints - : blackListedOutpoints.concat(filteredOutpoints); - shouldHide = outpointsToHide.some( - outpoint => outpoint && outpoint.txid === claim.txid && outpoint.nout === claim.nout, - ); + const outpointsToHide = blackListedOutpoints.concat(filteredOutpoints); + shouldHide = outpointsToHide.some(outpoint => outpoint.txid === claim.txid && outpoint.nout === claim.nout); } - - // TODO: hide channels on tag pages? - // shouldHide = 'channel' === claim.value_type; } - if (shouldHide || (!isResolvingUri && !claim && !featuredResult)) { + if (shouldHide || (featuredResult && !isResolvingUri && !claim && !title && !name)) { return null; } - const actualHideChannel = !isRepost && hideChannel; - const isChannel = name && name.startsWith('@'); - const hasThumbnail = !!thumbnail; return ( - <View> - {isRepost && ( - <View style={fileListStyle.repostInfo}> - <Icon name={'retweet'} size={14} style={fileListStyle.repostIcon} /> - <Text style={fileListStyle.repostChannelName}> - <Link - text={`@${repostChannel}`} - onPress={() => - navigateToUri( - navigation, - normalizeURI(repostChannelUrl || `@${repostChannel}`), - null, - false, - null, - false, - ) - } - />{' '} - reposted - </Text> - </View> - )} - - <TouchableOpacity - style={[style, isChannel ? fileListStyle.channelContainer : null]} - onPress={this.onPressHandler} - onLongPress={() => { - if (onLongPress) { - onLongPress(claim); - } - }} - > - {!isChannel && ( - <FileItemMedia - style={fileListStyle.thumbnail} - duration={duration} - resizeMode="cover" - title={title || name || normalizeURI(uri).substring(7)} - thumbnail={thumbnail} - /> - )} - - {isChannel && ( - <View style={fileListStyle.channelThumbnailView}> - <View style={[fileListStyle.channelThumbnailContainer, this.state.autoStyle]}> - {hasThumbnail && ( - <FastImage - style={fileListStyle.channelThumbnail} - resizeMode={FastImage.resizeMode.cover} - source={{ uri: thumbnail }} - /> - )} - {!hasThumbnail && ( - <Text style={channelIconStyle.autothumbCharacter}> - {title ? title.substring(0, 1).toUpperCase() : claim.name.substring(1, 2).toUpperCase()} - </Text> - )} - </View> - </View> - )} - - {selected && ( - <View style={fileListStyle.selectedOverlay}> - <Icon name={'check-circle'} solid color={Colors.NextLbryGreen} size={32} /> - </View> - )} - {fileInfo && fileInfo.completed && fileInfo.download_path && ( - <Icon - style={featuredResult ? fileListStyle.featuredDownloadedIcon : fileListStyle.downloadedIcon} - solid - color={Colors.NextLbryGreen} - name={'folder'} - size={16} - /> - )} - <FilePrice - uri={uri} - style={fileListStyle.filePriceContainer} - iconStyle={fileListStyle.filePriceIcon} - textStyle={fileListStyle.filePriceText} + <View style={style}> + <TouchableOpacity style={style} onPress={onPress || this.defaultOnPress}> + <FileItemMedia + style={fileListStyle.thumbnail} + blurRadius={obscureNsfw ? 15 : 0} + resizeMode="cover" + title={title || name} + thumbnail={thumbnail} /> + {fileInfo && fileInfo.completed && fileInfo.download_path && ( + <Icon style={fileListStyle.downloadedIcon} solid color={Colors.NextLbryGreen} name={'folder'} size={16} /> + )} <View style={fileListStyle.detailsContainer}> {featuredResult && ( <Text style={fileListStyle.featuredUri} numberOfLines={1}> @@ -237,50 +112,30 @@ class FileListItem extends React.PureComponent { {!title && !name && <Text style={fileListStyle.uri}>{uri}</Text>} {!title && !name && ( <View style={fileListStyle.row}> - <ActivityIndicator size={'small'} color={featuredResult ? Colors.White : Colors.NextLbryGreen} /> + <ActivityIndicator size={'small'} color={featuredResult ? Colors.White : Colors.LbryGreen} /> </View> )} </View> )} {(title || name) && ( - <View style={fileListStyle.titleContainer}> - <Text - style={featuredResult ? fileListStyle.featuredTitle : fileListStyle.title} - numberOfLines={actualHideChannel ? 4 : 3} - > - {title || name} - </Text> - {isRewardContent && <Icon style={fileListStyle.rewardIcon} name="award" size={12} />} - </View> + <Text style={featuredResult ? fileListStyle.featuredTitle : fileListStyle.title}> + {this.formatTitle(title) || this.formatTitle(name)} + </Text> )} - - {featuredResult && !isResolving && !claim && ( - <View style={fileListStyle.titleContainer}> - <Text style={fileListStyle.featuredTitle}>{__('Nothing here. Publish something!')}</Text> - </View> - )} - - {(channel || isChannel) && !actualHideChannel && ( + {channel && !hideChannel && ( <Link style={fileListStyle.publisher} - text={isChannel ? name : channel} + text={channel} onPress={() => { - navigateToUri( - navigation, - normalizeURI(isChannel ? uri : shortChannelUri || fullChannelUri), - null, - false, - isChannel ? claim && claim.permanent_url : fullChannelUri, - setPlayerVisible, - ); + navigateToUri(navigation, normalizeURI(fullChannelUri)); }} /> )} <View style={fileListStyle.info}> {fileInfo && !isNaN(fileInfo.written_bytes) && fileInfo.written_bytes > 0 && ( - <Text style={fileListStyle.infoText}>{getStorageForFileInfo(fileInfo)}</Text> + <Text style={fileListStyle.infoText}>{this.getStorageForFileInfo(fileInfo)}</Text> )} <DateTime style={fileListStyle.publishInfo} textStyle={fileListStyle.infoText} timeAgo uri={uri} /> </View> @@ -293,14 +148,16 @@ class FileListItem extends React.PureComponent { color={Colors.NextLbryGreen} height={3} style={fileListStyle.progress} - progress={getDownloadProgress(fileInfo)} + progress={this.getDownloadProgress(fileInfo)} /> )} </View> )} </View> </TouchableOpacity> - {obscure && <NsfwOverlay onPress={() => navigation.navigate({ routeName: 'Settings', key: 'settingsPage' })} />} + {obscureNsfw && ( + <NsfwOverlay onPress={() => navigation.navigate({ routeName: 'Settings', key: 'settingsPage' })} /> + )} </View> ); } diff --git a/src/component/filePrice/view.js b/src/component/filePrice/view.js index c284214..633e2ae 100644 --- a/src/component/filePrice/view.js +++ b/src/component/filePrice/view.js @@ -2,7 +2,6 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Text, View } from 'react-native'; import { formatCredits, formatFullPrice } from 'lbry-redux'; -import Icon from 'react-native-vector-icons/FontAwesome5'; class CreditAmount extends React.PureComponent { static propTypes = { @@ -43,16 +42,11 @@ class CreditAmount extends React.PureComponent { let amountText; if (this.props.showFree && parseFloat(this.props.amount) === 0) { - amountText = __('FREE'); + amountText = 'FREE'; } else { if (this.props.label) { const label = - typeof this.props.label === 'string' - ? this.props.label - : parseFloat(amount) === 1 - ? __('credit') - : __('credits'); - // TODO: handling singular / plural in other languages? + typeof this.props.label === 'string' ? this.props.label : parseFloat(amount) == 1 ? 'credit' : 'credits'; amountText = `${formattedAmount} ${label}`; } else { @@ -63,27 +57,25 @@ class CreditAmount extends React.PureComponent { } } - return ( - <Text style={style} numberOfLines={1}> - {amountText} - </Text> - ); + /*{this.props.isEstimate ? ( + <span + className="credit-amount__estimate" + title={__('This is an estimate and does not include data fees')} + > + * + </span> + ) : null}*/ + return <Text style={style}>{amountText}</Text>; } } class FilePrice extends React.PureComponent { componentWillMount() { - const { cost } = this.props; - if (isNaN(parseFloat(cost))) { - this.fetchCost(this.props); - } + this.fetchCost(this.props); } componentWillReceiveProps(nextProps) { - const { cost } = this.props; - if (isNaN(parseFloat(cost))) { - this.fetchCost(nextProps); - } + this.fetchCost(nextProps); } fetchCost(props) { @@ -95,25 +87,30 @@ class FilePrice extends React.PureComponent { } render() { - const { cost, costInfo, look = 'indicator', showFullPrice = false, style, iconStyle, textStyle } = this.props; + const { costInfo, look = 'indicator', showFullPrice = false, style, textStyle } = this.props; const isEstimate = costInfo ? !costInfo.includesData : null; - const amount = cost ? parseFloat(cost) : costInfo ? parseFloat(costInfo.cost) : 0; - if (isNaN(amount) || amount === 0) { - return null; + + if (!costInfo) { + return ( + <View style={style}> + <Text style={textStyle}>???</Text> + </View> + ); } return ( <View style={style}> - <Icon name="coins" size={9} style={iconStyle} /> <CreditAmount style={textStyle} label={false} - amount={amount} + amount={parseFloat(costInfo.cost)} isEstimate={isEstimate} showFree showFullPrice={showFullPrice} - /> + > + ??? + </CreditAmount> </View> ); } diff --git a/src/component/fileRewardsDriver/view.js b/src/component/fileRewardsDriver/view.js index 209cbf5..5e96a8a 100644 --- a/src/component/fileRewardsDriver/view.js +++ b/src/component/fileRewardsDriver/view.js @@ -9,8 +9,8 @@ class FileRewardsDriver extends React.PureComponent<Props> { return ( <TouchableOpacity style={filePageStyle.rewardDriverCard} onPress={() => navigation.navigate('Rewards')}> - <Icon name="award" size={16} style={filePageStyle.rewardDriverIcon} /> - <Text style={filePageStyle.rewardDriverText}>{__('Earn some credits to access this content.')}</Text> + <Icon name="award" size={16} style={filePageStyle.rewardIcon} /> + <Text style={filePageStyle.rewardDriverText}>Earn some credits to access this content.</Text> </TouchableOpacity> ); } diff --git a/src/component/floatingWalletBalance/index.js b/src/component/floatingWalletBalance/index.js index 29aa00a..cd88305 100644 --- a/src/component/floatingWalletBalance/index.js +++ b/src/component/floatingWalletBalance/index.js @@ -2,7 +2,7 @@ import { connect } from 'react-redux'; import { makeSelectClientSetting } from 'redux/selectors/settings'; import { selectBalance } from 'lbry-redux'; import { selectUnclaimedRewardValue } from 'lbryinc'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api +import Constants from 'constants'; import FloatingWalletBalance from './view'; const select = state => ({ @@ -11,4 +11,7 @@ const select = state => ({ rewardsNotInterested: makeSelectClientSetting(Constants.SETTING_REWARDS_NOT_INTERESTED)(state), }); -export default connect(select, null)(FloatingWalletBalance); +export default connect( + select, + null +)(FloatingWalletBalance); diff --git a/src/component/floatingWalletBalance/view.js b/src/component/floatingWalletBalance/view.js index 705d471..db65790 100644 --- a/src/component/floatingWalletBalance/view.js +++ b/src/component/floatingWalletBalance/view.js @@ -23,7 +23,7 @@ class FloatingWalletBalance extends React.PureComponent<Props> { style={floatingButtonStyle.pendingContainer} onPress={() => navigation && navigation.navigate({ routeName: 'Rewards' })} > - <Icon name="award" size={14} style={floatingButtonStyle.rewardIcon} /> + <Icon name="award" size={18} style={floatingButtonStyle.rewardIcon} /> <Text style={floatingButtonStyle.text}>{unclaimedRewardAmount}</Text> </TouchableOpacity> )} @@ -31,10 +31,9 @@ class FloatingWalletBalance extends React.PureComponent<Props> { style={floatingButtonStyle.container} onPress={() => navigation && navigation.navigate({ routeName: 'WalletStack' })} > - <Icon name="coins" size={12} style={floatingButtonStyle.balanceIcon} /> {isNaN(balance) && <ActivityIndicator size="small" color={Colors.White} />} {(!isNaN(balance) || balance === 0) && ( - <Text style={floatingButtonStyle.text}>{formatCredits(parseFloat(balance), 1, true)}</Text> + <Text style={floatingButtonStyle.text}>{formatCredits(parseFloat(balance), 2) + ' LBC'}</Text> )} </TouchableOpacity> </View> diff --git a/src/component/mediaPlayer/view.js b/src/component/mediaPlayer/view.js index 0d67dfb..ba7b06b 100644 --- a/src/component/mediaPlayer/view.js +++ b/src/component/mediaPlayer/view.js @@ -36,7 +36,7 @@ class MediaPlayer extends React.PureComponent { constructor(props) { super(props); this.state = { - buffering: true, + buffering: false, backgroundPlayEnabled: false, autoPaused: false, rate: 1, @@ -45,9 +45,9 @@ class MediaPlayer extends React.PureComponent { resizeMode: 'contain', duration: 0.0, currentTime: 0.0, - paused: true, + paused: !props.autoPlay, fullscreenMode: false, - areControlsVisible: false, + areControlsVisible: true, controlsTimeout: -1, seekerOffset: 0, seekerPosition: 0, @@ -87,9 +87,7 @@ class MediaPlayer extends React.PureComponent { } onLoad = data => { - const { autoPlay } = this.props; this.setState({ - buffering: false, duration: data.duration, }); @@ -102,17 +100,13 @@ class MediaPlayer extends React.PureComponent { if (this.props.onMediaLoaded) { this.props.onMediaLoaded(); } - - if (autoPlay) { - this.setState({ paused: false }); - } }; onProgress = data => { const { savePosition, claim } = this.props; this.setState({ buffering: false, currentTime: data.currentTime }); - if (claim && data.currentTime > 0 && Math.floor(data.currentTime) % positionSaveInterval === 0) { + if (data.currentTime > 0 && Math.floor(data.currentTime) % positionSaveInterval === 0) { const { claim_id: claimId, txid, nout } = claim; savePosition(claimId, `${txid}:${nout}`, data.currentTime); } @@ -173,7 +167,7 @@ class MediaPlayer extends React.PureComponent { togglePlay = () => { this.showPlayerControls(); - this.setState({ paused: !this.state.paused }, this.updateBackgroundMediaNotification); + this.setState({ paused: !this.state.paused }, this.handlePausedState); }; handlePausedState = () => { @@ -194,7 +188,7 @@ class MediaPlayer extends React.PureComponent { }; onEnd = () => { - this.setState({ paused: true }, this.updateBackgroundMediaNotification); + this.setState({ paused: true }); if (this.props.onPlaybackFinished) { this.props.onPlaybackFinished(); } @@ -333,10 +327,6 @@ class MediaPlayer extends React.PureComponent { } }; - onFocusChanged = evt => { - this.setState({ paused: !(this.state.paused && evt.hasAudioFocus) }, this.updateBackgroundMediaNotification); - }; - onBuffer = () => { if (!this.state.paused) { this.setState({ buffering: true }, () => this.manualHidePlayerControls()); @@ -351,12 +341,6 @@ class MediaPlayer extends React.PureComponent { this.setState({ paused: true }, this.updateBackgroundMediaNotification); }; - handleSeek = time => { - const { currentTime } = this.state; - const newTime = currentTime + time; - this.seekTo(newTime); - }; - updateBackgroundMediaNotification = () => { this.handlePausedState(); const { backgroundPlayEnabled } = this.props; @@ -378,26 +362,14 @@ class MediaPlayer extends React.PureComponent { <Icon name={'arrow-left'} size={18} style={mediaPlayerStyle.backButtonIcon} /> </TouchableOpacity> - <View style={mediaPlayerStyle.midControls}> - <TouchableOpacity style={mediaPlayerStyle.rewind10} onPress={() => this.handleSeek(-10)}> - <Icon name="undo" size={24} color={Colors.White} /> - <Text style={[mediaPlayerStyle.midControlText, mediaPlayerStyle.leftMidControlText]}>10</Text> - </TouchableOpacity> - - <TouchableOpacity style={mediaPlayerStyle.playPauseButton} onPress={this.togglePlay}> - {this.state.paused && <Icon name="play" size={40} color={Colors.White} />} - {!this.state.paused && <Icon name="pause" size={40} color={Colors.White} />} - </TouchableOpacity> - - <TouchableOpacity style={mediaPlayerStyle.forward10} onPress={() => this.handleSeek(10)}> - <Icon name="redo" size={24} color={Colors.White} /> - <Text style={[mediaPlayerStyle.midControlText, mediaPlayerStyle.rightMidControlText]}>10</Text> - </TouchableOpacity> - </View> + <TouchableOpacity style={mediaPlayerStyle.playPauseButton} onPress={this.togglePlay}> + {this.state.paused && <Icon name="play" size={40} color="#ffffff" />} + {!this.state.paused && <Icon name="pause" size={40} color="#ffffff" />} + </TouchableOpacity> <TouchableOpacity style={mediaPlayerStyle.toggleFullscreenButton} onPress={this.toggleFullscreenMode}> - {this.state.fullscreenMode && <Icon name="compress" size={16} color={Colors.White} />} - {!this.state.fullscreenMode && <Icon name="expand" size={16} color={Colors.White} />} + {this.state.fullscreenMode && <Icon name="compress" size={16} color="#ffffff" />} + {!this.state.fullscreenMode && <Icon name="expand" size={16} color="#ffffff" />} </TouchableOpacity> <Text style={mediaPlayerStyle.elapsedDuration}>{this.formatTime(this.state.currentTime)}</Text> @@ -446,13 +418,6 @@ class MediaPlayer extends React.PureComponent { : mediaPlayerStyle.containedTrackingControls, ]; - const seekerCircleStyle = [this.state.seeking ? mediaPlayerStyle.bigSeekerCircle : mediaPlayerStyle.seekerCircle]; - if (!this.state.seeking) { - seekerCircleStyle.push( - this.state.fullscreenMode ? mediaPlayerStyle.seekerCircleTopFs : mediaPlayerStyle.seekerCircleTop, - ); - } - return ( <View style={styles} onLayout={onLayout}> <Video @@ -468,7 +433,6 @@ class MediaPlayer extends React.PureComponent { }} resizeMode={this.state.resizeMode} playInBackground={this.state.backgroundPlayEnabled} - playWhenInactive={this.state.backgroundPlayEnabled} style={mediaPlayerStyle.player} rate={this.state.rate} volume={this.state.volume} @@ -479,7 +443,6 @@ class MediaPlayer extends React.PureComponent { onEnd={this.onEnd} onError={this.onError} minLoadRetryCount={999} - onAudioFocusChanged={this.onFocusChanged} /> {this.state.firstPlay && thumbnail && ( @@ -519,7 +482,7 @@ class MediaPlayer extends React.PureComponent { ]} {...this.seekResponder.panHandlers} > - <View style={seekerCircleStyle} /> + <View style={this.state.seeking ? mediaPlayerStyle.bigSeekerCircle : mediaPlayerStyle.seekerCircle} /> </View> <TouchableOpacity style={[ diff --git a/src/component/modalPicker/view.js b/src/component/modalPicker/view.js index 64bb490..b548f1a 100644 --- a/src/component/modalPicker/view.js +++ b/src/component/modalPicker/view.js @@ -46,7 +46,7 @@ export default class ModalPicker extends React.PureComponent { onPress={() => onItemSelected(item)} > {item.icon && <Icon style={modalPickerStyle.itemIcon} name={item.icon} size={16} />} - <Text style={modalPickerStyle.itemLabel}>{__(item.label)}</Text> + <Text style={modalPickerStyle.itemLabel}>{item.label}</Text> {selectedItem && selectedItem.name === item.name && ( <Icon style={modalPickerStyle.itemSelected} name={'check'} color={Colors.LbryGreen} size={16} /> )} diff --git a/src/component/modalRepostView/index.js b/src/component/modalRepostView/index.js deleted file mode 100644 index 12b1a45..0000000 --- a/src/component/modalRepostView/index.js +++ /dev/null @@ -1,28 +0,0 @@ -import { connect } from 'react-redux'; -import { - doClearRepostError, - doFetchChannelListMine, - doRepost, - doToast, - selectBalance, - selectMyChannelClaims, - selectRepostError, - selectRepostLoading, -} from 'lbry-redux'; -import ModalRepostView from './view'; - -const select = state => ({ - balance: selectBalance(state), - channels: selectMyChannelClaims(state), - reposting: selectRepostLoading(state), - error: selectRepostError(state), -}); - -const perform = dispatch => ({ - fetchChannelListMine: () => dispatch(doFetchChannelListMine(1, 99999, true)), - notify: data => dispatch(doToast(data)), - repost: options => dispatch(doRepost(options)), - clearError: () => dispatch(doClearRepostError()), -}); - -export default connect(select, perform)(ModalRepostView); diff --git a/src/component/modalRepostView/view.js b/src/component/modalRepostView/view.js deleted file mode 100644 index b10bb96..0000000 --- a/src/component/modalRepostView/view.js +++ /dev/null @@ -1,204 +0,0 @@ -import React from 'react'; -import { ActivityIndicator, Alert, Text, TextInput, TouchableOpacity, View } from 'react-native'; -import { formatCredits, creditsToString } from 'lbry-redux'; -import modalStyle from 'styles/modal'; -import modalRepostStyle from 'styles/modalRepost'; -import ChannelSelector from 'component/channelSelector'; -import Button from 'component/button'; -import Colors from 'styles/colors'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api -import Icon from 'react-native-vector-icons/FontAwesome5'; -import Link from 'component/link'; -import { logPublish } from 'utils/helper'; - -export default class ModalRepostView extends React.PureComponent { - depositAmountInput; - - state = { - channelName: null, - creditsInputFocused: false, - depositAmount: '0.01', - repostName: null, - repostStarted: false, - showAdvanced: false, - }; - - componentDidMount() { - const { claim, fetchChannelListMine } = this.props; - const { name } = claim; - fetchChannelListMine(); - this.setState({ repostName: name }); - this.checkChannelSelection(this.props); - } - - componentWillReceiveProps(nextProps) { - this.checkChannelSelection(nextProps); - const { notify } = this.props; - const { reposting, error } = nextProps; - if (this.state.repostStarted && !reposting && error) { - this.setState({ repostStarted: false }); - notify({ message: error, isError: true }); - } - } - - checkChannelSelection = props => { - const { channels = [] } = props; - if (!this.state.channelName && channels && channels.length > 0) { - const firstChannel = channels[0]; - this.setState({ channelName: firstChannel.name }); - } - }; - - handleChannelChange = channelName => { - const { channels = [] } = this.props; - if (channels && channels.length > 0) { - const filtered = channels.filter(c => c.name === channelName); - if (filtered.length > 0) { - const channel = filtered[0]; - this.setState({ channelName }); - } - } - }; - - handleRepost = () => { - const { claim, balance, notify, repost, onRepostSuccessful, channels = [], clearError } = this.props; - const { depositAmount, repostName, channelName } = this.state; - - if (parseInt(depositAmount, 10) > balance) { - notify({ - message: 'Insufficient credits', - isError: true, - }); - return; - } - - clearError(); - const channel = channels.filter(ch => ch.name === channelName)[0]; - this.setState({ repostStarted: true }, () => { - repost({ - name: repostName, - bid: creditsToString(depositAmount), - channel_id: channel.claim_id, - claim_id: claim.claim_id, - }).then(repostClaim => { - logPublish(repostClaim); - this.setState({ repostStarted: false }); - notify({ message: __('The content was successfully reposted!') }); - if (onRepostSuccessful) onRepostSuccessful(); - }); - }); - }; - - render() { - const { balance, channels, reposting, title, onCancelPress, onOverlayPress } = this.props; - const canRepost = !!this.state.channelName && !!this.state.repostName; - const channelsLoaded = channels && channels.length > 0; - const processing = this.state.repostStarted || reposting || !channelsLoaded; - - return ( - <TouchableOpacity style={modalStyle.overlay} activeOpacity={1} onPress={onOverlayPress}> - <TouchableOpacity style={modalStyle.container} activeOpacity={1}> - <View - style={modalRepostStyle.container} - onLayout={() => { - if (this.tipAmountInput) { - this.tipAmountInput.focus(); - } - }} - > - <Text style={modalRepostStyle.title} numberOfLines={1}> - {__('Repost %title%', { title })} - </Text> - <Text style={modalRepostStyle.infoText}> - {__('Repost your favorite content to help more people discover them!')} - </Text> - - <Text style={modalRepostStyle.label}>{__('Channel to post on')}</Text> - <ChannelSelector - showAnonymous={false} - channelName={this.state.channelName} - onChannelChange={this.handleChannelChange} - /> - - {this.state.showAdvanced && ( - <View> - <Text style={modalRepostStyle.label}>{__('Name')}</Text> - <View style={modalRepostStyle.nameRow}> - <TextInput - editable={false} - value={this.state.channelName ? `lbry://${this.state.channelName}/` : ''} - style={modalRepostStyle.input} - /> - <TextInput - editable={canRepost} - value={this.state.repostName} - underlineColorAndroid={Colors.NextLbryGreen} - selectTextOnFocus - onChangeText={value => this.setState({ repostName: value })} - style={modalRepostStyle.input} - /> - </View> - - <Text style={modalRepostStyle.label}>{__('Deposit')}</Text> - <View style={modalRepostStyle.row}> - <View style={modalRepostStyle.amountRow}> - <TextInput - editable={!this.state.repostStarted} - ref={ref => (this.depositAmountInput = ref)} - onChangeText={value => this.setState({ tipAmount: value })} - underlineColorAndroid={Colors.NextLbryGreen} - keyboardType={'numeric'} - onFocus={() => this.setState({ creditsInputFocused: true })} - onBlur={() => this.setState({ creditsInputFocused: false })} - placeholder={'0'} - value={this.state.depositAmount} - selectTextOnFocus - style={modalRepostStyle.depositAmountInput} - /> - <Text style={modalRepostStyle.currency}>LBC</Text> - <View style={modalRepostStyle.balance}> - {this.state.creditsInputFocused && <Icon name="coins" size={12} />} - {this.state.creditsInputFocused && ( - <Text style={modalRepostStyle.balanceText}>{formatCredits(parseFloat(balance), 1, true)}</Text> - )} - </View> - </View> - </View> - </View> - )} - - <View style={modalRepostStyle.buttonRow}> - {!processing && ( - <Link - style={modalRepostStyle.cancelLink} - text={__('Cancel')} - onPress={() => { - if (onCancelPress) onCancelPress(); - }} - /> - )} - - {processing && <ActivityIndicator size={'small'} color={Colors.NextLbryGreen} />} - - <View style={modalRepostStyle.rightButtonRow}> - <Link - style={modalRepostStyle.advancedLink} - text={this.state.showAdvanced ? __('Hide advanced') : __('Show advanced')} - onPress={() => { - this.setState({ showAdvanced: !this.state.showAdvanced }); - }} - /> - <Button - text={__('Repost')} - style={modalRepostStyle.button} - disabled={!canRepost || this.state.repostStarted || reposting} - onPress={this.handleRepost} - /> - </View> - </View> - </View> - </TouchableOpacity> - </TouchableOpacity> - ); - } -} diff --git a/src/component/modalSuggestedSubscriptions/index.js b/src/component/modalSuggestedSubscriptions/index.js deleted file mode 100644 index 72f9c24..0000000 --- a/src/component/modalSuggestedSubscriptions/index.js +++ /dev/null @@ -1,9 +0,0 @@ -import { connect } from 'react-redux'; -import { selectFetchingClaimSearch } from 'lbry-redux'; -import ModalSuggestedSubscriptions from './view'; - -const select = state => ({ - loadingSuggested: selectFetchingClaimSearch(state), -}); - -export default connect(select)(ModalSuggestedSubscriptions); diff --git a/src/component/modalSuggestedSubscriptions/view.js b/src/component/modalSuggestedSubscriptions/view.js deleted file mode 100644 index 96f773e..0000000 --- a/src/component/modalSuggestedSubscriptions/view.js +++ /dev/null @@ -1,29 +0,0 @@ -import React from 'react'; -import { ActivityIndicator, ScrollView, Text, TouchableOpacity, View } from 'react-native'; -import modalStyle from 'styles/modal'; -import subscriptionsStyle from 'styles/subscriptions'; -import Button from 'component/button'; -import Colors from 'styles/colors'; -import SuggestedSubscriptionsGrid from 'component/suggestedSubscriptionsGrid'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api -import Icon from 'react-native-vector-icons/FontAwesome5'; - -export default class ModalSuggestedSubcriptions extends React.PureComponent { - render() { - const { loadingSuggested, navigation, onDonePress, onOverlayPress } = this.props; - - return ( - <TouchableOpacity style={modalStyle.overlay} activeOpacity={1} onPress={onOverlayPress}> - <TouchableOpacity style={[modalStyle.container, subscriptionsStyle.modalContainer]} activeOpacity={1}> - <SuggestedSubscriptionsGrid inModal navigation={navigation} /> - <View style={modalStyle.wideButtons}> - <Button style={modalStyle.wideDoneButton} text={__('Done')} onPress={onDonePress} /> - {loadingSuggested && ( - <ActivityIndicator size="small" color={Colors.White} style={subscriptionsStyle.modalLoading} /> - )} - </View> - </TouchableOpacity> - </TouchableOpacity> - ); - } -} diff --git a/src/component/modalTagSelector/view.js b/src/component/modalTagSelector/view.js index 6e688cc..f0572b2 100644 --- a/src/component/modalTagSelector/view.js +++ b/src/component/modalTagSelector/view.js @@ -8,8 +8,7 @@ import Icon from 'react-native-vector-icons/FontAwesome5'; import Tag from 'component/tag'; import TagSearch from 'component/tagSearch'; import modalTagSelectorStyle from 'styles/modalTagSelector'; - -const minimumTags = 2; +import { __ } from 'utils/helper'; export default class ModalTagSelector extends React.PureComponent { handleAddTag = tag => { @@ -24,9 +23,6 @@ export default class ModalTagSelector extends React.PureComponent { } this.props.doToggleTagFollow(tag); - if (window.persistor) { - window.persistor.flush(); - } NativeModules.Firebase.track('tag_follow', { tag }); }; @@ -35,16 +31,7 @@ export default class ModalTagSelector extends React.PureComponent { return; } - const { followedTags, doToast } = this.props; - if (followedTags.length <= minimumTags) { - doToast({ message: __(`You can follow a minimum of ${minimumTags} tags.`) }); - return; - } - this.props.doToggleTagFollow(tag); - if (window.persistor) { - window.persistor.flush(); - } NativeModules.Firebase.track('tag_unfollow', { tag }); }; @@ -54,9 +41,9 @@ export default class ModalTagSelector extends React.PureComponent { return ( <TouchableOpacity style={modalTagSelectorStyle.overlay} activeOpacity={1} onPress={onOverlayPress}> - <TouchableOpacity style={modalTagSelectorStyle.container} activeOpacity={1}> + <View style={modalTagSelectorStyle.container}> <View style={modalTagSelectorStyle.titleRow}> - <Text style={modalTagSelectorStyle.title}>{__('Customize your tags')}</Text> + <Text style={modalTagSelectorStyle.title}>Customize your tags</Text> </View> <View style={modalTagSelectorStyle.tagList}> {tags && @@ -72,9 +59,9 @@ export default class ModalTagSelector extends React.PureComponent { </View> <TagSearch handleAddTag={this.handleAddTag} selectedTags={tags} /> <View style={modalTagSelectorStyle.buttons}> - <Button style={modalTagSelectorStyle.doneButton} text={__('Done')} onPress={onDonePress} /> + <Button style={modalTagSelectorStyle.doneButton} text={'Done'} onPress={onDonePress} /> </View> - </TouchableOpacity> + </View> </TouchableOpacity> ); } diff --git a/src/component/modalTipView/index.js b/src/component/modalTipView/index.js deleted file mode 100644 index 743c259..0000000 --- a/src/component/modalTipView/index.js +++ /dev/null @@ -1,17 +0,0 @@ -import { connect } from 'react-redux'; -import { doSendTip, doToast, selectBalance } from 'lbry-redux'; -import { selectSdkReady } from 'redux/selectors/settings'; -import ModalTipView from './view'; - -const select = state => ({ - balance: selectBalance(state), - sdkReady: selectSdkReady(state), -}); - -const perform = dispatch => ({ - notify: data => dispatch(doToast(data)), - sendTip: (amount, claimId, isSupport, successCallback, errorCallback) => - dispatch(doSendTip(amount, claimId, isSupport, successCallback, errorCallback)), -}); - -export default connect(select, perform)(ModalTipView); diff --git a/src/component/modalTipView/view.js b/src/component/modalTipView/view.js deleted file mode 100644 index 3fcdd6f..0000000 --- a/src/component/modalTipView/view.js +++ /dev/null @@ -1,157 +0,0 @@ -import React from 'react'; -import { ActivityIndicator, Alert, Text, TextInput, TouchableOpacity, View } from 'react-native'; -import { formatCredits } from 'lbry-redux'; -import modalStyle from 'styles/modal'; -import modalTipStyle from 'styles/modalTip'; -import Button from 'component/button'; -import Colors from 'styles/colors'; -import Icon from 'react-native-vector-icons/FontAwesome5'; -import Link from 'component/link'; - -export default class ModalTipView extends React.PureComponent { - tipAmountInput = null; - - state = { - creditsInputFocused: false, - sendTipStarted: false, - tipAmount: null, - }; - - handleSendTip = () => { - const { claim, balance, notify, onSendTipFailed, onSendTipSuccessful, sdkReady, sendTip } = this.props; - const { tipAmount } = this.state; - - if (!sdkReady) { - notify({ - message: __( - 'The background service is still initializing. You can still explore and watch content during the initialization process.', - ), - }); - return; - } - - if (tipAmount > balance) { - notify({ - message: 'Insufficient credits', - isError: true, - }); - return; - } - - const amount = parseInt(tipAmount, 10); - const message = - amount === 1 - ? __('Please confirm you want to tip %amount% credit', { amount }) - : __('Please confirm you want to tip %amount% credits', { amount }); - - Alert.alert( - __('Send Tip'), - message, - [ - { text: __('No') }, - { - text: __('Yes'), - onPress: () => { - this.setState({ sendTipStarted: true }, () => - sendTip( - tipAmount, - claim.claim_id, - false, - () => { - // success - this.setState({ tipAmount: null, sendTipStarted: false }); - if (onSendTipSuccessful) onSendTipSuccessful(); - }, - () => { - // error - if (onSendTipFailed) onSendTipFailed(); - }, - ), - ); - }, - }, - ], - { cancelable: true }, - ); - }; - - render() { - const { balance, channelName, contentName, onCancelPress, onOverlayPress } = this.props; - const canSendTip = this.state.tipAmount > 0; - - return ( - <TouchableOpacity style={modalStyle.overlay} activeOpacity={1} onPress={onOverlayPress}> - <TouchableOpacity style={modalStyle.container} activeOpacity={1}> - <View - style={modalTipStyle.container} - onLayout={() => { - if (this.tipAmountInput) { - this.tipAmountInput.focus(); - } - }} - > - <Text style={modalTipStyle.title} numberOfLines={1}> - {channelName ? __('Send a tip to %channel%', { channel: channelName }) : __('Send a tip')} - </Text> - - <View style={modalTipStyle.row}> - <View style={modalTipStyle.amountRow}> - <TextInput - editable={!this.state.sendTipStarted} - ref={ref => (this.tipAmountInput = ref)} - onChangeText={value => this.setState({ tipAmount: value })} - underlineColorAndroid={Colors.NextLbryGreen} - keyboardType={'numeric'} - onFocus={() => this.setState({ creditsInputFocused: true })} - onBlur={() => this.setState({ creditsInputFocused: false })} - placeholder={'0'} - value={this.state.tipAmount} - selectTextOnFocus - style={modalTipStyle.tipAmountInput} - /> - <Text style={modalTipStyle.currency}>LBC</Text> - <View style={modalTipStyle.balance}> - {this.state.creditsInputFocused && <Icon name="coins" size={12} />} - {this.state.creditsInputFocused && ( - <Text style={modalTipStyle.balanceText}>{formatCredits(parseFloat(balance), 1, true)}</Text> - )} - </View> - </View> - {this.state.sendTipStarted && <ActivityIndicator size={'small'} color={Colors.NextLbryGreen} />} - </View> - - <View style={modalTipStyle.info}> - <Text style={modalTipStyle.infoText}> - {__( - 'This will appear as a tip for %content%, which will boost its ability to be discovered while active.', - { content: contentName }, - )}{' '} - <Link - style={modalTipStyle.learnMoreLink} - text={__('Learn more.')} - href={'https://lbry.com/faq/tipping'} - /> - </Text> - </View> - - <View style={modalTipStyle.buttonRow}> - <Link - style={modalTipStyle.cancelTipLink} - text={__('Cancel')} - onPress={() => { - if (onCancelPress) onCancelPress(); - }} - /> - <Button - text={__('Send')} - style={modalTipStyle.button} - disabled={!canSendTip || this.state.sendTipStarted} - onPress={this.handleSendTip} - /> - </View> - </View> - </TouchableOpacity> - </TouchableOpacity> - ); - } -} diff --git a/src/component/nsfwOverlay/view.js b/src/component/nsfwOverlay/view.js index 64dffcc..39a1826 100644 --- a/src/component/nsfwOverlay/view.js +++ b/src/component/nsfwOverlay/view.js @@ -5,9 +5,9 @@ import discoverStyle from '../../styles/discover'; class NsfwOverlay extends React.PureComponent { render() { return ( - <TouchableOpacity style={discoverStyle.overlay} activeOpacity={1} onPress={this.props.onPress}> + <TouchableOpacity style={discoverStyle.overlay} activeOpacity={0.95} onPress={this.props.onPress}> <Text style={discoverStyle.overlayText}> - {__('This content is Not Safe For Work. To view adult content, please change your Settings.')} + This content is Not Safe For Work. To view adult content, please change your Settings. </Text> </TouchableOpacity> ); diff --git a/src/component/publishRewardsDriver/view.js b/src/component/publishRewardsDriver/view.js index effa214..33c9192 100644 --- a/src/component/publishRewardsDriver/view.js +++ b/src/component/publishRewardsDriver/view.js @@ -4,21 +4,17 @@ import Colors from 'styles/colors'; import Icon from 'react-native-vector-icons/FontAwesome5'; import publishStyle from 'styles/publish'; -class PublishRewardsDriver extends React.PureComponent<Props> { +class PublishRewadsDriver extends React.PureComponent<Props> { render() { const { navigation } = this.props; return ( <TouchableOpacity style={publishStyle.rewardDriverCard} onPress={() => navigation.navigate('Rewards')}> <Icon name="award" size={16} style={publishStyle.rewardIcon} /> - <Text style={publishStyle.rewardDriverText}> - {__('Publishing requires credits.')} - {'\n'} - {__('Tap here to get some for free.')} - </Text> + <Text style={publishStyle.rewardDriverText}>Earn some credits to be able to publish your content.</Text> </TouchableOpacity> ); } } -export default PublishRewardsDriver; +export default PublishRewadsDriver; diff --git a/src/component/relatedContent/index.js b/src/component/relatedContent/index.js index f2fd0ac..3d75163 100644 --- a/src/component/relatedContent/index.js +++ b/src/component/relatedContent/index.js @@ -1,35 +1,25 @@ import { connect } from 'react-redux'; import { - doResolveUris, - doResolvedSearch, makeSelectClaimForUri, - makeSelectResolvedRecommendedContentForUri, - selectResolvingUris, + makeSelectRecommendedContentForUri, + makeSelectTitleForUri, selectIsSearching, } from 'lbry-redux'; -import { selectShowNsfw } from 'redux/selectors/settings'; +import { doNativeSearch } from 'redux/actions/performance'; import RelatedContent from './view'; -const RESULT_SIZE = 16; - const select = (state, props) => ({ claim: makeSelectClaimForUri(props.uri)(state), + recommendedContent: makeSelectRecommendedContentForUri(props.uri)(state), + title: makeSelectTitleForUri(props.uri)(state), isSearching: selectIsSearching(state), - recommendedContent: makeSelectResolvedRecommendedContentForUri( - props.uri, - RESULT_SIZE, - props.claimId, - props.claimName, - props.title, - )(state), - resolvingUris: selectResolvingUris(state), - showNsfwContent: selectShowNsfw(state), }); const perform = dispatch => ({ - resolveUris: uris => dispatch(doResolveUris(uris)), - searchRecommended: (query, claimId, nsfw) => - dispatch(doResolvedSearch(query, RESULT_SIZE, undefined, true, { related_to: claimId }, nsfw)), + search: query => dispatch(doNativeSearch(query, 20, undefined, true)), }); -export default connect(select, perform)(RelatedContent); +export default connect( + select, + perform +)(RelatedContent); diff --git a/src/component/relatedContent/view.js b/src/component/relatedContent/view.js index 1b20f9c..39a0d25 100644 --- a/src/component/relatedContent/view.js +++ b/src/component/relatedContent/view.js @@ -1,45 +1,68 @@ import React from 'react'; import { ActivityIndicator, FlatList, Text, View } from 'react-native'; -import { normalizeURI } from 'lbry-redux'; import { navigateToUri } from 'utils/helper'; import Colors from 'styles/colors'; import FileListItem from 'component/fileListItem'; -import ClaimResultItem from 'component/claimResultItem'; import fileListStyle from 'styles/fileList'; import relatedContentStyle from 'styles/relatedContent'; export default class RelatedContent extends React.PureComponent { + constructor() { + super(); + + this.didSearch = undefined; + } + componentDidMount() { - const { title, claimId, searchRecommended, showNsfwContent } = this.props; - if (title && claimId) { - searchRecommended(title, claimId, showNsfwContent); + this.getRecommendedContent(); + } + + componentDidUpdate(prevProps) { + const { claim, uri } = this.props; + + if (uri !== prevProps.uri) { + this.didSearch = false; + } + + if (claim && !this.didSearch) { + this.getRecommendedContent(); } } - shouldComponentUpdate(nextProps, nextState) { - const { isSearching, recommendedContent } = nextProps; - return isSearching || (!isSearching && recommendedContent && recommendedContent.length > 0); + getRecommendedContent() { + const { search, title } = this.props; + + if (title) { + search(title); + this.didSearch = true; + } } + didSearch; + render() { - const { isSearching, recommendedContent, navigation, urlOpenHandler, uri, fullUri } = this.props; + const { recommendedContent, isSearching, navigation } = this.props; + + if (!isSearching && (!recommendedContent || recommendedContent.length === 0)) { + return null; + } return ( <View style={relatedContentStyle.container}> - <Text style={relatedContentStyle.title}>{__('Related Content')}</Text> - {isSearching && <ActivityIndicator size={'small'} color={Colors.NextLbryGreen} />} + <Text style={relatedContentStyle.title}>Related Content</Text> {recommendedContent && - recommendedContent.map(result => ( - <ClaimResultItem + recommendedContent.map(recommendedUri => ( + <FileListItem style={fileListStyle.item} - uri={result ? normalizeURI(`${result.name}#${result.claimId}`) : null} - urlOpenHandler={urlOpenHandler} - key={result.claimId} - result={result} + key={recommendedUri} + uri={recommendedUri} navigation={navigation} - autoplay + onPress={() => navigateToUri(navigation, recommendedUri, { autoplay: true })} /> ))} + {isSearching && ( + <ActivityIndicator size="small" color={Colors.NextLbryGreen} style={relatedContentStyle.loading} /> + )} </View> ); } diff --git a/src/component/rewardCard/view.js b/src/component/rewardCard/view.js index eab3b70..0e35ab5 100644 --- a/src/component/rewardCard/view.js +++ b/src/component/rewardCard/view.js @@ -1,11 +1,10 @@ // @flow import React from 'react'; import { ActivityIndicator, Text, TouchableOpacity, View } from 'react-native'; -import { formatUsd } from 'utils/helper'; -import Colors from 'styles/colors'; +import Colors from '../../styles/colors'; import Icon from 'react-native-vector-icons/FontAwesome5'; -import Link from 'component/link'; -import rewardStyle from 'styles/reward'; +import Link from '../link'; +import rewardStyle from '../../styles/reward'; type Props = { canClaim: boolean, @@ -14,7 +13,6 @@ type Props = { id: string, reward_title: string, reward_amount: number, - reward_range?: string, transaction_id: string, created_at: string, reward_description: string, @@ -35,7 +33,7 @@ class RewardCard extends React.PureComponent<Props> { notify({ message: errorMessage }); clearError(reward); } else { - notify({ message: __('Reward successfully claimed!') }); + notify({ message: 'Reward successfully claimed!' }); } this.setState({ claimStarted: false }); } @@ -48,7 +46,7 @@ class RewardCard extends React.PureComponent<Props> { if (showVerification) { showVerification(); } - notify({ message: __('Unfortunately, you are not eligible to claim this reward at this time.') }); + notify({ message: 'Unfortunately, you are not eligible to claim this reward at this time.' }); return; } @@ -57,23 +55,8 @@ class RewardCard extends React.PureComponent<Props> { }); }; - getDisplayAmount = () => { - const { reward } = this.props; - if (reward) { - const claimed = !!reward.transaction_id; - if (!claimed && reward.reward_range && reward.reward_range.includes('-')) { - return reward.reward_range.split('-')[1]; - } else if (reward.reward_amount > 0) { - return reward.reward_amount; - } - } - - // unknown amount which normally shouldn't happen - return '?'; - }; - render() { - const { canClaim, isPending, onClaimPress, reward, usdExchangeRate } = this.props; + const { canClaim, isPending, onClaimPress, reward } = this.props; const claimed = !!reward.transaction_id; return ( @@ -113,21 +96,13 @@ class RewardCard extends React.PureComponent<Props> { style={rewardStyle.link} href={`https://explorer.lbry.com/tx/${reward.transaction_id}`} text={reward.transaction_id.substring(0, 7)} - error={__('The transaction URL could not be opened')} + error={'The transaction URL could not be opened'} /> )} </View> <View style={rewardStyle.rightCol}> - {reward.reward_range && reward.reward_range.indexOf('-') > -1 && ( - <Text style={rewardStyle.rightColHeader}>{__('up to')}</Text> - )} - <Text style={rewardStyle.rewardAmount}>{this.getDisplayAmount()}</Text> + <Text style={rewardStyle.rewardAmount}>{reward.reward_amount}</Text> <Text style={rewardStyle.rewardCurrency}>LBC</Text> - {usdExchangeRate > 0 && ( - <Text style={rewardStyle.rewardUsd}> - ≈{formatUsd(parseFloat(this.getDisplayAmount()) * parseFloat(usdExchangeRate))} - </Text> - )} </View> </TouchableOpacity> ); diff --git a/src/component/rewardEnrolment/view.js b/src/component/rewardEnrolment/view.js index ff5a9f6..16552c8 100644 --- a/src/component/rewardEnrolment/view.js +++ b/src/component/rewardEnrolment/view.js @@ -1,13 +1,12 @@ import React from 'react'; -import { Linking, NativeModules, Text, TouchableOpacity, View } from 'react-native'; +import { NativeModules, Text, TouchableOpacity, View } from 'react-native'; import AsyncStorage from '@react-native-community/async-storage'; import Button from 'component/button'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api +import Constants from 'constants'; import Link from 'component/link'; import Colors from 'styles/colors'; import Icon from 'react-native-vector-icons/FontAwesome5'; import rewardStyle from 'styles/reward'; -import { formatUsd } from '../../utils/helper'; class RewardEnrolment extends React.Component { componentDidMount() { @@ -25,47 +24,26 @@ class RewardEnrolment extends React.Component { navigation.navigate({ routeName: 'Verification', key: 'verification', params: { syncFlow: false } }); }; - onLearnMorePressed = () => { - Linking.openURL('https://lbry.com/faq/earn-credits'); - }; - render() { - const { unclaimedRewardAmount, usdExchangeRate } = this.props; + const { fetching, navigation, unclaimedRewardAmount, user } = this.props; return ( - <View style={rewardStyle.enrollContainer}> + <View style={rewardStyle.enrollContainer} onPress> <View style={rewardStyle.summaryRow}> <Icon name="award" size={36} color={Colors.White} /> - <Text style={rewardStyle.summaryText}> - {unclaimedRewardAmount === 1 && __('%amount% available credit', { amount: unclaimedRewardAmount })} - {unclaimedRewardAmount !== 1 && __('%amount% available credits', { amount: unclaimedRewardAmount })} - </Text> + <Text style={rewardStyle.summaryText}>{unclaimedRewardAmount} unclaimed credits</Text> </View> <View style={rewardStyle.onboarding}> <Text style={rewardStyle.enrollDescText}> - {__('LBRY credits allow you to publish or purchase content.')} - {'\n\n'} - {__('You can obtain free credits worth %amount% after you provide an email address.', { - amount: formatUsd(parseFloat(unclaimedRewardAmount) * parseFloat(usdExchangeRate)), - })} - {'\n\n'} - <Link style={rewardStyle.learnMoreLink} text={__('Learn more')} onPress={this.onLearnMorePressed} />. + LBRY credits allow you to purchase content, publish content, and influence the network. You can start + earning credits by watching videos on LBRY. </Text> </View> <View style={rewardStyle.buttonRow}> - <Link - style={rewardStyle.notInterestedLink} - text={__('Not interested')} - onPress={this.onNotInterestedPressed} - /> - <Button - style={rewardStyle.enrollButton} - theme={'light'} - text={__('Get started')} - onPress={this.onEnrollPressed} - /> + <Link style={rewardStyle.notInterestedLink} text={'Not interested'} onPress={this.onNotInterestedPressed} /> + <Button style={rewardStyle.enrollButton} theme={'light'} text={'Enroll'} onPress={this.onEnrollPressed} /> </View> </View> ); diff --git a/src/component/rewardSummary/index.js b/src/component/rewardSummary/index.js new file mode 100644 index 0000000..a7de155 --- /dev/null +++ b/src/component/rewardSummary/index.js @@ -0,0 +1,20 @@ +import { connect } from 'react-redux'; +import { doToast } from 'lbry-redux'; +import { doRewardList, selectUnclaimedRewardValue, selectFetchingRewards, selectUser } from 'lbryinc'; +import RewardSummary from './view'; + +const select = state => ({ + unclaimedRewardAmount: selectUnclaimedRewardValue(state), + fetching: selectFetchingRewards(state), + user: selectUser(state), +}); + +const perform = dispatch => ({ + fetchRewards: () => dispatch(doRewardList()), + notify: data => dispatch(doToast(data)), +}); + +export default connect( + select, + perform +)(RewardSummary); diff --git a/src/component/rewardSummary/view.js b/src/component/rewardSummary/view.js new file mode 100644 index 0000000..6d27948 --- /dev/null +++ b/src/component/rewardSummary/view.js @@ -0,0 +1,82 @@ +import React from 'react'; +import { NativeModules, Text, TouchableOpacity, View } from 'react-native'; +import AsyncStorage from '@react-native-community/async-storage'; +import Button from 'component/button'; +import Colors from 'styles/colors'; +import Icon from 'react-native-vector-icons/FontAwesome5'; +import rewardStyle from 'styles/reward'; + +class RewardSummary extends React.Component { + static itemKey = 'rewardSummaryDismissed'; + + state = { + actionsLeft: 0, + dismissed: false, + }; + + componentDidMount() { + this.props.fetchRewards(); + + AsyncStorage.getItem(RewardSummary.itemKey).then(isDismissed => { + if ('true' === isDismissed) { + this.setState({ dismissed: true }); + } + + const { user } = this.props; + let actionsLeft = 0; + if (!user || !user.has_verified_email) { + actionsLeft++; + } + + if (!user || !user.is_identity_verified) { + actionsLeft++; + } + + this.setState({ actionsLeft }); + }); + } + + onDismissPressed = () => { + AsyncStorage.setItem(RewardSummary.itemKey, 'true'); + this.setState({ dismissed: true }); + this.props.notify({ + message: 'You can always claim your rewards from the Rewards page.', + }); + }; + + handleSummaryPressed = () => { + const { showVerification } = this.props; + if (showVerification) { + showVerification(); + } + }; + + render() { + const { fetching, navigation, unclaimedRewardAmount, user } = this.props; + + if (!user) { + return null; + } + + if ( + this.state.dismissed || + (user && user.is_reward_approved) || + this.state.actionsLeft === 0 || + unclaimedRewardAmount === 0 + ) { + return null; + } + + return ( + <TouchableOpacity style={rewardStyle.summaryContainer} onPress={this.handleSummaryPressed}> + <View style={rewardStyle.summaryRow}> + <Icon name="award" size={36} color={Colors.White} /> + <Text style={rewardStyle.summaryText}>{unclaimedRewardAmount} unclaimed credits</Text> + </View> + <Button style={rewardStyle.dismissButton} theme={'light'} text={'Dismiss'} onPress={this.onDismissPressed} /> + </TouchableOpacity> + ); + } +} + +export default RewardSummary; diff --git a/src/component/sdkLoadingStatus/index.js b/src/component/sdkLoadingStatus/index.js deleted file mode 100644 index e820594..0000000 --- a/src/component/sdkLoadingStatus/index.js +++ /dev/null @@ -1,4 +0,0 @@ -import { connect } from 'react-redux'; -import SdkLoadingStatus from './view'; - -export default connect()(SdkLoadingStatus); diff --git a/src/component/sdkLoadingStatus/view.js b/src/component/sdkLoadingStatus/view.js deleted file mode 100644 index 4fa9725..0000000 --- a/src/component/sdkLoadingStatus/view.js +++ /dev/null @@ -1,15 +0,0 @@ -import { ActivityIndicator, Text, View } from 'react-native'; -import React from 'react'; -import discoverStyle from 'styles/discover'; -import Colors from 'styles/colors'; - -export default class SdkLoadingStatus extends React.PureComponent { - render() { - return ( - <View style={discoverStyle.sdkLoading}> - <ActivityIndicator color={Colors.White} size={'small'} /> - <Text style={discoverStyle.sdkLoadingText}>{__('The LBRY background service is initializing...')}</Text> - </View> - ); - } -} diff --git a/src/component/searchInput/index.js b/src/component/searchInput/index.js new file mode 100644 index 0000000..a275b9b --- /dev/null +++ b/src/component/searchInput/index.js @@ -0,0 +1,19 @@ +import { connect } from 'react-redux'; +import { NativeModules } from 'react-native'; +import { doSearch, doUpdateSearchQuery } from 'lbry-redux'; +import SearchInput from './view'; + +const perform = dispatch => ({ + search: search => { + if (NativeModules.Firebase) { + NativeModules.Firebase.track('search', { query: search }); + } + return dispatch(doSearch(search)); + }, + updateSearchQuery: query => dispatch(doUpdateSearchQuery(query, false)), +}); + +export default connect( + null, + perform +)(SearchInput); diff --git a/src/component/searchInput/view.js b/src/component/searchInput/view.js new file mode 100644 index 0000000..3c4d67c --- /dev/null +++ b/src/component/searchInput/view.js @@ -0,0 +1,41 @@ +import React from 'react'; +import { TextInput } from 'react-native'; + +class SearchInput extends React.PureComponent { + static INPUT_TIMEOUT = 500; + + state = { + changeTextTimeout: -1, + }; + + handleChangeText = text => { + clearTimeout(this.state.changeTextTimeout); + if (!text || text.trim().length < 2) { + // only perform a search if 2 or more characters have been input + return; + } + const { search, updateSearchQuery } = this.props; + updateSearchQuery(text); + + let timeout = setTimeout(() => { + search(text); + }, SearchInput.INPUT_TIMEOUT); + this.setState({ changeTextTimeout: timeout }); + }; + + render() { + const { style, value } = this.props; + + return ( + <TextInput + style={style} + placeholder="Search" + underlineColorAndroid="transparent" + value={value} + onChangeText={text => this.handleChangeText(text)} + /> + ); + } +} + +export default SearchInput; diff --git a/src/component/storageStatsCard/view.js b/src/component/storageStatsCard/view.js index 7d18e33..e860161 100644 --- a/src/component/storageStatsCard/view.js +++ b/src/component/storageStatsCard/view.js @@ -1,9 +1,9 @@ import React from 'react'; import { normalizeURI, parseURI } from 'lbry-redux'; import { ActivityIndicator, Platform, Switch, Text, TouchableOpacity, View } from 'react-native'; -import { formatBytes } from 'utils/helper'; -import Colors from 'styles/colors'; -import storageStatsStyle from 'styles/storageStats'; +import { formatBytes } from '../../utils/helper'; +import Colors from '../../styles/colors'; +import storageStatsStyle from '../../styles/storageStats'; class StorageStatsCard extends React.PureComponent { state = { @@ -65,8 +65,7 @@ class StorageStatsCard extends React.PureComponent { } render() { - const { fileInfos } = this.props; - if (fileInfos.length === 0 || this.state.totalBytes === 0) { + if (this.state.totalBytes == 0) { return null; } @@ -75,10 +74,10 @@ class StorageStatsCard extends React.PureComponent { <View style={[storageStatsStyle.row, storageStatsStyle.totalSizeContainer]}> <View style={storageStatsStyle.summary}> <Text style={storageStatsStyle.totalSize}>{formatBytes(this.state.totalBytes, 2)}</Text> - <Text style={storageStatsStyle.annotation}>{__('used')}</Text> + <Text style={storageStatsStyle.annotation}>used</Text> </View> <View style={[storageStatsStyle.row, storageStatsStyle.toggleStatsContainer]}> - <Text style={storageStatsStyle.statsText}>{__('Stats')}</Text> + <Text style={storageStatsStyle.statsText}>Stats</Text> <Switch style={storageStatsStyle.statsToggle} value={this.state.showStats} @@ -98,28 +97,28 @@ class StorageStatsCard extends React.PureComponent { {this.state.totalAudioBytes > 0 && ( <View style={[storageStatsStyle.row, storageStatsStyle.legendItem]}> <View style={[storageStatsStyle.legendBox, storageStatsStyle.audioDistribution]} /> - <Text style={storageStatsStyle.legendText}>{__('Audio')}</Text> + <Text style={storageStatsStyle.legendText}>Audio</Text> <Text style={storageStatsStyle.legendSize}>{formatBytes(this.state.totalAudioBytes, 2)}</Text> </View> )} {this.state.totalImageBytes > 0 && ( <View style={[storageStatsStyle.row, storageStatsStyle.legendItem]}> <View style={[storageStatsStyle.legendBox, storageStatsStyle.imageDistribution]} /> - <Text style={storageStatsStyle.legendText}>{__('Images')}</Text> + <Text style={storageStatsStyle.legendText}>Images</Text> <Text style={storageStatsStyle.legendSize}>{formatBytes(this.state.totalImageBytes, 2)}</Text> </View> )} {this.state.totalVideoBytes > 0 && ( <View style={[storageStatsStyle.row, storageStatsStyle.legendItem]}> <View style={[storageStatsStyle.legendBox, storageStatsStyle.videoDistribution]} /> - <Text style={storageStatsStyle.legendText}>{__('Videos')}</Text> + <Text style={storageStatsStyle.legendText}>Videos</Text> <Text style={storageStatsStyle.legendSize}>{formatBytes(this.state.totalVideoBytes, 2)}</Text> </View> )} {this.state.totalOtherBytes > 0 && ( <View style={[storageStatsStyle.row, storageStatsStyle.legendItem]}> <View style={[storageStatsStyle.legendBox, storageStatsStyle.otherDistribution]} /> - <Text style={storageStatsStyle.legendText}>{__('Other')}</Text> + <Text style={storageStatsStyle.legendText}>Other</Text> <Text style={storageStatsStyle.legendSize}>{formatBytes(this.state.totalOtherBytes, 2)}</Text> </View> )} diff --git a/src/component/subscribeButtonOverlay/index.js b/src/component/subscribeButtonOverlay/index.js deleted file mode 100644 index 5849158..0000000 --- a/src/component/subscribeButtonOverlay/index.js +++ /dev/null @@ -1,18 +0,0 @@ -import { connect } from 'react-redux'; -import { doChannelSubscribe, doChannelUnsubscribe, selectSubscriptions, makeSelectIsSubscribed } from 'lbryinc'; -import { doToast } from 'lbry-redux'; -import SubscribeButtonOverlay from './view'; - -const select = (state, props) => ({ - subscriptions: selectSubscriptions(state), - isSubscribed: makeSelectIsSubscribed(props.uri, true)(state), -}); - -export default connect( - select, - { - doChannelSubscribe, - doChannelUnsubscribe, - doToast, - }, -)(SubscribeButtonOverlay); diff --git a/src/component/subscribeButtonOverlay/view.js b/src/component/subscribeButtonOverlay/view.js deleted file mode 100644 index 1afe9d8..0000000 --- a/src/component/subscribeButtonOverlay/view.js +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react'; -import { normalizeURI, parseURI } from 'lbry-redux'; -import { NativeModules, Text, View, TouchableOpacity } from 'react-native'; -import Icon from 'react-native-vector-icons/FontAwesome5'; -import Button from 'component/button'; -import Colors from 'styles/colors'; - -class SubscribeButtonOverlay extends React.PureComponent { - handlePress = () => { - const { claim, isSubscribed, doChannelSubscribe, doChannelUnsubscribe, uri } = this.props; - if (!claim) { - return; - } - - const subscriptionHandler = isSubscribed ? doChannelUnsubscribe : doChannelSubscribe; - const { name: claimName } = claim; - subscriptionHandler({ - channelName: claimName, - uri: normalizeURI(uri), - }); - }; - - render() { - const { uri, isSubscribed, style } = this.props; - let styles = style.length ? style : [style]; - - return ( - <TouchableOpacity style={styles} opacity={0.7} onPress={this.handlePress}> - {isSubscribed && <Icon name={'heart'} size={20} solid color={Colors.Red} />} - {!isSubscribed && <Icon name={'heart'} size={20} color={Colors.Red} />} - </TouchableOpacity> - ); - } -} - -export default SubscribeButtonOverlay; diff --git a/src/component/subscribeNotificationButton/view.js b/src/component/subscribeNotificationButton/view.js index c48186d..d98edea 100644 --- a/src/component/subscribeNotificationButton/view.js +++ b/src/component/subscribeNotificationButton/view.js @@ -5,27 +5,17 @@ import Button from 'component/button'; import Colors from 'styles/colors'; class SubscribeNotificationButton extends React.PureComponent { - handlePress = () => { + render() { const { + uri, name, doChannelSubscriptionEnableNotifications, doChannelSubscriptionDisableNotifications, doToast, enabledChannelNotifications, + isSubscribed, + style, } = this.props; - const shouldNotify = enabledChannelNotifications.indexOf(name) > -1; - - if (shouldNotify) { - doChannelSubscriptionDisableNotifications(name); - doToast({ message: 'You will not receive notifications for new content.' }); - } else { - doChannelSubscriptionEnableNotifications(name); - doToast({ message: 'You will receive all notifications for new content.' }); - } - }; - - render() { - const { enabledChannelNotifications, name, uri, isSubscribed, style } = this.props; if (!isSubscribed) { return null; @@ -41,14 +31,23 @@ class SubscribeNotificationButton extends React.PureComponent { } const shouldNotify = enabledChannelNotifications.indexOf(name) > -1; + const { claimName } = parseURI(uri); return ( <Button style={styles} theme={'light'} icon={shouldNotify ? 'bell-slash' : 'bell'} - solid - onPress={this.handlePress} + solid={true} + onPress={() => { + if (shouldNotify) { + doChannelSubscriptionDisableNotifications(name); + doToast({ message: 'You will not receive notifications for new content.' }); + } else { + doChannelSubscriptionEnableNotifications(name); + doToast({ message: 'You will receive all notifications for new content.' }); + } + }} /> ); } diff --git a/src/component/suggestedSubscriptionItem/index.js b/src/component/suggestedSubscriptionItem/index.js index 4327f63..4a52bb8 100644 --- a/src/component/suggestedSubscriptionItem/index.js +++ b/src/component/suggestedSubscriptionItem/index.js @@ -6,7 +6,6 @@ import { makeSelectTitleForUri, makeSelectIsUriResolving, } from 'lbry-redux'; -import { doChannelSubscribe, doChannelUnsubscribe, makeSelectIsSubscribed } from 'lbryinc'; import SuggestedSubscriptionItem from './view'; const select = (state, props) => ({ @@ -14,13 +13,13 @@ const select = (state, props) => ({ title: makeSelectTitleForUri(props.uri)(state), claim: makeSelectClaimForUri(props.uri)(state), isResolvingUri: makeSelectIsUriResolving(props.uri)(state), - isSubscribed: makeSelectIsSubscribed(props.uri, true)(state), }); const perform = dispatch => ({ resolveUri: uri => dispatch(doResolveUri(uri)), - subscribe: subscription => doChannelSubscribe(subscription), - unsubscribe: subscription => doChannelUnsubscribe(subscription), }); -export default connect(select, perform)(SuggestedSubscriptionItem); +export default connect( + select, + perform +)(SuggestedSubscriptionItem); diff --git a/src/component/suggestedSubscriptionItem/view.js b/src/component/suggestedSubscriptionItem/view.js index 0f9424a..fe7a686 100644 --- a/src/component/suggestedSubscriptionItem/view.js +++ b/src/component/suggestedSubscriptionItem/view.js @@ -1,99 +1,67 @@ import React from 'react'; import { buildURI, normalizeURI } from 'lbry-redux'; -import { ActivityIndicator, FlatList, Image, Text, TouchableOpacity, View } from 'react-native'; -import { navigateToUri } from 'utils/helper'; +import { ActivityIndicator, FlatList, Image, Text, View } from 'react-native'; import Colors from 'styles/colors'; -import ChannelIconItem from 'component/channelIconItem'; -import channelIconStyle from 'styles/channelIcon'; import discoverStyle from 'styles/discover'; import FileItem from 'component/fileItem'; -import SubscribeButtonOverlay from 'component/subscribeButtonOverlay'; +import SubscribeButton from 'component/subscribeButton'; import subscriptionsStyle from 'styles/subscriptions'; -import Link from 'component/link'; import Tag from 'component/tag'; class SuggestedSubscriptionItem extends React.PureComponent { - state = { - autoStyle: null, - }; - componentDidMount() { const { claim, uri, resolveUri } = this.props; if (!claim) { resolveUri(uri); } - - this.setState({ - autoStyle: - ChannelIconItem.AUTO_THUMB_STYLES[Math.floor(Math.random() * ChannelIconItem.AUTO_THUMB_STYLES.length)], - }); } render() { const { claim, isResolvingUri, navigation, thumbnail, title, uri } = this.props; - - let shortUrl, tags; - if (claim) { - shortUrl = claim.short_url; - if (claim.value) { - tags = claim.value.tags; - } + let tags; + if (claim && claim.value) { + tags = claim.value.tags; } - const hasThumbnail = !!thumbnail; if (isResolvingUri) { return ( <View style={subscriptionsStyle.itemLoadingContainer}> - <ActivityIndicator size={'small'} color={Colors.NextLbryGreen} /> + <ActivityIndicator size={'small'} color={Colors.LbryGreen} /> </View> ); } return ( - <TouchableOpacity style={subscriptionsStyle.suggestedItem}> - <View style={[subscriptionsStyle.suggestedItemThumbnailContainer, this.state.autoStyle]}> - {hasThumbnail && ( - <Image style={subscriptionsStyle.suggestedItemThumbnail} resizeMode={'cover'} source={{ uri: thumbnail }} /> - )} - {!hasThumbnail && ( - <Text style={channelIconStyle.autothumbCharacter}> - {title ? title.substring(0, 1).toUpperCase() : claim ? claim.name.substring(1, 2).toUpperCase() : ''} - </Text> - )} + <View style={subscriptionsStyle.suggestedItem}> + <View style={subscriptionsStyle.suggestedItemThumbnailContainer}> + <Image + style={subscriptionsStyle.suggestedItemThumbnail} + resizeMode={'cover'} + source={thumbnail ? { uri: thumbnail } : require('../../assets/default_avatar.jpg')} + /> </View> <View style={subscriptionsStyle.suggestedItemDetails}> - <Text style={subscriptionsStyle.suggestedItemTitle} numberOfLines={2}> - {title || claim.name} + {title && ( + <Text style={subscriptionsStyle.suggestedItemTitle} numberOfLines={1}> + {title} + </Text> + )} + <Text style={subscriptionsStyle.suggestedItemName} numberOfLines={1}> + {claim && claim.name} </Text> {tags && ( <View style={subscriptionsStyle.suggestedItemTagList}> {tags && tags - .slice(0, 1) - .map(tag => ( - <Tag - numberOfLines={1} - onPress={this.handleItemPress} - style={subscriptionsStyle.tag} - key={tag} - name={tag} - navigation={navigation} - truncate - /> - ))} + .slice(0, 3) + .map(tag => <Tag style={subscriptionsStyle.tag} key={tag} name={tag} navigation={navigation} />)} </View> )} </View> - {claim && ( - <SubscribeButtonOverlay - claim={claim} - style={subscriptionsStyle.suggestedItemSubscribeOverlay} - uri={normalizeURI(claim.permanent_url)} - /> - )} - </TouchableOpacity> + <SubscribeButton style={subscriptionsStyle.suggestedItemSubscribe} uri={normalizeURI(uri)} /> + </View> ); } } diff --git a/src/component/suggestedSubscriptions/index.js b/src/component/suggestedSubscriptions/index.js index a935b2c..0c6524c 100644 --- a/src/component/suggestedSubscriptions/index.js +++ b/src/component/suggestedSubscriptions/index.js @@ -1,19 +1,20 @@ import { connect } from 'react-redux'; -import { doClaimSearch, selectFetchingClaimSearch, selectClaimSearchByQuery, selectFollowedTags } from 'lbry-redux'; +import { doClaimSearch, selectFetchingClaimSearch, selectLastClaimSearchUris, selectFollowedTags } from 'lbry-redux'; import { selectSuggestedChannels, selectIsFetchingSuggested } from 'lbryinc'; -import { selectShowNsfw } from 'redux/selectors/settings'; import SuggestedSubscriptions from './view'; const select = state => ({ followedTags: selectFollowedTags(state), suggested: selectSuggestedChannels(state), loading: selectIsFetchingSuggested(state) || selectFetchingClaimSearch(state), - claimSearchByQuery: selectClaimSearchByQuery(state), - showNsfwContent: selectShowNsfw(state), + claimSearchUris: selectLastClaimSearchUris(state), }); const perform = dispatch => ({ - claimSearch: options => dispatch(doClaimSearch(options)), + claimSearch: options => dispatch(doClaimSearch(10, options)), }); -export default connect(select, perform)(SuggestedSubscriptions); +export default connect( + select, + perform +)(SuggestedSubscriptions); diff --git a/src/component/suggestedSubscriptions/view.js b/src/component/suggestedSubscriptions/view.js index 6e17296..99c1301 100644 --- a/src/component/suggestedSubscriptions/view.js +++ b/src/component/suggestedSubscriptions/view.js @@ -1,7 +1,7 @@ import React from 'react'; -import { ActivityIndicator, SectionList, Text, View } from 'react-native'; -import { MATURE_TAGS, createNormalizedClaimSearchKey, normalizeURI } from 'lbry-redux'; -import { navigateToUri } from 'utils/helper'; +import { ActivityIndicator, FlatList, SectionList, Text, View } from 'react-native'; +import { normalizeURI } from 'lbry-redux'; +import { __, navigateToUri } from 'utils/helper'; import SubscribeButton from 'component/subscribeButton'; import SuggestedSubscriptionItem from 'component/suggestedSubscriptionItem'; import Colors from 'styles/colors'; @@ -11,45 +11,34 @@ import Link from 'component/link'; import _ from 'lodash'; class SuggestedSubscriptions extends React.PureComponent { - state = { - options: {}, - }; - componentDidMount() { - const { claimSearch, followedTags, showNsfwContent } = this.props; + const { claimSearch, followedTags } = this.props; const options = { - any_tags: _.shuffle(followedTags.map(tag => tag.name)).slice(0, 3), + any_tags: _.shuffle(followedTags.map(tag => tag.name)).slice(0, 2), page: 1, no_totals: true, claim_type: 'channel', }; - if (!showNsfwContent) { - options.not_tags = MATURE_TAGS; - } - this.setState({ options }); claimSearch(options); } buildSections = () => { - const { suggested, claimSearchByQuery } = this.props; - const claimSearchKey = createNormalizedClaimSearchKey(this.state.options); - const claimSearchUris = claimSearchByQuery[claimSearchKey]; - + const { suggested, claimSearchUris } = this.props; const suggestedUris = suggested ? suggested.map(suggested => suggested.uri) : []; return [ { - title: __('Suggested channels'), - data: claimSearchUris ? claimSearchUris.filter(uri => !suggestedUris.includes(uri)) : [], + title: __('You might like'), + data: suggestedUris, }, { - title: __('You might also like'), - data: _.shuffle(suggestedUris), + title: __('Tags you follow'), + data: claimSearchUris ? claimSearchUris.filter(uri => !suggestedUris.includes(uri)) : [], }, ]; }; render() { - const { suggested, inModal, loading, navigation } = this.props; + const { suggested, loading, navigation } = this.props; if (loading) { return ( @@ -61,10 +50,8 @@ class SuggestedSubscriptions extends React.PureComponent { return ( <SectionList - style={inModal ? subscriptionsStyle.modalScrollContainer : subscriptionsStyle.scrollContainer} - contentContainerStyle={ - inModal ? subscriptionsStyle.modalSuggestedScrollContent : subscriptionsStyle.suggestedScrollContent - } + style={subscriptionsStyle.scrollContainer} + contentContainerStyle={subscriptionsStyle.suggestedScrollPadding} renderItem={({ item, index, section }) => ( <SuggestedSubscriptionItem key={item} uri={normalizeURI(item)} navigation={navigation} /> )} diff --git a/src/component/suggestedSubscriptionsGrid/index.js b/src/component/suggestedSubscriptionsGrid/index.js deleted file mode 100644 index 7122e33..0000000 --- a/src/component/suggestedSubscriptionsGrid/index.js +++ /dev/null @@ -1,27 +0,0 @@ -import { connect } from 'react-redux'; -import { - doClaimSearch, - selectFetchingClaimSearch, - selectClaimSearchByQuery, - selectClaimSearchByQueryLastPageReached, - selectFollowedTags, -} from 'lbry-redux'; -import { selectSubscriptions, selectSuggestedChannels, selectIsFetchingSuggested } from 'lbryinc'; -import { selectShowNsfw } from 'redux/selectors/settings'; -import SuggestedSubscriptionsGrid from './view'; - -const select = state => ({ - followedTags: selectFollowedTags(state), - subscriptions: selectSubscriptions(state), - suggested: selectSuggestedChannels(state), - loading: selectIsFetchingSuggested(state) || selectFetchingClaimSearch(state), - claimSearchByQuery: selectClaimSearchByQuery(state), - lastPageReached: selectClaimSearchByQueryLastPageReached(state), - showNsfwContent: selectShowNsfw(state), -}); - -const perform = dispatch => ({ - claimSearch: options => dispatch(doClaimSearch(options)), -}); - -export default connect(select, perform)(SuggestedSubscriptionsGrid); diff --git a/src/component/suggestedSubscriptionsGrid/view.js b/src/component/suggestedSubscriptionsGrid/view.js deleted file mode 100644 index d0d1e08..0000000 --- a/src/component/suggestedSubscriptionsGrid/view.js +++ /dev/null @@ -1,111 +0,0 @@ -import React from 'react'; -import { ActivityIndicator, SectionList, Text, View } from 'react-native'; -import { MATURE_TAGS, createNormalizedClaimSearchKey, normalizeURI } from 'lbry-redux'; -import { navigateToUri } from 'utils/helper'; -import { FlatGrid } from 'react-native-super-grid'; -import SubscribeButton from 'component/subscribeButton'; -import SuggestedSubscriptionItem from 'component/suggestedSubscriptionItem'; -import Colors from 'styles/colors'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api -import discoverStyle from 'styles/discover'; -import subscriptionsStyle from 'styles/subscriptions'; -import Link from 'component/link'; -import _ from 'lodash'; - -const suggestedPageSize = 24; -const softLimit = 2400; -class SuggestedSubscriptionsGrid extends React.PureComponent { - state = { - currentPage: 1, - options: {}, - // maintain a local state of subscriptions so that changes don't affect the search - subscriptionIds: [], - }; - - buildClaimSearchOptions() { - const { showNsfwContent } = this.props; - const { currentPage } = this.state; - - const options = { - no_totals: true, - page: currentPage, - page_size: suggestedPageSize, - claim_type: 'channel', - order_by: [Constants.ORDER_BY_EFFECTIVE_AMOUNT], - }; - if (!showNsfwContent) { - options.not_tags = MATURE_TAGS; - } - if (this.state.subscriptionIds.length > 0) { - options.not_channel_ids = this.state.subscriptionIds; - } - - return options; - } - - doClaimSearch() { - const { claimSearch } = this.props; - const options = this.buildClaimSearchOptions(); - claimSearch(options); - } - - handleVerticalEndReached = () => { - // fetch more content - const { claimSearchByQuery, lastPageReached } = this.props; - - const options = this.buildClaimSearchOptions(); - const claimSearchKey = createNormalizedClaimSearchKey(options); - const uris = claimSearchByQuery[claimSearchKey]; - if ( - lastPageReached[claimSearchKey] || - (uris.length > 0 && uris.length < suggestedPageSize) || uris.length >= softLimit - ) { - return; - } - - this.setState({ currentPage: this.state.currentPage + 1 }, () => this.doClaimSearch()); - }; - - componentDidMount() { - const { claimSearch, followedTags, showNsfwContent, subscriptions } = this.props; - if (subscriptions && subscriptions.length > 0) { - this.setState( - { - subscriptionIds: subscriptions.map(subscription => subscription.uri.split('#')[1]), - }, - () => this.doClaimSearch(), - ); - } else { - this.doClaimSearch(); - } - } - - render() { - const { claimSearchByQuery, inModal, navigation } = this.props; - const options = this.buildClaimSearchOptions(); - const claimSearchKey = createNormalizedClaimSearchKey(options); - const claimSearchUris = claimSearchByQuery[claimSearchKey]; - - return ( - <FlatGrid - initialNumToRender={24} - maxToRenderPerBatch={48} - removeClippedSubviews - itemDimension={120} - spacing={1} - items={claimSearchUris} - style={inModal ? subscriptionsStyle.modalScrollContainer : subscriptionsStyle.scrollContainer} - contentContainerStyle={ - inModal ? subscriptionsStyle.modalSuggestedScrollContent : subscriptionsStyle.suggestedScrollContent - } - renderItem={({ item, index }) => ( - <SuggestedSubscriptionItem key={item} uri={normalizeURI(item)} navigation={navigation} /> - )} - onEndReached={this.handleVerticalEndReached} - onEndReachedThreshold={0.2} - /> - ); - } -} - -export default SuggestedSubscriptionsGrid; diff --git a/src/component/tag/view.js b/src/component/tag/view.js index 7adfaf2..2296931 100644 --- a/src/component/tag/view.js +++ b/src/component/tag/view.js @@ -1,6 +1,5 @@ import React from 'react'; import { Text, TouchableOpacity, View } from 'react-native'; -import { MATURE_TAGS } from 'lbry-redux'; import { formatTagName } from 'utils/helper'; import tagStyle from 'styles/tag'; import Colors from 'styles/colors'; @@ -30,7 +29,7 @@ export default class Tag extends React.PureComponent { }; render() { - const { name, numberOfLines, onPress, style, type, truncate } = this.props; + const { name, onPress, style, type } = this.props; let styles = []; if (style) { @@ -42,7 +41,7 @@ export default class Tag extends React.PureComponent { } styles.push({ - backgroundColor: MATURE_TAGS.includes(name) ? Colors.TagGrape : Colors.TagGreen, + backgroundColor: Colors.TagGreen, borderRadius: 8, marginBottom: 4, }); @@ -50,9 +49,7 @@ export default class Tag extends React.PureComponent { return ( <TouchableOpacity style={styles} onPress={onPress || this.onPressDefault}> <View style={tagStyle.content}> - <Text style={tagStyle.text} numberOfLines={numberOfLines}> - {truncate ? formatTagName(name) : name} - </Text> + <Text style={tagStyle.text}>{formatTagName(name)}</Text> {type && <Icon style={tagStyle.icon} name={type === 'add' ? 'plus' : 'times'} size={8} />} </View> </TouchableOpacity> diff --git a/src/component/tagSearch/view.js b/src/component/tagSearch/view.js index 4e9abc2..ce4c365 100644 --- a/src/component/tagSearch/view.js +++ b/src/component/tagSearch/view.js @@ -1,6 +1,5 @@ import React from 'react'; import { KeyboardAvoidingView, Text, TextInput, TouchableOpacity, View } from 'react-native'; -import { MATURE_TAGS } from 'lbry-redux'; import Tag from 'component/tag'; import tagStyle from 'styles/tag'; import Colors from 'styles/colors'; @@ -67,14 +66,13 @@ export default class TagSearch extends React.PureComponent { }; render() { - const { editable, name, style, type, selectedTags = [], showNsfwTags } = this.props; + const { name, style, type, selectedTags = [] } = this.props; return ( <View> <TextInput - editable={editable} style={tagStyle.searchInput} - placeholder={__('Search for more tags')} + placeholder={'Search for more tags'} underlineColorAndroid={Colors.NextLbryGreen} value={this.state.tag} numberOfLines={1} @@ -87,22 +85,6 @@ export default class TagSearch extends React.PureComponent { ))} </View> </KeyboardAvoidingView> - {showNsfwTags && ( - <View style={tagStyle.nsfwTagsContainer}> - <Text style={tagStyle.nsfwTagsTitle}>{__('Mature tags')}</Text> - <View style={tagStyle.tagResultsList}> - {MATURE_TAGS.map(tag => ( - <Tag - key={tag} - name={tag} - style={tagStyle.tag} - type="add" - onAddPress={name => this.onAddTagPress(name)} - /> - ))} - </View> - </View> - )} </View> ); } diff --git a/src/component/transactionList/internal/transaction-list-item.js b/src/component/transactionList/internal/transaction-list-item.js index 64c75fa..09a8730 100644 --- a/src/component/transactionList/internal/transaction-list-item.js +++ b/src/component/transactionList/internal/transaction-list-item.js @@ -2,10 +2,10 @@ import React from 'react'; import { Text, View, Linking } from 'react-native'; import { buildURI, formatCredits } from 'lbry-redux'; -import { navigateToUri } from 'utils/helper'; -import Link from 'component/link'; +import { navigateToUri } from '../../../utils/helper'; +import Link from '../../link'; import moment from 'moment'; -import transactionListStyle from 'styles/transactionList'; +import transactionListStyle from '../../../styles/transactionList'; class TransactionListItem extends React.PureComponent { capitalize(string: string) { @@ -19,12 +19,11 @@ class TransactionListItem extends React.PureComponent { return ( <View style={transactionListStyle.listItem}> <View style={[transactionListStyle.row, transactionListStyle.topRow]}> - <View style={[transactionListStyle.col, transactionListStyle.leftCol]}> + <View style={transactionListStyle.col}> <Text style={transactionListStyle.text}>{this.capitalize(type)}</Text> {name && claimId && ( <Link style={transactionListStyle.link} - numberOfLines={1} onPress={() => navigateToUri(navigation, buildURI({ claimName: name, claimId }))} text={name} /> @@ -38,19 +37,19 @@ class TransactionListItem extends React.PureComponent { </View> </View> <View style={transactionListStyle.row}> - <View style={[transactionListStyle.col, transactionListStyle.leftCol]}> + <View style={transactionListStyle.col}> <Link style={transactionListStyle.smallLink} text={txid.substring(0, 8)} href={`https://explorer.lbry.com/tx/${txid}`} - error={__('The transaction URL could not be opened')} + error={'The transaction URL could not be opened'} /> </View> <View style={transactionListStyle.col}> {date ? ( <Text style={transactionListStyle.smallText}>{moment(date).format('MMM D')}</Text> ) : ( - <Text style={transactionListStyle.smallText}>{__('Pending')}</Text> + <Text style={transactionListStyle.smallText}>Pending</Text> )} </View> </View> diff --git a/src/component/transactionList/view.js b/src/component/transactionList/view.js index 360900f..e119578 100644 --- a/src/component/transactionList/view.js +++ b/src/component/transactionList/view.js @@ -47,7 +47,7 @@ class TransactionList extends React.PureComponent { return ( <View> {!transactionList.length && ( - <Text style={transactionListStyle.noTransactions}>{emptyMessage || __('No transactions to list.')}</Text> + <Text style={transactionListStyle.noTransactions}>{emptyMessage || 'No transactions to list.'}</Text> )} {!!transactionList.length && ( diff --git a/src/component/transactionListRecent/view.js b/src/component/transactionListRecent/view.js index 40871a0..0bd5b2c 100644 --- a/src/component/transactionListRecent/view.js +++ b/src/component/transactionListRecent/view.js @@ -1,12 +1,12 @@ // @flow import React from 'react'; -// import BusyIndicator from 'component/common/busy-indicator'; +//import BusyIndicator from 'component/common/busy-indicator'; import { Text, View } from 'react-native'; -import Button from 'component/button'; -import Link from 'component/link'; -import TransactionList from 'component/transactionList'; -import type { Transaction } from 'component/transactionList/view'; -import walletStyle from 'styles/wallet'; +import Button from '../button'; +import Link from '../link'; +import TransactionList from '../transactionList'; +import type { Transaction } from '../transactionList/view'; +import walletStyle from '../../styles/wallet'; type Props = { fetchTransactions: () => void, @@ -26,15 +26,15 @@ class TransactionListRecent extends React.PureComponent<Props> { return ( <View style={walletStyle.transactionsCard}> <View style={[walletStyle.row, walletStyle.transactionsHeader]}> - <Text style={walletStyle.transactionsTitle}>{__('Recent Transactions')}</Text> - <Link style={walletStyle.link} navigation={navigation} text={__('View All')} href={'#TransactionHistory'} /> + <Text style={walletStyle.transactionsTitle}>Recent Transactions</Text> + <Link style={walletStyle.link} navigation={navigation} text={'View All'} href={'#TransactionHistory'} /> </View> - {fetchingTransactions && <Text style={walletStyle.infoText}>{__('Fetching transactions...')}</Text>} + {fetchingTransactions && <Text style={walletStyle.infoText}>Fetching transactions...</Text>} {!fetchingTransactions && ( <TransactionList navigation={navigation} - transactions={transactions.slice(0, 5)} - emptyMessage={__("Looks like you don't have any recent transactions.")} + transactions={transactions} + emptyMessage={"Looks like you don't have any recent transactions."} /> )} </View> diff --git a/src/component/uriBar/index.js b/src/component/uriBar/index.js index 5f0ad96..1f01ae7 100644 --- a/src/component/uriBar/index.js +++ b/src/component/uriBar/index.js @@ -4,11 +4,8 @@ import { selectSearchState as selectSearch, selectSearchValue, selectSearchSuggestions, - SETTINGS, } from 'lbry-redux'; -import { doSetPlayerVisible } from 'redux/actions/drawer'; import { selectCurrentRoute } from 'redux/selectors/drawer'; -import { makeSelectClientSetting } from 'redux/selectors/settings'; import UriBar from './view'; const select = state => { @@ -19,16 +16,14 @@ const select = state => { query: selectSearchValue(state), currentRoute: selectCurrentRoute(state), suggestions: selectSearchSuggestions(state), - showUriBarSuggestions: makeSelectClientSetting(SETTINGS.SHOW_URI_BAR_SUGGESTIONS)(state), }; }; const perform = dispatch => ({ updateSearchQuery: query => dispatch(doUpdateSearchQuery(query)), - setPlayerVisible: (visible, uri) => dispatch(doSetPlayerVisible(visible, uri)), }); export default connect( select, - perform, + perform )(UriBar); diff --git a/src/component/uriBar/internal/uri-bar-item.js b/src/component/uriBar/internal/uri-bar-item.js index dd65b9f..ab42170 100644 --- a/src/component/uriBar/internal/uri-bar-item.js +++ b/src/component/uriBar/internal/uri-bar-item.js @@ -20,10 +20,6 @@ class UriBarItem extends React.PureComponent { icon = <Icon name="search" size={18} />; break; - case SEARCH_TYPES.TAG: - icon = <Icon name="hashtag" size={18} />; - break; - case SEARCH_TYPES.FILE: default: icon = <Icon name="file" size={18} />; @@ -41,7 +37,6 @@ class UriBarItem extends React.PureComponent { {type === SEARCH_TYPES.SEARCH && `Search for '${value}'`} {type === SEARCH_TYPES.CHANNEL && `View the @${shorthand} channel`} {type === SEARCH_TYPES.FILE && `View content at ${value}`} - {type === SEARCH_TYPES.TAG && `Explore the '${value}' tag`} </Text> </View> </TouchableOpacity> diff --git a/src/component/uriBar/view.js b/src/component/uriBar/view.js index f41d80e..59f25ce 100644 --- a/src/component/uriBar/view.js +++ b/src/component/uriBar/view.js @@ -1,44 +1,27 @@ // @flow import React from 'react'; import { SEARCH_TYPES, isNameValid, isURIValid, normalizeURI } from 'lbry-redux'; -import { Alert, Dimensions, FlatList, Keyboard, Text, TextInput, TouchableOpacity, View } from 'react-native'; -import { navigateToUri, transformUrl } from 'utils/helper'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api +import { FlatList, Keyboard, TextInput, View } from 'react-native'; +import { navigateToUri } from 'utils/helper'; +import Constants from 'constants'; import UriBarItem from './internal/uri-bar-item'; -import Icon from 'react-native-vector-icons/FontAwesome5'; import NavigationButton from 'component/navigationButton'; +import discoverStyle from 'styles/discover'; import uriBarStyle from 'styles/uriBar'; -import { NavigationActions, StackActions } from 'react-navigation'; class UriBar extends React.PureComponent { static INPUT_TIMEOUT = 2500; // 2.5 seconds textInput = null; - keyboardDidShowListener = null; - keyboardDidHideListener = null; - changeTextTimeout = -1; - - state = { - currentValue: null, - inputText: null, - focused: false, - keyboardHeight: 0, - selection: undefined, - }; - componentDidMount() { - this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', this._keyboardDidShow); this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this._keyboardDidHide); - this.setState({ selection: { start: 0, end: 0 } }); + this.setSelection(); } componentWillUnmount() { - if (this.keyboardDidShowListener) { - this.keyboardDidShowListener.remove(); - } if (this.keyboardDidHideListener) { this.keyboardDidHideListener.remove(); } @@ -53,38 +36,45 @@ class UriBar extends React.PureComponent { } } + constructor(props) { + super(props); + this.state = { + changeTextTimeout: null, + currentValue: null, + inputText: null, + focused: false, + // TODO: Add a setting to enable / disable direct search? + directSearch: true, + }; + } + handleChangeText = text => { - this.setState({ selection: undefined }); - const newValue = text || ''; - clearTimeout(this.changeTextTimeout); - const { updateSearchQuery, onSearchSubmitted, showUriBarSuggestions, navigation } = this.props; + const newValue = text ? text : ''; + clearTimeout(this.state.changeTextTimeout); + const { updateSearchQuery, onSearchSubmitted, navigation } = this.props; - this.changeTextTimeout = -1; - if (!showUriBarSuggestions) { - this.changeTextTimeout = setTimeout(() => { - if (text.trim().length === 0) { - // don't do anything if the text is empty - return; - } + let timeout = setTimeout(() => { + if (text.trim().length === 0) { + // don't do anything if the text is empty + return; + } - if (!text.startsWith('lbry://')) { - // not a URI input, so this is a search, perform a direct search - updateSearchQuery(text); - if (onSearchSubmitted) { - onSearchSubmitted(text); - } else { - navigation.navigate({ routeName: 'Search', key: 'searchPage', params: { searchQuery: text } }); - } - } - }, UriBar.INPUT_TIMEOUT); - } else { updateSearchQuery(text); - } - this.setState({ inputText: newValue, currentValue: newValue }); + + if (!text.startsWith('lbry://')) { + // not a URI input, so this is a search, perform a direct search + if (onSearchSubmitted) { + onSearchSubmitted(text); + } else { + navigation.navigate({ routeName: 'Search', key: 'searchPage', params: { searchQuery: text } }); + } + } + }, UriBar.INPUT_TIMEOUT); + this.setState({ inputText: newValue, currentValue: newValue, changeTextTimeout: timeout }); }; handleItemPress = item => { - const { navigation, onSearchSubmitted, setPlayerVisible, updateSearchQuery } = this.props; + const { navigation, onSearchSubmitted, updateSearchQuery } = this.props; const { type, value } = item; Keyboard.dismiss(); @@ -98,52 +88,35 @@ class UriBar extends React.PureComponent { return; } - navigation.navigate({ - routeName: Constants.DRAWER_ROUTE_SEARCH, - key: 'searchPage', - params: { searchQuery: value }, - }); - } else if (SEARCH_TYPES.TAG === type) { - navigation.navigate({ - routeName: Constants.DRAWER_ROUTE_TAG, - key: 'tagPage', - params: { - tag: value.toLowerCase(), - }, - }); + navigation.navigate({ routeName: 'Search', key: 'searchPage', params: { searchQuery: value } }); } else { const uri = normalizeURI(value); - navigateToUri(navigation, uri, null, false, null, setPlayerVisible); + navigateToUri(navigation, uri); } }; - _keyboardDidShow = evt => { - this.setState({ keyboardHeight: evt.endCoordinates.height }); - }; - _keyboardDidHide = () => { if (this.textInput) { this.textInput.blur(); } - this.setState({ focused: false, keyboardHeight: 0 }); + this.setState({ focused: false }); }; - handleSubmitEditing = () => { - const { navigation, onSearchSubmitted, setPlayerVisible, updateSearchQuery } = this.props; - if (this.state.inputText) { - let inputText = this.state.inputText, - inputTextIsUrl = false; - if (inputText.startsWith('lbry://')) { - const transformedUrl = transformUrl(inputText); - // if it's a URI (lbry://...), open the file page - if (transformedUrl && isURIValid(transformedUrl)) { - inputTextIsUrl = true; - navigateToUri(navigation, transformedUrl, null, false, null, setPlayerVisible); - } - } + setSelection() { + if (this.textInput) { + this.textInput.setNativeProps({ selection: { start: 0, end: 0 } }); + } + } - // couldn't parse the inputText as a URL for some reason, so do a search instead - if (!inputTextIsUrl) { + handleSubmitEditing = () => { + const { navigation, onSearchSubmitted, updateSearchQuery } = this.props; + if (this.state.inputText) { + let inputText = this.state.inputText; + if (inputText.startsWith('lbry://') && isURIValid(inputText)) { + // if it's a URI (lbry://...), open the file page + const uri = normalizeURI(inputText); + navigateToUri(navigation, uri); + } else { updateSearchQuery(inputText); // Not a URI, default to a search request if (onSearchSubmitted) { @@ -158,179 +131,70 @@ class UriBar extends React.PureComponent { } }; - handleFocus = () => { - this.setState( - { - focused: true, - }, - () => { - this.setState({ - selection: { start: 0, end: this.state.currentValue ? this.state.currentValue.length : 0 }, - }); - }, - ); - }; - - handleTouchStart = () => { - if (this.state.focused) { - this.setState({ selection: null }); - } - }; - - handleBlur = () => { - this.setState({ - focused: false, - selection: { start: 0, end: 0 }, - }); - }; - - handleNavigationButtonPress = () => { - const { navigation } = this.props; - if (!navigation.openDrawer) { - Alert.alert( - __('Stop watching?'), - 'The LBRY service is still loading stuff in the background. Would you like to continue?', - [ - { text: __('No') }, - { - text: __('Yes'), - onPress: () => { - const resetAction = StackActions.reset({ - index: 0, - actions: [ - NavigationActions.navigate({ routeName: 'Splash', params: { resetUrl: 'lbry://?subscriptions' } }), - ], - }); - navigation.dispatch(resetAction); - }, - }, - ], - ); - } else { - navigation.openDrawer(); - } - }; + onSearchPageBlurred() { + this.setState({ currenValueSet: false }); + } render() { - const { - allowEdit, - belowOverlay, - navigation, - onExitSelectionMode, - onEditActionPressed, - onDeleteActionPressed, - query, - selectedItemCount, - selectionMode, - suggestions, - showUriBarSuggestions, - value, - } = this.props; + const { navigation, suggestions, query, value, belowOverlay } = this.props; if (this.state.currentValue === null) { this.setState({ currentValue: value }); } - let style = [ - uriBarStyle.overlay, - belowOverlay ? null : uriBarStyle.overlayElevated, - this.state.focused && showUriBarSuggestions ? uriBarStyle.inFocus : null, - ]; + let style = [uriBarStyle.overlay, belowOverlay ? null : uriBarStyle.overlayElevated]; + + // TODO: Add optional setting to enable URI / search bar suggestions + /*if (this.state.focused) { style.push(uriBarStyle.inFocus); }*/ - // TODO: selectionModeActions should be dynamically created / specified return ( <View style={style}> <View style={[uriBarStyle.uriContainer, belowOverlay ? null : uriBarStyle.containerElevated]}> - {selectionMode && ( - <View style={uriBarStyle.selectionModeBar}> - <View style={uriBarStyle.selectionModeLeftBar}> - <TouchableOpacity - style={uriBarStyle.backTouchArea} - onPress={() => { - if (onExitSelectionMode) { - onExitSelectionMode(); - } - }} - > - <Icon name="arrow-left" size={20} /> - </TouchableOpacity> - {selectedItemCount > 0 && <Text style={uriBarStyle.itemCount}>{selectedItemCount}</Text>} - </View> - - <View style={uriBarStyle.selectionModeActions}> - {allowEdit && selectedItemCount === 1 && ( - <TouchableOpacity - style={[uriBarStyle.actionTouchArea, uriBarStyle.leftAction]} - onPress={() => { - if (onEditActionPressed) { - onEditActionPressed(); - } - }} - > - <Icon name="edit" size={20} style={uriBarStyle.actionIcon} /> - </TouchableOpacity> + <NavigationButton + name="bars" + size={24} + style={uriBarStyle.drawerMenuButton} + iconStyle={discoverStyle.drawerHamburger} + onPress={() => navigation.openDrawer()} + /> + <TextInput + ref={ref => { + this.textInput = ref; + }} + style={uriBarStyle.uriText} + onLayout={() => { + this.setSelection(); + }} + selectTextOnFocus={true} + placeholder={'Search movies, music, and more'} + underlineColorAndroid={'transparent'} + numberOfLines={1} + clearButtonMode={'while-editing'} + value={this.state.currentValue} + returnKeyType={'go'} + inlineImageLeft={'baseline_search_black_24'} + inlineImagePadding={16} + onFocus={() => this.setState({ focused: true })} + onBlur={() => { + this.setState({ focused: false }); + this.setSelection(); + }} + onChangeText={this.handleChangeText} + onSubmitEditing={this.handleSubmitEditing} + /> + {this.state.focused && !this.state.directSearch && ( + <View style={uriBarStyle.suggestions}> + <FlatList + style={uriBarStyle.suggestionList} + data={suggestions} + keyboardShouldPersistTaps={'handled'} + keyExtractor={(item, value) => item.value} + renderItem={({ item }) => ( + <UriBarItem item={item} navigation={navigation} onPress={() => this.handleItemPress(item)} /> )} - - <TouchableOpacity - style={uriBarStyle.actionTouchArea} - onPress={() => { - if (onDeleteActionPressed) { - onDeleteActionPressed(); - } - }} - > - <Icon name="trash-alt" solid={false} size={20} style={uriBarStyle.actionIcon} /> - </TouchableOpacity> - </View> + /> </View> )} - - {!selectionMode && ( - <NavigationButton - name="bars" - size={24} - style={uriBarStyle.drawerMenuButton} - iconStyle={uriBarStyle.drawerHamburger} - onPress={this.handleNavigationButtonPress} - /> - )} - {!selectionMode && ( - <TextInput - ref={ref => { - this.textInput = ref; - }} - onTouchStart={this.handleTouchStart} - autoCorrect={false} - style={uriBarStyle.uriText} - selection={this.state.selection} - placeholder={__('Search movies, music, and more')} - underlineColorAndroid={'transparent'} - numberOfLines={1} - clearButtonMode={'while-editing'} - value={this.state.currentValue} - returnKeyType={'go'} - inlineImageLeft={'baseline_search_black_24'} - inlineImagePadding={16} - onFocus={this.handleFocus} - onBlur={this.handleBlur} - onChangeText={this.handleChangeText} - onSubmitEditing={this.handleSubmitEditing} - /> - )} </View> - {this.state.focused && showUriBarSuggestions && ( - <FlatList - style={[ - uriBarStyle.suggestions, - { height: Dimensions.get('window').height - this.state.keyboardHeight - 60 }, - ]} - data={suggestions} - keyboardShouldPersistTaps={'handled'} - keyExtractor={(item, value) => `${item.value}-${item.type}`} - renderItem={({ item }) => ( - <UriBarItem item={item} navigation={navigation} onPress={() => this.handleItemPress(item)} /> - )} - /> - )} </View> ); } diff --git a/src/component/videoDuration/index.js b/src/component/videoDuration/index.js deleted file mode 100644 index 597cefe..0000000 --- a/src/component/videoDuration/index.js +++ /dev/null @@ -1,4 +0,0 @@ -import { connect } from 'react-redux'; -import VideoDuration from './view'; - -export default connect()(VideoDuration); diff --git a/src/component/videoDuration/view.js b/src/component/videoDuration/view.js deleted file mode 100644 index 80b0782..0000000 --- a/src/component/videoDuration/view.js +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react'; -import { Text, View } from 'react-native'; -import fileListStyle from 'styles/fileList'; -import _ from 'lodash'; - -export default class VideoDuration extends React.PureComponent { - getDurationString = duration => { - let seconds = duration; - const hours = Math.floor(seconds / 3600); - seconds = duration - hours * 3600; - const minutes = Math.floor(seconds / 60); - seconds = seconds % 60; - - let durationString = ''; - if (hours > 0) { - durationString += hours + ':'; - } - durationString += _.padStart(minutes, hours > 0 ? 2 : 0, '0') + ':'; - durationString += _.padStart(seconds, 2, '0'); - - return durationString; - }; - - render() { - const { duration, style, textStyle } = this.props; - if (!duration || isNaN(parseFloat(duration))) { - return null; - } - - return ( - <View style={style}> - <Text style={textStyle}>{this.getDurationString(duration)}</Text> - </View> - ); - } -} diff --git a/src/component/walletAddress/view.js b/src/component/walletAddress/view.js index f88ee1e..c4bb452 100644 --- a/src/component/walletAddress/view.js +++ b/src/component/walletAddress/view.js @@ -27,22 +27,21 @@ class WalletAddress extends React.PureComponent<Props> { return ( <View style={walletStyle.card}> - <Text style={walletStyle.title}>{__('Receive Credits')}</Text> + <Text style={walletStyle.title}>Receive Credits</Text> <Text style={[walletStyle.text, walletStyle.bottomMarginMedium]}> - {__('Use this wallet address to receive credits sent by another user (or yourself).')} + Use this wallet address to receive credits sent by another user (or yourself). </Text> <Address address={receiveAddress} style={walletStyle.bottomMarginSmall} /> <Button style={[walletStyle.button, walletStyle.bottomMarginLarge]} icon={'sync'} - text={__('Get new address')} + text={'Get new address'} onPress={getNewAddress} disabled={gettingNewAddress} /> <Text style={walletStyle.smallText}> - {__( - 'You can generate a new address at any time, and any previous addresses will continue to work. Using multiple addresses can be helpful for keeping track of incoming payments from multiple sources.' - )} + You can generate a new address at any time, and any previous addresses will continue to work. Using multiple + addresses can be helpful for keeping track of incoming payments from multiple sources. </Text> </View> ); diff --git a/src/component/walletBalance/index.js b/src/component/walletBalance/index.js index 9f69e65..6e136f1 100644 --- a/src/component/walletBalance/index.js +++ b/src/component/walletBalance/index.js @@ -6,4 +6,7 @@ const select = state => ({ balance: selectBalance(state), }); -export default connect(select, null)(WalletBalance); +export default connect( + select, + null +)(WalletBalance); diff --git a/src/component/walletBalance/view.js b/src/component/walletBalance/view.js index f620e9a..9332415 100644 --- a/src/component/walletBalance/view.js +++ b/src/component/walletBalance/view.js @@ -1,9 +1,9 @@ // @flow import React from 'react'; import { Image, Text, View } from 'react-native'; -import { formatCredits } from 'lbry-redux'; -import { Lbryio } from 'lbryinc'; -import { formatUsd } from 'utils/helper'; +import { Lbry, formatCredits } from 'lbry-redux'; +import Address from 'component/address'; +import Button from 'component/button'; import walletStyle from 'styles/wallet'; type Props = { @@ -11,35 +11,16 @@ type Props = { }; class WalletBalance extends React.PureComponent<Props> { - state = { - usdExchangeRate: 0, - }; - - componentDidMount() { - Lbryio.getExchangeRates().then(rates => { - if (!isNaN(rates.LBC_USD)) { - this.setState({ usdExchangeRate: rates.LBC_USD }); - } - }); - } - render() { const { balance } = this.props; return ( <View style={walletStyle.balanceCard}> <Image style={walletStyle.balanceBackground} resizeMode={'cover'} source={require('../../assets/stripe.png')} /> - <Text style={walletStyle.balanceTitle}>{__('Balance')}</Text> - <Text style={walletStyle.balanceCaption}>{__('You currently have')}</Text> + <Text style={walletStyle.balanceTitle}>Balance</Text> + <Text style={walletStyle.balanceCaption}>You currently have</Text> <Text style={walletStyle.balance}> {(balance || balance === 0) && formatCredits(parseFloat(balance), 2) + ' LBC'} </Text> - <Text style={walletStyle.usdBalance}> - {this.state.usdExchangeRate > 0 && ( - <Text> - ≈{formatUsd(isNaN(balance) ? 0 : parseFloat(balance) * parseFloat(this.state.usdExchangeRate))} - </Text> - )} - </Text> </View> ); } diff --git a/src/component/walletBalanceExtra/index.js b/src/component/walletBalanceExtra/index.js deleted file mode 100644 index 9aba337..0000000 --- a/src/component/walletBalanceExtra/index.js +++ /dev/null @@ -1,14 +0,0 @@ -import { connect } from 'react-redux'; -import { selectClaimsBalance, selectSupportsBalance, selectTipsBalance } from 'lbry-redux'; -import { makeSelectClientSetting } from 'redux/selectors/settings'; -import WalletBalanceExtra from './view'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api - -const select = state => ({ - claimsBalance: selectClaimsBalance(state) || 0, - deviceWalletSynced: makeSelectClientSetting(Constants.SETTING_DEVICE_WALLET_SYNCED)(state), - supportsBalance: selectSupportsBalance(state) || 0, - tipsBalance: selectTipsBalance(state) || 0, -}); - -export default connect(select, null)(WalletBalanceExtra); diff --git a/src/component/walletBalanceExtra/view.js b/src/component/walletBalanceExtra/view.js deleted file mode 100644 index 067cc43..0000000 --- a/src/component/walletBalanceExtra/view.js +++ /dev/null @@ -1,115 +0,0 @@ -// @flow -import React from 'react'; -import { Text, View } from 'react-native'; -import { formatCredits } from 'lbry-redux'; -import { Lbryio } from 'lbryinc'; -import { formatUsd } from 'utils/helper'; -import Colors from 'styles/colors'; -import Icon from 'react-native-vector-icons/FontAwesome5'; -import Link from 'component/link'; -import walletStyle from 'styles/wallet'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api - -type Props = { - claimsBalance: number, - supportsBalance: number, - tipsBalance: number, -}; - -class WalletBalanceExtra extends React.PureComponent<Props> { - state = { - usdExchangeRate: 0, - }; - - componentDidMount() { - Lbryio.getExchangeRates().then(rates => { - if (!isNaN(rates.LBC_USD)) { - this.setState({ usdExchangeRate: rates.LBC_USD }); - } - }); - } - - render() { - const { claimsBalance, deviceWalletSynced, navigation, supportsBalance, tipsBalance } = this.props; - - return ( - <View style={walletStyle.balanceExtra}> - <View style={walletStyle.usdInfoCard}> - <Text style={walletStyle.usdInfoText}> - You can convert your credits to USD and withdraw the converted amount using an exchange.{' '} - <Link - style={walletStyle.usdConvertFaqLink} - href={'https://lbry.com/faq/exchanges'} - text={__('Learn more')} - /> - . - </Text> - <Link - style={walletStyle.usdConvertLink} - href={'https://bittrex.com/Account/Register?referralCode=4M1-P30-BON'} - text={__('Convert credits to USD on Bittrex')} - /> - </View> - - <View style={walletStyle.balanceExtraCard}> - <View style={walletStyle.walletExtraRow}> - <View style={walletStyle.walletExtraCol}> - <Icon style={walletStyle.walletExtraIcon} color={Colors.LbryGreen} name={'gift'} size={16} /> - <Text style={walletStyle.walletExtraCaption}>{__('You also have')}</Text> - <View style={walletStyle.balanceRow}> - <Text style={walletStyle.walletExtraBalance}>{formatCredits(parseFloat(tipsBalance), 2)}</Text> - <Text style={walletStyle.walletExtraCurrency}>LBC</Text> - </View> - <Text style={walletStyle.usdWalletExtraBalance}> - ≈{formatUsd(parseFloat(tipsBalance) * parseFloat(this.state.usdExchangeRate))} - </Text> - <Text style={walletStyle.text}>{__('in tips')}</Text> - - <Link - style={walletStyle.earnTipsLink} - onPress={() => { - navigation.navigate({ routeName: Constants.DRAWER_ROUTE_PUBLISH }); - }} - text={__('Earn more tips by uploading cool videos')} - /> - </View> - - <View style={walletStyle.walletExtraCol}> - <Icon style={walletStyle.walletExtraIcon} color={Colors.LbryGreen} name={'lock'} size={16} /> - <Text style={walletStyle.walletExtraCaption}>{__('You staked')}</Text> - <View style={walletStyle.balanceRow}> - <Text style={walletStyle.walletExtraBalance}>{formatCredits(parseFloat(claimsBalance), 2)}</Text> - <Text style={walletStyle.walletExtraCurrency}>LBC</Text> - </View> - <Text style={walletStyle.text}>{__('in your publishes')}</Text> - <View style={[walletStyle.balanceRow, walletStyle.walletExtraTopMargin]}> - <Text style={walletStyle.walletExtraBalance}>{formatCredits(parseFloat(supportsBalance), 2)}</Text> - <Text style={walletStyle.walletExtraCurrency}>LBC</Text> - </View> - <Text style={walletStyle.text}>{__('in your supports')}</Text> - </View> - </View> - </View> - - <View style={walletStyle.syncDriverCustody}> - <Text style={walletStyle.syncInfoText}> - {deviceWalletSynced - ? __('A backup of your wallet is synced with lbry.tv') - : __('Your wallet is not currently synced with lbry.tv. You are responsible for backing up your wallet.')} - </Text> - <Link - text={__('What does this mean?')} - href={ - deviceWalletSynced - ? 'https://lbry.com/faq/account-sync' - : 'https://lbry.com/faq/how-to-backup-wallet#android' - } - style={walletStyle.syncInfoLink} - /> - </View> - </View> - ); - } -} - -export default WalletBalanceExtra; diff --git a/src/component/walletRewardsDriver/index.js b/src/component/walletRewardsDriver/index.js index 2856f8c..ec7c64a 100644 --- a/src/component/walletRewardsDriver/index.js +++ b/src/component/walletRewardsDriver/index.js @@ -1,10 +1,4 @@ import { connect } from 'react-redux'; -import { selectUnclaimedRewardValue, selectUser } from 'lbryinc'; import WalletRewardsDriver from './view'; -const select = state => ({ - unclaimedRewardAmount: selectUnclaimedRewardValue(state), - user: selectUser(state), -}); - -export default connect(select)(WalletRewardsDriver); +export default connect()(WalletRewardsDriver); diff --git a/src/component/walletRewardsDriver/view.js b/src/component/walletRewardsDriver/view.js index c3220bf..ea8184f 100644 --- a/src/component/walletRewardsDriver/view.js +++ b/src/component/walletRewardsDriver/view.js @@ -5,31 +5,12 @@ import walletStyle from 'styles/wallet'; class WalletRewardsDriver extends React.PureComponent<Props> { render() { - const { navigation, unclaimedRewardAmount, user } = this.props; - const signedIn = user && user.has_verified_email; + const { navigation } = this.props; return ( <TouchableOpacity style={walletStyle.rewardDriverCard} onPress={() => navigation.navigate('Rewards')}> <Icon name="award" size={16} style={walletStyle.rewardIcon} /> - {signedIn && ( - <Text style={walletStyle.rewardDriverText}> - {unclaimedRewardAmount === 0 && __('Free credits available in rewards.')} - {unclaimedRewardAmount === 1 && - __('%amount% free credit available in rewards.', { amount: unclaimedRewardAmount })} - {unclaimedRewardAmount > 1 && - __('%amount% free credits available in rewards.', { amount: unclaimedRewardAmount })}{' '} - {__('Tap to learn more.')} - </Text> - )} - - {!signedIn && ( - <Text style={walletStyle.rewardDriverText}> - {unclaimedRewardAmount === 1 && - __('Get %amount% free credit after creating an account.', { amount: unclaimedRewardAmount })} - {unclaimedRewardAmount !== 1 && - __('Get %amount% free credits after creating an account.', { amount: unclaimedRewardAmount })} - </Text> - )} + <Text style={walletStyle.rewardDriverText}>Earn credits while using the LBRY app.</Text> </TouchableOpacity> ); } diff --git a/src/component/walletSend/view.js b/src/component/walletSend/view.js index 61816e8..f1d33ae 100644 --- a/src/component/walletSend/view.js +++ b/src/component/walletSend/view.js @@ -1,10 +1,9 @@ // @flow import React from 'react'; -import { formatCredits, regexAddress } from 'lbry-redux'; +import { regexAddress } from 'lbry-redux'; import { Alert, Clipboard, TextInput, Text, View } from 'react-native'; import Button from 'component/button'; import Colors from 'styles/colors'; -import Icon from 'react-native-vector-icons/FontAwesome5'; import walletStyle from 'styles/wallet'; type DraftTransaction = { @@ -25,7 +24,6 @@ class WalletSend extends React.PureComponent<Props> { address: null, addressChanged: false, addressValid: false, - creditsInputFocused: false, }; componentWillUpdate(nextProps) { @@ -38,28 +36,26 @@ class WalletSend extends React.PureComponent<Props> { handleSend = () => { const { balance, sendToAddress, notify } = this.props; const { address, amount } = this.state; - if (address && (!regexAddress.test(address) || address.substring(0, 1) === 'r')) { + if (address && !regexAddress.test(address)) { notify({ - message: __('The recipient address is not a valid LBRY address.'), - isError: true, + message: 'The recipient address is not a valid LBRY address.', }); return; } if (amount > balance) { notify({ - message: __('Insufficient credits'), - isError: true, + message: 'Insufficient credits', }); return; } if (amount && address) { // Show confirmation before send - Alert.alert(__('Send LBC'), `Are you sure you want to send ${amount} LBC to ${address}?`, [ - { text: __('No') }, + Alert.alert('Send LBC', `Are you sure you want to send ${amount} LBC to ${address}?`, [ + { text: 'No' }, { - text: __('Yes'), + text: 'Yes', onPress: () => { sendToAddress(address, parseFloat(amount)); this.setState({ address: null, amount: null }); @@ -73,8 +69,7 @@ class WalletSend extends React.PureComponent<Props> { if (this.state.addressChanged && !this.state.addressValid) { const { notify } = this.props; notify({ - message: __('The recipient address is not a valid LBRY address.'), - isError: true, + message: 'The recipient address is not a valid LBRY address.', }); } }; @@ -87,23 +82,21 @@ class WalletSend extends React.PureComponent<Props> { render() { const { balance } = this.props; - const canSend = - this.state.address && this.state.amount > 0 && this.state.address.trim().length > 0 && this.state.addressValid; + const canSend = this.state.address && this.state.amount > 0 && this.state.address.trim().length > 0; return ( <View style={walletStyle.card}> - <Text style={walletStyle.title}>{__('Send Credits')}</Text> - <Text style={walletStyle.text}>{__('Recipient address')}</Text> + <Text style={walletStyle.title}>Send Credits</Text> + <Text style={walletStyle.text}>Recipient address</Text> <View style={[walletStyle.row, walletStyle.bottomMarginMedium]}> <TextInput onChangeText={value => this.setState({ address: value, addressChanged: true, - addressValid: value.trim().length === 0 || (regexAddress.test(value) && !value.startsWith('r')), + addressValid: value.trim().length == 0 || regexAddress.test(value), }) } - numberOfLines={1} onBlur={this.handleAddressInputBlur} onSubmitEditing={this.handleAddressInputSubmit} placeholder={'bbFxRyXXXXXXXXXXXZD8nE7XTLUxYnddTs'} @@ -118,14 +111,12 @@ class WalletSend extends React.PureComponent<Props> { onPress={() => Clipboard.getString().then(value => this.setState({ address: value, addressChanged: true }))} /> </View> - <Text style={walletStyle.text}>{__('Amount')}</Text> + <Text style={walletStyle.text}>Amount</Text> <View style={walletStyle.row}> <View style={walletStyle.amountRow}> <TextInput ref={ref => (this.amountInput = ref)} onChangeText={value => this.setState({ amount: value })} - onFocus={() => this.setState({ creditsInputFocused: true })} - onBlur={() => this.setState({ creditsInputFocused: false })} keyboardType={'numeric'} placeholder={'0'} underlineColorAndroid={Colors.NextLbryGreen} @@ -133,15 +124,9 @@ class WalletSend extends React.PureComponent<Props> { style={[walletStyle.input, walletStyle.amountInput]} /> <Text style={[walletStyle.text, walletStyle.currency]}>LBC</Text> - <View style={walletStyle.balanceFocus}> - {this.state.creditsInputFocused && <Icon name="coins" size={12} />} - {this.state.creditsInputFocused && ( - <Text style={walletStyle.balanceText}>{formatCredits(parseFloat(balance), 1, true)}</Text> - )} - </View> </View> <Button - text={__('Send')} + text={'Send'} style={[walletStyle.button, walletStyle.sendButton]} disabled={!canSend} onPress={this.handleSend} diff --git a/src/component/walletSignIn/index.js b/src/component/walletSignIn/index.js deleted file mode 100644 index 1872254..0000000 --- a/src/component/walletSignIn/index.js +++ /dev/null @@ -1,19 +0,0 @@ -import { connect } from 'react-redux'; -import { doToast } from 'lbry-redux'; -import { doSetClientSetting } from 'redux/actions/settings'; -import { selectUser } from 'lbryinc'; -import WalletSignIn from './view'; - -const select = state => ({ - user: selectUser(state), -}); - -const perform = dispatch => ({ - notify: data => dispatch(doToast(data)), - setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)), -}); - -export default connect( - select, - perform -)(WalletSignIn); diff --git a/src/component/walletSignIn/view.js b/src/component/walletSignIn/view.js deleted file mode 100644 index 8bf5058..0000000 --- a/src/component/walletSignIn/view.js +++ /dev/null @@ -1,57 +0,0 @@ -import React from 'react'; -import { Linking, NativeModules, Text, TouchableOpacity, View } from 'react-native'; -import AsyncStorage from '@react-native-community/async-storage'; -import Button from 'component/button'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api -import Link from 'component/link'; -import Colors from 'styles/colors'; -import Icon from 'react-native-vector-icons/FontAwesome5'; -import walletStyle from 'styles/wallet'; - -class WalletSignIn extends React.Component { - onContinuePressed = () => { - const { navigation, setClientSetting } = this.props; - setClientSetting(Constants.SETTING_ALPHA_UNDERSTANDS_RISKS, true); - }; - - onSignInPressed = () => { - const { navigation } = this.props; - navigation.navigate({ - routeName: 'Verification', - key: 'verification', - params: { syncFlow: true, signInFlow: true }, - }); - }; - - render() { - const { navigation, user } = this.props; - - return ( - <View style={walletStyle.signInContainer}> - <View style={walletStyle.signInSummaryRow}> - <Text style={walletStyle.signInTitle}>{__('Account Recommended')}</Text> - </View> - - <View style={walletStyle.onboarding}> - <Text style={walletStyle.onboardingText}> - {__('A lbry.tv account allows you to earn rewards, backup your wallet, and keep everything in sync.')} - {'\n\n'} - {__('Without an account, you assume all responsibility for securing your wallet and LBRY data.')} - </Text> - </View> - - <View style={walletStyle.buttonRow}> - <Link style={walletStyle.continueLink} text={__('Skip Account')} onPress={this.onContinuePressed} /> - <Button - style={walletStyle.signInButton} - theme={'light'} - text={__('Sign Up')} - onPress={this.onSignInPressed} - /> - </View> - </View> - ); - } -} - -export default WalletSignIn; diff --git a/src/component/walletSyncDriver/index.js b/src/component/walletSyncDriver/index.js index 1812ce2..1065158 100644 --- a/src/component/walletSyncDriver/index.js +++ b/src/component/walletSyncDriver/index.js @@ -3,7 +3,7 @@ import { doSetClientSetting } from 'redux/actions/settings'; import { makeSelectClientSetting } from 'redux/selectors/settings'; import { doToast } from 'lbry-redux'; import { selectUserEmail } from 'lbryinc'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api +import Constants from 'constants'; import WalletSyncDriver from './view'; const select = state => ({ diff --git a/src/component/walletSyncDriver/view.js b/src/component/walletSyncDriver/view.js index 455621a..799612c 100644 --- a/src/component/walletSyncDriver/view.js +++ b/src/component/walletSyncDriver/view.js @@ -1,7 +1,7 @@ import React from 'react'; import { Alert, NativeModules, Switch, Text, View } from 'react-native'; import Button from 'component/button'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api +import Constants from 'constants'; import Link from 'component/link'; import walletStyle from 'styles/wallet'; @@ -15,19 +15,19 @@ class WalletSyncDriver extends React.PureComponent<Props> { // turning off // set deviceWalletSynced to false (if confirmed) Alert.alert( - __('Disable wallet sync'), - __('Are you sure you want to turn off wallet sync?'), + 'Disable wallet sync', + 'Are you sure you want to turn off wallet sync?', [ - { text: __('No') }, + { text: 'No' }, { - text: __('Yes'), + text: 'Yes', onPress: () => { setClientSetting(Constants.SETTING_DEVICE_WALLET_SYNCED, false); - notify({ message: __('Wallet sync was successfully disabled.') }); + notify({ message: 'Wallet sync was successfully disabled.' }); }, }, ], - { cancelable: true }, + { cancelable: true } ); } }; @@ -37,14 +37,14 @@ class WalletSyncDriver extends React.PureComponent<Props> { return ( <View style={walletStyle.syncDriverCard}> - <Text style={walletStyle.syncDriverTitle}>{__('Wallet Sync')}</Text> + <Text style={walletStyle.syncDriverTitle}>Wallet Sync</Text> <View style={walletStyle.switchRow}> <View style={walletStyle.tableCol}> - <Text style={walletStyle.labelText}>{__('Sync status')}</Text> + <Text style={walletStyle.labelText}>Sync status</Text> </View> <View style={walletStyle.tableColRow}> - <Text selectable style={walletStyle.valueText}> - {deviceWalletSynced ? __('On') : __('Off')} + <Text selectable={true} style={walletStyle.valueText}> + {deviceWalletSynced ? 'On' : 'Off'} </Text> <Switch style={walletStyle.syncSwitch} @@ -56,11 +56,11 @@ class WalletSyncDriver extends React.PureComponent<Props> { {deviceWalletSynced && ( <View style={walletStyle.tableRow}> <View style={walletStyle.tableCol}> - <Text style={walletStyle.labelText}>{__('Connected email')}</Text> + <Text style={walletStyle.labelText}>Connected email</Text> </View> <View style={walletStyle.tableCol}> - <Text selectable style={walletStyle.valueText} numberOfLines={1}> - {userEmail || __('No connected email')} + <Text selectable={true} style={walletStyle.valueText}> + {userEmail ? userEmail : 'No connected email'} </Text> </View> </View> @@ -69,7 +69,7 @@ class WalletSyncDriver extends React.PureComponent<Props> { <View style={walletStyle.linkRow}> <View style={walletStyle.tableCol}> <Link - text={__('Manual backup')} + text="Manual backup" href="https://lbry.com/faq/how-to-backup-wallet#android" style={walletStyle.syncDriverLink} /> @@ -77,7 +77,7 @@ class WalletSyncDriver extends React.PureComponent<Props> { <View style={walletStyle.rightTableCol}> {!deviceWalletSynced && ( <Link - text={__('Sync FAQ')} + text="Sync FAQ" href="https://lbry.com/faq/how-to-backup-wallet#sync" style={[walletStyle.syncDriverLink, walletStyle.rightLink]} /> diff --git a/src/constants.js b/src/constants.js index e3ac8df..d2a892e 100644 --- a/src/constants.js +++ b/src/constants.js @@ -25,14 +25,11 @@ const Constants = { PHASE_DETAILS: 'details', PHASE_PUBLISH: 'publish', - PHASE_LIST: 'list', - PHASE_NEW: 'create', - CONTENT_TAB: 'content', ABOUT_TAB: 'about', KEY_FIRST_RUN_EMAIL: 'firstRunEmail', - KEY_WALLET_PASSWORD: 'firstRunPassword', + KEY_FIRST_RUN_PASSWORD: 'firstRunPassword', KEY_FIRST_USER_AUTH: 'firstUserAuth', KEY_SHOULD_VERIFY_EMAIL: 'shouldVerifyEmail', KEY_EMAIL_VERIFY_PENDING: 'emailVerifyPending', @@ -44,10 +41,6 @@ const Constants = { SETTING_BACKUP_DISMISSED: 'backupDismissed', SETTING_REWARDS_NOT_INTERESTED: 'rewardsNotInterested', SETTING_DEVICE_WALLET_SYNCED: 'deviceWalletSynced', - SETTING_DHT_ENABLED: 'dhtEnabled', - SETTING_NEW_ANDROID_REWARD_CLAIMED: 'newAndroidRewardClaimed', - - ACTION_SDK_READY: 'SDK_READY', ACTION_DELETE_COMPLETED_BLOBS: 'DELETE_COMPLETED_BLOBS', ACTION_FIRST_RUN_PAGE_CHANGED: 'FIRST_RUN_PAGE_CHANGED', @@ -60,18 +53,6 @@ const Constants = { ACTION_REACT_NAVIGATION_NAVIGATE: 'Navigation/NAVIGATE', ACTION_REACT_NAVIGATION_REPLACE: 'Navigation/REPLACE', - ACTION_SORT_BY_ITEM_CHANGED: 'SORT_BY_ITEM_CHANGED', - ACTION_TIME_ITEM_CHANGED: 'TIME_ITEM_CHANGED', - - ACTION_UPDATE_PUBLISH_FORM_STATE: 'UPDATE_PUBLISH_FORM_STATE', - ACTION_UPDATE_CHANNEL_FORM_STATE: 'UPDATE_CHANNEL_FORM_STATE', - ACTION_CLEAR_PUBLISH_FORM_STATE: 'CLEAR_PUBLISH_FORM_STATE', - ACTION_CLEAR_CHANNEL_FORM_STATE: 'CLEAR_CHANNEL_FORM_STATE', - - ACTION_SET_EXPLICIT_NAVIGATE_BACK: 'SET_EXPLICIT_NAVIGATE_BACK', - - ACTION_FULLSCREEN_MODE_TOGGLED: 'FULLSCREEN_MODE_TOGGLED', - ORIENTATION_HORIZONTAL: 'horizontal', ORIENTATION_VERTICAL: 'vertical', @@ -85,7 +66,6 @@ const Constants = { DRAWER_ROUTE_SUBSCRIPTIONS: 'Subscriptions', DRAWER_ROUTE_MY_LBRY: 'Downloads', DRAWER_ROUTE_PUBLISH: 'Publish', - DRAWER_ROUTE_PUBLISH_FORM: 'PublishForm', DRAWER_ROUTE_PUBLISHES: 'Publishes', DRAWER_ROUTE_REWARDS: 'Rewards', DRAWER_ROUTE_WALLET: 'Wallet', @@ -94,16 +74,14 @@ const Constants = { DRAWER_ROUTE_SEARCH: 'Search', DRAWER_ROUTE_TRANSACTION_HISTORY: 'TransactionHistory', DRAWER_ROUTE_TAG: 'Tag', - DRAWER_ROUTE_CHANNEL_CREATOR: 'ChannelCreator', - DRAWER_ROUTE_CHANNEL_CREATOR_FORM: 'ChannnelCreatorForm', - DRAWER_ROUTE_INVITES: 'Invites', - DRAWER_ROUTE_LITE_FILE: 'LiteFile', FULL_ROUTE_NAME_DISCOVER: 'DiscoverStack', + FULL_ROUTE_NAME_TRENDING: 'TrendingStack', + FULL_ROUTE_NAME_MY_SUBSCRIPTIONS: 'MySubscriptionsStack', FULL_ROUTE_NAME_WALLET: 'WalletStack', + FULL_ROUTE_NAME_MY_LBRY: 'MyLBRYStack', ROUTE_FILE: 'File', - DRAWER_ROUTE_FILE_VIEW: 'FileView', ITEM_CREATE_A_CHANNEL: 'Create a channel...', ITEM_ANONYMOUS: 'Publish anonymously', @@ -138,21 +116,17 @@ const Constants = { { name: TIME_ALL, label: 'All time' }, ], - DEFAULT_ORDER_BY: ['trending_group', 'trending_mixed'], + DEFAULT_ORDER_BY: ['trending_global', 'trending_mixed'], ORDER_BY_EFFECTIVE_AMOUNT: 'effective_amount', - DEFAULT_PAGE_SIZE: 20, + DEFAULT_PAGE_SIZE: 10, ALL_PLACEHOLDER: '_all', MORE_PLACEHOLDER: '_more', TRUE_STRING: 'true', - - MINIMUM_TRANSACTION_BALANCE: 0.01, - - SHARE_BASE_URL: 'https://open.lbry.com', }; export default Constants; @@ -172,13 +146,4 @@ export const DrawerRoutes = [ Constants.DRAWER_ROUTE_ABOUT, Constants.DRAWER_ROUTE_SEARCH, Constants.DRAWER_ROUTE_TRANSACTION_HISTORY, - Constants.DRAWER_ROUTE_CHANNEL_CREATOR, - Constants.DRAWER_ROUTE_INVITES, -]; - -// sub-pages for main routes -export const InnerDrawerRoutes = [ - Constants.DRAWER_ROUTE_CHANNEL_CREATOR_FORM, - Constants.DRAWER_ROUTE_PUBLISH_FORM, - Constants.DRAWER_ROUTE_FILE_VIEW, ]; diff --git a/src/i18n.js b/src/i18n.js deleted file mode 100644 index fd19c7b..0000000 --- a/src/i18n.js +++ /dev/null @@ -1,80 +0,0 @@ -import { NativeModules, Platform } from 'react-native'; -import { SETTINGS } from 'lbry-redux'; -import { doTransifexUpload } from 'lbryinc'; -import AsyncStorage from '@react-native-community/async-storage'; -import RNFS from 'react-native-fs'; - -const isProduction = !__DEV__; // eslint-disable-line no-undef -let knownMessages = null; - -window.language = NativeModules.UtilityModule.language; -window.i18n_messages = window.i18n_messages || {}; - -function saveMessage(message) { - // file path that won't get wiped if app storage is cleared or the app is uninstalled - const messagesFilePath = RNFS.ExternalStorageDirectoryPath + '/lbry-app-strings.json'; - - if (knownMessages === null) { - RNFS.readFile(messagesFilePath, 'utf8') - .then(fileContents => { - knownMessages = JSON.parse(fileContents); - checkMessageAndSave(message, messagesFilePath); - }) - .catch(err => { - knownMessages = {}; // no known messages, initialise the object - checkMessageAndSave(message, messagesFilePath); - }); - } else { - checkMessageAndSave(message, messagesFilePath); - } -} - -function checkMessageAndSave(message, messagesFilePath) { - if (!knownMessages[message]) { - knownMessages[message] = message; - const contents = JSON.stringify(knownMessages, null, 2); - - RNFS.writeFile(messagesFilePath, contents, 'utf8') - .then(() => { - // successful write - // send to transifex (should we do this even if the file doesn't get saved?) - // TODO: load token from .env - /* doTransifexUpload( - contents, - 'lbry-mobile', - '*token*', - () => { - // successful - }, - err => { - // failed - } - ); */ - }) - .catch(err => { - if (err && !isProduction) { - // only do this when not in production - console.error(err); - } - }); - } -} - -export function __(message, tokens) { - const w = global.window ? global.window : window; - let language = w.language ? w.language : 'en'; - - if (!isProduction) { - saveMessage(message); - } - - const translatedMessage = w.i18n_messages[language] ? w.i18n_messages[language][message] || message : message; - - if (!tokens) { - return translatedMessage; - } - - return translatedMessage.replace(/%([^%]+)%/g, function($1, $2) { - return tokens.hasOwnProperty($2) ? tokens[$2] : $2; - }); -} diff --git a/src/index.js b/src/index.js index 608c65e..6f4835f 100644 --- a/src/index.js +++ b/src/index.js @@ -4,8 +4,6 @@ import { Provider, connect } from 'react-redux'; import { AppRegistry, Text, View, NativeModules } from 'react-native'; import { Lbry, - buildSharedStateMiddleware, - blockedReducer, claimsReducer, contentReducer, fileReducer, @@ -15,25 +13,18 @@ import { searchReducer, tagsReducer, walletReducer, - ACTIONS as LBRY_REDUX_ACTIONS, } from 'lbry-redux'; import { - Lbryio, authReducer, blacklistReducer, costInfoReducer, - doGetSync, filteredReducer, homepageReducer, rewardsReducer, - selectUserVerifiedEmail, - statsReducer, subscriptionsReducer, syncReducer, userReducer, - LBRYINC_ACTIONS, } from 'lbryinc'; -import { makeSelectClientSetting } from 'redux/selectors/settings'; import { createStore, applyMiddleware, compose } from 'redux'; import AppWithNavigationState, { AppNavigator, @@ -41,28 +32,18 @@ import AppWithNavigationState, { reactNavigationMiddleware, } from 'component/AppNavigator'; import { REHYDRATE, PURGE, persistCombineReducers, persistStore } from 'redux-persist'; -import { __ } from 'i18n'; -import reactotron from '../reactotron'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api import getStoredStateMigrateV4 from 'redux-persist/lib/integration/getStoredStateMigrateV4'; import FilesystemStorage from 'redux-persist-filesystem-storage'; import createCompressor from 'redux-persist-transform-compress'; import createFilter from 'redux-persist-transform-filter'; import moment from 'moment'; -import formReducer from 'redux/reducers/form'; import drawerReducer from 'redux/reducers/drawer'; import settingsReducer from 'redux/reducers/settings'; import thunk from 'redux-thunk'; -window.__ = __; -if (!NativeModules.UtilityModule.dhtEnabled) { - Lbry.alternateConnectionString = 'https://api.lbry.tv/api/v1/proxy'; - Lbry.methodsUsingAlternateConnectionString = ['claim_search', 'resolve']; -} - const globalExceptionHandler = (error, isFatal) => { if (error && NativeModules.Firebase) { - NativeModules.Firebase.logException(!!isFatal, error.message ? error.message : 'No message', JSON.stringify(error)); + NativeModules.Firebase.logException(isFatal, error.message ? error.message : 'No message', JSON.stringify(error)); } }; setJSExceptionHandler(globalExceptionHandler, true); @@ -97,29 +78,18 @@ function enableBatching(reducer) { const compressor = createCompressor(); const authFilter = createFilter('auth', ['authToken']); -const blockedFilter = createFilter('blocked', ['blockedChannels']); const contentFilter = createFilter('content', ['positions']); -const drawerFilter = createFilter('drawer', ['lastRouteInStack']); const saveClaimsFilter = createFilter('claims', ['claimsByUri']); -const subscriptionsFilter = createFilter('subscriptions', ['enabledChannelNotifications', 'subscriptions', 'latest']); +const subscriptionsFilter = createFilter('subscriptions', ['enabledChannelNotifications', 'subscriptions']); const settingsFilter = createFilter('settings', ['clientSettings']); const tagsFilter = createFilter('tags', ['followedTags']); const walletFilter = createFilter('wallet', ['receiveAddress']); const v4PersistOptions = { - whitelist: ['auth', 'blocked', 'claims', 'drawer', 'content', 'subscriptions', 'settings', 'tags', 'wallet'], + whitelist: ['auth', 'claims', 'content', 'subscriptions', 'settings', 'tags', 'wallet'], // Order is important. Needs to be compressed last or other transforms can't // read the data - transforms: [ - authFilter, - blockedFilter, - drawerFilter, - saveClaimsFilter, - subscriptionsFilter, - settingsFilter, - walletFilter, - compressor, - ], + transforms: [authFilter, saveClaimsFilter, subscriptionsFilter, settingsFilter, walletFilter, compressor], debounce: 10000, storage: FilesystemStorage, }; @@ -132,7 +102,6 @@ const persistOptions = Object.assign({}, v4PersistOptions, { const reducers = persistCombineReducers(persistOptions, { auth: authReducer, blacklist: blacklistReducer, - blocked: blockedReducer, claims: claimsReducer, content: contentReducer, costInfo: costInfoReducer, @@ -140,7 +109,6 @@ const reducers = persistCombineReducers(persistOptions, { file: fileReducer, fileInfo: fileInfoReducer, filtered: filteredReducer, - form: formReducer, homepage: homepageReducer, nav: navigatorReducer, notifications: notificationsReducer, @@ -148,7 +116,6 @@ const reducers = persistCombineReducers(persistOptions, { rewards: rewardsReducer, settings: settingsReducer, search: searchReducer, - stats: statsReducer, subscriptions: subscriptionsReducer, sync: syncReducer, tags: tagsReducer, @@ -156,45 +123,8 @@ const reducers = persistCombineReducers(persistOptions, { wallet: walletReducer, }); -/** - * source: the reducer name - * property: the property in the reducer-specific state - * transform: optional method to modify the value to be stored - */ -const sharedStateActions = [ - LBRYINC_ACTIONS.CHANNEL_SUBSCRIBE, - LBRYINC_ACTIONS.CHANNEL_UNSUBSCRIBE, - LBRY_REDUX_ACTIONS.CREATE_CHANNEL_COMPLETED, - LBRY_REDUX_ACTIONS.TOGGLE_TAG_FOLLOW, - LBRY_REDUX_ACTIONS.TOGGLE_BLOCK_CHANNEL, -]; -const sharedStateFilters = { - tags: { source: 'tags', property: 'followedTags' }, - subscriptions: { - source: 'subscriptions', - property: 'subscriptions', - transform: function(value) { - return value.map(({ uri }) => uri); - }, - }, - blocked: { source: 'blocked', property: 'blockedChannels' }, -}; - -const sharedStateCallback = ({ dispatch, getState }) => { - const state = getState(); - const syncEnabled = makeSelectClientSetting(Constants.SETTING_DEVICE_WALLET_SYNCED)(state); - const emailVerified = selectUserVerifiedEmail(state); - if (syncEnabled && emailVerified) { - NativeModules.UtilityModule.getSecureValue(Constants.KEY_WALLET_PASSWORD).then(password => - dispatch(doGetSync(password)), - ); - } -}; - -const sharedStateMiddleware = buildSharedStateMiddleware(sharedStateActions, sharedStateFilters, sharedStateCallback); - const bulkThunk = createBulkThunkMiddleware(); -const middleware = [sharedStateMiddleware, thunk, bulkThunk, reactNavigationMiddleware]; +const middleware = [thunk, bulkThunk, reactNavigationMiddleware]; // eslint-disable-next-line no-underscore-dangle const composeEnhancers = compose; @@ -202,16 +132,42 @@ const composeEnhancers = compose; const store = createStore( enableBatching(reducers), {}, // initial state, - composeEnhancers(applyMiddleware(...middleware), reactotron.createEnhancer()), + composeEnhancers(applyMiddleware(...middleware)) ); window.store = store; -const persistor = persistStore(store, null, err => { +/* const persistor = persistStore(store, persistOptions, err => { if (err) { - // console.log('Unable to load saved SETTINGS'); + console.log('Unable to load saved SETTINGS'); } }); -window.persistor = persistor; +window.persistor = persistor; */ + +const persistFilter = { + auth: ['authToken'], + claims: ['byId', 'claimsByUri'], + content: ['positions'], + subscriptions: ['enabledChannelNotifications', 'subscriptions'], + settings: ['clientSettings'], + tags: ['followedTags'], + wallet: ['receiveAddress'], +}; + +store.subscribe(() => { + const state = (({ auth, claims, content, subscriptions, settings, tags, wallet }) => ({ + auth, + claims, + content, + subscriptions, + settings, + tags, + wallet, + }))(store.getState()); + NativeModules.StatePersistor.update(state, persistFilter); +}); + +// TODO: Find i18n module that is compatible with react-native +global.__ = str => str; class LBRYApp extends React.Component { render() { diff --git a/src/page/about/view.js b/src/page/about/view.js index ce00c80..3cf0927 100644 --- a/src/page/about/view.js +++ b/src/page/about/view.js @@ -2,7 +2,7 @@ import React from 'react'; import { Lbry } from 'lbry-redux'; import { NativeModules, Text, View, ScrollView } from 'react-native'; import { navigateBack } from 'utils/helper'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api +import Constants from 'constants'; import Link from 'component/link'; import PageHeader from 'component/pageHeader'; import aboutStyle from 'styles/about'; @@ -10,7 +10,6 @@ import aboutStyle from 'styles/about'; class AboutPage extends React.PureComponent { state = { appVersion: null, - firebaseToken: null, lbryId: null, versionInfo: null, }; @@ -19,7 +18,7 @@ class AboutPage extends React.PureComponent { componentWillMount() { const { navigation } = this.props; - // this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused); + this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused); } componentWillUnmount() { @@ -45,22 +44,19 @@ class AboutPage extends React.PureComponent { pushDrawerStack(); setPlayerVisible(); - NativeModules.Firebase.setCurrentScreen('About').then(result => { + if (NativeModules.VersionInfo) { NativeModules.VersionInfo.getAppVersion().then(version => { this.setState({ appVersion: version }); }); - NativeModules.Firebase.getMessagingToken().then(firebaseToken => { - this.setState({ firebaseToken }); + } + Lbry.version().then(info => { + this.setState({ + versionInfo: info, }); - Lbry.version().then(info => { - this.setState({ - versionInfo: info, - }); - }); - Lbry.status().then(info => { - this.setState({ - lbryId: info.installation_id, - }); + }); + Lbry.status().then(info => { + this.setState({ + lbryId: info.installation_id, }); }); @@ -69,29 +65,29 @@ class AboutPage extends React.PureComponent { render() { const { accessToken, drawerStack, navigation, notify, popDrawerStack, userEmail } = this.props; - const loading = __('Loading...'); + const loading = 'Loading...'; const ver = this.state.versionInfo ? this.state.versionInfo : null; return ( <View style={aboutStyle.container}> <PageHeader title={'About LBRY'} onBackPressed={() => navigateBack(navigation, drawerStack, popDrawerStack)} /> <ScrollView style={aboutStyle.scrollContainer}> - <Text style={aboutStyle.title}>{__('Content Freedom')}</Text> + <Text style={aboutStyle.title}>Content Freedom</Text> <Text style={aboutStyle.paragraph}> - {__( - 'LBRY is a free, open, and community-run digital marketplace. It is a decentralized peer-to-peer content distribution platform for creators to upload and share content, and earn LBRY credits for their effort. Users will be able to find a wide selection of videos, music, ebooks and other digital content they are interested in.', - )} + LBRY is a free, open, and community-run digital marketplace. It is a decentralized peer-to-peer content + distribution platform for creators to upload and share content, and earn LBRY credits for their effort. + Users will be able to find a wide selection of videos, music, ebooks and other digital content they are + interested in. </Text> <View style={aboutStyle.links}> - <Link style={aboutStyle.link} href="https://lbry.com/faq/what-is-lbry" text={__('What is LBRY?')} /> - <Link style={aboutStyle.link} href="https://lbry.com/faq/android-basics" text={__('Android App Basics')} /> - <Link style={aboutStyle.link} href="https://lbry.com/faq" text={__('Frequently Asked Questions')} /> + <Link style={aboutStyle.link} href="https://lbry.com/faq/what-is-lbry" text="What is LBRY?" /> + <Link style={aboutStyle.link} href="https://lbry.com/faq/android-basics" text="Android App Basics" /> + <Link style={aboutStyle.link} href="https://lbry.com/faq" text="Frequently Asked Questions" /> </View> - <Text style={aboutStyle.socialTitle}>{__('Get Social')}</Text> + <Text style={aboutStyle.socialTitle}>Get Social</Text> <Text style={aboutStyle.paragraph}> - {__( - 'You can interact with the LBRY team and members of the community on Discord, Facebook, Instagram, Twitter or Reddit.', - )} + You can interact with the LBRY team and members of the community on Discord, Facebook, Instagram, Twitter or + Reddit. </Text> <View style={aboutStyle.links}> <Link style={aboutStyle.link} href="https://discordapp.com/invite/Z3bERWA" text="Discord" /> @@ -101,15 +97,15 @@ class AboutPage extends React.PureComponent { <Link style={aboutStyle.link} href="https://reddit.com/r/lbry" text="Reddit" /> <Link style={aboutStyle.link} href="https://t.me/lbryofficial" text="Telegram" /> </View> - <Text style={aboutStyle.releaseInfoTitle}>{__('App info')}</Text> + <Text style={aboutStyle.releaseInfoTitle}>App info</Text> {userEmail && userEmail.trim().length > 0 && ( <View style={aboutStyle.verticalRow}> <View style={aboutStyle.innerRow}> <View style={aboutStyle.col}> - <Text style={aboutStyle.text}>{__('Connected email')}</Text> + <Text style={aboutStyle.text}>Connected email</Text> </View> <View style={aboutStyle.col}> - <Text selectable style={aboutStyle.valueText}> + <Text selectable={true} style={aboutStyle.valueText}> {userEmail} </Text> </View> @@ -118,7 +114,7 @@ class AboutPage extends React.PureComponent { <Link style={aboutStyle.listLink} href={`http://lbry.com/list/edit/${accessToken}`} - text={__('Update mailing preferences')} + text="Update mailing preferences" /> </View> </View> @@ -126,10 +122,10 @@ class AboutPage extends React.PureComponent { <View style={aboutStyle.row}> <View style={aboutStyle.col}> - <Text style={aboutStyle.text}>{__('App version')}</Text> + <Text style={aboutStyle.text}>App version</Text> </View> <View style={aboutStyle.col}> - <Text selectable style={aboutStyle.valueText}> + <Text selectable={true} style={aboutStyle.valueText}> {this.state.appVersion} </Text> </View> @@ -137,10 +133,10 @@ class AboutPage extends React.PureComponent { <View style={aboutStyle.row}> <View style={aboutStyle.col}> - <Text style={aboutStyle.text}>{__('LBRY SDK')}</Text> + <Text style={aboutStyle.text}>Daemon (lbrynet)</Text> </View> <View style={aboutStyle.col}> - <Text selectable style={aboutStyle.valueText}> + <Text selectable={true} style={aboutStyle.valueText}> {ver ? ver.lbrynet_version : loading} </Text> </View> @@ -148,10 +144,10 @@ class AboutPage extends React.PureComponent { <View style={aboutStyle.row}> <View style={aboutStyle.col}> - <Text style={aboutStyle.text}>{__('Platform')}</Text> + <Text style={aboutStyle.text}>Platform</Text> </View> <View style={aboutStyle.col}> - <Text selectable style={aboutStyle.valueText}> + <Text selectable={true} style={aboutStyle.valueText}> {ver ? ver.platform : loading} </Text> </View> @@ -159,8 +155,8 @@ class AboutPage extends React.PureComponent { <View style={aboutStyle.row}> <View style={aboutStyle.col}> - <Text style={aboutStyle.text}>{__('Installation ID')}</Text> - <Text selectable style={aboutStyle.lineValueText}> + <Text style={aboutStyle.text}>Installation ID</Text> + <Text selectable={true} style={aboutStyle.lineValueText}> {this.state.lbryId ? this.state.lbryId : loading} </Text> </View> @@ -168,21 +164,12 @@ class AboutPage extends React.PureComponent { <View style={aboutStyle.row}> <View style={aboutStyle.col}> - <Text style={aboutStyle.text}>{__('Firebase Token')}</Text> - <Text selectable style={aboutStyle.lineValueText}> - {this.state.firebaseToken ? this.state.firebaseToken : loading} - </Text> - </View> - </View> - - <View style={aboutStyle.row}> - <View style={aboutStyle.col}> - <Text style={aboutStyle.text}>{__('Logs')}</Text> + <Text style={aboutStyle.text}>Logs</Text> </View> <View style={aboutStyle.col}> <Link style={aboutStyle.listLink} - text={__('Send log')} + text="Send log" onPress={() => { if (NativeModules.UtilityModule) { NativeModules.UtilityModule.shareLogFile(error => { diff --git a/src/page/channel/index.js b/src/page/channel/index.js index e0f100d..ff19da4 100644 --- a/src/page/channel/index.js +++ b/src/page/channel/index.js @@ -1,31 +1,29 @@ import { connect } from 'react-redux'; -import { doAbandonClaim, doFetchChannelListMine, makeSelectClaimForUri, selectMyChannelClaims } from 'lbry-redux'; -import { doFetchSubCount, makeSelectSubCountForUri } from 'lbryinc'; +import { + doFetchClaimsByChannel, + makeSelectClaimForUri, + makeSelectClaimsInChannelForCurrentPageState, + makeSelectFetchingChannelClaims, + makeSelectTotalPagesForChannel, +} from 'lbry-redux'; import { doPopDrawerStack } from 'redux/actions/drawer'; -import { doSetSortByItem, doSetTimeItem } from 'redux/actions/settings'; import { selectDrawerStack } from 'redux/selectors/drawer'; -import { selectSortByItem, selectTimeItem } from 'redux/selectors/settings'; import ChannelPage from './view'; const select = (state, props) => ({ - channels: selectMyChannelClaims(state), claim: makeSelectClaimForUri(props.uri)(state), + claimsInChannel: makeSelectClaimsInChannelForCurrentPageState(props.uri)(state), drawerStack: selectDrawerStack(state), - sortByItem: selectSortByItem(state), - subCount: makeSelectSubCountForUri(props.uri)(state), - timeItem: selectTimeItem(state), + fetching: makeSelectFetchingChannelClaims(props.uri)(state), + totalPages: makeSelectTotalPagesForChannel(props.uri, 10)(state), // Update to use a default PAGE_SIZE constant }); const perform = dispatch => ({ - abandonClaim: (txid, nout) => dispatch(doAbandonClaim(txid, nout)), - fetchChannelListMine: () => dispatch(doFetchChannelListMine(1, 99999, true)), - fetchSubCount: claimId => dispatch(doFetchSubCount(claimId)), + fetchClaims: (uri, page) => dispatch(doFetchClaimsByChannel(uri, page)), popDrawerStack: () => dispatch(doPopDrawerStack()), - setSortByItem: item => dispatch(doSetSortByItem(item)), - setTimeItem: item => dispatch(doSetTimeItem(item)), }); export default connect( select, - perform, + perform )(ChannelPage); diff --git a/src/page/channel/view.js b/src/page/channel/view.js index 09b9260..d481ae5 100644 --- a/src/page/channel/view.js +++ b/src/page/channel/view.js @@ -1,121 +1,111 @@ // @flow import React from 'react'; -import { - ActivityIndicator, - Alert, - Dimensions, - Image, - NativeModules, - ScrollView, - Text, - TouchableOpacity, - View, -} from 'react-native'; +import { ActivityIndicator, Dimensions, Image, ScrollView, Text, TouchableOpacity, View } from 'react-native'; import { TabView, SceneMap } from 'react-native-tab-view'; -import { normalizeURI } from 'lbry-redux'; -import { navigateBack, getOrderBy, formatLbryUrlForWeb } from 'utils/helper'; -import ChannelIconItem from 'component/channelIconItem'; -import ClaimList from 'component/claimList'; +import { navigateBack } from 'utils/helper'; import Colors from 'styles/colors'; import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api import Button from 'component/button'; -import EmptyStateView from 'component/emptyStateView'; -import Icon from 'react-native-vector-icons/FontAwesome5'; import Link from 'component/link'; -import ModalPicker from 'component/modalPicker'; -import ModalTipView from 'component/modalTipView'; +import FileList from 'component/fileList'; import PageHeader from 'component/pageHeader'; import SubscribeButton from 'component/subscribeButton'; -import SubscribeNotificationButton from 'component/subscribeNotificationButton'; import UriBar from 'component/uriBar'; -import channelIconStyle from 'styles/channelIcon'; import channelPageStyle from 'styles/channelPage'; -import discoverStyle from 'styles/discover'; class ChannelPage extends React.PureComponent { state = { - autoStyle: null, - showSortPicker: false, - showTimePicker: false, - showTipView: false, - orderBy: ['release_time'], // sort by new by default + page: 1, + showPageButtons: false, activeTab: Constants.CONTENT_TAB, - currentSortByItem: Constants.CLAIM_SEARCH_SORT_BY_ITEMS[1], // should always default to sorting channel pages by new }; - componentWillMount() { - this.setState({ - autoStyle: - ChannelIconItem.AUTO_THUMB_STYLES[Math.floor(Math.random() * ChannelIconItem.AUTO_THUMB_STYLES.length)], - }); - } - componentDidMount() { - const { claim, fetchChannelListMine, fetchSubCount } = this.props; - NativeModules.Firebase.setCurrentScreen('Channel'); - fetchChannelListMine(); - if (claim) { - fetchSubCount(claim.claim_id); + const { uri, page, claimsInChannel, fetchClaims, fetchClaimCount } = this.props; + + if (!claimsInChannel || !claimsInChannel.length) { + fetchClaims(uri, page || this.state.page); } } - handleSortByItemSelected = item => { - // sort by specific only to this component state - this.setState({ currentSortByItem: item, orderBy: getOrderBy(item), showSortPicker: false }); + handlePreviousPage = () => { + const { uri, fetchClaims } = this.props; + if (this.state.page > 1) { + this.setState({ page: this.state.page - 1, showPageButtons: false }, () => { + fetchClaims(uri, this.state.page); + }); + } }; - handleTimeItemSelected = item => { - const { setTimeItem } = this.props; - setTimeItem(item); - this.setState({ showTimePicker: false }); - }; - - listHeader = () => { - const { timeItem } = this.props; - const { currentSortByItem } = this.state; - - return ( - <View style={channelPageStyle.listHeader}> - <View style={discoverStyle.pickerRow}> - <View style={discoverStyle.leftPickerRow}> - <TouchableOpacity style={discoverStyle.tagSortBy} onPress={() => this.setState({ showSortPicker: true })}> - <Text style={discoverStyle.tagSortText}>{__(currentSortByItem.label.split(' ')[0])}</Text> - <Icon style={discoverStyle.tagSortIcon} name={'sort-down'} size={14} /> - </TouchableOpacity> - {Constants.SORT_BY_TOP === currentSortByItem.name && ( - <TouchableOpacity style={discoverStyle.tagTime} onPress={() => this.setState({ showTimePicker: true })}> - <Text style={discoverStyle.tagSortText}>{__(timeItem.label)}</Text> - <Icon style={discoverStyle.tagSortIcon} name={'sort-down'} size={14} /> - </TouchableOpacity> - )} - </View> - </View> - </View> - ); + handleNextPage = () => { + const { uri, fetchClaims, totalPages } = this.props; + if (this.state.page < totalPages) { + this.setState({ page: this.state.page + 1, showPageButtons: false }, () => { + fetchClaims(uri, this.state.page); + }); + } }; renderContent = () => { - const { claim, navigation, timeItem } = this.props; + const { fetching, claimsInChannel, totalPages, navigation } = this.props; - let channelId; - if (claim) { - channelId = claim.claim_id; + let contentList; + if (fetching) { + contentList = ( + <View style={channelPageStyle.busyContainer}> + <ActivityIndicator size="large" color={Colors.NextLbryGreen} /> + <Text style={channelPageStyle.infoText}>Fetching content...</Text> + </View> + ); + } else { + contentList = + claimsInChannel && claimsInChannel.length ? ( + <FileList + sortByHeight + hideFilter + fileInfos={claimsInChannel} + navigation={navigation} + style={channelPageStyle.fileList} + contentContainerStyle={channelPageStyle.fileListContent} + onEndReached={() => this.setState({ showPageButtons: true })} + /> + ) : ( + <View style={channelPageStyle.busyContainer}> + <Text style={channelPageStyle.infoText}>No content found.</Text> + </View> + ); + } + + let pageButtons; + if (totalPages > 1 && this.state.showPageButtons) { + pageButtons = ( + <View style={channelPageStyle.pageButtons}> + <View> + {this.state.page > 1 && ( + <Button + style={channelPageStyle.button} + text={'Previous'} + disabled={!!fetching} + onPress={this.handlePreviousPage} + /> + )} + </View> + {this.state.page < totalPages && ( + <Button + style={[channelPageStyle.button, channelPageStyle.nextButton]} + text={'Next'} + disabled={!!fetching} + onPress={this.handleNextPage} + /> + )} + </View> + ); } return ( <View style={channelPageStyle.contentTab}> - {channelId && ( - <ClaimList - ListHeaderComponent={this.listHeader} - hideChannel - orderBy={this.state.orderBy} - time={timeItem.name} - navigation={navigation} - orientation={Constants.ORIENTATION_VERTICAL} - channelIds={[channelId]} - style={channelPageStyle.claimList} - /> - )} + {contentList} + {pageButtons} </View> ); }; @@ -127,7 +117,7 @@ class ChannelPage extends React.PureComponent { return ( <View style={channelPageStyle.aboutTab}> <View style={channelPageStyle.busyContainer}> - <Text style={channelPageStyle.infoText}>{__('No information to display.')}</Text> + <Text style={channelPageStyle.infoText}>No information to display.</Text> </View> </View> ); @@ -137,21 +127,23 @@ class ChannelPage extends React.PureComponent { return ( <View style={channelPageStyle.aboutTab}> {!websiteUrl && !email && !description && ( - <EmptyStateView message={__("There's nothing here yet.\nPlease check back later.")} /> + <View style={channelPageStyle.busyContainer}> + <Text style={channelPageStyle.infoText}>Nothing here yet. Please check back later.</Text> + </View> )} {(websiteUrl || email || description) && ( <ScrollView style={channelPageStyle.aboutScroll} contentContainerStyle={channelPageStyle.aboutScrollContent}> {websiteUrl && websiteUrl.trim().length > 0 && ( <View style={channelPageStyle.aboutItem}> - <Text style={channelPageStyle.aboutTitle}>{__('Website')}</Text> + <Text style={channelPageStyle.aboutTitle}>Website</Text> <Link style={channelPageStyle.aboutText} text={websiteUrl} href={websiteUrl} /> </View> )} {email && email.trim().length > 0 && ( <View style={channelPageStyle.aboutItem}> - <Text style={channelPageStyle.aboutTitle}>{__('Email')}</Text> + <Text style={channelPageStyle.aboutTitle}>Email</Text> <Link style={channelPageStyle.aboutText} text={email} href={`mailto:${email}`} /> </View> )} @@ -167,81 +159,19 @@ class ChannelPage extends React.PureComponent { ); }; - onEditPressed = () => { - const { claim, navigation } = this.props; - if (claim) { - const { permanent_url: permanentUrl } = claim; - navigation.navigate({ - routeName: Constants.DRAWER_ROUTE_CHANNEL_CREATOR, - params: { editChannelUrl: permanentUrl, returnUrl: permanentUrl }, - }); - } - this.onEditPressed = null; - }; - - onTipPressed = () => { - this.setState({ showTipView: true }); - }; - - onSharePressed = () => { - const { claim } = this.props; - if (claim) { - const { canonical_url: canonicalUrl, short_url: shortUrl, permanent_url: permanentUrl } = claim; - const url = Constants.SHARE_BASE_URL + formatLbryUrlForWeb(canonicalUrl || shortUrl || permanentUrl); - NativeModules.UtilityModule.shareUrl(url); - } - }; - - onDeletePressed = () => { - const { abandonClaim, claim, navigation } = this.props; - if (claim) { - const { txid, nout } = claim; - - // show confirm alert - Alert.alert( - __('Delete channel'), - __('Are you sure you want to delete this channel?'), - [ - { text: __('No') }, - { - text: __('Yes'), - onPress: () => { - abandonClaim(txid, nout); - navigation.navigate({ routeName: Constants.DRAWER_ROUTE_CHANNEL_CREATOR }); - }, - }, - ], - { cancelable: true }, - ); - } - }; - render() { - const { channels, claim, navigation, uri, drawerStack, popDrawerStack, subCount, timeItem } = this.props; + const { fetching, claimsInChannel, claim, navigation, totalPages, uri, drawerStack, popDrawerStack } = this.props; const { name, permanent_url: permanentUrl } = claim; - const { autoStyle, currentSortByItem, showSortPicker, showTimePicker, showTipView } = this.state; - const ownedChannel = channels ? channels.map(channel => channel.permanent_url).includes(permanentUrl) : false; - let thumbnailUrl, - coverUrl, - title, - fullUri, - displayName = null, - substrIndex = 0; - if (claim) { - if (claim.value) { - title = claim.value.title; - if (claim.value.cover) { - coverUrl = claim.value.cover.url; - } - if (claim.value.thumbnail) { - thumbnailUrl = claim.value.thumbnail.url; - } + let thumbnailUrl, coverUrl, title; + if (claim && claim.value) { + title = claim.value.title; + if (claim.value.cover) { + coverUrl = claim.value.cover.url; + } + if (claim.value.thumbnail) { + thumbnailUrl = claim.value.thumbnail.url; } - - displayName = title || claim.name; - substrIndex = displayName.startsWith('@') ? 1 : 0; - fullUri = normalizeURI(`${claim.name}#${claim.claim_id}`); } return ( @@ -262,63 +192,21 @@ class ChannelPage extends React.PureComponent { <View style={channelPageStyle.channelHeader}> <Text style={channelPageStyle.channelName}>{title && title.trim().length > 0 ? title : name}</Text> - <Text style={[channelPageStyle.followerCount, subCount >= 1 ? channelPageStyle.followerCountBg : null]}> - {subCount === 1 && __('%follower% follower', { follower: subCount })} - {subCount > 1 && __('%follower% followers', { follower: subCount })} - </Text> </View> - <View style={[channelPageStyle.avatarImageContainer, autoStyle]}> - {thumbnailUrl && ( - <Image style={channelPageStyle.avatarImage} resizeMode={'cover'} source={{ uri: thumbnailUrl }} /> - )} - {(!thumbnailUrl || thumbnailUrl.trim().length === 0) && ( - <Text style={channelIconStyle.autothumbCharacter}> - {displayName.substring(substrIndex, substrIndex + 1).toUpperCase()} - </Text> - )} + <View style={channelPageStyle.avatarImageContainer}> + <Image + style={channelPageStyle.avatarImage} + resizeMode={'cover'} + source={ + thumbnailUrl && thumbnailUrl.trim().length > 0 + ? { uri: thumbnailUrl } + : require('../../assets/default_avatar.jpg') + } + /> </View> - <View style={channelPageStyle.subscribeButtonContainer}> - {ownedChannel && ( - <Button - style={channelPageStyle.actionButton} - theme={'light'} - icon={'edit'} - text={__('Edit')} - onPress={this.onEditPressed} - /> - )} - {ownedChannel && ( - <Button - style={[channelPageStyle.actionButton, channelPageStyle.deleteButton]} - theme={'light'} - icon={'trash-alt'} - text={__('Delete')} - onPress={this.onDeletePressed} - /> - )} - <Button - style={[channelPageStyle.actionButton, channelPageStyle.shareButton]} - theme={'light'} - icon={'share-alt'} - onPress={this.onSharePressed} - /> - <Button - style={[channelPageStyle.actionButton, channelPageStyle.tipButton]} - theme={'light'} - icon={'gift'} - onPress={this.onTipPressed} - /> - {!ownedChannel && <SubscribeButton style={channelPageStyle.subscribeButton} uri={fullUri} name={name} />} - {false && !ownedChannel && ( - <SubscribeNotificationButton - style={[channelPageStyle.subscribeButton, channelPageStyle.bellButton]} - uri={fullUri} - name={name} - /> - )} - </View> + <SubscribeButton style={channelPageStyle.subscribeButton} uri={uri} name={name} /> </View> <View style={channelPageStyle.tabBar}> @@ -326,14 +214,14 @@ class ChannelPage extends React.PureComponent { style={channelPageStyle.tab} onPress={() => this.setState({ activeTab: Constants.CONTENT_TAB })} > - <Text style={channelPageStyle.tabTitle}>{__('CONTENT')}</Text> + <Text style={channelPageStyle.tabTitle}>CONTENT</Text> {Constants.CONTENT_TAB === this.state.activeTab && <View style={channelPageStyle.activeTabHint} />} </TouchableOpacity> <TouchableOpacity style={channelPageStyle.tab} onPress={() => this.setState({ activeTab: Constants.ABOUT_TAB })} > - <Text style={channelPageStyle.tabTitle}>{__('ABOUT')}</Text> + <Text style={channelPageStyle.tabTitle}>ABOUT</Text> {Constants.ABOUT_TAB === this.state.activeTab && <View style={channelPageStyle.activeTabHint} />} </TouchableOpacity> </View> @@ -341,35 +229,6 @@ class ChannelPage extends React.PureComponent { {Constants.CONTENT_TAB === this.state.activeTab && this.renderContent()} {Constants.ABOUT_TAB === this.state.activeTab && this.renderAbout()} </View> - - {showSortPicker && ( - <ModalPicker - title={__('Sort content by')} - onOverlayPress={() => this.setState({ showSortPicker: false })} - onItemSelected={this.handleSortByItemSelected} - selectedItem={currentSortByItem} - items={Constants.CLAIM_SEARCH_SORT_BY_ITEMS} - /> - )} - {showTimePicker && ( - <ModalPicker - title={__('Content from')} - onOverlayPress={() => this.setState({ showTimePicker: false })} - onItemSelected={this.handleTimeItemSelected} - selectedItem={timeItem} - items={Constants.CLAIM_SEARCH_TIME_ITEMS} - /> - )} - {showTipView && ( - <ModalTipView - claim={claim} - channelName={claim.name} - contentName={title} - onCancelPress={() => this.setState({ showTipView: false })} - onOverlayPress={() => this.setState({ showTipView: false })} - onSendTipSuccessful={() => this.setState({ showTipView: false })} - /> - )} </View> ); } diff --git a/src/page/channelCreator/index.js b/src/page/channelCreator/index.js deleted file mode 100644 index c9f8f21..0000000 --- a/src/page/channelCreator/index.js +++ /dev/null @@ -1,57 +0,0 @@ -import { connect } from 'react-redux'; -import { - selectAbandoningIds, - selectBalance, - selectMyChannelClaims, - selectFetchingMyChannels, - selectUpdatingChannel, - selectUpdateChannelError, - doAbandonClaim, - doFetchChannelListMine, - doCreateChannel, - doUpdateChannel, - doToast, -} from 'lbry-redux'; -import { doGetSync } from 'lbryinc'; -import { - doPushDrawerStack, - doPopDrawerStack, - doSetPlayerVisible, - doSetExplicitNavigateBack, -} from 'redux/actions/drawer'; -import { doUpdateChannelFormState, doClearChannelFormState } from 'redux/actions/form'; -import { selectDrawerStack } from 'redux/selectors/drawer'; -import { selectChannelFormState, selectHasChannelFormState } from 'redux/selectors/form'; -import { selectSdkReady } from 'redux/selectors/settings'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api -import ChannelCreator from './view'; - -const select = state => ({ - abandoningClaimIds: selectAbandoningIds(state), - channels: selectMyChannelClaims(state), - channelFormState: selectChannelFormState(state), - drawerStack: selectDrawerStack(state), - fetchingChannels: selectFetchingMyChannels(state), - balance: selectBalance(state), - hasFormState: selectHasChannelFormState(state), - sdkReady: selectSdkReady(state), - updatingChannel: selectUpdatingChannel(state), - updateChannelError: selectUpdateChannelError(state), -}); - -const perform = dispatch => ({ - abandonClaim: (txid, nout) => dispatch(doAbandonClaim(txid, nout)), - notify: data => dispatch(doToast(data)), - clearChannelFormState: () => dispatch(doClearChannelFormState()), - createChannel: (name, amount, optionalParams) => dispatch(doCreateChannel(name, amount, optionalParams)), - fetchChannelListMine: () => dispatch(doFetchChannelListMine(1, 99999, true)), - getSync: (password, callback) => dispatch(doGetSync(password, callback)), - updateChannel: params => dispatch(doUpdateChannel(params)), - updateChannelFormState: data => dispatch(doUpdateChannelFormState(data)), - pushDrawerStack: (routeName, params) => dispatch(doPushDrawerStack(routeName, params)), - popDrawerStack: () => dispatch(doPopDrawerStack()), - setPlayerVisible: () => dispatch(doSetPlayerVisible(false)), - setExplicitNavigateBack: flag => dispatch(doSetExplicitNavigateBack(flag)), -}); - -export default connect(select, perform)(ChannelCreator); diff --git a/src/page/channelCreator/view.js b/src/page/channelCreator/view.js deleted file mode 100644 index a7f6400..0000000 --- a/src/page/channelCreator/view.js +++ /dev/null @@ -1,1165 +0,0 @@ -import React from 'react'; -import { CLAIM_VALUES, Lbry, formatCredits, isNameValid, regexInvalidURI } from 'lbry-redux'; -import { - ActivityIndicator, - Alert, - DeviceEventEmitter, - FlatList, - Image, - NativeModules, - Picker, - ScrollView, - Text, - TextInput, - TouchableOpacity, - View, -} from 'react-native'; -import { navigateBack, navigateToUri, logPublish, uploadImageAsset } from 'utils/helper'; -import Button from 'component/button'; -import ChannelIconItem from 'component/channelIconItem'; -import ChannelRewardsDriver from 'component/channelRewardsDriver'; -import Colors from 'styles/colors'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api -import EmptyStateView from 'component/emptyStateView'; -import FastImage from 'react-native-fast-image'; -import FloatingWalletBalance from 'component/floatingWalletBalance'; -import Icon from 'react-native-vector-icons/FontAwesome5'; -import Link from 'component/link'; -import Tag from 'component/tag'; -import TagSearch from 'component/tagSearch'; -import UriBar from 'component/uriBar'; -import channelCreatorStyle from 'styles/channelCreator'; -import channelIconStyle from 'styles/channelIcon'; -import seedrandom from 'seedrandom'; - -export default class ChannelCreator extends React.PureComponent { - scrollView = null; - - state = { - autoStyle: null, - returnUrl: null, - canSave: true, - claimId: null, - creditsInputFocused: false, - currentSelectedValue: Constants.ITEM_ANONYMOUS, - currentPhase: null, - displayName: null, - channelNameUserEdited: false, - newChannelTitle: '', - newChannelName: '', - newChannelBid: 0.01, - addingChannel: false, - creatingChannel: false, - editChannelUrl: null, - newChannelNameError: '', - newChannelBidError: '', - createChannelError: undefined, - showCreateChannel: false, - thumbnailUrl: '', - coverImageUrl: '', - - avatarImagePickerOpen: false, - coverImagePickerOpen: false, - uploadingImage: false, - - autoStyles: [], - editMode: false, - selectionMode: false, - selectedChannels: [], - - currentChannelName: null, // if editing, the current channel name - description: null, - website: null, - email: null, - tags: [], - - showOptionalFields: false, - titleFocused: false, - descriptionFocused: false, - websiteFocused: false, - emailFocused: false, - hasReturnedBack: false, - }; - - didFocusListener; - - componentWillMount() { - const { navigation } = this.props; - // this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused); - } - - componentWillUnmount() { - if (this.didFocusListener) { - this.didFocusListener.remove(); - } - DeviceEventEmitter.removeListener('onDocumentPickerFilePicked', this.onFilePicked); - DeviceEventEmitter.removeListener('onDocumentPickerCanceled', this.onPickerCanceled); - } - - componentDidMount() { - this.setState({ - autoStyle: - ChannelIconItem.AUTO_THUMB_STYLES[Math.floor(Math.random() * ChannelIconItem.AUTO_THUMB_STYLES.length)], - }); - - this.onComponentFocused(); - } - - generateAutoStyles = size => { - const { channels = [] } = this.props; - const autoStyles = []; - if (channels) { - for (let i = 0; i < size && i < channels.length; i++) { - // seed generator using the claim_id - const rng = seedrandom(channels[i].permanent_url); // is this efficient? - const index = Math.floor(rng.quick() * ChannelIconItem.AUTO_THUMB_STYLES.length); - autoStyles.push(ChannelIconItem.AUTO_THUMB_STYLES[index]); - } - } - return autoStyles; - }; - - componentWillReceiveProps(nextProps) { - const { - currentRoute: prevRoute, - drawerStack: prevDrawerStack, - popDrawerStack, - setPlayerVisible, - navigation, - notify, - } = this.props; - const { currentRoute, drawerStack, updatingChannel, updateChannelError } = nextProps; - - if (Constants.DRAWER_ROUTE_CHANNEL_CREATOR === currentRoute && currentRoute !== prevRoute) { - this.onComponentFocused(); - } - - if (this.state.updateChannelStarted && !updatingChannel) { - if (updateChannelError && updateChannelError.length > 0) { - notify({ message: `The channel could not be updated: ${updateChannelError}`, error: true }); - } else { - // successful channel update - notify({ message: 'The channel was successfully updated.' }); - this.showChannelList(); - } - } - - if ( - this.state.currentPhase === Constants.PHASE_CREATE && - prevDrawerStack[prevDrawerStack.length - 1].route === Constants.DRAWER_ROUTE_CHANNEL_CREATOR_FORM && - drawerStack[drawerStack.length - 1].route === Constants.DRAWER_ROUTE_CHANNEL_CREATOR - ) { - // navigated back from the form - this.setState({ currentPhase: Constants.PHASE_LIST }); - if (!this.state.hasReturnedBack && this.state.returnUrl) { - this.setState({ hasReturnedBack: true }, () => { - navigateBack(navigation, drawerStack, popDrawerStack, setPlayerVisible); - }); - } - } - } - - onComponentFocused = () => { - const { - balance, - channels, - channelName, - fetchChannelListMine, - fetchClaimListMine, - fetchingChannels, - navigation, - pushDrawerStack, - setPlayerVisible, - hasFormState, - } = this.props; - - NativeModules.Firebase.setCurrentScreen('Channels').then(result => { - pushDrawerStack(Constants.DRAWER_ROUTE_CHANNEL_CREATOR, navigation.state.params ? navigation.state.params : null); - setPlayerVisible(); - fetchChannelListMine(); - - DeviceEventEmitter.addListener('onDocumentPickerFilePicked', this.onFilePicked); - DeviceEventEmitter.addListener('onDocumentPickerCanceled', this.onPickerCanceled); - - let isEditMode = false; - if (navigation.state.params) { - const { editChannelUrl, displayForm, returnUrl } = navigation.state.params; - if (editChannelUrl) { - isEditMode = true; - this.setState({ editChannelUrl, currentPhase: Constants.PHASE_CREATE }); - } - this.setState({ returnUrl }); - } - - if (!isEditMode && hasFormState) { - this.loadPendingFormState(); - } - this.setState({ currentPhase: isEditMode || hasFormState ? Constants.PHASE_CREATE : Constants.PHASE_LIST }); - }); - }; - - handleModePressed = () => { - this.setState({ showOptionalFields: !this.state.showOptionalFields }); - }; - - onFilePicked = evt => { - const { notify, updateChannelFormState } = this.props; - - if (evt.path && evt.path.length > 0) { - // check which image we're trying to upload - // should only be one or the other, so just default to cover - const isCover = this.state.coverImagePickerOpen; - const fileUrl = `file://${evt.path}`; - - // set the path to local url first, before uploading - if (isCover) { - this.setState({ coverImageUrl: fileUrl }); - } else { - this.setState({ thumbnailUrl: fileUrl }); - } - - this.setState( - { - uploadingImage: true, - avatarImagePickerOpen: false, - coverImagePickerOpen: false, - }, - () => { - uploadImageAsset( - fileUrl, - ({ url }) => { - if (isCover) { - updateChannelFormState({ coverImageUrl: url }); - this.setState({ coverImageUrl: url, uploadingImage: false }); - } else { - updateChannelFormState({ thumbnailUrl: url }); - this.setState({ thumbnailUrl: url, uploadingImage: false }); - } - }, - error => { - notify({ message: `The image could not be uploaded: ${error}` }); - this.setState({ uploadingImage: false }); - }, - ); - }, - ); - } else { - // could not determine the file path - notify({ message: 'We could not use the selected image. Please try a different image.' }); - } - }; - - onPickerCanceled = () => { - this.setState({ avatarImagePickerOpen: false, coverImagePickerOpen: false }); - }; - - componentDidUpdate() { - const { channels = [] } = this.props; - const { editChannelUrl } = this.state; - if (channels && channels.length > 0) { - if (this.state.autoStyles.length !== channels.length) { - this.setState({ - autoStyles: this.generateAutoStyles(channels.length), - }); - } - - if (editChannelUrl) { - this.setState({ editChannelUrl: null }, () => { - let channelToEdit = null; - for (let i = 0; i < channels.length; i++) { - if (editChannelUrl === channels[i].permanent_url) { - this.prepareEdit(channels[i]); - return; - } - } - }); - } - } - } - - handleCreateCancel = () => { - const { clearChannelFormState } = this.props; - clearChannelFormState(); // explicitly clear state on cancel? - this.setState({ showCreateChannel: false, newChannelName: '', newChannelBid: 0.01 }); - }; - - handlePickerValueChange = (itemValue, itemIndex) => { - if (Constants.ITEM_CREATE_A_CHANNEL === itemValue) { - this.setState({ showCreateChannel: true }); - } else { - this.handleCreateCancel(); - this.handleChannelChange(Constants.ITEM_ANONYMOUS === itemValue ? CLAIM_VALUES.CHANNEL_ANONYMOUS : itemValue); - } - this.setState({ currentSelectedValue: itemValue }); - }; - - handleChannelChange = value => { - const { onChannelChange } = this.props; - const { newChannelBid } = this.state; - const channel = value; - - if (channel === CLAIM_VALUES.CHANNEL_NEW) { - this.setState({ addingChannel: true }); - if (onChannelChange) { - onChannelChange(value); - } - this.handleNewChannelBidChange(newChannelBid); - } else { - this.setState({ addingChannel: false }); - if (onChannelChange) { - onChannelChange(value); - } - } - }; - - handleDescriptionChange = value => { - const { updateChannelFormState } = this.props; - updateChannelFormState({ description: value }); - this.setState({ description: value }); - }; - - handleWebsiteChange = value => { - const { updateChannelFormState } = this.props; - updateChannelFormState({ website: value }); - this.setState({ website: value }); - }; - - handleEmailChange = value => { - const { updateChannelFormState } = this.props; - updateChannelFormState({ email: value }); - this.setState({ email: value }); - }; - - handleNewChannelTitleChange = value => { - const { updateChannelFormState } = this.props; - updateChannelFormState({ newChannelTitle: value }); - this.setState({ newChannelTitle: value }); - if (value && !this.state.editMode && !this.state.channelNameUserEdited) { - // build the channel name based on the title - const channelName = value - .replace(new RegExp(regexInvalidURI.source, regexInvalidURI.flags + 'g'), '') - .toLowerCase(); - this.handleNewChannelNameChange(channelName, false); - } - }; - - handleNewChannelNameChange = (value, userInput) => { - const { notify, updateChannelFormState } = this.props; - - let newChannelName = value, - newChannelNameError = ''; - - if (newChannelName.startsWith('@')) { - newChannelName = newChannelName.slice(1); - } - - if (newChannelName.trim().length > 0 && !isNameValid(newChannelName)) { - newChannelNameError = 'Your channel name contains invalid characters.'; - } else if (this.channelExists(newChannelName)) { - newChannelNameError = 'You have already created a channel with the same name.'; - } - - if (userInput) { - this.setState({ channelNameUserEdited: true }); - } - - updateChannelFormState({ newChannelName }); - this.setState({ - newChannelName, - newChannelNameError, - }); - }; - - handleNewChannelBidChange = newChannelBid => { - const { balance, notify, updateChannelFormState } = this.props; - let newChannelBidError; - if (newChannelBid <= 0) { - newChannelBidError = __('Please enter a deposit above 0'); - } else if (newChannelBid === balance) { - newChannelBidError = __('Please decrease your deposit to account for transaction fees'); - } else if (newChannelBid > balance) { - newChannelBidError = __('Deposit cannot be higher than your balance'); - } - - notify({ message: newChannelBidError }); - updateChannelFormState({ newChannelBid }); - this.setState({ - newChannelBid, - newChannelBidError, - }); - }; - - handleCreateChannelClick = () => { - const { - balance, - clearChannelFormState, - createChannel, - onChannelChange, - getSync, - notify, - updateChannel, - } = this.props; - const { - claimId, - coverImageUrl, - currentChannelName, - editMode, - newChannelBid, - newChannelName, - newChannelTitle, - description, - email, - tags, - thumbnailUrl, - website, - } = this.state; - - if (balance < Constants.MINIMUM_TRANSACTION_BALANCE) { - notify({ - message: 'Creating a channel requires credits. Press the blue bar to get some for free.', - }); - if (this.scrollView) { - this.scrollView.scrollTo({ x: 0, y: 0, animated: true }); - } - return; - } - - if (newChannelName.trim().length === 0 || !isNameValid(newChannelName.substr(1), false)) { - notify({ message: 'Your channel name contains invalid characters.' }); - return; - } - - if (email && email.trim().length > 0 && (email.indexOf('@') === -1 || email.indexOf('.') === -1)) { - notify({ message: 'Please provide a valid email address.' }); - return; - } - - // shouldn't do this check in edit mode - if ( - (editMode && currentChannelName !== newChannelName && this.channelExists(newChannelName)) || - (!editMode && this.channelExists(newChannelName)) - ) { - // TODO: boolean check improvement? - notify({ message: 'You have already created a channel with the same name.' }); - return; - } - - if (newChannelBid > balance) { - notify({ message: 'Deposit cannot be higher than your balance' }); - return; - } - - const channelName = `@${newChannelName}`; - - this.setState({ - createChannelError: undefined, - }); - - const success = channelClaim => { - this.setState({ - creatingChannel: false, - addingChannel: false, - currentSelectedValue: channelName, - showCreateChannel: false, - }); - - if (onChannelChange) { - onChannelChange(channelName); - } - - // reset state and go back to the channel list - clearChannelFormState(); - notify({ message: 'The channel was successfully created.' }); - this.showChannelList(); - - logPublish(channelClaim); - }; - - const failure = () => { - notify({ message: 'Unable to create channel due to an internal error.' }); - this.setState({ - creatingChannel: false, - }); - }; - - const optionalParams = { - title: newChannelTitle, - description, - email, - tags: tags.map(tag => { - return { name: tag }; - }), - website, - coverUrl: coverImageUrl, - thumbnailUrl: thumbnailUrl, - }; - - if (this.state.editMode) { - // updateChannel - // TODO: Change updateChannel in lby-redux to match createChannel with success and failure callbacks? - const params = Object.assign( - {}, - { - claim_id: claimId, - amount: newChannelBid, - }, - optionalParams, - ); - this.setState({ updateChannelStarted: true }, () => updateChannel(params)); - } else { - this.setState({ creatingChannel: true }, () => - createChannel(channelName, newChannelBid, optionalParams).then(success, failure), - ); - } - }; - - channelExists = name => { - const { channels = [] } = this.props; - if (channels) { - for (let channel of channels) { - if ( - name.toLowerCase() === channel.name.toLowerCase() || - `@${name}`.toLowerCase() === channel.name.toLowerCase() - ) { - return true; - } - } - } - - return false; - }; - - onCoverImagePress = () => { - const { notify } = this.props; - if (this.state.uploadingImage) { - notify({ message: 'There is an image upload in progress. Please wait for the upload to complete.' }); - return; - } - - this.setState( - { - avatarImagePickerOpen: false, - coverImagePickerOpen: true, - }, - () => this.checkStoragePermission(), - ); - }; - - onAvatarImagePress = () => { - const { notify } = this.props; - if (this.state.uploadingImage) { - notify({ message: 'There is an image upload in progress. Please wait for the upload to complete.' }); - return; - } - - this.setState( - { - avatarImagePickerOpen: true, - coverImagePickerOpen: false, - }, - () => this.checkStoragePermission(), - ); - }; - - handleNewChannelPress = () => { - const { pushDrawerStack } = this.props; - pushDrawerStack(Constants.DRAWER_ROUTE_CHANNEL_CREATOR_FORM); - this.setState({ currentPhase: Constants.PHASE_CREATE }); - }; - - handleCreateCancel = () => { - this.showChannelList(); - }; - - showChannelList = () => { - const { drawerStack, popDrawerStack } = this.props; - if (drawerStack[drawerStack.length - 1].route === Constants.DRAWER_ROUTE_CHANNEL_CREATOR_FORM) { - popDrawerStack(); - } - this.setState({ currentPhase: Constants.PHASE_LIST }); - this.resetChannelCreator(); - }; - - resetChannelCreator = () => { - this.setState({ - canSave: true, - claimId: null, - editMode: false, - displayName: null, - channelNameUserEdited: false, - newChannelTitle: '', - newChannelName: '', - newChannelBid: 0.01, - addingChannel: false, - creatingChannel: false, - newChannelNameError: '', - newChannelBidError: '', - createChannelError: undefined, - showCreateChannel: false, - thumbnailUrl: '', - coverImageUrl: '', - avatarImagePickerOpen: false, - coverImagePickerOpen: false, - - currentChannelName: null, - description: null, - email: null, - tags: [], - website: null, - - showOptionalFields: false, - titleFocused: false, - descriptionFocused: false, - websiteFocused: false, - emailFocused: false, - uploadingImage: false, - }); - }; - - onExitSelectionMode = () => { - this.setState({ selectionMode: false, selectedChannels: [] }); - }; - - onEditActionPressed = () => { - const { navigation } = this.props; - const { selectedChannels } = this.state; - - // only 1 item can be edited (and edit button should be visible only if there is a single selection) - const channel = selectedChannels[0]; - this.onExitSelectionMode(); - - this.prepareEdit(channel); - }; - - loadPendingFormState = () => { - const { channelFormState } = this.props; - const showOptionalFields = - channelFormState.description || channelFormState.website || channelFormState.email || channelFormState.tags; - this.setState({ ...channelFormState, showOptionalFields }); - }; - - prepareEdit = channel => { - const { balance, pushDrawerStack } = this.props; - const { value } = channel; - - pushDrawerStack(Constants.DRAWER_ROUTE_CHANNEL_CREATOR_FORM); - this.setState({ - canSave: true, - claimId: channel.claim_id, - currentPhase: Constants.PHASE_CREATE, - displayName: value && value.title ? value.title : channel.name.substring(1), - editMode: true, - coverImageUrl: value && value.cover ? value.cover.url : '', - currentChannelName: channel.name.substring(1), - newChannelName: channel.name.substring(1), - newChannelTitle: value ? value.title : null, - newChannelBid: channel.amount, - description: value ? value.description : null, - email: value ? value.email : null, - website: value ? value.website_url : null, - tags: value && value.tags ? value.tags : [], - thumbnailUrl: value && value.thumbnail ? value.thumbnail.url : '', - showOptionalFields: value && (value.description || value.email || value.website_url || value.tags), - }); - }; - - onDeleteActionPressed = () => { - const { abandonClaim, fetchChannelListMine } = this.props; - const { selectedChannels } = this.state; - - // show confirm alert - Alert.alert( - __('Delete channels'), - __('Are you sure you want to delete the selected channels?'), - [ - { text: __('No') }, - { - text: __('Yes'), - onPress: () => { - selectedChannels.forEach(channel => { - const { txid, nout } = channel; - abandonClaim(txid, nout); - }); - - // re-fetch the channel list - fetchChannelListMine(); - this.onExitSelectionMode(); - }, - }, - ], - { cancelable: true }, - ); - }; - - handleAddTag = tag => { - if (!tag || !this.state.canSave || this.state.creatingChannel) { - return; - } - - const { notify, updateChannelFormState } = this.props; - const { tags } = this.state; - const index = tags.indexOf(tag.toLowerCase()); - if (index === -1) { - const newTags = tags.slice(); - newTags.push(tag); - updateChannelFormState({ tags: newTags }); - this.setState({ tags: newTags }); - } else { - notify({ message: __(`You already added the "${tag}" tag.`) }); - } - }; - - handleRemoveTag = tag => { - if (!tag || !this.state.canSave || this.state.creatingChannel) { - return; - } - - const { updateChannelFormState } = this.props; - const newTags = this.state.tags.slice(); - const index = newTags.indexOf(tag.toLowerCase()); - - if (index > -1) { - newTags.splice(index, 1); - updateChannelFormState({ tags: newTags }); - this.setState({ tags: newTags }); - } - }; - - selectedChannelIndex = channel => { - const { selectedChannels } = this.state; - for (let i = 0; i < selectedChannels.length; i++) { - if (selectedChannels[i].claim_id === channel.claim_id) { - return i; - } - } - - return -1; - }; - - addOrRemoveItem = channel => { - let selectedChannels = [...this.state.selectedChannels]; - const index = this.selectedChannelIndex(channel); - - if (index > -1) { - selectedChannels.splice(index, 1); - } else { - selectedChannels.push(channel); - } - - this.setState({ selectionMode: selectedChannels.length > 0, selectedChannels }); - }; - - handleChannelListItemPress = channel => { - const { navigation } = this.props; - const { selectionMode } = this.state; - if (selectionMode) { - this.addOrRemoveItem(channel); - } else { - navigateToUri(navigation, channel.permanent_url); - } - }; - - handleChannelListItemLongPress = channel => { - this.addOrRemoveItem(channel); - }; - - checkStoragePermission = () => { - // check if we the permission to write to external storage has been granted - NativeModules.UtilityModule.canReadWriteStorage().then(canReadWrite => { - if (!canReadWrite) { - // request permission - NativeModules.UtilityModule.requestStoragePermission(); - } else { - NativeModules.UtilityModule.openDocumentPicker('image/*'); - } - }); - }; - - handleStoragePermissionGranted = () => { - // update the configured download folder - NativeModules.UtilityModule.getDownloadDirectory().then(downloadDirectory => { - Lbry.settings_set({ - key: 'download_dir', - value: downloadDirectory, - }) - .then(() => {}) - .catch(() => {}); - }); - - // open picker for images - NativeModules.UtilityModule.openDocumentPicker('image/*'); - }; - - handleStoragePermissionRefused = () => { - const { notify } = this.props; - notify({ - message: __('Pictures from your device cannot be used because the permission to read storage was not granted.'), - isError: true, - }); - this.setState({ avatarImagePickerOpen: false, coverImagePickerOpen: false }); - }; - - render() { - const { - abandoningClaimIds, - balance, - fetchingChannels, - sdkReady, - updatingChannel, - channels = [], - navigation, - } = this.props; - const { - autoStyle, - autoStyles, - coverImageUrl, - currentPhase, - canSave, - editMode, - newChannelName, - newChannelNameError, - newChannelBid, - newChannelBidError, - creatingChannel, - createChannelError, - addingChannel, - showCreateChannel, - thumbnailUrl, - selectionMode, - selectedChannels, - uploadingImage, - } = this.state; - - const hasChannels = channels && channels.length > 0; - - if (!sdkReady) { - return ( - <View style={channelCreatorStyle.container}> - <UriBar navigation={navigation} /> - <EmptyStateView - message={__( - 'The background service is still initializing. You can still explore and watch content during the initialization process.', - )} - /> - </View> - ); - } - - return ( - <View style={channelCreatorStyle.container}> - <UriBar - allowEdit - navigation={navigation} - selectionMode={selectionMode} - selectedItemCount={selectedChannels.length} - onDeleteActionPressed={this.onDeleteActionPressed} - onEditActionPressed={this.onEditActionPressed} - onExitSelectionMode={this.onExitSelectionMode} - /> - - {fetchingChannels && ( - <View style={channelCreatorStyle.loading}> - <ActivityIndicator size={'large'} color={Colors.NextLbryGreen} /> - </View> - )} - - {currentPhase === Constants.PHASE_LIST && !fetchingChannels && !hasChannels && ( - <EmptyStateView - message={__('You have not created a channel.\nStart now by creating a new channel!')} - buttonText={__('Create a channel')} - onButtonPress={this.handleNewChannelPress} - /> - )} - - {currentPhase === Constants.PHASE_LIST && ( - <FlatList - extraData={this.state} - ListFooterComponent={ - !channels || channels.length === 0 ? null : ( - <View style={channelCreatorStyle.listFooter}> - <Button - style={channelCreatorStyle.createChannelButton} - text={__('Create a channel')} - onPress={this.handleNewChannelPress} - /> - </View> - ) - } - style={channelCreatorStyle.scrollContainer} - contentContainerStyle={channelCreatorStyle.scrollPadding} - initialNumToRender={10} - maxToRenderPerBatch={20} - removeClippedSubviews - renderItem={({ item, index }) => { - const itemAutoStyle = autoStyles.length > index ? autoStyles[index] : autoStyle; /* fallback */ - const value = item.value; - const itemThumbnailUrl = value && value.thumbnail ? value.thumbnail.url : null; - return ( - <TouchableOpacity - style={channelCreatorStyle.channelListItem} - onPress={() => this.handleChannelListItemPress(item)} - onLongPress={() => this.handleChannelListItemLongPress(item)} - > - <View style={[channelCreatorStyle.channelListAvatar, itemAutoStyle]}> - {itemThumbnailUrl && ( - <FastImage - style={channelCreatorStyle.avatarImage} - resizeMode={FastImage.resizeMode.cover} - source={{ uri: itemThumbnailUrl }} - /> - )} - {!itemThumbnailUrl && ( - <Text style={channelIconStyle.autothumbCharacter}>{item.name.substring(1, 2).toUpperCase()}</Text> - )} - </View> - <View style={channelCreatorStyle.channelListDetails}> - {value && value.title && ( - <Text style={channelCreatorStyle.channelListTitle}>{item.value.title}</Text> - )} - <Text style={channelCreatorStyle.channelListName}>{item.name}</Text> - </View> - {this.selectedChannelIndex(item) > -1 && ( - <View style={channelCreatorStyle.selectedOverlay}> - <Icon name={'check-circle'} solid color={Colors.NextLbryGreen} size={32} /> - </View> - )} - </TouchableOpacity> - ); - }} - data={channels ? channels.filter(channel => !abandoningClaimIds.includes(channel.claim_id)) : []} - keyExtractor={(item, index) => item.claim_id} - /> - )} - - {currentPhase === Constants.PHASE_CREATE && ( - <ScrollView ref={ref => (this.scrollView = ref)} style={channelCreatorStyle.createChannelContainer}> - <View style={channelCreatorStyle.imageSelectors}> - <TouchableOpacity style={channelCreatorStyle.coverImageTouchArea} onPress={this.onCoverImagePress}> - <Image - style={channelCreatorStyle.coverImage} - resizeMode={'cover'} - source={ - !!coverImageUrl && coverImageUrl.trim().length > 0 - ? { uri: coverImageUrl } - : require('../../assets/default_channel_cover.png') - } - /> - <View style={channelCreatorStyle.editOverlay}> - <Icon name={'edit'} style={channelCreatorStyle.editIcon} /> - </View> - - {this.state.uploadingImage && ( - <View style={channelCreatorStyle.uploadProgress}> - <ActivityIndicator size={'small'} color={Colors.NextLbryGreen} /> - <Text style={channelCreatorStyle.uploadText}>{__('Uploading image...')}</Text> - </View> - )} - </TouchableOpacity> - - <View style={[channelCreatorStyle.avatarImageContainer, autoStyle]}> - <TouchableOpacity style={channelCreatorStyle.avatarTouchArea} onPress={this.onAvatarImagePress}> - {!!thumbnailUrl && thumbnailUrl.trim().length > 0 && ( - <Image - style={channelCreatorStyle.avatarImage} - resizeMode={'cover'} - source={{ uri: thumbnailUrl }} - /> - )} - {(!!thumbnailUrl || (!!thumbnailUrl && thumbnailUrl.trim().length === 0)) && - newChannelName.length > 0 && ( - <Text style={channelIconStyle.autothumbCharacter}> - {newChannelName.substring(0, 1).toUpperCase()} - </Text> - )} - - <View style={channelCreatorStyle.thumbnailEditOverlay}> - <Icon name={'edit'} style={channelCreatorStyle.editIcon} /> - </View> - </TouchableOpacity> - </View> - </View> - {balance < Constants.MINIMUM_TRANSACTION_BALANCE && <ChannelRewardsDriver navigation={navigation} />} - - <View style={channelCreatorStyle.card}> - <View style={channelCreatorStyle.textInputLayout}> - {(this.state.titleFocused || - (this.state.newChannelTitle != null && this.state.newChannelTitle.trim().length > 0)) && ( - <Text style={channelCreatorStyle.textInputTitle}>{__('Title')}</Text> - )} - <TextInput - editable={canSave && !creatingChannel && !updatingChannel} - style={channelCreatorStyle.inputText} - value={this.state.newChannelTitle} - onChangeText={this.handleNewChannelTitleChange} - placeholder={this.state.titleFocused ? '' : __('Title')} - underlineColorAndroid={Colors.NextLbryGreen} - onFocus={() => this.setState({ titleFocused: true })} - onBlur={() => this.setState({ titleFocused: false })} - /> - </View> - - <View style={channelCreatorStyle.channelInputLayout}> - {(this.state.channelNameFocused || - (this.state.newChannelName != null && this.state.newChannelName.trim().length > 0)) && ( - <Text style={channelCreatorStyle.textInputTitle}>{__('Channel')}</Text> - )} - <View> - <Text style={channelCreatorStyle.channelAt}>@</Text> - <TextInput - editable={canSave && !editMode && !creatingChannel && !updatingChannel} - style={channelCreatorStyle.channelNameInput} - value={this.state.newChannelName} - onChangeText={value => this.handleNewChannelNameChange(value, true)} - placeholder={this.state.channelNameFocused ? '' : __('Channel')} - underlineColorAndroid={Colors.NextLbryGreen} - onFocus={() => this.setState({ channelNameFocused: true })} - onBlur={() => this.setState({ channelNameFocused: false })} - /> - </View> - </View> - {newChannelNameError.length > 0 && ( - <Text style={channelCreatorStyle.inlineError}>{newChannelNameError}</Text> - )} - {editMode && ( - <Text style={channelCreatorStyle.helpText}> - {__('The channel name cannot be changed while editing.')} - </Text> - )} - - <View style={channelCreatorStyle.bidRow}> - <Text style={channelCreatorStyle.label}>{__('Deposit')}</Text> - <TextInput - editable={canSave && !creatingChannel && !updatingChannel} - style={channelCreatorStyle.bidAmountInput} - value={String(newChannelBid)} - onChangeText={this.handleNewChannelBidChange} - onFocus={() => this.setState({ creditsInputFocused: true })} - onBlur={() => this.setState({ creditsInputFocused: false })} - placeholder={'0.00'} - keyboardType={'number-pad'} - underlineColorAndroid={Colors.NextLbryGreen} - /> - <Text style={channelCreatorStyle.currency}>LBC</Text> - <View style={channelCreatorStyle.balance}> - {this.state.creditsInputFocused && <Icon name="coins" size={12} />} - {this.state.creditsInputFocused && ( - <Text style={channelCreatorStyle.balanceText}>{formatCredits(parseFloat(balance), 1, true)}</Text> - )} - </View> - </View> - <Text style={channelCreatorStyle.helpText}> - {__('This LBC remains yours. It is a deposit to reserve the name and can be undone at any time.')} - </Text> - </View> - - {this.state.showOptionalFields && ( - <View style={channelCreatorStyle.card}> - <View style={channelCreatorStyle.textInputLayout}> - {(this.state.descriptionFocused || - (this.state.description != null && this.state.description.trim().length > 0)) && ( - <Text style={channelCreatorStyle.textInputTitle}>{__('Description')}</Text> - )} - <TextInput - editable={canSave && !creatingChannel && !updatingChannel} - style={channelCreatorStyle.inputText} - multiline - value={this.state.description} - onChangeText={this.handleDescriptionChange} - placeholder={this.state.descriptionFocused ? '' : __('Description')} - underlineColorAndroid={Colors.NextLbryGreen} - onFocus={() => this.setState({ descriptionFocused: true })} - onBlur={() => this.setState({ descriptionFocused: false })} - /> - </View> - - <View style={channelCreatorStyle.textInputLayout}> - {(this.state.websiteFocused || - (this.state.website != null && this.state.website.trim().length > 0)) && ( - <Text style={channelCreatorStyle.textInputTitle}>{__('Website')}</Text> - )} - <TextInput - editable={canSave && !creatingChannel && !updatingChannel} - style={channelCreatorStyle.inputText} - value={this.state.website} - onChangeText={this.handleWebsiteChange} - placeholder={this.state.websiteFocused ? '' : __('Website')} - underlineColorAndroid={Colors.NextLbryGreen} - onFocus={() => this.setState({ websiteFocused: true })} - onBlur={() => this.setState({ websiteFocused: false })} - /> - </View> - - <View style={channelCreatorStyle.textInputLayout}> - {(this.state.emailFocused || (this.state.email != null && this.state.email.trim().length > 0)) && ( - <Text style={channelCreatorStyle.textInputTitle}>{__('Email')}</Text> - )} - <TextInput - editable={canSave && !creatingChannel && !updatingChannel} - style={channelCreatorStyle.inputText} - value={this.state.email} - onChangeText={this.handleEmailChange} - placeholder={this.state.emailFocused ? '' : __('Email')} - underlineColorAndroid={Colors.NextLbryGreen} - onFocus={() => this.setState({ emailFocused: true })} - onBlur={() => this.setState({ emailFocused: false })} - /> - </View> - </View> - )} - - {this.state.showOptionalFields && ( - <View style={channelCreatorStyle.card}> - <Text style={channelCreatorStyle.cardTitle}>{__('Tags')}</Text> - <View style={channelCreatorStyle.tagList}> - {this.state.tags && - this.state.tags.map(tag => ( - <Tag - key={tag} - name={tag} - type={'remove'} - style={channelCreatorStyle.tag} - onRemovePress={this.handleRemoveTag} - /> - ))} - </View> - <TagSearch - editable={canSave && !creatingChannel && !updatingChannel} - handleAddTag={this.handleAddTag} - selectedTags={this.state.tags} - showNsfwTags - /> - </View> - )} - - <View style={channelCreatorStyle.toggleContainer}> - <Link - text={this.state.showOptionalFields ? __('Hide optional fields') : __('Show optional fields')} - onPress={this.handleModePressed} - style={channelCreatorStyle.modeLink} - /> - </View> - - <View style={channelCreatorStyle.buttonContainer}> - {(creatingChannel || updatingChannel) && ( - <ActivityIndicator size={'small'} color={Colors.NextLbryGreen} /> - )} - {!creatingChannel && !updatingChannel && ( - <View style={channelCreatorStyle.buttons}> - <Link style={channelCreatorStyle.cancelLink} text={__('Cancel')} onPress={this.handleCreateCancel} /> - <Button - style={channelCreatorStyle.createButton} - disabled={!canSave || uploadingImage} - text={editMode ? __('Update') : __('Create')} - onPress={this.handleCreateChannelClick} - /> - </View> - )} - </View> - </ScrollView> - )} - - {Constants.PHASE_CREATE !== this.state.currentPhase && <FloatingWalletBalance navigation={navigation} />} - </View> - ); - } -} diff --git a/src/page/discover/index.js b/src/page/discover/index.js index 6af8574..728c702 100644 --- a/src/page/discover/index.js +++ b/src/page/discover/index.js @@ -1,5 +1,12 @@ import { connect } from 'react-redux'; -import { doClaimSearch, doFileList, selectBalance, selectFileInfosDownloaded, selectFollowedTags } from 'lbry-redux'; +import { + doClaimSearch, + doFileList, + selectBalance, + selectFileInfosDownloaded, + selectLastClaimSearchUris, + selectFollowedTags, +} from 'lbry-redux'; import { doFetchFeaturedUris, doFetchRewardedContent, @@ -11,9 +18,9 @@ import { selectSubscriptionClaims, selectUnreadSubscriptions, } from 'lbryinc'; -import { doPushDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer'; -import { doSetClientSetting, doSetSortByItem, doSetTimeItem } from 'redux/actions/settings'; -import { makeSelectClientSetting, selectSdkReady, selectSortByItem, selectTimeItem } from 'redux/selectors/settings'; + +import { doSetClientSetting } from 'redux/actions/settings'; +import { makeSelectClientSetting } from 'redux/selectors/settings'; import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api import DiscoverPage from './view'; @@ -27,10 +34,8 @@ const select = state => ({ followedTags: selectFollowedTags(state), ratingReminderDisabled: makeSelectClientSetting(Constants.SETTING_RATING_REMINDER_DISABLED)(state), ratingReminderLastShown: makeSelectClientSetting(Constants.SETTING_RATING_REMINDER_LAST_SHOWN)(state), - sdkReady: selectSdkReady(state), - sortByItem: selectSortByItem(state), - timeItem: selectTimeItem(state), unreadSubscriptions: selectUnreadSubscriptions(state), + uris: selectLastClaimSearchUris(state), }); const perform = dispatch => ({ @@ -39,12 +44,11 @@ const perform = dispatch => ({ fetchRewardedContent: () => dispatch(doFetchRewardedContent()), fetchSubscriptions: () => dispatch(doFetchMySubscriptions()), fileList: () => dispatch(doFileList()), - pushDrawerStack: () => dispatch(doPushDrawerStack(Constants.DRAWER_ROUTE_DISCOVER)), removeUnreadSubscriptions: () => dispatch(doRemoveUnreadSubscriptions()), setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)), - setPlayerVisible: () => dispatch(doSetPlayerVisible(false)), - setSortByItem: item => dispatch(doSetSortByItem(item)), - setTimeItem: item => dispatch(doSetTimeItem(item)), }); -export default connect(select, perform)(DiscoverPage); +export default connect( + select, + perform +)(DiscoverPage); diff --git a/src/page/discover/view.js b/src/page/discover/view.js index a707619..8a0c737 100644 --- a/src/page/discover/view.js +++ b/src/page/discover/view.js @@ -11,9 +11,10 @@ import { View, } from 'react-native'; import { DEFAULT_FOLLOWED_TAGS, Lbry, normalizeURI, parseURI } from 'lbry-redux'; -import { formatTagTitle, getOrderBy } from 'utils/helper'; +import { __, formatTagTitle } from 'utils/helper'; import AsyncStorage from '@react-native-community/async-storage'; import moment from 'moment'; +import CategoryList from 'component/categoryList'; import ClaimList from 'component/claimList'; import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api import Colors from 'styles/colors'; @@ -23,65 +24,69 @@ import Icon from 'react-native-vector-icons/FontAwesome5'; import Link from 'component/link'; import ModalTagSelector from 'component/modalTagSelector'; import ModalPicker from 'component/modalPicker'; -import SdkLoadingStatus from 'component/sdkLoadingStatus'; import UriBar from 'component/uriBar'; import _ from 'lodash'; class DiscoverPage extends React.PureComponent { state = { tagCollection: [], - remainingTags: [], showModalTagSelector: false, showSortPicker: false, - showTimePicker: false, orderBy: Constants.DEFAULT_ORDER_BY, + currentSortByItem: Constants.CLAIM_SEARCH_SORT_BY_ITEMS[0], }; componentDidMount() { - const { sortByItem, fetchRewardedContent, fileList, followedTags } = this.props; + // Track the total time taken if this is the first launch + AsyncStorage.getItem('firstLaunchTime').then(startTime => { + if (startTime !== null && !isNaN(parseInt(startTime, 10))) { + // We don't need this value anymore once we've retrieved it + AsyncStorage.removeItem('firstLaunchTime'); + + // We know this is the first app launch because firstLaunchTime is set and it"s a valid number + const start = parseInt(startTime, 10); + const now = moment().unix(); + const delta = now - start; + AsyncStorage.getItem('firstLaunchSuspended').then(suspended => { + AsyncStorage.removeItem('firstLaunchSuspended'); + const appSuspended = suspended === 'true'; + if (NativeModules.Firebase) { + NativeModules.Firebase.track('first_run_time', { + total_seconds: delta, + app_suspended: appSuspended, + }); + } + }); + } + }); + + const { fetchRewardedContent, fetchSubscriptions, fileList, followedTags } = this.props; this.buildTagCollection(followedTags); fetchRewardedContent(); + fetchSubscriptions(); fileList(); - this.handleSortByItemSelected(sortByItem); this.showRatingReminder(); - - this.onComponentFocused(); } - componentWillReceiveProps(nextProps) { - const { currentRoute: prevRoute, followedTags: prevFollowedTags } = this.props; - const { currentRoute, followedTags } = nextProps; - - if (Constants.DRAWER_ROUTE_DISCOVER === currentRoute && currentRoute !== prevRoute) { - this.onComponentFocused(); - } - - if (!_.isEqual(followedTags, prevFollowedTags)) { - this.buildTagCollection(followedTags); - } - } - - onComponentFocused = () => { - const { pushDrawerStack, setPlayerVisible, currentRoute } = this.props; - pushDrawerStack(); - - NativeModules.Firebase.setCurrentScreen('Your tags'); - setPlayerVisible(); - }; - handleSortByItemSelected = item => { - const { setSortByItem } = this.props; - setSortByItem(item); - const orderBy = getOrderBy(item); - this.setState({ orderBy, showSortPicker: false }); - }; + let orderBy = []; + switch (item.name) { + case Constants.SORT_BY_HOT: + orderBy = Constants.DEFAULT_ORDER_BY; + break; - handleTimeItemSelected = item => { - const { setTimeItem } = this.props; - setTimeItem(item); - this.setState({ showTimePicker: false }); + case Constants.SORT_BY_NEW: + orderBy = ['release_time']; + break; + + case Constants.SORT_BY_TOP: + orderBy = ['effective_amount']; + break; + } + + this.setState({ currentSortByItem: item, orderBy, showSortPicker: false }); }; subscriptionForUri = (uri, channelName) => { @@ -101,6 +106,59 @@ class DiscoverPage extends React.PureComponent { return null; }; + componentWillReceiveProps(nextProps) { + const { followedTags: prevFollowedTags } = this.props; + const { followedTags } = nextProps; + if (!_.isEqual(followedTags, prevFollowedTags)) { + this.buildTagCollection(followedTags); + } + } + + componentDidUpdate(prevProps, prevState) { + const { unreadSubscriptions, enabledChannelNotifications } = this.props; + + const utility = NativeModules.UtilityModule; + if (utility) { + const hasUnread = + prevProps.unreadSubscriptions && + prevProps.unreadSubscriptions.length !== unreadSubscriptions.length && + unreadSubscriptions.length > 0; + + if (hasUnread) { + unreadSubscriptions.map(({ channel, uris }) => { + const { claimName: channelName } = parseURI(channel); + + // check if notifications are enabled for the channel + if (enabledChannelNotifications.indexOf(channelName) > -1) { + uris.forEach(uri => { + Lbry.resolve({ urls: uri }).then(result => { + const sub = result[uri].claim; + if (sub && sub.value && sub.value.stream) { + let isPlayable = false; + const source = sub.value.stream.source; + const metadata = sub.value.stream.metadata; + if (source) { + isPlayable = + source.contentType && ['audio', 'video'].indexOf(source.contentType.substring(0, 5)) > -1; + } + if (metadata) { + utility.showNotificationForContent( + uri, + metadata.title, + channelName, + metadata.thumbnail, + isPlayable + ); + } + } + }); + }); + } + }); + } + } + } + showRatingReminder = () => { const { ratingReminderDisabled, ratingReminderLastShown, setClientSetting } = this.props; @@ -113,25 +171,23 @@ class DiscoverPage extends React.PureComponent { if (!isNaN(lastShownTime) && !isNaN(lastShownCount)) { if (now > lastShownTime + Constants.RATING_REMINDER_INTERVAL * lastShownCount) { Alert.alert( - __('Enjoying LBRY?'), - __( - 'Are you enjoying your experience with the LBRY app? You can leave a review for us on the Play Store.', - ), + 'Enjoying LBRY?', + 'Are you enjoying your experience with the LBRY app? You can leave a review for us on the Play Store.', [ { - text: __('Never ask again'), + text: 'Never ask again', onPress: () => setClientSetting(Constants.SETTING_RATING_REMINDER_DISABLED, 'true'), }, - { text: __('Maybe later'), onPress: () => this.updateRatingReminderShown(lastShownCount) }, + { text: 'Maybe later', onPress: () => this.updateRatingReminderShown(lastShownCount) }, { - text: __('Rate app'), + text: 'Rate app', onPress: () => { setClientSetting(Constants.SETTING_RATING_REMINDER_DISABLED, 'true'); Linking.openURL(Constants.PLAY_STORE_URL); }, }, ], - { cancelable: false }, + { cancelable: false } ); } } @@ -151,7 +207,7 @@ class DiscoverPage extends React.PureComponent { buildSections = () => { return this.state.tagCollection.map(tags => ({ - title: tags.length === 1 ? tags[0] : __('All tags you follow'), + title: tags.length === 1 ? tags[0] : 'All tags you follow', data: [tags], })); }; @@ -161,138 +217,81 @@ class DiscoverPage extends React.PureComponent { // each of the followed tags const tagCollection = _.shuffle(tags) - .slice(0, 5) + .slice(0, 6) .map(tag => [tag]); - - const usedTags = tagCollection.map(tagList => tagList[0]); - const remainingTags = tags.filter(tag => !usedTags.includes(tag)); - // everything tagCollection.unshift(tags); - this.setState({ remainingTags, tagCollection }); + this.setState({ tagCollection }); }; handleTagPress = name => { - const { navigation, sortByItem } = this.props; - if (name.toLowerCase() !== __('all tags you follow')) { - navigation.navigate({ - routeName: Constants.DRAWER_ROUTE_TAG, - key: `tagPage`, - params: { - tag: name, - }, - }); + const { navigation } = this.props; + if (name.toLowerCase() !== 'trending') { + navigation.navigate({ routeName: Constants.DRAWER_ROUTE_TAG, key: `tagPage`, params: { tag: name } }); } else { // navigate to the trending page - navigation.navigate({ routeName: Constants.DRAWER_ROUTE_TRENDING, params: { filterForTags: true } }); + navigation.navigate({ routeName: Constants.FULL_ROUTE_NAME_TRENDING }); } }; - sectionListHeader = () => { - const { sortByItem, timeItem } = this.props; - return ( - <View style={discoverStyle.listHeader}> - <View style={discoverStyle.titleRow}> - <Text style={discoverStyle.pageTitle}>{__('Your Tags')}</Text> - </View> - <View style={discoverStyle.pickerRow}> - <View style={discoverStyle.leftPickerRow}> - <TouchableOpacity style={discoverStyle.tagSortBy} onPress={() => this.setState({ showSortPicker: true })}> - <Text style={discoverStyle.tagSortText}>{__(sortByItem.label.split(' ')[0])}</Text> - <Icon style={discoverStyle.tagSortIcon} name={'sort-down'} size={14} /> - </TouchableOpacity> - - {Constants.SORT_BY_TOP === sortByItem.name && ( - <TouchableOpacity style={discoverStyle.tagTime} onPress={() => this.setState({ showTimePicker: true })}> - <Text style={discoverStyle.tagSortText}>{__(timeItem.label)}</Text> - <Icon style={discoverStyle.tagSortIcon} name={'sort-down'} size={14} /> - </TouchableOpacity> - )} - </View> - - <Link - style={discoverStyle.customizeLink} - text={__('Customize')} - onPress={() => this.setState({ showModalTagSelector: true })} - /> - </View> - </View> - ); - }; - - sectionListFooter = () => { - const { remainingTags } = this.state; - if (remainingTags.length === 0) { - return null; - } - - return ( - <View style={discoverStyle.footer}> - <Text style={discoverStyle.footerTitle}>{__('More tags you follow')}</Text> - <View style={discoverStyle.footerTags}> - {remainingTags.map(tag => ( - <Text - key={tag} - style={[discoverStyle.categoryName, discoverStyle.footerTag]} - onPress={() => this.handleTagPress(tag)} - > - {formatTagTitle(tag)} - </Text> - ))} - </View> - </View> - ); - }; - - renderSectionListItem = ({ item, index, section }) => ( - <ClaimList - key={item.sort().join(',')} - orderBy={this.state.orderBy} - time={this.props.timeItem.name} - tags={item} - morePlaceholder - navigation={this.props.navigation} - orientation={Constants.ORIENTATION_HORIZONTAL} - /> - ); - - renderSectionHeader = ({ section: { title } }) => ( - <View style={discoverStyle.categoryTitleRow}> - <Text style={discoverStyle.categoryName} onPress={() => this.handleTagPress(title)}> - {formatTagTitle(title)} - </Text> - <TouchableOpacity onPress={() => this.handleTagPress(title)}> - <Icon name={'angle-double-down'} size={16} /> - </TouchableOpacity> - </View> - ); - render() { - const { currentRoute, navigation, sdkReady, sortByItem, timeItem } = this.props; - const { showModalTagSelector, showSortPicker, showTimePicker } = this.state; + const { navigation } = this.props; + const { currentSortByItem, orderBy, showModalTagSelector, showSortPicker } = this.state; return ( <View style={discoverStyle.container}> <UriBar navigation={navigation} belowOverlay={showModalTagSelector} /> - {currentRoute !== Constants.ROUTE_FILE && currentRoute !== Constants.DRAWER_ROUTE_FILE_VIEW && ( - <SectionList - ListHeaderComponent={this.sectionListHeader} - ListFooterComponent={this.sectionListFooter} - style={discoverStyle.scrollContainer} - contentContainerStyle={discoverStyle.scrollPadding} - initialNumToRender={4} - maxToRenderPerBatch={4} - removeClippedSubviews - renderItem={this.renderSectionListItem} - renderSectionHeader={this.renderSectionHeader} - sections={this.buildSections()} - keyExtractor={(item, index) => item} - /> - )} - {sdkReady && !showModalTagSelector && !showSortPicker && !showTimePicker && ( - <FloatingWalletBalance navigation={navigation} /> - )} + <SectionList + ListHeaderComponent={ + <View style={discoverStyle.titleRow}> + <Text style={discoverStyle.pageTitle}>Explore</Text> + <View style={discoverStyle.rightTitleRow}> + <Link + style={discoverStyle.customizeLink} + text={'Customize'} + onPress={() => this.setState({ showModalTagSelector: true })} + /> + <TouchableOpacity + style={discoverStyle.tagSortBy} + onPress={() => this.setState({ showSortPicker: true })} + > + <Text style={discoverStyle.tagSortText}>{currentSortByItem.label.split(' ')[0]}</Text> + <Icon style={discoverStyle.tagSortIcon} name={'sort-down'} size={14} /> + </TouchableOpacity> + </View> + </View> + } + style={discoverStyle.scrollContainer} + contentContainerStyle={discoverStyle.scrollPadding} + initialNumToRender={4} + maxToRenderPerBatch={4} + removeClippedSubviews + renderItem={({ item, index, section }) => ( + <ClaimList + key={item.sort().join(',')} + orderBy={orderBy} + time={Constants.TIME_WEEK} + tags={item} + morePlaceholder + navigation={navigation} + orientation={Constants.ORIENTATION_HORIZONTAL} + /> + )} + renderSectionHeader={({ section: { title } }) => ( + <View style={discoverStyle.categoryTitleRow}> + <Text style={discoverStyle.categoryName} onPress={() => this.handleTagPress(title)}> + {formatTagTitle(title)} + </Text> + <TouchableOpacity onPress={() => this.handleTagPress(title)}> + <Icon name={'angle-double-down'} size={16} /> + </TouchableOpacity> + </View> + )} + sections={this.buildSections()} + keyExtractor={(item, index) => item} + /> + {!showModalTagSelector && !showSortPicker && <FloatingWalletBalance navigation={navigation} />} {showModalTagSelector && ( <ModalTagSelector onOverlayPress={() => this.setState({ showModalTagSelector: false })} @@ -304,21 +303,10 @@ class DiscoverPage extends React.PureComponent { title={__('Sort content by')} onOverlayPress={() => this.setState({ showSortPicker: false })} onItemSelected={this.handleSortByItemSelected} - selectedItem={sortByItem} + selectedItem={currentSortByItem} items={Constants.CLAIM_SEARCH_SORT_BY_ITEMS} /> )} - {showTimePicker && ( - <ModalPicker - title={__('Content from')} - onOverlayPress={() => this.setState({ showTimePicker: false })} - onItemSelected={this.handleTimeItemSelected} - selectedItem={timeItem} - items={Constants.CLAIM_SEARCH_TIME_ITEMS} - /> - )} - - {!sdkReady && <SdkLoadingStatus />} </View> ); } diff --git a/src/page/downloads/index.js b/src/page/downloads/index.js index ddb9290..fb72860 100644 --- a/src/page/downloads/index.js +++ b/src/page/downloads/index.js @@ -1,37 +1,29 @@ import { connect } from 'react-redux'; import { doFileList, - doFetchClaimListMine, selectFileInfosDownloaded, - selectDownloadedUris, selectMyClaimsWithoutChannels, - selectIsFetchingClaimListMine, selectIsFetchingFileList, } from 'lbry-redux'; import { doPushDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer'; -import { doDeleteFile } from 'redux/actions/file'; import { selectCurrentRoute } from 'redux/selectors/drawer'; -import { selectSdkReady } from 'redux/selectors/settings'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api +import Constants from 'constants'; import DownloadsPage from './view'; const select = state => ({ claims: selectMyClaimsWithoutChannels(state), currentRoute: selectCurrentRoute(state), - downloadedUris: selectDownloadedUris(state), fileInfos: selectFileInfosDownloaded(state), - fetching: selectIsFetchingFileList(state) || selectIsFetchingClaimListMine(state), - sdkReady: selectSdkReady(state), + fetching: selectIsFetchingFileList(state), }); const perform = dispatch => ({ - deleteFile: (fileInfo, deleteFromDevice, abandonClaim) => { - dispatch(doDeleteFile(fileInfo, deleteFromDevice, abandonClaim)); - }, - fetchMyClaims: () => dispatch(doFetchClaimListMine()), fileList: () => dispatch(doFileList()), pushDrawerStack: () => dispatch(doPushDrawerStack(Constants.DRAWER_ROUTE_MY_LBRY)), setPlayerVisible: () => dispatch(doSetPlayerVisible(false)), }); -export default connect(select, perform)(DownloadsPage); +export default connect( + select, + perform +)(DownloadsPage); diff --git a/src/page/downloads/view.js b/src/page/downloads/view.js index 758eaef..3bcde0c 100644 --- a/src/page/downloads/view.js +++ b/src/page/downloads/view.js @@ -1,21 +1,10 @@ import React from 'react'; -import { Lbry, buildURI, normalizeURI } from 'lbry-redux'; -import { - ActivityIndicator, - Alert, - Button, - FlatList, - NativeModules, - Text, - TextInput, - View, - ScrollView, -} from 'react-native'; +import { Lbry, buildURI } from 'lbry-redux'; +import { ActivityIndicator, Button, FlatList, Text, TextInput, View, ScrollView } from 'react-native'; import { navigateToUri, uriFromFileInfo } from 'utils/helper'; import Colors from 'styles/colors'; import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api import PageHeader from 'component/pageHeader'; -import EmptyStateView from 'component/emptyStateView'; import FileListItem from 'component/fileListItem'; import FloatingWalletBalance from 'component/floatingWalletBalance'; import StorageStatsCard from 'component/storageStatsCard'; @@ -28,17 +17,11 @@ class DownloadsPage extends React.PureComponent { title: 'Downloads', }; - state = { - selectionMode: false, - selectedUris: [], - selectedClaimsMap: {}, - }; - didFocusListener; componentWillMount() { const { navigation } = this.props; - // this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused); + this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused); } componentWillUnmount() { @@ -48,12 +31,9 @@ class DownloadsPage extends React.PureComponent { } onComponentFocused = () => { - const { fetchMyClaims, fileList, pushDrawerStack, setPlayerVisible } = this.props; + const { fileList, pushDrawerStack, setPlayerVisible } = this.props; pushDrawerStack(); setPlayerVisible(); - NativeModules.Firebase.setCurrentScreen('Library'); - - fetchMyClaims(); fileList(); }; @@ -64,155 +44,49 @@ class DownloadsPage extends React.PureComponent { componentWillReceiveProps(nextProps) { const { currentRoute } = nextProps; const { currentRoute: prevRoute } = this.props; - if (Constants.DRAWER_ROUTE_MY_LBRY === currentRoute && currentRoute !== prevRoute) { + if (Constants.FULL_ROUTE_NAME_MY_LBRY === currentRoute && currentRoute !== prevRoute) { this.onComponentFocused(); } } - getFilteredUris = () => { - const { claims, downloadedUris } = this.props; - const claimUris = claims.map(claim => normalizeURI(`${claim.name}#${claim.claim_id}`)); - return downloadedUris.filter(uri => !claimUris.includes(uri)); - }; - - getFilteredFileInfos = () => { - const { claims, fileInfos } = this.props; - const claimUris = claims.map(claim => normalizeURI(`${claim.name}#${claim.claim_id}`)); - return fileInfos.filter( - fileInfo => !claimUris.includes(normalizeURI(`${fileInfo.claim_name}#${fileInfo.claim_id}`)), - ); - }; - - addOrRemoveItem = (uri, claim) => { - const { selectedClaimsMap } = this.state; - let selectedUris = [...this.state.selectedUris]; - - if (selectedUris.includes(uri)) { - delete selectedClaimsMap[uri]; - selectedUris.splice(selectedUris.indexOf(uri), 1); - } else { - selectedClaimsMap[uri] = claim; - selectedUris.push(uri); - } - - this.setState({ selectionMode: selectedUris.length > 0, selectedUris, selectedClaimsMap }); - }; - - handleSelectItem = (uri, claim) => { - this.addOrRemoveItem(uri, claim); - }; - - handleItemLongPress = (uri, claim) => { - this.addOrRemoveItem(uri, claim); - }; - - onExitSelectionMode = () => { - this.setState({ selectionMode: false, selectedUris: [], selectedClaimsMap: {} }); - }; - - onDeleteActionPressed = () => { - const { deleteFile, fileList } = this.props; - const { selectedClaimsMap } = this.state; - - // show confirm alert - Alert.alert( - __('Delete files'), - __('Are you sure you want to delete the selected content?'), - [ - { text: __('No') }, - { - text: __('Yes'), - onPress: () => { - const uris = Object.keys(selectedClaimsMap); - uris.forEach(uri => { - const { txid, nout, name, claim_id: claimId } = selectedClaimsMap[uri]; - if (name && claimId) { - NativeModules.UtilityModule.deleteDownload(normalizeURI(`${name}#${claimId}`)); - } - - deleteFile(`${txid}:${nout}`, true); - }); - this.onExitSelectionMode(); - fileList(); - }, - }, - ], - { - cancelable: true, - }, - ); - }; - render() { - const { downloadedUris, fetching, navigation, sdkReady } = this.props; - const { selectionMode, selectedUris } = this.state; - const filteredUris = this.getFilteredUris(); - const hasDownloads = filteredUris && filteredUris.length > 0; - - if (!sdkReady) { - return ( - <View style={downloadsStyle.container}> - <UriBar navigation={navigation} /> - <EmptyStateView - message={__( - 'The background service is still initializing. You can still explore and watch content during the initialization process.', - )} - /> - </View> - ); - } + const { fetching, fileInfos, navigation } = this.props; + const hasDownloads = fileInfos && Object.values(fileInfos).length > 0; return ( <View style={downloadsStyle.container}> - <UriBar - navigation={navigation} - selectionMode={selectionMode} - selectedItemCount={selectedUris.length} - onExitSelectionMode={this.onExitSelectionMode} - onDeleteActionPressed={this.onDeleteActionPressed} - /> - + <UriBar navigation={navigation} /> {!fetching && !hasDownloads && ( - <EmptyStateView message={__('You do not have any\ndownloaded content on this device.')} /> + <View style={downloadsStyle.busyContainer}> + <Text style={downloadsStyle.noDownloadsText}> + You have not watched or downloaded any content from LBRY yet. + </Text> + </View> )} - - <View style={downloadsStyle.subContainer}> - {hasDownloads && <StorageStatsCard fileInfos={this.getFilteredFileInfos()} />} - {fetching && ( - <View style={downloadsStyle.busyContainer}> - <ActivityIndicator size="large" color={Colors.NextLbryGreen} style={downloadsStyle.loading} /> - </View> - )} - - {!fetching && hasDownloads && ( + {fetching && !hasDownloads && ( + <View style={downloadsStyle.busyContainer}> + <ActivityIndicator size="large" color={Colors.NextLbryGreen} style={downloadsStyle.loading} /> + </View> + )} + {hasDownloads && ( + <View style={downloadsStyle.subContainer}> + <StorageStatsCard fileInfos={fileInfos} /> <FlatList - extraData={this.state} style={downloadsStyle.scrollContainer} contentContainerStyle={downloadsStyle.scrollPadding} renderItem={({ item }) => ( <FileListItem - autoplay - key={item} - uri={item} style={fileListStyle.item} - selected={selectedUris.includes(item)} - onPress={claim => { - if (selectionMode) { - this.handleSelectItem(item, claim); - } else { - // TODO: when shortUrl is available for my claims, navigate to that URL instead - navigateToUri(navigation, item, { autoplay: true }, false, null); - } - }} - onLongPress={claim => this.handleItemLongPress(item, claim)} + uri={uriFromFileInfo(item)} navigation={navigation} + onPress={() => navigateToUri(navigation, uriFromFileInfo(item), { autoplay: true })} /> )} - data={downloadedUris} - keyExtractor={(item, index) => item} + data={fileInfos} + keyExtractor={(item, index) => item.outpoint} /> - )} - </View> + </View> + )} <FloatingWalletBalance navigation={navigation} /> </View> ); diff --git a/src/page/file/index.js b/src/page/file/index.js index cc99564..f5f8961 100644 --- a/src/page/file/index.js +++ b/src/page/file/index.js @@ -1,14 +1,10 @@ import { connect } from 'react-redux'; import { - doAbandonClaim, doFetchFileInfo, - doFetchChannelListMine, - doFetchClaimListMine, doFileGet, doPurchaseUri, doDeletePurchasedUri, doResolveUri, - doResolveUris, doSendTip, doToast, makeSelectIsUriResolving, @@ -22,83 +18,75 @@ import { makeSelectThumbnailForUri, makeSelectTitleForUri, selectBalance, - selectMyChannelClaims, - selectMyClaimUrisWithoutChannels, selectPurchasedUris, selectFailedPurchaseUris, selectPurchaseUriErrorMessage, } from 'lbry-redux'; import { - doClaimEligiblePurchaseRewards, doFetchCostInfoForUri, - doFetchViewCount, makeSelectCostInfoForUri, - makeSelectViewCountForUri, selectRewardContentClaimIds, selectBlackListedOutpoints, } from 'lbryinc'; -import { doDeleteFile, doStopDownloadingFile } from 'redux/actions/file'; -import { doPushDrawerStack, doPopDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer'; -import { doToggleFullscreenMode } from 'redux/actions/settings'; -import { selectDrawerStack, makeSelectPlayerVisible } from 'redux/selectors/drawer'; -import { selectSdkReady } from 'redux/selectors/settings'; +import { + doStartDownload, + doUpdateDownload, + doCompleteDownload, + doDeleteFile, + doStopDownloadingFile, +} from 'redux/actions/file'; +import { doPopDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer'; +import { selectDrawerStack } from 'redux/selectors/drawer'; import FilePage from './view'; const select = (state, props) => { - const { uri, fullUri } = props.navigation.state.params; - const contentUri = fullUri || uri; - const selectProps = { uri: contentUri }; + const selectProps = { uri: props.navigation.state.params.uri }; return { balance: selectBalance(state), blackListedOutpoints: selectBlackListedOutpoints(state), - channels: selectMyChannelClaims(state), - claim: makeSelectClaimForUri(contentUri)(state), + claim: makeSelectClaimForUri(selectProps.uri)(state), drawerStack: selectDrawerStack(state), - isResolvingUri: makeSelectIsUriResolving(contentUri)(state), - contentType: makeSelectContentTypeForUri(contentUri)(state), - costInfo: makeSelectCostInfoForUri(contentUri)(state), - metadata: makeSelectMetadataForUri(contentUri)(state), - fileInfo: makeSelectFileInfoForUri(contentUri)(state), + isResolvingUri: makeSelectIsUriResolving(selectProps.uri)(state), + contentType: makeSelectContentTypeForUri(selectProps.uri)(state), + costInfo: makeSelectCostInfoForUri(selectProps.uri)(state), + metadata: makeSelectMetadataForUri(selectProps.uri)(state), + //obscureNsfw: !selectShowNsfw(state), + //tab: makeSelectCurrentParam('tab')(state), + fileInfo: makeSelectFileInfoForUri(selectProps.uri)(state), rewardedContentClaimIds: selectRewardContentClaimIds(state, selectProps), - channelUri: makeSelectChannelForClaimUri(contentUri, true)(state), - isPlayerVisible: makeSelectPlayerVisible(uri)(state), // use navigation uri for this selector - position: makeSelectContentPositionForUri(contentUri)(state), + channelUri: makeSelectChannelForClaimUri(selectProps.uri, true)(state), + position: makeSelectContentPositionForUri(selectProps.uri)(state), purchasedUris: selectPurchasedUris(state), failedPurchaseUris: selectFailedPurchaseUris(state), - myClaimUris: selectMyClaimUrisWithoutChannels(state), purchaseUriErrorMessage: selectPurchaseUriErrorMessage(state), - sdkReady: selectSdkReady(state), - streamingUrl: makeSelectStreamingUrlForUri(contentUri)(state), - thumbnail: makeSelectThumbnailForUri(contentUri)(state), - title: makeSelectTitleForUri(contentUri)(state), - viewCount: makeSelectViewCountForUri(contentUri)(state), + streamingUrl: makeSelectStreamingUrlForUri(selectProps.uri)(state), + thumbnail: makeSelectThumbnailForUri(selectProps.uri)(state), + title: makeSelectTitleForUri(selectProps.uri)(state), }; }; const perform = dispatch => ({ - abandonClaim: (txid, nout) => dispatch(doAbandonClaim(txid, nout)), - claimEligibleRewards: () => dispatch(doClaimEligiblePurchaseRewards()), deleteFile: (fileInfo, deleteFromDevice, abandonClaim) => { dispatch(doDeleteFile(fileInfo, deleteFromDevice, abandonClaim)); }, fetchFileInfo: uri => dispatch(doFetchFileInfo(uri)), fetchCostInfo: uri => dispatch(doFetchCostInfoForUri(uri)), - fetchMyClaims: () => dispatch(doFetchClaimListMine()), - fetchChannelListMine: () => dispatch(doFetchChannelListMine(1, 99999, true)), - fetchViewCount: claimId => dispatch(doFetchViewCount(claimId)), fileGet: (uri, saveFile) => dispatch(doFileGet(uri, saveFile)), notify: data => dispatch(doToast(data)), popDrawerStack: () => dispatch(doPopDrawerStack()), - pushDrawerStack: (routeName, params) => dispatch(doPushDrawerStack(routeName, params)), purchaseUri: (uri, costInfo, saveFile) => dispatch(doPurchaseUri(uri, costInfo, saveFile)), deletePurchasedUri: uri => dispatch(doDeletePurchasedUri(uri)), resolveUri: uri => dispatch(doResolveUri(uri)), - resolveUris: uris => dispatch(doResolveUris(uris)), - sendTip: (amount, claimId, isSupport, successCallback, errorCallback) => - dispatch(doSendTip(amount, claimId, isSupport, successCallback, errorCallback)), - setPlayerVisible: (visible, uri) => dispatch(doSetPlayerVisible(visible, uri)), + sendTip: (amount, claimId, uri, successCallback, errorCallback) => + dispatch(doSendTip(amount, claimId, uri, successCallback, errorCallback)), + setPlayerVisible: () => dispatch(doSetPlayerVisible(true)), stopDownload: (uri, fileInfo) => dispatch(doStopDownloadingFile(uri, fileInfo)), - toggleFullscreenMode: mode => dispatch(doToggleFullscreenMode(mode)), + startDownload: (uri, outpoint, fileInfo) => dispatch(doStartDownload(uri, outpoint, fileInfo)), + updateDownload: (uri, outpoint, fileInfo, progress) => dispatch(doUpdateDownload(uri, outpoint, fileInfo, progress)), + completeDownload: (uri, outpoint, fileInfo) => dispatch(doCompleteDownload(uri, outpoint, fileInfo)), }); -export default connect(select, perform)(FilePage); +export default connect( + select, + perform +)(FilePage); diff --git a/src/page/file/view.js b/src/page/file/view.js index 6a62a05..0946718 100644 --- a/src/page/file/view.js +++ b/src/page/file/view.js @@ -1,15 +1,12 @@ import React from 'react'; -import { Lbry, formatCredits, normalizeURI, parseURI } from 'lbry-redux'; +import { Lbry, normalizeURI } from 'lbry-redux'; import { Lbryio } from 'lbryinc'; import { ActivityIndicator, Alert, DeviceEventEmitter, Dimensions, - Image, - Linking, NativeModules, - Platform, ScrollView, StatusBar, StyleSheet, @@ -18,14 +15,13 @@ import { TouchableOpacity, TouchableWithoutFeedback, View, + WebView, } from 'react-native'; -import { WebView } from 'react-native-webview'; import { NavigationEvents } from 'react-navigation'; -import { navigateBack, navigateToUri, formatBytes, formatLbryUrlForWeb } from 'utils/helper'; +import { navigateBack, navigateToUri } from 'utils/helper'; import Icon from 'react-native-vector-icons/FontAwesome5'; import ImageViewer from 'react-native-image-zoom-viewer'; import Button from 'component/button'; -import EmptyStateView from 'component/emptyStateView'; import Tag from 'component/tag'; import ChannelPage from 'page/channel'; import Colors from 'styles/colors'; @@ -37,76 +33,54 @@ import FilePrice from 'component/filePrice'; import FloatingWalletBalance from 'component/floatingWalletBalance'; import Link from 'component/link'; import MediaPlayer from 'component/mediaPlayer'; -import ModalRepostView from 'component/modalRepostView'; -import ModalTipView from 'component/modalTipView'; -import ProgressCircle from 'react-native-progress-circle'; import RelatedContent from 'component/relatedContent'; import SubscribeButton from 'component/subscribeButton'; import SubscribeNotificationButton from 'component/subscribeNotificationButton'; import UriBar from 'component/uriBar'; +import Video from 'react-native-video'; import FileRewardsDriver from 'component/fileRewardsDriver'; import filePageStyle from 'styles/filePage'; import uriBarStyle from 'styles/uriBar'; -import RNFS from 'react-native-fs'; -import showdown from 'showdown'; -import _ from 'lodash'; class FilePage extends React.PureComponent { static navigationOptions = { title: '', }; + tipAmountInput = null; + playerBackground = null; scrollView = null; startTime = null; - webView = null; - - converter = null; - - linkHandlerScript = `(function () { - window.onclick = function(evt) { evt.preventDefault(); window.ReactNativeWebView.postMessage(evt.target.href); evt.stopPropagation(); } - }());`; - constructor(props) { super(props); this.state = { - autoGetAttempted: false, - autoOpened: false, - autoDownloadStarted: false, autoPlayMedia: false, - creditsInputFocused: false, + autoDownloadStarted: false, downloadButtonShown: false, downloadPressed: false, - didSearchRecommended: false, fileViewLogged: false, fullscreenMode: false, fileGetStarted: false, - hasCheckedAllResolved: false, imageUrls: null, isLandscape: false, mediaLoaded: false, pageSuspended: false, relatedContentY: 0, - sendTipStarted: false, showDescription: false, showImageViewer: false, showWebView: false, showTipView: false, - showRepostView: false, - playbackStarted: false, playerBgHeight: 0, playerHeight: 0, + tipAmount: null, uri: null, uriVars: null, - showRecommended: false, stopDownloadConfirmed: false, streamingMode: false, - viewCountFetched: false, - isRepost: false, - uriPushedToDrawerStack: false, }; } @@ -114,81 +88,48 @@ class FilePage extends React.PureComponent { componentWillMount() { const { navigation } = this.props; - // this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused); + this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused); } - checkRepost = () => { - const { claim, isResolvingUri, navigation, pushDrawerStack } = this.props; - const { uri } = this.state; - if (!isResolvingUri) { - if (claim && claim.repost_url) { - // redirect to canonical url - this.setState({ isRepost: true }); - navigateToUri(navigation, claim.canonical_url, null, false, claim.permanent_url, false, true); - } else { - this.setState({ uriPushedToDrawerStack: true }, () => { - pushDrawerStack(uri); - }); - } - } - }; - onComponentFocused = () => { StatusBar.setHidden(false); - NativeModules.Firebase.setCurrentScreen('File').then(result => { - const { setPlayerVisible } = this.props; - DeviceEventEmitter.addListener('onDownloadAborted', this.handleDownloadAborted); - DeviceEventEmitter.addListener('onStoragePermissionGranted', this.handleStoragePermissionGranted); - DeviceEventEmitter.addListener('onStoragePermissionRefused', this.handleStoragePermissionRefused); + DeviceEventEmitter.addListener('onDownloadStarted', this.handleDownloadStarted); + DeviceEventEmitter.addListener('onDownloadUpdated', this.handleDownloadUpdated); + DeviceEventEmitter.addListener('onDownloadCompleted', this.handleDownloadCompleted); - const { claim, fetchMyClaims, fileInfo, isResolvingUri, resolveUri, navigation } = this.props; - const { uri, uriVars } = navigation.state.params; - this.setState({ uri, uriVars }); + const { fileInfo, isResolvingUri, resolveUri, navigation } = this.props; + const { uri, uriVars } = navigation.state.params; + this.setState({ uri, uriVars }); - setPlayerVisible(true, uri); - if (!isResolvingUri && !claim) resolveUri(uri); + if (!isResolvingUri) resolveUri(uri); - this.checkRepost(); - - this.fetchFileInfo(uri, this.props); - this.fetchCostInfo(uri, this.props); - - fetchMyClaims(); + this.fetchFileInfo(this.props); + this.fetchCostInfo(this.props); + if (NativeModules.Firebase) { NativeModules.Firebase.track('open_file_page', { uri: uri }); + } + if (NativeModules.UtilityModule) { NativeModules.UtilityModule.keepAwakeOn(); - }); + } }; componentDidMount() { this.onComponentFocused(); } - difference = (object, base) => { - function changes(object, base) { - return _.transform(object, function(result, value, key) { - if (!_.isEqual(value, base[key])) { - result[key] = _.isObject(value) && _.isObject(base[key]) ? changes(value, base[key]) : value; - } - }); - } - return changes(object, base); - }; - componentWillReceiveProps(nextProps) { const { claim, currentRoute, failedPurchaseUris: prevFailedPurchaseUris, - fetchViewCount, purchasedUris: prevPurchasedUris, - purchaseUriErrorMessage: prevPurchaseUriErrorMessage, navigation, contentType, notify, - drawerStack: prevDrawerStack, } = this.props; + const { uri } = navigation.state.params; const { currentRoute: prevRoute, failedPurchaseUris, @@ -196,130 +137,54 @@ class FilePage extends React.PureComponent { purchasedUris, purchaseUriErrorMessage, streamingUrl, - drawerStack, - resolveUris, } = nextProps; - const uri = this.getPurchaseUrl(); if (Constants.ROUTE_FILE === currentRoute && currentRoute !== prevRoute) { this.onComponentFocused(); } - if (failedPurchaseUris.includes(uri) && prevPurchaseUriErrorMessage !== purchaseUriErrorMessage) { + if (failedPurchaseUris.includes(uri) && !purchasedUris.includes(uri)) { if (purchaseUriErrorMessage && purchaseUriErrorMessage.trim().length > 0) { notify({ message: purchaseUriErrorMessage, isError: true }); } - this.setState({ downloadPressed: false, fileViewLogged: false, mediaLoaded: false, showRecommended: true }); + this.setState({ downloadPressed: false, fileViewLogged: false, mediaLoaded: false }); } const mediaType = Lbry.getMediaType(contentType); const isPlayable = mediaType === 'video' || mediaType === 'audio'; - if (this.state.fileGetStarted || prevPurchasedUris.length !== purchasedUris.length) { - const { permanent_url: permanentUrl, nout, txid } = claim; - const outpoint = `${txid}:${nout}`; - if (this.state.fileGetStarted) { + if ( + (this.state.fileGetStarted || prevPurchasedUris.length !== purchasedUris.length) && + NativeModules.UtilityModule + ) { + if (purchasedUris.includes(uri)) { + const { nout, txid } = claim; + const outpoint = `${txid}:${nout}`; NativeModules.UtilityModule.queueDownload(outpoint); - this.setState({ fileGetStarted: false }); - } - - if (purchasedUris.includes(uri) || purchasedUris.includes(permanentUrl)) { // If the media is playable, file/view will be done in onPlaybackStarted if (!isPlayable && !this.state.fileViewLogged) { this.logFileView(uri, claim); } + this.setState({ fileGetStarted: false }); } NativeModules.UtilityModule.checkDownloads(); } - if ((!fileInfo || (fileInfo && !fileInfo.completed)) && !this.state.streamingMode && isPlayable) { + if (!this.state.streamingMode && isPlayable) { if (streamingUrl) { this.setState({ streamingMode: true, currentStreamUrl: streamingUrl }); } else if (fileInfo && fileInfo.streaming_url) { this.setState({ streamingMode: true, currentStreamUrl: fileInfo.streaming_url }); } } - - if ( - prevDrawerStack[prevDrawerStack.length - 1].route === Constants.DRAWER_ROUTE_FILE_VIEW && - prevDrawerStack.length !== drawerStack.length - ) { - this.setState({ - downloadPressed: false, - showImageViewer: false, - showWebView: false, - }); - } - - if (claim && !this.state.viewCountFetched) { - this.setState({ viewCountFetched: true }, () => fetchViewCount(claim.claim_id)); - } } - shouldComponentUpdate(nextProps, nextState) { - const { fileInfo: prevFileInfo } = this.props; - const { fileInfo } = nextProps; - - const propKeyTriggers = ['balance', 'viewCount', 'isResolvingUri']; - const stateKeyTriggers = [ - 'downloadPressed', - 'fullscreenMode', - 'mediaLoaded', - 'playerBgHeighht', - 'playerHeight', - 'relatedY', - 'showRepostView', - 'showTipView', - 'showImageViewer', - 'showWebView', - 'showDescription', - 'showRecommended', - 'uri', - ]; - for (let i = 0; i < propKeyTriggers.length; i++) { - const key = propKeyTriggers[i]; - if (this.props[key] !== nextProps[key]) { - return true; - } - } - for (let i = 0; i < stateKeyTriggers.length; i++) { - const key = stateKeyTriggers[i]; - if (this.state[key] !== nextState[key]) { - return true; - } - } - - if (!prevFileInfo && fileInfo) { - return true; - } - if (prevFileInfo && fileInfo && Object.keys(this.difference(fileInfo, prevFileInfo)).length > 0) { - return true; - } - - return false; - } - - componentDidUpdate(prevProps, prevState) { - const { - claim, - contentType, - costInfo, - fileInfo, - isResolvingUri, - resolveUri, - sdkReady, - navigation, - title, - } = this.props; + componentDidUpdate(prevProps) { + const { claim, contentType, fileInfo, isResolvingUri, resolveUri, navigation } = this.props; const { uri } = this.state; if (!isResolvingUri && claim === undefined && uri) { resolveUri(uri); } - if (!prevProps.claim && claim) { - this.checkRepost(); - return; - } - // Returned to the page. If mediaLoaded, and currentMediaInfo is different, update if (this.state.mediaLoaded && window.currentMediaInfo && window.currentMediaInfo.uri !== this.state.uri) { const { metadata } = this.props; @@ -329,121 +194,69 @@ class FilePage extends React.PureComponent { uri: this.state.uri, }; } - - // attempt to retrieve images and html/text automatically once the claim is loaded, and it's free - const mediaType = Lbry.getMediaType(contentType); - const isPlayable = mediaType === 'video' || mediaType === 'audio'; - const isViewable = mediaType === 'image' || mediaType === 'text'; - if (claim && costInfo && costInfo.cost === 0 && !this.state.autoGetAttempted && isViewable) { - this.setState({ autoGetAttempted: true }, () => { - this.checkStoragePermissionForDownload(); - }); - } - - if (((costInfo && costInfo.cost > 0) || !isPlayable) && !fileInfo && !isViewable && !this.state.showRecommended) { - this.setState({ showRecommended: true }); - } - - if ( - !fileInfo && - !this.state.autoDownloadStarted && - claim && - costInfo && - costInfo.cost === 0 && - (isPlayable || (this.state.uriVars && this.state.uriVars.download === 'true')) - ) { - this.setState({ autoDownloadStarted: true }, () => { - if (!isPlayable) { - this.checkStoragePermissionForDownload(); - } else { - this.confirmPurchaseUri(claim.permanent_url, costInfo, !isPlayable); - } - NativeModules.UtilityModule.checkDownloads(); - }); - } } - fetchFileInfo(uri, props) { + fetchFileInfo(props) { if (props.fileInfo === undefined) { - props.fetchFileInfo(uri); + props.fetchFileInfo(props.navigation.state.params.uri); } } - fetchCostInfo(uri, props) { + fetchCostInfo(props) { if (props.costInfo === undefined) { - props.fetchCostInfo(uri); + props.fetchCostInfo(props.navigation.state.params.uri); } } - handleFullscreenToggle = isFullscreen => { - const { toggleFullscreenMode } = this.props; - toggleFullscreenMode(isFullscreen); - - if (isFullscreen) { - // fullscreen, so change orientation to landscape mode - NativeModules.ScreenOrientation.lockOrientationLandscape(); - - // hide the navigation bar (on devices that have the soft navigation bar) - NativeModules.UtilityModule.hideNavigationBar(); - } else { - // Switch back to portrait mode when the media is not fullscreen - NativeModules.ScreenOrientation.lockOrientationPortrait(); - - // show the navigation bar (on devices that have the soft navigation bar) - NativeModules.UtilityModule.showNavigationBar(); + handleFullscreenToggle = mode => { + this.setState({ fullscreenMode: mode }); + StatusBar.setHidden(mode); + if (NativeModules.ScreenOrientation) { + if (mode) { + // fullscreen, so change orientation to landscape mode + NativeModules.ScreenOrientation.lockOrientationLandscape(); + if (NativeModules.UtilityModule) { + // hide the navigation bar (on devices that use have soft navigation bar) + NativeModules.UtilityModule.hideNavigationBar(); + } + } else { + // Switch back to portrait mode when the media is not fullscreen + NativeModules.ScreenOrientation.lockOrientationPortrait(); + if (NativeModules.UtilityModule) { + // hide the navigation bar (on devices that use have soft navigation bar) + NativeModules.UtilityModule.showNavigationBar(); + } + } } - - this.setState({ fullscreenMode: isFullscreen }); - StatusBar.setHidden(isFullscreen); - }; - - onEditPressed = () => { - const { claim, navigation } = this.props; - const uri = this.state.uri || this.getPurchaseUrl(); - navigation.navigate({ - routeName: Constants.DRAWER_ROUTE_PUBLISH, - params: { editMode: true, claimToEdit: claim, returnUrl: uri }, - }); }; onDeletePressed = () => { - const { abandonClaim, claim, deleteFile, deletePurchasedUri, myClaimUris, fileInfo, navigation } = this.props; + const { claim, deleteFile, deletePurchasedUri, fileInfo, navigation } = this.props; Alert.alert( - __('Delete file'), - __('Are you sure you want to remove this file from your device?'), + 'Delete file', + 'Are you sure you want to remove this file from your device?', [ - { text: __('No') }, + { text: 'No' }, { - text: __('Yes'), + text: 'Yes', onPress: () => { const { uri } = navigation.state.params; - const purchaseUrl = this.getPurchaseUrl(); - deleteFile(`${claim.txid}:${claim.nout}`, true); deletePurchasedUri(uri); - - NativeModules.UtilityModule.deleteDownload(normalizeURI(purchaseUrl)); + if (NativeModules.UtilityModule) { + NativeModules.UtilityModule.deleteDownload(uri); + } this.setState({ downloadPressed: false, fileViewLogged: false, mediaLoaded: false, stopDownloadConfirmed: false, }); - - if (claim) { - const fullUri = normalizeURI(`${claim.name}#${claim.claim_id}`); - const ownedClaim = myClaimUris.includes(fullUri); - if (ownedClaim) { - const { txid, nout } = claim; - abandonClaim(txid, nout); - navigation.navigate({ routeName: Constants.DRAWER_ROUTE_PUBLISHES }); - } - } }, }, ], - { cancelable: true }, + { cancelable: true } ); }; @@ -451,18 +264,19 @@ class FilePage extends React.PureComponent { const { deletePurchasedUri, fileInfo, navigation, notify, stopDownload } = this.props; Alert.alert( - __('Stop download'), - __('Are you sure you want to stop downloading this file?'), + 'Stop download', + 'Are you sure you want to stop downloading this file?', [ - { text: __('No') }, + { text: 'No' }, { - text: __('Yes'), + text: 'Yes', onPress: () => { - const uri = this.getPurchaseUrl(); + const { uri } = navigation.state.params; stopDownload(uri, fileInfo); deletePurchasedUri(uri); - NativeModules.UtilityModule.deleteDownload(normalizeURI(uri)); - + if (NativeModules.UtilityModule) { + NativeModules.UtilityModule.deleteDownload(uri); + } this.setState({ downloadPressed: false, fileViewLogged: false, @@ -473,12 +287,12 @@ class FilePage extends React.PureComponent { // there can be a bit of lag between the user pressing Yes and the UI being updated // after the file_set_status and file_delete operations, so let the user know notify({ - message: __('The download will stop momentarily. You do not need to wait to discover something else.'), + message: 'The download will stop momentarily. You do not need to wait to discover something else.', }); }, }, ], - { cancelable: true }, + { cancelable: true } ); }; @@ -498,67 +312,41 @@ class FilePage extends React.PureComponent { if (window.currentMediaInfo) { window.currentMediaInfo = null; } - DeviceEventEmitter.removeListener('onDownloadAborted', this.handleDownloadAborted); - DeviceEventEmitter.removeListener('onStoragePermissionGranted', this.handleStoragePermissionGranted); - DeviceEventEmitter.removeListener('onStoragePermissionRefused', this.handleStoragePermissionRefused); + window.player = null; + + DeviceEventEmitter.removeListener('onDownloadStarted', this.handleDownloadStarted); + DeviceEventEmitter.removeListener('onDownloadUpdated', this.handleDownloadUpdated); + DeviceEventEmitter.removeListener('onDownloadCompleted', this.handleDownloadCompleted); } - handleDownloadAborted = evt => { - const { deletePurchasedUri, fileInfo, stopDownload } = this.props; - const { uri, outpoint } = evt; - const purchaseUrl = normalizeURI(this.getPurchaseUrl()); - if (purchaseUrl === uri) { - stopDownload(uri, fileInfo); - deletePurchasedUri(uri); - NativeModules.UtilityModule.deleteDownload(normalizeURI(uri)); - - this.setState({ - downloadPressed: false, - fileViewLogged: false, - mediaLoaded: false, - stopDownloadConfirmed: true, - }); - } + handleDownloadStarted = evt => { + const { startDownload } = this.props; + const { uri, outpoint, fileInfo } = evt; + startDownload(uri, outpoint, fileInfo); }; - handleStoragePermissionGranted = () => { - // permission was allowed. proceed to download - const { notify } = this.props; - - // update the configured download folder and then download - NativeModules.UtilityModule.getDownloadDirectory().then(downloadDirectory => { - Lbry.settings_set({ - key: 'download_dir', - value: downloadDirectory, - }) - .then(() => this.performDownload()) - .catch(() => { - notify({ message: __('The file could not be downloaded to the default download directory.'), isError: true }); - }); - }); + handleDownloadUpdated = evt => { + const { updateDownload } = this.props; + const { uri, outpoint, fileInfo, progress } = evt; + updateDownload(uri, outpoint, fileInfo, progress); }; - handleStoragePermissionRefused = () => { - const { notify } = this.props; - this.setState({ downloadPressed: false }); - notify({ - message: __('The file could not be downloaded because the permission to write to storage was not granted.'), - isError: true, - }); + handleDownloadCompleted = evt => { + const { completeDownload } = this.props; + const { uri, outpoint, fileInfo } = evt; + completeDownload(uri, outpoint, fileInfo); }; localUriForFileInfo = fileInfo => { if (!fileInfo) { return null; } - return 'file://' + fileInfo.download_path; + return 'file:///' + fileInfo.download_path; }; playerUriForFileInfo = fileInfo => { const { streamingUrl } = this.props; - if (!this.state.streamingMode && fileInfo && fileInfo.download_path && fileInfo.completed) { - // take streamingMode in the state into account because if the download completes while - // the media is already streaming, it will restart from the beginning + if (fileInfo && fileInfo.download_path) { return this.getEncodedDownloadPath(fileInfo); } if (streamingUrl) { @@ -649,7 +437,7 @@ class FilePage extends React.PureComponent { let timeToStartMillis, timeToStart; if (this.startTime) { timeToStartMillis = Date.now() - this.startTime; - timeToStart = Math.ceil(timeToStartMillis / 1000.0); + timeToStart = Math.ceil(timeToStartMillis / 1000); this.startTime = null; } @@ -659,13 +447,10 @@ class FilePage extends React.PureComponent { let payload = { uri: uri }; if (!isNaN(timeToStart)) { - payload['time_to_start_seconds'] = parseInt(timeToStart, 10); - payload['time_to_start_ms'] = parseInt(timeToStartMillis, 10); + payload['time_to_start_seconds'] = timeToStart; + payload['time_to_start_ms'] = timeToStartMillis; } NativeModules.Firebase.track('play', payload); - - // only fetch recommended content after playback has started - this.setState({ playbackStarted: true, showRecommended: true }); }; onPlaybackFinished = () => { @@ -685,7 +470,6 @@ class FilePage extends React.PureComponent { return; } - const { claimEligibleRewards } = this.props; const { nout, claim_id: claimId, txid } = claim; const outpoint = `${txid}:${nout}`; const params = { @@ -697,19 +481,25 @@ class FilePage extends React.PureComponent { params.time_to_start = timeToStart; } - Lbryio.call('file', 'view', params) - .then(() => claimEligibleRewards()) - .catch(() => {}); + Lbryio.call('file', 'view', params).catch(() => {}); this.setState({ fileViewLogged: true }); }; - handleSharePress = () => { - const { claim, notify } = this.props; - if (claim) { - const { canonical_url: canonicalUrl, short_url: shortUrl, permanent_url: permanentUrl } = claim; - const url = Constants.SHARE_BASE_URL + formatLbryUrlForWeb(canonicalUrl || shortUrl || permanentUrl); - NativeModules.UtilityModule.shareUrl(url); + handleSendTip = () => { + const { claim, balance, navigation, notify, sendTip } = this.props; + const { uri } = navigation.state.params; + const { tipAmount } = this.state; + + if (tipAmount > balance) { + notify({ + message: 'Insufficient credits', + }); + return; } + + sendTip(tipAmount, claim.claim_id, uri, () => { + this.setState({ tipAmount: 0, showTipView: false }); + }); }; renderTags = tags => { @@ -719,303 +509,41 @@ class FilePage extends React.PureComponent { )); }; - confirmPurchaseUri = (uri, costInfo, download) => { - const { notify, purchaseUri, sdkReady, title } = this.props; - if (!costInfo) { - notify({ message: __('This content cannot be viewed at this time. Please try again in a bit.'), isError: true }); - this.setState({ downloadPressed: false }); - this.fetchCostInfo(uri, this.props); - return; - } - - const { cost } = costInfo; - if (!NativeModules.UtilityModule.dhtEnabled && !sdkReady && parseFloat(cost) === 0) { - this.attemptLbryTvPlayback(); - return; - } - - if (costInfo.cost > 0) { - Alert.alert( - __('Confirm Purchase'), - __( - cost === 1 - ? 'This will purchase "%title%" for %amount% credit' - : 'This will purchase "%title%" for %amount% credits', - { title, amount: cost }, - ), - [ - { - text: __('OK'), - onPress: () => { - this.startTime = Date.now(); - purchaseUri(uri, costInfo, download); - }, - }, - { text: __('Cancel') }, - ], - ); - } else { - // Free content. Just call purchaseUri directly. - this.startTime = Date.now(); - purchaseUri(uri, costInfo, download); - } - }; - - getStreamUrlForClaim = claim => { - const { name, claim_id: claimId } = claim; - return `https://player.lbry.tv/content/claims/${name}/${claimId}/stream`; - }; - - attemptLbryTvPlayback = () => { - const { claim } = this.props; - if (claim) { - this.setState({ streamingMode: true, currentStreamUrl: this.getStreamUrlForClaim(claim) }); - } - }; - - onFileDownloadButtonPressed = () => { + onFileDownloadButtonPlayed = () => { + const { setPlayerVisible } = this.props; this.startTime = Date.now(); - const { claim, costInfo, contentType, notify, sdkReady, setPlayerVisible } = this.props; - const mediaType = Lbry.getMediaType(contentType); - const isPlayable = mediaType === 'video' || mediaType === 'audio'; - const isViewable = mediaType === 'image' || mediaType === 'text'; - const purchaseUrl = this.getPurchaseUrl(); - - if (!isPlayable) { - if (!sdkReady) { - notify({ - message: __('The LBRY background service is still initializing. Please wait a few moments and try again.'), - }); - return; - } - this.onDownloadPressed(); - } else { - this.confirmPurchaseUri(purchaseUrl, costInfo, !isPlayable); - } - - NativeModules.Firebase.track('purchase_uri', { uri: purchaseUrl }); - - if (isPlayable) { - this.setState({ downloadPressed: true, autoPlayMedia: true, stopDownloadConfirmed: false }); - } - if (isViewable) { - this.setState({ downloadPressed: true }); - } - }; - - getPurchaseUrl = () => { - const { claim, navigation } = this.props; - const permanentUrl = claim ? claim.permanent_url : null; - - let purchaseUrl; - if (navigation.state.params) { - const { uri, fullUri } = navigation.state.params; - purchaseUrl = fullUri || permanentUrl || uri; - } - if (!purchaseUrl && permanentUrl) { - purchaseUrl = permanentUrl; - } - - return purchaseUrl; - }; - - onDownloadPressed = () => { - const { claim, notify, sdkReady, title } = this.props; - if (!sdkReady) { - notify({ - message: __( - 'The background service is still initializing. You can still explore and watch content during the initialization process.', - ), - }); - return; - } - - const fileSize = claim && claim.value && claim.value.source ? claim.value.source.size : 0; - Alert.alert( - __('Download file'), - fileSize > 0 - ? __('Save "%title%" (%size%) to your device', { title, size: formatBytes(fileSize, 0) }) - : __('Save "%title%" to your device', { title }), - [ - { text: __('No') }, - { - text: __('Yes'), - onPress: () => { - this.checkStoragePermissionForDownload(); - }, - }, - ], - { cancelable: true }, - ); - }; - - checkStoragePermissionForDownload = () => { - // check if we the permission to write to external storage has been granted - NativeModules.UtilityModule.canReadWriteStorage().then(canReadWrite => { - if (!canReadWrite) { - // request permission - NativeModules.UtilityModule.requestStoragePermission(); - } else { - this.performDownload(); - } - }); - }; - - performDownload = () => { - const { claim, costInfo, fileGet, fileInfo, purchasedUris } = this.props; - this.setState( - { - downloadPressed: true, - autoPlayMedia: false, - stopDownloadConfirmed: false, - }, - () => { - const url = this.getPurchaseUrl(); - if (fileInfo || purchasedUris.includes(url)) { - // file already in library or URI already purchased, use fileGet directly - this.setState({ fileGetStarted: true }, () => fileGet(url, true)); - } else { - this.confirmPurchaseUri(url, costInfo, true); - } - NativeModules.UtilityModule.checkDownloads(); - }, - ); + this.setState({ downloadPressed: true, autoPlayMedia: true, stopDownloadConfirmed: false }); + setPlayerVisible(); }; onBackButtonPressed = () => { - const { navigation, drawerStack, popDrawerStack, setPlayerVisible } = this.props; - navigateBack(navigation, drawerStack, popDrawerStack, setPlayerVisible); + const { navigation, drawerStack, popDrawerStack } = this.props; + navigateBack(navigation, drawerStack, popDrawerStack); }; - onOpenFilePressed = () => { - const { contentType, fileInfo, notify } = this.props; - const localFileUri = this.localUriForFileInfo(fileInfo); - const mediaType = Lbry.getMediaType(contentType); - const isViewable = mediaType === 'image' || mediaType === 'text'; - const isPlayable = mediaType === 'video' || mediaType === 'audio'; - if (isViewable) { - this.openFile(localFileUri, mediaType, contentType); - } else if (isPlayable) { - notify({ message: __('Please press the Play button.') }); + onSaveFilePressed = () => { + const { costInfo, fileGet, fileInfo, navigation, purchasedUris, purchaseUri } = this.props; + const { uri } = navigation.state.params; + + if (fileInfo || purchasedUris.includes(uri)) { + // file already in library or URI already purchased, use fileGet directly + this.setState({ fileGetStarted: true }, () => fileGet(uri, true)); } else { - notify({ message: __('This file cannot be displayed in the LBRY app.') }); + this.setState( + { + downloadPressed: true, + autoPlayMedia: false, + stopDownloadConfirmed: false, + }, + () => purchaseUri(uri, costInfo, true) + ); } }; - openFile = (localFileUri, mediaType, contentType) => { - const { pushDrawerStack } = this.props; - const isWebViewable = mediaType === 'text'; - - if (mediaType === 'image') { - // use image viewer - if (!this.state.showImageViewer) { - this.setState( - { - imageUrls: [ - { - url: localFileUri, - }, - ], - showImageViewer: true, - showRecommended: true, - }, - () => pushDrawerStack(Constants.DRAWER_ROUTE_FILE_VIEW), - ); - } - } - if (isWebViewable) { - // show webview - if (!this.state.showWebView) { - this.setState( - { - showWebView: true, - showRecommended: true, - }, - () => { - pushDrawerStack(Constants.DRAWER_ROUTE_FILE_VIEW); - }, - ); - } - } - }; - - handleWebViewLoad = () => { - const { contentType, fileInfo } = this.props; - const localFileUri = this.localUriForFileInfo(fileInfo); - if (this.webView && ['text/markdown', 'text/md'].includes(contentType)) { - RNFS.readFile(localFileUri, 'utf8').then(markdown => { - if (this.webView) { - if (!this.converter) { - this.converter = new showdown.Converter(); - } - const html = this.converter.makeHtml(markdown); - this.webView.injectJavaScript( - 'document.getElementById("content").innerHTML = \'' + - html.replace(/\n/g, '').replace(/'/g, "\\'") + - "'; true;", - ); - } - }); - } - }; - - handleWebViewMessage = evt => { - const href = evt.nativeEvent.data; - if (href && href.startsWith('http')) { - Linking.openURL(href); - } - }; - - buildWebViewSource = () => { - const { contentType, fileInfo } = this.props; - const localFileUri = this.localUriForFileInfo(fileInfo); - - if (['text/markdown', 'text/md'].includes(contentType)) { - let fontdecl = ''; - if (Platform.OS === 'android') { - fontdecl = ` - @font-face { - font-family: 'Inter'; - src: url('file:///android_asset/fonts/Inter-Regular.otf'); - font-weight: normal; - } - @font-face { - font-family: 'Inter; - src: url('file:///android_asset/fonts/Inter-Bold.otf'); - font-weight: bold; - } - `; - } - - const html = ` - <!doctype html> - <html> - <head> - <meta charset="utf-8"/> - <meta name="viewport" content="width=device-width, user-scalable=no"/> - <style type="text/css"> - ${fontdecl} - body { font-family: 'Inter', sans-serif; margin: 16px } - img { width: 100%; } - </style> - </head> - <body> - <div id="content"></div> - </body> - </html> - `; - - return { html }; - } - - return { uri: localFileUri }; - }; - render() { const { balance, claim, - channels, channelUri, costInfo, fileInfo, @@ -1023,310 +551,281 @@ class FilePage extends React.PureComponent { contentType, tab, rewardedContentClaimIds, - isPlayerVisible, isResolvingUri, blackListedOutpoints, - myClaimUris, navigation, position, - pushDrawerStack, - setPlayerVisible, + purchaseUri, thumbnail, title, - viewCount, } = this.props; const { uri, autoplay } = navigation.state.params; - const { isChannel } = parseURI(uri); - const myChannelUris = channels ? channels.map(channel => channel.permanent_url) : []; - const ownedClaim = myClaimUris.includes(uri) || myChannelUris.includes(uri); - let innerContent = null; if ((isResolvingUri && !claim) || !claim) { - if (!isResolvingUri && !claim && !this.state.uriPushedToDrawerStack) { - this.setState({ uriPushedToDrawerStack: true }, () => { - pushDrawerStack(uri); - }); - } - return ( - <View style={filePageStyle.pageContainer}> - <UriBar value={uri} navigation={navigation} /> + <View style={filePageStyle.container}> {isResolvingUri && ( <View style={filePageStyle.busyContainer}> <ActivityIndicator size="large" color={Colors.NextLbryGreen} /> - <Text style={filePageStyle.infoText}>{__('Loading decentralized data...')}</Text> + <Text style={filePageStyle.infoText}>Loading decentralized data...</Text> </View> )} {claim === null && !isResolvingUri && ( <View style={filePageStyle.container}> - {ownedClaim && ( - <EmptyStateView - message={ - isChannel - ? __('It looks like you just created this channel. It will appear in a few minutes.') - : __('It looks you just published this content. It will appear in a few minutes.') - } - /> - )} - {!ownedClaim && ( - <EmptyStateView - message={__("There's nothing at this location.")} - buttonText={__('Publish something here')} - onButtonPress={() => - navigation.navigate({ - routeName: Constants.DRAWER_ROUTE_PUBLISH, - params: { vanityUrl: uri.trim() }, - }) - } - /> - )} + <Text style={filePageStyle.emptyClaimText}>There's nothing at this location.</Text> </View> )} - <FloatingWalletBalance navigation={navigation} /> + <UriBar value={uri} navigation={navigation} /> </View> ); } - let isClaimBlackListed = false; - if (blackListedOutpoints) { - for (let i = 0; i < blackListedOutpoints.length; i += 1) { - const outpoint = blackListedOutpoints[i]; - if (outpoint.txid === claim.txid && outpoint.nout === claim.nout) { - isClaimBlackListed = true; - break; + if (claim) { + if (claim && claim.name.length && claim.name[0] === '@') { + return <ChannelPage uri={uri} navigation={navigation} />; + } + + let isClaimBlackListed = false; + + if (blackListedOutpoints) { + for (let i = 0; i < blackListedOutpoints.length; i += 1) { + const outpoint = blackListedOutpoints[i]; + if (outpoint.txid === claim.txid && outpoint.nout === claim.nout) { + isClaimBlackListed = true; + break; + } } } - } - if (isClaimBlackListed) { - innerContent = ( - <View style={filePageStyle.dmcaContainer}> - <Text style={filePageStyle.dmcaText}> - {__( - 'In response to a complaint we received under the US Digital Millennium Copyright Act, we have blocked access to this content from our applications.', - )} - </Text> - <Link style={filePageStyle.dmcaLink} href="https://lbry.com/faq/dmca" text={__('Read More')} /> - </View> - ); - } + if (isClaimBlackListed) { + return ( + <View style={filePageStyle.pageContainer}> + <View style={filePageStyle.dmcaContainer}> + <Text style={filePageStyle.dmcaText}> + In response to a complaint we received under the US Digital Millennium Copyright Act, we have blocked + access to this content from our applications. + </Text> + <Link style={filePageStyle.dmcaLink} href="https://lbry.com/faq/dmca" text="Read More" /> + </View> + <UriBar value={uri} navigation={navigation} /> + </View> + ); + } - let tags = []; - if (claim && claim.value && claim.value.tags) { - tags = claim.value.tags; - } + let tags = []; + if (claim && claim.value && claim.value.tags) { + tags = claim.value.tags; + } - if (!isResolvingUri && this.state.isRepost) { - return null; - } - - // in case we somehow get here without the uri pushed to the drawer stack - if (!isResolvingUri && !this.state.isRepost && !this.state.uriPushedToDrawerStack) { - this.setState({ uriPushedToDrawerStack: true }, () => { - pushDrawerStack(uri); - }); - } - - const completed = fileInfo && fileInfo.completed; - const isRewardContent = rewardedContentClaimIds.includes(claim.claim_id); - const description = metadata.description ? metadata.description : null; - const mediaType = Lbry.getMediaType(contentType); - const isPlayable = mediaType === 'video' || mediaType === 'audio'; - const isWebViewable = mediaType === 'text'; - const { height, signing_channel: signingChannel, value } = claim; - const channelName = signingChannel && signingChannel.name; - const channelClaimId = claim && claim.signing_channel && claim.signing_channel.claim_id; - const fullUri = `${claim.name}#${claim.claim_id}`; - const canEdit = - myClaimUris.includes(normalizeURI(fullUri)) || myClaimUris.includes(normalizeURI(claim.canonical_url)); - const showActions = - (canEdit || (fileInfo && fileInfo.download_path)) && - !this.state.fullscreenMode && - !this.state.showImageViewer && - !this.state.showWebView; - const showFileActions = - canEdit || - (fileInfo && + const completed = fileInfo && fileInfo.completed; + const isRewardContent = rewardedContentClaimIds.includes(claim.claim_id); + const description = metadata.description ? metadata.description : null; + const mediaType = Lbry.getMediaType(contentType); + const isPlayable = mediaType === 'video' || mediaType === 'audio'; + const { height, signing_channel: signingChannel, value } = claim; + const channelName = signingChannel && signingChannel.name; + const showActions = + fileInfo && fileInfo.download_path && - (completed || (fileInfo && !fileInfo.stopped && fileInfo.written_bytes < fileInfo.total_bytes))); - const fullChannelUri = - channelClaimId && channelClaimId.trim().length > 0 - ? normalizeURI(`${channelName}#${channelClaimId}`) - : normalizeURI(channelName); - const shortChannelUri = signingChannel ? signingChannel.short_url : null; + !this.state.fullscreenMode && + !this.state.showImageViewer && + !this.state.showWebView; + const showFileActions = + fileInfo && + fileInfo.download_path && + (completed || (fileInfo && !fileInfo.stopped && fileInfo.written_bytes < fileInfo.total_bytes)); + const channelClaimId = claim && claim.signing_channel && claim.signing_channel.claim_id; + const canSendTip = this.state.tipAmount > 0; + const fullChannelUri = + channelClaimId && channelClaimId.trim().length > 0 ? `${channelName}#${channelClaimId}` : channelName; - const playerStyle = [ - filePageStyle.player, - this.state.isLandscape - ? filePageStyle.containedPlayerLandscape - : this.state.fullscreenMode - ? filePageStyle.fullscreenPlayer - : filePageStyle.containedPlayer, - ]; - const playerBgStyle = [filePageStyle.playerBackground, filePageStyle.containedPlayerBackground]; - const fsPlayerBgStyle = [filePageStyle.playerBackground, filePageStyle.fullscreenPlayerBackground]; - // at least 2MB (or the full download) before media can be loaded - const canLoadMedia = - this.state.streamingMode || - (fileInfo && (fileInfo.written_bytes >= 2097152 || fileInfo.written_bytes === fileInfo.total_bytes)); // 2MB = 1024*1024*2 - const duration = claim && claim.value && claim.value.video ? claim.value.video.duration : null; - const isViewable = mediaType === 'image' || mediaType === 'text'; - const canOpen = isViewable && completed; - const localFileUri = this.localUriForFileInfo(fileInfo); - const unsupported = !isPlayable && !canOpen; + const playerStyle = [ + filePageStyle.player, + this.state.isLandscape + ? filePageStyle.containedPlayerLandscape + : this.state.fullscreenMode + ? filePageStyle.fullscreenPlayer + : filePageStyle.containedPlayer, + ]; + const playerBgStyle = [filePageStyle.playerBackground, filePageStyle.containedPlayerBackground]; + const fsPlayerBgStyle = [filePageStyle.playerBackground, filePageStyle.fullscreenPlayerBackground]; + // at least 2MB (or the full download) before media can be loaded + const canLoadMedia = + this.state.streamingMode || + (fileInfo && (fileInfo.written_bytes >= 2097152 || fileInfo.written_bytes === fileInfo.total_bytes)); // 2MB = 1024*1024*2 + const isViewable = mediaType === 'image' || mediaType === 'text'; + const isWebViewable = mediaType === 'text'; + const canOpen = isViewable && completed; + const localFileUri = this.localUriForFileInfo(fileInfo); - if (this.state.downloadPressed && canOpen && !this.state.autoOpened) { - // automatically open a web viewable or image file after the download button is pressed - this.setState({ autoOpened: true }, () => this.openFile(localFileUri, mediaType, contentType)); - } + const openFile = () => { + if (mediaType === 'image') { + // use image viewer + if (!this.state.showImageViewer) { + this.setState({ + imageUrls: [ + { + url: localFileUri, + }, + ], + showImageViewer: true, + }); + } + } + if (isWebViewable) { + // show webview + if (!this.state.showWebView) { + this.setState({ + showWebView: true, + }); + } + } + }; - if (isChannel) { - return <ChannelPage uri={uri} navigation={navigation} />; - } + if (fileInfo && !this.state.autoDownloadStarted && this.state.uriVars && this.state.uriVars.download === 'true') { + this.setState({ autoDownloadStarted: true }, () => { + purchaseUri(uri, costInfo, !isPlayable); + if (NativeModules.UtilityModule) { + NativeModules.UtilityModule.checkDownloads(); + } + }); + } - return ( - <View style={filePageStyle.pageContainer}> - {!this.state.fullscreenMode && <UriBar value={uri} navigation={navigation} />} - {innerContent} - {this.state.showWebView && isWebViewable && ( - <WebView - ref={ref => { - this.webView = ref; - }} - allowFileAccess - javaScriptEnabled - originWhiteList={['*']} - source={this.buildWebViewSource()} - style={filePageStyle.viewer} - onLoad={this.handleWebViewLoad} - injectedJavaScript={this.linkHandlerScript} - onMessage={this.handleWebViewMessage} - /> - )} - {this.state.showImageViewer && ( - <ImageViewer - style={StyleSheet.flatten(filePageStyle.viewer)} - imageUrls={this.state.imageUrls} - renderIndicator={() => null} - /> - )} - {!innerContent && !this.state.showWebView && ( - <View - style={ - this.state.fullscreenMode ? filePageStyle.innerPageContainerFsMode : filePageStyle.innerPageContainer - } - onLayout={this.checkOrientation} - > - <TouchableOpacity - activeOpacity={0.5} - style={filePageStyle.mediaContainer} - onPress={this.onFileDownloadButtonPressed} + if (this.state.downloadPressed && canOpen) { + // automatically open a web viewable or image file after the download button is pressed + openFile(); + } + + return ( + <View style={filePageStyle.pageContainer}> + {!this.state.fullscreenMode && <UriBar value={uri} navigation={navigation} />} + {this.state.showWebView && isWebViewable && ( + <WebView source={{ uri: localFileUri }} style={filePageStyle.viewer} /> + )} + + {this.state.showImageViewer && ( + <ImageViewer + style={StyleSheet.flatten(filePageStyle.viewer)} + imageUrls={this.state.imageUrls} + renderIndicator={() => null} + /> + )} + + {!this.state.showWebView && ( + <View + style={ + this.state.fullscreenMode ? filePageStyle.innerPageContainerFsMode : filePageStyle.innerPageContainer + } + onLayout={this.checkOrientation} > - {(canOpen || !fileInfo || (isPlayable && !canLoadMedia) || (!canOpen && fileInfo)) && ( - <FileItemMedia - duration={duration} - style={filePageStyle.thumbnail} - title={title} - thumbnail={thumbnail} + <View style={filePageStyle.mediaContainer}> + {(canOpen || (!fileInfo || (isPlayable && !canLoadMedia)) || (!canOpen && fileInfo)) && ( + <FileItemMedia style={filePageStyle.thumbnail} title={title} thumbnail={thumbnail} /> + )} + {(!this.state.downloadButtonShown || this.state.downloadPressed) && !this.state.mediaLoaded && ( + <ActivityIndicator size="large" color={Colors.NextLbryGreen} style={filePageStyle.loading} /> + )} + {((isPlayable && !completed && !canLoadMedia) || + canOpen || + (!completed && !this.state.streamingMode)) && + !this.state.downloadPressed && ( + <FileDownloadButton + uri={uri} + style={filePageStyle.downloadButton} + openFile={openFile} + isPlayable={isPlayable} + isViewable={isViewable} + onPlay={this.onFileDownloadButtonPlayed} + onView={() => this.setState({ downloadPressed: true })} + onButtonLayout={() => this.setState({ downloadButtonShown: true })} + /> + )} + {!fileInfo && ( + <FilePrice + uri={uri} + style={filePageStyle.filePriceContainer} + textStyle={filePageStyle.filePriceText} + /> + )} + + <TouchableOpacity style={filePageStyle.backButton} onPress={this.onBackButtonPressed}> + <Icon name={'arrow-left'} size={18} style={filePageStyle.backButtonIcon} /> + </TouchableOpacity> + </View> + {(this.state.streamingMode || (canLoadMedia && fileInfo && isPlayable)) && ( + <View + style={playerBgStyle} + ref={ref => { + this.playerBackground = ref; + }} + onLayout={evt => { + if (!this.state.playerBgHeight) { + this.setState({ playerBgHeight: evt.nativeEvent.layout.height }); + } + }} /> )} - {!unsupported && - (!this.state.downloadButtonShown || this.state.downloadPressed) && - !this.state.mediaLoaded && ( - <ActivityIndicator size="large" color={Colors.NextLbryGreen} style={filePageStyle.loading} /> + {(this.state.streamingMode || (canLoadMedia && fileInfo && isPlayable)) && this.state.fullscreenMode && ( + <View style={fsPlayerBgStyle} /> + )} + {(this.state.streamingMode || (canLoadMedia && fileInfo && isPlayable)) && ( + <MediaPlayer + claim={claim} + assignPlayer={ref => { + this.player = ref; + }} + uri={uri} + source={this.playerUriForFileInfo(fileInfo)} + style={playerStyle} + autoPlay={autoplay || this.state.autoPlayMedia} + onFullscreenToggled={this.handleFullscreenToggle} + onLayout={evt => { + if (!this.state.playerHeight) { + this.setState({ playerHeight: evt.nativeEvent.layout.height }); + } + }} + onMediaLoaded={() => this.onMediaLoaded(channelName, title, uri)} + onBackButtonPressed={this.onBackButtonPressed} + onPlaybackStarted={this.onPlaybackStarted} + onPlaybackFinished={this.onPlaybackFinished} + thumbnail={thumbnail} + position={position} + /> )} - {unsupported && fileInfo && completed && ( - <View style={filePageStyle.unsupportedContent}> - <Image - style={filePageStyle.unsupportedContentImage} - resizeMode={'stretch'} - source={require('../../assets/gerbil-happy.png')} - /> - <View style={filePageStyle.unspportedContentTextContainer}> - <Text style={filePageStyle.unsupportedContentTitle}>{__('Unsupported Content')}</Text> - <Text style={filePageStyle.unsupportedContentText}> - Sorry, we are unable to display this content in the app. You can find the file named{' '} - <Text style={filePageStyle.unsupportedContentFilename}>{fileInfo.file_name}</Text> in your - downloads folder. - </Text> - </View> + {showActions && showFileActions && ( + <View style={filePageStyle.actions}> + {showFileActions && ( + <View style={filePageStyle.fileActions}> + {completed && ( + <Button + style={filePageStyle.actionButton} + theme={'light'} + icon={'trash'} + text={'Delete'} + onPress={this.onDeletePressed} + /> + )} + {!completed && + fileInfo && + !fileInfo.stopped && + fileInfo.written_bytes < fileInfo.total_bytes && + !this.state.stopDownloadConfirmed && ( + <Button + style={filePageStyle.actionButton} + icon={'stop'} + theme={'light'} + text={'Stop Download'} + onPress={this.onStopDownloadPressed} + /> + )} + </View> + )} </View> )} - - {((isPlayable && !completed && !canLoadMedia) || - canOpen || - (!completed && !this.state.streamingMode)) && ( - <FileDownloadButton - uri={claim && claim.permanent_url ? claim.permanent_url : uri} - style={filePageStyle.downloadButton} - openFile={() => this.openFile(localFileUri, mediaType, contentType)} - isPlayable={isPlayable} - isViewable={isViewable} - onFileActionPress={this.onFileDownloadButtonPressed} - onButtonLayout={() => this.setState({ downloadButtonShown: true })} - /> - )} - {!fileInfo && ( - <FilePrice - uri={claim && claim.permanent_url ? claim.permanent_url : uri} - style={filePageStyle.filePriceContainer} - textStyle={filePageStyle.filePriceText} - iconStyle={filePageStyle.filePriceIcon} - /> - )} - - <TouchableOpacity style={filePageStyle.backButton} onPress={this.onBackButtonPressed}> - <Icon name={'arrow-left'} size={18} style={filePageStyle.backButtonIcon} /> - </TouchableOpacity> - </TouchableOpacity> - {!innerContent && (this.state.streamingMode || (canLoadMedia && fileInfo && isPlayable)) && ( - <View - style={playerBgStyle} - ref={ref => { - this.playerBackground = ref; - }} - onLayout={evt => { - if (!this.state.playerBgHeight) { - this.setState({ playerBgHeight: evt.nativeEvent.layout.height }); - } - }} - /> - )} - {!innerContent && - (this.state.streamingMode || (canLoadMedia && fileInfo && isPlayable)) && - this.state.fullscreenMode && <View style={fsPlayerBgStyle} />} - {isPlayerVisible && - !innerContent && - (this.state.streamingMode || (canLoadMedia && fileInfo && isPlayable)) && ( - <MediaPlayer - claim={claim} - assignPlayer={ref => { - this.player = ref; - }} - uri={uri} - source={this.playerUriForFileInfo(fileInfo)} - style={playerStyle} - autoPlay - onFullscreenToggled={this.handleFullscreenToggle} - onLayout={evt => { - if (!this.state.playerHeight) { - this.setState({ playerHeight: evt.nativeEvent.layout.height }); - } - }} - onMediaLoaded={() => this.onMediaLoaded(channelName, title, uri)} - onBackButtonPressed={this.onBackButtonPressed} - onPlaybackStarted={this.onPlaybackStarted} - onPlaybackFinished={this.onPlaybackFinished} - thumbnail={thumbnail} - position={position} - /> - )} - - {!innerContent && ( <ScrollView - style={filePageStyle.scrollContainer} + style={showActions ? filePageStyle.scrollContainerActions : filePageStyle.scrollContainer} contentContainerstyle={showActions ? null : filePageStyle.scrollContent} keyboardShouldPersistTaps={'handled'} ref={ref => { @@ -1337,112 +836,15 @@ class FilePage extends React.PureComponent { style={filePageStyle.titleTouch} onPress={() => this.setState({ showDescription: !this.state.showDescription })} > - <View style={filePageStyle.titleArea}> - <View style={filePageStyle.titleRow}> - <Text style={filePageStyle.title} selectable> - {title} - </Text> - {isRewardContent && <Icon name="award" style={filePageStyle.rewardIcon} size={16} />} - <View style={filePageStyle.descriptionToggle}> - <Icon name={this.state.showDescription ? 'caret-up' : 'caret-down'} size={24} /> - </View> - </View> - <Text style={filePageStyle.viewCount}> - {viewCount === 1 && __('%view% view', { view: viewCount })} - {viewCount > 1 && __('%view% views', { view: viewCount })} + <View style={filePageStyle.titleRow}> + <Text style={filePageStyle.title} selectable> + {title} </Text> + <View style={filePageStyle.descriptionToggle}> + <Icon name={this.state.showDescription ? 'caret-up' : 'caret-down'} size={24} /> + </View> </View> </TouchableWithoutFeedback> - - <View style={filePageStyle.largeButtonsRow}> - <TouchableOpacity style={filePageStyle.largeButton} onPress={this.handleSharePress}> - <Icon name={'share-alt'} size={16} style={filePageStyle.largeButtonIcon} /> - <Text style={filePageStyle.largeButtonText}>{__('Share')}</Text> - </TouchableOpacity> - - <TouchableOpacity - style={filePageStyle.largeButton} - onPress={() => this.setState({ showRepostView: true })} - > - <Icon name={'retweet'} size={16} style={filePageStyle.largeButtonIcon} /> - <Text style={filePageStyle.largeButtonText}>{__('Repost')}</Text> - </TouchableOpacity> - - <TouchableOpacity - style={filePageStyle.largeButton} - onPress={() => this.setState({ showTipView: true })} - > - <Icon name={'gift'} size={16} style={filePageStyle.largeButtonIcon} /> - <Text style={filePageStyle.largeButtonText}>{__('Tip')}</Text> - </TouchableOpacity> - - {!canEdit && ( - <View style={filePageStyle.sharedLargeButton}> - {!this.state.downloadPressed && - (!fileInfo || !fileInfo.download_path || (fileInfo.written_bytes <= 0 && !completed)) && ( - <TouchableOpacity style={filePageStyle.innerLargeButton} onPress={this.onDownloadPressed}> - <Icon name={'download'} size={16} style={filePageStyle.largeButtonIcon} /> - <Text style={filePageStyle.largeButtonText}>{__('Download')}</Text> - </TouchableOpacity> - )} - - {this.state.downloadPressed && (!fileInfo || fileInfo.written_bytes === 0) && ( - <ActivityIndicator size={'small'} color={Colors.NextLbryGreen} /> - )} - - {!completed && - fileInfo && - fileInfo.written_bytes > 0 && - fileInfo.written_bytes < fileInfo.total_bytes && - !this.state.stopDownloadConfirmed && ( - <TouchableOpacity style={filePageStyle.innerLargeButton} onPress={this.onStopDownloadPressed}> - <ProgressCircle - percent={(fileInfo.written_bytes / fileInfo.total_bytes) * 100} - radius={9} - borderWidth={2} - shadowColor={Colors.ActionGrey} - color={Colors.NextLbryGreen} - > - <Icon name={'stop'} size={6} style={filePageStyle.largeButtonIcon} /> - </ProgressCircle> - <Text style={filePageStyle.largeButtonText}>{__('Stop')}</Text> - </TouchableOpacity> - )} - - {completed && fileInfo && ( - <TouchableOpacity style={filePageStyle.innerLargeButton} onPress={this.onOpenFilePressed}> - <Icon name={'folder-open'} size={16} style={filePageStyle.largeButtonIcon} /> - <Text style={filePageStyle.largeButtonText}>{__('Open')}</Text> - </TouchableOpacity> - )} - </View> - )} - - {!canEdit && ( - <TouchableOpacity - style={filePageStyle.largeButton} - onPress={() => Linking.openURL(`https://lbry.com/dmca/${claim.claim_id}`)} - > - <Icon name={'flag'} size={16} style={filePageStyle.largeButtonIcon} /> - <Text style={filePageStyle.largeButtonText}>{__('Report')}</Text> - </TouchableOpacity> - )} - - {canEdit && ( - <TouchableOpacity style={filePageStyle.largeButton} onPress={this.onEditPressed}> - <Icon name={'edit'} size={16} style={filePageStyle.largeButtonIcon} /> - <Text style={filePageStyle.largeButtonText}>{__('Edit')}</Text> - </TouchableOpacity> - )} - - {(completed || canEdit) && ( - <TouchableOpacity style={filePageStyle.largeButton} onPress={this.onDeletePressed}> - <Icon name={'trash-alt'} size={16} style={filePageStyle.largeButtonIcon} /> - <Text style={filePageStyle.largeButtonText}>{__('Delete')}</Text> - </TouchableOpacity> - )} - </View> - <View style={filePageStyle.channelRow}> <View style={filePageStyle.publishInfo}> {channelName && ( @@ -1453,31 +855,38 @@ class FilePage extends React.PureComponent { numberOfLines={1} ellipsizeMode={'tail'} onPress={() => { - navigateToUri( - navigation, - normalizeURI(shortChannelUri || fullChannelUri), - null, - false, - fullChannelUri, - setPlayerVisible, - ); + navigateToUri(navigation, normalizeURI(fullChannelUri)); }} /> )} {!channelName && ( <Text style={filePageStyle.anonChannelName} selectable ellipsizeMode={'tail'}> - {__('Anonymous')} + Anonymous </Text> )} <DateTime style={filePageStyle.publishDate} textStyle={filePageStyle.publishDateText} - uri={fullUri} + uri={uri} formatOptions={{ day: 'numeric', month: 'long', year: 'numeric' }} show={DateTime.SHOW_DATE} /> </View> <View style={filePageStyle.subscriptionRow}> + {false && ((isPlayable && !fileInfo) || (isPlayable && fileInfo && !fileInfo.download_path)) && ( + <Button + style={[filePageStyle.actionButton, filePageStyle.saveFileButton]} + theme={'light'} + icon={'download'} + onPress={this.onSaveFilePressed} + /> + )} + <Button + style={[filePageStyle.actionButton, filePageStyle.tipButton]} + theme={'light'} + icon={'gift'} + onPress={() => this.setState({ showTipView: true })} + /> {channelName && ( <SubscribeButton style={filePageStyle.actionButton} @@ -1486,7 +895,7 @@ class FilePage extends React.PureComponent { hideText={false} /> )} - {false && channelName && ( + {channelName && ( <SubscribeNotificationButton style={[filePageStyle.actionButton, filePageStyle.bellButton]} uri={fullChannelUri} @@ -1496,6 +905,36 @@ class FilePage extends React.PureComponent { </View> </View> + {this.state.showTipView && <View style={filePageStyle.divider} />} + {this.state.showTipView && ( + <View style={filePageStyle.tipCard}> + <View style={filePageStyle.row}> + <View style={filePageStyle.amountRow}> + <TextInput + ref={ref => (this.tipAmountInput = ref)} + onChangeText={value => this.setState({ tipAmount: value })} + keyboardType={'numeric'} + placeholder={'0'} + value={this.state.tipAmount} + style={[filePageStyle.input, filePageStyle.tipAmountInput]} + /> + <Text style={[filePageStyle.text, filePageStyle.currency]}>LBC</Text> + </View> + <Link + style={[filePageStyle.link, filePageStyle.cancelTipLink]} + text={'Cancel'} + onPress={() => this.setState({ showTipView: false })} + /> + <Button + text={'Send a tip'} + style={[filePageStyle.button, filePageStyle.sendButton]} + disabled={!canSendTip} + onPress={this.handleSendTip} + /> + </View> + </View> + )} + {this.state.showDescription && description && description.length > 0 && ( <View style={filePageStyle.divider} /> )} @@ -1506,58 +945,28 @@ class FilePage extends React.PureComponent { </Text> {tags && tags.length > 0 && ( <View style={filePageStyle.tagContainer}> - <Text style={filePageStyle.tagTitle}>{__('Tags')}</Text> + <Text style={filePageStyle.tagTitle}>Tags</Text> <View style={filePageStyle.tagList}>{this.renderTags(tags)}</View> </View> )} </View> )} - {costInfo && parseFloat(costInfo.cost) > balance && !fileInfo && ( - <FileRewardsDriver navigation={navigation} /> - )} + {costInfo && parseFloat(costInfo.cost) > balance && <FileRewardsDriver navigation={navigation} />} <View onLayout={this.setRelatedContentPosition} /> - - {this.state.showRecommended && ( - <RelatedContent - navigation={navigation} - claimId={claim.claim_id} - title={title} - uri={fullUri} - fullUri={fullUri} - /> - )} + <RelatedContent navigation={navigation} uri={uri} /> </ScrollView> - )} - </View> - )} - {this.state.showTipView && ( - <ModalTipView - claim={claim} - channelName={channelName} - contentName={title} - onCancelPress={() => this.setState({ showTipView: false })} - onOverlayPress={() => this.setState({ showTipView: false })} - onSendTipSuccessful={() => this.setState({ showTipView: false })} - /> - )} - {this.state.showRepostView && ( - <ModalRepostView - claim={claim} - title={title} - onCancelPress={() => this.setState({ showRepostView: false })} - onOverlayPress={() => this.setState({ showRepostView: false })} - onRepostSuccessful={() => this.setState({ showRepostView: false })} - /> - )} - {!this.state.fullscreenMode && - !this.state.showRepostView && - !this.state.showTipView && - !this.state.showImageViewer && - !this.state.showWebView && <FloatingWalletBalance navigation={navigation} />} - </View> - ); + </View> + )} + {!this.state.fullscreenMode && !this.state.showImageViewer && !this.state.showWebView && ( + <FloatingWalletBalance navigation={navigation} /> + )} + </View> + ); + } + + return null; } } diff --git a/src/page/firstRun/index.js b/src/page/firstRun/index.js index 70d95b8..35ce654 100644 --- a/src/page/firstRun/index.js +++ b/src/page/firstRun/index.js @@ -1,14 +1,14 @@ import { connect } from 'react-redux'; -import { SETTINGS, doToast } from 'lbry-redux'; +import { doToast } from 'lbry-redux'; import { doAuthenticate, doCheckSync, doGetSync, + doSetDefaultAccount, doSyncApply, doUserEmailNew, doUserResendVerificationEmail, selectAuthToken, - selectEmailAlreadyExists, selectEmailNewErrorMessage, selectEmailNewIsPending, selectEmailToVerify, @@ -22,19 +22,16 @@ import { selectUser, } from 'lbryinc'; import { doSetClientSetting } from 'redux/actions/settings'; -import { makeSelectClientSetting } from 'redux/selectors/settings'; import FirstRun from './view'; const select = state => ({ authenticating: selectAuthenticationIsPending(state), authToken: selectAuthToken(state), emailToVerify: selectEmailToVerify(state), - emailAlreadyExists: selectEmailAlreadyExists(state), emailNewErrorMessage: selectEmailNewErrorMessage(state), emailNewPending: selectEmailNewIsPending(state), hasSyncedWallet: selectHasSyncedWallet(state), getSyncIsPending: selectGetSyncIsPending(state), - language: makeSelectClientSetting(SETTINGS.LANGUAGE)(state), syncApplyErrorMessage: selectSyncApplyErrorMessage(state), syncApplyIsPending: selectSyncApplyIsPending(state), syncHash: selectSyncHash(state), @@ -44,11 +41,12 @@ const select = state => ({ const perform = dispatch => ({ addUserEmail: email => dispatch(doUserEmailNew(email)), - authenticate: (appVersion, os, firebaseToken) => dispatch(doAuthenticate(appVersion, os, firebaseToken)), + authenticate: (appVersion, os) => dispatch(doAuthenticate(appVersion, os)), setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)), syncApply: (hash, data, password) => dispatch(doSyncApply(hash, data, password)), - getSync: (password, callback) => dispatch(doGetSync(password, callback)), + getSync: password => dispatch(doGetSync(password)), checkSync: () => dispatch(doCheckSync()), + setDefaultAccount: () => dispatch(doSetDefaultAccount()), notify: data => dispatch(doToast(data)), resendVerificationEmail: email => dispatch(doUserResendVerificationEmail(email)), }); diff --git a/src/page/firstRun/internal/email-collect-page.js b/src/page/firstRun/internal/email-collect-page.js index 04c9b43..04bb651 100644 --- a/src/page/firstRun/internal/email-collect-page.js +++ b/src/page/firstRun/internal/email-collect-page.js @@ -3,7 +3,7 @@ import { Lbry } from 'lbry-redux'; import { NativeModules, Platform, Text, TextInput, View } from 'react-native'; import AsyncStorage from '@react-native-community/async-storage'; import Colors from 'styles/colors'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api +import Constants from 'constants'; import firstRunStyle from 'styles/firstRun'; class EmailCollectPage extends React.PureComponent { @@ -44,7 +44,7 @@ class EmailCollectPage extends React.PureComponent { const content = ( <View onLayout={() => onEmailViewLayout('collect')}> - <Text style={firstRunStyle.title}>{__('Setup account')}</Text> + <Text style={firstRunStyle.title}>Setup account</Text> <TextInput style={firstRunStyle.emailInput} placeholder={this.state.placeholder} @@ -64,10 +64,10 @@ class EmailCollectPage extends React.PureComponent { }} /> <Text style={firstRunStyle.paragraph}> - {__('A lbry.tv account allows you to earn rewards, backup your wallet, and keep everything in sync.')} + An account will allow you to earn rewards and keep your account and settings synced. </Text> <Text style={firstRunStyle.infoParagraph}> - {__('This information is disclosed only to LBRY, Inc. and not to the LBRY network.')} + This information is disclosed only to LBRY, Inc. and not to the LBRY network. </Text> </View> ); diff --git a/src/page/firstRun/internal/email-verify-page.js b/src/page/firstRun/internal/email-verify-page.js index 835849d..64f24ca 100644 --- a/src/page/firstRun/internal/email-verify-page.js +++ b/src/page/firstRun/internal/email-verify-page.js @@ -4,7 +4,7 @@ import { ActivityIndicator, Linking, NativeModules, Platform, Switch, Text, Text import AsyncStorage from '@react-native-community/async-storage'; import Button from 'component/button'; import Colors from 'styles/colors'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api +import Constants from 'constants'; import Icon from 'react-native-vector-icons/FontAwesome5'; import firstRunStyle from 'styles/firstRun'; @@ -13,30 +13,28 @@ class EmailVerifyPage extends React.PureComponent { const { email, notify, resendVerificationEmail } = this.props; resendVerificationEmail(email); AsyncStorage.setItem(Constants.KEY_EMAIL_VERIFY_PENDING, 'true'); - notify({ message: __('Please follow the instructions in the email sent to your address to continue.') }); + notify({ message: 'Please follow the instructions in the email sent to your address to continue.' }); }; render() { - const { onEmailViewLayout, email, emailAlreadyExists } = this.props; + const { onEmailViewLayout, email } = this.props; const content = ( <View onLayout={() => onEmailViewLayout('verify')}> - <Text style={firstRunStyle.title}>{emailAlreadyExists ? __('Sign In') : __('Verify Email')}</Text> - + <Text style={firstRunStyle.title}>Verify Email</Text> <Text style={firstRunStyle.paragraph}> - {__('An email has been sent to')} - {'\n\n'} - {email} - {'\n\n'} - {emailAlreadyExists && __('Please click the link in the message to complete signing in')} - {!emailAlreadyExists && __('Please click the link in the message to verify your email address')}. + An email has been sent to{' '} + <Text style={firstRunStyle.nowrap} numberOfLines={1}> + {email} + </Text> + . Please follow the instructions in the message to verify your email address. </Text> <View style={firstRunStyle.buttonContainer}> <Button style={firstRunStyle.verificationButton} theme={'light'} - text={__('Resend')} + text={'Resend'} onPress={this.onResendPressed} /> </View> diff --git a/src/page/firstRun/internal/skip-account-page.js b/src/page/firstRun/internal/skip-account-page.js index a4973bf..254e800 100644 --- a/src/page/firstRun/internal/skip-account-page.js +++ b/src/page/firstRun/internal/skip-account-page.js @@ -12,7 +12,7 @@ import { View, } from 'react-native'; import Colors from 'styles/colors'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api +import Constants from 'constants'; import Icon from 'react-native-vector-icons/FontAwesome5'; import firstRunStyle from 'styles/firstRun'; @@ -28,10 +28,10 @@ class SkipAccountPage extends React.PureComponent { <View onLayout={onSkipAccountViewLayout}> <View style={firstRunStyle.row}> <Icon name="exclamation-triangle" style={firstRunStyle.titleIcon} size={32} color={Colors.White} /> - <Text style={firstRunStyle.title}>{__('Are you sure?')}</Text> + <Text style={firstRunStyle.title}>Are you sure?</Text> </View> <Text style={firstRunStyle.paragraph}> - {__('Without an account, you will not receive rewards, sync and backup services, or security updates.')} + Without an account, you will not receive rewards, sync and backup services, or security updates. </Text> <View style={[firstRunStyle.row, firstRunStyle.confirmContainer]}> @@ -45,9 +45,8 @@ class SkipAccountPage extends React.PureComponent { /> </View> <Text style={firstRunStyle.rowParagraph}> - {__( - 'I understand that by uninstalling LBRY I will lose any balances or published content with no recovery option if it is not backed up manually (see wallet page)' - )} + I understand that by uninstalling LBRY I will lose any balances or published content with no recovery + option. </Text> </View> </View> diff --git a/src/page/firstRun/internal/wallet-page.js b/src/page/firstRun/internal/wallet-page.js index 981c2ff..f1b1cfb 100644 --- a/src/page/firstRun/internal/wallet-page.js +++ b/src/page/firstRun/internal/wallet-page.js @@ -14,7 +14,7 @@ import { import { BarPasswordStrengthDisplay } from 'react-native-password-strength-meter'; import AsyncStorage from '@react-native-community/async-storage'; import Colors from 'styles/colors'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api +import Constants from 'constants'; import firstRunStyle from 'styles/firstRun'; import Icon from 'react-native-vector-icons/FontAwesome5'; @@ -28,32 +28,12 @@ class WalletPage extends React.PureComponent { walletReady: false, hasCheckedSync: false, revealPassword: false, - autoPassword: false, - autoLoginAttempted: false, }; componentDidMount() { this.checkWalletReady(); } - componentDidUpdate() { - const { hasSyncedWallet, getSyncIsPending, onPasswordChanged, autoLogin } = this.props; - if (this.state.walletReady && this.state.hasCheckedSync && !getSyncIsPending) { - if (!hasSyncedWallet && !this.state.autoPassword) { - // new account, in which case, don't ask for a password, and act as the final first run step - this.setState({ password: '', autoPassword: true }); - if (onPasswordChanged) { - onPasswordChanged('', true); - } - } - - if (hasSyncedWallet && !this.state.autoLoginAttempted && autoLogin) { - autoLogin(); - this.setState({ autoLoginAttempted: true }); - } - } - } - checkWalletReady = () => { // make sure the sdk wallet component is ready Lbry.status() @@ -82,42 +62,31 @@ class WalletPage extends React.PureComponent { }; render() { - const { - onPasswordChanged, - onWalletViewLayout, - getSyncIsPending, - hasSyncedWallet, - syncApplyIsPending, - syncApplyStarted, - syncApplyCompleted, - } = this.props; + const { onPasswordChanged, onWalletViewLayout, getSyncIsPending, hasSyncedWallet, syncApplyIsPending } = this.props; let content; if (!this.state.walletReady || !this.state.hasCheckedSync || getSyncIsPending) { content = ( <View style={firstRunStyle.centered}> <ActivityIndicator size="large" color={Colors.White} style={firstRunStyle.waiting} /> - <Text style={firstRunStyle.paragraph}>{__('Retrieving your account information...')}</Text> + <Text style={firstRunStyle.paragraph}>Retrieving your account information...</Text> </View> ); - } else if (syncApplyStarted || syncApplyIsPending || syncApplyCompleted) { + } else if (syncApplyIsPending) { content = ( <View style={firstRunStyle.centered}> <ActivityIndicator size="large" color={Colors.White} style={firstRunStyle.waiting} /> - <Text style={firstRunStyle.paragraph}> - {syncApplyIsPending ? __('Validating password') : __('Synchronizing')}... - </Text> + <Text style={firstRunStyle.paragraph}>Validating password...</Text> </View> ); - } else if (hasSyncedWallet && this.state.autoLoginAttempted) { - // only display this view if it's not a new user (or auto-login has been attempted once) + } else { content = ( <View onLayout={onWalletViewLayout}> - <Text style={firstRunStyle.title}>{__('Password')}</Text> + <Text style={firstRunStyle.title}>Password</Text> <Text style={firstRunStyle.paragraph}> {hasSyncedWallet - ? __('Please enter the password you used to secure your wallet.') - : __('Please enter a password to secure your account and wallet.')} + ? 'Please enter the password you used to secure your wallet.' + : 'Please enter a password to secure your account and wallet.'} </Text> <View style={firstRunStyle.passwordInputContainer}> <TextInput @@ -146,6 +115,15 @@ class WalletPage extends React.PureComponent { <Icon name={this.state.revealPassword ? 'eye-slash' : 'eye'} size={16} style={firstRunStyle.revealIcon} /> </TouchableOpacity> </View> + {(!this.state.password || this.state.password.trim().length === 0) && ( + <View style={firstRunStyle.passwordWarning}> + <Text style={firstRunStyle.passwordWarningText}> + {hasSyncedWallet + ? 'If you did not provide a password, please press Use LBRY to continue.' + : 'You can proceed without a password, but this is not recommended.'} + </Text> + </View> + )} {(!hasSyncedWallet && this.state.password && this.state.password.trim().length) > 0 && ( <View style={firstRunStyle.passwordStrength}> @@ -157,7 +135,7 @@ class WalletPage extends React.PureComponent { </View> )} <Text style={firstRunStyle.infoParagraph}> - {__('Note: for wallet security purposes, LBRY is unable to reset your password.')} + Note: for wallet security purposes, LBRY is unable to reset your password. </Text> </View> ); diff --git a/src/page/firstRun/internal/welcome-page.js b/src/page/firstRun/internal/welcome-page.js index b3c5b87..04c80c2 100644 --- a/src/page/firstRun/internal/welcome-page.js +++ b/src/page/firstRun/internal/welcome-page.js @@ -3,8 +3,7 @@ import { Lbry } from 'lbry-redux'; import { ActivityIndicator, NativeModules, Platform, Text, View } from 'react-native'; import AsyncStorage from '@react-native-community/async-storage'; import Colors from 'styles/colors'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api -import Link from 'component/link'; +import Constants from 'constants'; import firstRunStyle from 'styles/firstRun'; class WelcomePage extends React.PureComponent { @@ -26,7 +25,7 @@ class WelcomePage extends React.PureComponent { } else { // first_user_auth because it's the first time AsyncStorage.getItem(Constants.KEY_FIRST_USER_AUTH).then(firstUserAuth => { - if (firstUserAuth !== 'true') { + if ('true' !== firstUserAuth) { // first_user_auth NativeModules.Firebase.track('first_user_auth', null); AsyncStorage.setItem(Constants.KEY_FIRST_USER_AUTH, 'true'); @@ -45,39 +44,31 @@ class WelcomePage extends React.PureComponent { } startAuthenticating = () => { + const { authenticate } = this.props; this.setState({ authenticationStarted: true, authenticationFailed: false }); NativeModules.VersionInfo.getAppVersion().then(appVersion => { - NativeModules.Firebase.getMessagingToken() - .then(firebaseToken => this.performAuthenticate(appVersion, firebaseToken)) - .catch(() => { - this.performAuthenticate(appVersion); /* proceed without firebase */ + Lbry.status() + .then(info => { + this.setState({ sdkStarted: true }); + + authenticate(appVersion, Platform.OS); + }) + .catch(error => { + if (this.state.statusTries >= WelcomePage.MAX_STATUS_TRIES) { + this.setState({ authenticationFailed: true }); + + // sdk_start_failed + NativeModules.Firebase.track('sdk_start_failed', null); + } else { + setTimeout(() => { + this.startAuthenticating(); + this.setState({ statusTries: this.state.statusTries + 1 }); + }, 1000); // Retry every second for a maximum of MAX_STATUS_TRIES tries (60 seconds) + } }); }); }; - performAuthenticate(appVersion, firebaseToken) { - const { authenticate } = this.props; - Lbry.status() - .then(info => { - this.setState({ sdkStarted: true }); - - authenticate(appVersion, Platform.OS, firebaseToken); - }) - .catch(error => { - if (this.state.statusTries >= WelcomePage.MAX_STATUS_TRIES) { - this.setState({ authenticationFailed: true }); - - // sdk_start_failed - NativeModules.Firebase.track('sdk_start_failed', null); - } else { - setTimeout(() => { - this.startAuthenticating(); - this.setState({ statusTries: this.state.statusTries + 1 }); - }, 1000); // Retry every second for a maximum of MAX_STATUS_TRIES tries (60 seconds) - } - }); - } - render() { const { authenticating, authToken, onWelcomePageLayout } = this.props; @@ -87,9 +78,8 @@ class WelcomePage extends React.PureComponent { content = ( <View> <Text style={firstRunStyle.paragraph}> - {__( - 'The LBRY servers were unreachable at this time. Please check your Internet connection and then restart the app to try again.' - )} + The LBRY servers were unreachable at this time. Please check your Internet connection and then restart the + app to try again. </Text> </View> ); @@ -97,22 +87,16 @@ class WelcomePage extends React.PureComponent { content = ( <View style={firstRunStyle.centered}> <ActivityIndicator size="large" color={Colors.White} style={firstRunStyle.waiting} /> - <Text style={firstRunStyle.paragraph}>{__('Please wait while we get some things ready...')}</Text> + <Text style={firstRunStyle.paragraph}>Please wait while we get some things ready...</Text> </View> ); } else { content = ( <View onLayout={onWelcomePageLayout}> - <Text style={firstRunStyle.title}>{__('Welcome to LBRY.')}</Text> + <Text style={firstRunStyle.title}>Welcome to LBRY.</Text> <Text style={firstRunStyle.paragraph}> - {__( - 'LBRY is a community-controlled content platform where you can find and publish videos, music, books, and more.' - )} - </Text> - <Text style={[firstRunStyle.infoParagraph, firstRunStyle.tosParagraph]}> - By continuing, I agree to the{' '} - <Link style={firstRunStyle.tosLink} text={'Terms of Service'} href={'https://lbry.com/termsofservice'} />{' '} - and confirm I am over the age of 13. + LBRY is a community-controlled content platform where you can find and publish videos, music, books, and + more. </Text> </View> ); diff --git a/src/page/firstRun/view.js b/src/page/firstRun/view.js index d7a156e..816c6af 100644 --- a/src/page/firstRun/view.js +++ b/src/page/firstRun/view.js @@ -1,17 +1,16 @@ import React from 'react'; -import { SETTINGS, Lbry } from 'lbry-redux'; +import { Lbry } from 'lbry-redux'; import { ActivityIndicator, Linking, NativeModules, Text, TouchableOpacity, View } from 'react-native'; import { NavigationActions, StackActions } from 'react-navigation'; import AsyncStorage from '@react-native-community/async-storage'; import Colors from 'styles/colors'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api +import Constants from 'constants'; import WalletPage from './internal/wallet-page'; import WelcomePage from './internal/welcome-page'; import EmailCollectPage from './internal/email-collect-page'; import EmailVerifyPage from './internal/email-verify-page'; import SkipAccountPage from './internal/skip-account-page'; import firstRunStyle from 'styles/firstRun'; -import RNFS from 'react-native-fs'; class FirstRunScreen extends React.PureComponent { static pages = [ @@ -28,17 +27,14 @@ class FirstRunScreen extends React.PureComponent { emailCollectTracked: false, emailSubmitted: false, enterPasswordTracked: false, - autoLoginTried: false, isFirstRun: false, launchUrl: null, - languageLoaded: false, showSkip: false, isEmailVerified: false, skipAccountConfirmed: false, showBottomContainer: false, - walletPassword: '', + walletPassword: null, syncApplyStarted: false, - syncApplyCompleted: false, }; componentDidMount() { @@ -48,70 +44,28 @@ class FirstRunScreen extends React.PureComponent { } }); - NativeModules.UtilityModule.getNativeStringSetting(SETTINGS.LANGUAGE, 'en').then(language => - this.loadLanguage(language) - ); - } + if (NativeModules.FirstRun) { + NativeModules.FirstRun.isFirstRun().then(firstRun => { + AsyncStorage.removeItem(Constants.KEY_FIRST_RUN_EMAIL); + AsyncStorage.removeItem(Constants.KEY_EMAIL_VERIFY_PENDING); + this.setState({ isFirstRun: firstRun }); - loadLanguage = language => { - if (!language || language === 'en') { - this.checkFirstRun(); - } else { - // Load the current language setting before doing anything - const languageFile = RNFS.ExternalDirectoryPath + '/' + language + '.json'; - RNFS.readFile(languageFile, 'utf8') - .then(fileContents => { - const json = JSON.parse(fileContents); - window.language = language; - window.i18n_messages[language] = json; - // language exists, so download an update - this.downloadLanguageUpdate(language); - this.checkFirstRun(); - }) - .catch(err => { - // language file doesn't exist? maintain the default language - this.checkFirstRun(); - }); - } - }; - - downloadLanguageUpdate = language => { - fetch('https://lbry.com/i18n/get/lbry-mobile/app-strings/' + language + '.json') - .then(r => r.json()) - .then(j => { - window.i18n_messages[language] = j; - - // write the language file to the filesystem - const langFilePath = RNFS.ExternalDirectoryPath + '/' + language + '.json'; - RNFS.writeFile(langFilePath, JSON.stringify(j), 'utf8'); - - // update state and client setting - window.language = language; - }) - .catch(() => { - /* pass */ + if (firstRun) { + this.setState({ currentPage: FirstRunScreen.pages[0] }); + } else { + // Not the first run. Navigate to the splash screen right away + this.launchSplashScreen(); + } }); - }; - - checkFirstRun = () => { - NativeModules.FirstRun.isFirstRun().then(firstRun => { - AsyncStorage.removeItem(Constants.KEY_FIRST_RUN_EMAIL); - AsyncStorage.removeItem(Constants.KEY_EMAIL_VERIFY_PENDING); - this.setState({ isFirstRun: firstRun }); - - if (firstRun) { - NativeModules.Firebase.setCurrentScreen('First Run'); - this.setState({ currentPage: FirstRunScreen.pages[0] }); - } else { - // Not the first run. Navigate to the splash screen right away - this.launchSplashScreen(); - } - }); - }; + } else { + // The first run module was not detected. Go straight to the splash screen. + this.launchSplashScreen(); + } + } componentWillReceiveProps(nextProps) { const { emailNewErrorMessage, emailNewPending, syncApplyErrorMessage, syncApplyIsPending, user } = nextProps; - const { notify, isApplyingSync, setClientSetting } = this.props; + const { notify, isApplyingSync, setClientSetting, setDefaultAccount } = this.props; if (this.state.emailSubmitted && !emailNewPending) { this.setState({ emailSubmitted: false }); @@ -119,49 +73,23 @@ class FirstRunScreen extends React.PureComponent { notify({ message: String(emailNewErrorMessage), isError: true }); } else { // Request successful. Navigate to email verify page. - NativeModules.Firebase.track('email_added', { email: this.state.email }); this.showPage(Constants.FIRST_RUN_PAGE_EMAIL_VERIFY); } } if (this.state.syncApplyStarted && !syncApplyIsPending) { + this.setState({ syncApplyStarted: false }); if (syncApplyErrorMessage && syncApplyErrorMessage.trim().length > 0) { - if (this.state.autoLoginTried) { - // don't show the error message for auto-login if it fails - notify({ message: __(syncApplyErrorMessage), isError: true }); - } - this.setState({ - autoLoginTried: true, - showBottomContainer: true, - syncApplyStarted: false, - syncApplyCompleted: false, - }); + notify({ message: syncApplyErrorMessage, isError: true }); + this.setState({ showBottomContainer: true }); } else { - this.setState({ syncApplyCompleted: true }); // password successfully verified - NativeModules.UtilityModule.setSecureValue( - Constants.KEY_WALLET_PASSWORD, - this.state.walletPassword ? this.state.walletPassword : '' - ); - + if (NativeModules.UtilityModule) { + NativeModules.UtilityModule.setSecureValue(Constants.KEY_FIRST_RUN_PASSWORD, this.state.walletPassword); + } + setDefaultAccount(); setClientSetting(Constants.SETTING_DEVICE_WALLET_SYNCED, true); - Lbry.wallet_status().then(status => { - // unlock the wallet - if (status.is_locked) { - Lbry.wallet_unlock({ password: this.state.walletPassword ? this.state.walletPassword : '' }).then( - unlocked => { - if (unlocked) { - this.closeFinalPage(); - } else { - notify({ message: __('The wallet could not be unlocked at this time. Please restart the app.') }); - } - } - ); - } else { - // wallet not locked. close final page - this.closeFinalPage(); - } - }); + this.closeFinalPage(); } } @@ -187,9 +115,9 @@ class FirstRunScreen extends React.PureComponent { const { navigation } = this.props; const resetAction = StackActions.reset({ index: 0, - actions: [NavigationActions.navigate({ routeName: 'Splash', params: { launchUri: this.state.launchUrl } })], + actions: [NavigationActions.navigate({ routeName: 'Splash', params: { launchUri: this.state.launchUri } })], }); - setTimeout(() => navigation.dispatch(resetAction), 1000); + navigation.dispatch(resetAction); } handleLeftButtonPressed = () => { @@ -218,23 +146,10 @@ class FirstRunScreen extends React.PureComponent { }); }; - autoLogin = () => { - const { hasSyncedWallet } = this.props; - if (hasSyncedWallet && !this.state.syncApplyStarted) { - this.checkWalletPassword(); - } - }; - handleContinuePressed = () => { const { notify, user, hasSyncedWallet } = this.props; const pageIndex = FirstRunScreen.pages.indexOf(this.state.currentPage); - - if (Constants.FIRST_RUN_PAGE_WELCOME === this.state.currentPage) { - // only show the welcome screen on first run - this.closeFinalPage(); - } - - /* if (Constants.FIRST_RUN_PAGE_WALLET === this.state.currentPage) { + if (Constants.FIRST_RUN_PAGE_WALLET === this.state.currentPage) { // do apply sync to check if the password is valid if (hasSyncedWallet) { this.checkWalletPassword(); @@ -245,7 +160,7 @@ class FirstRunScreen extends React.PureComponent { } if (Constants.FIRST_RUN_PAGE_SKIP_ACCOUNT === this.state.currentPage && !this.state.skipAccountConfirmed) { - notify({ message: __('Please confirm that you want to use LBRY without creating an account.') }); + notify({ message: 'Please confirm that you want to use LBRY without creating an account.' }); return; } @@ -262,7 +177,7 @@ class FirstRunScreen extends React.PureComponent { } else { this.showNextPage(); } - } */ + } }; handleEmailCollectPageContinue() { @@ -271,7 +186,7 @@ class FirstRunScreen extends React.PureComponent { // validate the email if (!email || email.indexOf('@') === -1) { return notify({ - message: __('Please provide a valid email address to continue.'), + message: 'Please provide a valid email address to continue.', }); } @@ -303,7 +218,6 @@ class FirstRunScreen extends React.PureComponent { closeFinalPage() { // Final page. Let the app know that first run experience is completed. - this.setState({ syncApplyStarted: false }); if (NativeModules.FirstRun) { NativeModules.FirstRun.firstRunCompleted(); } @@ -314,34 +228,30 @@ class FirstRunScreen extends React.PureComponent { onEmailChanged = email => { this.setState({ email }); - if (Constants.FIRST_RUN_PAGE_EMAIL_COLLECT === this.state.currentPage) { - this.setState({ showSkip: !email || typeof email !== 'string' || email.trim().length === 0 }); + if (Constants.FIRST_RUN_PAGE_EMAIL_COLLECT == this.state.currentPage) { + this.setState({ showSkip: !email || email.trim().length === 0 }); } else { this.setState({ showSkip: false }); } }; onEmailViewLayout = phase => { - if (phase === 'collect') { + if ('collect' === phase) { if (!this.state.emailCollectTracked) { // we only want to track this once this.setState({ emailCollectTracked: true }, () => NativeModules.Firebase.track('first_run_email_collect', null) ); } - } else if (phase === 'verify') { + } else if ('verify' === phase) { NativeModules.Firebase.track('first_run_email_verify', null); } this.setState({ showBottomContainer: true, showSkip: true }); }; - onWalletPasswordChanged = (password, finalStep) => { - this.setState({ walletPassword: password !== null ? password : '' }); - if (finalStep) { - // final step for a new user - this.setFreshPassword(); - } + onWalletPasswordChanged = password => { + this.setState({ walletPassword: password }); }; onWalletViewLayout = () => { @@ -370,20 +280,13 @@ class FirstRunScreen extends React.PureComponent { const { getSync, setClientSetting } = this.props; if (NativeModules.UtilityModule) { const newPassword = this.state.walletPassword ? this.state.walletPassword : ''; - NativeModules.UtilityModule.setSecureValue(Constants.KEY_WALLET_PASSWORD, newPassword); - if (newPassword.trim().length === 0) { - // blank password. Do not encrypt + NativeModules.UtilityModule.setSecureValue(Constants.KEY_FIRST_RUN_PASSWORD, newPassword); + Lbry.account_encrypt({ new_password: newPassword }).then(() => { + // fresh account, new password set getSync(newPassword); setClientSetting(Constants.SETTING_DEVICE_WALLET_SYNCED, true); this.closeFinalPage(); - } else { - Lbry.wallet_encrypt({ new_password: newPassword }).then(() => { - // fresh account, new password set - getSync(newPassword); - setClientSetting(Constants.SETTING_DEVICE_WALLET_SYNCED, true); - this.closeFinalPage(); - }); - } + }); } }; @@ -393,11 +296,9 @@ class FirstRunScreen extends React.PureComponent { authenticating, authToken, checkSync, - emailAlreadyExists, emailNewErrorMessage, emailNewPending, emailToVerify, - language, notify, hasSyncedWallet, getSyncIsPending, @@ -435,7 +336,6 @@ class FirstRunScreen extends React.PureComponent { <EmailVerifyPage onEmailViewLayout={this.onEmailViewLayout} email={this.state.email} - emailAlreadyExists={emailAlreadyExists} notify={notify} resendVerificationEmail={resendVerificationEmail} /> @@ -449,11 +349,8 @@ class FirstRunScreen extends React.PureComponent { hasSyncedWallet={hasSyncedWallet} getSyncIsPending={getSyncIsPending} syncApplyIsPending={syncApplyIsPending} - syncApplyStarted={this.state.syncApplyStarted} - syncApplyCompleted={this.state.syncApplyCompleted} onWalletViewLayout={this.onWalletViewLayout} onPasswordChanged={this.onWalletPasswordChanged} - autoLogin={this.autoLogin} /> ); break; @@ -486,34 +383,29 @@ class FirstRunScreen extends React.PureComponent { <Text style={firstRunStyle.buttonText}> «{' '} {Constants.FIRST_RUN_PAGE_SKIP_ACCOUNT === this.state.currentPage - ? __('Setup account') - : __('Change email')} + ? 'Setup account' + : 'Change email'} </Text> </TouchableOpacity> )} {!emailNewPending && Constants.FIRST_RUN_PAGE_EMAIL_COLLECT === this.state.currentPage && ( <TouchableOpacity style={firstRunStyle.leftButton} onPress={this.handleLeftButtonPressed}> - <Text style={firstRunStyle.smallLeftButtonText}>{__('No, thanks')} »</Text> + <Text style={firstRunStyle.smallLeftButtonText}>No, thanks »</Text> </TouchableOpacity> )} {!emailNewPending && ( <TouchableOpacity style={firstRunStyle.button} onPress={this.handleContinuePressed}> {Constants.FIRST_RUN_PAGE_SKIP_ACCOUNT === this.state.currentPage && ( - <Text style={firstRunStyle.smallButtonText}>{__('Use LBRY')} »</Text> + <Text style={firstRunStyle.smallButtonText}>Use LBRY »</Text> )} {Constants.FIRST_RUN_PAGE_SKIP_ACCOUNT !== this.state.currentPage && Constants.FIRST_RUN_PAGE_EMAIL_VERIFY !== this.state.currentPage && ( - <Text style={firstRunStyle.buttonText}> - {[Constants.FIRST_RUN_PAGE_WALLET, Constants.FIRST_RUN_PAGE_WELCOME].includes( - this.state.currentPage - ) - ? __('Use LBRY') - : __('Continue')}{' '} - » - </Text> - )} + <Text style={firstRunStyle.buttonText}> + {Constants.FIRST_RUN_PAGE_WALLET === this.state.currentPage ? 'Use LBRY' : 'Continue'} » + </Text> + )} </TouchableOpacity> )} </View> diff --git a/src/page/invites/index.js b/src/page/invites/index.js deleted file mode 100644 index ad1c35c..0000000 --- a/src/page/invites/index.js +++ /dev/null @@ -1,42 +0,0 @@ -import { connect } from 'react-redux'; -import { selectMyChannelClaims, selectFetchingMyChannels, doFetchChannelListMine, doToast } from 'lbry-redux'; -import { - selectReferralReward, - selectUserInvitesRemaining, - selectUserInviteNewIsPending, - selectUserInviteNewErrorMessage, - selectUserInviteReferralLink, - selectUserInviteReferralCode, - selectUserInvitees, - selectUserInviteStatusIsPending, - doFetchInviteStatus, - doUserInviteNew, -} from 'lbryinc'; -import { doPushDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer'; -import { selectSdkReady } from 'redux/selectors/settings'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api -import InvitesPage from './view'; - -const select = state => ({ - channels: selectMyChannelClaims(state), - errorMessage: selectUserInviteNewErrorMessage(state), - fetchingChannels: selectFetchingMyChannels(state), - fetchingInvitees: selectUserInviteStatusIsPending(state), - invitees: selectUserInvitees(state), - invitesRemaining: selectUserInvitesRemaining(state), - isPending: selectUserInviteNewIsPending(state), - referralCode: selectUserInviteReferralCode(state), - referralReward: selectReferralReward(state), - sdkReady: selectSdkReady(state), -}); - -const perform = dispatch => ({ - fetchChannelListMine: () => dispatch(doFetchChannelListMine(1, 99999, true)), - fetchInviteStatus: () => dispatch(doFetchInviteStatus()), - inviteNew: email => dispatch(doUserInviteNew(email)), - pushDrawerStack: () => dispatch(doPushDrawerStack(Constants.DRAWER_ROUTE_INVITES)), - setPlayerVisible: () => dispatch(doSetPlayerVisible(false)), - notify: data => dispatch(doToast(data)), -}); - -export default connect(select, perform)(InvitesPage); diff --git a/src/page/invites/view.js b/src/page/invites/view.js deleted file mode 100644 index f5e3776..0000000 --- a/src/page/invites/view.js +++ /dev/null @@ -1,253 +0,0 @@ -import React from 'react'; -import { Lbry, parseURI } from 'lbry-redux'; -import { - ActivityIndicator, - Clipboard, - NativeModules, - ScrollView, - Text, - TextInput, - TouchableOpacity, - View, -} from 'react-native'; -import Colors from 'styles/colors'; -import Icon from 'react-native-vector-icons/FontAwesome5'; -import Button from 'component/button'; -import ChannelSelector from 'component/channelSelector'; -import EmptyStateView from 'component/emptyStateView'; -import UriBar from 'component/uriBar'; -import invitesStyle from 'styles/invites'; -import { fetchReferralCode, logPublish } from 'utils/helper'; - -class InvitesPage extends React.PureComponent { - state = { - channelName: null, - email: null, - inviteLink: null, - selectedChannel: null, - }; - - componentWillMount() { - const { navigation } = this.props; - // this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused); - } - - componentWillUnmount() { - if (this.didFocusListener) { - this.didFocusListener.remove(); - } - } - - onComponentFocused = () => { - const { fetchChannelListMine, fetchInviteStatus, pushDrawerStack, navigation, setPlayerVisible, user } = this.props; - - pushDrawerStack(); - setPlayerVisible(); - NativeModules.Firebase.setCurrentScreen('Invites').then(result => { - fetchReferralCode( - response => { - if (response && response.length > 0) { - // only need to use the first referral code. - // inviteLink will be updated after channels are loaded (if the user has created at least one channel) - this.setState({ inviteLink: `https://lbry.tv/$/invite/${response[0]}` }); - } - fetchChannelListMine(); - }, - error => { - fetchChannelListMine(); - }, - ); - fetchInviteStatus(); - }); - }; - - componentDidMount() { - this.onComponentFocused(); - } - - handleChannelChange = channelName => { - const { channels = [] } = this.props; - if (channels && channels.length > 0) { - const filtered = channels.filter(c => c.name === channelName); - if (filtered.length > 0) { - const channel = filtered[0]; - logPublish(channel); - this.setState({ channelName, inviteLink: this.getLinkForChannel(channel) }); - } - } - }; - - getLinkForChannel = channel => { - const parsedUrl = channel.canonical_url ? parseURI(channel.canonical_url) : parseURI(channel.permanent_url); - const { claimId, claimName } = parsedUrl; - return `https://lbry.tv/$/invite/${claimName}:${claimId}`; - }; - - handleInviteEmailChange = text => { - this.setState({ email: text }); - }; - - handleInvitePress = () => { - const { inviteNew, notify } = this.props; - const { email } = this.state; - if (!email || email.indexOf('@') === -1) { - return notify({ - message: __('Please enter a valid email address to send an invite to.'), - isError: true, - }); - } - - inviteNew(email); - }; - - componentWillReceiveProps(nextProps) { - const { isPending: prevPending, notify } = this.props; - const { channels = [], isPending, errorMessage } = nextProps; - const { email } = this.state; - - if (!this.state.channelName && channels && channels.length > 0) { - const firstChannel = channels[0]; - logPublish(firstChannel); - this.setState({ channelName: firstChannel.name, inviteLink: this.getLinkForChannel(firstChannel) }); - } - - if (prevPending && !isPending) { - if (errorMessage && errorMessage.trim().length > 0) { - notify({ message: errorMessage, isError: true }); - } else { - notify({ message: __(`${email} was invited to the LBRY party!`) }); - this.setState({ email: null }); - } - } - } - - handleInviteLinkPress = () => { - const { notify } = this.props; - Clipboard.setString(this.state.inviteLink); - notify({ - message: __('Invite link copied'), - }); - }; - - render() { - const { fetchingInvitees, invitees, isPending, navigation, sdkReady } = this.props; - const { email } = this.state; - const hasInvitees = invitees && invitees.length > 0; - - if (!sdkReady) { - return ( - <View style={invitesStyle.container}> - <UriBar navigation={navigation} /> - <EmptyStateView - message={__( - 'The background service is still initializing. You can still explore and watch content during the initialization process.', - )} - /> - </View> - ); - } - - return ( - <View style={invitesStyle.container}> - <UriBar navigation={navigation} /> - - <ScrollView style={invitesStyle.scrollContainer}> - <TouchableOpacity style={invitesStyle.rewardDriverCard} onPress={() => navigation.navigate('Rewards')}> - <Icon name="award" size={16} style={invitesStyle.rewardDriverIcon} /> - <Text style={invitesStyle.rewardDriverText}>{__('Earn rewards for inviting your friends.')}</Text> - </TouchableOpacity> - - <View style={invitesStyle.card}> - <Text style={invitesStyle.title}>{__('Invite Link')}</Text> - <Text style={invitesStyle.text}> - {__('Share this link with friends (or enemies) and get 20 LBC when they join lbry.tv')} - </Text> - - <Text style={invitesStyle.subTitle}>{__('Your invite link')}</Text> - <View style={invitesStyle.row}> - <Text selectable numberOfLines={1} style={invitesStyle.inviteLink} onPress={this.handleInviteLinkPress}> - {this.state.inviteLink} - </Text> - <Button icon={'clipboard'} style={invitesStyle.button} onPress={this.handleInviteLinkPress} /> - </View> - - <Text style={invitesStyle.customizeTitle}>{__('Customize invite link')}</Text> - <ChannelSelector - showAnonymous={false} - channelName={this.state.channelName} - onChannelChange={this.handleChannelChange} - /> - </View> - - <View style={invitesStyle.card}> - <Text style={invitesStyle.title}>{__('Invite by Email')}</Text> - <Text style={invitesStyle.text}> - {__('Invite someone you know by email and earn 20 LBC when they join lbry.tv.')} - </Text> - - <TextInput - style={invitesStyle.emailInput} - editable={!isPending} - value={this.state.email} - onChangeText={this.handleInviteEmailChange} - placeholder={__('imaginary@friend.com')} - underlineColorAndroid={Colors.NextLbryGreen} - /> - <View style={invitesStyle.rightRow}> - {isPending && ( - <ActivityIndicator size={'small'} color={Colors.NextLbryGreen} style={invitesStyle.loading} /> - )} - <Button - disabled={!email || email.indexOf('@') === -1 || isPending} - style={invitesStyle.button} - text={__('Invite')} - onPress={this.handleInvitePress} - /> - </View> - </View> - - <View style={[invitesStyle.card, invitesStyle.lastCard]}> - <View style={invitesStyle.titleRow}> - <Text style={invitesStyle.titleCol}>{__('Invite History')}</Text> - {fetchingInvitees && <ActivityIndicator size={'small'} color={Colors.NextLbryGreen} />} - </View> - - <Text style={invitesStyle.text}> - {__( - 'Earn 20 LBC for inviting a friend, an enemy, a frenemy, or an enefriend. Everyone needs content freedom.', - )} - </Text> - - <View style={invitesStyle.invitees}> - {hasInvitees && ( - <View style={invitesStyle.inviteesHeader}> - <Text style={invitesStyle.emailHeader} numberOfLines={1}> - {__('Email')} - </Text> - <Text style={invitesStyle.rewardHeader} numberOfLines={1}> - {__('Reward')} - </Text> - </View> - )} - {hasInvitees && - invitees.map(invitee => ( - <View key={invitee.email} style={invitesStyle.inviteeItem}> - <Text style={invitesStyle.inviteeEmail} numberOfLines={1}> - {invitee.email} - </Text> - <Text style={invitesStyle.rewardStatus} numberOfLines={1}> - {invitee.invite_reward_claimed && __('Claimed')} - {!invitee.invite_reward_claimed && - (invitee.invite_reward_claimable ? __('Claimable') : __('Unclaimable'))} - </Text> - </View> - ))} - </View> - </View> - </ScrollView> - </View> - ); - } -} - -export default InvitesPage; diff --git a/src/page/liteFile/index.js b/src/page/liteFile/index.js deleted file mode 100644 index 533d439..0000000 --- a/src/page/liteFile/index.js +++ /dev/null @@ -1,28 +0,0 @@ -import { connect } from 'react-redux'; -import { makeSelectContentPositionForUri, selectBalance } from 'lbry-redux'; -import { doClaimEligiblePurchaseRewards, makeSelectViewCountForUri, selectRewardContentClaimIds } from 'lbryinc'; -import { doSetPlayerVisible } from 'redux/actions/drawer'; -import { makeSelectPlayerVisible } from 'redux/selectors/drawer'; -import { doToggleFullscreenMode } from 'redux/actions/settings'; -import LiteFilePage from './view'; - -const select = (state, props) => { - const { uri, fullUri } = props.navigation.state.params; - const contentUri = fullUri || uri; - const selectProps = { uri: contentUri }; - return { - balance: selectBalance(state), - isPlayerVisible: makeSelectPlayerVisible(uri)(state), // use navigation uri for this selector - position: makeSelectContentPositionForUri(contentUri)(state), - viewCount: makeSelectViewCountForUri(contentUri)(state), - rewardedContentClaimIds: selectRewardContentClaimIds(state), - }; -}; - -const perform = dispatch => ({ - claimEligibleRewards: () => dispatch(doClaimEligiblePurchaseRewards()), - setPlayerVisible: (visible, uri) => dispatch(doSetPlayerVisible(visible, uri)), - toggleFullscreenMode: mode => dispatch(doToggleFullscreenMode(mode)), -}); - -export default connect(select, perform)(LiteFilePage); diff --git a/src/page/liteFile/view.js b/src/page/liteFile/view.js deleted file mode 100644 index f2511a0..0000000 --- a/src/page/liteFile/view.js +++ /dev/null @@ -1,297 +0,0 @@ -import React from 'react'; -import { Lbry, formatCredits, normalizeURI, parseURI, parseQueryParams } from 'lbry-redux'; -import { Lbryio } from 'lbryinc'; -import { - ActivityIndicator, - Alert, - DeviceEventEmitter, - Dimensions, - Image, - Linking, - NativeModules, - Platform, - ScrollView, - StatusBar, - StyleSheet, - Text, - TextInput, - TouchableOpacity, - TouchableWithoutFeedback, - View, -} from 'react-native'; -import UriBar from 'component/uriBar'; -import Link from 'component/link'; -import MediaPlayer from 'component/mediaPlayer'; -import RelatedContent from 'component/relatedContent'; -import filePageStyle from 'styles/filePage'; -import { decode, formatLbryUrlForWeb, navigateToUri } from 'utils/helper'; -import Icon from 'react-native-vector-icons/FontAwesome5'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api -import uriBarStyle from 'styles/uriBar'; -import { NavigationActions, StackActions } from 'react-navigation'; - -// This page will only be used for playing audio / video content from a remote stream URL -class LiteFilePage extends React.PureComponent { - playerBackground = null; - - scrollView = null; - - player = null; - - startTime = null; - - state = { - channelName: null, - channelUrl: null, - fileViewLogged: false, - fullscreenMode: false, - playbackStarted: false, - playerHeight: null, - isLandscape: false, - sdkReady: false, // TODO: progressively enable features (e.g. tip) when sdk is ready - showRecommended: false, - title: null, - viewCount: 0, - }; - - checkOrientation = () => { - if (this.state.fullscreenMode) { - return; - } - - const screenDimension = Dimensions.get('window'); - const screenWidth = screenDimension.width; - const screenHeight = screenDimension.height; - const isLandscape = screenWidth > screenHeight; - this.setState({ isLandscape }); - - if (!this.playerBackground) { - return; - } - - if (isLandscape) { - this.playerBackground.setNativeProps({ - height: screenHeight - StyleSheet.flatten(uriBarStyle.uriContainer).height, - }); - } else if (this.state.playerBgHeight > 0) { - this.playerBackground.setNativeProps({ height: this.state.playerBgHeight }); - } - }; - - handleFullscreenToggle = isFullscreen => { - const { toggleFullscreenMode } = this.props; - toggleFullscreenMode(isFullscreen); - - if (isFullscreen) { - // fullscreen, so change orientation to landscape mode - NativeModules.ScreenOrientation.lockOrientationLandscape(); - - // hide the navigation bar (on devices that have the soft navigation bar) - NativeModules.UtilityModule.hideNavigationBar(); - } else { - // Switch back to portrait mode when the media is not fullscreen - NativeModules.ScreenOrientation.lockOrientationPortrait(); - - // show the navigation bar (on devices that have the soft navigation bar) - NativeModules.UtilityModule.showNavigationBar(); - } - - this.setState({ fullscreenMode: isFullscreen }); - StatusBar.setHidden(isFullscreen); - }; - - getStreamUrl = url => { - const { claimName, claimId } = parseURI(url); - return `https://player.lbry.tv/content/claims/${claimName}/${claimId}/stream`; - }; - - handleSharePress = url => { - const shareUrl = Constants.SHARE_BASE_URL + formatLbryUrlForWeb(url); - NativeModules.UtilityModule.shareUrl(shareUrl); - }; - - handleOpenUrl = url => { - const { navigation } = this.props; - Alert.alert( - __('Stop watching?'), - 'The LBRY service is still loading stuff in the background. Would you like to continue?', - [ - { text: __('No') }, - { - text: __('Yes'), - onPress: () => { - const resetAction = StackActions.reset({ - index: 0, - actions: [NavigationActions.navigate({ routeName: 'Splash', params: { resetUrl: url } })], - }); - navigation.dispatch(resetAction); - }, - }, - ], - ); - }; - - componentDidMount() { - this.startTime = Date.now(); - } - - componentDidUpdate() { - const { navigation } = this.props; - const { uri } = navigation.state.params; - - if (!this.state.title) { - const params = parseQueryParams(uri); - const { channelUrl, contentTitle } = params; - const channelName = channelUrl ? parseURI(decode(channelUrl)).claimName : null; - - this.setState({ - title: decode(contentTitle), - channelUrl, - channelName, - showRecommended: true, - }); - } - } - - render() { - const { navigation, rewardedContentClaimIds } = this.props; - const { channelName, channelUrl, title, sdkReady, viewCount } = this.state; - const { uri } = navigation.state.params; - const { claimName, claimId } = parseURI(uri); - const isRewardContent = rewardedContentClaimIds.includes(claimId); - - const playerBgStyle = [filePageStyle.playerBackground, filePageStyle.containedPlayerBackground]; - const fsPlayerBgStyle = [filePageStyle.playerBackground, filePageStyle.fullscreenPlayerBackground]; - - const playerStyle = [ - filePageStyle.player, - this.state.isLandscape - ? filePageStyle.containedPlayerLandscape - : this.state.fullscreenMode - ? filePageStyle.fullscreenPlayer - : filePageStyle.containedPlayer, - ]; - - return ( - <View style={filePageStyle.pageContainer}> - {!this.state.fullscreenMode && <UriBar value={uri.split('?')[0]} navigation={navigation} />} - - <View - style={this.state.fullscreenMode ? filePageStyle.innerPageContainerFsMode : filePageStyle.innerPageContainer} - onLayout={this.checkOrientation} - > - <TouchableOpacity activeOpacity={0.5} style={filePageStyle.mediaContainer} /> - - <View - style={playerBgStyle} - ref={ref => { - this.playerBackground = ref; - }} - onLayout={evt => { - if (!this.state.playerBgHeight) { - this.setState({ playerBgHeight: evt.nativeEvent.layout.height }); - } - }} - /> - - {this.state.fullscreenMode && <View style={fsPlayerBgStyle} />} - <MediaPlayer - assignPlayer={ref => { - this.player = ref; - }} - uri={uri} - source={this.getStreamUrl(uri)} - style={playerStyle} - autoPlay - onFullscreenToggled={this.handleFullscreenToggle} - onLayout={evt => { - if (!this.state.playerHeight) { - this.setState({ playerHeight: evt.nativeEvent.layout.height }); - } - }} - /> - - <ScrollView - style={filePageStyle.scrollContainer} - contentContainerStyle={filePageStyle.scrollContent} - keyboardShouldPersistTaps={'handled'} - ref={ref => { - this.scrollView = ref; - }} - > - <TouchableWithoutFeedback - style={filePageStyle.titleTouch} - onPress={() => this.setState({ showDescription: !this.state.showDescription })} - > - <View style={filePageStyle.titleArea}> - <View style={filePageStyle.titleRow}> - <Text style={filePageStyle.title} selectable> - {title} - </Text> - {isRewardContent && <Icon name="award" style={filePageStyle.rewardIcon} size={16} />} - </View> - <Text style={filePageStyle.viewCount}> - {viewCount === 1 && __('%view% view', { view: viewCount })} - {viewCount > 1 && __('%view% views', { view: viewCount })} - </Text> - </View> - </TouchableWithoutFeedback> - - <View style={filePageStyle.largeButtonsRow}> - <TouchableOpacity style={filePageStyle.largeButton} onPress={() => this.handleSharePress(uri)}> - <Icon name={'share-alt'} size={16} style={filePageStyle.largeButtonIcon} /> - <Text style={filePageStyle.largeButtonText}>{__('Share')}</Text> - </TouchableOpacity> - - {sdkReady && ( - <TouchableOpacity - style={filePageStyle.largeButton} - onPress={() => this.setState({ showTipView: true })} - > - <Icon name={'gift'} size={16} style={filePageStyle.largeButtonIcon} /> - <Text style={filePageStyle.largeButtonText}>{__('Tip')}</Text> - </TouchableOpacity> - )} - </View> - - <View style={filePageStyle.channelRow}> - <View style={filePageStyle.publishInfo}> - {channelName && ( - <Link - style={filePageStyle.channelName} - selectable - text={channelName} - numberOfLines={1} - ellipsizeMode={'tail'} - onPress={() => this.handleOpenUrl(channelUrl)} - /> - )} - {!channelName && ( - <Text style={filePageStyle.anonChannelName} selectable ellipsizeMode={'tail'}> - {__('Anonymous')} - </Text> - )} - </View> - </View> - - <View onLayout={this.setRelatedContentPosition} /> - - {this.state.showRecommended && ( - <RelatedContent - navigation={navigation} - claimId={claimId} - claimName={claimName} - title={title} - urlOpenHandler={this.handleOpenUrl} - uri={uri} - fullUri={uri} - /> - )} - </ScrollView> - </View> - </View> - ); - } -} - -export default LiteFilePage; diff --git a/src/page/publish/index.js b/src/page/publish/index.js index 7d9065e..5c5604f 100644 --- a/src/page/publish/index.js +++ b/src/page/publish/index.js @@ -1,44 +1,31 @@ import { connect } from 'react-redux'; import { doPublish, - doFetchClaimListMine, doResolveUri, doToast, - doUpdatePublishForm, + doUploadThumbnail, selectBalance, - selectMyClaims, selectPublishFormValues, } from 'lbry-redux'; -import { selectDrawerStack } from 'redux/selectors/drawer'; -import { doUpdatePublishFormState, doClearPublishFormState, doPendingPublishSuccess } from 'redux/actions/form'; -import { doPushDrawerStack, doPopDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer'; -import { selectPublishFormState, selectHasPublishFormState } from 'redux/selectors/form'; -import { selectSdkReady } from 'redux/selectors/settings'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api +import { doPushDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer'; +import Constants from 'constants'; import PublishPage from './view'; const select = state => ({ balance: selectBalance(state), - drawerStack: selectDrawerStack(state), - hasFormState: selectHasPublishFormState(state), - myClaims: selectMyClaims(state), - publishFormState: selectPublishFormState(state), publishFormValues: selectPublishFormValues(state), - sdkReady: selectSdkReady(state), }); const perform = dispatch => ({ notify: data => dispatch(doToast(data)), - clearPublishFormState: () => dispatch(doClearPublishFormState()), - fetchMyClaims: () => dispatch(doFetchClaimListMine()), - pendingPublishSuccess: pendingClaim => dispatch(doPendingPublishSuccess(pendingClaim)), - updatePublishForm: value => dispatch(doUpdatePublishForm(value)), - updatePublishFormState: data => dispatch(doUpdatePublishFormState(data)), - publish: (success, fail) => dispatch(doPublish(success, fail)), + uploadThumbnail: (filePath, fsAdapter) => dispatch(doUploadThumbnail(filePath, null, fsAdapter)), + publish: params => dispatch(doPublish(params)), resolveUri: uri => dispatch(doResolveUri(uri)), - pushDrawerStack: (routeName, params) => dispatch(doPushDrawerStack(routeName, params)), - popDrawerStack: () => dispatch(doPopDrawerStack()), + pushDrawerStack: () => dispatch(doPushDrawerStack(Constants.DRAWER_ROUTE_PUBLISH)), setPlayerVisible: () => dispatch(doSetPlayerVisible(false)), }); -export default connect(select, perform)(PublishPage); +export default connect( + select, + perform +)(PublishPage); diff --git a/src/page/publish/view.js b/src/page/publish/view.js index 26e308f..c699780 100644 --- a/src/page/publish/view.js +++ b/src/page/publish/view.js @@ -15,21 +15,8 @@ import { View, } from 'react-native'; import { FlatGrid } from 'react-native-super-grid'; -import { - Lbry, - isNameValid, - batchActions, - buildURI, - formatCredits, - normalizeURI, - parseURI, - regexInvalidURI, - ACTIONS, - CLAIM_VALUES, - LICENSES, - MATURE_TAGS, - THUMBNAIL_STATUSES, -} from 'lbry-redux'; +import { isNameValid, buildURI, regexInvalidURI, CLAIM_VALUES, LICENSES, THUMBNAIL_STATUSES } from 'lbry-redux'; +import { DocumentPicker, DocumentPickerUtil } from 'react-native-document-picker'; import { RNCamera } from 'react-native-camera'; import { generateCombination } from 'gfycat-style-urls'; import RNFS from 'react-native-fs'; @@ -37,7 +24,6 @@ import Button from 'component/button'; import ChannelSelector from 'component/channelSelector'; import Colors from 'styles/colors'; import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api -import EmptyStateView from 'component/emptyStateView'; import FastImage from 'react-native-fast-image'; import FloatingWalletBalance from 'component/floatingWalletBalance'; import Icon from 'react-native-vector-icons/FontAwesome5'; @@ -48,7 +34,6 @@ import Tag from 'component/tag'; import TagSearch from 'component/tagSearch'; import UriBar from 'component/uriBar'; import publishStyle from 'styles/publish'; -import { navigateToUri, navigateBack, logPublish, uploadImageAsset } from 'utils/helper'; const languages = { en: 'English', @@ -81,23 +66,14 @@ const languages = { class PublishPage extends React.PureComponent { camera = null; - scrollView = null; - state = { - canPublish: true, canUseCamera: false, - creditsInputFocused: false, - documentPickerOpen: false, - editMode: false, titleFocused: false, descriptionFocused: false, - loadingVideos: false, - vanityUrl: null, // gallery videos videos: null, - allThumbnailsChecked: false, - checkedThumbnails: [], + galleryThumbnailsChecked: false, // camera cameraType: RNCamera.Constants.Type.back, @@ -111,7 +87,7 @@ class PublishPage extends React.PureComponent { currentMedia: null, currentThumbnailUri: null, updatingThumbnailUri: false, - currentPhase: null, + currentPhase: Constants.PHASE_SELECTOR, // publish advancedMode: false, @@ -120,213 +96,50 @@ class PublishPage extends React.PureComponent { priceSet: false, // input data - hasEditedContentAddress: false, - bid: 0.01, + bid: 0.1, description: null, title: null, language: 'en', license: LICENSES.NONE, - licenseUrl: '', - otherLicenseDescription: '', + mature: false, name: null, price: 0, - currency: 'LBC', uri: null, tags: [], - selectedChannel: null, uploadedThumbnailUri: null, - vanityUrlSet: false, - - thumbnailImagePickerOpen: false, // other publishStarted: false, - storagePermissionRequired: false, - hasReturnedBack: false, - returnUrl: null, }; didFocusListener; componentWillMount() { const { navigation } = this.props; - // this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused); - DeviceEventEmitter.addListener('onGalleryThumbnailChecked', this.handleGalleryThumbnailChecked); - DeviceEventEmitter.addListener('onAllGalleryThumbnailsChecked', this.handleAllGalleryThumbnailsChecked); - DeviceEventEmitter.addListener('onDocumentPickerFilePicked', this.onFilePicked); - DeviceEventEmitter.addListener('onDocumentPickerCanceled', this.onPickerCanceled); + this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused); + DeviceEventEmitter.addListener('onGalleryThumbnailsChecked', this.handleGalleryThumbnailsChecked); } componentWillUnmount() { if (this.didFocusListener) { this.didFocusListener.remove(); } - DeviceEventEmitter.removeListener('onGalleryThumbnailChecked', this.handleGalleryThumbnailChecked); - DeviceEventEmitter.removeListener('onAllGalleryThumbnailsChecked', this.handleAllGalleryThumbnailsChecked); - DeviceEventEmitter.removeListener('onDocumentPickerFilePicked', this.onFilePicked); - DeviceEventEmitter.removeListener('onDocumentPickerCanceled', this.onPickerCanceled); - DeviceEventEmitter.removeListener('onStoragePermissionGranted', this.handleStoragePermissionGranted); - DeviceEventEmitter.removeListener('onStoragePermissionRefused', this.handleStoragePermissionRefused); + DeviceEventEmitter.removeListener('onGalleryThumbnailsChecked', this.handleGalleryThumbnailsChecked); } - handleGalleryThumbnailChecked = evt => { - const checkedThumbnails = [...this.state.checkedThumbnails]; - const { id } = evt; - // using checked because we only want thumbnails that can be displayed - if (!checkedThumbnails.includes(id)) { - checkedThumbnails.push(id); - } - this.setState({ checkedThumbnails }); - }; - - handleAllGalleryThumbnailsChecked = () => { - this.setState({ allThumbnailsChecked: true }); - }; - - loadPendingFormState = () => { - const { publishFormState } = this.props; - const advancedMode = publishFormState.license !== null; - this.setState({ ...publishFormState, advancedMode }); - }; - - checkStoragePermission = () => { - // check if we the permission to write to external storage has been granted - NativeModules.UtilityModule.canReadWriteStorage().then(canReadWrite => { - if (!canReadWrite) { - // request permission - NativeModules.UtilityModule.requestStoragePermission(); - } - }); - }; - - loadVideos = () => { - this.setState( - { - loadingVideos: true, - storagePermissionRequired: false, - }, - () => { - NativeModules.Gallery.getVideos().then(videos => this.setState({ videos, loadingVideos: false })); - }, - ); + handleGalleryThumbnailsChecked = () => { + this.setState({ galleryThumbnailsChecked: true }); }; onComponentFocused = () => { - const { balance, fetchMyClaims, hasFormState, pushDrawerStack, setPlayerVisible, navigation } = this.props; - NativeModules.Firebase.setCurrentScreen('Publish').then(result => { - pushDrawerStack(Constants.DRAWER_ROUTE_PUBLISH, navigation.state.params ? navigation.state.params : null); - setPlayerVisible(); + const { pushDrawerStack, setPlayerVisible } = this.props; - DeviceEventEmitter.addListener('onStoragePermissionGranted', this.handleStoragePermissionGranted); - DeviceEventEmitter.addListener('onStoragePermissionRefused', this.handleStoragePermissionRefused); + pushDrawerStack(); + setPlayerVisible(); - NativeModules.Gallery.canUseCamera().then(canUseCamera => this.setState({ canUseCamera })); - NativeModules.Gallery.getThumbnailPath().then(thumbnailPath => this.setState({ thumbnailPath })); - fetchMyClaims(); - - NativeModules.UtilityModule.canReadWriteStorage().then(canReadWrite => { - if (!canReadWrite) { - this.setState({ storagePermissionRequired: true }, () => - NativeModules.UtilityModule.requestStoragePermission(), - ); - } else { - // Can only load videos when the storage permission is granted - this.loadVideos(); - } - }); - - // Check if this is an edit action - let isEditMode = false, - vanityUrlSet = false; - if (navigation.state.params) { - const { displayForm, editMode, claimToEdit, vanityUrl, returnUrl } = navigation.state.params; - if (editMode) { - this.prepareEdit(claimToEdit); - isEditMode = true; - } else if (vanityUrl) { - const { claimName } = parseURI(vanityUrl); - vanityUrlSet = true; - this.setState({ - name: claimName, - hasEditedContentAddress: true, - vanityUrlSet, - vanityUrl: claimName, - }); - } - this.setState({ returnUrl }); - } - - if (!isEditMode && hasFormState) { - this.loadPendingFormState(); - if (vanityUrlSet) { - // replace name with the specified vanity URL if there was one in the pending state - this.setState({ name: this.state.vanityUrl }); - } - } - this.setState({ currentPhase: isEditMode || hasFormState ? Constants.PHASE_DETAILS : Constants.PHASE_SELECTOR }); - }); - }; - - prepareEdit = claim => { - const { pushDrawerStack } = this.props; - const { amount, name, signing_channel: signingChannel, value } = claim; - const { description, fee, languages, license, license_url: licenseUrl, tags, thumbnail, title } = value; - - let channelName; - if (signingChannel) { - channelName = signingChannel.name; - } - - const thumbnailUrl = thumbnail ? thumbnail.url : null; - - // Determine the license - let licenseType, otherLicenseDescription; - if (!LICENSES.CC_LICENSES.some(({ value }) => value === license)) { - if (!license || license === LICENSES.NONE || license === LICENSES.PUBLIC_DOMAIN) { - licenseType = license; - } else if (license && !licenseUrl && license !== LICENSES.NONE) { - licenseType = LICENSES.COPYRIGHT; - } else { - licenseType = LICENSES.OTHER; - } - - otherLicenseDescription = license; - } else { - licenseType = license; - } - - this.setState( - { - editMode: true, - publishStarted: false, - currentPhase: Constants.PHASE_DETAILS, - - hasEditedContentAddress: true, - bid: amount, - channelName, - description, - language: languages && languages.length > 0 ? languages[0] : 'en', // default to English - license: licenseType, - licenseUrl, - otherLicenseDescription, - name, - currency: fee && fee.currency ? fee.currency : 'LBC', - price: fee && fee.amount ? fee.amount : 0, - priceSet: fee && fee.amount > 0, - tags: tags && tags.length > 0 ? tags : [], - title, - currentThumbnailUri: thumbnailUrl, - uploadedThumbnailUri: thumbnailUrl, - vanityUrlSet: false, - }, - () => { - this.handleNameChange(name); - if (channelName) { - this.handleChannelChange(channelName); - } - pushDrawerStack(Constants.DRAWER_ROUTE_PUBLISH_FORM); - }, - ); + NativeModules.Gallery.canUseCamera().then(canUseCamera => this.setState({ canUseCamera })); + NativeModules.Gallery.getThumbnailPath().then(thumbnailPath => this.setState({ thumbnailPath })); + NativeModules.Gallery.getVideos().then(videos => this.setState({ videos })); }; getNewUri(name, channel) { @@ -338,7 +151,7 @@ class PublishPage extends React.PureComponent { // We are only going to store the full uri, but we need to resolve the uri with and without the channel name let uri; try { - uri = buildURI({ claimName: name, channelName }); + uri = buildURI({ contentName: name, channelName }); } catch (e) { // something wrong with channel or name } @@ -346,7 +159,7 @@ class PublishPage extends React.PureComponent { if (uri) { if (channelName) { // resolve without the channel name so we know the winning bid for it - const uriLessChannel = buildURI({ claimName: name }); + const uriLessChannel = buildURI({ contentName: name }); resolveUri(uriLessChannel); } resolveUri(uri); @@ -361,18 +174,15 @@ class PublishPage extends React.PureComponent { }; handlePublishPressed = () => { - const { balance, myClaims, notify, publish, updatePublishForm } = this.props; + const { notify, publish } = this.props; const { - editMode, bid, channelName, currentMedia, - currency, description, language, license, - licenseUrl, - otherLicenseDescription, + mature, name, price, priceSet, @@ -382,93 +192,43 @@ class PublishPage extends React.PureComponent { uri, } = this.state; - if (balance < Constants.MINIMUM_TRANSACTION_BALANCE) { - notify({ - message: __('Publishing content requires credits. Press the blue bar to get some for free.'), - }); - if (this.scrollView) { - this.scrollView.scrollTo({ x: 0, y: 0, animated: true }); - } - return; - } - if (!title || title.trim().length === 0) { - notify({ message: __('Please provide a title'), isError: true }); + notify({ message: 'Please provide a title' }); return; } if (!name) { - notify({ message: __('Please specify an address where people can find your content.'), isError: true }); + notify({ message: 'Please specify an address where people can find your content.' }); return; } - if (!isNameValid(name, false)) { - notify({ message: __('Your content address contains invalid characters.'), isError: true }); - return; - } else if (!editMode && myClaims && myClaims.length > 0) { - if (myClaims.some(claim => claim.name.toLowerCase() === name.trim().toLowerCase())) { - notify({ - message: __('You have already published to the specified content address. Please enter a new address.'), - isError: true, - }); - return; - } - } - - if (!currentMedia && !editMode) { - // sanity check. normally shouldn't happen - notify({ - message: __('No file selected. Please select a video or take a photo before publishing.'), - isError: true, - }); - return; + const publishTags = tags.slice(); + if (mature) { + publishTags.push('nsfw'); } const publishParams = { - filePath: currentMedia ? currentMedia.filePath : null, + filePath: currentMedia.filePath, bid: bid || 0.1, + tags: publishTags, title: title || '', - thumbnail: thumbnail || '', + thumbnail: thumbnail, description: description || '', language, + nsfw: mature, license, - licenseType: license, - licenseUrl, - otherLicenseDescription, + licenseUrl: '', + otherLicenseDescription: '', name: name || undefined, contentIsFree: !priceSet, - fee: { currency, amount: price }, + fee: { currency: 'LBC', price }, uri: uri || undefined, - channel: CLAIM_VALUES.CHANNEL_ANONYMOUS === channelName ? null : channelName, + channel_name: CLAIM_VALUES.CHANNEL_ANONYMOUS === channelName ? undefined : channelName, isStillEditing: false, - tags: tags.map(tag => { - return { name: tag }; - }), + claim: null, }; - updatePublishForm(publishParams); - this.setState({ publishStarted: true }, () => publish(this.handlePublishSuccess, this.handlePublishFailure)); - }; - - handlePublishSuccess = data => { - const { clearPublishFormState, navigation, notify, pendingPublishSuccess } = this.props; - const pendingClaim = data.outputs[0]; - logPublish(pendingClaim); - - pendingPublishSuccess(pendingClaim); - - notify({ - message: __('Your content was successfully published. It will be available in a few mintues.'), - }); - clearPublishFormState(); - this.setState({ publishStarted: false }); - navigation.navigate({ routeName: Constants.DRAWER_ROUTE_PUBLISHES, params: { publishSuccess: true } }); - }; - - handlePublishFailure = error => { - const { notify } = this.props; - notify({ message: __('Your content could not be published at this time. Please try again.') }); - this.setState({ publishStarted: false }); + this.setState({ publishStarted: true }, () => publish(publishParams)); }; componentDidMount() { @@ -476,108 +236,74 @@ class PublishPage extends React.PureComponent { } componentWillReceiveProps(nextProps) { - const { - currentRoute: prevRoute, - drawerStack: prevDrawerStack, - popDrawerStack, - setPlayerVisible, - navigation, - notify, - updatePublishFormState, - } = this.props; - const { currentRoute, drawerStack, publishFormValues } = nextProps; + const { currentRoute, publishFormValues } = nextProps; + const { currentRoute: prevRoute } = this.props; if (Constants.DRAWER_ROUTE_PUBLISH === currentRoute && currentRoute !== prevRoute) { this.onComponentFocused(); } - if ( - this.state.currentPhase === Constants.PHASE_DETAILS && - prevDrawerStack[prevDrawerStack.length - 1].route === Constants.DRAWER_ROUTE_PUBLISH_FORM && - drawerStack[drawerStack.length - 1].route === Constants.DRAWER_ROUTE_PUBLISH - ) { - // navigated back from the form - this.showSelector(); - if (!this.state.hasReturnedBack && this.state.returnUrl) { - this.setState({ hasReturnedBack: true }, () => { - navigateBack(navigation, drawerStack, popDrawerStack, setPlayerVisible); - }); + if (publishFormValues) { + if (publishFormValues.thumbnail && !this.state.uploadedThumbnailUri) { + this.setState({ uploadedThumbnailUri: publishFormValues.thumbnail }); + } + + if (this.state.publishStarted) { + if (publishFormValues.publishSuccess) { + this.setState({ publishStarted: false, currentPhase: Constants.PHASE_PUBLISH }); + } else if (publishFormValues.publishError) { + // TODO: Display error if any + } + + if (!publishFormValues.publishing && this.state.publishStarted) { + this.setState({ publishStarted: false }); + } } } } setCurrentMedia(media) { - const { pushDrawerStack, updatePublishFormState } = this.props; - const name = generateCombination(2, ' ', true); - const newName = this.state.hasEditedContentAddress ? this.state.name : this.formatNameForTitle(name); - updatePublishFormState({ currentMedia: media, name: newName }); this.setState( { - publishStarted: false, currentMedia: media, - title: null, // no title autogeneration (user will fill this in) - name: newName, + title: media.name, + name: this.formatNameForTitle(media.name), currentPhase: Constants.PHASE_DETAILS, }, - () => { - this.handleNameChange(this.state.name); - pushDrawerStack(Constants.DRAWER_ROUTE_PUBLISH_FORM); - }, + () => this.handleNameChange(this.state.name) ); } formatNameForTitle = title => { - return title.replace(new RegExp(regexInvalidURI.source, regexInvalidURI.flags + 'g'), '-').toLowerCase(); + return title.replace(regexInvalidURI, '-').toLowerCase(); }; showSelector() { - const { clearPublishFormState, updatePublishForm } = this.props; + this.setState({ + publishStarted: false, - this.setState( - { - publishStarted: false, - documentPickerOpen: false, - editMode: false, - vanityUrl: null, + currentMedia: null, + currentThumbnailUri: null, + currentPhase: Constants.PHASE_SELECTOR, - currentMedia: null, - currentThumbnailUri: null, - currentPhase: Constants.PHASE_SELECTOR, - updatingThumbnailUri: false, - uploadThumbnailStarted: false, + // publish + advancedMode: false, + anonymous: true, + channelName: CLAIM_VALUES.CHANNEL_ANONYMOUS, + priceSet: false, - // publish - advancedMode: false, - anonymous: true, - channelName: CLAIM_VALUES.CHANNEL_ANONYMOUS, - priceSet: false, - - // input data - hasEditedContentAddress: false, - bid: 0.1, - description: null, - title: null, - language: 'en', - license: LICENSES.NONE, - licenseUrl: '', - otherLicenseDescription: '', - name: null, - price: 0, - uri: null, - tags: [], - selectedChannel: null, - uploadedThumbnailUri: null, - - thumbnailImagePickerOpen: false, - - vanityUrlSet: false, - }, - () => { - clearPublishFormState(); - // reset thumbnail - updatePublishForm({ thumbnail: null }); - }, - ); + // input data + bid: 0.1, + description: null, + title: null, + language: 'en', + license: LICENSES.NONE, + name: null, + price: 0, + uri: null, + tags: [], + uploadedThumbnailUri: null, + }); } handleRecordVideoPressed = () => { @@ -592,76 +318,6 @@ class PublishPage extends React.PureComponent { } }; - handleUploadPressed = () => { - if (this.state.documentPickerOpen) { - return; - } - - this.setState( - { - documentPickerOpen: true, - }, - () => { - NativeModules.UtilityModule.openDocumentPicker('*/*'); - }, - ); - }; - - handleThumbnailUploadSuccess = ({ url }) => { - const { updatePublishFormState } = this.props; - - this.setState({ - uploadThumbnailStarted: false, - currentThumbnailUri: url, - uploadedThumbnailUri: url, - }); - updatePublishFormState({ currentThumbnailUri: url, uploadedThumbnailUri: url }); - }; - - handleThumbnailUploadFailure = err => { - const { notify } = this.props; - this.setState({ uploadThumbnailStarted: false }); - notify({ message: __('The thumbnail could not be uploaded. Please try again.') }); - }; - - onFilePicked = evt => { - const { notify } = this.props; - if (evt.path && evt.path.length > 0) { - const fileUrl = `file://${evt.path}`; - - if (this.state.documentPickerOpen) { - this.setState({ documentPickerOpen: false, thumbnailImagePickerOpen: false }, () => { - const currentMedia = { - id: -1, - filePath: evt.path, - duration: 0, - }; - this.setCurrentMedia(currentMedia); - }); - } else if (this.state.thumbnailImagePickerOpen) { - this.setState( - { - documentPickerOpen: false, - thumbnailImagePickerOpen: false, - uploadThumbnailStarted: true, - currentThumbnailUri: fileUrl, - }, - () => { - // upload a new thumbnail - uploadImageAsset(fileUrl, this.handleThumbnailUploadSuccess, this.handleThumbnailUploadFailure); - }, - ); - } - } else { - // could not determine the file path - notify({ message: __('The path could not be determined. Please try a different file.'), isError: true }); - } - }; - - onPickerCanceled = () => { - this.setState({ documentPickerOpen: false, thumbnailImagePickerOpen: false }); - }; - handleCloseCameraPressed = () => { this.setState({ showCameraOverlay: false, videoRecordingMode: false }); }; @@ -671,8 +327,6 @@ class PublishPage extends React.PureComponent { }; handleCameraActionPressed = () => { - const { pushDrawerStack } = this.props; - // check if it's video or photo mode if (this.state.videoRecordingMode) { if (this.state.recordingVideo) { @@ -686,22 +340,19 @@ class PublishPage extends React.PureComponent { const currentMedia = { id: -1, filePath: this.getFilePathFromUri(data.uri), + name: generateCombination(2, ' ', true), type: 'video/mp4', // always MP4 duration: 0, }; this.setCurrentMedia(currentMedia); - this.setState( - { - currentThumbnailUri: null, - updatingThumbnailUri: false, - publishStarted: false, - currentPhase: Constants.PHASE_DETAILS, - showCameraOverlay: false, - videoRecordingMode: false, - recordingVideo: false, - }, - () => pushDrawerStack(Constants.DRAWER_ROUTE_PUBLISH_FORM), - ); + this.setState({ + currentThumbnailUri: null, + updatingThumbnailUri: false, + currentPhase: Constants.PHASE_DETAILS, + showCameraOverlay: false, + videoRecordingMode: false, + recordingVideo: false, + }); }); } } else { @@ -715,17 +366,13 @@ class PublishPage extends React.PureComponent { duration: 0, }; this.setCurrentMedia(currentMedia); - this.setState( - { - currentPhase: Constants.PHASE_DETAILS, - currentThumbnailUri: null, - publishStarted: false, - updatingThumbnailUri: false, - showCameraOverlay: false, - videoRecordingMode: false, - }, - () => pushDrawerStack(Constants.DRAWER_ROUTE_PUBLISH), - ); + this.setState({ + currentPhase: Constants.PHASE_DETAILS, + currentThumbnailUri: null, + updatingThumbnailUri: false, + showCameraOverlay: false, + videoRecordingMode: false, + }); }); } }; @@ -738,6 +385,19 @@ class PublishPage extends React.PureComponent { }); }; + handleUploadPressed = () => { + DocumentPicker.show( + { + filetype: [DocumentPickerUtil.allFiles()], + }, + (error, res) => { + if (!error) { + // console.log(res); + } + } + ); + }; + getRandomFileId = () => { // generate a random id for a photo or recorded video between 1 and 20 (for creating thumbnails) const id = Math.floor(Math.random() * (20 - 2)) + 1; @@ -749,27 +409,18 @@ class PublishPage extends React.PureComponent { }; handleBidChange = bid => { - const { updatePublishFormState } = this.props; - updatePublishFormState({ bid }); this.setState({ bid }); }; handlePriceChange = price => { - const { updatePublishFormState } = this.props; - updatePublishFormState({ price }); this.setState({ price }); }; - handleNameChange = (name, userInput) => { - const { notify, updatePublishFormState } = this.props; - updatePublishFormState({ name }); + handleNameChange = name => { + const { notify } = this.props; this.setState({ name }); - if (userInput) { - this.setState({ hasEditedContentAddress: true }); - } - if (!isNameValid(name, false)) { - notify({ message: __('Your content address contains invalid characters') }); + notify({ message: 'Your content address contains invalid characters' }); return; } @@ -777,44 +428,39 @@ class PublishPage extends React.PureComponent { this.setState({ uri }); }; - handleChannelChange = channel => { - const { updatePublishFormState } = this.props; - const { name } = this.state; - const uri = this.getNewUri(name, channel); - updatePublishFormState({ uri, channelName: channel, selectedChannel: channel }); - this.setState({ uri, channelName: channel, selectedChannel: channel }); + handleChannelChanged = channel => { + this.setState({ channelName: channel }); + const uri = this.getNewUri(name, this.state.channelName); + this.setState({ uri }); }; handleAddTag = tag => { - if (!tag || !this.state.canPublish || this.state.publishStarted) { + if (!tag) { return; } - const { notify, updatePublishFormState } = this.props; + const { notify } = this.props; const { tags } = this.state; const index = tags.indexOf(tag.toLowerCase()); if (index === -1) { const newTags = tags.slice(); newTags.push(tag); - updatePublishFormState({ tags: newTags }); this.setState({ tags: newTags }); } else { - notify({ message: __(`You already added the "${tag}" tag.`) }); // TODO: tokenize i18n + notify({ message: __(`You already added the "${tag}" tag.`) }); } }; handleRemoveTag = tag => { - if (!tag || !this.state.canPublish || this.state.publishStarted) { + if (!tag) { return; } - const { updatePublishFormState } = this.props; const newTags = this.state.tags.slice(); const index = newTags.indexOf(tag.toLowerCase()); if (index > -1) { newTags.splice(index, 1); - updatePublishFormState({ tags: newTags }); this.setState({ tags: newTags }); } }; @@ -824,7 +470,7 @@ class PublishPage extends React.PureComponent { return; } - const { notify } = this.props; + const { notify, uploadThumbnail } = this.props; const { thumbnailPath } = this.state; this.setState({ updatingThumbnailUri: true }); @@ -839,13 +485,7 @@ class PublishPage extends React.PureComponent { // upload the thumbnail if (!this.state.uploadedThumbnailUri) { - this.setState({ uploadThumbnailStarted: true }, () => - uploadImageAsset( - this.getFilePathFromUri(uri), - this.handleThumbnailUploadSuccess, - this.handleThumbnailUploadFailure, - ), - ); + this.setState({ uploadThumbnailStarted: true }, () => uploadThumbnail(this.getFilePathFromUri(uri), RNFS)); } } else if (mediaType === 'image' || mediaType === 'video') { const create = @@ -856,9 +496,7 @@ class PublishPage extends React.PureComponent { .then(path => { this.setState({ currentThumbnailUri: `file://${path}`, updatingThumbnailUri: false }); if (!this.state.uploadedThumbnailUri) { - this.setState({ uploadThumbnailStarted: true }, () => - uploadImageAsset(path, this.handleThumbnailUploadSuccess, this.handleThumbnailUploadFailure), - ); + this.setState({ uploadThumbnailStarted: true }, () => uploadThumbnail(path, RNFS)); } }) .catch(err => { @@ -870,203 +508,64 @@ class PublishPage extends React.PureComponent { }; handleTitleChange = title => { - const { updatePublishFormState } = this.props; - updatePublishFormState({ title }); - this.setState({ title }); - - if (!this.state.editMode && !this.state.hasEditedContentAddress) { - // only autogenerate url if the user has not yet edited the field - // also shouldn't change url in edit mode - this.setState( - { - name: this.formatNameForTitle(title), - }, - () => { - this.handleNameChange(this.state.name); - }, - ); - } - }; - - handleCurrencyValueChange = currency => { - const { updatePublishFormState } = this.props; - updatePublishFormState({ currency }); - this.setState({ currency }); - }; - - handleDescriptionChange = description => { - const { updatePublishFormState } = this.props; - updatePublishFormState({ description }); - this.setState({ description }); - }; - - handleLanguageValueChange = language => { - const { updatePublishFormState } = this.props; - updatePublishFormState({ language }); - this.setState({ language }); - }; - - handleLicenseValueChange = license => { - const { updatePublishFormState } = this.props; - - const otherLicenseDescription = [LICENSES.COPYRIGHT, LICENSES.OTHER].includes(license) - ? this.state.otherLicenseDescription - : ''; - const licenseUrl = LICENSES.CC_LICENSES.reduce((value, item) => { - if (typeof value === 'object') { - value = license === value.value ? item.url : ''; - } - if (license === item.value) { - value = item.url; - } - return value; - }); - - updatePublishFormState({ otherLicenseDescription, license, licenseUrl }); - this.setState({ otherLicenseDescription, license, licenseUrl }); - }; - - handleChangeLicenseDescription = otherLicenseDescription => { - const { updatePublishFormState } = this.props; - updatePublishFormState({ otherLicenseDescription }); - this.setState({ otherLicenseDescription }); - }; - - handleThumbnailPressed = () => { - const { notify } = this.props; - if (this.state.thumbnailImagePickerOpen || this.state.uploadThumbnailStarted) { - if (this.state.uploadThumbnailStarted) { - notify({ message: __('A thumbnail is already being uploaded. Please wait for the upload to finish.') }); - } - return; - } - this.setState( { - thumbnailImagePickerOpen: true, + title, + name: this.formatNameForTitle(title), }, () => { - NativeModules.UtilityModule.openDocumentPicker('image/*'); - }, + this.handleNameChange(this.state.name); + } ); }; - handleStoragePermissionGranted = () => { - // update the configured download folder - this.loadVideos(); - NativeModules.UtilityModule.getDownloadDirectory().then(downloadDirectory => { - Lbry.settings_set({ - key: 'download_dir', - value: downloadDirectory, - }) - .then(() => {}) - .catch(() => {}); - }); - }; - - handleStoragePermissionRefused = () => { - const { notify } = this.props; - notify({ - message: __( - 'Content from your device cannot be published because the permission to read storage was not granted.', - ), - isError: true, - }); - }; - render() { - const { balance, navigation, notify, sdkReady } = this.props; - const { - allThumbnailsChecked, - canUseCamera, - showCameraOverlay, - currentPhase, - checkedThumbnails, - loadingVideos, - storagePermissionRequired, - thumbnailPath, - videos, - } = this.state; - - if (!sdkReady) { - return ( - <View style={publishStyle.container}> - <UriBar navigation={navigation} /> - <EmptyStateView - message={__( - 'The background service is still initializing. You can still explore and watch content during the initialization process.', - )} - /> - </View> - ); - } + const { balance, navigation, notify, publishFormValues } = this.props; + const { canUseCamera, currentPhase, galleryThumbnailsChecked, thumbnailPath, videos } = this.state; let content; if (Constants.PHASE_SELECTOR === currentPhase) { content = ( <View style={publishStyle.gallerySelector}> <View style={publishStyle.actionsView}> - {canUseCamera && !showCameraOverlay && ( - <RNCamera captureAudio={false} style={publishStyle.cameraPreview} type={RNCamera.Constants.Type.back} /> - )} + {canUseCamera && <RNCamera style={publishStyle.cameraPreview} type={RNCamera.Constants.Type.back} />} <View style={publishStyle.actionsSubView}> - <TouchableOpacity - style={[ - publishStyle.record, - canUseCamera ? publishStyle.transparentBackground : publishStyle.actionBackground, - ]} - onPress={this.handleRecordVideoPressed} - > + <TouchableOpacity style={publishStyle.record} onPress={this.handleRecordVideoPressed}> <Icon name="video" size={48} color={Colors.White} /> - <Text style={publishStyle.actionText}>{__('Record')}</Text> + <Text style={publishStyle.actionText}>Record</Text> </TouchableOpacity> <View style={publishStyle.subActions}> - <TouchableOpacity - style={[ - publishStyle.photo, - canUseCamera ? publishStyle.transparentBackground : publishStyle.actionBackground, - ]} - onPress={this.handleTakePhotoPressed} - > + <TouchableOpacity style={publishStyle.photo} onPress={this.handleTakePhotoPressed}> <Icon name="camera" size={48} color={Colors.White} /> - <Text style={publishStyle.actionText}>{__('Take a photo')}</Text> - </TouchableOpacity> - <TouchableOpacity style={publishStyle.upload} onPress={this.handleUploadPressed}> - <Icon name="file-upload" size={48} color={Colors.White} /> - <Text style={publishStyle.actionText}>{__('Upload a file')}</Text> + <Text style={publishStyle.actionText}>Take a photo</Text> </TouchableOpacity> + {false && ( + <TouchableOpacity style={publishStyle.upload} onPress={this.handleUploadPressed}> + <Icon name="file-upload" size={48} color={Colors.White} /> + <Text style={publishStyle.actionText}>Upload a file</Text> + </TouchableOpacity> + )} </View> </View> </View> - {storagePermissionRequired && ( - <View style={publishStyle.relativeCentered}> - <Text style={publishStyle.noVideos}> - {__('The storage permission is required to be able to display and publish your videos.')} - </Text> - </View> - )} - {!storagePermissionRequired && (loadingVideos || !allThumbnailsChecked) && ( + {(!videos || !thumbnailPath || !galleryThumbnailsChecked) && ( <View style={publishStyle.loadingView}> - <ActivityIndicator size="small" color={Colors.NextLbryGreen} /> - <Text style={publishStyle.loadingText}>{__('Please wait while we load your videos...')}</Text> + <ActivityIndicator size="large" color={Colors.NextLbryGreen} /> </View> )} - {!storagePermissionRequired && !loadingVideos && (!videos || videos.length === 0) && ( - <View style={publishStyle.relativeCentered}> + {thumbnailPath && (!videos || videos.length === 0) && ( + <View style={publishStyle.centered}> <Text style={publishStyle.noVideos}> - {__('We could not find any videos on your device. Take a photo or record a video to get started.')} + We could not find any videos on your device. Take a photo or record a video to get started. </Text> </View> )} - {videos && thumbnailPath && allThumbnailsChecked && ( + {videos && thumbnailPath && galleryThumbnailsChecked && ( <FlatGrid style={publishStyle.galleryGrid} - initialNumToRender={18} - maxToRenderPerBatch={24} - removeClippedSubviews itemDimension={134} spacing={2} - items={videos.filter(video => checkedThumbnails.includes(video.id))} + items={this.state.videos} renderItem={({ item, index }) => { return ( <TouchableOpacity key={index} onPress={() => this.setCurrentMedia(item)}> @@ -1082,44 +581,38 @@ class PublishPage extends React.PureComponent { )} </View> ); - } else if ( - Constants.PHASE_DETAILS === this.state.currentPhase && - (this.state.editMode || this.state.currentMedia) - ) { + } else if (Constants.PHASE_DETAILS === this.state.currentPhase && this.state.currentMedia) { const { currentMedia, currentThumbnailUri } = this.state; - if (!currentThumbnailUri && !this.state.editMode) { + if (!currentThumbnailUri) { this.updateThumbnailUriForMedia(currentMedia); } content = ( - <ScrollView ref={ref => (this.scrollView = ref)} style={publishStyle.publishDetails}> - <TouchableOpacity style={publishStyle.mainThumbnailContainer} onPress={this.handleThumbnailPressed}> - <FastImage - style={publishStyle.mainThumbnail} - resizeMode={FastImage.resizeMode.contain} - source={{ uri: currentThumbnailUri }} - /> - - <View style={publishStyle.thumbnailEditOverlay}> - <Icon name={'edit'} style={publishStyle.editIcon} /> + <ScrollView style={publishStyle.publishDetails}> + {currentThumbnailUri && currentThumbnailUri.trim().length > 0 && ( + <View style={publishStyle.mainThumbnailContainer}> + <FastImage + style={publishStyle.mainThumbnail} + resizeMode={FastImage.resizeMode.contain} + source={{ uri: currentThumbnailUri }} + /> </View> + )} + {balance < 0.1 && <PublishRewardsDriver navigation={navigation} />} - {this.state.uploadThumbnailStarted && ( - <View style={publishStyle.thumbnailUploadContainer}> - <ActivityIndicator size={'small'} color={Colors.NextLbryGreen} /> - <Text style={publishStyle.thumbnailUploadText}>{__('Uploading thumbnail...')}</Text> - </View> - )} - </TouchableOpacity> - {balance < Constants.MINIMUM_TRANSACTION_BALANCE && <PublishRewardsDriver navigation={navigation} />} + {this.state.uploadThumbnailStarted && !this.state.uploadedThumbnailUri && ( + <View style={publishStyle.thumbnailUploadContainer}> + <ActivityIndicator size={'small'} color={Colors.LbryGreen} /> + <Text style={publishStyle.thumbnailUploadText}>Uploading thumbnail...</Text> + </View> + )} <View style={publishStyle.card}> <View style={publishStyle.textInputLayout}> {(this.state.titleFocused || (this.state.title != null && this.state.title.trim().length > 0)) && ( - <Text style={publishStyle.textInputTitle}>{__('Title')}</Text> + <Text style={publishStyle.textInputTitle}>Title</Text> )} <TextInput - editable={this.state.canPublish && !this.state.publishStarted} - placeholder={this.state.titleFocused ? '' : __('Title')} + placeholder={this.state.titleFocused ? '' : 'Title'} style={publishStyle.inputText} value={this.state.title} numberOfLines={1} @@ -1133,12 +626,10 @@ class PublishPage extends React.PureComponent { <View style={publishStyle.textInputLayout}> {(this.state.descriptionFocused || (this.state.description != null && this.state.description.trim().length > 0)) && ( - <Text style={publishStyle.textInputTitle}>{__('Description')}</Text> + <Text style={publishStyle.textInputTitle}>Description</Text> )} <TextInput - editable={this.state.canPublish && !this.state.publishStarted} - multiline - placeholder={this.state.descriptionFocused ? '' : __('Description')} + placeholder={this.state.descriptionFocused ? '' : 'Description'} style={publishStyle.inputText} value={this.state.description} underlineColorAndroid={Colors.NextLbryGreen} @@ -1150,7 +641,7 @@ class PublishPage extends React.PureComponent { </View> <View style={publishStyle.card}> - <Text style={publishStyle.cardTitle}>{__('Tags')}</Text> + <Text style={publishStyle.cardTitle}>Tags</Text> <View style={publishStyle.tagList}> {this.state.tags && this.state.tags.map(tag => ( @@ -1163,37 +654,30 @@ class PublishPage extends React.PureComponent { /> ))} </View> - <TagSearch handleAddTag={this.handleAddTag} selectedTags={this.state.tags} showNsfwTags /> + <TagSearch handleAddTag={this.handleAddTag} selectedTags={this.state.tags} /> </View> <View style={publishStyle.card}> - <Text style={publishStyle.cardTitle}>{__('Channel')}</Text> + <Text style={publishStyle.cardTitle}>Channel</Text> - <ChannelSelector - enabled={this.state.canPublish && !this.state.publishStarted} - channelName={this.state.channelName} - onChannelChange={this.handleChannelChange} - /> + <ChannelSelector onChannelChange={this.handleChannelChange} /> </View> <View style={publishStyle.card}> <View style={publishStyle.titleRow}> - <Text style={publishStyle.cardTitle}>{__('Price')}</Text> + <Text style={publishStyle.cardTitle}>Price</Text> <View style={publishStyle.switchTitleRow}> <Switch value={this.state.priceSet} onValueChange={value => this.setState({ priceSet: value })} /> </View> </View> {!this.state.priceSet && ( - <Text style={publishStyle.cardText}> - {__('Your content will be free. Press the toggle to set a price.')} - </Text> + <Text style={publishStyle.cardText}>Your content will be free. Press the toggle to set a price.</Text> )} {this.state.priceSet && ( <View style={[publishStyle.inputRow, publishStyle.priceInputRow]}> <TextInput - editable={this.state.canPublish && !this.state.publishStarted} placeholder={'0.00'} keyboardType={'number-pad'} style={publishStyle.priceInput} @@ -1202,144 +686,115 @@ class PublishPage extends React.PureComponent { value={String(this.state.price)} onChangeText={this.handlePriceChange} /> - <Picker - style={publishStyle.currencyPicker} - enabled={this.state.canPublish && !this.state.publishStarted} - selectedValue={this.state.currency} - itemStyle={publishStyle.pickerItem} - onValueChange={this.handleCurrencyValueChange} - > - <Picker.Item label={'LBC'} value={'LBC'} /> - <Picker.Item label={'USD'} value={'USD'} /> - </Picker> + <Text style={publishStyle.currency}>LBC</Text> </View> )} </View> - <View style={publishStyle.card}> - <Text style={publishStyle.cardTitle}>{__('Content address')}</Text> - <Text style={publishStyle.helpText}> - {__('The address where people can find your content (ex. lbry://myvideo). ')} - {this.state.editMode && - __( - 'You cannot change this address while editing your content. If you wish to use a new address, please republish the content.', - )} - </Text> + {this.state.advancedMode && ( + <View style={publishStyle.card}> + <Text style={publishStyle.cardTitle}>Content Address</Text> + <Text style={publishStyle.helpText}> + The address where people can find your content (ex. lbry://myvideo) + </Text> - <TextInput - editable={!this.state.editMode && this.state.canPublish && !this.state.publishStarted} - placeholder={'lbry://'} - style={publishStyle.inputText} - underlineColorAndroid={Colors.NextLbryGreen} - numberOfLines={1} - value={this.state.name} - onChangeText={value => this.handleNameChange(value, true)} - /> - <View style={publishStyle.inputRow}> <TextInput - editable={this.state.canPublish && !this.state.publishStarted} - placeholder={'0.00'} - style={publishStyle.priceInput} + placeholder={'lbry://'} + style={publishStyle.inputText} underlineColorAndroid={Colors.NextLbryGreen} numberOfLines={1} - keyboardType={'numeric'} - value={String(this.state.bid)} - onChangeText={this.handleBidChange} - onFocus={() => this.setState({ creditsInputFocused: true })} - onBlur={() => this.setState({ creditsInputFocused: false })} + value={this.state.name} + onChangeText={this.handleNameChange} /> - <Text style={publishStyle.currency}>LBC</Text> - <View style={publishStyle.balance}> - {this.state.creditsInputFocused && <Icon name="coins" size={12} />} - {this.state.creditsInputFocused && ( - <Text style={publishStyle.balanceText}>{formatCredits(parseFloat(balance), 1, true)}</Text> - )} + <View style={publishStyle.inputRow}> + <TextInput + placeholder={'0.00'} + style={publishStyle.priceInput} + underlineColorAndroid={Colors.NextLbryGreen} + numberOfLines={1} + keyboardType={'numeric'} + value={String(this.state.bid)} + onChangeText={this.handleBidChange} + /> + <Text style={publishStyle.currency}>LBC</Text> </View> + <Text style={publishStyle.helpText}> + This LBC remains yours and the deposit can be undone at any time. + </Text> </View> - <Text style={publishStyle.helpText}> - {__('This LBC remains yours and the deposit can be undone at any time.')} - </Text> - </View> + )} {this.state.advancedMode && ( <View style={publishStyle.card}> - <Text style={publishStyle.cardTitle}>{__('Additional Options')}</Text> + <Text style={publishStyle.cardTitle}>Additional Options</Text> + <View style={publishStyle.toggleField}> + <Switch value={this.state.mature} onValueChange={value => this.setState({ mature: value })} /> + <Text style={publishStyle.toggleText}>Mature content</Text> + </View> + <View> - <Text style={publishStyle.cardText}>{__('Language')}</Text> + <Text style={publishStyle.cardText}>Language</Text> <Picker - enabled={this.state.canPublish && !this.state.publishStarted} selectedValue={this.state.language} style={publishStyle.picker} itemStyle={publishStyle.pickerItem} onValueChange={this.handleLanguageValueChange} > {Object.keys(languages).map(lang => ( - <Picker.Item label={__(languages[lang])} value={lang} key={lang} /> + <Picker.Item label={languages[lang]} value={lang} key={lang} /> ))} </Picker> </View> <View> - <Text style={publishStyle.cardText}>{__('License')}</Text> + <Text style={publishStyle.cardText}>License</Text> <Picker - enabled={this.state.canPublish && !this.state.publishStarted} selectedValue={this.state.license} style={publishStyle.picker} itemStyle={publishStyle.pickerItem} onValueChange={this.handleLicenseValueChange} > - <Picker.Item label={__('None')} value={LICENSES.NONE} key={LICENSES.NONE} /> - <Picker.Item - label={__('Public Domain')} - value={LICENSES.PUBLIC_DOMAIN} - key={LICENSES.PUBLIC_DOMAIN} - /> + <Picker.Item label={'None'} value={LICENSES.NONE} key={LICENSES.NONE} /> + <Picker.Item label={'Public Domain'} value={LICENSES.PUBLIC_DOMAIN} key={LICENSES.PUBLIC_DOMAIN} /> {LICENSES.CC_LICENSES.map(({ value, url }) => ( <Picker.Item label={value} value={value} key={value} /> ))} - <Picker.Item label={__('Copyrighted...')} value={LICENSES.COPYRIGHT} key={LICENSES.COPYRIGHT} /> - <Picker.Item label={__('Other...')} value={LICENSES.OTHER} key={LICENSES.OTHER} /> + <Picker.Item label={'Copyrighted...'} value={LICENSES.COPYRIGHT} key={LICENSES.COPYRIGHT} /> + <Picker.Item label={'Other...'} value={LICENSES.OTHER} key={LICENSES.OTHER} /> </Picker> - {[LICENSES.COPYRIGHT, LICENSES.OTHER].includes(this.state.license) && ( - <TextInput - editable={this.state.canPublish && !this.state.publishStarted} - placeholder={__('License description')} - style={publishStyle.inputText} - underlineColorAndroid={Colors.NextLbryGreen} - numberOfLines={1} - value={this.state.otherLicenseDescription} - onChangeText={this.handleChangeLicenseDescription} - /> - )} </View> </View> )} <View style={publishStyle.toggleContainer}> <Link - text={this.state.advancedMode ? __('Hide extra fields') : __('Show extra fields')} + text={this.state.advancedMode ? 'Hide extra fields' : 'Show extra fields'} onPress={this.handleModePressed} style={publishStyle.modeLink} /> </View> <View style={publishStyle.actionButtons}> - {this.state.publishStarted && ( + {(this.state.publishStarted || publishFormValues.publishing) && ( <View style={publishStyle.progress}> - <ActivityIndicator size={'small'} color={Colors.NextLbryGreen} /> + <ActivityIndicator size={'small'} color={Colors.LbryGreen} /> </View> )} - {!this.state.publishStarted && ( - <Link style={publishStyle.cancelLink} text={__('Cancel')} onPress={() => this.showSelector()} /> + {!publishFormValues.publishing && !this.state.publishStarted && ( + <Link + style={publishStyle.cancelLink} + text="Cancel" + onPress={() => this.setState({ currentPhase: Constants.PHASE_SELECTOR })} + /> )} - {!this.state.publishStarted && ( + {!publishFormValues.publishing && !this.state.publishStarted && ( <View style={publishStyle.rightActionButtons}> <Button style={publishStyle.publishButton} - disabled={this.state.uploadThumbnailStarted} - text={this.state.editMode ? __('Save changes') : __('Publish')} + disabled={balance < 0.1 || !this.state.uploadedThumbnailUri} + text="Publish" onPress={this.handlePublishPressed} /> </View> @@ -1351,37 +806,26 @@ class PublishPage extends React.PureComponent { content = ( <ScrollView style={publishStyle.publishDetails}> <View style={publishStyle.successContainer}> - <Text style={publishStyle.successTitle}>{__('Success!')}</Text> - <Text style={publishStyle.successText}> - {__('Congratulations! Your content was successfully uploaded.')} - </Text> + <Text style={publishStyle.successTitle}>Success!</Text> + <Text style={publishStyle.successText}>Congratulations! Your content was successfully uploaded.</Text> <View style={publishStyle.successRow}> - <Link - style={publishStyle.successUrl} - text={this.state.uri} - onPress={() => navigateToUri(navigation, this.state.uri)} - /> + <Link style={publishStyle.successUrl} text={this.state.uri} href={this.state.uri} /> <TouchableOpacity onPress={() => { Clipboard.setString(this.state.uri); - notify({ message: __('Copied.') }); + notify({ message: 'Copied.' }); }} > <Icon name="clipboard" size={24} color={Colors.LbryGreen} /> </TouchableOpacity> </View> <Text style={publishStyle.successText}> - {__( - 'Your content will be live in a few minutes. In the mean time, feel free to publish more content or explore the app.', - )} + Your content will be live in a few minutes. In the mean time, feel free to publish more content or explore + the app. </Text> </View> <View style={publishStyle.actionButtons}> - <Button - style={publishStyle.publishButton} - text={__('Publish again')} - onPress={this.handlePublishAgainPressed} - /> + <Button style={publishStyle.publishButton} text="Publish again" onPress={this.handlePublishAgainPressed} /> </View> </ScrollView> ); @@ -1394,36 +838,28 @@ class PublishPage extends React.PureComponent { {false && Constants.PHASE_SELECTOR !== this.state.currentPhase && ( <FloatingWalletBalance navigation={navigation} /> )} - {this.state.showCameraOverlay && ( + {this.state.canUseCamera && this.state.showCameraOverlay && ( <View style={publishStyle.cameraOverlay}> - {this.state.canUseCamera && ( - <RNCamera - captureAudio={this.state.videoRecordingMode} - style={publishStyle.fullCamera} - ref={ref => { - this.camera = ref; - }} - type={this.state.cameraType} - flashMode={RNCamera.Constants.FlashMode.off} - androidCameraPermissionOptions={{ - title: __('Camera'), - message: __('Please grant access to make use of your camera'), - buttonPositive: __('OK'), - buttonNegative: __('Cancel'), - }} - androidRecordAudioPermissionOptions={{ - title: __('Audio'), - message: __('Please grant access to record audio'), - buttonPositive: __('OK'), - buttonNegative: __('Cancel'), - }} - notAuthorizedView={ - <View style={publishStyle.fullCentered}> - <Text style={publishStyle.cameraInfo}>{__('Camera not authorized')}</Text> - </View> - } - /> - )} + <RNCamera + style={publishStyle.fullCamera} + ref={ref => { + this.camera = ref; + }} + type={this.state.cameraType} + flashMode={RNCamera.Constants.FlashMode.off} + androidCameraPermissionOptions={{ + title: 'Camera', + message: 'Please grant access to make use of your camera', + buttonPositive: 'OK', + buttonNegative: 'Cancel', + }} + androidRecordAudioPermissionOptions={{ + title: 'Audio', + message: 'Please grant access to record audio', + buttonPositive: 'OK', + buttonNegative: 'Cancel', + }} + /> <View style={[ publishStyle.cameraControls, @@ -1431,7 +867,7 @@ class PublishPage extends React.PureComponent { ]} > <View style={publishStyle.controlsRow}> - <TouchableOpacity onPress={this.handleCloseCameraPressed} style={publishStyle.backButtonControl}> + <TouchableOpacity onPress={this.handleCloseCameraPressed}> <Icon name="arrow-left" size={28} color={Colors.White} /> </TouchableOpacity> diff --git a/src/page/publishes/index.js b/src/page/publishes/index.js index 0b365be..3989253 100644 --- a/src/page/publishes/index.js +++ b/src/page/publishes/index.js @@ -1,32 +1,21 @@ import { connect } from 'react-redux'; -import { - doAbandonClaim, - doCheckPendingPublishes, - doFetchClaimListMine, - doToast, - selectMyClaimUrisWithoutChannels, - selectPendingClaims, - selectIsFetchingClaimListMine, -} from 'lbry-redux'; +import { doCheckPendingPublishes, selectMyClaimUrisWithoutChannels, selectIsFetchingClaimListMine } from 'lbry-redux'; import { doPushDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer'; -import { selectSdkReady } from 'redux/selectors/settings'; import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api import PublishesPage from './view'; const select = state => ({ uris: selectMyClaimUrisWithoutChannels(state), fetching: selectIsFetchingClaimListMine(state), - pendingClaims: selectPendingClaims(state), - sdkReady: selectSdkReady(state), }); const perform = dispatch => ({ - abandonClaim: (txid, nout) => dispatch(doAbandonClaim(txid, nout)), - fetchMyClaims: () => dispatch(doFetchClaimListMine()), checkPendingPublishes: () => dispatch(doCheckPendingPublishes()), - notify: data => dispatch(doToast(data)), pushDrawerStack: () => dispatch(doPushDrawerStack(Constants.DRAWER_ROUTE_PUBLISHES)), setPlayerVisible: () => dispatch(doSetPlayerVisible(false)), }); -export default connect(select, perform)(PublishesPage); +export default connect( + select, + perform +)(PublishesPage); diff --git a/src/page/publishes/view.js b/src/page/publishes/view.js index b43dcbf..3a09d06 100644 --- a/src/page/publishes/view.js +++ b/src/page/publishes/view.js @@ -1,27 +1,20 @@ import React from 'react'; -import { ActivityIndicator, Alert, FlatList, NativeModules, Text, TouchableOpacity, View } from 'react-native'; +import { ActivityIndicator, FlatList, Text, TouchableOpacity, View } from 'react-native'; import Button from 'component/button'; import Colors from 'styles/colors'; import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api -import EmptyStateView from 'component/emptyStateView'; import FileListItem from 'component/fileListItem'; import FloatingWalletBalance from 'component/floatingWalletBalance'; import UriBar from 'component/uriBar'; import publishStyle from 'styles/publish'; -import { navigateToUri } from 'utils/helper'; +import { __ } from 'utils/helper'; class PublishesPage extends React.PureComponent { - state = { - selectionMode: false, - selectedUris: [], - selectedClaimsMap: {}, - }; - didFocusListener; componentWillMount() { const { navigation } = this.props; - // this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused); + this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused); } componentWillUnmount() { @@ -30,177 +23,48 @@ class PublishesPage extends React.PureComponent { } } - componentDidMount() { - this.onComponentFocused(); - } - - componentWillReceiveProps(nextProps) { - const { currentRoute } = nextProps; - const { currentRoute: prevRoute } = this.props; - - if (Constants.DRAWER_ROUTE_PUBLISHES === currentRoute && currentRoute !== prevRoute) { - this.onComponentFocused(); - } - } - onComponentFocused = () => { - const { checkPendingPublishes, fetchMyClaims, pushDrawerStack, setPlayerVisible } = this.props; + const { checkPendingPublishes, pushDrawerStack, setPlayerVisible } = this.props; + pushDrawerStack(); setPlayerVisible(); - NativeModules.Firebase.setCurrentScreen('Publishes').then(result => { - fetchMyClaims(); - checkPendingPublishes(); - }); - }; - - addOrRemoveItem = (uri, claim) => { - const { pendingClaims } = this.state; - - const { selectedClaimsMap } = this.state; - let selectedUris = [...this.state.selectedUris]; - - if (selectedUris.includes(uri)) { - delete selectedClaimsMap[uri]; - selectedUris.splice(selectedUris.indexOf(uri), 1); - } else { - selectedClaimsMap[uri] = claim; - selectedUris.push(uri); - } - - this.setState({ selectionMode: selectedUris.length > 0, selectedUris, selectedClaimsMap }); - }; - - handleSelectItem = (uri, claim) => { - this.addOrRemoveItem(uri, claim); - }; - - handleItemLongPress = (uri, claim) => { - this.addOrRemoveItem(uri, claim); - }; - - onExitSelectionMode = () => { - this.setState({ selectionMode: false, selectedUris: [], selectedClaimsMap: {} }); - }; - - onEditActionPressed = () => { - const { navigation } = this.props; - const { selectedClaimsMap, selectedUris } = this.state; - // only 1 item can be edited (and edit button should be visible only if there is a single selection) - const claim = selectedClaimsMap[selectedUris[0]]; - this.onExitSelectionMode(); - - navigation.navigate({ routeName: Constants.DRAWER_ROUTE_PUBLISH, params: { editMode: true, claimToEdit: claim } }); - }; - - onDeleteActionPressed = () => { - const { abandonClaim } = this.props; - const { selectedClaimsMap } = this.state; - - // show confirm alert - Alert.alert( - __('Unpublish'), - __('Are you sure you want to unpublish the selected content?'), - [ - { text: __('No') }, - { - text: __('Yes'), - onPress: () => { - const uris = Object.keys(selectedClaimsMap); - uris.forEach(uri => { - const { txid, nout } = selectedClaimsMap[uri]; - abandonClaim(txid, nout); - }); - this.onExitSelectionMode(); - }, - }, - ], - { cancelable: true }, - ); + checkPendingPublishes(); }; render() { - const { fetching, navigation, sdkReady, uris } = this.props; - const { selectionMode, selectedUris } = this.state; - - if (!sdkReady) { - return ( - <View style={publishStyle.container}> - <UriBar navigation={navigation} /> - <EmptyStateView - message={__( - 'The background service is still initializing. You can still explore and watch content during the initialization process.', - )} - /> - </View> - ); - } + const { fetching, navigation, uris } = this.props; return ( <View style={publishStyle.container}> - <UriBar - allowEdit - navigation={navigation} - selectionMode={selectionMode} - selectedItemCount={selectedUris.length} - onDeleteActionPressed={this.onDeleteActionPressed} - onEditActionPressed={this.onEditActionPressed} - onExitSelectionMode={this.onExitSelectionMode} - /> + <UriBar navigation={navigation} /> {fetching && ( <View style={publishStyle.centered}> - <ActivityIndicator size={'large'} color={Colors.NextLbryGreen} /> + <ActivityIndicator size={'small'} color={Colors.LbryGreen} /> </View> )} {!fetching && (!uris || uris.length === 0) && ( - <EmptyStateView - message={__('It looks like you have not\npublished any content to LBRY yet.')} - buttonText={__('Publish something new')} - onButtonPress={() => navigation.navigate({ routeName: Constants.DRAWER_ROUTE_PUBLISH })} - /> + <View style={publishStyle.noPublishes}> + <Text style={publishStyle.noPublishText}> + {__('It looks like you have not published anything to LBRY yet.')} + </Text> + <Button + style={publishStyle.publishNowButton} + text={__('Publish something new')} + onPress={() => navigation.navigate({ routeName: Constants.DRAWER_ROUTE_PUBLISH })} + /> + </View> )} {uris && uris.length > 0 && ( <FlatList style={publishStyle.publishesList} contentContainerStyle={publishStyle.publishesScrollPadding} - extraData={this.state} initialNumToRender={8} maxToRenderPerBatch={24} removeClippedSubviews - ListFooterComponent={ - <View style={publishStyle.publishesFooter}> - <Button - style={publishStyle.publishesFooterButton} - text={__('Publish something new')} - onPress={() => navigation.navigate({ routeName: Constants.DRAWER_ROUTE_PUBLISH })} - /> - </View> - } renderItem={({ item }) => ( - <FileListItem - key={item} - uri={item} - style={publishStyle.listItem} - selected={selectedUris.includes(item)} - onPress={claim => { - if (selectionMode) { - this.handleSelectItem(item, claim); - } else { - const { notify, pendingClaims } = this.props; - if (pendingClaims.some(pendingClaim => pendingClaim.claim_id === claim.claim_id)) { - notify({ - message: __('This content is currently pending. It will be available in a few minutes.'), - }); - } else { - // TODO: when shortUrl is available for my claims, navigate to that URL instead - navigateToUri(navigation, claim.permanent_url); - } - } - }} - onLongPress={claim => this.handleItemLongPress(item, claim)} - navigation={navigation} - /> + <FileListItem hideChannel key={item} uri={item} style={publishStyle.listItem} navigation={navigation} /> )} data={uris} keyExtractor={(item, index) => item} diff --git a/src/page/rewards/index.js b/src/page/rewards/index.js index 2232f3f..410a976 100644 --- a/src/page/rewards/index.js +++ b/src/page/rewards/index.js @@ -12,8 +12,7 @@ import { import { doToast } from 'lbry-redux'; import { doPushDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer'; import { selectCurrentRoute } from 'redux/selectors/drawer'; -import { selectSdkReady } from 'redux/selectors/settings'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api +import Constants from 'constants'; import RewardsPage from './view'; const select = state => ({ @@ -23,7 +22,6 @@ const select = state => ({ emailVerifyPending: selectEmailVerifyIsPending(state), fetching: selectFetchingRewards(state), rewards: selectUnclaimedRewards(state), - sdkReady: selectSdkReady(state), user: selectUser(state), }); @@ -35,4 +33,7 @@ const perform = dispatch => ({ setPlayerVisible: () => dispatch(doSetPlayerVisible(false)), }); -export default connect(select, perform)(RewardsPage); +export default connect( + select, + perform +)(RewardsPage); diff --git a/src/page/rewards/view.js b/src/page/rewards/view.js index 4edec91..0a588cf 100644 --- a/src/page/rewards/view.js +++ b/src/page/rewards/view.js @@ -1,30 +1,25 @@ import React from 'react'; -import { Lbryio } from 'lbryinc'; +import { Lbry } from 'lbry-redux'; import { ActivityIndicator, NativeModules, ScrollView, Text, View } from 'react-native'; import Colors from 'styles/colors'; import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api import Link from 'component/link'; import CustomRewardCard from 'component/customRewardCard'; -import EmptyStateView from 'component/emptyStateView'; +import PageHeader from 'component/pageHeader'; import RewardCard from 'component/rewardCard'; import RewardEnrolment from 'component/rewardEnrolment'; +import RewardSummary from 'component/rewardSummary'; import UriBar from 'component/uriBar'; import rewardStyle from 'styles/reward'; -const FILTER_ALL = 'all'; -const FILTER_AVAILABLE = 'available'; -const FILTER_CLAIMED = 'claimed'; - class RewardsPage extends React.PureComponent { state = { - currentFilter: FILTER_AVAILABLE, - firstRewardClaimed: false, isEmailVerified: false, isIdentityVerified: false, isRewardApproved: false, - revealVerification: true, - usdExchangeRate: 0, verifyRequestStarted: false, + revealVerification: true, + firstRewardClaimed: false, }; scrollView = null; @@ -33,7 +28,7 @@ class RewardsPage extends React.PureComponent { componentWillMount() { const { navigation } = this.props; - // this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused); + this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused); } componentWillUnmount() { @@ -47,14 +42,6 @@ class RewardsPage extends React.PureComponent { pushDrawerStack(); setPlayerVisible(); - NativeModules.Firebase.setCurrentScreen('Rewards'); - - Lbryio.getExchangeRates().then(rates => { - if (!isNaN(rates.LBC_USD)) { - this.setState({ usdExchangeRate: rates.LBC_USD }); - } - }); - fetchRewards(); this.setState({ @@ -116,10 +103,9 @@ class RewardsPage extends React.PureComponent { if (this.state.isEmailVerified && this.state.isIdentityVerified && !this.state.isRewardApproved) { return ( <View style={[rewardStyle.card, rewardStyle.verification]}> - <Text style={rewardStyle.title}>{__('Manual Reward Verification')}</Text> + <Text style={rewardStyle.title}>Manual Reward Verification</Text> <Text style={rewardStyle.text}> - __('You need to be manually verified before you can start claiming rewards.') Please request to be verified - on the{' '} + You need to be manually verified before you can start claiming rewards. Please request to be verified on the{' '} <Link style={rewardStyle.greenLink} href="https://discordapp.com/invite/Z3bERWA" @@ -142,15 +128,13 @@ class RewardsPage extends React.PureComponent { return ( <View style={rewardStyle.busyContainer}> <ActivityIndicator size="large" color={Colors.NextLbryGreen} /> - <Text style={rewardStyle.infoText}>{__('Fetching rewards...')}</Text> + <Text style={rewardStyle.infoText}>Fetching rewards...</Text> </View> ); } else if (user === null) { return ( <View style={rewardStyle.busyContainer}> - <Text style={rewardStyle.infoText}> - {__('This app is unable to earn rewards due to an authentication failure.')} - </Text> + <Text style={rewardStyle.infoText}>This app is unable to earn rewards due to an authentication failure.</Text> </View> ); } @@ -165,7 +149,6 @@ class RewardsPage extends React.PureComponent { canClaim={!isNotEligible} reward={reward} reward_type={reward.reward_type} - usdExchangeRate={this.state.usdExchangeRate} /> ))} <CustomRewardCard canClaim={!isNotEligible} showVerification={this.showVerification} /> @@ -195,33 +178,13 @@ class RewardsPage extends React.PureComponent { }); }; - setFilter = filter => { - this.setState({ currentFilter: filter }); - }; - render() { - const { navigation, sdkReady } = this.props; - const { currentFilter } = this.state; - - if (!sdkReady) { - return ( - <View style={rewardStyle.container}> - <UriBar navigation={navigation} /> - <EmptyStateView - message={__( - 'The background service is still initializing. You can still explore and watch content during the initialization process.', - )} - /> - </View> - ); - } + const { user, navigation } = this.props; return ( <View style={rewardStyle.container}> <UriBar navigation={navigation} /> - {(!this.state.isEmailVerified || !this.state.isRewardApproved) && ( - <RewardEnrolment usdExchangeRate={this.state.usdExchangeRate} navigation={navigation} /> - )} + {(!this.state.isEmailVerified || !this.state.isRewardApproved) && <RewardEnrolment navigation={navigation} />} {this.state.isEmailVerified && this.state.isRewardApproved && ( <ScrollView @@ -230,29 +193,8 @@ class RewardsPage extends React.PureComponent { style={rewardStyle.scrollContainer} contentContainerStyle={rewardStyle.scrollContentContainer} > - <View style={rewardStyle.filterHeader}> - <Link - style={[rewardStyle.filterLink, currentFilter === FILTER_ALL ? rewardStyle.activeFilterLink : null]} - text={__('All')} - onPress={() => this.setFilter(FILTER_ALL)} - /> - <Link - style={[ - rewardStyle.filterLink, - currentFilter === FILTER_AVAILABLE ? rewardStyle.activeFilterLink : null, - ]} - text={__('Available')} - onPress={() => this.setFilter(FILTER_AVAILABLE)} - /> - <Link - style={[rewardStyle.filterLink, currentFilter === FILTER_CLAIMED ? rewardStyle.activeFilterLink : null]} - text={__('Claimed')} - onPress={() => this.setFilter(FILTER_CLAIMED)} - /> - </View> - - {(currentFilter === FILTER_AVAILABLE || currentFilter === FILTER_ALL) && this.renderUnclaimedRewards()} - {(currentFilter === FILTER_CLAIMED || currentFilter === FILTER_ALL) && this.renderClaimedRewards()} + {this.renderUnclaimedRewards()} + {this.renderClaimedRewards()} </ScrollView> )} </View> diff --git a/src/page/search/index.js b/src/page/search/index.js index f84ee10..7cda584 100644 --- a/src/page/search/index.js +++ b/src/page/search/index.js @@ -1,52 +1,34 @@ import { connect } from 'react-redux'; import { - doClaimSearch, - doResolveUris, - doResolvedSearch, + doSearch, doUpdateSearchQuery, - makeSelectResolvedSearchResults, - makeSelectResolvedSearchResultsLastPageReached, makeSelectSearchUris, - selectClaimSearchByQuery, selectIsSearching, - selectResolvingUris, selectSearchValue, makeSelectQueryWithOptions, + selectSearchUrisByQuery, } from 'lbry-redux'; import { doPushDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer'; import { selectCurrentRoute } from 'redux/selectors/drawer'; -import { selectShowNsfw } from 'redux/selectors/settings'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api +import Constants from 'constants'; import SearchPage from './view'; const select = state => ({ - claimSearchByQuery: selectClaimSearchByQuery(state), currentRoute: selectCurrentRoute(state), isSearching: selectIsSearching(state), query: selectSearchValue(state), - resolvingUris: selectResolvingUris(state), - showNsfwContent: selectShowNsfw(state), - uris: makeSelectSearchUris( - makeSelectQueryWithOptions(null, { size: Constants.DEFAULT_PAGE_SIZE, isBackgroundSearch: false })(state), - )(state), - results: makeSelectResolvedSearchResults( - makeSelectQueryWithOptions(null, { size: Constants.DEFAULT_PAGE_SIZE, isBackgroundSearch: false })(state), - )(state), - lastPageReached: makeSelectResolvedSearchResultsLastPageReached( - makeSelectQueryWithOptions(null, { size: Constants.DEFAULT_PAGE_SIZE, isBackgroundSearch: false })(state), - )(state), + uris: makeSelectSearchUris(makeSelectQueryWithOptions(null, 25)(state))(state), + urisByQuery: selectSearchUrisByQuery(state), }); const perform = dispatch => ({ - search: (query, from, nsfw) => dispatch(doResolvedSearch(query, Constants.DEFAULT_PAGE_SIZE, from, false, {}, nsfw)), - claimSearch: options => dispatch(doClaimSearch(options)), + search: query => dispatch(doSearch(query, 25)), updateSearchQuery: query => dispatch(doUpdateSearchQuery(query)), - pushDrawerStack: (routeName, params) => dispatch(doPushDrawerStack(routeName, params)), - resolveUris: uris => dispatch(doResolveUris(uris)), + pushDrawerStack: () => dispatch(doPushDrawerStack(Constants.DRAWER_ROUTE_SEARCH)), setPlayerVisible: () => dispatch(doSetPlayerVisible(false)), }); export default connect( select, - perform, + perform )(SearchPage); diff --git a/src/page/search/view.js b/src/page/search/view.js index 9680248..3f65cf5 100644 --- a/src/page/search/view.js +++ b/src/page/search/view.js @@ -1,37 +1,19 @@ import React from 'react'; -import { Lbry, createNormalizedClaimSearchKey, parseURI, normalizeURI, isURIValid } from 'lbry-redux'; -import { - ActivityIndicator, - Button, - FlatList, - NativeModules, - Text, - TextInput, - TouchableOpacity, - View, -} from 'react-native'; +import { Lbry, parseURI, normalizeURI, isURIValid } from 'lbry-redux'; +import { ActivityIndicator, Button, Text, TextInput, View, ScrollView } from 'react-native'; import { navigateToUri } from 'utils/helper'; import Colors from 'styles/colors'; import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api import PageHeader from 'component/pageHeader'; import FileListItem from 'component/fileListItem'; -import ClaimResultItem from 'component/claimResultItem'; import FloatingWalletBalance from 'component/floatingWalletBalance'; import UriBar from 'component/uriBar'; import searchStyle from 'styles/search'; -const softLimit = 500; - class SearchPage extends React.PureComponent { state = { currentQuery: null, - currentFrom: 0, currentUri: null, - showTagResult: false, - claimSearchRun: false, - claimSearchOptions: null, - resultsResolved: false, - tagResultDisplayed: false, }; static navigationOptions = { @@ -42,7 +24,7 @@ class SearchPage extends React.PureComponent { componentWillMount() { const { navigation } = this.props; - // this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused); + this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused); } componentWillUnmount() { @@ -52,25 +34,18 @@ class SearchPage extends React.PureComponent { } onComponentFocused = () => { - const { pushDrawerStack, setPlayerVisible, navigation, query, search, showNsfwContent } = this.props; + const { pushDrawerStack, setPlayerVisible, query, search } = this.props; + pushDrawerStack(); setPlayerVisible(); - pushDrawerStack(Constants.DRAWER_ROUTE_SEARCH, navigation.state.params ? navigation.state.params : null); - NativeModules.Firebase.setCurrentScreen('Search').then(result => { - const searchQuery = query || this.getSearchQuery(); - if (searchQuery && searchQuery.trim().length > 0) { - this.setState({ - currentFrom: 0, - currentQuery: searchQuery, - currentUri: isURIValid(searchQuery) ? normalizeURI(searchQuery) : null, - claimSearchOptions: null, - claimSearchRun: false, - showTagResult: false, - resultsResolved: false, - tagResultDisplayed: false, - }); - search(searchQuery, 0, showNsfwContent); - } - }); + + const searchQuery = query || this.getSearchQuery(); + if (searchQuery && searchQuery.trim().length > 0) { + this.setState({ + currentQuery: searchQuery, + currentUri: isURIValid(searchQuery) ? normalizeURI(searchQuery) : null, + }); + search(searchQuery); + } }; componentDidMount() { @@ -78,8 +53,8 @@ class SearchPage extends React.PureComponent { } componentWillReceiveProps(nextProps) { - const { currentRoute, query, isSearching } = nextProps; - const { currentRoute: prevRoute, search, isSearching: prevIsSearching, showNsfwContent } = this.props; + const { currentRoute, query } = nextProps; + const { currentRoute: prevRoute, search } = this.props; if (Constants.DRAWER_ROUTE_SEARCH === currentRoute && currentRoute !== prevRoute) { this.onComponentFocused(); @@ -87,43 +62,10 @@ class SearchPage extends React.PureComponent { if (query && query.trim().length > 0 && query !== this.state.currentQuery) { this.setState({ - currentFrom: 0, currentQuery: query, currentUri: isURIValid(query) ? normalizeURI(query) : null, - resultsResolved: false, - tagResultDisplayed: false, }); - search(query, 0, showNsfwContent); - } - } - - allContentResolved(props) { - const { uris, resolvingUris } = props; - if (!this.state.resultsResolved) { - return false; - } - if (uris) { - let allResolved = true; - uris.forEach(uri => { - allResolved = allResolved && !resolvingUris.includes(uri); - }); - return allResolved; - } - - return false; - } - - /* shouldComponentUpdate(nextProps) { - const { isSearching, uris } = this.props; - return (isSearching && (!uris || uris.length === 0)) || (!isSearching && this.allContentResolved(this.props)); - } */ - - componentDidUpdate() { - const { claimSearchByQuery } = this.props; - if (this.state.claimSearchRun && this.state.claimSearchOptions && !this.state.tagResultDisplayed) { - const claimSearchKey = createNormalizedClaimSearchKey(this.state.claimSearchOptions); - const claimSearchUris = claimSearchByQuery[claimSearchKey]; - this.setState({ showTagResult: claimSearchUris && claimSearchUris.length > 0, tagResultDisplayed: true }); + search(query); } } @@ -136,120 +78,59 @@ class SearchPage extends React.PureComponent { } handleSearchSubmitted = keywords => { - const { search, showNsfwContent } = this.props; - this.setState({ - currentUri: isURIValid(keywords) ? normalizeURI(keywords) : null, - currentFrom: 0, - currentQuery: keywords, - claimSearchOptions: null, - claimSearchRun: false, - showTagResult: false, - resultsResolved: false, - tagResultDisplayed: false, - }); - search(keywords, 0, showNsfwContent); - }; - - listEmptyComponent = () => { - const { query } = this.props; - return ( - <View style={searchStyle.noResults}> - <Text style={searchStyle.noResultsText}> - {__('There are no results to display for "%query%". Please try a different search term.', { query })} - </Text> - </View> - ); - }; - - listHeaderComponent = (showTagResult, query) => { - const { navigation, claimSearch } = this.props; - const { currentUri } = this.state; - - const canBeTag = query && query.trim().length > 0 && isURIValid(query); - if (canBeTag && !this.state.claimSearchRun) { - const options = { - any_tags: [query.toLowerCase()], - page: 1, - no_totals: true, - }; - this.setState({ claimSearchOptions: options, claimSearchRun: true }, () => claimSearch(options)); - } - - return ( - <View> - <FileListItem uri={currentUri} featuredResult style={searchStyle.featuredResultItem} navigation={navigation} /> - {showTagResult && ( - <TouchableOpacity style={searchStyle.tagResultItem} onPress={() => this.handleTagResultPressed(query)}> - <Text style={searchStyle.tagResultTitle}>#{query.toLowerCase()}</Text> - <Text style={searchStyle.tagResultDescription}>{__('Explore content for this tag')}</Text> - </TouchableOpacity> - )} - </View> - ); - }; - - handleTagResultPressed = tag => { - const { navigation } = this.props; - navigation.navigate({ routeName: Constants.DRAWER_ROUTE_TAG, key: `tagPage`, params: { tag: tag.toLowerCase() } }); - }; - - handleVerticalEndReached = () => { - // fetch more results - const { lastPageReached, results, search, showNsfwContent, isSearching } = this.props; - if (lastPageReached || (results && results.length > softLimit)) { - return; - } - - if (!isSearching) { - const from = results ? results.length : 0; - this.setState({ currentFrom: from }, () => { - search(this.state.currentQuery, from, showNsfwContent); - }); - } + const { search } = this.props; + this.setState({ currentUri: isURIValid(keywords) ? normalizeURI(keywords) : null }); + search(keywords); }; render() { - const { isSearching, navigation, query, results } = this.props; + const { isSearching, navigation, query, uris, urisByQuery } = this.props; return ( <View style={searchStyle.container}> <UriBar value={query} navigation={navigation} onSearchSubmitted={this.handleSearchSubmitted} /> - - {isSearching && this.state.currentFrom === 0 && ( + {isSearching && ( <View style={searchStyle.busyContainer}> <ActivityIndicator size="large" color={Colors.NextLbryGreen} style={searchStyle.loading} /> </View> )} - <FlatList - extraData={this.state} - style={searchStyle.scrollContainer} - contentContainerStyle={searchStyle.scrollPadding} - keyboardShouldPersistTaps={'handled'} - data={results} - keyExtractor={(item, index) => item.claimId} - initialNumToRender={10} - maxToRenderPerBatch={20} - onEndReached={this.handleVerticalEndReached} - onEndReachedThreshold={0.2} - removeClippedSubviews - ListEmptyComponent={!isSearching ? this.listEmptyComponent() : null} - ListHeaderComponent={this.listHeaderComponent(this.state.showTagResult, this.state.currentQuery)} - renderItem={({ item }) => ( - <ClaimResultItem - key={item.claimId} - uri={item ? normalizeURI(`${item.name}#${item.claimId}`) : null} - result={item} - style={searchStyle.resultItem} - navigation={navigation} - /> - )} - /> - - {this.state.currentFrom > 0 && isSearching && ( - <View style={searchStyle.moreLoading}> - <ActivityIndicator size="small" color={Colors.NextLbryGreen} /> - </View> + {!isSearching && ( + <ScrollView + style={searchStyle.scrollContainer} + contentContainerStyle={searchStyle.scrollPadding} + keyboardShouldPersistTaps={'handled'} + > + {this.state.currentUri && ( + <FileListItem + key={this.state.currentUri} + uri={this.state.currentUri} + featuredResult + style={searchStyle.featuredResultItem} + navigation={navigation} + onPress={() => navigateToUri(navigation, this.state.currentUri)} + /> + )} + {uris && uris.length + ? uris.map(uri => ( + <FileListItem + key={uri} + uri={uri} + style={searchStyle.resultItem} + navigation={navigation} + onPress={() => navigateToUri(navigation, uri)} + /> + )) + : null} + {(!uris || uris.length === 0) && ( + <View style={searchStyle.noResults}> + <Text style={searchStyle.noResultsText}> + There are no results to display for <Text style={searchStyle.boldText}>{query}</Text>. Please try a + different search term. + </Text> + </View> + )} + </ScrollView> )} <FloatingWalletBalance navigation={navigation} /> </View> diff --git a/src/page/settings/index.js b/src/page/settings/index.js index f5353a4..e630143 100644 --- a/src/page/settings/index.js +++ b/src/page/settings/index.js @@ -1,33 +1,28 @@ import { connect } from 'react-redux'; -import { SETTINGS, doToast } from 'lbry-redux'; +import { SETTINGS } from 'lbry-redux'; import { doPushDrawerStack, doPopDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer'; import { doSetClientSetting } from 'redux/actions/settings'; import { selectCurrentRoute, selectDrawerStack } from 'redux/selectors/drawer'; import { makeSelectClientSetting } from 'redux/selectors/settings'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api +import Constants from 'constants'; import SettingsPage from './view'; const select = state => ({ backgroundPlayEnabled: makeSelectClientSetting(SETTINGS.BACKGROUND_PLAY_ENABLED)(state), currentRoute: selectCurrentRoute(state), drawerStack: selectDrawerStack(state), - enableDht: makeSelectClientSetting(Constants.SETTING_DHT_ENABLED)(state), keepDaemonRunning: makeSelectClientSetting(SETTINGS.KEEP_DAEMON_RUNNING)(state), - language: makeSelectClientSetting(SETTINGS.LANGUAGE)(state), showNsfw: makeSelectClientSetting(SETTINGS.SHOW_NSFW)(state), - showUriBarSuggestions: makeSelectClientSetting(SETTINGS.SHOW_URI_BAR_SUGGESTIONS)(state), - receiveSubscriptionNotifications: makeSelectClientSetting(SETTINGS.RECEIVE_SUBSCRIPTION_NOTIFICATIONS)(state), - receiveRewardNotifications: makeSelectClientSetting(SETTINGS.RECEIVE_REWARD_NOTIFICATIONS)(state), - receiveInterestsNotifications: makeSelectClientSetting(SETTINGS.RECEIVE_INTERESTS_NOTIFICATIONS)(state), - receiveCreatorNotifications: makeSelectClientSetting(SETTINGS.RECEIVE_CREATOR_NOTIFICATIONS)(state), }); const perform = dispatch => ({ - notify: data => dispatch(doToast(data)), pushDrawerStack: () => dispatch(doPushDrawerStack(Constants.DRAWER_ROUTE_SETTINGS)), popDrawerStack: () => dispatch(doPopDrawerStack()), setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)), setPlayerVisible: () => dispatch(doSetPlayerVisible(false)), }); -export default connect(select, perform)(SettingsPage); +export default connect( + select, + perform +)(SettingsPage); diff --git a/src/page/settings/view.js b/src/page/settings/view.js index 04c23c6..f131bf6 100644 --- a/src/page/settings/view.js +++ b/src/page/settings/view.js @@ -1,54 +1,12 @@ import React from 'react'; import { SETTINGS } from 'lbry-redux'; -import { - ActivityIndicator, - Picker, - Platform, - Text, - TextInput, - View, - ScrollView, - Switch, - NativeModules, -} from 'react-native'; +import { Text, View, ScrollView, Switch, NativeModules } from 'react-native'; import { navigateBack } from 'utils/helper'; -import AsyncStorage from '@react-native-community/async-storage'; -import Colors from 'styles/colors'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api +import Constants from 'constants'; import PageHeader from 'component/pageHeader'; -import RNFS from 'react-native-fs'; import settingsStyle from 'styles/settings'; -const languageOptions = [ - { code: 'default', name: 'Use device language' }, - { code: 'jv', name: 'Basa Jawa' }, - { code: 'da', name: 'Danish' }, - { code: 'nl', name: 'Dutch' }, - { code: 'en', name: 'English' }, - { code: 'et', name: 'Estonian' }, - { code: 'fr', name: 'French' }, - { code: 'gu', name: 'Gujarati' }, - { code: 'hi', name: 'Hindi' }, - { code: 'id', name: 'Indonesian' }, - { code: 'it', name: 'Italian' }, - { code: 'kn', name: 'Kannada' }, - { code: 'ms', name: 'Malay' }, - { code: 'mr', name: 'Marathi' }, - { code: 'pl', name: 'Polish' }, - { code: 'pt', name: 'Portuguese' }, - { code: 'ro', name: 'Romanian' }, - { code: 'ru', name: 'Russian' }, - { code: 'sk', name: 'Slovak' }, - { code: 'es', name: 'Spanish' }, - { code: 'tr', name: 'Turkish' }, - { code: 'uk', name: 'Ukrainian' }, -]; - class SettingsPage extends React.PureComponent { - state = { - downloadingLanguage: false, - }; - static navigationOptions = { title: 'Settings', }; @@ -57,7 +15,7 @@ class SettingsPage extends React.PureComponent { componentWillMount() { const { navigation } = this.props; - // this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused); + this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused); } componentWillUnmount() { @@ -70,7 +28,6 @@ class SettingsPage extends React.PureComponent { const { pushDrawerStack, setPlayerVisible } = this.props; pushDrawerStack(); setPlayerVisible(); - NativeModules.Firebase.setCurrentScreen('Settings'); }; componentDidMount() { @@ -85,112 +42,30 @@ class SettingsPage extends React.PureComponent { } } - setNativeBooleanSetting = (key, value) => { - const { setClientSetting } = this.props; - setClientSetting(key, value); - NativeModules.UtilityModule.setNativeBooleanSetting(key, value); - }; - - getBooleanSetting = (value, defaultValue) => { - return value === null || value === undefined ? defaultValue : value; - }; - - handleLanguageValueChange = value => { - const { notify, setClientSetting } = this.props; - - let language; - if (value === 'default') { - language = - Platform.OS === 'android' - ? NativeModules.I18nManager.localeIdentifier - : NativeModules.SettingsManager.settings.AppleLocale; - language = language ? language.substring(0, 2) : 'en'; - } else { - language = value; - } - - // check the local filesystem for the language first? Or download remote strings first? - if (language === 'en') { - // don't attempt to download English - NativeModules.UtilityModule.setNativeStringSetting(SETTINGS.LANGUAGE, language); - - // update state and client setting - window.language = language; - setClientSetting(SETTINGS.LANGUAGE, value); - } else { - // download and save the language file - this.setState({ downloadingLanguage: true }, () => { - fetch('https://lbry.com/i18n/get/lbry-mobile/app-strings/' + language + '.json') - .then(r => r.json()) - .then(j => { - window.i18n_messages[language] = j; - - // write the language file to the filesystem - const langFilePath = RNFS.ExternalDirectoryPath + '/' + language + '.json'; - RNFS.writeFile(langFilePath, JSON.stringify(j), 'utf8'); - - // save the setting outside redux because when the first component mounts, the redux value isn't loaded yet - // so we have to load it from native settings - NativeModules.UtilityModule.setNativeStringSetting(SETTINGS.LANGUAGE, language); - - // update state and client setting - window.language = language; - setClientSetting(SETTINGS.LANGUAGE, value); - - this.setState({ downloadingLanguage: false }); - }) - .catch(e => { - notify({ message: __('Failed to load %language% translations.', { language: language }), isError: true }); - this.setState({ downloadingLanguage: false }); - }); - }); - } - }; - - handleBackPressed = () => { - const { navigation, notify, drawerStack, popDrawerStack } = this.props; - - if (this.state.downloadingLanguage) { - notify({ message: 'Please wait for the language file to finish downloading' }); - return; - } - - navigateBack(navigation, drawerStack, popDrawerStack); - }; - render() { const { backgroundPlayEnabled, - enableDht, + drawerStack, keepDaemonRunning, - receiveSubscriptionNotifications, - receiveRewardNotifications, - receiveInterestsNotifications, - receiveCreatorNotifications, - language, + navigation, + popDrawerStack, showNsfw, - showUriBarSuggestions, setClientSetting, } = this.props; // default to true if the setting is null or undefined - const actualKeepDaemonRunning = this.getBooleanSetting(keepDaemonRunning, true); - const actualReceiveSubscriptionNotifications = this.getBooleanSetting(receiveSubscriptionNotifications, true); - const actualReceiveRewardNotifications = this.getBooleanSetting(receiveRewardNotifications, true); - const actualReceiveInterestsNotifications = this.getBooleanSetting(receiveInterestsNotifications, true); - const actualReceiveCreatorNotifications = this.getBooleanSetting(receiveCreatorNotifications, true); - const actualEnableDht = this.getBooleanSetting(enableDht, false); + const actualKeepDaemonRunning = + keepDaemonRunning === null || keepDaemonRunning === undefined ? true : keepDaemonRunning; return ( <View style={settingsStyle.container}> - <PageHeader title={__('Settings')} onBackPressed={this.handleBackPressed} /> + <PageHeader title={'Settings'} onBackPressed={() => navigateBack(navigation, drawerStack, popDrawerStack)} /> <ScrollView style={settingsStyle.scrollContainer}> - <Text style={settingsStyle.sectionTitle}>{__('Content')}</Text> <View style={settingsStyle.row}> <View style={settingsStyle.switchText}> - <Text style={settingsStyle.label}>{__('Enable background media playback')}</Text> + <Text style={settingsStyle.label}>Enable background media playback</Text> <Text style={settingsStyle.description}> - {__('Enable this option to play audio or video in the background when the app is suspended.')} + Enable this option to play audio or video in the background when the app is suspended. </Text> </View> <View style={settingsStyle.switchContainer}> @@ -201,124 +76,21 @@ class SettingsPage extends React.PureComponent { </View> </View> - <Text style={settingsStyle.sectionTitle}>{__('Language')}</Text> - <View style={settingsStyle.pickerRow}> - <View style={settingsStyle.pickerText}> - <Text style={settingsStyle.label}>{__('Choose language')}</Text> - </View> - <View style={settingsStyle.pickerContainer}> - {this.state.downloadingLanguage && <ActivityIndicator size={'small'} color={Colors.NextLbryGreen} />} - <Picker - enabled={!this.state.downloadingLanguage} - selectedValue={language || 'default'} - style={settingsStyle.languagePicker} - itemStyle={settingsStyle.languagePickerItem} - onValueChange={this.handleLanguageValueChange} - > - {languageOptions.map(option => ( - <Picker.Item label={__(option.name)} value={option.code} key={option.code} /> - ))} - </Picker> - </View> - </View> - <View style={settingsStyle.row}> <View style={settingsStyle.switchText}> - <Text style={settingsStyle.label}>{__('Show mature content')}</Text> + <Text style={settingsStyle.label}>Show NSFW content</Text> </View> <View style={settingsStyle.switchContainer}> <Switch value={showNsfw} onValueChange={value => setClientSetting(SETTINGS.SHOW_NSFW, value)} /> </View> </View> - <View style={settingsStyle.sectionDivider} /> - <Text style={settingsStyle.sectionTitle}>{__('Notifications')}</Text> - <Text style={settingsStyle.sectionDescription}> - {__('Choose the notifications you would like to receive.')} - </Text> <View style={settingsStyle.row}> <View style={settingsStyle.switchText}> - <Text style={settingsStyle.label}>{__('Subscriptions')}</Text> - </View> - <View style={settingsStyle.switchContainer}> - <Switch - value={actualReceiveSubscriptionNotifications} - onValueChange={value => { - this.setNativeBooleanSetting(SETTINGS.RECEIVE_SUBSCRIPTION_NOTIFICATIONS, value); - }} - /> - </View> - </View> - - <View style={settingsStyle.row}> - <View style={settingsStyle.switchText}> - <Text style={settingsStyle.label}>{__('Rewards')}</Text> - </View> - <View style={settingsStyle.switchContainer}> - <Switch - value={actualReceiveRewardNotifications} - onValueChange={value => { - this.setNativeBooleanSetting(SETTINGS.RECEIVE_REWARD_NOTIFICATIONS, value); - }} - /> - </View> - </View> - - <View style={settingsStyle.row}> - <View style={settingsStyle.switchText}> - <Text style={settingsStyle.label}>{__('Content Interests')}</Text> - </View> - <View style={settingsStyle.switchContainer}> - <Switch - value={actualReceiveInterestsNotifications} - onValueChange={value => { - this.setNativeBooleanSetting(SETTINGS.RECEIVE_INTERESTS_NOTIFICATIONS, value); - }} - /> - </View> - </View> - - {false && ( - <View style={settingsStyle.row}> - <View style={settingsStyle.switchText}> - <Text style={settingsStyle.label}>{__('Content creator tips')}</Text> - </View> - <View style={settingsStyle.switchContainer}> - <Switch - value={actualReceiveCreatorNotifications} - onValueChange={value => { - this.setNativeBooleanSetting(SETTINGS.RECEIVE_CREATOR_NOTIFICATIONS, value); - }} - /> - </View> - </View> - )} - - <View style={settingsStyle.sectionDivider} /> - <Text style={settingsStyle.sectionTitle}>{__('Search')}</Text> - <View style={settingsStyle.row}> - <View style={settingsStyle.switchText}> - <Text style={settingsStyle.label}>{__('Show URL suggestions')}</Text> - </View> - <View style={settingsStyle.switchContainer}> - <Switch - value={showUriBarSuggestions} - onValueChange={value => setClientSetting(SETTINGS.SHOW_URI_BAR_SUGGESTIONS, value)} - /> - </View> - </View> - - <View style={settingsStyle.sectionDivider} /> - <Text style={settingsStyle.sectionTitle}>{__('Other')}</Text> - <View style={settingsStyle.row}> - <View style={settingsStyle.switchText}> - <Text style={settingsStyle.label}> - {__('Keep the SDK background service running after closing the app')} - </Text> + <Text style={settingsStyle.label}>Keep the daemon background service running after closing the app</Text> <Text style={settingsStyle.description}> - {__( - 'Enable this option for quicker app launch and to keep the synchronisation with the blockchain up to date.', - )} + Enable this option for quicker app launch and to keep the synchronisation with the blockchain up to + date. </Text> </View> <View style={settingsStyle.switchContainer}> @@ -333,25 +105,6 @@ class SettingsPage extends React.PureComponent { /> </View> </View> - - <View style={settingsStyle.row}> - <View style={settingsStyle.switchText}> - <Text style={settingsStyle.label}>{__('Participate in the data network')}</Text> - <Text style={settingsStyle.description}> - {__( - 'Enable peer-to-peer functionality (this will take effect upon app and background service restart)', - )} - </Text> - </View> - <View style={settingsStyle.switchContainer}> - <Switch - value={actualEnableDht} - onValueChange={value => { - this.setNativeBooleanSetting(Constants.SETTING_DHT_ENABLED, value); - }} - /> - </View> - </View> </ScrollView> </View> ); diff --git a/src/page/splash/index.js b/src/page/splash/index.js index 7e8e3b7..d3b644e 100644 --- a/src/page/splash/index.js +++ b/src/page/splash/index.js @@ -1,45 +1,45 @@ import { connect } from 'react-redux'; -import { SETTINGS, doUpdateBlockHeight, doPopulateSharedUserState, doToast } from 'lbry-redux'; +import { doBalanceSubscribe, doUpdateBlockHeight, doToast } from 'lbry-redux'; import { doAuthenticate, - doClaimRewardType, - doInstallNewWithParams, + doBlackListedOutpointsSubscribe, + doFilteredOutpointsSubscribe, + doCheckSubscriptionsInit, doFetchMySubscriptions, doFetchRewardedContent, doGetSync, doUserEmailToVerify, doUserEmailVerify, doUserEmailVerifyFailure, - selectAuthenticationIsPending, selectUser, selectEmailToVerify, } from 'lbryinc'; import { doSetClientSetting } from 'redux/actions/settings'; -import { selectLastRouteInStack } from 'redux/selectors/drawer'; import SplashScreen from './view'; const select = state => ({ - authIsPending: selectAuthenticationIsPending(state), user: selectUser(state), emailToVerify: selectEmailToVerify(state), - lastRouteInStack: selectLastRouteInStack(state), }); const perform = dispatch => ({ - authenticate: (appVersion, os, firebaseToken, callInstall) => - dispatch(doAuthenticate(appVersion, os, firebaseToken, true, null, callInstall)), - installNewWithParams: (appVersion, installationId, nodeId, lbrynetVersion, os, platform, firebaseToken) => - dispatch(doInstallNewWithParams(appVersion, installationId, nodeId, lbrynetVersion, os, platform, firebaseToken)), + authenticate: (appVersion, os) => dispatch(doAuthenticate(appVersion, os)), + balanceSubscribe: () => dispatch(doBalanceSubscribe()), + blacklistedOutpointsSubscribe: () => dispatch(doBlackListedOutpointsSubscribe()), + filteredOutpointsSubscribe: () => dispatch(doFilteredOutpointsSubscribe()), + checkSubscriptionsInit: () => dispatch(doCheckSubscriptionsInit()), fetchRewardedContent: () => dispatch(doFetchRewardedContent()), fetchSubscriptions: callback => dispatch(doFetchMySubscriptions(callback)), - getSync: (password, callback) => dispatch(doGetSync(password, callback)), + getSync: password => dispatch(doGetSync(password)), notify: data => dispatch(doToast(data)), setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)), setEmailToVerify: email => dispatch(doUserEmailToVerify(email)), - populateSharedUserState: settings => dispatch(doPopulateSharedUserState(settings)), updateBlockHeight: () => dispatch(doUpdateBlockHeight()), verifyUserEmail: (token, recaptcha) => dispatch(doUserEmailVerify(token, recaptcha)), verifyUserEmailFailure: error => dispatch(doUserEmailVerifyFailure(error)), }); -export default connect(select, perform)(SplashScreen); +export default connect( + select, + perform +)(SplashScreen); diff --git a/src/page/splash/view.js b/src/page/splash/view.js index 5ad5265..266e07e 100644 --- a/src/page/splash/view.js +++ b/src/page/splash/view.js @@ -1,35 +1,33 @@ import React from 'react'; -import { Lbry, doPreferenceGet, isURIValid } from 'lbry-redux'; -import { Lbryio } from 'lbryinc'; -import { ActivityIndicator, DeviceEventEmitter, Linking, NativeModules, Platform, Text, View } from 'react-native'; +import { Lbry } from 'lbry-redux'; +import { ActivityIndicator, Linking, NativeModules, Platform, Text, View } from 'react-native'; import { NavigationActions, StackActions } from 'react-navigation'; import { decode as atob } from 'base-64'; -import { navigateToUri, transformUrl } from 'utils/helper'; +import { navigateToUri } from 'utils/helper'; import moment from 'moment'; import AsyncStorage from '@react-native-community/async-storage'; import Button from 'component/button'; import ProgressBar from 'component/progressBar'; import PropTypes from 'prop-types'; import Colors from 'styles/colors'; -import Constants, { DrawerRoutes, InnerDrawerRoutes } from 'constants'; // eslint-disable-line node/no-deprecated-api +import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api import splashStyle from 'styles/splash'; -import RNFS from 'react-native-fs'; const BLOCK_HEIGHT_INTERVAL = 1000 * 60 * 2.5; // every 2.5 minutes +const testingNetwork = 'Testing network'; +const waitingForResolution = 'Waiting for name resolution'; + class SplashScreen extends React.PureComponent { static navigationOptions = { title: 'Splash', }; state = { - authWithoutSdk: false, accountUnlockFailed: false, - appVersion: null, daemonReady: false, - details: __('Starting up'), - firebaseToken: null, - message: __('Connecting'), + details: 'Starting up', + message: 'Connecting', isRunning: false, isLagging: false, launchUrl: null, @@ -37,247 +35,172 @@ class SplashScreen extends React.PureComponent { headersDownloadProgress: 0, shouldAuthenticate: false, subscriptionsFetched: false, - liteMode: false, - liteModeParams: {}, }; - initLiteMode = () => { - NativeModules.UtilityModule.getLbrynetDirectory().then(path => { - NativeModules.UtilityModule.getPlatform().then(platform => { - RNFS.readFile(`${path}/install_id`, 'utf8') - .then(installIdContent => { - // node_id is actually optional (won't be present if dht is disabled) - // RNFS.readFile(`${path}/node_id`, 'utf8').then(nodeIdContent => { - // TODO: Load proper lbrynetVersion value - this.setState( - { - liteModeParams: { - installationId: installIdContent, - nodeId: null, - lbrynetVersion: '0.64.0', - platform, - }, - }, - () => this.updateStatus(), - ); - // }).catch((err) => { console.log(err); console.log('node_id not found.'); this.lbryConnect() }); - }) - .catch(() => this.lbryConnect()); - }); - }); - }; - - authenticateWithoutSdk() { - const { authenticate } = this.props; - NativeModules.VersionInfo.getAppVersion().then(appVersion => { - this.setState({ appVersion, shouldAuthenticate: true, authWithoutSdk: true }); - NativeModules.Firebase.getMessagingToken() - .then(firebaseToken => { - this.setState({ firebaseToken }, () => authenticate(appVersion, Platform.OS, firebaseToken, false)); - }) - .catch(() => { - authenticate(appVersion, Platform.OS, null, false); - }); - }); - } - - updateStatus() { - const { liteMode } = this.state; - - // authenticate immediately - if (!NativeModules.UtilityModule.dhtEnabled) { - this.authenticateWithoutSdk(); + componentWillMount() { + if (NativeModules.DaemonServiceControl) { + NativeModules.DaemonServiceControl.startService(); } } + updateStatus() { + Lbry.status().then(status => { + this._updateStatusCallback(status); + }); + } + navigateToMain = () => { - const { lastRouteInStack, navigation, notify, verifyUserEmail, verifyUserEmailFailure } = this.props; + const { navigation, notify, verifyUserEmail, verifyUserEmailFailure } = this.props; const resetAction = StackActions.reset({ index: 0, actions: [NavigationActions.navigate({ routeName: 'Main' })], }); navigation.dispatch(resetAction); - const launchUrl = - navigation.state.params && navigation.state.params.launchUrl - ? navigation.state.params.launchUrl - : this.state.launchUrl; + const launchUrl = navigation.state.params.launchUrl || this.state.launchUrl; if (launchUrl) { - navigateToUri(navigation, transformUrl(launchUrl)); - } else if (lastRouteInStack) { - // no launch url, check if there's a last route in stack to navigate to. - const { route, params } = lastRouteInStack; - if (route) { - if (DrawerRoutes.includes(route)) { - navigation.navigate({ routeName: route, params }); - } else if (!InnerDrawerRoutes.includes(route) && isURIValid(route)) { - navigateToUri(navigation, route); + if (launchUrl.startsWith('lbry://?verify=')) { + let verification = {}; + try { + verification = JSON.parse(atob(launchUrl.substring(15))); + } catch (error) { + console.log(error); } + if (verification.token && verification.recaptcha) { + AsyncStorage.setItem(Constants.KEY_SHOULD_VERIFY_EMAIL, 'true'); + try { + verifyUserEmail(verification.token, verification.recaptcha); + } catch (error) { + const message = 'Invalid Verification Token'; + verifyUserEmailFailure(message); + notify({ message }); + } + } else { + notify({ + message: 'Invalid Verification URI', + }); + } + } else { + navigateToUri(navigation, launchUrl); } } - - // splash screen is done at this point, next page to be displayed will be user-interactable - NativeModules.Firebase.logLaunchTiming(); }; componentWillReceiveProps(nextProps) { - const { getSync, installNewWithParams } = this.props; - const { - daemonReady, - authWithoutSdk, - shouldAuthenticate, - liteMode, - liteModeParams, - appVersion, - firebaseToken, - } = this.state; + const { emailToVerify, getSync, setEmailToVerify, verifyUserEmail, verifyUserEmailFailure } = this.props; const { user } = nextProps; - if (liteMode && user && user.id) { - this.navigateToLiteMode(); - } else if (shouldAuthenticate && user && user.id) { - if (daemonReady || authWithoutSdk) { - this.setState({ shouldAuthenticate: false }, () => { - // call install new after successful authentication - if (authWithoutSdk) { - const { installationId, nodeId, lbrynetVersion, platform } = liteModeParams; - installNewWithParams( - appVersion, - installationId, - nodeId, - lbrynetVersion, - Platform.OS, - platform, - firebaseToken, - ); - } - - // user is authenticated, navigate to the main view - if (user.has_verified_email) { - NativeModules.UtilityModule.getSecureValue(Constants.KEY_WALLET_PASSWORD).then(walletPassword => { - getSync(walletPassword, () => { - this.getUserSettings(); - }); - }); - + if (this.state.daemonReady && this.state.shouldAuthenticate && user && user.id) { + this.setState({ shouldAuthenticate: false }, () => { + // user is authenticated, navigate to the main view + if (user.has_verified_email) { + NativeModules.UtilityModule.getSecureValue(Constants.KEY_FIRST_RUN_PASSWORD).then(walletPassword => { + if (walletPassword && walletPassword.trim().length > 0) { + getSync(walletPassword); + } this.navigateToMain(); - return; - } + }); + return; + } - this.navigateToMain(); - }); - } + this.navigateToMain(); + }); } } - navigateToLiteMode = () => { - const { navigation } = this.props; - const { launchUrl } = this.state; - const resetAction = StackActions.reset({ - index: 0, - actions: [ - NavigationActions.navigate({ - routeName: Constants.DRAWER_ROUTE_LITE_FILE, - params: { uri: launchUrl }, - }), - ], - }); - navigation.dispatch(resetAction); - }; - - getUserSettings = () => { - const { populateSharedUserState } = this.props; - - doPreferenceGet( - 'shared', - preference => { - populateSharedUserState(preference); - }, - error => { - /* failed */ - }, - ); - }; - - onNotificationTargetLaunch = evt => { - if (evt.url && evt.url.startsWith('lbry://')) { - this.setState({ launchUrl: evt.url }); - } - }; - finishSplashScreen = () => { - const { authenticate, getSync, user } = this.props; + const { + authenticate, + balanceSubscribe, + blacklistedOutpointsSubscribe, + checkSubscriptionsInit, + filteredOutpointsSubscribe, + getSync, + updateBlockHeight, + user, + } = this.props; - // Leave the splash screen - if (user && user.id && user.has_verified_email) { - // user already authenticated - NativeModules.UtilityModule.getSecureValue(Constants.KEY_WALLET_PASSWORD).then(walletPassword => { - getSync(walletPassword, () => { - this.getUserSettings(); + Lbry.resolve({ urls: 'lbry://one' }).then(() => { + // Leave the splash screen + balanceSubscribe(); + blacklistedOutpointsSubscribe(); + filteredOutpointsSubscribe(); + checkSubscriptionsInit(); + + if (user && user.id && user.has_verified_email) { + // user already authenticated + NativeModules.UtilityModule.getSecureValue(Constants.KEY_FIRST_RUN_PASSWORD).then(walletPassword => { + if (walletPassword && walletPassword.trim().length > 0) { + getSync(walletPassword); + } + this.navigateToMain(); }); - }); - this.navigateToMain(); - } else { - NativeModules.VersionInfo.getAppVersion().then(appVersion => { - this.setState({ shouldAuthenticate: true }, () => { - NativeModules.Firebase.getMessagingToken() - .then(firebaseToken => { - authenticate(appVersion, Platform.OS, firebaseToken, true); - }) - .catch(() => authenticate(appVersion, Platform.OS, null, true)); + } else { + NativeModules.VersionInfo.getAppVersion().then(appVersion => { + this.setState({ shouldAuthenticate: true }); + authenticate(appVersion, Platform.OS); }); - }); - } + } + }); }; handleAccountUnlockFailed() { this.setState({ accountUnlockFailed: true }); } - handleSdkReady = () => { - this.setState({ daemonReady: true }, () => { - Lbry.wallet_status().then(secureWalletStatus => { - // For now, automatically unlock the wallet if a password is set so that downloads work - NativeModules.UtilityModule.getSecureValue(Constants.KEY_WALLET_PASSWORD).then(password => { - if ((secureWalletStatus.is_encrypted && !secureWalletStatus.is_locked) || secureWalletStatus.is_locked) { - this.setState({ - message: __('Unlocking account'), - details: __('Decrypting wallet'), - }); - - // unlock the wallet and then finish the splash screen - Lbry.wallet_unlock({ password: password || '' }).then(unlocked => { - if (unlocked) { - this.setState({ - message: __('Authenticating'), - details: __('Waiting for authentication'), - }); - this.finishSplashScreen(); - } else { - this.handleAccountUnlockFailed(); - } - }); - } else { - this.setState({ - message: __('Authenticating'), - details: __('Waiting for authentication'), - }); - this.finishSplashScreen(); - } - }); + _updateStatusCallback(status) { + const { fetchSubscriptions, getSync, setClientSetting } = this.props; + const startupStatus = status.startup_status; + // At the minimum, wallet should be started and blocks_behind equal to 0 before calling resolve + const hasStarted = startupStatus.stream_manager && startupStatus.wallet && status.wallet.blocks_behind <= 0; + if (hasStarted) { + // Wait until we are able to resolve a name before declaring + // that we are done. + // TODO: This is a hack, and the logic should live in the daemon + // to give us a better sense of when we are actually started + this.setState({ + daemonReady: true, + isLagging: false, + isRunning: true, }); - }); - }; - handleSdkStatusResponse = evt => { - const { status } = evt; + // For now, automatically unlock the wallet if a password is set so that downloads work + NativeModules.UtilityModule.getSecureValue(Constants.KEY_FIRST_RUN_PASSWORD).then(password => { + if (password && password.trim().length > 0) { + this.setState({ + message: 'Unlocking account', + details: 'Decrypting wallet', + }); + + // unlock the wallet and then finish the splash screen + Lbry.account_unlock({ password }) + .then(() => { + this.setState({ + message: testingNetwork, + details: waitingForResolution, + }); + this.finishSplashScreen(); + }) + .catch(() => this.handleAccountUnlockFailed()); + } else { + this.setState({ + message: testingNetwork, + details: waitingForResolution, + }); + this.finishSplashScreen(); + } + }); + + return; + } + + const blockchainHeaders = status.blockchain_headers; const walletStatus = status.wallet; - const headerSyncProgress = walletStatus ? walletStatus.headers_synchronization_progress : null; - if (headerSyncProgress && headerSyncProgress < 100) { + if (blockchainHeaders) { this.setState({ - isDownloadingHeaders: true, - headersDownloadProgress: headerSyncProgress, + isDownloadingHeaders: blockchainHeaders.downloading_headers, + headersDownloadProgress: blockchainHeaders.download_progress, }); } else { // set downloading flag to false if blockchain_headers isn't in the status response @@ -286,66 +209,41 @@ class SplashScreen extends React.PureComponent { }); } - if (headerSyncProgress < 100) { - const downloadProgress = isNaN(parseInt(headerSyncProgress, 10)) ? '0' : headerSyncProgress || '0'; + if (blockchainHeaders && blockchainHeaders.downloading_headers) { + const downloadProgress = blockchainHeaders.download_progress ? blockchainHeaders.download_progress : 0; this.setState({ - message: __('Blockchain Sync'), - details: __('Catching up with the blockchain (%progress%%)', { progress: downloadProgress }), + message: 'Blockchain Sync', + details: `Catching up with the blockchain (${downloadProgress}%)`, }); } else if (walletStatus && walletStatus.blocks_behind > 0) { const behind = walletStatus.blocks_behind; - const behindText = - behind === 1 ? __('%num% block behind', { num: behind }) : __('%num% blocks behind', { num: behind }); + const behindText = behind + ' block' + (behind === 1 ? '' : 's') + ' behind'; this.setState({ - message: __('Blockchain Sync'), + message: 'Blockchain Sync', details: behindText, }); } else { this.setState({ - message: __('Network Loading'), - details: __('Initializing LBRY service'), + message: 'Network Loading', + details: 'Initializing LBRY service', }); } - }; - componentWillMount() { - DeviceEventEmitter.addListener('onNotificationTargetLaunch', this.onNotificationTargetLaunch); - DeviceEventEmitter.addListener('onSdkReady', this.handleSdkReady); - DeviceEventEmitter.addListener('onSdkStatusResponse', this.handleSdkStatusResponse); - } - - componentWillUnmount() { - DeviceEventEmitter.removeListener('onNotificationTargetLaunch', this.onNotificationTargetLaunch); - DeviceEventEmitter.removeListener('onSdkReady', this.handleSdkReady); - DeviceEventEmitter.removeListener('onSdkStatusResponse', this.handleSdkStatusResponse); + setTimeout(() => { + this.updateStatus(); + }, 1000); } componentDidMount() { - NativeModules.Firebase.track('app_launch', null); - NativeModules.Firebase.setCurrentScreen('Splash'); - NativeModules.UtilityModule.checkSdkReady(); - - const { navigation } = this.props; - const { resetUrl } = navigation.state.params; - const isResetUrlSet = !!resetUrl; + if (NativeModules.Firebase) { + NativeModules.Firebase.track('app_launch', null); + } this.props.fetchRewardedContent(); Linking.getInitialURL().then(url => { - let liteMode; if (url) { - liteMode = !isResetUrlSet && url.indexOf('liteMode=1') > -1; - this.setState({ launchUrl: resetUrl || url, liteMode }); + this.setState({ launchUrl: url }); } - - NativeModules.UtilityModule.getNotificationLaunchTarget().then(target => { - if (target) { - liteMode = !isResetUrlSet && target.indexOf('liteMode=1') > -1; - this.setState({ launchUrl: resetUrl || target, liteMode }); - } - - // Only connect after checking initial launch url / notification launch target - this.initLiteMode(); - }); }); // Start measuring the first launch time from the splash screen @@ -357,36 +255,29 @@ class SplashScreen extends React.PureComponent { AsyncStorage.setItem('firstLaunchTime', String(moment().unix())); } }); - } - lbryConnect = () => { - if (NativeModules.UtilityModule.dhtEnabled) { - Lbry.connect() - .then(() => { - this.updateStatus(); - }) - .catch(e => { - this.setState({ - isLagging: true, - message: __('Connection Failure'), - details: __( - 'We could not establish a connection to the SDK. Your data connection may be preventing LBRY from connecting. Contact hello@lbry.com if you think this is a software bug.', - ), - }); + Lbry.connect() + .then(() => { + this.updateStatus(); + }) + .catch(e => { + this.setState({ + isLagging: true, + message: 'Connection Failure', + details: + 'We could not establish a connection to the daemon. Your data connection may be preventing LBRY from connecting. Contact hello@lbry.com if you think this is a software bug.', }); - } else { - this.updateStatus(); // skip lbry.connect for now (unless dht flag is enabled) - } - }; + }); + } handleContinueAnywayPressed = () => { this.setState( { accountUnlockFailed: false, - message: __('Authenticating'), - details: __('Waiting for authentication'), + message: testingNetwork, + details: waitingForResolution, }, - () => this.finishSplashScreen(), + () => this.finishSplashScreen() ); }; @@ -396,22 +287,19 @@ class SplashScreen extends React.PureComponent { if (accountUnlockFailed) { return ( <View style={splashStyle.container}> - <Text style={splashStyle.errorTitle}>{__('Oops! Something went wrong.')}</Text> + <Text style={splashStyle.errorTitle}>Oops! Something went wrong.</Text> <Text style={splashStyle.paragraph}> - {__( - 'Your wallet failed to unlock, which means you may not be able to play any videos or access your funds.', - )} + Your wallet failed to unlock, which means you may not be able to play any videos or access your funds. </Text> <Text style={splashStyle.paragraph}> - {__( - 'You can try to fix this by tapping Stop on the LBRY service notification and starting the app again. If the problem continues, you may have to reinstall the app and restore your account.', - )} + You can try to fix this by tapping Stop on the LBRY service notification and starting the app again. If the + problem continues, you may have to reinstall the app and restore your account. </Text> <Button style={splashStyle.continueButton} theme={'light'} - text={__('Continue anyway')} + text={'Continue anyway'} onPress={this.handleContinueAnywayPressed} /> </View> diff --git a/src/page/subscriptions/index.js b/src/page/subscriptions/index.js index 8ed92bb..e59a3d0 100644 --- a/src/page/subscriptions/index.js +++ b/src/page/subscriptions/index.js @@ -1,24 +1,21 @@ import { connect } from 'react-redux'; import { - doChannelUnsubscribe, doFetchMySubscriptions, doSetViewMode, doFetchRecommendedSubscriptions, selectSubscriptionClaims, selectSubscriptions, selectIsFetchingSubscriptions, + selectIsFetchingSuggested, selectSuggestedChannels, selectUnreadSubscriptions, selectViewMode, selectFirstRunCompleted, selectShowSuggestedSubs, - selectUnclaimedRewardValue, - selectUser, } from 'lbryinc'; -import { doToast, selectFetchingClaimSearch } from 'lbry-redux'; import { doPushDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer'; -import { doSetClientSetting, doSetTimeItem } from 'redux/actions/settings'; -import { makeSelectClientSetting, selectSdkReady, selectTimeItem } from 'redux/selectors/settings'; +import { doSetClientSetting } from 'redux/actions/settings'; +import { makeSelectClientSetting } from 'redux/selectors/settings'; import { selectCurrentRoute } from 'redux/selectors/drawer'; import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api import SubscriptionsPage from './view'; @@ -26,7 +23,7 @@ import SubscriptionsPage from './view'; const select = state => ({ currentRoute: selectCurrentRoute(state), loading: selectIsFetchingSubscriptions(state), - loadingSuggested: selectFetchingClaimSearch(state), + loadingSuggested: selectIsFetchingSuggested(state), subscribedChannels: selectSubscriptions(state), suggestedChannels: selectSuggestedChannels(state), subscriptionsViewMode: makeSelectClientSetting(Constants.SETTING_SUBSCRIPTIONS_VIEW_MODE)(state), @@ -34,24 +31,19 @@ const select = state => ({ unreadSubscriptions: selectUnreadSubscriptions(state), viewMode: selectViewMode(state), firstRunCompleted: selectFirstRunCompleted(state), - rewardsNotInterested: makeSelectClientSetting(Constants.SETTING_REWARDS_NOT_INTERESTED)(state), showSuggestedSubs: selectShowSuggestedSubs(state), - timeItem: selectTimeItem(state), - sdkReady: selectSdkReady(state), - unclaimedRewardAmount: selectUnclaimedRewardValue(state), - user: selectUser(state), }); const perform = dispatch => ({ - channelUnsubscribe: subscription => dispatch(doChannelUnsubscribe(subscription)), doFetchMySubscriptions: () => dispatch(doFetchMySubscriptions()), doFetchRecommendedSubscriptions: () => dispatch(doFetchRecommendedSubscriptions()), doSetViewMode: viewMode => dispatch(doSetViewMode(viewMode)), - notify: data => dispatch(doToast(data)), pushDrawerStack: () => dispatch(doPushDrawerStack(Constants.DRAWER_ROUTE_SUBSCRIPTIONS)), setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)), setPlayerVisible: () => dispatch(doSetPlayerVisible(false)), - setTimeItem: item => dispatch(doSetTimeItem(item)), }); -export default connect(select, perform)(SubscriptionsPage); +export default connect( + select, + perform +)(SubscriptionsPage); diff --git a/src/page/subscriptions/view.js b/src/page/subscriptions/view.js index 4a48f01..243c027 100644 --- a/src/page/subscriptions/view.js +++ b/src/page/subscriptions/view.js @@ -11,7 +11,7 @@ import { View, } from 'react-native'; import { buildURI, parseURI } from 'lbry-redux'; -import { formatUsd, getOrderBy } from 'utils/helper'; +import { __, uriFromFileInfo } from 'utils/helper'; import AsyncStorage from '@react-native-community/async-storage'; import moment from 'moment'; import Button from 'component/button'; @@ -25,34 +25,24 @@ import FileItem from 'component/fileItem'; import Icon from 'react-native-vector-icons/FontAwesome5'; import Link from 'component/link'; import ModalPicker from 'component/modalPicker'; -import ModalSuggestedSubscriptions from 'component/modalSuggestedSubscriptions'; import SubscribedChannelList from 'component/subscribedChannelList'; import SuggestedSubscriptions from 'component/suggestedSubscriptions'; -import SuggestedSubscriptionsGrid from 'component/suggestedSubscriptionsGrid'; import UriBar from 'component/uriBar'; -import SdkLoadingStatus from 'component/sdkLoadingStatus'; -import Snackbar from 'react-native-snackbar'; -import { Lbryio } from 'lbryinc'; class SubscriptionsPage extends React.PureComponent { state = { - currentSortByItem: Constants.CLAIM_SEARCH_SORT_BY_ITEMS[1], // should always default to sorting subscriptions by new - filteredChannels: [], - orderBy: ['release_time'], - showRewardsNag: true, showingSuggestedSubs: false, showSortPicker: false, - showTimePicker: false, - showModalSuggestedSubs: false, - usdExchangeRate: 0, - userEmailVerified: false, + orderBy: ['release_time'], + filteredChannels: [], + currentSortByItem: Constants.CLAIM_SEARCH_SORT_BY_ITEMS[1], // should always default to sorting subscriptions by new }; didFocusListener; componentWillMount() { const { navigation } = this.props; - // this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused); + this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused); } componentWillUnmount() { @@ -62,26 +52,19 @@ class SubscriptionsPage extends React.PureComponent { } onComponentFocused = () => { - const { currentRoute, doFetchMySubscriptions, pushDrawerStack, sdkReady, setPlayerVisible, user } = this.props; + const { + doFetchMySubscriptions, + doFetchRecommendedSubscriptions, + doSetViewMode, + pushDrawerStack, + setPlayerVisible, + subscriptionsViewMode, + } = this.props; - if (currentRoute === Constants.DRAWER_ROUTE_SUBSCRIPTIONS) { - pushDrawerStack(); - } + pushDrawerStack(); setPlayerVisible(); - NativeModules.Firebase.setCurrentScreen('Subscriptions'); - - Lbryio.getExchangeRates().then(rates => { - if (!isNaN(rates.LBC_USD)) { - this.setState({ usdExchangeRate: rates.LBC_USD }, () => { - if (sdkReady && parseFloat(this.state.usdExchangeRate) > 0 && user && !user.is_reward_approved) { - this.showRewardsAvailable(); - } - }); - } - }); - - this.setState({ userEmailVerified: user && user.has_verified_email }); doFetchMySubscriptions(); + doFetchRecommendedSubscriptions(); }; componentDidMount() { @@ -89,73 +72,30 @@ class SubscriptionsPage extends React.PureComponent { } componentWillReceiveProps(nextProps) { - const { currentRoute, user, sdkReady } = nextProps; - const { currentRoute: prevRoute, doFetchMySubscriptions } = this.props; - if (Constants.DRAWER_ROUTE_SUBSCRIPTIONS === currentRoute && currentRoute !== prevRoute) { + const { currentRoute } = nextProps; + const { currentRoute: prevRoute } = this.props; + if (Constants.FULL_ROUTE_NAME_MY_SUBSCRIPTIONS === currentRoute && currentRoute !== prevRoute) { this.onComponentFocused(); } - - if (user && user.has_verified_email && !this.state.userEmailVerified) { - // user just signed in - this.setState({ showingSuggestedSubs: false, userEmailVerified: true }, () => { - doFetchMySubscriptions(); - }); - } - - if ( - sdkReady && - parseFloat(this.state.usdExchangeRate) > 0 && - this.state.showRewardsNag && - user && - !user.is_reward_approved - ) { - this.showRewardsAvailable(); - } - - this.unsubscribeShortChannelUrls(); } - showRewardsAvailable = () => { - const { navigation, unclaimedRewardAmount, rewardsNotInterested } = this.props; - if (rewardsNotInterested) { - this.setState({ showRewardsNag: false }); - return; - } - - this.setState({ showRewardsNag: false }, () => { - Snackbar.show({ - title: __('Did you know that you can earn free credits worth up to %amount%?', { - amount: formatUsd(parseFloat(this.state.usdExchangeRate) * parseFloat(unclaimedRewardAmount)), - }), - duration: Snackbar.LENGTH_LONG, - action: { - title: __('SHOW ME'), - color: Colors.LbryGreen, - onPress: () => { - navigation.navigate({ routeName: Constants.DRAWER_ROUTE_REWARDS }); - }, - }, - }); - }); - }; - handleSortByItemSelected = item => { - this.setState({ currentSortByItem: item, orderBy: getOrderBy(item), showSortPicker: false }); - }; + let orderBy = []; + switch (item.name) { + case Constants.SORT_BY_HOT: + orderBy = Constants.DEFAULT_ORDER_BY; + break; - shouldComponentUpdate(nextProps, nextState) { - const { showModalSuggestedSubs: prevShowModalSuggestedSubs } = this.state; - const { showModalSuggestedSubs } = this.state; - if (prevShowModalSuggestedSubs && showModalSuggestedSubs) { - return false; + case Constants.SORT_BY_NEW: + orderBy = ['release_time']; + break; + + case Constants.SORT_BY_TOP: + orderBy = ['effective_amount']; + break; } - return true; - } - handleTimeItemSelected = item => { - const { setTimeItem } = this.props; - setTimeItem(item); - this.setState({ showTimePicker: false }); + this.setState({ currentSortByItem: item, orderBy, showSortPicker: false }); }; handleChannelSelected = channelUri => { @@ -173,22 +113,23 @@ class SubscriptionsPage extends React.PureComponent { return [Constants.ALL_PLACEHOLDER].concat(channelUris); }; - // Added in 0.12.1. Can be dropped on or after 1 Feb 2020. - unsubscribeShortChannelUrls = () => { - // this should only have to happen once - const { subscribedChannels, channelUnsubscribe } = this.props; - const badSubs = subscribedChannels.filter(sub => { - const parts = sub.uri.split('#'); - return parts.length === 1 || parts[1].length < 5; - }); - if (badSubs.length > 0) { - badSubs.forEach(sub => channelUnsubscribe(sub)); - } - }; - render() { - const { subscribedChannels, loading, loadingSuggested, sdkReady, timeItem, navigation, notify } = this.props; - const { currentSortByItem, filteredChannels, showModalSuggestedSubs, showSortPicker, showTimePicker } = this.state; + const { + suggestedChannels, + subscribedChannels, + allSubscriptions, + viewMode, + doSetViewMode, + loading, + loadingSuggested, + firstRunCompleted, + doCompleteFirstRun, + doShowSuggestedSubs, + showSuggestedSubs, + unreadSubscriptions, + navigation, + } = this.props; + const { currentSortByItem, filteredChannels } = this.state; const numberOfSubscriptions = subscribedChannels ? subscribedChannels.length : 0; const hasSubscriptions = numberOfSubscriptions > 0; @@ -213,41 +154,17 @@ class SubscriptionsPage extends React.PureComponent { <View style={subscriptionsStyle.container}> <UriBar navigation={navigation} belowOverlay={this.state.showSortPicker} /> <View style={subscriptionsStyle.titleRow}> - <Text style={subscriptionsStyle.pageTitle}> - {hasSubscriptions && !this.state.showingSuggestedSubs - ? __('Channels you follow') - : __('Find Channels to follow')} - </Text> + <Text style={subscriptionsStyle.pageTitle}>Channels you follow</Text> + {!this.state.showingSuggestedSubs && hasSubscriptions && ( + <TouchableOpacity + style={subscriptionsStyle.tagSortBy} + onPress={() => this.setState({ showSortPicker: true })} + > + <Text style={subscriptionsStyle.tagSortText}>{currentSortByItem.label.split(' ')[0]}</Text> + <Icon style={subscriptionsStyle.tagSortIcon} name={'sort-down'} size={14} /> + </TouchableOpacity> + )} </View> - {!this.state.showingSuggestedSubs && hasSubscriptions && ( - <View style={subscriptionsStyle.pickerRow}> - <View style={subscriptionsStyle.leftPickerRow}> - <TouchableOpacity - style={subscriptionsStyle.tagSortBy} - onPress={() => this.setState({ showSortPicker: true })} - > - <Text style={subscriptionsStyle.tagSortText}>{__(currentSortByItem.label.split(' ')[0])}</Text> - <Icon style={subscriptionsStyle.tagSortIcon} name={'sort-down'} size={14} /> - </TouchableOpacity> - - {Constants.SORT_BY_TOP === currentSortByItem.name && ( - <TouchableOpacity - style={subscriptionsStyle.tagSortBy} - onPress={() => this.setState({ showTimePicker: true })} - > - <Text style={subscriptionsStyle.tagSortText}>{__(timeItem.label)}</Text> - <Icon style={subscriptionsStyle.tagSortIcon} name={'sort-down'} size={14} /> - </TouchableOpacity> - )} - </View> - - <Link - style={subscriptionsStyle.suggestedLink} - text={__('Discover')} - onPress={() => this.setState({ showModalSuggestedSubs: true })} - /> - </View> - )} {!this.state.showingSuggestedSubs && hasSubscriptions && !loading && ( <View style={subscriptionsStyle.subContainer}> <SubscribedChannelList @@ -258,7 +175,6 @@ class SubscriptionsPage extends React.PureComponent { style={subscriptionsStyle.claimList} channelIds={channelIds} orderBy={this.state.orderBy} - time={timeItem.name} navigation={navigation} orientation={Constants.ORIENTATION_VERTICAL} /> @@ -273,67 +189,44 @@ class SubscriptionsPage extends React.PureComponent { {this.state.showingSuggestedSubs && ( <View style={subscriptionsStyle.suggestedSubsContainer}> - <View style={subscriptionsStyle.infoArea}> - <Text style={subscriptionsStyle.infoText}> - {__( - 'LBRY works better if you follow at least 5 creators you like. Sign in to show creators you follow if you already have an account.', - )} - </Text> - </View> + {!hasSubscriptions && ( + <View style={subscriptionsStyle.infoArea}> + <Text style={subscriptionsStyle.infoText}>You are not subscribed to any channels at the moment.</Text> + </View> + )} - <View style={subscriptionsStyle.mainSuggested}> - <SuggestedSubscriptionsGrid navigation={navigation} /> - </View> - - <Button - style={subscriptionsStyle.suggestedDoneButton} - text={ - numberOfSubscriptions < 5 - ? __('%remaining% more...', { remaining: 5 - numberOfSubscriptions }) - : __('Done') - } - onPress={() => { - if (!hasSubscriptions) { - notify({ message: __('Tap on any channel to follow') }); - } else { - this.setState({ showingSuggestedSubs: false }); - } - }} - /> + {hasSubscriptions && ( + <View style={subscriptionsStyle.infoArea}> + <Text style={subscriptionsStyle.infoText}> + You are currently subscribed to {numberOfSubscriptions} channel{numberOfSubscriptions > 1 ? 's' : ''}. + </Text> + <Button + style={subscriptionsStyle.button} + text={'View my subscriptions'} + onPress={() => this.setState({ showingSuggestedSubs: false })} + /> + </View> + )} {loadingSuggested && ( - <ActivityIndicator size="small" color={Colors.White} style={subscriptionsStyle.suggestedLoading} /> + <View style={subscriptionsStyle.centered}> + <ActivityIndicator size="large" colors={Colors.NextLbryGreen} style={subscriptionsStyle.loading} /> + </View> )} + {!loadingSuggested && <SuggestedSubscriptions navigation={navigation} />} </View> )} - {showSortPicker && ( + {!this.state.showSortPicker && <FloatingWalletBalance navigation={navigation} />} + {this.state.showSortPicker && ( <ModalPicker title={__('Sort content by')} onOverlayPress={() => this.setState({ showSortPicker: false })} onItemSelected={this.handleSortByItemSelected} - selectedItem={currentSortByItem} + selectedItem={this.state.currentSortByItem} items={Constants.CLAIM_SEARCH_SORT_BY_ITEMS} /> )} - {showTimePicker && ( - <ModalPicker - title={__('Content from')} - onOverlayPress={() => this.setState({ showTimePicker: false })} - onItemSelected={this.handleTimeItemSelected} - selectedItem={timeItem} - items={Constants.CLAIM_SEARCH_TIME_ITEMS} - /> - )} - {showModalSuggestedSubs && ( - <ModalSuggestedSubscriptions - navigation={navigation} - onOverlayPress={() => this.setState({ showModalSuggestedSubs: false })} - onDonePress={() => this.setState({ showModalSuggestedSubs: false })} - /> - )} - - {!sdkReady && <SdkLoadingStatus />} </View> ); } diff --git a/src/page/tag/index.js b/src/page/tag/index.js index ca0b81d..5a76f94 100644 --- a/src/page/tag/index.js +++ b/src/page/tag/index.js @@ -1,25 +1,19 @@ import { connect } from 'react-redux'; -import { selectFollowedTags, doToggleTagFollow } from 'lbry-redux'; import { doPushDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer'; -import { doSetSortByItem, doSetTimeItem } from 'redux/actions/settings'; import { selectCurrentRoute } from 'redux/selectors/drawer'; -import { selectSdkReady, selectSortByItem, selectTimeItem } from 'redux/selectors/settings'; +import Constants from 'constants'; import TagPage from './view'; const select = state => ({ currentRoute: selectCurrentRoute(state), - sdkReady: selectSdkReady(state), - sortByItem: selectSortByItem(state), - timeItem: selectTimeItem(state), - followedTags: selectFollowedTags(state), }); const perform = dispatch => ({ - pushDrawerStack: (routeName, params) => dispatch(doPushDrawerStack(routeName, params)), + pushDrawerStack: () => dispatch(doPushDrawerStack(Constants.DRAWER_ROUTE_TAG)), setPlayerVisible: () => dispatch(doSetPlayerVisible(false)), - setSortByItem: item => dispatch(doSetSortByItem(item)), - setTimeItem: item => dispatch(doSetTimeItem(item)), - toggleTagFollow: tag => dispatch(doToggleTagFollow(tag)), }); -export default connect(select, perform)(TagPage); +export default connect( + select, + perform +)(TagPage); diff --git a/src/page/tag/view.js b/src/page/tag/view.js index 82093f4..dc02fac 100644 --- a/src/page/tag/view.js +++ b/src/page/tag/view.js @@ -1,7 +1,7 @@ import React from 'react'; import { ActivityIndicator, NativeModules, FlatList, Text, TouchableOpacity, View } from 'react-native'; import { DEFAULT_FOLLOWED_TAGS, normalizeURI } from 'lbry-redux'; -import { formatTagTitle, getOrderBy } from 'utils/helper'; +import { formatTagTitle } from 'utils/helper'; import AsyncStorage from '@react-native-community/async-storage'; import moment from 'moment'; import ClaimList from 'component/claimList'; @@ -12,9 +12,7 @@ import fileListStyle from 'styles/fileList'; import Colors from 'styles/colors'; import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api import FloatingWalletBalance from 'component/floatingWalletBalance'; -import Link from 'component/link'; import ModalPicker from 'component/modalPicker'; -import SdkLoadingStatus from 'component/sdkLoadingStatus'; import UriBar from 'component/uriBar'; class TagPage extends React.PureComponent { @@ -23,13 +21,16 @@ class TagPage extends React.PureComponent { showSortPicker: false, showTimePicker: false, orderBy: Constants.DEFAULT_ORDER_BY, + time: Constants.TIME_WEEK, + currentSortByItem: Constants.CLAIM_SEARCH_SORT_BY_ITEMS[0], + currentTimeItem: Constants.CLAIM_SEARCH_TIME_ITEMS[1], }; didFocusListener; componentWillMount() { const { navigation } = this.props; - // this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused); + this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused); } componentWillUnmount() { @@ -39,12 +40,10 @@ class TagPage extends React.PureComponent { } onComponentFocused = () => { - const { navigation, pushDrawerStack, setPlayerVisible, sortByItem } = this.props; - const { tag } = navigation.state.params; - this.setState({ tag, orderBy: getOrderBy(sortByItem) }); - pushDrawerStack(Constants.DRAWER_ROUTE_TAG, navigation.state.params); + const { pushDrawerStack, setPlayerVisible, navigation } = this.props; + this.setState({ tag: navigation.state.params.tag }); + pushDrawerStack(); setPlayerVisible(); - NativeModules.Firebase.setCurrentScreen('Tag'); }; componentDidMount() { @@ -60,98 +59,65 @@ class TagPage extends React.PureComponent { } handleSortByItemSelected = item => { - const { setSortByItem } = this.props; - setSortByItem(item); - this.setState({ orderBy: getOrderBy(item), showSortPicker: false }); + let orderBy = []; + switch (item.name) { + case Constants.SORT_BY_HOT: + orderBy = Constants.DEFAULT_ORDER_BY; + break; + + case Constants.SORT_BY_NEW: + orderBy = ['release_time']; + break; + + case Constants.SORT_BY_TOP: + orderBy = [Constants.ORDER_BY_EFFECTIVE_AMOUNT]; + break; + } + + this.setState({ currentSortByItem: item, orderBy, showSortPicker: false }); }; handleTimeItemSelected = item => { - const { setTimeItem } = this.props; - setTimeItem(item); - this.setState({ showTimePicker: false }); - }; - - isFollowingTag = tag => { - const { followedTags } = this.props; - return followedTags.map(tag => tag.name).includes(tag); - }; - - handleFollowTagToggle = () => { - const { toggleTagFollow } = this.props; - const { tag } = this.state; - const isFollowing = this.isFollowingTag(tag); - if (isFollowing) { - // unfollow - NativeModules.Firebase.track('tag_unfollow', { tag }); - } else { - // follow - NativeModules.Firebase.track('tag_follow', { tag }); - } - - toggleTagFollow(tag); - if (window.persistor) { - window.persistor.flush(); - } - }; - - listHeader = () => { - const { sortByItem, timeItem } = this.props; - const { tag } = this.state; - - return ( - <View style={discoverStyle.listHeader}> - <View style={discoverStyle.titleRow}> - <Text style={discoverStyle.pageTitle}>{formatTagTitle(tag)}</Text> - </View> - <View style={discoverStyle.pickerRow}> - <View style={discoverStyle.leftPickerRow}> - <TouchableOpacity style={discoverStyle.tagSortBy} onPress={() => this.setState({ showSortPicker: true })}> - <Text style={discoverStyle.tagSortText}>{__(sortByItem.label.split(' ')[0])}</Text> - <Icon style={discoverStyle.tagSortIcon} name={'sort-down'} size={14} /> - </TouchableOpacity> - {Constants.SORT_BY_TOP === sortByItem.name && ( - <TouchableOpacity style={discoverStyle.tagTime} onPress={() => this.setState({ showTimePicker: true })}> - <Text style={discoverStyle.tagSortText}>{__(timeItem.label)}</Text> - <Icon style={discoverStyle.tagSortIcon} name={'sort-down'} size={14} /> - </TouchableOpacity> - )} - </View> - - <Link - style={discoverStyle.customizeLink} - text={this.isFollowingTag(tag) ? __('Unfollow') : __('Follow')} - onPress={this.handleFollowTagToggle} - /> - </View> - </View> - ); + this.setState({ currentTimeItem: item, time: item.name, showTimePicker: false }); }; render() { - const { navigation, sdkReady, sortByItem, timeItem } = this.props; - const { tag, showSortPicker, showTimePicker } = this.state; + const { navigation } = this.props; + const { tag, currentSortByItem, currentTimeItem, showSortPicker, showTimePicker } = this.state; return ( <View style={discoverStyle.container}> <UriBar navigation={navigation} belowOverlay={showSortPicker || showTimePicker} /> - {this.state.tag && ( - <ClaimList - ListHeaderComponent={this.listHeader} - style={discoverStyle.tagPageClaimList} - orderBy={this.state.orderBy} - time={timeItem.name} - tags={[tag]} - navigation={navigation} - orientation={Constants.ORIENTATION_VERTICAL} - /> - )} - {sdkReady && !showSortPicker && !showTimePicker && <FloatingWalletBalance navigation={navigation} />} + <ClaimList + ListHeaderComponent={ + <View style={discoverStyle.tagTitleRow}> + <Text style={discoverStyle.tagPageTitle}>{formatTagTitle(tag)}</Text> + {Constants.SORT_BY_TOP === currentSortByItem.name && ( + <TouchableOpacity style={discoverStyle.tagTime} onPress={() => this.setState({ showTimePicker: true })}> + <Text style={discoverStyle.tagSortText}>{currentTimeItem.label}</Text> + <Icon style={discoverStyle.tagSortIcon} name={'sort-down'} size={14} /> + </TouchableOpacity> + )} + <TouchableOpacity style={discoverStyle.tagSortBy} onPress={() => this.setState({ showSortPicker: true })}> + <Text style={discoverStyle.tagSortText}>{currentSortByItem.label.split(' ')[0]}</Text> + <Icon style={discoverStyle.tagSortIcon} name={'sort-down'} size={14} /> + </TouchableOpacity> + </View> + } + style={discoverStyle.tagPageClaimList} + orderBy={this.state.orderBy} + time={this.state.time} + tags={[tag]} + navigation={navigation} + orientation={Constants.ORIENTATION_VERTICAL} + /> + {!showSortPicker && !showTimePicker && <FloatingWalletBalance navigation={navigation} />} {showSortPicker && ( <ModalPicker title={__('Sort content by')} onOverlayPress={() => this.setState({ showSortPicker: false })} onItemSelected={this.handleSortByItemSelected} - selectedItem={sortByItem} + selectedItem={this.state.currentSortByItem} items={Constants.CLAIM_SEARCH_SORT_BY_ITEMS} /> )} @@ -160,11 +126,10 @@ class TagPage extends React.PureComponent { title={__('Content from')} onOverlayPress={() => this.setState({ showTimePicker: false })} onItemSelected={this.handleTimeItemSelected} - selectedItem={timeItem} + selectedItem={this.state.currentTimeItem} items={Constants.CLAIM_SEARCH_TIME_ITEMS} /> )} - {!sdkReady && <SdkLoadingStatus />} </View> ); } diff --git a/src/page/transactionHistory/view.js b/src/page/transactionHistory/view.js index 6ddd7a2..5aa80a2 100644 --- a/src/page/transactionHistory/view.js +++ b/src/page/transactionHistory/view.js @@ -1,8 +1,6 @@ import React from 'react'; -import { ActivityIndicator, NativeModules, View, ScrollView, Text } from 'react-native'; -import Colors from 'styles/colors'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api -import EmptyStateView from 'component/emptyStateView'; +import { View, ScrollView, Text } from 'react-native'; +import Constants from 'constants'; import TransactionList from 'component/transactionList'; import UriBar from 'component/uriBar'; import walletStyle from 'styles/wallet'; @@ -12,7 +10,7 @@ class TransactionHistoryPage extends React.PureComponent { componentWillMount() { const { navigation } = this.props; - // this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused); + this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused); } componentWillUnmount() { @@ -25,9 +23,7 @@ class TransactionHistoryPage extends React.PureComponent { const { fetchTransactions, pushDrawerStack, setPlayerVisible } = this.props; pushDrawerStack(); setPlayerVisible(); - NativeModules.Firebase.setCurrentScreen('Transaction History').then(result => { - fetchTransactions(); - }); + fetchTransactions(); }; componentDidMount() { @@ -46,19 +42,16 @@ class TransactionHistoryPage extends React.PureComponent { const { fetchingTransactions, transactions, navigation } = this.props; return ( - <View style={walletStyle.container}> + <View> <UriBar navigation={navigation} /> - {fetchingTransactions && ( - <View style={walletStyle.loadingContainer}> - <ActivityIndicator size={'small'} color={Colors.NextLbryGreen} /> - <Text style={walletStyle.loadingText}>{__('Loading transactions...')}</Text> - </View> - )} - {!fetchingTransactions && transactions.length === 0 && ( - <EmptyStateView message={__('No transactions to list.')} /> - )} <ScrollView style={walletStyle.transactionHistoryScroll}> <View style={walletStyle.historyList}> + {fetchingTransactions && !transactions.length && ( + <Text style={walletStyle.infoText}>Loading transactions...</Text> + )} + {!fetchingTransactions && transactions.length === 0 && ( + <Text style={walletStyle.infoText}>No transactions to list.</Text> + )} {!fetchingTransactions && transactions && transactions.length > 0 && ( <TransactionList navigation={navigation} transactions={transactions} /> )} diff --git a/src/page/trending/index.js b/src/page/trending/index.js index c2f6990..86df237 100644 --- a/src/page/trending/index.js +++ b/src/page/trending/index.js @@ -1,23 +1,18 @@ import { connect } from 'react-redux'; import { selectFollowedTags } from 'lbry-redux'; import { doPushDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer'; -import { doSetSortByItem, doSetTimeItem } from 'redux/actions/settings'; import { selectCurrentRoute } from 'redux/selectors/drawer'; -import { selectSortByItem, selectTimeItem } from 'redux/selectors/settings'; +import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api import TrendingPage from './view'; const select = state => ({ currentRoute: selectCurrentRoute(state), - sortByItem: selectSortByItem(state), - timeItem: selectTimeItem(state), followedTags: selectFollowedTags(state), }); const perform = dispatch => ({ - pushDrawerStack: (routeName, params) => dispatch(doPushDrawerStack(routeName, params)), + pushDrawerStack: () => dispatch(doPushDrawerStack(Constants.DRAWER_ROUTE_TRENDING)), setPlayerVisible: () => dispatch(doSetPlayerVisible(false)), - setSortByItem: item => dispatch(doSetSortByItem(item)), - setTimeItem: item => dispatch(doSetTimeItem(item)), }); export default connect( diff --git a/src/page/trending/view.js b/src/page/trending/view.js index 07e1b4d..7ab602b 100644 --- a/src/page/trending/view.js +++ b/src/page/trending/view.js @@ -1,7 +1,6 @@ import React from 'react'; import { ActivityIndicator, NativeModules, FlatList, Text, TouchableOpacity, View } from 'react-native'; -import { normalizeURI } from 'lbry-redux'; -import { getOrderBy } from 'utils/helper'; +import { DEFAULT_FOLLOWED_TAGS, normalizeURI } from 'lbry-redux'; import AsyncStorage from '@react-native-community/async-storage'; import moment from 'moment'; import ClaimList from 'component/claimList'; @@ -24,10 +23,7 @@ const TRENDING_FOR_ITEMS = [ class TrendingPage extends React.PureComponent { state = { showModalTagSelector: false, - showSortByPicker: false, - showTimePicker: false, showTrendingForPicker: false, - orderBy: Constants.DEFAULT_ORDER_BY, currentTrendingForItem: TRENDING_FOR_ITEMS[0], }; @@ -35,7 +31,7 @@ class TrendingPage extends React.PureComponent { componentWillMount() { const { navigation } = this.props; - // this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused); + this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused); } componentWillUnmount() { @@ -45,15 +41,9 @@ class TrendingPage extends React.PureComponent { } onComponentFocused = () => { - const { pushDrawerStack, setPlayerVisible, navigation, sortByItem } = this.props; - const { filterForTags } = navigation.state.params ? navigation.state.params : { filterForTags: false }; - this.setState({ - currentTrendingForItem: TRENDING_FOR_ITEMS[filterForTags ? 1 : 0], - orderBy: getOrderBy(sortByItem), - }); - pushDrawerStack(Constants.DRAWER_ROUTE_TRENDING, navigation.state.params); + const { pushDrawerStack, setPlayerVisible } = this.props; + pushDrawerStack(); setPlayerVisible(); - NativeModules.Firebase.setCurrentScreen('All content'); }; componentDidMount() { @@ -63,7 +53,7 @@ class TrendingPage extends React.PureComponent { componentWillReceiveProps(nextProps) { const { currentRoute } = nextProps; const { currentRoute: prevRoute } = this.props; - if (Constants.DRAWER_ROUTE_TRENDING === currentRoute && currentRoute !== prevRoute) { + if (Constants.FULL_ROUTE_NAME_TRENDING === currentRoute && currentRoute !== prevRoute) { this.onComponentFocused(); } } @@ -72,96 +62,44 @@ class TrendingPage extends React.PureComponent { this.setState({ currentTrendingForItem: item, showTrendingForPicker: false }); }; - handleSortByItemSelected = item => { - const { setSortByItem } = this.props; - setSortByItem(item); - this.setState({ orderBy: getOrderBy(item), showSortPicker: false }); - }; - - handleTimeItemSelected = item => { - const { setTimeItem } = this.props; - setTimeItem(item); - this.setState({ showTimePicker: false }); - }; - - listHeader = () => { - const { sortByItem, timeItem } = this.props; - const { currentTrendingForItem } = this.state; - const sortByTop = Constants.SORT_BY_TOP === sortByItem.name; - - return ( - <View style={discoverStyle.listHeader}> - <View style={discoverStyle.titleRow}> - <Text style={discoverStyle.pageTitle}>{__('All Content')}</Text> - </View> - <View style={discoverStyle.pickerRow}> - <View style={discoverStyle.leftPickerRow}> - <TouchableOpacity - style={discoverStyle.allTagSortBy} - onPress={() => this.setState({ showSortPicker: true })} - > - <Text style={discoverStyle.tagSortText}>{__(sortByItem.label.split(' ')[0])}</Text> - <Icon style={discoverStyle.tagSortIcon} name={'sort-down'} size={14} /> - </TouchableOpacity> - - <Text style={discoverStyle.pickerLabel}>{__('for')}</Text> - <TouchableOpacity - style={discoverStyle.allTagSortBy} - onPress={() => this.setState({ showTrendingForPicker: true })} - > - <Text style={discoverStyle.tagSortText}>{__(currentTrendingForItem.label.split(' ')[0])}</Text> - <Icon style={discoverStyle.tagSortIcon} name={'sort-down'} size={14} /> - </TouchableOpacity> - - {sortByTop && <Text style={discoverStyle.pickerLabel}>{__('from')}</Text>} - - {sortByTop && ( - <TouchableOpacity style={discoverStyle.tagTime} onPress={() => this.setState({ showTimePicker: true })}> - <Text style={discoverStyle.tagSortText}>{__(timeItem.label)}</Text> - <Icon style={discoverStyle.tagSortIcon} name={'sort-down'} size={14} /> - </TouchableOpacity> - )} - </View> - - {TRENDING_FOR_ITEMS[1].name === currentTrendingForItem.name && ( - <Link - style={discoverStyle.customizeLink} - text={__('Customize')} - onPress={() => this.setState({ showModalTagSelector: true })} - /> - )} - </View> - </View> - ); - }; - render() { - const { followedTags, navigation, sortByItem, timeItem } = this.props; - const { - currentTrendingForItem, - orderBy, - showModalTagSelector, - showSortPicker, - showTimePicker, - showTrendingForPicker, - } = this.state; - const filteredForTags = TRENDING_FOR_ITEMS[1].name === currentTrendingForItem.name; + const { followedTags, navigation } = this.props; + const { currentTrendingForItem, showModalTagSelector, showTrendingForPicker } = this.state; return ( <View style={discoverStyle.container}> <UriBar navigation={navigation} /> <ClaimList - ListHeaderComponent={this.listHeader} + ListHeaderComponent={ + <View style={discoverStyle.titleRow}> + <Text style={discoverStyle.pageTitle}>Trending</Text> + <View style={discoverStyle.rightTitleRow}> + {TRENDING_FOR_ITEMS[1].name === currentTrendingForItem.name && ( + <Link + style={discoverStyle.customizeLink} + text={'Customize'} + onPress={() => this.setState({ showModalTagSelector: true })} + /> + )} + <TouchableOpacity + style={discoverStyle.tagSortBy} + onPress={() => this.setState({ showTrendingForPicker: true })} + > + <Text style={discoverStyle.tagSortText}>{currentTrendingForItem.label.split(' ')[0]}</Text> + <Icon style={discoverStyle.tagSortIcon} name={'sort-down'} size={14} /> + </TouchableOpacity> + </View> + </View> + } style={discoverStyle.verticalClaimList} - orderBy={orderBy} - tags={filteredForTags ? followedTags.map(tag => tag.name) : null} - time={timeItem.name} + orderBy={Constants.DEFAULT_ORDER_BY} + trendingForAll={TRENDING_FOR_ITEMS[0].name === currentTrendingForItem.name} + tags={followedTags.map(tag => tag.name)} + time={null} navigation={navigation} orientation={Constants.ORIENTATION_VERTICAL} /> - {!showModalTagSelector && !showTrendingForPicker && !showSortPicker && !showTimePicker && ( - <FloatingWalletBalance navigation={navigation} /> - )} + {!showModalTagSelector && <FloatingWalletBalance navigation={navigation} />} {showModalTagSelector && ( <ModalTagSelector onOverlayPress={() => this.setState({ showModalTagSelector: false })} @@ -170,31 +108,13 @@ class TrendingPage extends React.PureComponent { )} {showTrendingForPicker && ( <ModalPicker - title={__('Filter for')} + title={'Trending for'} onOverlayPress={() => this.setState({ showTrendingForPicker: false })} onItemSelected={this.handleTrendingForItemSelected} selectedItem={currentTrendingForItem} items={TRENDING_FOR_ITEMS} /> )} - {showSortPicker && ( - <ModalPicker - title={__('Sort content by')} - onOverlayPress={() => this.setState({ showSortPicker: false })} - onItemSelected={this.handleSortByItemSelected} - selectedItem={sortByItem} - items={Constants.CLAIM_SEARCH_SORT_BY_ITEMS} - /> - )} - {showTimePicker && ( - <ModalPicker - title={__('Content from')} - onOverlayPress={() => this.setState({ showTimePicker: false })} - onItemSelected={this.handleTimeItemSelected} - selectedItem={timeItem} - items={Constants.CLAIM_SEARCH_TIME_ITEMS} - /> - )} </View> ); } diff --git a/src/page/verification/index.js b/src/page/verification/index.js index 0202d6d..c1d71bd 100644 --- a/src/page/verification/index.js +++ b/src/page/verification/index.js @@ -1,8 +1,9 @@ import { connect } from 'react-redux'; -import { doToast, doPopulateSharedUserState } from 'lbry-redux'; +import { doToast } from 'lbry-redux'; import { doCheckSync, doGetSync, + doSetDefaultAccount, doSyncApply, doUserEmailNew, doUserEmailToVerify, @@ -14,7 +15,6 @@ import { selectPhoneToVerify, selectPhoneVerifyIsPending, selectPhoneVerifyErrorMessage, - selectEmailAlreadyExists, selectEmailNewErrorMessage, selectEmailNewIsPending, selectEmailToVerify, @@ -29,11 +29,10 @@ import { } from 'lbryinc'; import { doSetClientSetting } from 'redux/actions/settings'; import { makeSelectClientSetting } from 'redux/selectors/settings'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api +import Constants from 'constants'; import Verification from './view'; const select = state => ({ - emailAlreadyExists: selectEmailAlreadyExists(state), emailToVerify: selectEmailToVerify(state), emailNewErrorMessage: selectEmailNewErrorMessage(state), emailNewPending: selectEmailNewIsPending(state), @@ -55,13 +54,13 @@ const select = state => ({ const perform = dispatch => ({ addUserEmail: email => dispatch(doUserEmailNew(email)), - addUserPhone: (phone, countryCode) => dispatch(doUserPhoneNew(phone, countryCode)), - getSync: (password, callback) => dispatch(doGetSync(password, callback)), + addUserPhone: (phone, country_code) => dispatch(doUserPhoneNew(phone, country_code)), + getSync: password => dispatch(doGetSync(password)), checkSync: () => dispatch(doCheckSync()), verifyPhone: verificationCode => dispatch(doUserPhoneVerify(verificationCode)), notify: data => dispatch(doToast(data)), - populateSharedUserState: settings => dispatch(doPopulateSharedUserState(settings)), setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)), + setDefaultAccount: () => dispatch(doSetDefaultAccount()), setEmailToVerify: email => dispatch(doUserEmailToVerify(email)), syncApply: (hash, data, password) => dispatch(doSyncApply(hash, data, password)), resendVerificationEmail: email => dispatch(doUserResendVerificationEmail(email)), diff --git a/src/page/verification/internal/email-verify-page.js b/src/page/verification/internal/email-verify-page.js index 6e3635c..4ff1a37 100644 --- a/src/page/verification/internal/email-verify-page.js +++ b/src/page/verification/internal/email-verify-page.js @@ -1,11 +1,11 @@ import React from 'react'; import { Lbry } from 'lbry-redux'; -import { ActivityIndicator, NativeModules, View, Text, TextInput } from 'react-native'; +import { ActivityIndicator, View, Text, TextInput } from 'react-native'; import AsyncStorage from '@react-native-community/async-storage'; import Button from 'component/button'; import Link from 'component/link'; import Colors from 'styles/colors'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api +import Constants from 'constants'; import firstRunStyle from 'styles/firstRun'; import rewardStyle from 'styles/reward'; @@ -44,12 +44,11 @@ class EmailVerifyPage extends React.PureComponent { notify({ message: String(emailNewErrorMessage), isError: true }); this.setState({ verifyStarted: false }); } else { - NativeModules.Firebase.track('email_added', { email: this.state.email }); this.setState({ phase: Constants.PHASE_VERIFICATION }); if (setEmailVerificationPhase) { setEmailVerificationPhase(true); } - // notify({ message: __('Please follow the instructions in the email sent to your address to continue.') }); + //notify({ message: 'Please follow the instructions in the email sent to your address to continue.' }); AsyncStorage.setItem(Constants.KEY_EMAIL_VERIFY_PENDING, 'true'); } } @@ -65,7 +64,7 @@ class EmailVerifyPage extends React.PureComponent { const { email } = this.state; if (!email || email.trim().length === 0 || email.indexOf('@') === -1) { return notify({ - message: __('Please provide a valid email address to continue.'), + message: 'Please provide a valid email address to continue.', }); } @@ -89,7 +88,7 @@ class EmailVerifyPage extends React.PureComponent { // resend verification email if there was one previously set (and it wasn't changed) resendVerificationEmail(this.state.email); AsyncStorage.setItem(Constants.KEY_EMAIL_VERIFY_PENDING, 'true'); - notify({ message: __('Please follow the instructions in the email sent to your address to continue.') }); + notify({ message: 'Please follow the instructions in the email sent to your address to continue.' }); }; onEditPressed = () => { @@ -105,20 +104,16 @@ class EmailVerifyPage extends React.PureComponent { }; render() { - const { emailAlreadyExists, emailNewPending } = this.props; + const { emailNewPending } = this.props; return ( <View style={firstRunStyle.container}> <Text style={rewardStyle.verificationTitle}> - {Constants.PHASE_COLLECTION === this.state.phase - ? __('Email') - : emailAlreadyExists - ? __('Sign In') - : __('Verify Email')} + {Constants.PHASE_COLLECTION === this.state.phase ? 'Email' : 'Verify Email'} </Text> {Constants.PHASE_COLLECTION === this.state.phase && ( <View> - <Text style={firstRunStyle.paragraph}>{__('Please provide an email address.')}</Text> + <Text style={firstRunStyle.paragraph}>Please provide an email address.</Text> <TextInput style={firstRunStyle.emailInput} placeholder={this.state.placeholder} @@ -142,7 +137,7 @@ class EmailVerifyPage extends React.PureComponent { <Button style={rewardStyle.verificationButton} theme={'light'} - text={__('Continue')} + text={'Send verification email'} onPress={this.onSendVerificationPressed} /> )} @@ -158,22 +153,18 @@ class EmailVerifyPage extends React.PureComponent { {Constants.PHASE_VERIFICATION === this.state.phase && ( <View> <Text style={firstRunStyle.paragraph}> - {__('An email has been sent to')} - {'\n\n'} - {this.state.email} - {'\n\n'} - {emailAlreadyExists && __('Please click the link in the message to complete signing in.')} - {!emailAlreadyExists && __('Please click the link in the message to verify your email address')} + An email has been sent to <Text style={firstRunStyle.nowrap}>{this.state.email}</Text>. Please follow the + instructions in the message to verify your email address. </Text> <View style={rewardStyle.buttonContainer}> <Button style={rewardStyle.verificationButton} theme={'light'} - text={__('Resend')} + text={'Resend'} onPress={this.onResendPressed} /> - <Link style={rewardStyle.verificationLink} text={__('Edit')} onPress={this.onEditPressed} /> + <Link style={rewardStyle.verificationLink} text={'Edit'} onPress={this.onEditPressed} /> </View> </View> )} diff --git a/src/page/verification/internal/manual-verify-page.js b/src/page/verification/internal/manual-verify-page.js index 32f1e44..b95e1d3 100644 --- a/src/page/verification/internal/manual-verify-page.js +++ b/src/page/verification/internal/manual-verify-page.js @@ -5,7 +5,7 @@ import AsyncStorage from '@react-native-community/async-storage'; import Button from 'component/button'; import Link from 'component/link'; import Colors from 'styles/colors'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api +import Constants from 'constants'; import firstRunStyle from 'styles/firstRun'; import rewardStyle from 'styles/reward'; @@ -20,22 +20,21 @@ class ManualVerifyPage extends React.PureComponent { render() { return ( <View style={firstRunStyle.container}> - <Text style={rewardStyle.verificationTitle}>{__('Manual Reward Verification')}</Text> + <Text style={rewardStyle.verificationTitle}>Manual Reward Verification</Text> <Text style={firstRunStyle.spacedParagraph}> - {__( - 'This account must undergo review before you can participate in the rewards program. This can take anywhere from several minutes to several days.' - )} + This account must undergo review before you can participate in the rewards program. This can take anywhere + from several minutes to several days. </Text> <Text style={firstRunStyle.spacedParagraph}> - {__('If you continue to see this message, please request to be verified on the')}{' '} + If you continue to see this message, please request to be verified on the{' '} <Link style={rewardStyle.underlinedTextLink} href="https://discordapp.com/invite/Z3bERWA" - text={__('LBRY Discord server')} + text="LBRY Discord server" /> . </Text> - <Text style={firstRunStyle.spacedParagraph}>{__('Please enjoy free content in the meantime!')}</Text> + <Text style={firstRunStyle.spacedParagraph}>Please enjoy free content in the meantime!</Text> </View> ); } diff --git a/src/page/verification/internal/phone-verify-page.js b/src/page/verification/internal/phone-verify-page.js index f980752..5170c9e 100644 --- a/src/page/verification/internal/phone-verify-page.js +++ b/src/page/verification/internal/phone-verify-page.js @@ -13,7 +13,7 @@ import { import AsyncStorage from '@react-native-community/async-storage'; import Button from 'component/button'; import Colors from 'styles/colors'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api +import Constants from 'constants'; import CountryPicker from 'react-native-country-picker-modal'; import Icon from 'react-native-vector-icons/FontAwesome5'; import Link from 'component/link'; @@ -34,7 +34,6 @@ class PhoneVerifyPage extends React.PureComponent { codeVerifyStarted: false, codeVerifySuccessful: false, countryCode: null, - countryPickerVisible: false, newPhoneAdded: false, number: null, phoneVerifyFailed: false, @@ -76,7 +75,7 @@ class PhoneVerifyPage extends React.PureComponent { notify({ message: String(phoneVerifyErrorMessage) }); this.setState({ codeVerifyStarted: false, phoneVerifyFailed: true }); } else { - notify({ message: __('Your phone number was successfully verified.') }); + notify({ message: 'Your phone number was successfully verified.' }); this.setState({ codeVerifySuccessful: true, phoneVerifyFailed: false }); if (onPhoneVerifySuccessful) { onPhoneVerifySuccessful(); @@ -104,7 +103,7 @@ class PhoneVerifyPage extends React.PureComponent { if (!this.phoneInput.isValidNumber()) { return notify({ - message: __('Please provide a valid telephone number.'), + message: 'Please provide a valid telephone number.', }); } @@ -126,15 +125,15 @@ class PhoneVerifyPage extends React.PureComponent { }; onPressFlag = () => { - this.setState({ countryPickerVisible: true }); + if (this.picker) { + this.picker.openModal(); + } }; - selectCountry = country => { + selectCountry(country) { this.phoneInput.selectCountry(country.cca2.toLowerCase()); - this.setState({ cca2: country.cca2, countryPickerVisible: false }, () => { - this.phoneInput.focus(); - }); - }; + this.setState({ cca2: country.cca2 }); + } handleChangeText = text => { this.setState({ verificationCode: text }); @@ -146,14 +145,14 @@ class PhoneVerifyPage extends React.PureComponent { return ( <View style={firstRunStyle.container}> <Text style={rewardStyle.verificationTitle}> - {this.state.phase === Constants.PHASE_VERIFICATION ? __('Verify Phone Number') : __('Phone Number')} + {this.state.phase === Constants.PHASE_VERIFICATION ? 'Verify ' : ''}Phone Number </Text> <View style={rewardStyle.phoneVerificationContainer}> - {this.state.phase === Constants.PHASE_COLLECTION && ( + {this.state.phase == Constants.PHASE_COLLECTION && ( <View> <Text style={[rewardStyle.bottomMarginMedium, firstRunStyle.paragraph]}> - {__('Please provide a phone number to prevent fraud.')} + Please provide a phone number to prevent fraud. </Text> <PhoneInput ref={ref => { @@ -170,7 +169,7 @@ class PhoneVerifyPage extends React.PureComponent { <Button style={[rewardStyle.verificationButton, rewardStyle.topMarginMedium]} theme={'light'} - text={__('Send verification text')} + text={'Send verification text'} onPress={this.onSendTextPressed} /> )} @@ -188,7 +187,7 @@ class PhoneVerifyPage extends React.PureComponent { {!phoneVerifyIsPending && !this.codeVerifyStarted && ( <View> <Text style={[rewardStyle.bottomMarginSmall, firstRunStyle.paragraph]}> - {__('Please enter the verification code sent to %phone%', { phone })}. + Please enter the verification code sent to {phone}. </Text> <TextInput style={rewardStyle.verificationCodeInput} @@ -203,16 +202,16 @@ class PhoneVerifyPage extends React.PureComponent { <Button style={[rewardStyle.verificationButton, rewardStyle.topMarginSmall]} theme={'light'} - text={__('Verify')} + text={'Verify'} onPress={this.onVerifyPressed} /> - <Link style={rewardStyle.verificationLink} text={__('Edit')} onPress={this.onEditPressed} /> + <Link style={rewardStyle.verificationLink} text={'Edit'} onPress={this.onEditPressed} /> </View> </View> )} {phoneVerifyIsPending && ( <View style={firstRunStyle.centered}> - <Text style={firstRunStyle.paragraph}>{__('Verifying your phone number...')}</Text> + <Text style={firstRunStyle.paragraph}>Verifying your phone number...</Text> <ActivityIndicator color={Colors.White} size="small" @@ -234,17 +233,17 @@ class PhoneVerifyPage extends React.PureComponent { </View> <CountryPicker - countryCode={this.state.cca2} - withAlphaFilter - withFilter - withFlag - withFlagButton={false} - withCallingCode - withModal - onSelect={this.selectCountry} + ref={picker => { + this.picker = picker; + }} + cca2={this.state.cca2} + filterable={true} + onChange={value => this.selectCountry(value)} + showCallingCode={true} translation="eng" - modalProps={{ visible: this.state.countryPickerVisible }} - /> + > + <View /> + </CountryPicker> </View> ); } diff --git a/src/page/verification/internal/sync-verify-page.js b/src/page/verification/internal/sync-verify-page.js index da92430..c53653b 100644 --- a/src/page/verification/internal/sync-verify-page.js +++ b/src/page/verification/internal/sync-verify-page.js @@ -5,7 +5,7 @@ import { BarPasswordStrengthDisplay } from 'react-native-password-strength-meter import Button from 'component/button'; import Link from 'component/link'; import Colors from 'styles/colors'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api +import Constants from 'constants'; import firstRunStyle from 'styles/firstRun'; import Icon from 'react-native-vector-icons/FontAwesome5'; import rewardStyle from 'styles/reward'; @@ -14,15 +14,10 @@ class SyncVerifyPage extends React.PureComponent { state = { checkSyncStarted: false, password: null, - placeholder: __('password'), + placeholder: 'password', syncApplyStarted: false, - syncApplyCompleted: false, syncChecked: false, revealPassword: false, - autoPassword: false, - autoLoginAttempted: false, - autoLoginTried: false, - autoLoginFlow: true, }; componentDidMount() { @@ -42,87 +37,39 @@ class SyncVerifyPage extends React.PureComponent { if (!hasSyncedWallet) { // fresh account with no sync const newPassword = this.state.password ? this.state.password : ''; - if (newPassword.trim().length === 0) { + Lbry.account_encrypt({ new_password: newPassword }).then(() => { getSync(newPassword); setClientSetting(Constants.SETTING_DEVICE_WALLET_SYNCED, true); navigation.goBack(); - } else { - Lbry.wallet_encrypt({ new_password: newPassword }).then(() => { - getSync(newPassword); - setClientSetting(Constants.SETTING_DEVICE_WALLET_SYNCED, true); - navigation.goBack(); - }); - } + }); } else { - syncApply(syncHash, syncData, this.state.password ? this.state.password : ''); + syncApply(syncHash, syncData, this.state.password); } }); }; componentWillReceiveProps(nextProps) { const { getSyncIsPending, syncApplyIsPending, syncApplyErrorMessage } = nextProps; - const { getSync, hasSyncedWallet, navigation, notify, setClientSetting } = this.props; + const { getSync, hasSyncedWallet, navigation, notify, setClientSetting, setDefaultAccount } = this.props; if (this.state.checkSyncStarted && !getSyncIsPending) { this.setState({ syncChecked: true }); } if (this.state.syncApplyStarted && !syncApplyIsPending) { if (syncApplyErrorMessage && syncApplyErrorMessage.trim().length > 0) { - if (this.state.autoLoginTried) { - notify({ message: __(syncApplyErrorMessage), isError: true }); - } - this.setState({ autoLoginTried: true, syncApplyStarted: false, autoLoginFlow: false }); + notify({ message: syncApplyErrorMessage, isError: true }); + this.setState({ syncApplyStarted: false }); } else { // password successfully verified - this.setState({ syncApplyCompleted: true }); - if (NativeModules.UtilityModule) { - NativeModules.UtilityModule.setSecureValue( - Constants.KEY_WALLET_PASSWORD, - this.state.password ? this.state.password : '' - ); + NativeModules.UtilityModule.setSecureValue(Constants.KEY_FIRST_RUN_PASSWORD, this.state.password); } - - this.finishSync(true); - } - } - } - - componentDidUpdate() { - const { hasSyncedWallet } = this.props; - if (this.state.syncChecked && !this.state.autoPassword && !hasSyncedWallet) { - // new user sync, don't prompt for a password - this.setState({ password: '', autoPassword: true }); - this.onEnableSyncPressed(); - } - - if (this.state.syncChecked && hasSyncedWallet && !this.state.autoLoginAttempted) { - this.setState({ autoLoginAttempted: true, password: '' }, () => this.onEnableSyncPressed()); - } - } - - finishSync = (notifyUnlockFailed = false) => { - const { navigation, notify, setClientSetting } = this.props; - - setClientSetting(Constants.SETTING_DEVICE_WALLET_SYNCED, true); - - // unlock the wallet (if locked) - Lbry.wallet_status().then(status => { - if (status.is_locked) { - Lbry.wallet_unlock({ password: this.state.password ? this.state.password : '' }).then(unlocked => { - if (unlocked) { - navigation.goBack(); - } else { - if (notifyUnlockFailed) { - notify({ message: __('The wallet could not be unlocked at this time. Please restart the app.') }); - } - } - }); - } else { + setDefaultAccount(); + setClientSetting(Constants.SETTING_DEVICE_WALLET_SYNCED, true); navigation.goBack(); } - }); - }; + } + } handleChangeText = text => { // save the value to the state email @@ -134,16 +81,16 @@ class SyncVerifyPage extends React.PureComponent { }; render() { - const { hasSyncedWallet, syncApplyIsPending, signInFlow } = this.props; + const { hasSyncedWallet, syncApplyIsPending } = this.props; let paragraph; if (!hasSyncedWallet) { paragraph = ( - <Text style={firstRunStyle.paragraph}>{__('Please enter a password to secure your account and wallet.')}</Text> + <Text style={firstRunStyle.paragraph}>Please enter a password to secure your account and wallet.</Text> ); } else { paragraph = ( - <Text style={firstRunStyle.paragraph}>{__('Please enter the password you used to secure your wallet.')}</Text> + <Text style={firstRunStyle.paragraph}>Please enter the password you used to secure your wallet.</Text> ); } @@ -152,22 +99,13 @@ class SyncVerifyPage extends React.PureComponent { content = ( <View style={firstRunStyle.centered}> <ActivityIndicator size="large" color={Colors.White} style={firstRunStyle.waiting} /> - <Text style={firstRunStyle.paragraph}>{__('Retrieving your account information...')}</Text> + <Text style={firstRunStyle.paragraph}>Retrieving your account information...</Text> </View> ); - } else if (this.state.autoLoginFlow && (syncApplyIsPending || this.state.syncApplyCompleted)) { - // first attempt at auto-login, only display activity indicator + } else { content = ( <View> - <View style={firstRunStyle.centerInside}> - <ActivityIndicator size={'small'} color={Colors.White} /> - </View> - </View> - ); - } else if (hasSyncedWallet && this.state.autoLoginAttempted) { - content = ( - <View> - <Text style={rewardStyle.verificationTitle}>{__('Wallet Sync')}</Text> + <Text style={rewardStyle.verificationTitle}>Wallet Sync</Text> {paragraph} <View style={firstRunStyle.passwordInputContainer}> <TextInput @@ -185,7 +123,7 @@ class SyncVerifyPage extends React.PureComponent { }} onBlur={() => { if (!this.state.password || this.state.password.length === 0) { - this.setState({ placeholder: __('password') }); + this.setState({ placeholder: 'password' }); } }} /> @@ -197,6 +135,16 @@ class SyncVerifyPage extends React.PureComponent { </TouchableOpacity> </View> + {(!this.state.password || this.state.password.trim().length === 0) && ( + <View style={firstRunStyle.passwordWarning}> + <Text style={firstRunStyle.passwordWarningText}> + {hasSyncedWallet + ? 'If you did not provide a password, please press Use LBRY to continue.' + : 'You can proceed without a password, but this is not recommended.'} + </Text> + </View> + )} + {(!hasSyncedWallet && this.state.password && this.state.password.trim().length) > 0 && ( <View style={firstRunStyle.passwordStrength}> <BarPasswordStrengthDisplay @@ -207,7 +155,7 @@ class SyncVerifyPage extends React.PureComponent { </View> )} <Text style={firstRunStyle.infoParagraph}> - {__('Note: for wallet security purposes, LBRY is unable to reset your password.')} + Note: for wallet security purposes, LBRY is unable to reset your password. </Text> <View style={rewardStyle.buttonContainer}> @@ -215,11 +163,11 @@ class SyncVerifyPage extends React.PureComponent { <Button style={rewardStyle.verificationButton} theme={'light'} - text={signInFlow ? __('Use LBRY') : __('Enable sync')} + text={'Enable sync'} onPress={this.onEnableSyncPressed} /> )} - {(syncApplyIsPending || this.state.syncApplyCompleted) && ( + {syncApplyIsPending && ( <View style={firstRunStyle.centerInside}> <ActivityIndicator size={'small'} color={Colors.White} /> </View> diff --git a/src/page/verification/view.js b/src/page/verification/view.js index 551fb55..6168b03 100644 --- a/src/page/verification/view.js +++ b/src/page/verification/view.js @@ -1,11 +1,10 @@ import React from 'react'; -import { Lbry, doPreferenceGet } from 'lbry-redux'; +import { Lbry } from 'lbry-redux'; import { ActivityIndicator, Linking, NativeModules, Text, TouchableOpacity, View } from 'react-native'; import { NavigationActions, StackActions } from 'react-navigation'; import AsyncStorage from '@react-native-community/async-storage'; import Colors from 'styles/colors'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api -import Icon from 'react-native-vector-icons/FontAwesome5'; +import Constants from 'constants'; import EmailVerifyPage from './internal/email-verify-page'; import ManualVerifyPage from './internal/manual-verify-page'; import PhoneVerifyPage from './internal/phone-verify-page'; @@ -20,7 +19,6 @@ class VerificationScreen extends React.PureComponent { showSkip: false, skipAccountConfirmed: false, showBottomContainer: true, - signInFlow: false, walletPassword: null, isEmailVerificationPhase: false, isEmailVerified: false, @@ -29,33 +27,16 @@ class VerificationScreen extends React.PureComponent { }; componentDidMount() { - const { user, navigation } = this.props; - const { signInFlow } = navigation.state.params; - this.setState({ signInFlow }); + const { user } = this.props; this.checkVerificationStatus(user); - NativeModules.Firebase.setCurrentScreen('Verification'); } setEmailVerificationPhase = value => { this.setState({ isEmailVerificationPhase: value }); }; - getUserSettings = () => { - const { populateSharedUserState } = this.props; - - doPreferenceGet( - 'shared', - preference => { - populateSharedUserState(preference); - }, - error => { - /* failed */ - } - ); - }; - checkVerificationStatus = user => { - const { deviceWalletSynced, getSync, navigation } = this.props; + const { deviceWalletSynced, navigation } = this.props; const { syncFlow } = navigation.state.params; this.setState( @@ -75,13 +56,7 @@ class VerificationScreen extends React.PureComponent { } if (this.state.isEmailVerified && syncFlow && deviceWalletSynced) { - // retrieve user settings - NativeModules.UtilityModule.getSecureValue(Constants.KEY_WALLET_PASSWORD).then(walletPassword => { - getSync(walletPassword, () => { - this.getUserSettings(); - navigation.goBack(); - }); - }); + navigation.goBack(); } } else { if (this.state.isEmailVerified && !this.state.isIdentityVerified && !this.state.isRewardApproved) { @@ -93,9 +68,6 @@ class VerificationScreen extends React.PureComponent { if (this.state.isEmailVerified && this.state.isRewardApproved) { // verification steps already completed // simply navigate back to the rewards page - if (user.primary_email) { - NativeModules.Firebase.track('reward_eligibility_completed', { email: user.primary_email }); - } navigation.goBack(); } } @@ -118,7 +90,6 @@ class VerificationScreen extends React.PureComponent { addUserEmail, checkSync, emailNewErrorMessage, - emailAlreadyExists, emailNewPending, emailToVerify, getSync, @@ -126,6 +97,7 @@ class VerificationScreen extends React.PureComponent { notify, addUserPhone, getSyncIsPending, + setDefaultAccount, hasSyncedWallet, setSyncIsPending, syncApplyIsPending, @@ -149,7 +121,6 @@ class VerificationScreen extends React.PureComponent { page = ( <EmailVerifyPage addUserEmail={addUserEmail} - emailAlreadyExists={emailAlreadyExists} emailNewErrorMessage={emailNewErrorMessage} emailNewPending={emailNewPending} emailToVerify={emailToVerify} @@ -187,13 +158,13 @@ class VerificationScreen extends React.PureComponent { notify={notify} setEmailVerificationPhase={this.setEmailVerificationPhase} setClientSetting={setClientSetting} + setDefaultAccount={setDefaultAccount} setSyncIsPending={setSyncIsPending} syncApplyIsPending={syncApplyIsPending} syncApplyErrorMessage={syncApplyErrorMessage} syncApply={syncApply} syncData={syncData} syncHash={syncHash} - signInFlow={this.state.signInFlow} /> ); break; @@ -209,7 +180,7 @@ class VerificationScreen extends React.PureComponent { {!this.state.isEmailVerificationPhase && ( <TouchableOpacity style={firstRunStyle.closeButton} onPress={this.onCloseButtonPressed}> - <Icon name={'times'} size={16} style={firstRunStyle.closeButtonIcon} /> + <Text style={firstRunStyle.closeButtonText}>x</Text> </TouchableOpacity> )} </View> diff --git a/src/page/wallet/index.js b/src/page/wallet/index.js index 1089ea2..634455d 100644 --- a/src/page/wallet/index.js +++ b/src/page/wallet/index.js @@ -1,11 +1,11 @@ import { connect } from 'react-redux'; import { doSetClientSetting } from 'redux/actions/settings'; -import { makeSelectClientSetting, selectSdkReady } from 'redux/selectors/settings'; +import { makeSelectClientSetting } from 'redux/selectors/settings'; import { doPushDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer'; import { selectCurrentRoute } from 'redux/selectors/drawer'; import { selectBalance } from 'lbry-redux'; import { doCheckSync, doGetSync, selectUser, selectHasSyncedWallet } from 'lbryinc'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api +import Constants from 'constants'; import WalletPage from './view'; const select = state => ({ @@ -15,17 +15,19 @@ const select = state => ({ deviceWalletSynced: makeSelectClientSetting(Constants.SETTING_DEVICE_WALLET_SYNCED)(state), hasSyncedWallet: selectHasSyncedWallet(state), rewardsNotInterested: makeSelectClientSetting(Constants.SETTING_REWARDS_NOT_INTERESTED)(state), - sdkReady: selectSdkReady(state), understandsRisks: makeSelectClientSetting(Constants.SETTING_ALPHA_UNDERSTANDS_RISKS)(state), user: selectUser(state), }); const perform = dispatch => ({ checkSync: () => dispatch(doCheckSync()), - getSync: (password, callback) => dispatch(doGetSync(password, callback)), + getSync: password => dispatch(doGetSync(password)), setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)), pushDrawerStack: () => dispatch(doPushDrawerStack(Constants.DRAWER_ROUTE_WALLET)), setPlayerVisible: () => dispatch(doSetPlayerVisible(false)), }); -export default connect(select, perform)(WalletPage); +export default connect( + select, + perform +)(WalletPage); diff --git a/src/page/wallet/view.js b/src/page/wallet/view.js index ed6e9a6..0f76b14 100644 --- a/src/page/wallet/view.js +++ b/src/page/wallet/view.js @@ -1,16 +1,15 @@ import React from 'react'; import { NativeModules, ScrollView, Text, View } from 'react-native'; -import EmptyStateView from 'component/emptyStateView'; import TransactionListRecent from 'component/transactionListRecent'; import WalletAddress from 'component/walletAddress'; import WalletBalance from 'component/walletBalance'; -import WalletBalanceExtra from 'component/walletBalanceExtra'; import WalletSend from 'component/walletSend'; import WalletRewardsDriver from 'component/walletRewardsDriver'; -import WalletSignIn from 'component/walletSignIn'; import WalletSyncDriver from 'component/walletSyncDriver'; +import Button from 'component/button'; +import Link from 'component/link'; import UriBar from 'component/uriBar'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api +import Constants from 'constants'; import walletStyle from 'styles/wallet'; class WalletPage extends React.PureComponent { @@ -18,7 +17,7 @@ class WalletPage extends React.PureComponent { componentWillMount() { const { navigation } = this.props; - // this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused); + this.didFocusListener = navigation.addListener('didFocus', this.onComponentFocused); } componentWillUnmount() { @@ -43,12 +42,13 @@ class WalletPage extends React.PureComponent { const { pushDrawerStack, setPlayerVisible } = this.props; pushDrawerStack(); setPlayerVisible(); - NativeModules.Firebase.setCurrentScreen('Wallet'); const { deviceWalletSynced, getSync, user } = this.props; if (deviceWalletSynced && user && user.has_verified_email) { - NativeModules.UtilityModule.getSecureValue(Constants.KEY_WALLET_PASSWORD).then(walletPassword => { - getSync(walletPassword); + NativeModules.UtilityModule.getSecureValue(Constants.KEY_FIRST_RUN_PASSWORD).then(walletPassword => { + if (walletPassword && walletPassword.trim().length > 0) { + getSync(walletPassword); + } }); } }; @@ -59,31 +59,45 @@ class WalletPage extends React.PureComponent { }; render() { - const { balance, rewardsNotInterested, understandsRisks, navigation, sdkReady, user } = this.props; + const { + balance, + backupDismissed, + hasSyncedWallet, + rewardsNotInterested, + understandsRisks, + setClientSetting, + navigation, + } = this.props; - if (!sdkReady) { + if (!understandsRisks) { return ( - <View style={walletStyle.container}> + <View> <UriBar navigation={navigation} /> - <EmptyStateView - message={__( - 'The background service is still initializing. You can still explore and watch content during the initialization process.', + <View style={walletStyle.warning}> + <Text style={walletStyle.warningParagraph}> + This is beta software. You may lose any credits that you send to your wallet due to software bugs, deleted + files, or malicious third-party software. You should not use this wallet as your primary wallet. + </Text> + {!hasSyncedWallet && ( + <Text style={walletStyle.warningParagraph}> + Since you are not using the LBRY sync service, you will lose all of your credits if you uninstall this + application. Instructions on how to enroll as well as how to backup your wallet manually are available + on the next page. + </Text> )} + <Text style={walletStyle.warningText}> + If you understand the risks and you wish to continue, please tap the button below. + </Text> + </View> + <Button + text={'I understand the risks'} + style={[walletStyle.button, walletStyle.understand]} + onPress={() => setClientSetting(Constants.SETTING_ALPHA_UNDERSTANDS_RISKS, true)} /> </View> ); } - const signedIn = user && user.has_verified_email; - if (!signedIn && !understandsRisks) { - return ( - <View style={walletStyle.container}> - <UriBar navigation={navigation} /> - <WalletSignIn navigation={navigation} /> - </View> - ); - } - return ( <View style={walletStyle.container}> <UriBar navigation={navigation} /> @@ -94,7 +108,6 @@ class WalletPage extends React.PureComponent { > {!rewardsNotInterested && (!balance || balance === 0) && <WalletRewardsDriver navigation={navigation} />} <WalletBalance /> - <WalletBalanceExtra navigation={navigation} /> <WalletAddress /> <WalletSend /> <TransactionListRecent navigation={navigation} /> diff --git a/src/redux/actions/drawer.js b/src/redux/actions/drawer.js index 344d820..08b2184 100644 --- a/src/redux/actions/drawer.js +++ b/src/redux/actions/drawer.js @@ -1,28 +1,18 @@ -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api +import Constants from 'constants'; -export const doPushDrawerStack = (routeName, params) => dispatch => { +export const doPushDrawerStack = routeName => dispatch => dispatch({ type: Constants.ACTION_PUSH_DRAWER_STACK, - data: { routeName, params }, + data: routeName, }); - if (window.persistor) { - window.persistor.flush(); - } -}; - -export const doPopDrawerStack = () => dispatch => { +export const doPopDrawerStack = () => dispatch => dispatch({ type: Constants.ACTION_POP_DRAWER_STACK, }); - if (window.persistor) { - window.persistor.flush(); - } -}; - -export const doSetPlayerVisible = (visible, uri) => dispatch => +export const doSetPlayerVisible = visible => dispatch => dispatch({ type: Constants.ACTION_SET_PLAYER_VISIBLE, - data: { visible, uri }, + data: { visible }, }); diff --git a/src/redux/actions/file.js b/src/redux/actions/file.js index 56a5d3f..3694fed 100644 --- a/src/redux/actions/file.js +++ b/src/redux/actions/file.js @@ -59,24 +59,22 @@ export function doCompleteDownload(uri, outpoint, fileInfo) { export function doStopDownloadingFile(uri, fileInfo) { return dispatch => { let params = { status: 'stop' }; - if (fileInfo) { - if (fileInfo.sd_hash) { - params.sd_hash = fileInfo.sd_hash; - } - if (fileInfo.stream_hash) { - params.stream_hash = fileInfo.stream_hash; - } - - Lbry.file_set_status(params).then(() => { - dispatch({ - type: ACTIONS.DOWNLOADING_CANCELED, - data: { uri, outpoint: fileInfo.outpoint }, - }); - - // Should also delete the file after the user stops downloading - dispatch(doDeleteFile(fileInfo.outpoint, uri)); - }); + if (fileInfo.sd_hash) { + params.sd_hash = fileInfo.sd_hash; } + if (fileInfo.stream_hash) { + params.stream_hash = fileInfo.stream_hash; + } + + Lbry.file_set_status(params).then(() => { + dispatch({ + type: ACTIONS.DOWNLOADING_CANCELED, + data: { uri, outpoint: fileInfo.outpoint }, + }); + + // Should also delete the file after the user stops downloading + dispatch(doDeleteFile(fileInfo.outpoint, uri)); + }); }; } @@ -97,7 +95,7 @@ export function doDeleteFile(outpoint, deleteFromComputer, abandonClaim) { }); // If the file is for a claim we published then also abandon the claim - /* const myClaimsOutpoints = selectMyClaimsOutpoints(state); + /*const myClaimsOutpoints = selectMyClaimsOutpoints(state); if (abandonClaim && myClaimsOutpoints.indexOf(outpoint) !== -1) { const byOutpoint = selectFileInfosByOutpoint(state); const fileInfo = byOutpoint[outpoint]; @@ -108,7 +106,7 @@ export function doDeleteFile(outpoint, deleteFromComputer, abandonClaim) { dispatch(doAbandonClaim(txid, nout)); } - } */ + }*/ dispatch({ type: ACTIONS.FILE_DELETE, diff --git a/src/redux/actions/form.js b/src/redux/actions/form.js deleted file mode 100644 index 7a0d352..0000000 --- a/src/redux/actions/form.js +++ /dev/null @@ -1,52 +0,0 @@ -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api -import { ACTIONS, batchActions, selectMyClaims } from 'lbry-redux'; - -export const doUpdatePublishFormState = publishFormValue => dispatch => - dispatch({ - type: Constants.ACTION_UPDATE_PUBLISH_FORM_STATE, - data: { ...publishFormValue }, - }); - -export const doUpdateChannelFormState = channelFormValue => dispatch => - dispatch({ - type: Constants.ACTION_UPDATE_CHANNEL_FORM_STATE, - data: { ...channelFormValue }, - }); - -export const doClearPublishFormState = () => dispatch => - dispatch({ - type: Constants.ACTION_CLEAR_PUBLISH_FORM_STATE, - }); - -export const doClearChannelFormState = () => dispatch => - dispatch({ - type: Constants.ACTION_CLEAR_CHANNEL_FORM_STATE, - }); - -export const doPendingPublishSuccess = pendingClaim => (dispatch, getState) => { - const state = getState(); - const myClaims = selectMyClaims(state); - const { permanent_url: url } = pendingClaim; - const actions = [ - { - type: ACTIONS.PUBLISH_SUCCESS, - }, - ]; - - // We have to fake a temp claim until the new pending one is returned by claim_list_mine - // We can't rely on claim_list_mine because there might be some delay before the new claims are returned - // Doing this allows us to show the pending claim immediately, it will get overwritten by the real one - const isMatch = claim => claim.claim_id === pendingClaim.claim_id; - const isEdit = myClaims.some(isMatch); - - const myNewClaims = isEdit - ? myClaims.map(claim => (isMatch(claim) ? pendingClaim : claim)) - : myClaims.concat(pendingClaim); - actions.push({ - type: ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED, - data: { - claims: myNewClaims, - }, - }); - dispatch(batchActions(...actions)); -}; diff --git a/src/redux/actions/performance.js b/src/redux/actions/performance.js new file mode 100644 index 0000000..dcfc197 --- /dev/null +++ b/src/redux/actions/performance.js @@ -0,0 +1,96 @@ +// @flow +import { NativeModules } from 'react-native'; +import { + ACTIONS, + batchActions, + buildURI, + doResolveUri, + doUpdateSearchQuery, + makeSelectSearchUris, + selectSuggestions, + makeSelectQueryWithOptions, + selectSearchValue, +} from 'lbry-redux'; + +let CONNECTION_STRING = 'https://lighthouse.lbry.com/'; + +const handleNativeFetchResponse = str => { + const json = JSON.parse(str); + if (json.error) { + return Promise.reject(new Error(json.error)); + } + + return Promise.resolve(json); +}; + +// Use a native asyncTask to call the lighthouse api +export const doNativeSearch = ( + rawQuery: string, // pass in a query if you don't want to search for what's in the search bar + size: ?number, // only pass in if you don't want to use the users setting (ex: related content) + from: ?number, + isBackgroundSearch: boolean = false +) => (dispatch: Dispatch, getState: GetState) => { + const query = rawQuery.replace(/^lbry:\/\//i, '').replace(/\//, ' '); + + if (!query) { + dispatch({ + type: ACTIONS.SEARCH_FAIL, + }); + return; + } + + const state = getState(); + const queryWithOptions = makeSelectQueryWithOptions(query, size, from, isBackgroundSearch)(state); + + // If we have already searched for something, we don't need to do anything + const urisForQuery = makeSelectSearchUris(queryWithOptions)(state); + if (urisForQuery && !!urisForQuery.length) { + return; + } + + dispatch({ + type: ACTIONS.SEARCH_START, + }); + + // If the user is on the file page with a pre-populated uri and they select + // the search option without typing anything, searchQuery will be empty + // We need to populate it so the input is filled on the search page + // isBackgroundSearch means the search is happening in the background, don't update the search query + if (!state.search.searchQuery && !isBackgroundSearch) { + dispatch(doUpdateSearchQuery(query)); + } + + const url = `${CONNECTION_STRING}search?${queryWithOptions}`; + NativeModules.Requests.get(url) + .then(handleNativeFetchResponse) + .then((data: Array<{ name: String, claimId: string }>) => { + const uris = []; + const actions = []; + + data.forEach(result => { + if (result.name) { + const uri = buildURI({ + claimName: result.name, + claimId: result.claimId, + }); + actions.push(doResolveUri(uri)); + uris.push(uri); + } + }); + + actions.push({ + type: ACTIONS.SEARCH_SUCCESS, + data: { + query: queryWithOptions, + uris, + }, + }); + dispatch(batchActions(...actions)); + }) + .catch(e => { + console.log(e); + dispatch({ + type: ACTIONS.SEARCH_FAIL, + }); + }); +}; diff --git a/src/redux/actions/settings.js b/src/redux/actions/settings.js index 1d7f919..754f960 100644 --- a/src/redux/actions/settings.js +++ b/src/redux/actions/settings.js @@ -1,5 +1,4 @@ import { ACTIONS } from 'lbry-redux'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api export function doSetClientSetting(key, value) { return dispatch => { @@ -16,44 +15,3 @@ export function doSetClientSetting(key, value) { } }; } - -export function doSetSdkReady() { - return dispatch => { - dispatch({ - type: Constants.ACTION_SDK_READY, - }); - }; -} - -export function doSetSortByItem(item) { - return dispatch => { - dispatch({ - type: Constants.ACTION_SORT_BY_ITEM_CHANGED, - data: { - name: item.name, - }, - }); - }; -} - -export function doSetTimeItem(item) { - return dispatch => { - dispatch({ - type: Constants.ACTION_TIME_ITEM_CHANGED, - data: { - name: item.name, - }, - }); - }; -} - -export function doToggleFullscreenMode(mode) { - return dispatch => { - dispatch({ - type: Constants.ACTION_FULLSCREEN_MODE_TOGGLED, - data: { - mode, - }, - }); - }; -} diff --git a/src/redux/reducers/drawer.js b/src/redux/reducers/drawer.js index 6b5a8c5..3de7a7b 100644 --- a/src/redux/reducers/drawer.js +++ b/src/redux/reducers/drawer.js @@ -1,76 +1,38 @@ -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api +import Constants from 'constants'; const reducers = {}; const defaultState = { - stack: [{ route: Constants.DRAWER_ROUTE_SUBSCRIPTIONS, params: {} }], // Following is always the first drawer route - lastRouteInStack: {}, + stack: [Constants.DRAWER_ROUTE_DISCOVER], // Discover is always the first drawer route playerVisible: false, - playerVisibleByUri: {}, currentRoute: null, }; -reducers[Constants.ACTION_SET_PLAYER_VISIBLE] = (state, action) => { - const { visible, uri } = action.data; - const playerVisibleByUri = Object.assign({}, state.playerVisibleByUri); - - if (!uri) { - Object.keys(playerVisibleByUri).forEach(playerUri => { - playerVisibleByUri[playerUri] = visible; - }); - } else { - playerVisibleByUri[uri] = visible; - } - - return Object.assign({}, state, { +reducers[Constants.ACTION_SET_PLAYER_VISIBLE] = (state, action) => + Object.assign({}, state, { playerVisible: action.data.visible, - playerVisibleByUri, }); -}; reducers[Constants.ACTION_PUSH_DRAWER_STACK] = (state, action) => { - const { routeName, params } = action.data; + const routeName = action.data; const newStack = state.stack.slice(); - const lastRoute = newStack[newStack.length - 1].route; - let canPushStack = routeName !== lastRoute; - if ( - lastRoute === Constants.DRAWER_ROUTE_CHANNEL_CREATOR_FORM && - routeName === Constants.DRAWER_ROUTE_CHANNEL_CREATOR - ) { - canPushStack = false; - } - if (lastRoute === Constants.DRAWER_ROUTE_PUBLISH_FORM && routeName === Constants.DRAWER_ROUTE_PUBLISH) { - canPushStack = false; - } - if (routeName === Constants.DRAWER_ROUTE_SUBSCRIPTIONS && newStack.length === 1) { - canPushStack = false; - } - if (routeName === Constants.DRAWER_ROUTE_LITE_FILE) { - canPushStack = false; - } - - let lastRouteInStack; - if (canPushStack) { - newStack.push({ route: routeName, params }); - lastRouteInStack = { route: routeName, params }; + if (routeName !== newStack[newStack.length - 1]) { + newStack.push(routeName); } return { ...state, stack: newStack, - lastRouteInStack, }; }; reducers[Constants.ACTION_POP_DRAWER_STACK] = (state, action) => { // We don't want to pop the Discover route, since it's always expected to be the first const newStack = state.stack.length === 1 ? state.stack.slice() : state.stack.slice(0, state.stack.length - 1); - const lastRouteInStack = newStack && newStack.length > 0 ? newStack[newStack.length - 1] : null; return { ...state, stack: newStack, - lastRouteInStack, }; }; diff --git a/src/redux/reducers/form.js b/src/redux/reducers/form.js deleted file mode 100644 index 321d55e..0000000 --- a/src/redux/reducers/form.js +++ /dev/null @@ -1,49 +0,0 @@ -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api - -const reducers = {}; -const defaultState = { - channelFormValues: {}, - publishFormValues: {}, -}; - -reducers[Constants.ACTION_UPDATE_PUBLISH_FORM_STATE] = (state, action) => { - const { data } = action; - const publishFormValues = Object.assign({}, state.publishFormValues); - const newPublishFormValues = Object.assign(publishFormValues, data); - - return { - ...state, - publishFormValues: newPublishFormValues, - }; -}; - -reducers[Constants.ACTION_UPDATE_CHANNEL_FORM_STATE] = (state, action) => { - const { data } = action; - const channelFormValues = Object.assign({}, state.channelFormValues); - const newChannelFormValues = Object.assign(channelFormValues, data); - - return { - ...state, - channelFormValues: newChannelFormValues, - }; -}; - -reducers[Constants.ACTION_CLEAR_PUBLISH_FORM_STATE] = state => { - return { - ...state, - publishFormValues: {}, - }; -}; - -reducers[Constants.ACTION_CLEAR_CHANNEL_FORM_STATE] = state => { - return { - ...state, - channelFormValues: {}, - }; -}; - -export default function reducer(state = defaultState, action) { - const handler = reducers[action.type]; - if (handler) return handler(state, action); - return state; -} diff --git a/src/redux/reducers/settings.js b/src/redux/reducers/settings.js index 85a64bb..0a500a5 100644 --- a/src/redux/reducers/settings.js +++ b/src/redux/reducers/settings.js @@ -1,13 +1,8 @@ import { ACTIONS } from 'lbry-redux'; -import Constants from 'constants'; // eslint-disable-line node/no-deprecated-api const reducers = {}; const defaultState = { clientSettings: {}, - sdkReady: false, - sortByItemName: Constants.SORT_BY_HOT, - timeItemName: Constants.TIME_WEEK, - fullscreenMode: false, }; reducers[ACTIONS.CLIENT_SETTING_CHANGED] = (state, action) => { @@ -21,26 +16,6 @@ reducers[ACTIONS.CLIENT_SETTING_CHANGED] = (state, action) => { }); }; -reducers[Constants.ACTION_SDK_READY] = (state, action) => - Object.assign({}, state, { - sdkReady: true, - }); - -reducers[Constants.ACTION_SORT_BY_ITEM_CHANGED] = (state, action) => - Object.assign({}, state, { - sortByItemName: action.data.name, - }); - -reducers[Constants.ACTION_TIME_ITEM_CHANGED] = (state, action) => - Object.assign({}, state, { - timeItemName: action.data.name, - }); - -reducers[Constants.ACTION_FULLSCREEN_MODE_TOGGLED] = (state, action) => - Object.assign({}, state, { - fullscreenMode: action.data.mode, - }); - export default function reducer(state = defaultState, action) { const handler = reducers[action.type]; if (handler) return handler(state, action); diff --git a/src/redux/selectors/drawer.js b/src/redux/selectors/drawer.js index 5cb7dc1..ef956a9 100644 --- a/src/redux/selectors/drawer.js +++ b/src/redux/selectors/drawer.js @@ -4,25 +4,14 @@ export const selectState = state => state.drawer || {}; export const selectDrawerStack = createSelector( selectState, - state => state.stack, + state => state.stack ); export const selectIsPlayerVisible = createSelector( selectState, - state => state.playerVisible, + state => state.playerVisible ); -export const selectPlayerVisibleByUri = createSelector( - selectState, - state => state.playerVisibleByUri, -); - -export const makeSelectPlayerVisible = uri => - createSelector( - selectPlayerVisibleByUri, - byUri => (byUri ? byUri[uri] : false), - ); - export const selectLastDrawerRoute = createSelector( selectState, state => { @@ -31,15 +20,10 @@ export const selectLastDrawerRoute = createSelector( } return null; - }, -); - -export const selectLastRouteInStack = createSelector( - selectState, - state => state.lastRouteInStack, + } ); export const selectCurrentRoute = createSelector( selectState, - state => state.currentRoute, + state => state.currentRoute ); diff --git a/src/redux/selectors/form.js b/src/redux/selectors/form.js deleted file mode 100644 index 79c7a2c..0000000 --- a/src/redux/selectors/form.js +++ /dev/null @@ -1,23 +0,0 @@ -import { createSelector } from 'reselect'; - -export const selectState = state => state.form || {}; - -export const selectPublishFormState = createSelector( - selectState, - state => state.publishFormValues || {} -); - -export const selectChannelFormState = createSelector( - selectState, - state => state.channelFormValues || {} -); - -export const selectHasPublishFormState = createSelector( - selectPublishFormState, - values => Object.keys(values).length > 0 -); - -export const selectHasChannelFormState = createSelector( - selectChannelFormState, - values => Object.keys(values).length > 0 -); diff --git a/src/redux/selectors/settings.js b/src/redux/selectors/settings.js index 1bebeff..7bad4dd 100644 --- a/src/redux/selectors/settings.js +++ b/src/redux/selectors/settings.js @@ -1,25 +1,25 @@ import { SETTINGS } from 'lbry-redux'; import { createSelector } from 'reselect'; -import { getSortByItemForName, getTimeItemForName } from 'utils/helper'; const selectState = state => state.settings || {}; -export const selectDaemonSettings = createSelector(selectState, state => state.daemonSettings); +export const selectDaemonSettings = createSelector( + selectState, + state => state.daemonSettings +); -export const selectClientSettings = createSelector(selectState, state => state.clientSettings || {}); - -export const selectSortByItem = createSelector(selectState, state => getSortByItemForName(state.sortByItemName)); - -export const selectTimeItem = createSelector(selectState, state => getTimeItemForName(state.timeItemName)); +export const selectClientSettings = createSelector( + selectState, + state => state.clientSettings || {} +); export const makeSelectClientSetting = setting => - createSelector(selectClientSettings, settings => (settings ? settings[setting] : undefined)); + createSelector( + selectClientSettings, + settings => (settings ? settings[setting] : undefined) + ); // refactor me export const selectShowNsfw = makeSelectClientSetting(SETTINGS.SHOW_NSFW); export const selectKeepDaemonRunning = makeSelectClientSetting(SETTINGS.KEEP_DAEMON_RUNNING); - -export const selectFullscreenMode = createSelector(selectState, state => state.fullscreenMode); - -export const selectSdkReady = createSelector(selectState, state => state.sdkReady); diff --git a/src/styles/about.js b/src/styles/about.js index 27c0e90..03bf90c 100644 --- a/src/styles/about.js +++ b/src/styles/about.js @@ -32,14 +32,14 @@ const aboutStyle = StyleSheet.create({ title: { color: Colors.LbryGreen, fontSize: 24, - fontFamily: 'Inter-SemiBold', + fontFamily: 'Inter-UI-SemiBold', marginTop: 16, marginLeft: 12, marginRight: 12, marginBottom: 8, }, paragraph: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 16, lineHeight: 24, marginLeft: 12, @@ -53,13 +53,13 @@ const aboutStyle = StyleSheet.create({ }, link: { color: Colors.LbryGreen, - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 16, marginBottom: 24, }, listLink: { color: Colors.LbryGreen, - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 15, alignSelf: 'flex-end', }, @@ -67,30 +67,30 @@ const aboutStyle = StyleSheet.create({ alignSelf: 'stretch', }, socialTitle: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', marginLeft: 12, marginRight: 12, marginBottom: 8, fontSize: 20, }, releaseInfoTitle: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', marginLeft: 12, marginRight: 12, marginBottom: 12, fontSize: 20, }, text: { - fontFamily: 'Inter-SemiBold', + fontFamily: 'Inter-UI-SemiBold', fontSize: 15, }, valueText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', textAlign: 'right', fontSize: 15, }, lineValueText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 15, }, }); diff --git a/src/styles/autothumb.js b/src/styles/autothumb.js deleted file mode 100644 index 7853646..0000000 --- a/src/styles/autothumb.js +++ /dev/null @@ -1,57 +0,0 @@ -import { StyleSheet } from 'react-native'; - -const autothumbStyle = StyleSheet.create({ - autothumbPurple: { - backgroundColor: '#9c27b0', - }, - autothumbDeepPurple: { - backgroundColor: '#5e35b1', - }, - autothumbRed: { - backgroundColor: '#e53935', - }, - autothumbPink: { - backgroundColor: '#e91e63', - }, - autothumbIndigo: { - backgroundColor: '#3f51b5', - }, - autothumbBlue: { - backgroundColor: '#2196f3', - }, - autothumbLightBlue: { - backgroundColor: '#039be5', - }, - autothumbCyan: { - backgroundColor: '#00acc1', - }, - autothumbTeal: { - backgroundColor: '#009688', - }, - autothumbGreen: { - backgroundColor: '#43a047', - }, - autothumbYellow: { - backgroundColor: '#ffeb3b', - }, - autothumbOrange: { - backgroundColor: '#ffa726', - }, - autothumbAmber: { - backgroundColor: '#ffb300', - }, - autothumbLime: { - backgroundColor: '#c0ca33', - }, - autothumbLightGreen: { - backgroundColor: '#7cb342', - }, - autothumbDeepOrange: { - backgroundColor: '#f4511e', - }, - autothumbBrown: { - backgroundColor: '#6d4c41', - }, -}); - -export default autothumbStyle; diff --git a/src/styles/button.js b/src/styles/button.js index 30ae7f5..cb162bc 100644 --- a/src/styles/button.js +++ b/src/styles/button.js @@ -29,11 +29,11 @@ const buttonStyle = StyleSheet.create({ color: Colors.DarkGrey, }, text: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 14, }, textWithIcon: { - marginLeft: 4, + marginLeft: 8, }, }); diff --git a/src/styles/channelCreator.js b/src/styles/channelCreator.js deleted file mode 100644 index dc3cf0c..0000000 --- a/src/styles/channelCreator.js +++ /dev/null @@ -1,280 +0,0 @@ -import { Dimensions, StyleSheet } from 'react-native'; -import Colors from './colors'; - -const screenDimension = Dimensions.get('window'); -const screenWidth = screenDimension.width; - -const channelCreatorStyle = StyleSheet.create({ - card: { - backgroundColor: Colors.White, - marginTop: 16, - marginLeft: 16, - marginRight: 16, - padding: 16, - }, - container: { - flex: 1, - backgroundColor: Colors.PageBackground, - }, - channelPicker: { - fontFamily: 'Inter-Regular', - fontSize: 16, - height: 52, - width: '100%', - }, - bidRow: { - flexDirection: 'row', - alignItems: 'center', - }, - label: { - fontFamily: 'Inter-Regular', - fontSize: 16, - }, - balance: { - alignItems: 'center', - flexDirection: 'row', - marginLeft: 24, - }, - balanceText: { - fontFamily: 'Inter-SemiBold', - fontSize: 14, - marginLeft: 4, - }, - channelNameInput: { - fontFamily: 'Inter-Regular', - fontSize: 16, - paddingLeft: 20, - }, - bidAmountInput: { - fontFamily: 'Inter-Regular', - fontSize: 16, - marginLeft: 16, - textAlign: 'right', - width: 80, - }, - helpText: { - fontFamily: 'Inter-Regular', - fontSize: 12, - color: Colors.DescriptionGrey, - }, - channelTitleInput: { - marginBottom: 4, - }, - createChannelContainer: { - marginTop: 60, - flex: 1, - }, - channelAt: { - position: 'absolute', - left: 4, - top: 13, - fontFamily: 'Inter-Regular', - fontSize: 16, - }, - buttonContainer: { - marginTop: 24, - marginBottom: 16, - }, - buttons: { - marginLeft: 16, - marginRight: 16, - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'space-between', - }, - cancelLink: { - marginRight: 16, - }, - createButton: { - backgroundColor: Colors.LbryGreen, - alignSelf: 'flex-end', - }, - inlineError: { - fontFamily: 'Inter-Regular', - fontSize: 12, - color: Colors.Red, - marginTop: 2, - }, - imageSelectors: { - width: '100%', - height: 160, - }, - coverImageTouchArea: { - position: 'absolute', - left: 0, - right: 0, - top: 0, - bottom: 0, - alignItems: 'center', - justifyContent: 'center', - }, - coverImage: { - width: '100%', - height: '100%', - }, - avatarImageContainer: { - position: 'absolute', - left: screenWidth / 2 - 80 / 2, - bottom: -8, - width: 80, - height: 80, - borderRadius: 160, - overflow: 'hidden', - zIndex: 50, - }, - avatarTouchArea: { - width: 80, - height: 80, - alignItems: 'center', - justifyContent: 'center', - }, - avatarImage: { - width: '100%', - height: '100%', - }, - listFooter: { - marginTop: 8, - }, - createChannelButton: { - backgroundColor: Colors.LbryGreen, - alignSelf: 'flex-start', - }, - scrollContainer: { - marginTop: 60, - }, - scrollPadding: { - padding: 16, - }, - channelListItem: { - flexDirection: 'row', - marginBottom: 16, - alignItems: 'center', - }, - channelListTitle: { - fontFamily: 'Inter-Regular', - fontSize: 18, - marginBottom: 4, - }, - channelListName: { - fontFamily: 'Inter-Regular', - fontSize: 14, - }, - channelListAvatar: { - marginRight: 16, - width: 80, - height: 80, - borderRadius: 160, - overflow: 'hidden', - alignItems: 'center', - justifyContent: 'center', - }, - selectedOverlay: { - position: 'absolute', - left: 0, - top: 0, - width: 80, - height: 80, - borderRadius: 160, - overflow: 'hidden', - alignItems: 'center', - justifyContent: 'center', - backgroundColor: '#000000aa', - }, - listHeader: { - alignItems: 'center', - marginTop: 16, - marginBottom: 16, - }, - textInputLayout: { - marginBottom: 4, - }, - textInputTitle: { - fontFamily: 'Inter-Regular', - fontSize: 12, - marginBottom: -10, - marginLeft: 4, - }, - inputText: { - fontFamily: 'Inter-Regular', - fontSize: 16, - }, - toggleContainer: { - marginTop: 24, - alignItems: 'center', - justifyContent: 'flex-end', - }, - modeLink: { - color: Colors.LbryGreen, - alignSelf: 'flex-end', - marginRight: 16, - }, - cardTitle: { - fontFamily: 'Inter-Regular', - fontSize: 20, - marginBottom: 8, - }, - tag: { - marginRight: 4, - marginBottom: 4, - }, - tagList: { - flexDirection: 'row', - flexWrap: 'wrap', - }, - editOverlay: { - alignItems: 'center', - justifyContent: 'center', - borderRadius: 24, - position: 'absolute', - padding: 8, - left: 4, - bottom: 4, - backgroundColor: '#00000077', - }, - thumbnailEditOverlay: { - alignItems: 'center', - justifyContent: 'center', - borderRadius: 24, - position: 'absolute', - padding: 8, - left: 80 / 2 - 32 / 2, - bottom: 4, - backgroundColor: '#00000077', - }, - editIcon: { - color: Colors.White, - fontFamily: 'Inter-SemiBold', - fontSize: 12, - }, - uploadProgress: { - alignItems: 'center', - borderRadius: 16, - flexDirection: 'row', - position: 'absolute', - top: 8, - right: 8, - backgroundColor: '#00000077', - paddingLeft: 8, - paddingRight: 8, - paddingTop: 4, - paddingBottom: 4, - justifyContent: 'center', - }, - uploadText: { - color: Colors.White, - fontFamily: 'Inter-SemiBold', - fontSize: 12, - marginLeft: 4, - }, - loading: { - position: 'absolute', - left: 0, - right: 0, - top: 0, - bottom: 0, - alignItems: 'center', - justifyContent: 'center', - }, -}); - -export default channelCreatorStyle; diff --git a/src/styles/channelIcon.js b/src/styles/channelIcon.js index 82a5c22..34856c0 100644 --- a/src/styles/channelIcon.js +++ b/src/styles/channelIcon.js @@ -10,7 +10,7 @@ const channelIconStyle = StyleSheet.create({ alignSelf: 'flex-start', }, placeholderText: { - fontFamily: 'Inter-SemiBold', + fontFamily: 'Inter-UI-SemiBold', fontSize: 14, }, thumbnailContainer: { @@ -18,8 +18,6 @@ const channelIconStyle = StyleSheet.create({ height: 80, borderRadius: 160, overflow: 'hidden', - alignItems: 'center', - justifyContent: 'center', }, borderedThumbnailContainer: { borderWidth: 1, @@ -39,17 +37,12 @@ const channelIconStyle = StyleSheet.create({ justifyContent: 'center', }, title: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 12, width: 80, marginTop: 4, textAlign: 'center', }, - autothumbCharacter: { - fontFamily: 'Inter-Regular', - fontSize: 48, - color: Colors.White, - }, }); export default channelIconStyle; diff --git a/src/styles/channelPage.js b/src/styles/channelPage.js index 24f5561..4de25b9 100644 --- a/src/styles/channelPage.js +++ b/src/styles/channelPage.js @@ -23,7 +23,7 @@ const channelPageStyle = StyleSheet.create({ }, title: { color: Colors.LbryGreen, - fontFamily: 'Inter-SemiBold', + fontFamily: 'Inter-UI-SemiBold', fontSize: 30, margin: 16, }, @@ -31,12 +31,13 @@ const channelPageStyle = StyleSheet.create({ flex: 1, justifyContent: 'center', alignItems: 'center', - padding: 24, + flexDirection: 'row', }, infoText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 20, textAlign: 'center', + marginLeft: 10, }, pageButtons: { width: '100%', @@ -62,26 +63,18 @@ const channelPageStyle = StyleSheet.create({ }, channelName: { color: Colors.White, - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 18, - padding: 2, - backgroundColor: '#000000aa', - }, - subscribeButtonContainer: { - position: 'absolute', - flexDirection: 'row', - right: 8, - bottom: -90, - zIndex: 100, }, subscribeButton: { alignSelf: 'flex-start', backgroundColor: Colors.White, paddingLeft: 16, paddingRight: 16, - }, - bellButton: { - marginLeft: 8, + position: 'absolute', + right: 8, + bottom: -88, + zIndex: 100, }, cover: { width: '100%', @@ -98,7 +91,7 @@ const channelPageStyle = StyleSheet.create({ justifyContent: 'flex-end', }, tabTitle: { - fontFamily: 'Inter-SemiBold', + fontFamily: 'Inter-UI-SemiBold', fontSize: 14, color: Colors.White, }, @@ -127,16 +120,15 @@ const channelPageStyle = StyleSheet.create({ marginBottom: 24, }, aboutScrollContent: { - paddingTop: 52, padding: 24, }, aboutTitle: { - fontFamily: 'Inter-SemiBold', + fontFamily: 'Inter-UI-SemiBold', fontSize: 16, lineHeight: 24, }, aboutText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 16, lineHeight: 24, }, @@ -147,51 +139,13 @@ const channelPageStyle = StyleSheet.create({ position: 'absolute', overflow: 'hidden', left: 24, - bottom: -24, + bottom: -40, zIndex: 100, - alignItems: 'center', - justifyContent: 'center', }, avatarImage: { width: '100%', height: '100%', }, - listHeader: { - marginTop: 16, - marginBottom: 8, - marginLeft: 16, - marginRight: 16, - }, - claimList: { - flex: 1, - }, - claimListContent: { - paddingTop: 16, - }, - actionButton: { - backgroundColor: Colors.White, - }, - deleteButton: { - marginLeft: 8, - }, - shareButton: { - marginLeft: 8, - marginRight: 8, - }, - tipButton: { - marginRight: 8, - }, - followerCount: { - fontFamily: 'Inter-Regular', - fontSize: 12, - color: Colors.White, - marginTop: 2, - padding: 2, - flexWrap: 'wrap', - }, - followerCountBg: { - backgroundColor: '#000000aa', - }, }); export default channelPageStyle; diff --git a/src/styles/channelSelector.js b/src/styles/channelSelector.js index d3a4ef3..3186a16 100644 --- a/src/styles/channelSelector.js +++ b/src/styles/channelSelector.js @@ -6,48 +6,34 @@ const channelSelectorStyle = StyleSheet.create({ flex: 1, }, channelPicker: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 16, height: 52, width: '100%', }, - channelPickerItem: { - fontFamily: 'Inter-Regular', - fontSize: 16, - }, bidRow: { flex: 1, flexDirection: 'row', alignItems: 'center', }, label: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 16, }, - balance: { - alignItems: 'center', - flexDirection: 'row', - marginLeft: 24, - }, - balanceText: { - fontFamily: 'Inter-SemiBold', - fontSize: 14, - marginLeft: 4, - }, channelNameInput: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 16, paddingLeft: 20, }, bidAmountInput: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 16, marginLeft: 16, textAlign: 'right', width: 80, }, helpText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 12, }, createChannelContainer: { @@ -59,7 +45,7 @@ const channelSelectorStyle = StyleSheet.create({ position: 'absolute', left: 4, top: 13, - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 16, }, buttonContainer: { @@ -79,12 +65,6 @@ const channelSelectorStyle = StyleSheet.create({ createButton: { backgroundColor: Colors.NextLbryGreen, }, - inlineError: { - fontFamily: 'Inter-Regular', - fontSize: 12, - color: Colors.Red, - marginTop: 2, - }, }); export default channelSelectorStyle; diff --git a/src/styles/claimList.js b/src/styles/claimList.js index 8551492..5ab9514 100644 --- a/src/styles/claimList.js +++ b/src/styles/claimList.js @@ -11,13 +11,6 @@ const claimListStyle = StyleSheet.create({ verticalScrollContainer: { flex: 1, }, - noContentText: { - color: Colors.DescriptionGrey, - fontFamily: 'Inter-Regular', - fontSize: 14, - margin: 16, - textAlign: 'center', - }, verticalScrollPadding: { paddingBottom: 16, }, @@ -25,10 +18,10 @@ const claimListStyle = StyleSheet.create({ flex: 1, flexDirection: 'row', justifyContent: 'space-between', - marginLeft: 16, - marginRight: 16, - marginTop: 8, - marginBottom: 12, + marginLeft: 8, + marginRight: 8, + marginTop: 4, + marginBottom: 4, }, verticalLoading: { width: '100%', diff --git a/src/styles/colors.js b/src/styles/colors.js index 2eb3e68..10ca801 100644 --- a/src/styles/colors.js +++ b/src/styles/colors.js @@ -10,9 +10,7 @@ const Colors = { BrighterLbryGreen: '#40b887', NextLbryGreen: '#38d9a9', TagGreen: '#e3f6f1', - TagGrape: '#da77f255', LightGrey: '#cccccc', - ActionGrey: '#aaaaaa', LighterGrey: '#e5e5e5', Orange: '#ffbb00', Red: '#ff0000', @@ -20,13 +18,10 @@ const Colors = { VeryLightGrey: '#f1f1f1', White: '#ffffff', UriDescBlue: '#3971db', - RewardDriverBlue: '#2196f3', StatsAudio: '#f6a637', StatsImage: '#ff4a7d', StatsOther: '#26bcf7', - - ThumbnailPlaceholder: '#d5d5d5', }; export default Colors; diff --git a/src/styles/discover.js b/src/styles/discover.js index 34f0d12..46d2301 100644 --- a/src/styles/discover.js +++ b/src/styles/discover.js @@ -22,45 +22,33 @@ const discoverStyle = StyleSheet.create({ flex: 1, backgroundColor: Colors.PageBackground, }, - drawerContentArea: { - flex: 1, - backgroundColor: Colors.White, - }, drawerContentContainer: { flex: 1, }, scrollContainer: { flex: 1, }, - listHeader: { - marginBottom: 8, - marginLeft: 16, - marginRight: 16, - }, titleRow: { flexDirection: 'row', marginTop: 76, marginBottom: 8, alignItems: 'center', justifyContent: 'space-between', + marginLeft: 16, + marginRight: 16, }, - pickerRow: { - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'space-between', - marginBottom: 8, - }, - leftPickerRow: { + rightTitleRow: { flexDirection: 'row', alignItems: 'center', }, pageTitle: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 24, }, customizeLink: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 14, + marginRight: 48, }, trendingContainer: { flex: 1, @@ -74,7 +62,7 @@ const discoverStyle = StyleSheet.create({ flexDirection: 'row', }, title: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 20, textAlign: 'center', marginLeft: 10, @@ -88,27 +76,8 @@ const discoverStyle = StyleSheet.create({ marginTop: 6, marginBottom: 6, }, - footer: { - marginTop: 12, - marginLeft: 16, - marginRight: 16, - marginBottom: 56, - }, - footerTitle: { - fontFamily: 'Inter-Regular', - fontSize: 20, - marginBottom: 10, - }, - footerTags: { - flexDirection: 'row', - flexWrap: 'wrap', - }, - footerTag: { - marginRight: 24, - marginBottom: 12, - }, categoryName: { - fontFamily: 'Inter-SemiBold', + fontFamily: 'Inter-UI-SemiBold', fontSize: 18, color: Colors.Black, }, @@ -127,7 +96,7 @@ const discoverStyle = StyleSheet.create({ justifyContent: 'center', }, moreText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', color: Colors.White, fontSize: 24, }, @@ -142,22 +111,16 @@ const discoverStyle = StyleSheet.create({ justifyContent: 'center', }, fileItemName: { - fontFamily: 'Inter-SemiBold', + fontFamily: 'Inter-UI-SemiBold', marginTop: 8, fontSize: 14, }, channelName: { - fontFamily: 'Inter-SemiBold', + fontFamily: 'Inter-UI-SemiBold', fontSize: 12, marginTop: 4, color: Colors.LbryGreen, }, - anonChannelName: { - fontFamily: 'Inter-SemiBold', - fontSize: 12, - marginTop: 4, - color: Colors.DescriptionGrey, - }, downloadedIcon: { position: 'absolute', right: 8, @@ -166,8 +129,6 @@ const discoverStyle = StyleSheet.create({ filePriceContainer: { backgroundColor: Colors.NextLbryGreen, justifyContent: 'center', - alignItems: 'center', - flexDirection: 'row', position: 'absolute', right: 8, top: 8, @@ -176,14 +137,18 @@ const discoverStyle = StyleSheet.create({ borderRadius: 4, }, filePriceText: { - fontFamily: 'Inter-Bold', + fontFamily: 'Inter-UI-Bold', fontSize: 12, textAlign: 'center', color: '#0c604b', }, - filePriceIcon: { - marginRight: 2, - color: '#0c604b', + drawerMenuButton: { + height: '100%', + justifyContent: 'center', + }, + drawerHamburger: { + marginLeft: 16, + marginRight: 16, }, rightHeaderIcon: { marginRight: 16, @@ -198,14 +163,14 @@ const discoverStyle = StyleSheet.create({ position: 'absolute', left: 0, top: 0, - right: 0, - bottom: 0, + width: '100%', + height: '100%', }, overlayText: { color: Colors.White, fontSize: 14, textAlign: 'center', - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', }, rewardTitleContainer: { alignItems: 'center', @@ -213,7 +178,7 @@ const discoverStyle = StyleSheet.create({ justifyContent: 'space-between', }, rewardIcon: { - color: Colors.NextLbryGreen, + color: Colors.Red, flex: 0.1, textAlign: 'right', marginTop: 6, @@ -222,11 +187,11 @@ const discoverStyle = StyleSheet.create({ flex: 0.9, }, menuText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 16, }, titleText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', }, detailsRow: { flexDirection: 'row', @@ -236,7 +201,7 @@ const discoverStyle = StyleSheet.create({ marginTop: 2, }, dateTimeText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 12, color: Colors.DescriptionGrey, }, @@ -259,7 +224,7 @@ const discoverStyle = StyleSheet.create({ flex: 1, }, tagPageTitle: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 24, }, tagPageClaimList: { @@ -276,145 +241,20 @@ const discoverStyle = StyleSheet.create({ tagSortBy: { flexDirection: 'row', alignItems: 'center', - marginRight: 24, - }, - allTagSortBy: { - flexDirection: 'row', - alignItems: 'center', - marginRight: 8, + marginRight: 4, }, tagTime: { flexDirection: 'row', alignItems: 'center', }, tagSortText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 14, marginRight: 4, }, tagSortIcon: { marginTop: -6, }, - pickerLabel: { - fontFamily: 'Inter-Regular', - fontSize: 14, - color: Colors.DescriptionGrey, - marginRight: 6, - }, - menuScrollContent: {}, - menuGroup: { - marginTop: 8, - marginBottom: 8, - }, - menuGroupName: { - fontFamily: 'Inter-Regular', - fontSize: 12, - color: Colors.DescriptionGrey, - textTransform: 'uppercase', - marginBottom: 4, - marginLeft: 16, - marginRight: 16, - }, - menuItemTouchArea: { - flex: 1, - flexDirection: 'row', - paddingTop: 12, - paddingBottom: 12, - paddingLeft: 16, - paddingRight: 16, - alignItems: 'center', - }, - menuItemTouchAreaFocused: { - backgroundColor: Colors.VeryLightGrey, - }, - menuItemFocused: { - color: Colors.LbryGreen, - }, - menuItemIcon: { - alignItems: 'center', - justifyContent: 'center', - width: 24, - }, - menuItem: { - marginLeft: 8, - fontFamily: 'Inter-Regular', - fontSize: 16, - }, - signInContainer: { - backgroundColor: Colors.LbryGreen, - height: 140, - padding: 16, - }, - signInButton: { - backgroundColor: Colors.White, - alignSelf: 'flex-start', - position: 'absolute', - bottom: 16, - left: 16, - }, - signedInEmail: { - fontFamily: 'Inter-SemiBold', - fontSize: 15, - color: Colors.White, - }, - signedInAvatar: { - backgroundColor: Colors.NextLbryGreen, - width: 80, - height: 80, - marginBottom: 12, - borderRadius: 160, - overflow: 'hidden', - alignItems: 'center', - justifyContent: 'center', - }, - signedInAvatarImage: { - width: '100%', - height: '100%', - }, - signInMenuItem: { - paddingTop: 16, - paddingBottom: 12, - paddingLeft: 16, - paddingRight: 16, - marginBottom: 6, - borderBottomWidth: 1, - }, - signInMenuItemBorder: { - borderBottomColor: Colors.VeryLightGrey, - }, - signInMenuItemButton: { - backgroundColor: Colors.LbryGreen, - borderBottomColor: Colors.LbryGreen, - }, - signInMenuItemText: { - color: Colors.DescriptionGrey, - fontFamily: 'Inter-SemiBold', - fontSize: 14, - textAlign: 'center', - }, - signInMenuItemButtonText: { - color: Colors.White, - fontFamily: 'Inter-SemiBold', - fontSize: 14, - textAlign: 'center', - }, - sdkLoading: { - position: 'absolute', - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'center', - bottom: 0, - left: 0, - right: 0, - padding: 8, - backgroundColor: Colors.LbryGreen, - }, - sdkLoadingText: { - fontFamily: 'Inter-Regular', - fontSize: 14, - color: Colors.White, - marginLeft: 8, - }, }); export default discoverStyle; diff --git a/src/styles/downloads.js b/src/styles/downloads.js index 8337dc0..70a0204 100644 --- a/src/styles/downloads.js +++ b/src/styles/downloads.js @@ -24,13 +24,14 @@ const downloadsStyle = StyleSheet.create({ paddingLeft: 16, paddingRight: 16, marginTop: 16, + marginBottom: 60, }, scrollPadding: { marginTop: -16, paddingBottom: 16, }, noDownloadsText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 16, lineHeight: 24, marginLeft: 16, diff --git a/src/styles/emptyState.js b/src/styles/emptyState.js deleted file mode 100644 index 8b487e5..0000000 --- a/src/styles/emptyState.js +++ /dev/null @@ -1,40 +0,0 @@ -import { StyleSheet } from 'react-native'; -import Colors from './colors'; - -const emptyStateStyle = StyleSheet.create({ - container: { - position: 'absolute', - left: 0, - right: 0, - bottom: 0, - paddingLeft: 24, - paddingRight: 24, - alignItems: 'center', - justifyContent: 'center', - zIndex: 99, - }, - outerContainer: { - top: 60, - }, - innerContainer: { - top: 0, - }, - button: { - backgroundColor: Colors.LbryGreen, - fontSize: 18, - }, - image: { - width: 128, - height: 170, - }, - message: { - marginTop: 24, - textAlign: 'center', - fontFamily: 'Inter-Regular', - fontSize: 18, - lineHeight: 28, - marginBottom: 24, - }, -}); - -export default emptyStateStyle; diff --git a/src/styles/fileDownloadButton.js b/src/styles/fileDownloadButton.js index 2ec132e..7485b9f 100644 --- a/src/styles/fileDownloadButton.js +++ b/src/styles/fileDownloadButton.js @@ -11,7 +11,7 @@ const fileDownloadButtonStyle = StyleSheet.create({ backgroundColor: Colors.LbryGreen, }, text: { - fontFamily: 'Inter-Medium', + fontFamily: 'Inter-UI-Medium', color: Colors.White, fontSize: 14, textAlign: 'center', diff --git a/src/styles/fileItemMedia.js b/src/styles/fileItemMedia.js index 4940056..36a5e46 100644 --- a/src/styles/fileItemMedia.js +++ b/src/styles/fileItemMedia.js @@ -10,11 +10,44 @@ const fileItemMediaStyle = StyleSheet.create({ alignItems: 'center', }, autothumbText: { - fontFamily: 'Inter-SemiBold', + fontFamily: 'Inter-UI-SemiBold', textAlign: 'center', color: Colors.White, fontSize: 40, }, + autothumbPurple: { + backgroundColor: '#9c27b0', + }, + autothumbRed: { + backgroundColor: '#e53935', + }, + autothumbPink: { + backgroundColor: '#e91e63', + }, + autothumbIndigo: { + backgroundColor: '#3f51b5', + }, + autothumbBlue: { + backgroundColor: '#2196f3', + }, + autothumbLightBlue: { + backgroundColor: '#039be5', + }, + autothumbCyan: { + backgroundColor: '#00acc1', + }, + autothumbTeal: { + backgroundColor: '#009688', + }, + autothumbGreen: { + backgroundColor: '#43a047', + }, + autothumbYellow: { + backgroundColor: '#ffeb3b', + }, + autothumbOrange: { + backgroundColor: '#ffa726', + }, resolving: { alignItems: 'center', flex: 1, @@ -22,33 +55,16 @@ const fileItemMediaStyle = StyleSheet.create({ }, text: { color: '#ffffff', - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 16, marginTop: 8, }, - image: { - width: '100%', - height: '100%', - }, thumbnail: { flex: 1, width: '100%', height: 200, shadowColor: 'transparent', }, - duration: { - backgroundColor: Colors.Black, - position: 'absolute', - right: 4, - bottom: 4, - paddingLeft: 2, - paddingRight: 2, - }, - durationText: { - fontFamily: 'Inter-SemiBold', - fontSize: 12, - color: Colors.White, - }, }); export default fileItemMediaStyle; diff --git a/src/styles/fileList.js b/src/styles/fileList.js index 0ac8fd1..4006569 100644 --- a/src/styles/fileList.js +++ b/src/styles/fileList.js @@ -22,70 +22,37 @@ const fileListStyle = StyleSheet.create({ flex: 1, }, featuredUri: { - fontFamily: 'Inter-SemiBold', + fontFamily: 'Inter-UI-SemiBold', fontSize: 24, color: Colors.White, }, featuredTitle: { - fontFamily: 'Inter-SemiBold', - fontSize: screenWidthPixels <= 720 ? 11 : 16, + fontFamily: 'Inter-UI-SemiBold', + fontSize: screenWidthPixels <= 720 ? 12 : 16, color: Colors.White, }, thumbnail: { - backgroundColor: Colors.ThumbnailPlaceholder, width: thumbnailWidth, height: thumbnailHeight, marginRight: screenWidthPixels <= 720 ? 10 : 12, alignItems: 'center', justifyContent: 'center', }, - channelThumbnailView: { - width: thumbnailWidth, - height: thumbnailHeight, - marginRight: screenWidthPixels <= 720 ? 10 : 12, - alignItems: 'center', - justifyContent: 'center', - }, - channelThumbnailContainer: { - width: thumbnailHeight, // maintain same width and height - height: thumbnailHeight, - borderRadius: 140, - overflow: 'hidden', - alignItems: 'center', - justifyContent: 'center', - }, - channelThumbnail: { - width: '100%', - height: '100%', - }, - selectedOverlay: { - position: 'absolute', - left: 0, - top: 0, - width: thumbnailWidth, - height: thumbnailHeight, - alignItems: 'center', - justifyContent: 'center', - backgroundColor: '#000000aa', - }, title: { - fontFamily: 'Inter-SemiBold', - fontSize: screenWidthPixels <= 720 ? 11 : 14, + fontFamily: 'Inter-UI-SemiBold', + fontSize: screenWidthPixels <= 720 ? 12 : 14, }, uri: { - fontFamily: 'Inter-SemiBold', - fontSize: screenWidthPixels <= 720 ? 11 : 14, + fontFamily: 'Inter-UI-SemiBold', + fontSize: screenWidthPixels <= 720 ? 12 : 14, marginBottom: 8, }, publisher: { - fontFamily: 'Inter-SemiBold', - fontSize: screenWidthPixels <= 720 ? 10 : 12, + fontFamily: 'Inter-UI-SemiBold', + fontSize: screenWidthPixels <= 720 ? 11 : 12, marginTop: screenWidthPixels <= 720 ? 1 : 3, color: Colors.LbryGreen, }, - channelContainer: { - alignItems: 'center', - }, loading: { position: 'absolute', }, @@ -95,15 +62,15 @@ const fileListStyle = StyleSheet.create({ justifyContent: 'space-between', }, infoText: { - fontFamily: 'Inter-Regular', - fontSize: screenWidthPixels <= 720 ? 10 : 12, + fontFamily: 'Inter-UI-Regular', + fontSize: screenWidthPixels <= 720 ? 11 : 12, color: Colors.ChannelGrey, }, downloadInfo: { marginTop: 2, }, progress: { - marginTop: screenWidthPixels <= 720 ? 1 : 4, + marginTop: screenWidthPixels <= 720 ? 2 : 4, }, progressCompleted: { backgroundColor: Colors.LbryGreen, @@ -117,11 +84,6 @@ const fileListStyle = StyleSheet.create({ top: 8, left: 8, }, - featuredDownloadedIcon: { - position: 'absolute', - left: 16, - top: 16, - }, fileItem: { marginLeft: 24, marginRight: 24, @@ -133,53 +95,6 @@ const fileListStyle = StyleSheet.create({ alignItems: 'center', justifyContent: 'center', }, - titleContainer: { - flexDirection: 'row', - marginRight: 16, - }, - rewardIcon: { - color: Colors.NextLbryGreen, - textAlign: 'right', - marginLeft: 4, - marginTop: 4, - }, - filePriceContainer: { - backgroundColor: Colors.NextLbryGreen, - justifyContent: 'center', - alignItems: 'center', - flexDirection: 'row', - position: 'absolute', - left: thumbnailWidth - 60, - top: 4, - width: 56, - height: 24, - borderRadius: 4, - }, - filePriceText: { - fontFamily: 'Inter-Bold', - fontSize: 12, - textAlign: 'center', - color: '#0c604b', - }, - filePriceIcon: { - marginRight: 2, - color: '#0c604b', - }, - repostChannelName: { - color: Colors.DescriptionGrey, - fontFamily: 'Inter-Regular', - fontSize: 14, - }, - repostIcon: { - color: Colors.DescriptionGrey, - marginRight: 4, - }, - repostInfo: { - marginLeft: 16, - marginRight: 16, - alignItems: 'center', - flexDirection: 'row', - }, }); export default fileListStyle; diff --git a/src/styles/filePage.js b/src/styles/filePage.js index 60ad4d5..ff01fa1 100644 --- a/src/styles/filePage.js +++ b/src/styles/filePage.js @@ -38,11 +38,11 @@ const filePageStyle = StyleSheet.create({ marginBottom: -17, }, emptyClaimText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', textAlign: 'center', fontSize: 20, - marginLeft: 24, - marginRight: 24, + marginLeft: 16, + marginRight: 16, }, scrollContainer: { flex: 1, @@ -54,7 +54,7 @@ const filePageStyle = StyleSheet.create({ flex: 1, }, title: { - fontFamily: 'Inter-Bold', + fontFamily: 'Inter-UI-Bold', fontSize: 16, flex: 18, alignSelf: 'flex-start', @@ -65,6 +65,7 @@ const filePageStyle = StyleSheet.create({ titleRow: { flexDirection: 'row', marginTop: 12, + marginBottom: 2, marginLeft: 12, marginRight: 12, alignItems: 'center', @@ -88,17 +89,17 @@ const filePageStyle = StyleSheet.create({ marginTop: 6, }, channelName: { - fontFamily: 'Inter-SemiBold', + fontFamily: 'Inter-UI-SemiBold', fontSize: 14, color: Colors.LbryGreen, }, anonChannelName: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 14, color: Colors.DescriptionGrey, }, publishDateText: { - fontFamily: 'Inter-SemiBold', + fontFamily: 'Inter-UI-SemiBold', fontSize: 12, color: Colors.DescriptionGrey, }, @@ -107,13 +108,12 @@ const filePageStyle = StyleSheet.create({ }, description: { color: Colors.DescriptionGrey, - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 13, lineHeight: 18, marginTop: -8, marginLeft: 12, marginRight: 12, - marginBottom: 16, }, thumbnail: { width: screenWidth, @@ -170,8 +170,6 @@ const filePageStyle = StyleSheet.create({ filePriceContainer: { backgroundColor: Colors.NextLbryGreen, justifyContent: 'center', - alignItems: 'center', - flexDirection: 'row', position: 'absolute', right: 16, top: 16, @@ -180,14 +178,11 @@ const filePageStyle = StyleSheet.create({ borderRadius: 4, }, filePriceText: { - fontFamily: 'Inter-Bold', + fontFamily: 'Inter-UI-Bold', fontSize: 12, textAlign: 'center', color: '#0c604b', }, - filePriceIcon: { - marginRight: 2, - }, actions: { flexDirection: 'row', justifyContent: 'space-between', @@ -199,10 +194,6 @@ const filePageStyle = StyleSheet.create({ }, fileActions: { alignSelf: 'flex-end', - flexDirection: 'row', - }, - editButton: { - marginRight: 8, }, socialActions: { alignSelf: 'flex-start', @@ -235,19 +226,19 @@ const filePageStyle = StyleSheet.create({ paddingRight: 24, }, dmcaText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 18, lineHeight: 24, }, dmcaLink: { color: Colors.LbryGreen, - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 18, lineHeight: 24, marginTop: 24, }, infoText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 20, textAlign: 'center', marginLeft: 10, @@ -282,7 +273,6 @@ const filePageStyle = StyleSheet.create({ amountRow: { flexDirection: 'row', flex: 0.75, - alignItems: 'center', }, button: { backgroundColor: Colors.LbryGreen, @@ -294,18 +284,19 @@ const filePageStyle = StyleSheet.create({ marginBottom: 14, }, input: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 14, }, tipAmountInput: { alignSelf: 'flex-start', - textAlign: 'right', width: 80, fontSize: 16, letterSpacing: 1, }, currency: { + alignSelf: 'flex-start', fontSize: 12, + marginTop: 15, marginLeft: 4, }, descriptionToggle: { @@ -316,7 +307,7 @@ const filePageStyle = StyleSheet.create({ marginTop: -8, }, text: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 16, lineHeight: 24, }, @@ -326,22 +317,20 @@ const filePageStyle = StyleSheet.create({ saveFileButton: { marginRight: 8, }, - reportButton: { - marginRight: 8, - }, tagContainer: { marginLeft: 12, marginRight: 12, + marginTop: 16, marginBottom: 16, flexDirection: 'row', }, tagTitle: { - fontFamily: 'Inter-SemiBold', + fontFamily: 'Inter-UI-SemiBold', flex: 0.2, marginTop: 4, }, tagList: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', flex: 0.8, flexDirection: 'row', flexWrap: 'wrap', @@ -351,26 +340,21 @@ const filePageStyle = StyleSheet.create({ }, rewardDriverCard: { alignItems: 'center', - backgroundColor: Colors.RewardDriverBlue, + backgroundColor: Colors.BrighterLbryGreen, flexDirection: 'row', paddingLeft: 16, paddingRight: 16, paddingTop: 12, paddingBottom: 12, }, - rewardDriverIcon: { - color: Colors.White, - marginRight: 8, - }, rewardDriverText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', color: Colors.White, fontSize: 14, }, rewardIcon: { - color: Colors.NextLbryGreen, - marginTop: -8, - marginLeft: 8, + color: Colors.White, + marginRight: 8, }, backButton: { position: 'absolute', @@ -384,90 +368,6 @@ const filePageStyle = StyleSheet.create({ backButtonIcon: { color: Colors.White, }, - sharedLargeButton: { - alignItems: 'center', - justifyContent: 'center', - flex: 0.2, - }, - innerLargeButton: { - alignItems: 'center', - justifyContent: 'center', - }, - largeButton: { - alignItems: 'center', - justifyContent: 'center', - flex: 0.2, - }, - largeButtonIcon: { - color: Colors.ActionGrey, - }, - largeButtonText: { - color: Colors.ActionGrey, - fontFamily: 'Inter-Regular', - fontSize: 12, - marginTop: 4, - }, - largeButtonsRow: { - flexDirection: 'row', - alignItems: 'center', - marginLeft: 16, - marginRight: 16, - marginTop: 12, - marginBottom: 12, - }, - unsupportedContent: { - position: 'absolute', - left: 0, - right: 0, - top: 0, - bottom: 16, - padding: 24, - flexDirection: 'row', - alignItems: 'center', - backgroundColor: Colors.White, - }, - unspportedContentTextContainer: { - flex: 1, - }, - unsupportedContentFilename: { - color: Colors.LbryGreen, - fontFamily: 'Inter-SemiBold', - fontSize: 16, - }, - unsupportedContentImage: { - width: 64, - height: 80, - marginRight: 24, - }, - unsupportedContentTitle: { - fontFamily: 'Inter-Regular', - fontSize: 20, - }, - unsupportedContentText: { - fontFamily: 'Inter-Regular', - fontSize: 16, - marginTop: 4, - }, - relatedLoading: { - marginTop: 16, - }, - viewCount: { - fontFamily: 'Inter-Regular', - fontSize: 12, - color: Colors.DescriptionGrey, - marginLeft: 12, - marginRight: 12, - }, - balance: { - alignItems: 'center', - flexDirection: 'row', - marginLeft: 24, - }, - balanceText: { - fontFamily: 'Inter-SemiBold', - fontSize: 14, - marginLeft: 4, - }, }); export default filePageStyle; diff --git a/src/styles/firstRun.js b/src/styles/firstRun.js index d0bd438..d7531fb 100644 --- a/src/styles/firstRun.js +++ b/src/styles/firstRun.js @@ -17,7 +17,7 @@ const firstRunStyle = StyleSheet.create({ backgroundColor: Colors.LbryGreen, }, title: { - fontFamily: 'Inter-SemiBold', + fontFamily: 'Inter-UI-SemiBold', fontSize: 40, marginLeft: 32, marginRight: 32, @@ -25,7 +25,7 @@ const firstRunStyle = StyleSheet.create({ color: Colors.White, }, paragraph: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 18, lineHeight: 24, marginLeft: 32, @@ -34,7 +34,7 @@ const firstRunStyle = StyleSheet.create({ color: Colors.White, }, spacedParagraph: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 18, lineHeight: 28, marginLeft: 32, @@ -43,7 +43,7 @@ const firstRunStyle = StyleSheet.create({ color: Colors.White, }, infoParagraph: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 14, lineHeight: 20, marginLeft: 32, @@ -55,7 +55,7 @@ const firstRunStyle = StyleSheet.create({ marginTop: 36, }, rowParagraph: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 16, lineHeight: 24, color: Colors.White, @@ -67,7 +67,7 @@ const firstRunStyle = StyleSheet.create({ marginRight: 8, }, emailInput: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 24, lineHeight: 24, marginLeft: 32, @@ -76,7 +76,7 @@ const firstRunStyle = StyleSheet.create({ textAlign: 'center', }, passwordInput: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 24, lineHeight: 24, marginLeft: 32, @@ -102,7 +102,7 @@ const firstRunStyle = StyleSheet.create({ actionButton: { backgroundColor: Colors.White, alignSelf: 'center', - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 12, paddingLeft: 16, paddingRight: 16, @@ -114,18 +114,18 @@ const firstRunStyle = StyleSheet.create({ paddingRight: 32, }, buttonText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 18, color: Colors.White, }, smallButtonText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 14, color: Colors.White, marginBottom: -2, }, smallLeftButtonText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 14, color: Colors.White, marginBottom: 6, @@ -153,10 +153,6 @@ const firstRunStyle = StyleSheet.create({ color: Colors.White, fontSize: 16, }, - closeButtonIcon: { - alignSelf: 'center', - color: Colors.White, - }, buttonContainer: { flexDirection: 'row', alignItems: 'center', @@ -182,8 +178,8 @@ const firstRunStyle = StyleSheet.create({ marginBottom: 24, }, passwordWarningText: { - color: Colors.NextLbryGreen, - fontFamily: 'Inter-Regular', + color: Colors.BrightRed, + fontFamily: 'Inter-UI-Regular', fontSize: 16, }, centered: { @@ -213,12 +209,6 @@ const firstRunStyle = StyleSheet.create({ revealIcon: { color: Colors.White, }, - tosLink: { - textDecorationLine: 'underline', - }, - tosParagraph: { - marginTop: 48, - }, }); export default firstRunStyle; diff --git a/src/styles/floatingButton.js b/src/styles/floatingButton.js index 768c97d..b092b17 100644 --- a/src/styles/floatingButton.js +++ b/src/styles/floatingButton.js @@ -13,14 +13,13 @@ const floatingButtonStyle = StyleSheet.create({ container: { zIndex: 100, borderRadius: 24, - padding: 10, - paddingLeft: 16, - paddingRight: 16, + padding: 14, + paddingLeft: 20, + paddingRight: 20, alignItems: 'center', justifyContent: 'center', - flexDirection: 'row', backgroundColor: Colors.LbryGreen, - shadowColor: Colors.Black, + shadowColor: 'black', shadowOpacity: 0.1, shadowRadius: StyleSheet.hairlineWidth, shadowOffset: { @@ -30,10 +29,10 @@ const floatingButtonStyle = StyleSheet.create({ }, pendingContainer: { borderRadius: 24, - padding: 10, - paddingLeft: 12, - paddingRight: 58, - marginRight: -52, + padding: 14, + paddingLeft: 20, + paddingRight: 70, + marginRight: -60, alignItems: 'center', justifyContent: 'center', backgroundColor: Colors.BrighterLbryGreen, @@ -42,21 +41,16 @@ const floatingButtonStyle = StyleSheet.create({ }, text: { color: Colors.White, - fontFamily: 'Inter-SemiBold', - fontSize: 16, + fontFamily: 'Inter-UI-Bold', + fontSize: 18, }, bottomRight: { - right: 0, - bottom: 0, + right: 10, + bottom: 10, }, rewardIcon: { color: Colors.White, - marginRight: 3, - }, - balanceIcon: { - color: Colors.White, - marginRight: 3, - marginTop: -1, + marginRight: 4, }, }); diff --git a/src/styles/invites.js b/src/styles/invites.js deleted file mode 100644 index 3fa7278..0000000 --- a/src/styles/invites.js +++ /dev/null @@ -1,150 +0,0 @@ -import { StyleSheet } from 'react-native'; -import Colors from './colors'; - -const walletStyle = StyleSheet.create({ - container: { - flex: 1, - backgroundColor: Colors.PageBackground, - }, - scrollContainer: { - marginTop: 60, - }, - row: { - flexDirection: 'row', - justifyContent: 'space-between', - alignItems: 'center', - }, - button: { - backgroundColor: Colors.LbryGreen, - alignSelf: 'flex-start', - }, - card: { - backgroundColor: Colors.White, - marginTop: 16, - marginLeft: 16, - marginRight: 16, - padding: 16, - }, - title: { - fontFamily: 'Inter-SemiBold', - fontSize: 20, - marginBottom: 8, - }, - titleRow: { - alignItems: 'center', - flexDirection: 'row', - marginBottom: 8, - justifyContent: 'space-between', - }, - titleCol: { - fontFamily: 'Inter-SemiBold', - fontSize: 20, - }, - text: { - fontFamily: 'Inter-Regular', - fontSize: 14, - }, - link: { - color: Colors.LbryGreen, - fontFamily: 'Inter-Regular', - fontSize: 14, - }, - smallText: { - fontFamily: 'Inter-Regular', - fontSize: 12, - }, - rewardDriverCard: { - alignItems: 'center', - backgroundColor: Colors.RewardDriverBlue, - flexDirection: 'row', - padding: 16, - marginLeft: 16, - marginTop: 16, - marginRight: 16, - }, - rewardDriverIcon: { - color: Colors.White, - marginRight: 8, - }, - rewardDriverText: { - fontFamily: 'Inter-Regular', - color: Colors.White, - fontSize: 14, - }, - subTitle: { - fontFamily: 'Inter-Regular', - fontSize: 14, - marginTop: 12, - marginBottom: 4, - }, - customizeTitle: { - fontFamily: 'Inter-Regular', - fontSize: 14, - marginTop: 12, - }, - inviteLink: { - fontFamily: 'Inter-Regular', - borderWidth: 1, - borderRadius: 16, - borderStyle: 'dashed', - borderColor: '#e1e1e1', - backgroundColor: '#f9f9f9', - paddingTop: 8, - paddingLeft: 8, - paddingRight: 8, - paddingBottom: 6, - width: '88%', - }, - emailInput: { - fontFamily: 'Inter-Regular', - fontSize: 14, - }, - rightRow: { - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'flex-end', - }, - loading: { - marginRight: 8, - }, - lastCard: { - marginBottom: 16, - }, - invitees: { - marginTop: 8, - }, - inviteesHeader: { - flex: 1, - flexDirection: 'row', - alignItems: 'center', - marginBottom: 8, - }, - emailHeader: { - fontFamily: 'Inter-SemiBold', - fontSize: 14, - width: '65%', - }, - rewardHeader: { - fontFamily: 'Inter-SemiBold', - fontSize: 14, - width: '35%', - }, - inviteeItem: { - flex: 1, - flexDirection: 'row', - alignItems: 'center', - marginBottom: 8, - }, - inviteeEmail: { - fontFamily: 'Inter-Regular', - fontSize: 12, - width: '65%', - }, - rewardStatus: { - fontFamily: 'Inter-Regular', - fontSize: 12, - width: '35%', - }, -}); - -export default walletStyle; diff --git a/src/styles/mediaPlayer.js b/src/styles/mediaPlayer.js index 42cdd0e..132024f 100644 --- a/src/styles/mediaPlayer.js +++ b/src/styles/mediaPlayer.js @@ -56,41 +56,13 @@ const mediaPlayerStyle = StyleSheet.create({ height: '100%', }, playerControlsContainer: { - backgroundColor: '#00000040', + backgroundColor: '#00000020', flex: 1, alignItems: 'center', justifyContent: 'center', }, - midControls: { - flex: 1, - flexDirection: 'row', - height: 64, - position: 'absolute', - alignItems: 'center', - justifyContent: 'center', - }, - midControlText: { - fontFamily: 'Inter-Regular', - fontSize: 10, - position: 'absolute', - top: 10, - color: Colors.White, - }, - leftMidControlText: { - left: -6, - }, - rightMidControlText: { - right: -6, - }, - rewind10: { - marginRight: 48, - alignItems: 'center', - }, - forward10: { - marginLeft: 48, - alignItems: 'center', - }, playPauseButton: { + position: 'absolute', width: 64, height: 64, alignItems: 'center', @@ -106,7 +78,7 @@ const mediaPlayerStyle = StyleSheet.create({ bottom: 14, }, elapsedDuration: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', position: 'absolute', left: 8, bottom: 24, @@ -114,7 +86,7 @@ const mediaPlayerStyle = StyleSheet.create({ color: '#ffffff', }, totalDuration: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', position: 'absolute', right: 48, bottom: 24, @@ -124,17 +96,12 @@ const mediaPlayerStyle = StyleSheet.create({ seekerCircle: { borderRadius: 12, position: 'relative', + top: 14, left: 15, height: 12, width: 12, backgroundColor: Colors.LbryGreen, }, - seekerCircleTop: { - top: 14, - }, - seekerCircleTopFs: { - top: 15, - }, seekerHandle: { backgroundColor: 'transparent', position: 'absolute', diff --git a/src/styles/modal.js b/src/styles/modal.js deleted file mode 100644 index 2667167..0000000 --- a/src/styles/modal.js +++ /dev/null @@ -1,60 +0,0 @@ -import { StyleSheet } from 'react-native'; -import Colors from './colors'; - -const modalPickerStyle = StyleSheet.create({ - overlay: { - backgroundColor: '#00000055', - flex: 1, - position: 'absolute', - left: 0, - right: 0, - top: 0, - bottom: 0, - zIndex: 300, - }, - overlayTouchArea: { - position: 'absolute', - left: 0, - right: 0, - top: 0, - bottom: 0, - }, - container: { - position: 'absolute', - left: 8, - right: 8, - bottom: 8, - borderRadius: 8, - backgroundColor: Colors.White, - overflow: 'hidden', - }, - paddedContatiner: { - padding: 12, - }, - buttons: { - marginTop: 16, - left: 8, - bottom: 8, - position: 'absolute', - }, - wideButtons: { - marginTop: 16, - left: 8, - bottom: 8, - right: 8, - position: 'absolute', - }, - doneButton: { - alignSelf: 'flex-start', - backgroundColor: Colors.LbryGreen, - paddingLeft: 16, - paddingRight: 16, - }, - wideDoneButton: { - backgroundColor: Colors.LbryGreen, - paddingLeft: 16, - paddingRight: 16, - }, -}); - -export default modalPickerStyle; diff --git a/src/styles/modalPicker.js b/src/styles/modalPicker.js index 103f1e1..41a615a 100644 --- a/src/styles/modalPicker.js +++ b/src/styles/modalPicker.js @@ -29,7 +29,7 @@ const modalPickerStyle = StyleSheet.create({ padding: 12, }, title: { - fontFamily: 'Inter-SemiBold', + fontFamily: 'Inter-UI-SemiBold', fontSize: 12, marginTop: 4, textTransform: 'uppercase', @@ -54,7 +54,7 @@ const modalPickerStyle = StyleSheet.create({ itemLabel: { marginLeft: 8, alignSelf: 'flex-start', - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 16, }, itemSelected: { diff --git a/src/styles/modalRepost.js b/src/styles/modalRepost.js deleted file mode 100644 index 8854a49..0000000 --- a/src/styles/modalRepost.js +++ /dev/null @@ -1,93 +0,0 @@ -import { StyleSheet } from 'react-native'; -import Colors from './colors'; - -const modalRepostStyle = StyleSheet.create({ - container: { - padding: 16, - }, - title: { - fontFamily: 'Inter-Regular', - fontSize: 24, - marginBottom: 8, - }, - row: { - flexDirection: 'row', - flex: 1, - }, - amountRow: { - flexDirection: 'row', - alignItems: 'center', - marginRight: 24, - }, - depositAmountInput: { - fontFamily: 'Inter-Regular', - fontSize: 14, - alignSelf: 'flex-start', - textAlign: 'right', - width: 80, - letterSpacing: 1, - }, - currency: { - fontFamily: 'Inter-Regular', - fontSize: 12, - marginLeft: 4, - }, - buttonRow: { - alignItems: 'center', - flexDirection: 'row', - justifyContent: 'space-between', - marginTop: 16, - }, - button: { - backgroundColor: Colors.LbryGreen, - }, - cancelLink: { - color: Colors.Grey, - }, - advancedLink: { - color: Colors.Grey, - marginRight: 16, - }, - balance: { - alignItems: 'center', - flexDirection: 'row', - marginLeft: 24, - }, - balanceText: { - fontFamily: 'Inter-SemiBold', - fontSize: 14, - marginLeft: 4, - }, - info: { - marginTop: 4, - }, - infoText: { - fontFamily: 'Inter-Regular', - fontSize: 14, - color: Colors.DescriptionGrey, - }, - learnMoreLink: { - fontFamily: 'Inter-Regular', - fontSize: 14, - color: Colors.LbryGreen, - }, - label: { - fontFamily: 'Inter-Regular', - fontSize: 14, - marginTop: 8, - }, - nameRow: { - flexDirection: 'row', - alignItems: 'center', - }, - rightButtonRow: { - flexDirection: 'row', - alignItems: 'center', - }, - input: { - fontFamily: 'Inter-Regular', - fontSize: 14, - }, -}); - -export default modalRepostStyle; diff --git a/src/styles/modalTagSelector.js b/src/styles/modalTagSelector.js index 0ba147f..a341c95 100644 --- a/src/styles/modalTagSelector.js +++ b/src/styles/modalTagSelector.js @@ -42,7 +42,7 @@ const modalTagSelectorStyle = StyleSheet.create({ marginBottom: 12, }, title: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 24, }, buttons: { diff --git a/src/styles/modalTip.js b/src/styles/modalTip.js deleted file mode 100644 index a0dedf9..0000000 --- a/src/styles/modalTip.js +++ /dev/null @@ -1,71 +0,0 @@ -import { StyleSheet } from 'react-native'; -import Colors from './colors'; - -const modalTipStyle = StyleSheet.create({ - container: { - padding: 16, - }, - title: { - fontFamily: 'Inter-Regular', - fontSize: 24, - }, - row: { - flexDirection: 'row', - flex: 1, - }, - amountRow: { - flexDirection: 'row', - alignItems: 'center', - marginRight: 24, - }, - tipAmountInput: { - fontFamily: 'Inter-Regular', - fontSize: 14, - alignSelf: 'flex-start', - textAlign: 'right', - width: 80, - letterSpacing: 1, - }, - currency: { - fontFamily: 'Inter-Regular', - fontSize: 12, - marginLeft: 4, - }, - buttonRow: { - alignItems: 'center', - flexDirection: 'row', - justifyContent: 'space-between', - marginTop: 16, - }, - button: { - backgroundColor: Colors.LbryGreen, - }, - cancelTipLink: { - color: Colors.Grey, - }, - balance: { - alignItems: 'center', - flexDirection: 'row', - marginLeft: 24, - }, - balanceText: { - fontFamily: 'Inter-SemiBold', - fontSize: 14, - marginLeft: 4, - }, - info: { - marginTop: 4, - }, - infoText: { - fontFamily: 'Inter-Regular', - fontSize: 14, - color: Colors.DescriptionGrey, - }, - learnMoreLink: { - fontFamily: 'Inter-Regular', - fontSize: 14, - color: Colors.LbryGreen, - }, -}); - -export default modalTipStyle; diff --git a/src/styles/pageHeader.js b/src/styles/pageHeader.js index daccac3..5833d87 100644 --- a/src/styles/pageHeader.js +++ b/src/styles/pageHeader.js @@ -42,7 +42,7 @@ const pageHeaderStyle = StyleSheet.create({ flexDirection: 'row', }, titleText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: Platform.OS === 'ios' ? 17 : 20, fontWeight: Platform.OS === 'ios' ? '700' : '500', color: 'rgba(0, 0, 0, .9)', diff --git a/src/styles/publish.js b/src/styles/publish.js index 459ff99..f5371e0 100644 --- a/src/styles/publish.js +++ b/src/styles/publish.js @@ -1,9 +1,6 @@ -import { Dimensions, StyleSheet } from 'react-native'; +import { StyleSheet } from 'react-native'; import Colors from './colors'; -const screenDimension = Dimensions.get('window'); -const screenWidth = screenDimension.width; - const publishStyle = StyleSheet.create({ container: { flex: 1, @@ -19,11 +16,11 @@ const publishStyle = StyleSheet.create({ flex: 1, }, galleryGridImage: { - width: '100%', + width: 134, height: 90, }, inputText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 16, }, card: { @@ -57,7 +54,7 @@ const publishStyle = StyleSheet.create({ alignSelf: 'flex-end', }, cardTitle: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 20, marginBottom: 8, }, @@ -67,29 +64,25 @@ const publishStyle = StyleSheet.create({ overflow: 'hidden', }, record: { + backgroundColor: 'transparent', flex: 0.5, justifyContent: 'center', alignItems: 'center', }, - actionBackground: { - backgroundColor: Colors.Black, - }, - transparentBackground: { - backgroundColor: 'transparent', - }, subActions: { flex: 0.5, borderLeftWidth: 2, - borderLeftColor: Colors.DarkGrey, + borderLeftColor: Colors.DarkerGrey, }, actionText: { color: Colors.White, - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 14, marginTop: 8, }, photo: { - height: 120, + backgroundColor: 'transparent', + height: 240, justifyContent: 'center', alignItems: 'center', }, @@ -97,7 +90,7 @@ const publishStyle = StyleSheet.create({ backgroundColor: Colors.Black, height: 120, borderTopWidth: 2, - borderTopColor: Colors.DarkGrey, + borderTopColor: Colors.DarkerGrey, justifyContent: 'center', alignItems: 'center', }, @@ -119,12 +112,11 @@ const publishStyle = StyleSheet.create({ }, priceInput: { width: 80, - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 16, - textAlign: 'right', }, currency: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', }, cardRow: { flex: 1, @@ -151,24 +143,13 @@ const publishStyle = StyleSheet.create({ flex: 1, alignItems: 'center', justifyContent: 'center', - flexDirection: 'row', - }, - loadingText: { - color: Colors.White, - fontFamily: 'Inter-Regular', - fontSize: 16, - marginLeft: 8, - }, - listEmptyText: { - fontFamily: 'Inter-Regular', - fontSize: 14, }, titleRow: { flexDirection: 'row', justifyContent: 'space-between', }, cardText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 14, }, cameraPreview: { @@ -192,12 +173,12 @@ const publishStyle = StyleSheet.create({ padding: 16, }, successTitle: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 28, marginBottom: 16, }, successText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 16, marginBottom: 16, lineHeight: 20, @@ -211,7 +192,7 @@ const publishStyle = StyleSheet.create({ successUrl: { flex: 0.9, fontSize: 32, - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', color: Colors.NextLbryGreen, marginRight: 16, }, @@ -247,9 +228,6 @@ const publishStyle = StyleSheet.create({ alignItems: 'center', justifyContent: 'space-between', }, - backButtonControl: { - flex: 0.1, - }, mainControlsRow: { flex: 0.8, flexDirection: 'row', @@ -258,7 +236,6 @@ const publishStyle = StyleSheet.create({ }, switchCameraToggle: { marginRight: 48, - color: Colors.White, }, cameraAction: { width: 72, @@ -289,15 +266,9 @@ const publishStyle = StyleSheet.create({ alignItems: 'center', justifyContent: 'flex-end', }, - warning: { - marginTop: 24, - marginLeft: 16, - marginRight: 16, - alignItems: 'center', - }, rewardDriverCard: { alignItems: 'center', - backgroundColor: Colors.RewardDriverBlue, + backgroundColor: Colors.BrighterLbryGreen, flexDirection: 'row', paddingLeft: 16, paddingRight: 16, @@ -305,7 +276,7 @@ const publishStyle = StyleSheet.create({ paddingBottom: 12, }, rewardDriverText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', color: Colors.White, fontSize: 14, }, @@ -325,30 +296,24 @@ const publishStyle = StyleSheet.create({ marginBottom: 4, }, textInputTitle: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 12, marginBottom: -10, marginLeft: 4, }, thumbnailUploadContainer: { - alignItems: 'center', - borderRadius: 16, + marginTop: 16, + marginLeft: 16, + marginRight: 16, + paddingLeft: 2, + paddingRight: 2, flexDirection: 'row', - position: 'absolute', - top: 8, - right: 8, - backgroundColor: '#00000077', - paddingLeft: 8, - paddingRight: 8, - paddingTop: 4, - paddingBottom: 4, - justifyContent: 'center', + alignItems: 'center', }, thumbnailUploadText: { - color: Colors.White, - fontFamily: 'Inter-SemiBold', - fontSize: 12, - marginLeft: 4, + fontFamily: 'Inter-UI-Regular', + fontSize: 14, + marginLeft: 8, }, toggleField: { flexDirection: 'row', @@ -357,15 +322,10 @@ const publishStyle = StyleSheet.create({ marginBottom: 16, }, toggleText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 14, marginLeft: 8, }, - relativeCentered: { - alignItems: 'center', - justifyContent: 'center', - padding: 16, - }, centered: { position: 'absolute', left: 0, @@ -375,18 +335,6 @@ const publishStyle = StyleSheet.create({ alignItems: 'center', justifyContent: 'center', }, - currencyPicker: { - width: 100, - }, - fullCentered: { - position: 'absolute', - left: 0, - right: 0, - top: 0, - bottom: 0, - alignItems: 'center', - justifyContent: 'center', - }, noPublishes: { position: 'absolute', left: 0, @@ -398,7 +346,7 @@ const publishStyle = StyleSheet.create({ padding: 16, }, noPublishText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 16, }, publishNowButton: { @@ -411,7 +359,6 @@ const publishStyle = StyleSheet.create({ marginTop: 60, }, publishesScrollPadding: { - paddingTop: 16, paddingBottom: 16, }, listItem: { @@ -419,65 +366,14 @@ const publishStyle = StyleSheet.create({ flexDirection: 'row', justifyContent: 'space-between', marginTop: 8, - marginLeft: 16, - marginRight: 16, - marginBottom: 12, + marginLeft: 8, + marginRight: 8, }, noVideos: { color: Colors.White, - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 16, }, - cameraInfo: { - color: Colors.White, - fontFamily: 'Inter-Regular', - fontSize: 16, - }, - warningText: { - fontFamily: 'Inter-Regular', - fontSize: 14, - color: Colors.DescriptionGrey, - }, - helpText: { - fontFamily: 'Inter-Regular', - fontSize: 12, - color: Colors.DescriptionGrey, - }, - publishesFooter: { - marginTop: 2, - marginLeft: 16, - marginRight: 16, - }, - publishesFooterButton: { - alignSelf: 'flex-start', - backgroundColor: Colors.LbryGreen, - marginTop: 8, - }, - thumbnailEditOverlay: { - alignItems: 'center', - justifyContent: 'center', - borderRadius: 24, - position: 'absolute', - padding: 8, - left: screenWidth / 2 - 32 / 2, - bottom: 8, - backgroundColor: '#00000077', - }, - editIcon: { - color: Colors.White, - fontFamily: 'Inter-SemiBold', - fontSize: 12, - }, - balance: { - alignItems: 'center', - flexDirection: 'row', - marginLeft: 24, - }, - balanceText: { - fontFamily: 'Inter-SemiBold', - fontSize: 14, - marginLeft: 4, - }, }); export default publishStyle; diff --git a/src/styles/relatedContent.js b/src/styles/relatedContent.js index e4b091f..587a698 100644 --- a/src/styles/relatedContent.js +++ b/src/styles/relatedContent.js @@ -12,7 +12,7 @@ const relatedContentStyle = StyleSheet.create({ borderTopWidth: 1, }, title: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 18, }, itemList: { diff --git a/src/styles/reward.js b/src/styles/reward.js index aa5d603..cf2eb7f 100644 --- a/src/styles/reward.js +++ b/src/styles/reward.js @@ -29,7 +29,10 @@ const rewardStyle = StyleSheet.create({ }, enrollContainer: { flex: 1, - marginTop: 60, + marginTop: 76, + marginLeft: 16, + marginRight: 16, + marginBottom: 16, padding: 24, backgroundColor: Colors.LbryGreen, }, @@ -37,7 +40,7 @@ const rewardStyle = StyleSheet.create({ marginTop: 36, }, enrollDescText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 18, lineHeight: 28, color: Colors.White, @@ -67,36 +70,36 @@ const rewardStyle = StyleSheet.create({ paddingBottom: 16, }, text: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 16, lineHeight: 24, }, infoText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 18, marginLeft: 12, }, title: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 22, marginBottom: 6, color: Colors.LbryGreen, }, subtitle: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 18, marginBottom: 6, color: Colors.LbryGreen, }, subcardText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 15, lineHeight: 20, marginLeft: 2, marginRight: 2, }, subcardTextInput: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 16, marginTop: 2, marginBottom: 2, @@ -122,7 +125,7 @@ const rewardStyle = StyleSheet.create({ }, link: { color: Colors.LbryGreen, - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 14, }, textLink: { @@ -147,27 +150,22 @@ const rewardStyle = StyleSheet.create({ width: '18%', alignItems: 'center', }, - rightColHeader: { - fontFamily: 'Inter-Regular', - fontSize: 12, - }, rewardAmount: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 26, textAlign: 'center', }, rewardCurrency: { - fontFamily: 'Inter-Regular', - fontSize: 12, + fontFamily: 'Inter-UI-Regular', }, rewardTitle: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 16, color: Colors.LbryGreen, marginBottom: 4, }, rewardDescription: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 14, lineHeight: 18, marginBottom: 4, @@ -200,7 +198,7 @@ const rewardStyle = StyleSheet.create({ }, summaryText: { color: Colors.White, - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 28, marginLeft: 12, }, @@ -213,19 +211,19 @@ const rewardStyle = StyleSheet.create({ marginRight: 32, }, phoneInputText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 16, letterSpacing: 1.3, color: Colors.White, }, verifyingText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 14, marginLeft: 12, alignSelf: 'flex-start', }, verificationCodeInput: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', color: Colors.White, fontSize: 24, letterSpacing: 12, @@ -249,21 +247,16 @@ const rewardStyle = StyleSheet.create({ }, notInterestedLink: { fontSize: 14, - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', color: Colors.White, }, - learnMoreLink: { - fontFamily: 'Inter-Regular', - color: Colors.White, - textDecorationLine: 'underline', - }, enrollButton: { backgroundColor: Colors.White, paddingLeft: 16, paddingRight: 16, }, customCodeInput: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 16, letterSpacing: 1.3, marginTop: -8, @@ -290,7 +283,7 @@ const rewardStyle = StyleSheet.create({ verificationTitle: { fontSize: 32, color: Colors.White, - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', marginLeft: 32, marginRight: 32, marginBottom: 24, @@ -305,34 +298,11 @@ const rewardStyle = StyleSheet.create({ fontSize: 14, }, paragraphText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', color: Colors.White, fontSize: 12, lineHeight: 16, }, - filterHeader: { - flexDirection: 'row', - alignItems: 'center', - marginTop: 16, - marginLeft: 16, - marginRight: 16, - padding: 16, - backgroundColor: Colors.White, - }, - filterLink: { - fontFamily: 'Inter-Regular', - fontSize: 14, - marginRight: 24, - }, - activeFilterLink: { - fontFamily: 'Inter-SemiBold', - }, - rewardUsd: { - fontFamily: 'Inter-Regular', - fontSize: 12, - color: Colors.DescriptionGrey, - marginTop: 6, - }, }); export default rewardStyle; diff --git a/src/styles/search.js b/src/styles/search.js index b57373a..c27429b 100644 --- a/src/styles/search.js +++ b/src/styles/search.js @@ -12,11 +12,6 @@ const searchStyle = StyleSheet.create({ }, busyContainer: { flex: 1, - position: 'absolute', - top: 60, - left: 0, - right: 0, - bottom: 0, alignItems: 'center', justifyContent: 'center', }, @@ -35,28 +30,16 @@ const searchStyle = StyleSheet.create({ flex: 1, flexDirection: 'row', justifyContent: 'space-between', - padding: 8, + paddingTop: 8, + paddingBottom: 8, + paddingLeft: 8, + paddingRight: 8, backgroundColor: Colors.Black, }, - tagResultItem: { - flex: 1, - padding: 16, - backgroundColor: Colors.DarkerGrey, - }, - tagResultTitle: { - fontFamily: 'Inter-SemiBold', - fontSize: 24, - color: Colors.White, - }, - tagResultDescription: { - fontFamily: 'Inter-Regular', - fontSize: 14, - color: Colors.VeryLightGrey, - }, searchInput: { width: '100%', height: '100%', - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 16, }, noResults: { @@ -67,25 +50,19 @@ const searchStyle = StyleSheet.create({ alignItems: 'center', }, noResultsText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 16, marginTop: 16, marginLeft: 16, marginRight: 16, }, boldText: { - fontFamily: 'Inter-SemiBold', + fontFamily: 'Inter-UI-SemiBold', fontSize: 16, }, loading: { position: 'absolute', }, - moreLoading: { - width: '100%', - height: 48, - alignItems: 'center', - justifyContent: 'center', - }, }); export default searchStyle; diff --git a/src/styles/settings.js b/src/styles/settings.js index b159ac8..f20f302 100644 --- a/src/styles/settings.js +++ b/src/styles/settings.js @@ -28,54 +28,17 @@ const settingsStyle = StyleSheet.create({ width: '25%', justifyContent: 'center', }, - pickerText: { - width: '40%', - }, - pickerContainer: { - width: '60%', - flexDirection: 'row', - justifyContent: 'flex-end', - }, label: { fontSize: 14, - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', lineHeight: 18, }, description: { color: '#aaaaaa', fontSize: 12, - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', lineHeight: 18, }, - sectionTitle: { - fontFamily: 'Inter-Regular', - fontSize: 20, - marginBottom: 4, - }, - sectionDescription: { - color: '#aaaaaa', - fontFamily: 'Inter-Regular', - fontSize: 12, - lineHeight: 18, - marginBottom: 8, - }, - sectionDivider: { - marginTop: 24, - }, - languagePicker: { - width: '85%', - }, - languagePickerItem: { - fontFamily: 'Inter-Regular', - fontSize: 14, - }, - pickerRow: { - marginBottom: 24, - flex: 1, - flexDirection: 'row', - justifyContent: 'space-between', - alignItems: 'center', - }, }); export default settingsStyle; diff --git a/src/styles/splash.js b/src/styles/splash.js index 1e46f07..2064f70 100644 --- a/src/styles/splash.js +++ b/src/styles/splash.js @@ -8,14 +8,14 @@ const splashStyle = StyleSheet.create({ backgroundColor: Colors.LbryGreen, }, title: { - fontFamily: 'Inter-Bold', + fontFamily: 'Inter-UI-Bold', fontSize: 64, textAlign: 'center', marginBottom: 48, color: Colors.White, }, errorTitle: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 28, marginBottom: 24, marginLeft: 24, @@ -23,7 +23,7 @@ const splashStyle = StyleSheet.create({ color: Colors.White, }, paragraph: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 16, lineHeight: 24, marginBottom: 20, @@ -48,7 +48,7 @@ const splashStyle = StyleSheet.create({ width: '50%', }, details: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 14, marginLeft: 16, marginRight: 16, @@ -56,7 +56,7 @@ const splashStyle = StyleSheet.create({ textAlign: 'center', }, message: { - fontFamily: 'Inter-Bold', + fontFamily: 'Inter-UI-Bold', fontSize: 18, color: Colors.White, marginLeft: 16, diff --git a/src/styles/storageStats.js b/src/styles/storageStats.js index 236f9a8..17e4d06 100644 --- a/src/styles/storageStats.js +++ b/src/styles/storageStats.js @@ -16,16 +16,16 @@ const storageStatsStyle = StyleSheet.create({ padding: 16, }, totalSize: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 36, }, annotation: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 14, marginTop: -4, }, statsText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 14, }, distributionBar: { @@ -57,12 +57,12 @@ const storageStatsStyle = StyleSheet.create({ height: 16, }, legendText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 14, flex: 0.3, }, legendSize: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 14, flex: 0.6, textAlign: 'right', diff --git a/src/styles/subscriptions.js b/src/styles/subscriptions.js index 5c03cc2..f8c377d 100644 --- a/src/styles/subscriptions.js +++ b/src/styles/subscriptions.js @@ -13,7 +13,7 @@ const subscriptionsStyle = StyleSheet.create({ suggestedSubsContainer: { flex: 1, }, - suggestedScrollContent: { + suggestedScrollPadding: { paddingTop: 8, }, button: { @@ -37,14 +37,12 @@ const subscriptionsStyle = StyleSheet.create({ paddingTop: 24, }, infoText: { - fontFamily: 'Inter-Regular', - fontSize: 14, + fontFamily: 'Inter-UI-Regular', + fontSize: 16, marginTop: 8, marginBottom: 8, }, infoArea: { - flexDirection: 'row', - justifyContent: 'space-between', marginLeft: 16, marginRight: 16, paddingBottom: 4, @@ -59,7 +57,7 @@ const subscriptionsStyle = StyleSheet.create({ marginTop: 16, }, contentText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 16, marginLeft: 24, marginRight: 24, @@ -98,7 +96,7 @@ const subscriptionsStyle = StyleSheet.create({ justifyContent: 'center', }, fileItemName: { - fontFamily: 'Inter-Bold', + fontFamily: 'Inter-UI-Bold', marginTop: 8, fontSize: 18, }, @@ -111,7 +109,7 @@ const subscriptionsStyle = StyleSheet.create({ borderBottomWidth: 1, }, channelTitle: { - fontFamily: 'Inter-SemiBold', + fontFamily: 'Inter-UI-SemiBold', fontSize: 20, marginLeft: 24, marginTop: 16, @@ -138,16 +136,16 @@ const subscriptionsStyle = StyleSheet.create({ color: Colors.LbryGreen, }, inactiveMode: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', }, activeMode: { - fontFamily: 'Inter-SemiBold', + fontFamily: 'Inter-UI-SemiBold', }, claimList: { flex: 1, }, pageTitle: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 24, }, titleRow: { @@ -158,22 +156,13 @@ const subscriptionsStyle = StyleSheet.create({ alignItems: 'center', justifyContent: 'space-between', }, - pickerRow: { - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'space-between', - marginLeft: 16, - marginRight: 16, - marginTop: 8, - marginBottom: 8, - }, tagSortBy: { flexDirection: 'row', alignItems: 'center', - marginRight: 24, + marginRight: 4, }, tagSortText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 14, marginRight: 4, }, @@ -190,59 +179,52 @@ const subscriptionsStyle = StyleSheet.create({ justifyContent: 'center', }, suggestedItem: { + flexDirection: 'row', alignItems: 'center', marginBottom: 16, - height: 140, + marginLeft: 16, + marginRight: 16, }, suggestedItemThumbnailContainer: { width: 70, height: 70, borderRadius: 140, overflow: 'hidden', - alignItems: 'center', - justifyContent: 'center', }, suggestedItemThumbnail: { width: '100%', height: '100%', }, suggestedItemDetails: { - marginLeft: 8, - marginRight: 8, - alignItems: 'center', + marginLeft: 16, + marginRight: 16, + flex: 0.8, }, suggestedItemSubscribe: { backgroundColor: Colors.White, - }, - suggestedItemSubscribeOverlay: { position: 'absolute', - left: 0, right: 0, top: 0, - alignItems: 'center', - justifyContent: 'flex-end', - paddingBottom: 4, - height: 70, }, suggestedItemTitle: { - fontFamily: 'Inter-Regular', - textAlign: 'center', - fontSize: 13, - marginTop: 4, - marginBottom: 2, + fontFamily: 'Inter-UI-Regular', + fontSize: 16, + marginBottom: 4, + width: '85%', }, suggestedItemName: { - fontFamily: 'Inter-SemiBold', + fontFamily: 'Inter-UI-SemiBold', fontSize: 14, marginBottom: 4, color: Colors.LbryGreen, + width: '95%', }, suggestedItemTagList: { flexDirection: 'row', - justifyContent: 'center', + flexWrap: 'wrap', }, suggestedSubTitle: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 20, marginLeft: 16, marginRight: 16, @@ -255,41 +237,6 @@ const subscriptionsStyle = StyleSheet.create({ marginRight: 4, marginBottom: 4, }, - leftPickerRow: { - flexDirection: 'row', - alignItems: 'center', - }, - suggestedLink: { - fontFamily: 'Inter-Regular', - fontSize: 14, - }, - modalContainer: { - height: '80%', - backgroundColor: Colors.PageBackground, - }, - modalScrollContainer: { - marginBottom: 50, - }, - modalSuggestedScrollContent: { - paddingTop: 16, - }, - suggestedDoneButton: { - backgroundColor: Colors.LbryGreen, - margin: 16, - }, - mainSuggested: { - flex: 1, - }, - suggestedLoading: { - position: 'absolute', - right: 24, - bottom: 22, - }, - modalLoading: { - position: 'absolute', - right: 7, - bottom: 7, - }, }); export default subscriptionsStyle; diff --git a/src/styles/tag.js b/src/styles/tag.js index 15bee52..3db6355 100644 --- a/src/styles/tag.js +++ b/src/styles/tag.js @@ -7,7 +7,7 @@ const tagStyle = StyleSheet.create({ marginBottom: 4, }, tagSearchInput: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 16, }, content: { @@ -22,22 +22,14 @@ const tagStyle = StyleSheet.create({ marginRight: 8, }, text: { - fontFamily: 'Inter-Regular', - fontSize: 12, + fontFamily: 'Inter-UI-Regular', + fontSize: 14, marginRight: 8, }, tagResultsList: { flexDirection: 'row', flexWrap: 'wrap', }, - nsfwTagsContainer: { - marginTop: 8, - }, - nsfwTagsTitle: { - fontFamily: 'Inter-Regular', - fontSize: 16, - marginBottom: 4, - }, }); export default tagStyle; diff --git a/src/styles/transactionList.js b/src/styles/transactionList.js index f575dc2..8414465 100644 --- a/src/styles/transactionList.js +++ b/src/styles/transactionList.js @@ -17,36 +17,33 @@ const transactionListStyle = StyleSheet.create({ topRow: { marginBottom: 4, }, - leftCol: { - flex: 0.7, - }, col: { alignSelf: 'stretch', }, text: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 14, }, link: { color: Colors.LbryGreen, - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 14, }, amount: { textAlign: 'right', }, smallText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 12, color: '#aaaaaa', }, smallLink: { color: Colors.LbryGreen, - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 12, }, noTransactions: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', textAlign: 'center', padding: 16, color: '#aaaaaa', diff --git a/src/styles/uriBar.js b/src/styles/uriBar.js index 61e430d..ea5722e 100644 --- a/src/styles/uriBar.js +++ b/src/styles/uriBar.js @@ -20,23 +20,19 @@ const uriBarStyle = StyleSheet.create({ containerElevated: { elevation: 4, }, - drawerHamburger: { - marginLeft: 16, - marginRight: 16, - }, uriText: { backgroundColor: Colors.VeryLightGrey, borderRadius: 24, paddingLeft: 12, paddingRight: 12, - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 16, lineHeight: 18, flex: 17, }, overlay: { position: 'absolute', - backgroundColor: 'red', + backgroundColor: 'transparent', top: 0, width: '100%', zIndex: 200, @@ -54,10 +50,9 @@ const uriBarStyle = StyleSheet.create({ item: { flexDirection: 'row', alignItems: 'center', - paddingLeft: 16, - paddingRight: 16, - paddingTop: 12, - paddingBottom: 12, + padding: 12, + paddingTop: 8, + paddingBottom: 8, }, itemContent: { marginLeft: 12, @@ -65,11 +60,11 @@ const uriBarStyle = StyleSheet.create({ flex: 1, }, itemText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 16, }, itemDesc: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 14, color: Colors.UriDescBlue, }, @@ -78,39 +73,6 @@ const uriBarStyle = StyleSheet.create({ justifyContent: 'center', flex: 3, }, - selectionModeBar: { - flex: 1, - height: 46, - flexDirection: 'row', - alignItems: 'center', - justifyContent: 'space-between', - }, - selectionModeLeftBar: { - flexDirection: 'row', - alignItems: 'center', - marginLeft: 16, - }, - selectionModeActions: { - flexDirection: 'row', - alignItems: 'center', - marginRight: 16, - }, - backTouchArea: { - height: '100%', - alignItems: 'center', - }, - leftAction: { - marginRight: 16, - }, - actionTouchArea: { - height: '100%', - alignItems: 'center', - }, - itemCount: { - fontFamily: 'Inter-Regular', - fontSize: 20, - marginLeft: 30, - }, }); export default uriBarStyle; diff --git a/src/styles/wallet.js b/src/styles/wallet.js index 6b037df..3079076 100644 --- a/src/styles/wallet.js +++ b/src/styles/wallet.js @@ -3,7 +3,6 @@ import Colors from './colors'; const walletStyle = StyleSheet.create({ container: { - flex: 1, backgroundColor: Colors.PageBackground, }, scrollContainer: { @@ -26,17 +25,12 @@ const walletStyle = StyleSheet.create({ flexDirection: 'row', }, address: { - fontFamily: 'Inter-Regular', - letterSpacing: 0.8, + fontFamily: 'Inter-UI-Regular', borderWidth: 1, - borderRadius: 16, borderStyle: 'dashed', - borderColor: '#e1e1e1', + borderColor: '#cccccc', backgroundColor: '#f9f9f9', - paddingTop: 8, - paddingLeft: 8, - paddingRight: 8, - paddingBottom: 6, + padding: 8, width: '85%', }, button: { @@ -69,12 +63,12 @@ const walletStyle = StyleSheet.create({ margin: 16, }, title: { - fontFamily: 'Inter-SemiBold', + fontFamily: 'Inter-UI-SemiBold', fontSize: 20, marginBottom: 24, }, transactionsTitle: { - fontFamily: 'Inter-SemiBold', + fontFamily: 'Inter-UI-SemiBold', fontSize: 20, }, transactionsHeader: { @@ -86,16 +80,16 @@ const walletStyle = StyleSheet.create({ borderBottomColor: '#eeeeee', }, text: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 14, }, link: { color: Colors.LbryGreen, - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 14, }, smallText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 12, }, balanceCard: { @@ -103,14 +97,6 @@ const walletStyle = StyleSheet.create({ marginLeft: 16, marginRight: 16, }, - balanceExtra: { - marginLeft: 16, - marginRight: 16, - }, - balanceExtraCard: { - backgroundColor: Colors.White, - padding: 16, - }, balanceBackground: { position: 'absolute', alignSelf: 'stretch', @@ -119,14 +105,14 @@ const walletStyle = StyleSheet.create({ }, balanceTitle: { color: Colors.White, - fontFamily: 'Inter-SemiBold', + fontFamily: 'Inter-UI-SemiBold', fontSize: 20, marginLeft: 16, marginTop: 16, }, balanceCaption: { color: '#caedB9', - fontFamily: 'Inter-Medium', + fontFamily: 'Inter-UI-Medium', fontSize: 14, marginLeft: 16, marginTop: 8, @@ -134,37 +120,20 @@ const walletStyle = StyleSheet.create({ }, balance: { color: Colors.White, - fontFamily: 'Inter-Bold', + fontFamily: 'Inter-UI-Bold', fontSize: 36, marginLeft: 16, - }, - usdBalance: { - color: Colors.White, - fontFamily: 'Inter-Regular', - fontSize: 20, - marginLeft: 16, - marginTop: 2, marginBottom: 16, }, - balanceFocus: { - alignItems: 'center', - flexDirection: 'row', - marginLeft: 24, - }, - balanceText: { - fontFamily: 'Inter-SemiBold', - fontSize: 14, - marginLeft: 4, - }, infoText: { color: '#aaaaaa', - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 14, padding: 16, textAlign: 'center', }, input: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 14, }, amountInput: { @@ -187,14 +156,14 @@ const walletStyle = StyleSheet.create({ }, warningParagraph: { color: Colors.White, - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 16, lineHeight: 24, marginBottom: 16, }, warningText: { color: Colors.White, - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 16, lineHeight: 24, marginBottom: 8, @@ -206,7 +175,6 @@ const walletStyle = StyleSheet.create({ paddingRight: 18, }, currency: { - fontFamily: 'Inter-Regular', alignSelf: 'flex-start', fontSize: 12, marginTop: 16, @@ -229,7 +197,7 @@ const walletStyle = StyleSheet.create({ }, rewardDriverCard: { alignItems: 'center', - backgroundColor: Colors.RewardDriverBlue, + backgroundColor: Colors.BrighterLbryGreen, flexDirection: 'row', padding: 16, marginLeft: 16, @@ -238,7 +206,7 @@ const walletStyle = StyleSheet.create({ }, rewardDriverText: { color: Colors.White, - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 14, lineHeight: 16, }, @@ -253,7 +221,7 @@ const walletStyle = StyleSheet.create({ marginRight: 16, }, syncDriverTitle: { - fontFamily: 'Inter-SemiBold', + fontFamily: 'Inter-UI-SemiBold', fontSize: 20, paddingLeft: 16, marginTop: 16, @@ -261,25 +229,9 @@ const walletStyle = StyleSheet.create({ borderBottomWidth: 1, borderBottomColor: Colors.PageBackground, }, - syncDriverCustody: { - backgroundColor: Colors.LbryGreen, - padding: 16, - }, - syncInfoText: { - color: Colors.White, - fontFamily: 'Inter-Regular', - fontSize: 16, - marginBottom: 8, - }, - syncInfoLink: { - color: Colors.White, - fontFamily: 'Inter-Regular', - fontSize: 14, - textDecorationLine: 'underline', - }, syncDriverLink: { color: Colors.LbryGreen, - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 14, }, actionRow: { @@ -323,11 +275,11 @@ const walletStyle = StyleSheet.create({ justifyContent: 'flex-end', }, labelText: { - fontFamily: 'Inter-SemiBold', + fontFamily: 'Inter-UI-SemiBold', fontSize: 16, }, valueText: { - fontFamily: 'Inter-Regular', + fontFamily: 'Inter-UI-Regular', fontSize: 16, }, rightLink: { @@ -336,134 +288,6 @@ const walletStyle = StyleSheet.create({ syncSwitch: { marginLeft: 8, }, - loadingContainer: { - position: 'absolute', - flexDirection: 'row', - left: 0, - right: 0, - top: 60, - bottom: 0, - alignItems: 'center', - justifyContent: 'center', - }, - loadingText: { - color: '#aaaaaa', - fontFamily: 'Inter-Regular', - fontSize: 16, - marginLeft: 8, - }, - buttonRow: { - width: '100%', - position: 'absolute', - alignItems: 'center', - left: 24, - bottom: 24, - flexDirection: 'row', - justifyContent: 'space-between', - }, - continueLink: { - fontSize: 14, - fontFamily: 'Inter-Regular', - color: Colors.White, - }, - learnMoreLink: { - fontFamily: 'Inter-Regular', - color: Colors.NextLbryGreen, - }, - signInButton: { - backgroundColor: Colors.White, - paddingLeft: 16, - paddingRight: 16, - }, - signInContainer: { - flex: 1, - marginTop: 60, - padding: 24, - backgroundColor: Colors.LbryGreen, - }, - onboarding: { - marginTop: 36, - }, - onboardingText: { - fontFamily: 'Inter-Regular', - fontSize: 18, - lineHeight: 28, - color: Colors.White, - }, - signInSummaryRow: { - flexDirection: 'row', - }, - signInTitle: { - color: Colors.White, - fontFamily: 'Inter-Regular', - fontSize: 28, - }, - walletExtraRow: { - flexDirection: 'row', - }, - walletExtraCol: { - flex: 0.5, - paddingLeft: 24, - }, - walletExtraBalance: { - fontFamily: 'Inter-SemiBold', - fontSize: 28, - }, - usdWalletExtraBalance: { - fontFamily: 'Inter-Regular', - fontSize: 16, - color: Colors.DescriptionGrey, - }, - balanceRow: { - flexDirection: 'row', - alignItems: 'center', - }, - walletExtraCaption: { - fontFamily: 'Inter-Medium', - fontSize: 14, - }, - walletExtraCurrency: { - fontFamily: 'Inter-Regular', - fontSize: 12, - marginTop: 8, - marginLeft: 4, - }, - walletExtraTopMargin: { - marginTop: 16, - }, - walletExtraIcon: { - position: 'absolute', - left: 0, - top: 0, - }, - usdInfoCard: { - backgroundColor: Colors.White, - padding: 16, - borderBottomColor: Colors.VeryLightGrey, - borderBottomWidth: 1, - }, - usdInfoText: { - fontFamily: 'Inter-Regular', - fontSize: 14, - marginBottom: 8, - }, - usdConvertLink: { - fontFamily: 'Inter-Regular', - fontSize: 16, - color: Colors.LbryGreen, - }, - usdConvertFaqLink: { - fontFamily: 'Inter-Regular', - fontSize: 14, - color: Colors.LbryGreen, - }, - earnTipsLink: { - fontFamily: 'Inter-Regular', - fontSize: 14, - color: Colors.LbryGreen, - marginTop: 12, - marginRight: 16, - }, }); export default walletStyle; diff --git a/src/utils/deep-equal.js b/src/utils/deep-equal.js deleted file mode 100644 index 1925763..0000000 --- a/src/utils/deep-equal.js +++ /dev/null @@ -1,117 +0,0 @@ -/* eslint-disable */ -// underscore's deep equal function -// https://github.com/jashkenas/underscore/blob/master/underscore.js#L1189 - -export default function isEqual(a, b, aStack, bStack) { - // Identical objects are equal. `0 === -0`, but they aren't identical. - // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). - if (a === b) return a !== 0 || 1 / a === 1 / b; - // `null` or `undefined` only equal to itself (strict comparison). - if (a == null || b == null) return false; - // `NaN`s are equivalent, but non-reflexive. - if (a !== a) return b !== b; - // Exhaust primitive checks - var type = typeof a; - if (type !== 'function' && type !== 'object' && typeof b != 'object') return false; - return deepEq(a, b, aStack, bStack); -} - -function deepEq(a, b, aStack, bStack) { - // Compare `[[Class]]` names. - var className = toString.call(a); - if (className !== toString.call(b)) return false; - switch (className) { - // Strings, numbers, regular expressions, dates, and booleans are compared by value. - case '[object RegExp]': - // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i') - case '[object String]': - // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is - // equivalent to `new String("5")`. - return '' + a === '' + b; - case '[object Number]': - // `NaN`s are equivalent, but non-reflexive. - // Object(NaN) is equivalent to NaN. - if (+a !== +a) return +b !== +b; - // An `egal` comparison is performed for other numeric values. - return +a === 0 ? 1 / +a === 1 / b : +a === +b; - case '[object Date]': - case '[object Boolean]': - // Coerce dates and booleans to numeric primitive values. Dates are compared by their - // millisecond representations. Note that invalid dates with millisecond representations - // of `NaN` are not equivalent. - return +a === +b; - case '[object Symbol]': - return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b); - } - - var areArrays = className === '[object Array]'; - if (!areArrays) { - if (typeof a != 'object' || typeof b != 'object') return false; - - // Objects with different constructors are not equivalent, but `Object`s or `Array`s - // from different frames are. - var aCtor = a.constructor, - bCtor = b.constructor; - if ( - aCtor !== bCtor && - !( - typeof aCtor === 'function' && - aCtor instanceof aCtor && - typeof bCtor === 'function' && - bCtor instanceof bCtor - ) && - ('constructor' in a && 'constructor' in b) - ) { - return false; - } - } - // Assume equality for cyclic structures. The algorithm for detecting cyclic - // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. - - // Initializing stack of traversed objects. - // It's done here since we only need them for objects and arrays comparison. - aStack = aStack || []; - bStack = bStack || []; - var length = aStack.length; - while (length--) { - // Linear search. Performance is inversely proportional to the number of - // unique nested structures. - if (aStack[length] === a) return bStack[length] === b; - } - - // Add the first object to the stack of traversed objects. - aStack.push(a); - bStack.push(b); - - // Recursively compare objects and arrays. - if (areArrays) { - // Compare array lengths to determine if a deep comparison is necessary. - length = a.length; - if (length !== b.length) return false; - // Deep compare the contents, ignoring non-numeric properties. - while (length--) { - if (!isEqual(a[length], b[length], aStack, bStack)) return false; - } - } else { - // Deep compare objects. - var keys = Object.keys(a), - key; - length = keys.length; - // Ensure that both objects contain the same number of properties before comparing deep equality. - if (Object.keys(b).length !== length) return false; - while (length--) { - // Deep compare each member - key = keys[length]; - if (!(has(b, key) && isEqual(a[key], b[key], aStack, bStack))) return false; - } - } - // Remove the first object from the stack of traversed objects. - aStack.pop(); - bStack.pop(); - return true; -} - -function has(obj, path) { - return obj != null && hasOwnProperty.call(obj, path); -} -/* eslint-enable */ diff --git a/src/utils/helper.js b/src/utils/helper.js index 66d2e2a..ae6f023 100644 --- a/src/utils/helper.js +++ b/src/utils/helper.js @@ -1,44 +1,36 @@ import { NavigationActions, StackActions } from 'react-navigation'; -import { buildURI, isURIValid, normalizeURI } from 'lbry-redux'; -import { Lbryio } from 'lbryinc'; +import { buildURI, isURIValid } from 'lbry-redux'; import { doPopDrawerStack, doPushDrawerStack, doSetPlayerVisible } from 'redux/actions/drawer'; -import Constants, { DrawerRoutes, InnerDrawerRoutes } from 'constants'; // eslint-disable-line node/no-deprecated-api +import Constants, { DrawerRoutes } from 'constants'; // eslint-disable-line node/no-deprecated-api const tagNameLength = 10; -const specialRouteMap = { - about: Constants.DRAWER_ROUTE_ABOUT, - allContent: Constants.DRAWER_ROUTE_TRENDING, - channels: Constants.DRAWER_ROUTE_CHANNEL_CREATOR, - invite: Constants.DRAWER_ROUTE_INVITES, - invites: Constants.DRAWER_ROUTE_INVITES, - library: Constants.DRAWER_ROUTE_MY_LBRY, - publish: Constants.DRAWER_ROUTE_PUBLISH, - publishes: Constants.DRAWER_ROUTE_PUBLISHES, - rewards: Constants.DRAWER_ROUTE_REWARDS, - settings: Constants.DRAWER_ROUTE_SETTINGS, - subscriptions: Constants.DRAWER_ROUTE_SUBSCRIPTIONS, - wallet: Constants.FULL_ROUTE_NAME_WALLET, - discover: Constants.FULL_ROUTE_NAME_DISCOVER, -}; - function getRouteForSpecialUri(uri) { let targetRoute; const page = uri.substring(8).trim(); // 'lbry://?'.length == 8 - if (specialRouteMap[page]) { - targetRoute = specialRouteMap[page]; - } - - if (!targetRoute) { - // default to the home page if there is no match for the page - targetRoute = Constants.FULL_ROUTE_NAME_DISCOVER; + switch (page) { + case Constants.PAGE_REWARDS: + targetRoute = 'Rewards'; + break; + case Constants.PAGE_SETTINGS: + targetRoute = 'Settings'; + break; + case Constants.PAGE_TRENDING: + targetRoute = 'TrendingStack'; + break; + case Constants.PAGE_WALLET: + targetRoute = 'WalletStack'; + break; + default: + targetRoute = 'DiscoverStack'; + break; } return targetRoute; } -export function dispatchNavigateToUri(dispatch, nav, uri, isNavigatingBack, fullUri) { +export function dispatchNavigateToUri(dispatch, nav, uri, isNavigatingBack) { if (uri.startsWith('lbry://?')) { dispatch(NavigationActions.navigate({ routeName: getRouteForSpecialUri(uri) })); return; @@ -52,14 +44,13 @@ export function dispatchNavigateToUri(dispatch, nav, uri, isNavigatingBack, full uriVars = parseUriVars(uriVarsStr); } - const params = { uri, uriVars, fullUri: fullUri }; + const params = { uri, uriVars }; if (!isNavigatingBack) { dispatch(doPushDrawerStack(uri)); + dispatch(doSetPlayerVisible(true)); } - dispatch(doSetPlayerVisible(false)); - if (nav && nav.routes && nav.routes.length > 0 && nav.routes[0].routeName === 'Main') { const mainRoute = nav.routes[0]; const discoverRoute = mainRoute.routes[0]; @@ -116,15 +107,7 @@ function parseUriVars(vars) { return uriVars; } -export function navigateToUri( - navigation, - uri, - additionalParams, - isNavigatingBack, - fullUri, - setPlayerVisible, - pushStack = false, -) { +export function navigateToUri(navigation, uri, additionalParams, isNavigatingBack) { if (!navigation) { return; } @@ -146,116 +129,51 @@ export function navigateToUri( uriVars = parseUriVars(uriVarsStr); } - if (setPlayerVisible) { - setPlayerVisible(false); - } - const { store } = window; - const params = Object.assign({ uri, uriVars, fullUri: fullUri }, additionalParams); + const params = Object.assign({ uri, uriVars }, additionalParams); if (navigation.state.routeName === 'File') { const stackAction = StackActions.replace({ routeName: 'File', newKey: uri, params }); navigation.dispatch(stackAction); if (store && store.dispatch && !isNavigatingBack) { store.dispatch(doPushDrawerStack(uri)); + store.dispatch(doSetPlayerVisible(true)); } return; } navigation.navigate({ routeName: 'File', key: uri, params }); - if (pushStack && store && store.dispatch && !isNavigatingBack) { + if (store && store.dispatch && !isNavigatingBack) { store.dispatch(doPushDrawerStack(uri)); + store.dispatch(doSetPlayerVisible(true)); } } -export function navigateBack(navigation, drawerStack, popDrawerStack, setPlayerVisible) { - if (drawerStack[drawerStack.length - 1].route === Constants.DRAWER_ROUTE_FILE_VIEW) { - // inner file_view (web / image view) is handled differently - if (popDrawerStack) { - popDrawerStack(); - } - return; - } - +export function navigateBack(navigation, drawerStack, popDrawerStack) { if (popDrawerStack) { popDrawerStack(); } - if (setPlayerVisible) { - setPlayerVisible(false); - } - const target = drawerStack[drawerStack.length > 1 ? drawerStack.length - 2 : 0]; - const { route, params } = target; navigation.goBack(navigation.state.key); - - if (!DrawerRoutes.includes(route) && !InnerDrawerRoutes.includes(route) && isURIValid(route)) { - navigateToUri(navigation, route, null, true, null, setPlayerVisible); + if (DrawerRoutes.indexOf(target) === -1 && isURIValid(target)) { + navigateToUri(navigation, target, null, true); } else { - let targetRoute = route; - let targetParams = params; - if (InnerDrawerRoutes.includes(route)) { - if (Constants.DRAWER_ROUTE_CHANNEL_CREATOR_FORM === route) { - targetRoute = Constants.DRAWER_ROUTE_CHANNEL_CREATOR; - } else if (Constants.DRAWER_ROUTE_PUBLISH_FORM === route) { - targetRoute = Constants.DRAWER_ROUTE_PUBLISH; - } - - if (targetParams) { - targetParams.displayForm = true; - } else { - targetParams = { displayForm: true }; - } - } - - navigation.navigate({ routeName: targetRoute, targetParams }); + navigation.navigate({ routeName: target }); } } export function dispatchNavigateBack(dispatch, nav, drawerStack) { - const currentRoute = drawerStack[drawerStack.length - 1].route; - if ( - [ - Constants.DRAWER_ROUTE_FILE_VIEW, - Constants.DRAWER_ROUTE_CHANNEL_CREATOR_FORM, - Constants.DRAWER_ROUTE_PUBLISH_FORM, - ].includes(currentRoute) - ) { - // inner routes are handled a little differently - dispatch(doPopDrawerStack()); - return; - } - dispatch(doPopDrawerStack()); - dispatch(doSetPlayerVisible(false)); const target = drawerStack[drawerStack.length > 1 ? drawerStack.length - 2 : 0]; - const { route } = target; dispatch(NavigationActions.back()); - if (!DrawerRoutes.includes(route) && !InnerDrawerRoutes.includes(route) && isURIValid(route)) { - dispatchNavigateToUri(dispatch, nav, route, true); + + if (DrawerRoutes.indexOf(target) === -1 && isURIValid(target)) { + dispatchNavigateToUri(dispatch, nav, target, true); } else { - const newTarget = drawerStack[drawerStack.length > 1 ? drawerStack.length - 2 : 0]; - let targetRoute = newTarget.route; - let targetParams = newTarget.params; - if (InnerDrawerRoutes.includes(targetRoute)) { - if (Constants.DRAWER_ROUTE_CHANNEL_CREATOR_FORM === route) { - targetRoute = Constants.DRAWER_ROUTE_CHANNEL_CREATOR; - } else if (Constants.DRAWER_ROUTE_PUBLISH_FORM === route) { - targetRoute = Constants.DRAWER_ROUTE_PUBLISH; - } - - if (targetParams) { - targetParams.displayForm = true; - } else { - targetParams = { displayForm: true }; - } - } - const navigateAction = NavigationActions.navigate({ - routeName: targetRoute, - params: targetParams, + routeName: drawerStack[drawerStack.length > 1 ? drawerStack.length - 2 : 0], }); - dispatch(navigateAction); } } @@ -263,7 +181,7 @@ export function dispatchNavigateBack(dispatch, nav, drawerStack) { export function uriFromFileInfo(fileInfo) { const { name: claimName, claim_name: claimNameDownloaded, claim_id: claimId } = fileInfo; const uriParams = {}; - uriParams.claimName = claimName || claimNameDownloaded; + uriParams.contentName = claimName || claimNameDownloaded; uriParams.claimId = claimId; return buildURI(uriParams); } @@ -286,160 +204,7 @@ export function formatTagName(name) { return name.substring(0, 7) + '...'; } -export function getSortByItemForName(name) { - for (let i = 0; i < Constants.CLAIM_SEARCH_SORT_BY_ITEMS.length; i++) { - if (name === Constants.CLAIM_SEARCH_SORT_BY_ITEMS[i].name) { - return Constants.CLAIM_SEARCH_SORT_BY_ITEMS[i]; - } - } - - return null; -} - -export function getTimeItemForName(name) { - for (let i = 0; i < Constants.CLAIM_SEARCH_TIME_ITEMS.length; i++) { - if (name === Constants.CLAIM_SEARCH_TIME_ITEMS[i].name) { - return Constants.CLAIM_SEARCH_TIME_ITEMS[i]; - } - } - - return null; -} - -export function getOrderBy(item) { - let orderBy = []; - switch (item.name) { - case Constants.SORT_BY_HOT: - orderBy = Constants.DEFAULT_ORDER_BY; - break; - - case Constants.SORT_BY_NEW: - orderBy = ['release_time']; - break; - - case Constants.SORT_BY_TOP: - orderBy = [Constants.ORDER_BY_EFFECTIVE_AMOUNT]; - break; - } - - return orderBy; -} - -// replace occurrences of ':' with '#' in a url (entered in the URI bar) -export function transformUrl(url) { - const start = 'lbry://'.length; - return normalizeURI(url.substring(start).replace(/:/g, '#')); -} - // i18n placeholder until we find a good react-native i18n module export function __(str) { return str; } - -export function logPublish(claimResult) { - // eslint-disable-next-line no-undef - if (!__DEV__) { - const { permanent_url: uri, claim_id: claimId, txid, nout, signing_channel: signingChannel } = claimResult; - let channelClaimId; - if (signingChannel) { - channelClaimId = signingChannel.claim_id; - } - const outpoint = `${txid}:${nout}`; - const params = { uri, claim_id: claimId, outpoint }; - if (channelClaimId) { - params['channel_claim_id'] = channelClaimId; - } - Lbryio.call('event', 'publish', params); - } -} - -export function uploadImageAsset(filePath, success, failure) { - const makeid = () => { - let text = ''; - const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; - for (let i = 0; i < 24; i += 1) text += possible.charAt(Math.floor(Math.random() * 62)); - return text; - }; - - const fileName = filePath.substring(filePath.lastIndexOf('/') + 1); - let fileExt = fileName.indexOf('.') > -1 ? fileName.substring(fileName.lastIndexOf('.') + 1).trim() : 0; - if (!fileExt) { - fileExt = 'jpg'; // default to jpg - } - const fileType = `image/${fileExt}`; - - const data = new FormData(); - const name = makeid(); - data.append('name', name); - data.append('file', { uri: 'file://' + filePath, type: fileType, name: fileName }); - - return fetch('https://spee.ch/api/claim/publish', { - method: 'POST', - body: data, - }) - .then(response => response.json()) - .then(json => { - if (json.success) { - if (success) { - success({ url: `${json.data.url}.${fileExt}` }); - } - } - }) - .catch(err => { - if (failure) { - failure(err.message ? err.message : 'The image failed to upload.'); - } - }); -} - -// TODO: Move this to lbry-redux -export function formatLbryUrlForWeb(url) { - return url.replace('lbry://', '/').replace(/#/g, ':'); -} - -export function getDownloadProgress(fileInfo) { - return Math.ceil((fileInfo.written_bytes / fileInfo.total_bytes) * 100); -} - -export function getStorageForFileInfo(fileInfo) { - if (!fileInfo.completed) { - const written = formatBytes(fileInfo.written_bytes); - const total = formatBytes(fileInfo.total_bytes); - return `(${written} / ${total})`; - } - - return formatBytes(fileInfo.written_bytes); -} - -export function formatTitle(title) { - if (!title) { - return title; - } - - return title.length > 80 ? title.substring(0, 77).trim() + '...' : title; -} - -export function fetchReferralCode(successCallback, errorCallback) { - Lbryio.call('user_referral_code', 'list') - .then(response => { - if (successCallback) { - successCallback(response); - } - }) - .catch(err => { - if (errorCallback) { - errorCallback(err); - } - }); -} - -export function decode(value) { - return decodeURIComponent(value).replace(/\+/g, ' '); -} - -export function formatUsd(value) { - if (isNaN(parseFloat(value))) { - value = 0; - } - return '$' + parseFloat(value).toFixed(2); -} diff --git a/yarn.lock b/yarn.lock deleted file mode 100644 index 7a7426d..0000000 --- a/yarn.lock +++ /dev/null @@ -1,8186 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e" - integrity sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g== - dependencies: - "@babel/highlight" "^7.8.3" - -"@babel/core@^7.0.0", "@babel/core@^7.6.2": - version "7.8.7" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.8.7.tgz#b69017d221ccdeb203145ae9da269d72cf102f3b" - integrity sha512-rBlqF3Yko9cynC5CCFy6+K/w2N+Sq/ff2BPy+Krp7rHlABIr5epbA7OxVeKoMHB39LZOp1UY5SuLjy6uWi35yA== - dependencies: - "@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@^7.0.0", "@babel/generator@^7.8.6", "@babel/generator@^7.8.7": - version "7.8.7" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.8.7.tgz#870b3cf7984f5297998152af625c4f3e341400f7" - integrity sha512-DQwjiKJqH4C3qGiyQCAExJHoZssn49JTMJgZ8SANGgVFdkupcUhLOdkAeoC6kmHZCPfoDG5M0b6cFlSN5wW7Ew== - dependencies: - "@babel/types" "^7.8.7" - jsesc "^2.5.1" - lodash "^4.17.13" - source-map "^0.5.0" - -"@babel/helper-annotate-as-pure@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.8.3.tgz#60bc0bc657f63a0924ff9a4b4a0b24a13cf4deee" - integrity sha512-6o+mJrZBxOoEX77Ezv9zwW7WV8DdluouRKNY/IR5u/YTMuKHgugHOzYWlYvYLpLA9nPsQCAAASpCIbjI9Mv+Uw== - dependencies: - "@babel/types" "^7.8.3" - -"@babel/helper-builder-binary-assignment-operator-visitor@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.8.3.tgz#c84097a427a061ac56a1c30ebf54b7b22d241503" - integrity sha512-5eFOm2SyFPK4Rh3XMMRDjN7lBH0orh3ss0g3rTYZnBQ+r6YPj7lgDyCvPphynHvUrobJmeMignBr6Acw9mAPlw== - dependencies: - "@babel/helper-explode-assignable-expression" "^7.8.3" - "@babel/types" "^7.8.3" - -"@babel/helper-builder-react-jsx@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.8.3.tgz#dee98d7d79cc1f003d80b76fe01c7f8945665ff6" - integrity sha512-JT8mfnpTkKNCboTqZsQTdGo3l3Ik3l7QIt9hh0O9DYiwVel37VoJpILKM4YFbP2euF32nkQSb+F9cUk9b7DDXQ== - dependencies: - "@babel/types" "^7.8.3" - esutils "^2.0.0" - -"@babel/helper-call-delegate@^7.8.7": - version "7.8.7" - resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.8.7.tgz#28a279c2e6c622a6233da548127f980751324cab" - integrity sha512-doAA5LAKhsFCR0LAFIf+r2RSMmC+m8f/oQ+URnUET/rWeEzC0yTRmAGyWkD4sSu3xwbS7MYQ2u+xlt1V5R56KQ== - dependencies: - "@babel/helper-hoist-variables" "^7.8.3" - "@babel/traverse" "^7.8.3" - "@babel/types" "^7.8.7" - -"@babel/helper-create-class-features-plugin@^7.8.3": - version "7.8.6" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.8.6.tgz#243a5b46e2f8f0f674dc1387631eb6b28b851de0" - integrity sha512-klTBDdsr+VFFqaDHm5rR69OpEQtO2Qv8ECxHS1mNhJJvaHArR6a1xTf5K/eZW7eZpJbhCx3NW1Yt/sKsLXLblg== - dependencies: - "@babel/helper-function-name" "^7.8.3" - "@babel/helper-member-expression-to-functions" "^7.8.3" - "@babel/helper-optimise-call-expression" "^7.8.3" - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/helper-replace-supers" "^7.8.6" - "@babel/helper-split-export-declaration" "^7.8.3" - -"@babel/helper-create-regexp-features-plugin@^7.8.3": - version "7.8.6" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.6.tgz#7fa040c97fb8aebe1247a5c645330c32d083066b" - integrity sha512-bPyujWfsHhV/ztUkwGHz/RPV1T1TDEsSZDsN42JPehndA+p1KKTh3npvTadux0ZhCrytx9tvjpWNowKby3tM6A== - dependencies: - "@babel/helper-annotate-as-pure" "^7.8.3" - "@babel/helper-regex" "^7.8.3" - regexpu-core "^4.6.0" - -"@babel/helper-define-map@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.8.3.tgz#a0655cad5451c3760b726eba875f1cd8faa02c15" - integrity sha512-PoeBYtxoZGtct3md6xZOCWPcKuMuk3IHhgxsRRNtnNShebf4C8YonTSblsK4tvDbm+eJAw2HAPOfCr+Q/YRG/g== - dependencies: - "@babel/helper-function-name" "^7.8.3" - "@babel/types" "^7.8.3" - lodash "^4.17.13" - -"@babel/helper-explode-assignable-expression@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.8.3.tgz#a728dc5b4e89e30fc2dfc7d04fa28a930653f982" - integrity sha512-N+8eW86/Kj147bO9G2uclsg5pwfs/fqqY5rwgIL7eTBklgXjcOJ3btzS5iM6AitJcftnY7pm2lGsrJVYLGjzIw== - dependencies: - "@babel/traverse" "^7.8.3" - "@babel/types" "^7.8.3" - -"@babel/helper-function-name@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz#eeeb665a01b1f11068e9fb86ad56a1cb1a824cca" - integrity sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA== - dependencies: - "@babel/helper-get-function-arity" "^7.8.3" - "@babel/template" "^7.8.3" - "@babel/types" "^7.8.3" - -"@babel/helper-get-function-arity@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz#b894b947bd004381ce63ea1db9f08547e920abd5" - integrity sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA== - dependencies: - "@babel/types" "^7.8.3" - -"@babel/helper-hoist-variables@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.8.3.tgz#1dbe9b6b55d78c9b4183fc8cdc6e30ceb83b7134" - integrity sha512-ky1JLOjcDUtSc+xkt0xhYff7Z6ILTAHKmZLHPxAhOP0Nd77O+3nCsd6uSVYur6nJnCI029CrNbYlc0LoPfAPQg== - dependencies: - "@babel/types" "^7.8.3" - -"@babel/helper-member-expression-to-functions@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz#659b710498ea6c1d9907e0c73f206eee7dadc24c" - integrity sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA== - dependencies: - "@babel/types" "^7.8.3" - -"@babel/helper-module-imports@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz#7fe39589b39c016331b6b8c3f441e8f0b1419498" - integrity sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg== - dependencies: - "@babel/types" "^7.8.3" - -"@babel/helper-module-transforms@^7.8.3": - version "7.8.6" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.8.6.tgz#6a13b5eecadc35692047073a64e42977b97654a4" - integrity sha512-RDnGJSR5EFBJjG3deY0NiL0K9TO8SXxS9n/MPsbPK/s9LbQymuLNtlzvDiNS7IpecuL45cMeLVkA+HfmlrnkRg== - dependencies: - "@babel/helper-module-imports" "^7.8.3" - "@babel/helper-replace-supers" "^7.8.6" - "@babel/helper-simple-access" "^7.8.3" - "@babel/helper-split-export-declaration" "^7.8.3" - "@babel/template" "^7.8.6" - "@babel/types" "^7.8.6" - lodash "^4.17.13" - -"@babel/helper-optimise-call-expression@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz#7ed071813d09c75298ef4f208956006b6111ecb9" - integrity sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ== - dependencies: - "@babel/types" "^7.8.3" - -"@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz#9ea293be19babc0f52ff8ca88b34c3611b208670" - integrity sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ== - -"@babel/helper-regex@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.8.3.tgz#139772607d51b93f23effe72105b319d2a4c6965" - integrity sha512-BWt0QtYv/cg/NecOAZMdcn/waj/5P26DR4mVLXfFtDokSR6fyuG0Pj+e2FqtSME+MqED1khnSMulkmGl8qWiUQ== - dependencies: - lodash "^4.17.13" - -"@babel/helper-remap-async-to-generator@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.8.3.tgz#273c600d8b9bf5006142c1e35887d555c12edd86" - integrity sha512-kgwDmw4fCg7AVgS4DukQR/roGp+jP+XluJE5hsRZwxCYGg+Rv9wSGErDWhlI90FODdYfd4xG4AQRiMDjjN0GzA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.8.3" - "@babel/helper-wrap-function" "^7.8.3" - "@babel/template" "^7.8.3" - "@babel/traverse" "^7.8.3" - "@babel/types" "^7.8.3" - -"@babel/helper-replace-supers@^7.8.3", "@babel/helper-replace-supers@^7.8.6": - version "7.8.6" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.8.6.tgz#5ada744fd5ad73203bf1d67459a27dcba67effc8" - integrity sha512-PeMArdA4Sv/Wf4zXwBKPqVj7n9UF/xg6slNRtZW84FM7JpE1CbG8B612FyM4cxrf4fMAMGO0kR7voy1ForHHFA== - dependencies: - "@babel/helper-member-expression-to-functions" "^7.8.3" - "@babel/helper-optimise-call-expression" "^7.8.3" - "@babel/traverse" "^7.8.6" - "@babel/types" "^7.8.6" - -"@babel/helper-simple-access@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz#7f8109928b4dab4654076986af575231deb639ae" - integrity sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw== - dependencies: - "@babel/template" "^7.8.3" - "@babel/types" "^7.8.3" - -"@babel/helper-split-export-declaration@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz#31a9f30070f91368a7182cf05f831781065fc7a9" - integrity sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA== - dependencies: - "@babel/types" "^7.8.3" - -"@babel/helper-wrap-function@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.8.3.tgz#9dbdb2bb55ef14aaa01fe8c99b629bd5352d8610" - integrity sha512-LACJrbUET9cQDzb6kG7EeD7+7doC3JNvUgTEQOx2qaO1fKlzE/Bf05qs9w1oXQMmXlPO65lC3Tq9S6gZpTErEQ== - dependencies: - "@babel/helper-function-name" "^7.8.3" - "@babel/template" "^7.8.3" - "@babel/traverse" "^7.8.3" - "@babel/types" "^7.8.3" - -"@babel/helpers@^7.8.4": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.8.4.tgz#754eb3ee727c165e0a240d6c207de7c455f36f73" - integrity sha512-VPbe7wcQ4chu4TDQjimHv/5tj73qz88o12EPkO2ValS2QiQS/1F2SsjyIGNnAD0vF/nZS6Cf9i+vW6HIlnaR8w== - dependencies: - "@babel/template" "^7.8.3" - "@babel/traverse" "^7.8.4" - "@babel/types" "^7.8.3" - -"@babel/highlight@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.8.3.tgz#28f173d04223eaaa59bc1d439a3836e6d1265797" - integrity sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg== - dependencies: - chalk "^2.0.0" - esutils "^2.0.2" - js-tokens "^4.0.0" - -"@babel/parser@^7.0.0", "@babel/parser@^7.8.6", "@babel/parser@^7.8.7": - version "7.8.7" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.8.7.tgz#7b8facf95d25fef9534aad51c4ffecde1a61e26a" - integrity sha512-9JWls8WilDXFGxs0phaXAZgpxTZhSk/yOYH2hTHC0X1yC7Z78IJfvR1vJ+rmJKq3I35td2XzXzN6ZLYlna+r/A== - -"@babel/plugin-external-helpers@^7.0.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-external-helpers/-/plugin-external-helpers-7.8.3.tgz#5a94164d9af393b2820a3cdc407e28ebf237de4b" - integrity sha512-mx0WXDDiIl5DwzMtzWGRSPugXi9BxROS05GQrhLNbEamhBiicgn994ibwkyiBH+6png7bm/yA7AUsvHyCXi4Vw== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/plugin-proposal-class-properties@^7.0.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.8.3.tgz#5e06654af5cd04b608915aada9b2a6788004464e" - integrity sha512-EqFhbo7IosdgPgZggHaNObkmO1kNUe3slaKu54d5OWvy+p9QIKOzK1GAEpAIsZtWVtPXUHSMcT4smvDrCfY4AA== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.8.3" - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/plugin-proposal-export-default-from@^7.0.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.8.3.tgz#4cb7c2fdeaed490b60d9bfd3dc8a20f81f9c2e7c" - integrity sha512-PYtv2S2OdCdp7GSPDg5ndGZFm9DmWFvuLoS5nBxZCgOBggluLnhTScspJxng96alHQzPyrrHxvC9/w4bFuspeA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/plugin-syntax-export-default-from" "^7.8.3" - -"@babel/plugin-proposal-nullish-coalescing-operator@^7.0.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.8.3.tgz#e4572253fdeed65cddeecfdab3f928afeb2fd5d2" - integrity sha512-TS9MlfzXpXKt6YYomudb/KU7nQI6/xnapG6in1uZxoxDghuSMZsPb6D2fyUwNYSAp4l1iR7QtFOjkqcRYcUsfw== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" - -"@babel/plugin-proposal-object-rest-spread@^7.0.0", "@babel/plugin-proposal-object-rest-spread@^7.5.4": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.8.3.tgz#eb5ae366118ddca67bed583b53d7554cad9951bb" - integrity sha512-8qvuPwU/xxUCt78HocNlv0mXXo0wdh9VT1R04WU8HGOfaOob26pF+9P5/lYjN/q7DHOX1bvX60hnhOvuQUJdbA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/plugin-syntax-object-rest-spread" "^7.8.0" - -"@babel/plugin-proposal-optional-catch-binding@^7.0.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.8.3.tgz#9dee96ab1650eed88646ae9734ca167ac4a9c5c9" - integrity sha512-0gkX7J7E+AtAw9fcwlVQj8peP61qhdg/89D5swOkjYbkboA2CVckn3kiyum1DE0wskGb7KJJxBdyEBApDLLVdw== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" - -"@babel/plugin-proposal-optional-chaining@^7.0.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.8.3.tgz#ae10b3214cb25f7adb1f3bc87ba42ca10b7e2543" - integrity sha512-QIoIR9abkVn+seDE3OjA08jWcs3eZ9+wJCKSRgo3WdEU2csFYgdScb+8qHB3+WXsGJD55u+5hWCISI7ejXS+kg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/plugin-syntax-optional-chaining" "^7.8.0" - -"@babel/plugin-syntax-class-properties@^7.0.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.8.3.tgz#6cb933a8872c8d359bfde69bbeaae5162fd1e8f7" - integrity sha512-UcAyQWg2bAN647Q+O811tG9MrJ38Z10jjhQdKNAL8fsyPzE3cCN/uT+f55cFVY4aGO4jqJAvmqsuY3GQDwAoXg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/plugin-syntax-dynamic-import@^7.0.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" - integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-export-default-from@^7.0.0", "@babel/plugin-syntax-export-default-from@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.8.3.tgz#f1e55ce850091442af4ba9c2550106035b29d678" - integrity sha512-a1qnnsr73KLNIQcQlcQ4ZHxqqfBKM6iNQZW2OMTyxNbA2WC7SHWHtGVpFzWtQAuS2pspkWVzdEBXXx8Ik0Za4w== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/plugin-syntax-flow@^7.0.0", "@babel/plugin-syntax-flow@^7.2.0", "@babel/plugin-syntax-flow@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.8.3.tgz#f2c883bd61a6316f2c89380ae5122f923ba4527f" - integrity sha512-innAx3bUbA0KSYj2E2MNFSn9hiCeowOFLxlsuhXzw8hMQnzkDomUr9QCD7E9VF60NmnG1sNTuuv6Qf4f8INYsg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/plugin-syntax-jsx@^7.0.0", "@babel/plugin-syntax-jsx@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.8.3.tgz#521b06c83c40480f1e58b4fd33b92eceb1d6ea94" - integrity sha512-WxdW9xyLgBdefoo0Ynn3MRSkhe5tFVxxKNVdnZSh318WrG2e2jH+E9wd/++JsqcLJZPfz87njQJ8j2Upjm0M0A== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" - integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-object-rest-spread@^7.0.0", "@babel/plugin-syntax-object-rest-spread@^7.8.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" - integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-catch-binding@^7.8.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" - integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-chaining@^7.8.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" - integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-typescript@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.8.3.tgz#c1f659dda97711a569cef75275f7e15dcaa6cabc" - integrity sha512-GO1MQ/SGGGoiEXY0e0bSpHimJvxqB7lktLLIq2pv8xG7WZ8IMEle74jIe1FhprHBWjwjZtXHkycDLZXIWM5Wfg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/plugin-transform-arrow-functions@^7.0.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.8.3.tgz#82776c2ed0cd9e1a49956daeb896024c9473b8b6" - integrity sha512-0MRF+KC8EqH4dbuITCWwPSzsyO3HIWWlm30v8BbbpOrS1B++isGxPnnuq/IZvOX5J2D/p7DQalQm+/2PnlKGxg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/plugin-transform-async-to-generator@^7.0.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.8.3.tgz#4308fad0d9409d71eafb9b1a6ee35f9d64b64086" - integrity sha512-imt9tFLD9ogt56Dd5CI/6XgpukMwd/fLGSrix2httihVe7LOGVPhyhMh1BU5kDM7iHD08i8uUtmV2sWaBFlHVQ== - dependencies: - "@babel/helper-module-imports" "^7.8.3" - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/helper-remap-async-to-generator" "^7.8.3" - -"@babel/plugin-transform-block-scoped-functions@^7.0.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.8.3.tgz#437eec5b799b5852072084b3ae5ef66e8349e8a3" - integrity sha512-vo4F2OewqjbB1+yaJ7k2EJFHlTP3jR634Z9Cj9itpqNjuLXvhlVxgnjsHsdRgASR8xYDrx6onw4vW5H6We0Jmg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/plugin-transform-block-scoping@^7.0.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.8.3.tgz#97d35dab66857a437c166358b91d09050c868f3a" - integrity sha512-pGnYfm7RNRgYRi7bids5bHluENHqJhrV4bCZRwc5GamaWIIs07N4rZECcmJL6ZClwjDz1GbdMZFtPs27hTB06w== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - lodash "^4.17.13" - -"@babel/plugin-transform-classes@^7.0.0": - version "7.8.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.8.6.tgz#77534447a477cbe5995ae4aee3e39fbc8090c46d" - integrity sha512-k9r8qRay/R6v5aWZkrEclEhKO6mc1CCQr2dLsVHBmOQiMpN6I2bpjX3vgnldUWeEI1GHVNByULVxZ4BdP4Hmdg== - dependencies: - "@babel/helper-annotate-as-pure" "^7.8.3" - "@babel/helper-define-map" "^7.8.3" - "@babel/helper-function-name" "^7.8.3" - "@babel/helper-optimise-call-expression" "^7.8.3" - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/helper-replace-supers" "^7.8.6" - "@babel/helper-split-export-declaration" "^7.8.3" - globals "^11.1.0" - -"@babel/plugin-transform-computed-properties@^7.0.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.8.3.tgz#96d0d28b7f7ce4eb5b120bb2e0e943343c86f81b" - integrity sha512-O5hiIpSyOGdrQZRQ2ccwtTVkgUDBBiCuK//4RJ6UfePllUTCENOzKxfh6ulckXKc0DixTFLCfb2HVkNA7aDpzA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/plugin-transform-destructuring@^7.0.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.8.3.tgz#20ddfbd9e4676906b1056ee60af88590cc7aaa0b" - integrity sha512-H4X646nCkiEcHZUZaRkhE2XVsoz0J/1x3VVujnn96pSoGCtKPA99ZZA+va+gK+92Zycd6OBKCD8tDb/731bhgQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/plugin-transform-exponentiation-operator@^7.0.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.8.3.tgz#581a6d7f56970e06bf51560cd64f5e947b70d7b7" - integrity sha512-zwIpuIymb3ACcInbksHaNcR12S++0MDLKkiqXHl3AzpgdKlFNhog+z/K0+TGW+b0w5pgTq4H6IwV/WhxbGYSjQ== - dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.8.3" - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/plugin-transform-flow-strip-types@^7.0.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.8.3.tgz#da705a655466b2a9b36046b57bf0cbcd53551bd4" - integrity sha512-g/6WTWG/xbdd2exBBzMfygjX/zw4eyNC4X8pRaq7aRHRoDUCzAIu3kGYIXviOv8BjCuWm8vDBwjHcjiRNgXrPA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/plugin-syntax-flow" "^7.8.3" - -"@babel/plugin-transform-for-of@^7.0.0": - version "7.8.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.8.6.tgz#a051bd1b402c61af97a27ff51b468321c7c2a085" - integrity sha512-M0pw4/1/KI5WAxPsdcUL/w2LJ7o89YHN3yLkzNjg7Yl15GlVGgzHyCU+FMeAxevHGsLVmUqbirlUIKTafPmzdw== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/plugin-transform-function-name@^7.0.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.8.3.tgz#279373cb27322aaad67c2683e776dfc47196ed8b" - integrity sha512-rO/OnDS78Eifbjn5Py9v8y0aR+aSYhDhqAwVfsTl0ERuMZyr05L1aFSCJnbv2mmsLkit/4ReeQ9N2BgLnOcPCQ== - dependencies: - "@babel/helper-function-name" "^7.8.3" - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/plugin-transform-literals@^7.0.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.8.3.tgz#aef239823d91994ec7b68e55193525d76dbd5dc1" - integrity sha512-3Tqf8JJ/qB7TeldGl+TT55+uQei9JfYaregDcEAyBZ7akutriFrt6C/wLYIer6OYhleVQvH/ntEhjE/xMmy10A== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/plugin-transform-member-expression-literals@^7.0.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.8.3.tgz#963fed4b620ac7cbf6029c755424029fa3a40410" - integrity sha512-3Wk2EXhnw+rP+IDkK6BdtPKsUE5IeZ6QOGrPYvw52NwBStw9V1ZVzxgK6fSKSxqUvH9eQPR3tm3cOq79HlsKYA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/plugin-transform-modules-commonjs@^7.0.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.8.3.tgz#df251706ec331bd058a34bdd72613915f82928a5" - integrity sha512-JpdMEfA15HZ/1gNuB9XEDlZM1h/gF/YOH7zaZzQu2xCFRfwc01NXBMHHSTT6hRjlXJJs5x/bfODM3LiCk94Sxg== - dependencies: - "@babel/helper-module-transforms" "^7.8.3" - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/helper-simple-access" "^7.8.3" - babel-plugin-dynamic-import-node "^2.3.0" - -"@babel/plugin-transform-object-assign@^7.0.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.8.3.tgz#dc3b8dd50ef03837868a37b7df791f64f288538e" - integrity sha512-i3LuN8tPDqUCRFu3dkzF2r1Nx0jp4scxtm7JxtIqI9he9Vk20YD+/zshdzR9JLsoBMlJlNR82a62vQExNEVx/Q== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/plugin-transform-object-super@^7.0.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.8.3.tgz#ebb6a1e7a86ffa96858bd6ac0102d65944261725" - integrity sha512-57FXk+gItG/GejofIyLIgBKTas4+pEU47IXKDBWFTxdPd7F80H8zybyAY7UoblVfBhBGs2EKM+bJUu2+iUYPDQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/helper-replace-supers" "^7.8.3" - -"@babel/plugin-transform-parameters@^7.0.0": - version "7.8.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.8.7.tgz#66fa2f1de4129b4e0447509223ac71bda4955395" - integrity sha512-brYWaEPTRimOctz2NDA3jnBbDi7SVN2T4wYuu0aqSzxC3nozFZngGaw29CJ9ZPweB7k+iFmZuoG3IVPIcXmD2g== - dependencies: - "@babel/helper-call-delegate" "^7.8.7" - "@babel/helper-get-function-arity" "^7.8.3" - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/plugin-transform-property-literals@^7.0.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.8.3.tgz#33194300d8539c1ed28c62ad5087ba3807b98263" - integrity sha512-uGiiXAZMqEoQhRWMK17VospMZh5sXWg+dlh2soffpkAl96KAm+WZuJfa6lcELotSRmooLqg0MWdH6UUq85nmmg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/plugin-transform-react-display-name@^7.0.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.8.3.tgz#70ded987c91609f78353dd76d2fb2a0bb991e8e5" - integrity sha512-3Jy/PCw8Fe6uBKtEgz3M82ljt+lTg+xJaM4og+eyu83qLT87ZUSckn0wy7r31jflURWLO83TW6Ylf7lyXj3m5A== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/plugin-transform-react-jsx-source@^7.0.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.8.3.tgz#951e75a8af47f9f120db731be095d2b2c34920e0" - integrity sha512-PLMgdMGuVDtRS/SzjNEQYUT8f4z1xb2BAT54vM1X5efkVuYBf5WyGUMbpmARcfq3NaglIwz08UVQK4HHHbC6ag== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/plugin-syntax-jsx" "^7.8.3" - -"@babel/plugin-transform-react-jsx@^7.0.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.8.3.tgz#4220349c0390fdefa505365f68c103562ab2fc4a" - integrity sha512-r0h+mUiyL595ikykci+fbwm9YzmuOrUBi0b+FDIKmi3fPQyFokWVEMJnRWHJPPQEjyFJyna9WZC6Viv6UHSv1g== - dependencies: - "@babel/helper-builder-react-jsx" "^7.8.3" - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/plugin-syntax-jsx" "^7.8.3" - -"@babel/plugin-transform-regenerator@^7.0.0": - version "7.8.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.8.7.tgz#5e46a0dca2bee1ad8285eb0527e6abc9c37672f8" - integrity sha512-TIg+gAl4Z0a3WmD3mbYSk+J9ZUH6n/Yc57rtKRnlA/7rcCvpekHXe0CMZHP1gYp7/KLe9GHTuIba0vXmls6drA== - dependencies: - regenerator-transform "^0.14.2" - -"@babel/plugin-transform-runtime@^7.0.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.8.3.tgz#c0153bc0a5375ebc1f1591cb7eea223adea9f169" - integrity sha512-/vqUt5Yh+cgPZXXjmaG9NT8aVfThKk7G4OqkVhrXqwsC5soMn/qTCxs36rZ2QFhpfTJcjw4SNDIZ4RUb8OL4jQ== - dependencies: - "@babel/helper-module-imports" "^7.8.3" - "@babel/helper-plugin-utils" "^7.8.3" - resolve "^1.8.1" - semver "^5.5.1" - -"@babel/plugin-transform-shorthand-properties@^7.0.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.8.3.tgz#28545216e023a832d4d3a1185ed492bcfeac08c8" - integrity sha512-I9DI6Odg0JJwxCHzbzW08ggMdCezoWcuQRz3ptdudgwaHxTjxw5HgdFJmZIkIMlRymL6YiZcped4TTCB0JcC8w== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/plugin-transform-spread@^7.0.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.8.3.tgz#9c8ffe8170fdfb88b114ecb920b82fb6e95fe5e8" - integrity sha512-CkuTU9mbmAoFOI1tklFWYYbzX5qCIZVXPVy0jpXgGwkplCndQAa58s2jr66fTeQnA64bDox0HL4U56CFYoyC7g== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/plugin-transform-sticky-regex@^7.0.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.8.3.tgz#be7a1290f81dae767475452199e1f76d6175b100" - integrity sha512-9Spq0vGCD5Bb4Z/ZXXSK5wbbLFMG085qd2vhL1JYu1WcQ5bXqZBAYRzU1d+p79GcHs2szYv5pVQCX13QgldaWw== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/helper-regex" "^7.8.3" - -"@babel/plugin-transform-template-literals@^7.0.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.8.3.tgz#7bfa4732b455ea6a43130adc0ba767ec0e402a80" - integrity sha512-820QBtykIQOLFT8NZOcTRJ1UNuztIELe4p9DCgvj4NK+PwluSJ49we7s9FB1HIGNIYT7wFUJ0ar2QpCDj0escQ== - dependencies: - "@babel/helper-annotate-as-pure" "^7.8.3" - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/plugin-transform-typescript@^7.0.0": - version "7.8.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.8.7.tgz#48bccff331108a7b3a28c3a4adc89e036dc3efda" - integrity sha512-7O0UsPQVNKqpHeHLpfvOG4uXmlw+MOxYvUv6Otc9uH5SYMIxvF6eBdjkWvC3f9G+VXe0RsNExyAQBeTRug/wqQ== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.8.3" - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/plugin-syntax-typescript" "^7.8.3" - -"@babel/plugin-transform-unicode-regex@^7.0.0": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.8.3.tgz#0cef36e3ba73e5c57273effb182f46b91a1ecaad" - integrity sha512-+ufgJjYdmWfSQ+6NS9VGUR2ns8cjJjYbrbi11mZBTaWm+Fui/ncTLFF28Ei1okavY+xkojGr1eJxNsWYeA5aZw== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.8.3" - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/register@^7.0.0": - version "7.8.6" - resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.8.6.tgz#a1066aa6168a73a70c35ef28cc5865ccc087ea69" - integrity sha512-7IDO93fuRsbyml7bAafBQb3RcBGlCpU4hh5wADA2LJEEcYk92WkwFZ0pHyIi2fb5Auoz1714abETdZKCOxN0CQ== - dependencies: - find-cache-dir "^2.0.0" - lodash "^4.17.13" - make-dir "^2.1.0" - pirates "^4.0.0" - source-map-support "^0.5.16" - -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.8.4": - version "7.8.7" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.8.7.tgz#8fefce9802db54881ba59f90bb28719b4996324d" - integrity sha512-+AATMUFppJDw6aiR5NVPHqIQBlV/Pj8wY/EZH+lmvRdUo9xBaz/rF3alAwFJQavvKfeOlPE7oaaDHVbcySbCsg== - dependencies: - regenerator-runtime "^0.13.4" - -"@babel/template@^7.0.0", "@babel/template@^7.8.3", "@babel/template@^7.8.6": - version "7.8.6" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.6.tgz#86b22af15f828dfb086474f964dcc3e39c43ce2b" - integrity sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg== - dependencies: - "@babel/code-frame" "^7.8.3" - "@babel/parser" "^7.8.6" - "@babel/types" "^7.8.6" - -"@babel/traverse@^7.0.0", "@babel/traverse@^7.8.3", "@babel/traverse@^7.8.4", "@babel/traverse@^7.8.6": - version "7.8.6" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.8.6.tgz#acfe0c64e1cd991b3e32eae813a6eb564954b5ff" - integrity sha512-2B8l0db/DPi8iinITKuo7cbPznLCEk0kCxDoB9/N6gGNg/gxOXiR/IcymAFPiBwk5w6TtQ27w4wpElgp9btR9A== - dependencies: - "@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" - -"@babel/types@^7.0.0", "@babel/types@^7.8.3", "@babel/types@^7.8.6", "@babel/types@^7.8.7": - version "7.8.7" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.8.7.tgz#1fc9729e1acbb2337d5b6977a63979b4819f5d1d" - integrity sha512-k2TreEHxFA4CjGkL+GYjRyx35W0Mr7DP5+9q6WMkyKXB+904bYmG40syjMFV0oLlhhFCwWl0vA0DyzTDkwAiJw== - dependencies: - esutils "^2.0.2" - lodash "^4.17.13" - to-fast-properties "^2.0.0" - -"@callstack/react-theme-provider@3.0.3": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@callstack/react-theme-provider/-/react-theme-provider-3.0.3.tgz#f964dda28cd6e731c3fbcf916b0579c6f9fb2db7" - integrity sha512-B+9JBK7zsND/AdVkjwHvbb4cR05fJofLFG30hOeoXke8WkKAWN36yFljauAhI8qwlXlGFGZMYE1wQvsqBSccrA== - dependencies: - "@types/hoist-non-react-statics" "^3.3.1" - deepmerge "^3.2.0" - hoist-non-react-statics "^3.3.0" - -"@cnakazawa/watch@^1.0.3": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a" - integrity sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ== - dependencies: - exec-sh "^0.3.2" - minimist "^1.2.0" - -"@expo/vector-icons@^8.1.0": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@expo/vector-icons/-/vector-icons-8.1.0.tgz#2a70d8d4a8b74f275063bcb2087e8b276a579955" - integrity sha512-/aKa+bgp3LIcTKJWPLRYTYCL0wf/Fr4dwl4XYmNGFG092pK3McuBoDk3b8tWyZnXBnEiqnMLd6Qwr+LEX6Jc0Q== - dependencies: - lodash "^4.17.4" - react-native-vector-icons "6.0.0" - -"@hapi/address@2.x.x": - version "2.1.4" - resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5" - integrity sha512-QD1PhQk+s31P1ixsX0H0Suoupp3VMXzIVMSwobR3F3MSUO2YCV0B7xqLcUw/Bh8yuvd3LhpyqLQWTNcRmp6IdQ== - -"@hapi/bourne@1.x.x": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@hapi/bourne/-/bourne-1.3.2.tgz#0a7095adea067243ce3283e1b56b8a8f453b242a" - integrity sha512-1dVNHT76Uu5N3eJNTYcvxee+jzX4Z9lfciqRRHCU27ihbUcYi+iSc2iml5Ke1LXe1SyJCLA0+14Jh4tXJgOppA== - -"@hapi/hoek@8.x.x", "@hapi/hoek@^8.3.0": - version "8.5.1" - resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-8.5.1.tgz#fde96064ca446dec8c55a8c2f130957b070c6e06" - integrity sha512-yN7kbciD87WzLGc5539Tn0sApjyiGHAJgKvG9W8C7O+6c7qmoQMfVs0W4bX17eqz6C78QJqqFrtgdK5EWf6Qow== - -"@hapi/joi@^15.0.3": - version "15.1.1" - resolved "https://registry.yarnpkg.com/@hapi/joi/-/joi-15.1.1.tgz#c675b8a71296f02833f8d6d243b34c57b8ce19d7" - integrity sha512-entf8ZMOK8sc+8YfeOlM8pCfg3b5+WZIKBfUaaJT8UsjAAPjartzxIYm3TIbjvA4u+u++KbcXD38k682nVHDAQ== - dependencies: - "@hapi/address" "2.x.x" - "@hapi/bourne" "1.x.x" - "@hapi/hoek" "8.x.x" - "@hapi/topo" "3.x.x" - -"@hapi/topo@3.x.x": - version "3.1.6" - resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-3.1.6.tgz#68d935fa3eae7fdd5ab0d7f953f3205d8b2bfc29" - integrity sha512-tAag0jEcjwH+P2quUfipd7liWCNX2F8NvYjQp2wtInsZxnMlypdw0FtAOLxtvvkO+GSRRbmNi8m/5y42PQJYCQ== - dependencies: - "@hapi/hoek" "^8.3.0" - -"@jest/console@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.9.0.tgz#79b1bc06fb74a8cfb01cbdedf945584b1b9707f0" - integrity sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ== - dependencies: - "@jest/source-map" "^24.9.0" - chalk "^2.0.1" - slash "^2.0.0" - -"@jest/fake-timers@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.9.0.tgz#ba3e6bf0eecd09a636049896434d306636540c93" - integrity sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A== - dependencies: - "@jest/types" "^24.9.0" - jest-message-util "^24.9.0" - jest-mock "^24.9.0" - -"@jest/source-map@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-24.9.0.tgz#0e263a94430be4b41da683ccc1e6bffe2a191714" - integrity sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg== - dependencies: - callsites "^3.0.0" - graceful-fs "^4.1.15" - source-map "^0.6.0" - -"@jest/test-result@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.9.0.tgz#11796e8aa9dbf88ea025757b3152595ad06ba0ca" - integrity sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA== - dependencies: - "@jest/console" "^24.9.0" - "@jest/types" "^24.9.0" - "@types/istanbul-lib-coverage" "^2.0.0" - -"@jest/types@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.9.0.tgz#63cb26cb7500d069e5a389441a7c6ab5e909fc59" - integrity sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw== - dependencies: - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^1.1.1" - "@types/yargs" "^13.0.0" - -"@jest/types@^25.1.0": - version "25.1.0" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.1.0.tgz#b26831916f0d7c381e11dbb5e103a72aed1b4395" - integrity sha512-VpOtt7tCrgvamWZh1reVsGADujKigBUFTi19mlRjqEGsE8qH4r3s+skY33dNdXOwyZIvuftZ5tqdF1IgsMejMA== - dependencies: - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^1.1.1" - "@types/yargs" "^15.0.0" - chalk "^3.0.0" - -"@react-native-community/async-storage@^1.5.1": - version "1.8.1" - resolved "https://registry.yarnpkg.com/@react-native-community/async-storage/-/async-storage-1.8.1.tgz#c93e69dcf948667b207e409b8039b7edf199159b" - integrity sha512-MA1fTp4SB7OOtDmNAwds6jIpiwwty1NIoFboWjEWkoyWW35zIuxlhHxD4joSy21aWEzUVwvv6JJ2hSsP/HTb7A== - -"@react-native-community/cli-debugger-ui@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-3.0.0.tgz#d01d08d1e5ddc1633d82c7d84d48fff07bd39416" - integrity sha512-m3X+iWLsK/H7/b7PpbNO33eQayR/+M26la4ZbYe1KRke5Umg4PIWsvg21O8Tw4uJcY8LA5hsP+rBi/syBkBf0g== - dependencies: - serve-static "^1.13.1" - -"@react-native-community/cli-platform-android@^3.0.0": - version "3.1.4" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-3.1.4.tgz#61f964dc311623e60b0fb29c5f3732cc8a6f076f" - integrity sha512-ClSdY20F0gzWVLTqCv7vHjnUqOcuq10jd9GgHX6lGSc2GI+Ql3/aQg3tmG4uY3KXNNwAv3U8QCoYgg1WGfwiHA== - dependencies: - "@react-native-community/cli-tools" "^3.0.0" - chalk "^2.4.2" - execa "^1.0.0" - jetifier "^1.6.2" - logkitty "^0.6.0" - slash "^3.0.0" - xmldoc "^1.1.2" - -"@react-native-community/cli-platform-ios@^3.0.0": - version "3.2.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-3.2.0.tgz#c469444f5993c9e6737a4b16d78cf033e3702f00" - integrity sha512-pzEnx68H6+mHBq5jsMrr3UmAmkrLSMlC9BZ4yoUdfUXCQq6/R70zNYvH4hjUw8h2Al7Kgq53UzHUsM0ph8TSWQ== - dependencies: - "@react-native-community/cli-tools" "^3.0.0" - chalk "^2.4.2" - js-yaml "^3.13.1" - xcode "^2.0.0" - -"@react-native-community/cli-tools@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-3.0.0.tgz#fe48b80822ed7e49b8af051f9fe41e22a2a710b1" - integrity sha512-8IhQKZdf3E4CR8T7HhkPGgorot/cLkRDgneJFDSWk/wCYZAuUh4NEAdumQV7N0jLSMWX7xxiWUPi94lOBxVY9g== - dependencies: - chalk "^2.4.2" - lodash "^4.17.5" - mime "^2.4.1" - node-fetch "^2.5.0" - -"@react-native-community/cli-types@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-types/-/cli-types-3.0.0.tgz#488d46605cb05e88537e030f38da236eeda74652" - integrity sha512-ng6Tm537E/M42GjE4TRUxQyL8sRfClcL7bQWblOCoxPZzJ2J3bdALsjeG3vDnVCIfI/R0AeFalN9KjMt0+Z/Zg== - -"@react-native-community/cli@^3.0.0": - version "3.2.1" - resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-3.2.1.tgz#2a466801eb6080a1f73358c5d740c53c24ed8c6f" - integrity sha512-bZ/bfZ+9r1gQSxp6t7+00DcpC6vmbVYSvzUCFM/yo5k8bhsDdcy8aocscIaXXVGG+v9Edri/Q7hH9ks7L18/Rg== - dependencies: - "@hapi/joi" "^15.0.3" - "@react-native-community/cli-debugger-ui" "^3.0.0" - "@react-native-community/cli-tools" "^3.0.0" - "@react-native-community/cli-types" "^3.0.0" - chalk "^2.4.2" - command-exists "^1.2.8" - commander "^2.19.0" - compression "^1.7.1" - connect "^3.6.5" - cosmiconfig "^5.1.0" - deepmerge "^3.2.0" - didyoumean "^1.2.1" - envinfo "^7.1.0" - errorhandler "^1.5.0" - execa "^1.0.0" - find-up "^4.1.0" - fs-extra "^7.0.1" - glob "^7.1.1" - graceful-fs "^4.1.3" - inquirer "^3.0.6" - lodash "^4.17.5" - metro "^0.56.0" - metro-config "^0.56.0" - metro-core "^0.56.0" - metro-react-native-babel-transformer "^0.56.0" - minimist "^1.2.0" - mkdirp "^0.5.1" - morgan "^1.9.0" - node-notifier "^5.2.1" - open "^6.2.0" - ora "^3.4.0" - plist "^3.0.0" - pretty-format "^25.1.0" - semver "^6.3.0" - serve-static "^1.13.1" - shell-quote "1.6.1" - strip-ansi "^5.2.0" - sudo-prompt "^9.0.0" - wcwidth "^1.0.1" - ws "^1.1.0" - -"@react-native-community/eslint-config@^0.0.5": - version "0.0.5" - resolved "https://registry.yarnpkg.com/@react-native-community/eslint-config/-/eslint-config-0.0.5.tgz#584f6493258202a57efc22e7be66966e43832795" - integrity sha512-jwO2tnKaTPTLX5XYXMHGEnFdf543SU7jz98/OF5mDH3b7lP+BOaCD+jVfqqHoDRkcqyPlYiR1CgwVGWpi0vMWg== - dependencies: - "@typescript-eslint/eslint-plugin" "^1.5.0" - "@typescript-eslint/parser" "^1.5.0" - babel-eslint "10.0.1" - eslint-plugin-eslint-comments "^3.1.1" - eslint-plugin-flowtype "2.50.3" - eslint-plugin-jest "22.4.1" - eslint-plugin-prettier "2.6.2" - eslint-plugin-react "7.12.4" - eslint-plugin-react-hooks "^1.5.1" - eslint-plugin-react-native "3.6.0" - prettier "1.16.4" - -"@react-native-community/masked-view@^0.1.5": - version "0.1.7" - resolved "https://registry.yarnpkg.com/@react-native-community/masked-view/-/masked-view-0.1.7.tgz#a65ce0702f55cb67fd777995de6fc7b3e5781903" - integrity sha512-9KbP7LTLFz9dx1heURJbO6nuVMdSjDez8znlrUzaB1nUwKVsTTwlKRuHxGUYIIkReLWrJQeCv9tidy+84z2eCw== - -"@react-navigation/core@^3.6.1": - version "3.6.1" - resolved "https://registry.yarnpkg.com/@react-navigation/core/-/core-3.6.1.tgz#1b8922d9b0e6d74bd9d8802d1eaf21271c90a648" - integrity sha512-zjz5dUAhehqw4xO/6uNrO0LC/dlOSEh22Sa63f2nNYse1iZdcrrVGsd4EXjO4wdtLMYs/tlqAU/iayQ2hW/nMw== - dependencies: - hoist-non-react-statics "^3.3.2" - path-to-regexp "^1.8.0" - query-string "^6.11.0" - react-is "^16.8.6" - -"@react-navigation/native@^3.7.3": - version "3.7.3" - resolved "https://registry.yarnpkg.com/@react-navigation/native/-/native-3.7.3.tgz#f1869a6194cc3cc6dc520c349c7466de9c82a175" - integrity sha512-kXEmy5uNAocule6/IqFn1QeGwSojCAgliJW57jqq5kMZFX9Vi3QeM67uzPXTl1DzL0suG5e00AAsx1Hq+SYYqw== - dependencies: - hoist-non-react-statics "^3.3.2" - react-native-safe-area-view "^0.14.8" - -"@samverschueren/stream-to-observable@^0.3.0": - version "0.3.0" - resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f" - integrity sha512-MI4Xx6LHs4Webyvi6EbspgyAb4D2Q2VtnCQ1blOJcoLS6mVa8lNN2rkIy1CVxfTUpoyIbCTkXES1rLXztFD1lg== - dependencies: - any-observable "^0.3.0" - -"@types/color-name@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" - integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== - -"@types/eslint-visitor-keys@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" - integrity sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag== - -"@types/hoist-non-react-statics@^3.3.1": - version "3.3.1" - resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f" - integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA== - dependencies: - "@types/react" "*" - hoist-non-react-statics "^3.3.0" - -"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff" - integrity sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg== - -"@types/istanbul-lib-report@*": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" - integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== - dependencies: - "@types/istanbul-lib-coverage" "*" - -"@types/istanbul-reports@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz#7a8cbf6a406f36c8add871625b278eaf0b0d255a" - integrity sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA== - dependencies: - "@types/istanbul-lib-coverage" "*" - "@types/istanbul-lib-report" "*" - -"@types/json-schema@^7.0.3": - version "7.0.4" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339" - integrity sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA== - -"@types/node@^8.0.24": - version "8.10.59" - resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.59.tgz#9e34261f30183f9777017a13d185dfac6b899e04" - integrity sha512-8RkBivJrDCyPpBXhVZcjh7cQxVBSmRk9QM7hOketZzp6Tg79c0N8kkpAIito9bnJ3HCVCHVYz+KHTEbfQNfeVQ== - -"@types/prop-types@*": - version "15.7.3" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7" - integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw== - -"@types/react@*": - version "16.9.23" - resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.23.tgz#1a66c6d468ba11a8943ad958a8cb3e737568271c" - integrity sha512-SsGVT4E7L2wLN3tPYLiF20hmZTPGuzaayVunfgXzUn1x4uHVsKH6QDJQ/TdpHqwsTLd4CwrmQ2vOgxN7gE24gw== - dependencies: - "@types/prop-types" "*" - csstype "^2.2.0" - -"@types/stack-utils@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" - integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw== - -"@types/yargs-parser@*": - version "15.0.0" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-15.0.0.tgz#cb3f9f741869e20cce330ffbeb9271590483882d" - integrity sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw== - -"@types/yargs@^13.0.0": - version "13.0.8" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-13.0.8.tgz#a38c22def2f1c2068f8971acb3ea734eb3c64a99" - integrity sha512-XAvHLwG7UQ+8M4caKIH0ZozIOYay5fQkAgyIXegXT9jPtdIGdhga+sUEdAr1CiG46aB+c64xQEYyEzlwWVTNzA== - dependencies: - "@types/yargs-parser" "*" - -"@types/yargs@^15.0.0": - version "15.0.4" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.4.tgz#7e5d0f8ca25e9d5849f2ea443cf7c402decd8299" - integrity sha512-9T1auFmbPZoxHz0enUFlUuKRy3it01R+hlggyVUMtnCTQRunsQYifnSGb8hET4Xo8yiC0o0r1paW3ud5+rbURg== - dependencies: - "@types/yargs-parser" "*" - -"@typescript-eslint/eslint-plugin@^1.5.0": - version "1.13.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-1.13.0.tgz#22fed9b16ddfeb402fd7bcde56307820f6ebc49f" - integrity sha512-WQHCozMnuNADiqMtsNzp96FNox5sOVpU8Xt4meaT4em8lOG1SrOv92/mUbEHQVh90sldKSfcOc/I0FOb/14G1g== - dependencies: - "@typescript-eslint/experimental-utils" "1.13.0" - eslint-utils "^1.3.1" - functional-red-black-tree "^1.0.1" - regexpp "^2.0.1" - tsutils "^3.7.0" - -"@typescript-eslint/experimental-utils@1.13.0": - version "1.13.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-1.13.0.tgz#b08c60d780c0067de2fb44b04b432f540138301e" - integrity sha512-zmpS6SyqG4ZF64ffaJ6uah6tWWWgZ8m+c54XXgwFtUv0jNz8aJAVx8chMCvnk7yl6xwn8d+d96+tWp7fXzTuDg== - dependencies: - "@types/json-schema" "^7.0.3" - "@typescript-eslint/typescript-estree" "1.13.0" - eslint-scope "^4.0.0" - -"@typescript-eslint/parser@^1.5.0": - version "1.13.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-1.13.0.tgz#61ac7811ea52791c47dc9fd4dd4a184fae9ac355" - integrity sha512-ITMBs52PCPgLb2nGPoeT4iU3HdQZHcPaZVw+7CsFagRJHUhyeTgorEwHXhFf3e7Evzi8oujKNpHc8TONth8AdQ== - dependencies: - "@types/eslint-visitor-keys" "^1.0.0" - "@typescript-eslint/experimental-utils" "1.13.0" - "@typescript-eslint/typescript-estree" "1.13.0" - eslint-visitor-keys "^1.0.0" - -"@typescript-eslint/typescript-estree@1.13.0": - version "1.13.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-1.13.0.tgz#8140f17d0f60c03619798f1d628b8434913dc32e" - integrity sha512-b5rCmd2e6DCC6tCTN9GSUAuxdYwCM/k/2wdjHGrIRGPSJotWMCe/dGpi66u42bhuh8q3QBzqM4TMA1GUUCJvdw== - dependencies: - lodash.unescape "4.0.1" - semver "5.5.0" - -abort-controller@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" - integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== - dependencies: - event-target-shim "^5.0.0" - -absolute-path@^0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/absolute-path/-/absolute-path-0.0.0.tgz#a78762fbdadfb5297be99b15d35a785b2f095bf7" - integrity sha1-p4di+9rftSl76ZsV01p4Wy8JW/c= - -accepts@~1.3.5, accepts@~1.3.7: - version "1.3.7" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" - integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== - dependencies: - mime-types "~2.1.24" - negotiator "0.6.2" - -acorn-jsx@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.2.0.tgz#4c66069173d6fdd68ed85239fc256226182b2ebe" - integrity sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ== - -acorn@^7.1.0: - version "7.1.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.1.tgz#e35668de0b402f359de515c5482a1ab9f89a69bf" - integrity sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg== - -ajv@^6.10.0, ajv@^6.10.2, ajv@^6.5.5: - version "6.12.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.0.tgz#06d60b96d87b8454a5adaba86e7854da629db4b7" - integrity sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ansi-align@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" - integrity sha1-w2rsy6VjuJzrVW82kPCx2eNUf38= - dependencies: - string-width "^2.0.0" - -ansi-colors@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-1.1.0.tgz#6374b4dd5d4718ff3ce27a671a3b1cad077132a9" - integrity sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA== - dependencies: - ansi-wrap "^0.1.0" - -ansi-cyan@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-cyan/-/ansi-cyan-0.1.1.tgz#538ae528af8982f28ae30d86f2f17456d2609873" - integrity sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM= - dependencies: - ansi-wrap "0.1.0" - -ansi-escapes@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" - integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== - -ansi-escapes@^4.2.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.1.tgz#a5c47cc43181f1f38ffd7076837700d395522a61" - integrity sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA== - dependencies: - type-fest "^0.11.0" - -ansi-fragments@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/ansi-fragments/-/ansi-fragments-0.2.1.tgz#24409c56c4cc37817c3d7caa99d8969e2de5a05e" - integrity sha512-DykbNHxuXQwUDRv5ibc2b0x7uw7wmwOGLBUd5RmaQ5z8Lhx19vwvKV+FAsM5rEA6dEcHxX+/Ad5s9eF2k2bB+w== - dependencies: - colorette "^1.0.7" - slice-ansi "^2.0.0" - strip-ansi "^5.0.0" - -ansi-gray@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251" - integrity sha1-KWLPVOyXksSFEKPetSRDaGHvclE= - dependencies: - ansi-wrap "0.1.0" - -ansi-red@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-red/-/ansi-red-0.1.1.tgz#8c638f9d1080800a353c9c28c8a81ca4705d946c" - integrity sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw= - dependencies: - ansi-wrap "0.1.0" - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= - -ansi-regex@^4.0.0, ansi-regex@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" - integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== - -ansi-regex@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" - integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== - -ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= - -ansi-styles@^3.2.0, ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" - integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA== - dependencies: - "@types/color-name" "^1.1.1" - color-convert "^2.0.1" - -ansi-wrap@0.1.0, ansi-wrap@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" - integrity sha1-qCJQ3bABXponyoLoLqYDu/pF768= - -any-observable@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/any-observable/-/any-observable-0.3.0.tgz#af933475e5806a67d0d7df090dd5e8bef65d119b" - integrity sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog== - -anymatch@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" - integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== - dependencies: - micromatch "^3.1.4" - normalize-path "^2.1.1" - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - -arr-diff@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-1.1.0.tgz#687c32758163588fef7de7b36fabe495eb1a399a" - integrity sha1-aHwydYFjWI/vfeezb6vklesaOZo= - dependencies: - arr-flatten "^1.0.1" - array-slice "^0.2.3" - -arr-diff@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" - integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= - -arr-flatten@^1.0.1, arr-flatten@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== - -arr-union@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-2.1.0.tgz#20f9eab5ec70f5c7d215b1077b1c39161d292c7d" - integrity sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0= - -arr-union@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" - integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= - -array-filter@~0.0.0: - version "0.0.1" - resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" - integrity sha1-fajPLiZijtcygDWB/SH2fKzS7uw= - -array-find-index@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" - integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= - -array-includes@^3.0.3, array-includes@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.1.tgz#cdd67e6852bdf9c1215460786732255ed2459348" - integrity sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0" - is-string "^1.0.5" - -array-map@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662" - integrity sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI= - -array-reduce@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b" - integrity sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys= - -array-slice@^0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-0.2.3.tgz#dd3cfb80ed7973a75117cdac69b0b99ec86186f5" - integrity sha1-3Tz7gO15c6dRF82sabC5nshhhvU= - -array-unique@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= - -array.prototype.flat@^1.2.1: - version "1.2.3" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz#0de82b426b0318dbfdb940089e38b043d37f6c7b" - integrity sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - -art@^0.10.0: - version "0.10.3" - resolved "https://registry.yarnpkg.com/art/-/art-0.10.3.tgz#b01d84a968ccce6208df55a733838c96caeeaea2" - integrity sha512-HXwbdofRTiJT6qZX/FnchtldzJjS3vkLJxQilc3Xj+ma2MXjY4UAyQ0ls1XZYVnDvVIBiFZbC6QsvtW86TD6tQ== - -asap@~2.0.3: - version "2.0.6" - resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" - integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= - -asn1@~0.2.3: - version "0.2.4" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" - integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= - -assign-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" - integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= - -astral-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" - integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== - -async-limiter@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" - integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== - -async@^2.4.0: - version "2.6.3" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" - integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== - dependencies: - lodash "^4.17.14" - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= - -atob@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" - integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= - -aws4@^1.8.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e" - integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug== - -babel-code-frame@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" - integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= - dependencies: - chalk "^1.1.3" - esutils "^2.0.2" - js-tokens "^3.0.2" - -babel-eslint@10.0.1: - version "10.0.1" - resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.0.1.tgz#919681dc099614cd7d31d45c8908695092a1faed" - integrity sha512-z7OT1iNV+TjOwHNLLyJk+HN+YVWX+CLE6fPD2SymJZOZQBs+QIexFjhm4keGTm8MW9xr4EC9Q0PbaLB24V5GoQ== - dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/parser" "^7.0.0" - "@babel/traverse" "^7.0.0" - "@babel/types" "^7.0.0" - eslint-scope "3.7.1" - eslint-visitor-keys "^1.0.0" - -babel-eslint@10.0.2: - version "10.0.2" - resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.0.2.tgz#182d5ac204579ff0881684b040560fdcc1558456" - integrity sha512-UdsurWPtgiPgpJ06ryUnuaSXC2s0WoSZnQmEpbAH65XZSdwowgN5MvyP7e88nW07FYXv72erVtpBkxyDVKhH1Q== - dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/parser" "^7.0.0" - "@babel/traverse" "^7.0.0" - "@babel/types" "^7.0.0" - eslint-scope "3.7.1" - eslint-visitor-keys "^1.0.0" - -babel-helper-bindify-decorators@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz#14c19e5f142d7b47f19a52431e52b1ccbc40a330" - integrity sha1-FMGeXxQte0fxmlJDHlKxzLxAozA= - dependencies: - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" - integrity sha1-zORReto1b0IgvK6KAsKzRvmlZmQ= - dependencies: - babel-helper-explode-assignable-expression "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-call-delegate@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" - integrity sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340= - dependencies: - 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@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" - integrity sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8= - dependencies: - 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@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" - integrity sha1-8luCz33BBDPFX3BZLVdGQArCLKo= - dependencies: - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-explode-class@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz#7dc2a3910dee007056e1e31d640ced3d54eaa9eb" - integrity sha1-fcKjkQ3uAHBW4eMdZAztPVTqqes= - dependencies: - 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@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" - integrity sha1-00dbjAPtmCQqJbSDUasYOZ01gKk= - dependencies: - 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@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" - integrity sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0= - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-hoist-variables@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" - integrity sha1-HssnaJydJVE+rbyZFKc/VAi+enY= - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-optimise-call-expression@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" - integrity sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc= - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-regex@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" - integrity sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI= - dependencies: - babel-runtime "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - -babel-helper-remap-async-to-generator@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" - integrity sha1-XsWBgnrXI/7N04HxySg5BnbkVRs= - dependencies: - 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@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" - integrity sha1-v22/5Dk40XNpohPKiov3S2qQqxo= - dependencies: - 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-messages@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" - integrity sha1-8830cDhYA1sqKVHG7F7fbGLyYw4= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-check-es2015-constants@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" - integrity sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-dynamic-import-node@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz#f00f507bdaa3c3e3ff6e7e5e98d90a7acab96f7f" - integrity sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ== - dependencies: - object.assign "^4.1.0" - -babel-plugin-module-resolver@^3.1.1: - version "3.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-module-resolver/-/babel-plugin-module-resolver-3.2.0.tgz#ddfa5e301e3b9aa12d852a9979f18b37881ff5a7" - integrity sha512-tjR0GvSndzPew/Iayf4uICWZqjBwnlMWjSx6brryfQ81F9rxBVqwDJtFCV8oOs0+vJeefK9TmdZtkIFdFe1UnA== - dependencies: - find-babel-config "^1.1.0" - glob "^7.1.2" - pkg-up "^2.0.0" - reselect "^3.0.1" - resolve "^1.4.0" - -babel-plugin-syntax-async-functions@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" - integrity sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU= - -babel-plugin-syntax-async-generators@^6.5.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz#6bc963ebb16eccbae6b92b596eb7f35c342a8b9a" - integrity sha1-a8lj67FuzLrmuStZbrfzXDQqi5o= - -babel-plugin-syntax-class-properties@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de" - integrity sha1-1+sjt5oxf4VDlixQW4J8fWysJ94= - -babel-plugin-syntax-decorators@^6.13.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz#312563b4dbde3cc806cee3e416cceeaddd11ac0b" - integrity sha1-MSVjtNvePMgGzuPkFszurd0RrAs= - -babel-plugin-syntax-dynamic-import@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da" - integrity sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo= - -babel-plugin-syntax-exponentiation-operator@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" - integrity sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4= - -babel-plugin-syntax-flow@^6.8.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d" - integrity sha1-TDqyCiryaqIM0lmVw5jE63AxDI0= - -babel-plugin-syntax-object-rest-spread@^6.8.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" - integrity sha1-/WU28rzhODb/o6VFjEkDpZe7O/U= - -babel-plugin-syntax-trailing-function-commas@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" - integrity sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM= - -babel-plugin-syntax-trailing-function-commas@^7.0.0-beta.0: - version "7.0.0-beta.0" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-7.0.0-beta.0.tgz#aa213c1435e2bffeb6fca842287ef534ad05d5cf" - integrity sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ== - -babel-plugin-transform-async-generator-functions@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz#f058900145fd3e9907a6ddf28da59f215258a5db" - integrity sha1-8FiQAUX9PpkHpt3yjaWfIVJYpds= - dependencies: - 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@^6.22.0, babel-plugin-transform-async-to-generator@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" - integrity sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E= - dependencies: - 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-properties@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz#6a79763ea61d33d36f37b611aa9def81a81b46ac" - integrity sha1-anl2PqYdM9NvN7YRqp3vgagbRqw= - dependencies: - 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@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz#788013d8f8c6b5222bdf7b344390dfd77569e24d" - integrity sha1-eIAT2PjGtSIr33s0Q5Df13Vp4k0= - dependencies: - 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-es2015-arrow-functions@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" - integrity sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" - integrity sha1-u8UbSflk1wy42OC5ToICRs46YUE= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-block-scoping@^6.23.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" - integrity sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8= - dependencies: - 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@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" - integrity sha1-WkxYpQyclGHlZLSyo7+ryXolhNs= - dependencies: - 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@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" - integrity sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM= - dependencies: - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-destructuring@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" - integrity sha1-mXux8auWf2gtKwh2/jWNYOdlxW0= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-duplicate-keys@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" - integrity sha1-c+s9MQypaePvnskcU3QabxV2Qj4= - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-for-of@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" - integrity sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-function-name@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" - integrity sha1-g0yJhTvDaxrw86TF26qU/Y6sqos= - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-literals@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" - integrity sha1-T1SgLWzWbPkVKAAZox0xklN3yi4= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" - integrity sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ= - dependencies: - 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@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1: - version "6.26.2" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3" - integrity sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q== - dependencies: - 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@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" - integrity sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM= - dependencies: - babel-helper-hoist-variables "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-modules-umd@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" - integrity sha1-rJl+YoXNGO1hdq22B9YCNErThGg= - dependencies: - 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@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" - integrity sha1-JM72muIcuDp/hgPa0CH1cusnj40= - dependencies: - babel-helper-replace-supers "^6.24.1" - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-parameters@^6.23.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" - integrity sha1-V6w1GrScrxSpfNE7CfZv3wpiXys= - dependencies: - 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@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" - integrity sha1-JPh11nIch2YbvZmkYi5R8U3jiqA= - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-spread@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" - integrity sha1-1taKmfia7cRTbIGlQujdnxdG+NE= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-sticky-regex@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" - integrity sha1-AMHNsaynERLN8M9hJsLta0V8zbw= - dependencies: - babel-helper-regex "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-template-literals@^6.22.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" - integrity sha1-qEs0UPfp+PH2g51taH2oS7EjbY0= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-typeof-symbol@^6.23.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" - integrity sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-unicode-regex@^6.22.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" - integrity sha1-04sS9C6nMj9yk4fxinxa4frrNek= - dependencies: - babel-helper-regex "^6.24.1" - babel-runtime "^6.22.0" - regexpu-core "^2.0.0" - -babel-plugin-transform-exponentiation-operator@^6.22.0, babel-plugin-transform-exponentiation-operator@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" - integrity sha1-KrDJx/MJj6SJB3cruBP+QejeOg4= - dependencies: - 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-flow-comments@^6.17.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-comments/-/babel-plugin-transform-flow-comments-6.22.0.tgz#8d9491132f2b48abd0656f96c20f3bbd6fc17529" - integrity sha1-jZSREy8rSKvQZW+Wwg87vW/BdSk= - dependencies: - babel-plugin-syntax-flow "^6.8.0" - babel-runtime "^6.22.0" - -babel-plugin-transform-object-rest-spread@^6.22.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz#0f36692d50fef6b7e2d4b3ac1478137a963b7b06" - integrity sha1-DzZpLVD+9rfi1LOsFHgTepY7ewY= - dependencies: - babel-plugin-syntax-object-rest-spread "^6.8.0" - babel-runtime "^6.26.0" - -babel-plugin-transform-regenerator@^6.22.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" - integrity sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8= - dependencies: - regenerator-transform "^0.10.0" - -babel-plugin-transform-strict-mode@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" - integrity sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g= - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-preset-env@^1.6.1: - version "1.7.0" - resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.7.0.tgz#dea79fa4ebeb883cd35dab07e260c1c9c04df77a" - integrity sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg== - dependencies: - babel-plugin-check-es2015-constants "^6.22.0" - babel-plugin-syntax-trailing-function-commas "^6.22.0" - babel-plugin-transform-async-to-generator "^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.23.0" - babel-plugin-transform-es2015-classes "^6.23.0" - babel-plugin-transform-es2015-computed-properties "^6.22.0" - babel-plugin-transform-es2015-destructuring "^6.23.0" - babel-plugin-transform-es2015-duplicate-keys "^6.22.0" - babel-plugin-transform-es2015-for-of "^6.23.0" - babel-plugin-transform-es2015-function-name "^6.22.0" - babel-plugin-transform-es2015-literals "^6.22.0" - babel-plugin-transform-es2015-modules-amd "^6.22.0" - babel-plugin-transform-es2015-modules-commonjs "^6.23.0" - babel-plugin-transform-es2015-modules-systemjs "^6.23.0" - babel-plugin-transform-es2015-modules-umd "^6.23.0" - babel-plugin-transform-es2015-object-super "^6.22.0" - babel-plugin-transform-es2015-parameters "^6.23.0" - babel-plugin-transform-es2015-shorthand-properties "^6.22.0" - babel-plugin-transform-es2015-spread "^6.22.0" - babel-plugin-transform-es2015-sticky-regex "^6.22.0" - babel-plugin-transform-es2015-template-literals "^6.22.0" - babel-plugin-transform-es2015-typeof-symbol "^6.23.0" - babel-plugin-transform-es2015-unicode-regex "^6.22.0" - babel-plugin-transform-exponentiation-operator "^6.22.0" - babel-plugin-transform-regenerator "^6.22.0" - browserslist "^3.2.6" - invariant "^2.2.2" - semver "^5.3.0" - -babel-preset-fbjs@^3.1.2, babel-preset-fbjs@^3.2.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/babel-preset-fbjs/-/babel-preset-fbjs-3.3.0.tgz#a6024764ea86c8e06a22d794ca8b69534d263541" - integrity sha512-7QTLTCd2gwB2qGoi5epSULMHugSVgpcVt5YAeiFO9ABLrutDQzKfGwzxgZHLpugq8qMdg/DhRZDZ5CLKxBkEbw== - dependencies: - "@babel/plugin-proposal-class-properties" "^7.0.0" - "@babel/plugin-proposal-object-rest-spread" "^7.0.0" - "@babel/plugin-syntax-class-properties" "^7.0.0" - "@babel/plugin-syntax-flow" "^7.0.0" - "@babel/plugin-syntax-jsx" "^7.0.0" - "@babel/plugin-syntax-object-rest-spread" "^7.0.0" - "@babel/plugin-transform-arrow-functions" "^7.0.0" - "@babel/plugin-transform-block-scoped-functions" "^7.0.0" - "@babel/plugin-transform-block-scoping" "^7.0.0" - "@babel/plugin-transform-classes" "^7.0.0" - "@babel/plugin-transform-computed-properties" "^7.0.0" - "@babel/plugin-transform-destructuring" "^7.0.0" - "@babel/plugin-transform-flow-strip-types" "^7.0.0" - "@babel/plugin-transform-for-of" "^7.0.0" - "@babel/plugin-transform-function-name" "^7.0.0" - "@babel/plugin-transform-literals" "^7.0.0" - "@babel/plugin-transform-member-expression-literals" "^7.0.0" - "@babel/plugin-transform-modules-commonjs" "^7.0.0" - "@babel/plugin-transform-object-super" "^7.0.0" - "@babel/plugin-transform-parameters" "^7.0.0" - "@babel/plugin-transform-property-literals" "^7.0.0" - "@babel/plugin-transform-react-display-name" "^7.0.0" - "@babel/plugin-transform-react-jsx" "^7.0.0" - "@babel/plugin-transform-shorthand-properties" "^7.0.0" - "@babel/plugin-transform-spread" "^7.0.0" - "@babel/plugin-transform-template-literals" "^7.0.0" - babel-plugin-syntax-trailing-function-commas "^7.0.0-beta.0" - -babel-preset-stage-2@^6.18.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz#d9e2960fb3d71187f0e64eec62bc07767219bdc1" - integrity sha1-2eKWD7PXEYfw5k7sYrwHdnIZvcE= - dependencies: - 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@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz#836ada0a9e7a7fa37cb138fb9326f87934a48395" - integrity sha1-g2raCp56f6N8sTj7kyb4eTSkg5U= - dependencies: - 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-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" - integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= - dependencies: - core-js "^2.4.0" - regenerator-runtime "^0.11.0" - -babel-template@^6.24.1, babel-template@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" - integrity sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI= - dependencies: - 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@^6.24.1, babel-traverse@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" - integrity sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4= - dependencies: - 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@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" - integrity sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc= - dependencies: - babel-runtime "^6.26.0" - esutils "^2.0.2" - lodash "^4.17.4" - to-fast-properties "^1.0.3" - -babylon@^6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" - integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== - -balanced-match@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" - integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= - -base-64@0.1.0, base-64@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/base-64/-/base-64-0.1.0.tgz#780a99c84e7d600260361511c4877613bf24f6bb" - integrity sha1-eAqZyE59YAJgNhURxId2E78k9rs= - -base64-js@^1.1.2, base64-js@^1.2.3: - version "1.3.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" - integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== - -base@^0.11.1: - version "0.11.2" - resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" - integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== - dependencies: - 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" - -basic-auth@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-2.0.1.tgz#b998279bf47ce38344b4f3cf916d4679bbf51e3a" - integrity sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg== - dependencies: - safe-buffer "5.1.2" - -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= - dependencies: - tweetnacl "^0.14.3" - -big-integer@^1.6.44: - version "1.6.48" - resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.48.tgz#8fd88bd1632cba4a1c8c3e3d7159f08bb95b4b9e" - integrity sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w== - -bindings@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" - integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== - dependencies: - file-uri-to-path "1.0.0" - -boxen@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" - integrity sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw== - dependencies: - ansi-align "^2.0.0" - camelcase "^4.0.0" - chalk "^2.0.1" - cli-boxes "^1.0.0" - string-width "^2.0.0" - term-size "^1.2.0" - widest-line "^2.0.0" - -bplist-creator@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/bplist-creator/-/bplist-creator-0.0.8.tgz#56b2a6e79e9aec3fc33bf831d09347d73794e79c" - integrity sha512-Za9JKzD6fjLC16oX2wsXfc+qBEhJBJB1YPInoAQpMLhDuj5aVOv1baGeIQSq1Fr3OCqzvsoQcSBSwGId/Ja2PA== - dependencies: - stream-buffers "~2.2.0" - -bplist-parser@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.2.0.tgz#43a9d183e5bf9d545200ceac3e712f79ebbe8d0e" - integrity sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw== - dependencies: - big-integer "^1.6.44" - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@^2.3.1: - version "2.3.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" - integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== - dependencies: - 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" - -browserslist@^3.2.6: - version "3.2.8" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.2.8.tgz#b0005361d6471f0f5952797a76fc985f1f978fc6" - integrity sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ== - dependencies: - caniuse-lite "^1.0.30000844" - electron-to-chromium "^1.3.47" - -bser@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" - integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== - dependencies: - node-int64 "^0.4.0" - -buffer-crc32@^0.2.13: - version "0.2.13" - resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" - integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= - -buffer-from@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== - -bytes@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" - integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= - -cache-base@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" - integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== - dependencies: - 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" - -caller-callsite@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" - integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= - dependencies: - callsites "^2.0.0" - -caller-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" - integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= - dependencies: - caller-callsite "^2.0.0" - -callsites@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" - integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -camelcase-keys@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" - integrity sha1-MIvur/3ygRkFHvodkyITyRuPkuc= - dependencies: - camelcase "^2.0.0" - map-obj "^1.0.0" - -camelcase@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" - integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= - -camelcase@^4.0.0, camelcase@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" - integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= - -camelcase@^5.0.0, camelcase@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - -caniuse-lite@^1.0.30000844: - version "1.0.30001032" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001032.tgz#b8d224914e2cd7f507085583d4e38144c652bce4" - integrity sha512-8joOm7BwcpEN4BfVHtfh0hBXSAPVYk+eUIcNntGtMkUWy/6AKRCDZINCLe3kB1vHhT2vBxBF85Hh9VlPXi/qjA== - -capture-exit@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" - integrity sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g== - dependencies: - rsvp "^4.8.4" - -capture-stack-trace@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d" - integrity sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw== - -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= - -chalk@^1.0.0, chalk@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= - dependencies: - 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" - -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.1, chalk@^2.4.1, chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" - integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chardet@^0.4.0: - version "0.4.2" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" - integrity sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I= - -chardet@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" - integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== - -ci-info@^1.5.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" - integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A== - -ci-info@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" - integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== - -class-utils@^0.3.5: - version "0.3.6" - resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" - integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== - dependencies: - arr-union "^3.1.0" - define-property "^0.2.5" - isobject "^3.0.0" - static-extend "^0.1.1" - -cli-boxes@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" - integrity sha1-T6kXw+WclKAEzWH47lCdplFocUM= - -cli-cursor@^2.0.0, cli-cursor@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" - integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= - dependencies: - restore-cursor "^2.0.0" - -cli-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" - integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== - dependencies: - restore-cursor "^3.1.0" - -cli-spinners@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.2.0.tgz#e8b988d9206c692302d8ee834e7a85c0144d8f77" - integrity sha512-tgU3fKwzYjiLEQgPMD9Jt+JjHVL9kW93FiIMX/l7rivvOD4/LL0Mf7gda3+4U2KJBloybwgj5KEoQgGRioMiKQ== - -cli-truncate@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574" - integrity sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ= - dependencies: - slice-ansi "0.0.4" - string-width "^1.0.1" - -cli-width@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" - integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= - -cliui@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" - integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - wrap-ansi "^2.0.0" - -cliui@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" - integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ== - dependencies: - string-width "^2.1.1" - strip-ansi "^4.0.0" - wrap-ansi "^2.0.0" - -cliui@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" - integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== - dependencies: - string-width "^3.1.0" - strip-ansi "^5.2.0" - wrap-ansi "^5.1.0" - -clone@^1.0.2: - version "1.0.4" - resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" - integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= - -collection-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" - integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= - dependencies: - map-visit "^1.0.0" - object-visit "^1.0.0" - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -color-support@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" - integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== - -colorette@^1.0.7: - version "1.1.0" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.1.0.tgz#1f943e5a357fac10b4e0f5aaef3b14cdc1af6ec7" - integrity sha512-6S062WDQUXi6hOfkO/sBPVwE5ASXY4G2+b4atvhJfSsuUUhIaUKlkjLe9692Ipyt5/a+IPF5aVTu3V5gvXq5cg== - -combined-stream@^1.0.6, combined-stream@~1.0.6: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - -command-exists@^1.2.8: - version "1.2.8" - resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.8.tgz#715acefdd1223b9c9b37110a149c6392c2852291" - integrity sha512-PM54PkseWbiiD/mMsbvW351/u+dafwTJ0ye2qB60G1aGQP9j3xK2gmMDc+R34L3nDtx4qMCitXT75mkbkGJDLw== - -commander@^2.14.1, commander@^2.19.0, commander@^2.9.0: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - -commander@~2.13.0: - version "2.13.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" - integrity sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA== - -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= - -component-emitter@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" - integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== - -compressible@~2.0.16: - version "2.0.18" - resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" - integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== - dependencies: - mime-db ">= 1.43.0 < 2" - -compression@^1.7.1: - version "1.7.4" - resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" - integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== - dependencies: - accepts "~1.3.5" - bytes "3.0.0" - compressible "~2.0.16" - debug "2.6.9" - on-headers "~1.0.2" - safe-buffer "5.1.2" - vary "~1.1.2" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= - -concat-stream@1.6.2, concat-stream@^1.6.0: - version "1.6.2" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" - integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - -configstore@^3.0.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.2.tgz#c6f25defaeef26df12dd33414b001fe81a543f8f" - integrity sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw== - dependencies: - dot-prop "^4.1.0" - graceful-fs "^4.1.2" - make-dir "^1.0.0" - unique-string "^1.0.0" - write-file-atomic "^2.0.0" - xdg-basedir "^3.0.0" - -connect@^3.6.5: - version "3.7.0" - resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" - integrity sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ== - dependencies: - debug "2.6.9" - finalhandler "1.1.2" - parseurl "~1.3.3" - utils-merge "1.0.1" - -contains-path@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" - integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= - -convert-source-map@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" - integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== - dependencies: - safe-buffer "~5.1.1" - -copy-descriptor@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= - -core-js@^1.0.0: - version "1.2.7" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" - integrity sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY= - -core-js@^2.2.2, core-js@^2.4.0, core-js@^2.4.1: - version "2.6.11" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c" - integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg== - -core-util-is@1.0.2, core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= - -cosmiconfig@^5.0.2, cosmiconfig@^5.0.5, cosmiconfig@^5.1.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" - integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA== - dependencies: - import-fresh "^2.0.0" - is-directory "^0.3.1" - js-yaml "^3.13.1" - parse-json "^4.0.0" - -create-error-class@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" - integrity sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y= - dependencies: - capture-stack-trace "^1.0.0" - -create-react-class@^15.6.3: - version "15.6.3" - resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.6.3.tgz#2d73237fb3f970ae6ebe011a9e66f46dbca80036" - integrity sha512-M+/3Q6E6DLO6Yx3OwrWjwHBnvfXXYA7W+dFjt/ZDBemHO1DDZhsalX/NUtnTYclN6GfnBDRh4qRHjcDHmlJBJg== - dependencies: - fbjs "^0.8.9" - loose-envify "^1.3.1" - object-assign "^4.1.1" - -cross-spawn@^5.0.1, cross-spawn@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" - integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= - dependencies: - lru-cache "^4.0.1" - shebang-command "^1.2.0" - which "^1.2.9" - -cross-spawn@^6.0.0, cross-spawn@^6.0.5: - version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== - dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" - -crypto-random-string@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" - integrity sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4= - -csstype@^2.2.0: - version "2.6.9" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.9.tgz#05141d0cd557a56b8891394c1911c40c8a98d098" - integrity sha512-xz39Sb4+OaTsULgUERcCk+TJj8ylkL4aSVDQiX/ksxbELSqwkgt4d4RD7fovIdgJGSuNYqwZEiVjYY5l0ask+Q== - -currently-unhandled@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" - integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= - dependencies: - array-find-index "^1.0.1" - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= - dependencies: - assert-plus "^1.0.0" - -date-fns@^1.27.2: - version "1.30.1" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c" - integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw== - -dayjs@^1.8.15: - version "1.8.21" - resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.21.tgz#98299185b72b9b679f31c7ed987b63923c961552" - integrity sha512-1kbWK0hziklUHkGgiKr7xm59KwAg/K3Tp7H/8X+f58DnNCwY3pKYjOCJpIlVs125FRBukGVZdKZojC073D0IeQ== - -debounce@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.0.tgz#44a540abc0ea9943018dc0eaa95cce87f65cd131" - integrity sha512-mYtLl1xfZLi1m4RtQYlZgJUNQjl4ZxVnHzIR8nLLgi4q1YT8o/WM+MK/f8yfcc9s5Ir5zRaPZyZU6xs1Syoocg== - -debug@2.6.9, debug@^2.1.3, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@^3.1.0: - version "3.2.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== - dependencies: - ms "^2.1.1" - -debug@^4.0.1, debug@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" - integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== - dependencies: - ms "^2.1.1" - -decamelize@^1.1.1, decamelize@^1.1.2, decamelize@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= - -decode-uri-component@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" - integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= - -dedent@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" - integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= - -deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - -deep-is@~0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" - integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= - -deepmerge@^3.2.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-3.3.0.tgz#d3c47fd6f3a93d517b14426b0628a17b0125f5f7" - integrity sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA== - -defaults@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" - integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730= - dependencies: - clone "^1.0.2" - -define-properties@^1.1.2, define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== - dependencies: - object-keys "^1.0.12" - -define-property@^0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" - integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= - dependencies: - is-descriptor "^0.1.0" - -define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" - integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= - dependencies: - is-descriptor "^1.0.0" - -define-property@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" - integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== - dependencies: - is-descriptor "^1.0.2" - isobject "^3.0.1" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= - -denodeify@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/denodeify/-/denodeify-1.2.1.tgz#3a36287f5034e699e7577901052c2e6c94251631" - integrity sha1-OjYof1A05pnnV3kBBSwubJQlFjE= - -depd@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= - -destroy@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" - integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= - -didyoumean@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.1.tgz#e92edfdada6537d484d73c0172fd1eba0c4976ff" - integrity sha1-6S7f2tplN9SE1zwBcv0eugxJdv8= - -doctrine@1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" - integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= - dependencies: - esutils "^2.0.2" - isarray "^1.0.0" - -doctrine@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" - integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== - dependencies: - esutils "^2.0.2" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - -dot-prop@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" - integrity sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ== - dependencies: - is-obj "^1.0.0" - -duplexer3@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" - integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= - -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= - -electron-download@^3.0.1: - version "3.3.0" - resolved "https://registry.yarnpkg.com/electron-download/-/electron-download-3.3.0.tgz#2cfd54d6966c019c4d49ad65fbe65cc9cdef68c8" - integrity sha1-LP1U1pZsAZxNSa1l++Zcyc3vaMg= - dependencies: - debug "^2.2.0" - fs-extra "^0.30.0" - home-path "^1.0.1" - minimist "^1.2.0" - nugget "^2.0.0" - path-exists "^2.1.0" - rc "^1.1.2" - semver "^5.3.0" - sumchecker "^1.2.0" - -electron-to-chromium@^1.3.47: - version "1.3.370" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.370.tgz#420fba483d30ba3f7965b30ecf850fdb5f08a0bc" - integrity sha512-399cXDE9C7qoVF2CUgCA/MLflfvxbo1F0kB/pkB94426freL/JgZ0HNaloomsOfnE+VC/qgTFZqzmivSdaNfPQ== - -electron@^1.8.7: - version "1.8.8" - resolved "https://registry.yarnpkg.com/electron/-/electron-1.8.8.tgz#a90cddb075291f49576993e6f5c8bb4439301cae" - integrity sha512-1f9zJehcTTGjrkb06o6ds+gsRq6SYhZJyxOk6zIWjRH8hVy03y/RzUDELzNas71f5vcvXmfGVvyjeEsadDI8tg== - dependencies: - "@types/node" "^8.0.24" - electron-download "^3.0.1" - extract-zip "^1.0.3" - -elegant-spinner@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e" - integrity sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4= - -eme-encryption-scheme-polyfill@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/eme-encryption-scheme-polyfill/-/eme-encryption-scheme-polyfill-2.0.1.tgz#b080b01bffd74c75c9cf8044c1cabedf3b83954f" - integrity sha512-Wz+Ro1c0/2Wsx2RLFvTOO0m4LvYn+7cSnq3XOvRvLLBq8jbvUACH/zpU9s0/5+mQa5oaelkU69x+q0z/iWYrFA== - -emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" - integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= - -encoding@^0.1.11: - version "0.1.12" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" - integrity sha1-U4tm8+5izRq1HsMjgp0flIDHS+s= - dependencies: - iconv-lite "~0.4.13" - -end-of-stream@^1.1.0: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - -envinfo@^7.1.0: - version "7.5.0" - resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.5.0.tgz#91410bb6db262fb4f1409bd506e9ff57e91023f4" - integrity sha512-jDgnJaF/Btomk+m3PZDTTCb5XIIIX3zYItnCRfF73zVgvinLoRomuhi75Y4su0PtQxWz4v66XnLLckyvyJTOIQ== - -error-ex@^1.2.0, error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -errorhandler@^1.5.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/errorhandler/-/errorhandler-1.5.1.tgz#b9ba5d17cf90744cd1e851357a6e75bf806a9a91" - integrity sha512-rcOwbfvP1WTViVoUjcfZicVzjhjTuhSMntHh6mW3IrEiyE6mJyXvsToJUJGlGlw/2xU9P5whlWNGlIDVeCiT4A== - dependencies: - accepts "~1.3.7" - escape-html "~1.0.3" - -es-abstract@^1.17.0, es-abstract@^1.17.0-next.1: - version "1.17.4" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.4.tgz#e3aedf19706b20e7c2594c35fc0d57605a79e184" - integrity sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ== - dependencies: - 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" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -es6-promise@^4.0.5: - version "4.2.8" - resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" - integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== - -escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= - -escape-string-regexp@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" - integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== - -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= - -eslint-config-standard-jsx@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/eslint-config-standard-jsx/-/eslint-config-standard-jsx-6.0.2.tgz#90c9aa16ac2c4f8970c13fc7efc608bacd02da70" - integrity sha512-D+YWAoXw+2GIdbMBRAzWwr1ZtvnSf4n4yL0gKGg7ShUOGXkSOLerI17K4F6LdQMJPNMoWYqepzQD/fKY+tXNSg== - -eslint-config-standard@^12.0.0: - version "12.0.0" - resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-12.0.0.tgz#638b4c65db0bd5a41319f96bba1f15ddad2107d9" - integrity sha512-COUz8FnXhqFitYj4DTqHzidjIL/t4mumGZto5c7DrBpvWoie+Sn3P4sLEzUGeYhRElWuFEf8K1S1EfvD1vixCQ== - -eslint-import-resolver-node@^0.3.2: - version "0.3.3" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz#dbaa52b6b2816b50bc6711af75422de808e98404" - integrity sha512-b8crLDo0M5RSe5YG8Pu2DYBj71tSB6OvXkfzwbJU2w7y8P4/yo0MyF8jU26IEuEuHF2K5/gcAJE3LhQGqBBbVg== - dependencies: - debug "^2.6.9" - resolve "^1.13.1" - -eslint-module-utils@^2.4.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.5.2.tgz#7878f7504824e1b857dd2505b59a8e5eda26a708" - integrity sha512-LGScZ/JSlqGKiT8OC+cYRxseMjyqt6QO54nl281CK93unD89ijSeRV6An8Ci/2nvWVKe8K/Tqdm75RQoIOCr+Q== - dependencies: - debug "^2.6.9" - pkg-dir "^2.0.0" - -eslint-plugin-es@^1.3.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-1.4.1.tgz#12acae0f4953e76ba444bfd1b2271081ac620998" - integrity sha512-5fa/gR2yR3NxQf+UXkeLeP8FBBl6tSgdrAz1+cF84v1FMM4twGwQoqTnn+QxFLcPOrF4pdKEJKDB/q9GoyJrCA== - dependencies: - eslint-utils "^1.4.2" - regexpp "^2.0.1" - -eslint-plugin-eslint-comments@^3.1.1: - version "3.1.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.1.2.tgz#4ef6c488dbe06aa1627fea107b3e5d059fc8a395" - integrity sha512-QexaqrNeteFfRTad96W+Vi4Zj1KFbkHHNMMaHZEYcovKav6gdomyGzaxSDSL3GoIyUOo078wRAdYlu1caiauIQ== - dependencies: - escape-string-regexp "^1.0.5" - ignore "^5.0.5" - -eslint-plugin-flowtype@2.50.3, eslint-plugin-flowtype@^2.46.1: - version "2.50.3" - resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.50.3.tgz#61379d6dce1d010370acd6681740fd913d68175f" - integrity sha512-X+AoKVOr7Re0ko/yEXyM5SSZ0tazc6ffdIOocp2fFUlWoDt7DV0Bz99mngOkAFLOAWjqRA5jPwqUCbrx13XoxQ== - dependencies: - lodash "^4.17.10" - -eslint-plugin-import@^2.17.2: - version "2.20.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.20.1.tgz#802423196dcb11d9ce8435a5fc02a6d3b46939b3" - integrity sha512-qQHgFOTjguR+LnYRoToeZWT62XM55MBVXObHM6SKFd1VzDcX/vqT1kAz8ssqigh5eMj8qXcRoXXGZpPP6RfdCw== - dependencies: - array-includes "^3.0.3" - array.prototype.flat "^1.2.1" - contains-path "^0.1.0" - debug "^2.6.9" - doctrine "1.5.0" - eslint-import-resolver-node "^0.3.2" - eslint-module-utils "^2.4.1" - has "^1.0.3" - minimatch "^3.0.4" - object.values "^1.1.0" - read-pkg-up "^2.0.0" - resolve "^1.12.0" - -eslint-plugin-jest@22.4.1: - version "22.4.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-22.4.1.tgz#a5fd6f7a2a41388d16f527073b778013c5189a9c" - integrity sha512-gcLfn6P2PrFAVx3AobaOzlIEevpAEf9chTpFZz7bYfc7pz8XRv7vuKTIE4hxPKZSha6XWKKplDQ0x9Pq8xX2mg== - -eslint-plugin-node@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-8.0.1.tgz#55ae3560022863d141fa7a11799532340a685964" - integrity sha512-ZjOjbjEi6jd82rIpFSgagv4CHWzG9xsQAVp1ZPlhRnnYxcTgENUVBvhYmkQ7GvT1QFijUSo69RaiOJKhMu6i8w== - dependencies: - eslint-plugin-es "^1.3.1" - eslint-utils "^1.3.1" - ignore "^5.0.2" - minimatch "^3.0.4" - resolve "^1.8.1" - semver "^5.5.0" - -eslint-plugin-prettier@2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-2.6.2.tgz#71998c60aedfa2141f7bfcbf9d1c459bf98b4fad" - integrity sha512-tGek5clmW5swrAx1mdPYM8oThrBE83ePh7LeseZHBWfHVGrHPhKn7Y5zgRMbU/9D5Td9K4CEmUPjGxA7iw98Og== - dependencies: - fast-diff "^1.1.1" - jest-docblock "^21.0.0" - -eslint-plugin-promise@^4.1.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz#845fd8b2260ad8f82564c1222fce44ad71d9418a" - integrity sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw== - -eslint-plugin-react-hooks@^1.5.1: - version "1.7.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.7.0.tgz#6210b6d5a37205f0b92858f895a4e827020a7d04" - integrity sha512-iXTCFcOmlWvw4+TOE8CLWj6yX1GwzT0Y6cUfHHZqWnSk144VmVIRcVGtUAzrLES7C798lmvnt02C7rxaOX1HNA== - -eslint-plugin-react-native-globals@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-native-globals/-/eslint-plugin-react-native-globals-0.1.2.tgz#ee1348bc2ceb912303ce6bdbd22e2f045ea86ea2" - integrity sha512-9aEPf1JEpiTjcFAmmyw8eiIXmcNZOqaZyHO77wgm0/dWfT/oxC1SrIq8ET38pMxHYrcB6Uew+TzUVsBeczF88g== - -eslint-plugin-react-native@3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-native/-/eslint-plugin-react-native-3.6.0.tgz#7cad3b7c6159df6d26fe3252c6c5417a17f27b4b" - integrity sha512-BEQcHZ06hZSBYWFVuNEq0xuui5VEsWpHDsZGBtfadHfCRqRMUrkYPgdDb3bpc60qShHE83kqIv59uKdinEg91Q== - dependencies: - eslint-plugin-react-native-globals "^0.1.1" - -eslint-plugin-react@7.12.4: - version "7.12.4" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.12.4.tgz#b1ecf26479d61aee650da612e425c53a99f48c8c" - integrity sha512-1puHJkXJY+oS1t467MjbqjvX53uQ05HXwjqDgdbGBqf5j9eeydI54G3KwiJmWciQ0HTBacIKw2jgwSBSH3yfgQ== - dependencies: - array-includes "^3.0.3" - doctrine "^2.1.0" - has "^1.0.3" - jsx-ast-utils "^2.0.1" - object.fromentries "^2.0.0" - prop-types "^15.6.2" - resolve "^1.9.0" - -eslint-plugin-react@^7.12.4: - version "7.18.3" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.18.3.tgz#8be671b7f6be095098e79d27ac32f9580f599bc8" - integrity sha512-Bt56LNHAQCoou88s8ViKRjMB2+36XRejCQ1VoLj716KI1MoE99HpTVvIThJ0rvFmG4E4Gsq+UgToEjn+j044Bg== - dependencies: - array-includes "^3.1.1" - doctrine "^2.1.0" - has "^1.0.3" - jsx-ast-utils "^2.2.3" - object.entries "^1.1.1" - object.fromentries "^2.0.2" - object.values "^1.1.1" - prop-types "^15.7.2" - resolve "^1.14.2" - string.prototype.matchall "^4.0.2" - -eslint-plugin-standard@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-4.0.1.tgz#ff0519f7ffaff114f76d1bd7c3996eef0f6e20b4" - integrity sha512-v/KBnfyaOMPmZc/dmc6ozOdWqekGp7bBGq4jLAecEfPGmfKiWS4sA8sC0LqiV9w5qmXAtXVn4M3p1jSyhY85SQ== - -eslint-scope@3.7.1: - version "3.7.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" - integrity sha1-PWPD7f2gLgbgGkUq2IyqzHzctug= - dependencies: - esrecurse "^4.1.0" - estraverse "^4.1.1" - -eslint-scope@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" - integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== - dependencies: - esrecurse "^4.1.0" - estraverse "^4.1.1" - -eslint-scope@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.0.0.tgz#e87c8887c73e8d1ec84f1ca591645c358bfc8fb9" - integrity sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw== - dependencies: - esrecurse "^4.1.0" - estraverse "^4.1.1" - -eslint-utils@^1.3.1, eslint-utils@^1.4.2, eslint-utils@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" - integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== - dependencies: - eslint-visitor-keys "^1.1.0" - -eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" - integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== - -eslint@^6.5.1: - version "6.8.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.8.0.tgz#62262d6729739f9275723824302fb227c8c93ffb" - integrity sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig== - dependencies: - "@babel/code-frame" "^7.0.0" - ajv "^6.10.0" - chalk "^2.1.0" - cross-spawn "^6.0.5" - debug "^4.0.1" - doctrine "^3.0.0" - eslint-scope "^5.0.0" - eslint-utils "^1.4.3" - eslint-visitor-keys "^1.1.0" - espree "^6.1.2" - esquery "^1.0.1" - esutils "^2.0.2" - file-entry-cache "^5.0.1" - functional-red-black-tree "^1.0.1" - glob-parent "^5.0.0" - globals "^12.1.0" - ignore "^4.0.6" - import-fresh "^3.0.0" - imurmurhash "^0.1.4" - inquirer "^7.0.0" - is-glob "^4.0.0" - js-yaml "^3.13.1" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.3.0" - lodash "^4.17.14" - minimatch "^3.0.4" - mkdirp "^0.5.1" - natural-compare "^1.4.0" - optionator "^0.8.3" - progress "^2.0.0" - regexpp "^2.0.1" - semver "^6.1.2" - strip-ansi "^5.2.0" - strip-json-comments "^3.0.1" - table "^5.2.3" - text-table "^0.2.0" - v8-compile-cache "^2.0.3" - -espree@^6.1.2: - version "6.2.0" - resolved "https://registry.yarnpkg.com/espree/-/espree-6.2.0.tgz#349fef01a202bbab047748300deb37fa44da79d7" - integrity sha512-Xs8airJ7RQolnDIbLtRutmfvSsAe0xqMMAantCN/GMoqf81TFbeI1T7Jpd56qYu1uuh32dOG5W/X9uO+ghPXzA== - dependencies: - acorn "^7.1.0" - acorn-jsx "^5.2.0" - eslint-visitor-keys "^1.1.0" - -esprima@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - -esquery@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.1.0.tgz#c5c0b66f383e7656404f86b31334d72524eddb48" - integrity sha512-MxYW9xKmROWF672KqjO75sszsA8Mxhw06YFeS5VHlB98KDHbOSurm3ArsjO60Eaf3QmGMCP1yn+0JQkNLo/97Q== - dependencies: - estraverse "^4.0.0" - -esrecurse@^4.1.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" - integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== - dependencies: - estraverse "^4.1.0" - -estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -esutils@^2.0.0, esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= - -event-target-shim@^5.0.0, event-target-shim@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" - integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== - -eventemitter3@^3.0.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7" - integrity sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q== - -exec-sh@^0.3.2: - version "0.3.4" - resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.4.tgz#3a018ceb526cc6f6df2bb504b2bfe8e3a4934ec5" - integrity sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A== - -execa@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" - integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c= - dependencies: - cross-spawn "^5.0.1" - get-stream "^3.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - -execa@^0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.9.0.tgz#adb7ce62cf985071f60580deb4a88b9e34712d01" - integrity sha512-BbUMBiX4hqiHZUA5+JujIjNb6TyAlp2D5KLheMjMluwOuzcnylDL4AxZYLLn1n2AGB49eSWwyKvvEQoRpnAtmA== - dependencies: - cross-spawn "^5.0.1" - get-stream "^3.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - -execa@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" - integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== - dependencies: - cross-spawn "^6.0.0" - get-stream "^4.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - -expand-brackets@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" - integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= - dependencies: - 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" - -extend-shallow@^1.1.2: - version "1.1.4" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-1.1.4.tgz#19d6bf94dfc09d76ba711f39b872d21ff4dd9071" - integrity sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE= - dependencies: - kind-of "^1.1.0" - -extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= - dependencies: - is-extendable "^0.1.0" - -extend-shallow@^3.0.0, extend-shallow@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" - integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= - dependencies: - assign-symbols "^1.0.0" - is-extendable "^1.0.1" - -extend@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - -external-editor@^2.0.4: - version "2.2.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" - integrity sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A== - dependencies: - chardet "^0.4.0" - iconv-lite "^0.4.17" - tmp "^0.0.33" - -external-editor@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" - integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== - dependencies: - chardet "^0.7.0" - iconv-lite "^0.4.24" - tmp "^0.0.33" - -extglob@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" - integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== - dependencies: - 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" - -extract-zip@^1.0.3: - version "1.6.7" - resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.6.7.tgz#a840b4b8af6403264c8db57f4f1a74333ef81fe9" - integrity sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k= - dependencies: - concat-stream "1.6.2" - debug "2.6.9" - mkdirp "0.5.1" - yauzl "2.4.1" - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= - -extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= - -fancy-log@^1.3.2: - version "1.3.3" - resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.3.tgz#dbc19154f558690150a23953a0adbd035be45fc7" - integrity sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw== - dependencies: - ansi-gray "^0.1.1" - color-support "^1.1.3" - parse-node-version "^1.0.0" - time-stamp "^1.0.0" - -fast-deep-equal@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" - integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== - -fast-diff@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" - integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-levenshtein@~2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= - -fb-watchman@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" - integrity sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg== - dependencies: - bser "2.1.1" - -fbjs-css-vars@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz#216551136ae02fe255932c3ec8775f18e2c078b8" - integrity sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ== - -fbjs-scripts@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/fbjs-scripts/-/fbjs-scripts-1.2.0.tgz#069a0c0634242d10031c6460ef1fccefcdae8b27" - integrity sha512-5krZ8T0Bf8uky0abPoCLrfa7Orxd8UH4Qq8hRUF2RZYNMu+FmEOrBc7Ib3YVONmxTXTlLAvyrrdrVmksDb2OqQ== - dependencies: - "@babel/core" "^7.0.0" - ansi-colors "^1.0.1" - babel-preset-fbjs "^3.2.0" - core-js "^2.4.1" - cross-spawn "^5.1.0" - fancy-log "^1.3.2" - object-assign "^4.0.1" - plugin-error "^0.1.2" - semver "^5.1.0" - through2 "^2.0.0" - -fbjs@^0.8.9: - version "0.8.17" - resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd" - integrity sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90= - dependencies: - core-js "^1.0.0" - isomorphic-fetch "^2.1.1" - loose-envify "^1.0.0" - object-assign "^4.1.0" - promise "^7.1.1" - setimmediate "^1.0.5" - ua-parser-js "^0.7.18" - -fbjs@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-1.0.0.tgz#52c215e0883a3c86af2a7a776ed51525ae8e0a5a" - integrity sha512-MUgcMEJaFhCaF1QtWGnmq9ZDRAzECTCRAF7O6UZIlAlkTs1SasiX9aP0Iw7wfD2mJ7wDTNfg2w7u5fSCwJk1OA== - dependencies: - core-js "^2.4.1" - fbjs-css-vars "^1.0.0" - isomorphic-fetch "^2.1.1" - loose-envify "^1.0.0" - object-assign "^4.1.0" - promise "^7.1.1" - setimmediate "^1.0.5" - ua-parser-js "^0.7.18" - -fd-slicer@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.0.1.tgz#8b5bcbd9ec327c5041bf9ab023fd6750f1177e65" - integrity sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU= - dependencies: - pend "~1.2.0" - -figures@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" - integrity sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4= - dependencies: - escape-string-regexp "^1.0.5" - object-assign "^4.1.0" - -figures@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" - integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= - dependencies: - escape-string-regexp "^1.0.5" - -figures@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" - integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== - dependencies: - escape-string-regexp "^1.0.5" - -file-entry-cache@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" - integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== - dependencies: - flat-cache "^2.0.1" - -file-uri-to-path@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" - integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== - -fill-range@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" - integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= - dependencies: - extend-shallow "^2.0.1" - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range "^2.1.0" - -finalhandler@1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" - integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== - dependencies: - debug "2.6.9" - encodeurl "~1.0.2" - escape-html "~1.0.3" - on-finished "~2.3.0" - parseurl "~1.3.3" - statuses "~1.5.0" - unpipe "~1.0.0" - -find-babel-config@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/find-babel-config/-/find-babel-config-1.2.0.tgz#a9b7b317eb5b9860cda9d54740a8c8337a2283a2" - integrity sha512-jB2CHJeqy6a820ssiqwrKMeyC6nNdmrcgkKWJWmpoxpE8RKciYJXCcXRq1h2AzCo5I5BJeN2tkGEO3hLTuePRA== - dependencies: - json5 "^0.5.1" - path-exists "^3.0.0" - -find-cache-dir@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" - integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== - dependencies: - commondir "^1.0.1" - make-dir "^2.0.0" - pkg-dir "^3.0.0" - -find-parent-dir@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/find-parent-dir/-/find-parent-dir-0.3.0.tgz#33c44b429ab2b2f0646299c5f9f718f376ff8d54" - integrity sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ= - -find-up@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= - dependencies: - path-exists "^2.0.0" - pinkie-promise "^2.0.0" - -find-up@^2.0.0, find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= - dependencies: - locate-path "^2.0.0" - -find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== - dependencies: - locate-path "^3.0.0" - -find-up@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - -flat-cache@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" - integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== - dependencies: - flatted "^2.0.0" - rimraf "2.6.3" - write "1.0.3" - -flatted@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.1.tgz#69e57caa8f0eacbc281d2e2cb458d46fdb449e08" - integrity sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg== - -flow-babel-webpack-plugin@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/flow-babel-webpack-plugin/-/flow-babel-webpack-plugin-1.1.1.tgz#7dd41110b96045eab8d8af6df48883310de54e91" - integrity sha512-xgZt6sWUWMek1P+rdzJqXG9OaWCUqTfaDb1OoEVh2mXFb7Nppcd4Rm9WW9Dz4uS5T3MTe/BFVH0ZjUX8Oxh1JQ== - dependencies: - babel-plugin-transform-flow-comments "^6.17.0" - flow-bin ">=0.44.2 <1" - lodash.merge "^4.6.0" - -"flow-bin@>=0.44.2 <1": - version "0.120.1" - resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.120.1.tgz#ab051d6df71829b70a26a2c90bb81f9d43797cae" - integrity sha512-KgE+d+rKzdXzhweYVJty1QIOOZTTbtnXZf+4SLnmArLvmdfeLreQOZpeLbtq5h79m7HhDzX/HkUkoyu/fmSC2A== - -for-in@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= - -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - -fragment-cache@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" - integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= - dependencies: - map-cache "^0.2.2" - -fresh@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= - -fs-extra@^0.30.0: - version "0.30.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" - integrity sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A= - dependencies: - graceful-fs "^4.1.2" - jsonfile "^2.1.0" - klaw "^1.0.0" - path-is-absolute "^1.0.0" - rimraf "^2.2.8" - -fs-extra@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-1.0.0.tgz#cd3ce5f7e7cb6145883fcae3191e9877f8587950" - integrity sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA= - dependencies: - graceful-fs "^4.1.2" - jsonfile "^2.1.0" - klaw "^1.0.0" - -fs-extra@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" - integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== - dependencies: - graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= - -fsevents@^1.2.7: - version "1.2.11" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.11.tgz#67bf57f4758f02ede88fb2a1712fef4d15358be3" - integrity sha512-+ux3lx6peh0BpvY0JebGyZoiR4D+oYzdPZMKJwkZ+sFkNJzpL7tXc/wehS49gUAxg3tmMHPHZkA8JU2rhhgDHw== - dependencies: - bindings "^1.5.0" - nan "^2.12.1" - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= - -fuse.js@3.4.5: - version "3.4.5" - resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-3.4.5.tgz#8954fb43f9729bd5dbcb8c08f251db552595a7a6" - integrity sha512-s9PGTaQIkT69HaeoTVjwGsLfb8V8ScJLx5XGFcKHg0MqLUH/UZ4EKOtqtXX9k7AFqCGxD1aJmYb8Q5VYDibVRQ== - -gensync@^1.0.0-beta.1: - version "1.0.0-beta.1" - resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" - integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg== - -get-caller-file@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" - integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== - -get-caller-file@^2.0.1: - version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-own-enumerable-property-symbols@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" - integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== - -get-stdin@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" - integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= - -get-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" - integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= - -get-stream@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" - integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== - dependencies: - pump "^3.0.0" - -get-value@^2.0.3, get-value@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= - dependencies: - assert-plus "^1.0.0" - -gfycat-style-urls@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/gfycat-style-urls/-/gfycat-style-urls-1.0.3.tgz#355c876e0a63754be30f806b401387ce0e6aad65" - integrity sha512-HirQ+dsQWChjnfwZXB07ytzh3eZQFVlOdO2ML1YvpHBOXplumtzGIAejVu91wmj4Cw7t4760M2fKtgI+NAi/2w== - -glob-parent@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.0.tgz#5f4c1d1e748d30cd73ad2944b3577a81b081e8c2" - integrity sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw== - dependencies: - is-glob "^4.0.1" - -glob@7.0.6: - version "7.0.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.6.tgz#211bafaf49e525b8cd93260d14ab136152b3f57a" - integrity sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo= - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.2" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.1.1, glob@^7.1.2, glob@^7.1.3: - version "7.1.6" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== - dependencies: - 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" - -global-dirs@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" - integrity sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU= - dependencies: - ini "^1.3.4" - -globals@^11.1.0: - version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== - -globals@^12.1.0: - version "12.3.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-12.3.0.tgz#1e564ee5c4dded2ab098b0f88f24702a3c56be13" - integrity sha512-wAfjdLgFsPZsklLJvOBUBmzYE8/CwhEqSBEMRXA3qxIiNtyqvjYurAtIfDh6chlEPUfmTY3MnZh5Hfh4q0UlIw== - dependencies: - type-fest "^0.8.1" - -globals@^9.18.0: - version "9.18.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" - integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== - -google-libphonenumber@^2.0.9: - version "2.0.19" - resolved "https://registry.yarnpkg.com/google-libphonenumber/-/google-libphonenumber-2.0.19.tgz#a6d5ff60412aa33b161bb830d70aa39682583054" - integrity sha512-kwtbruT+eyiof081cxT1tltMTxgTOq3CQhUoEYBROC+vNf+COPqzfKJtVnDvgXQe4SzfbnAYkP8KoSpbJBIlSg== - -got@^6.7.1: - version "6.7.1" - resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" - integrity sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA= - dependencies: - create-error-class "^3.0.0" - duplexer3 "^0.1.4" - get-stream "^3.0.0" - is-redirect "^1.0.0" - is-retry-allowed "^1.0.0" - is-stream "^1.0.0" - lowercase-keys "^1.0.0" - safe-buffer "^5.0.1" - timed-out "^4.0.0" - unzip-response "^2.0.1" - url-parse-lax "^1.0.0" - -graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.1.9: - version "4.2.3" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" - integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== - -growly@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" - integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= - -hammerjs@^2.0.8: - version "2.0.8" - resolved "https://registry.yarnpkg.com/hammerjs/-/hammerjs-2.0.8.tgz#04ef77862cff2bb79d30f7692095930222bf60f1" - integrity sha1-BO93hiz/K7edMPdpIJWTAiK/YPE= - -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= - -har-validator@~5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" - integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== - dependencies: - ajv "^6.5.5" - har-schema "^2.0.0" - -has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= - dependencies: - ansi-regex "^2.0.0" - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-symbols@^1.0.0, has-symbols@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" - integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== - -has-value@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" - integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= - dependencies: - get-value "^2.0.3" - has-values "^0.1.4" - isobject "^2.0.0" - -has-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" - integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= - dependencies: - get-value "^2.0.6" - has-values "^1.0.0" - isobject "^3.0.0" - -has-values@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" - integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= - -has-values@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" - integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -hermes-engine@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/hermes-engine/-/hermes-engine-0.2.1.tgz#25c0f1ff852512a92cb5c5cc47cf967e1e722ea2" - integrity sha512-eNHUQHuadDMJARpaqvlCZoK/Nitpj6oywq3vQ3wCwEsww5morX34mW5PmKWQTO7aU0ck0hgulxR+EVDlXygGxQ== - -hoist-non-react-statics@^2.3.1: - version "2.5.5" - resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz#c5903cf409c0dfd908f388e619d86b9c1174cb47" - integrity sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw== - -hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" - integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== - dependencies: - react-is "^16.7.0" - -home-path@^1.0.1: - version "1.0.7" - resolved "https://registry.yarnpkg.com/home-path/-/home-path-1.0.7.tgz#cf77d7339ff3ddc3347a23c52612b1f5e7e56313" - integrity sha512-tM1pVa+u3ZqQwIkXcWfhUlY3HWS3TsnKsfi2OHHvnhkX52s9etyktPyy1rQotkr0euWimChDq+QkQuDe8ngUlQ== - -hosted-git-info@^2.1.4: - version "2.8.8" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" - integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== - -http-errors@~1.7.2: - version "1.7.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" - integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== - dependencies: - depd "~1.1.2" - inherits "2.0.4" - setprototypeof "1.1.1" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -husky@^0.14.3: - version "0.14.3" - resolved "https://registry.yarnpkg.com/husky/-/husky-0.14.3.tgz#c69ed74e2d2779769a17ba8399b54ce0b63c12c3" - integrity sha512-e21wivqHpstpoiWA/Yi8eFti8E+sQDSS53cpJsPptPs295QTOQR0ZwnHo2TXy1XOpZFD9rPOd3NpmqTK6uMLJA== - dependencies: - is-ci "^1.0.10" - normalize-path "^1.0.0" - strip-indent "^2.0.0" - -iconv-lite@^0.4.17, iconv-lite@^0.4.24, iconv-lite@~0.4.13: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -ignore@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== - -ignore@^5.0.2, ignore@^5.0.5: - version "5.1.4" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.4.tgz#84b7b3dbe64552b6ef0eca99f6743dbec6d97adf" - integrity sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A== - -image-size@^0.6.0: - version "0.6.3" - resolved "https://registry.yarnpkg.com/image-size/-/image-size-0.6.3.tgz#e7e5c65bb534bd7cdcedd6cb5166272a85f75fb2" - integrity sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA== - -import-fresh@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" - integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= - dependencies: - caller-path "^2.0.0" - resolve-from "^3.0.0" - -import-fresh@^3.0.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" - integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -import-lazy@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" - integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= - -indent-string@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" - integrity sha1-ji1INIdCEhtKghi3oTfppSBJ3IA= - dependencies: - repeating "^2.0.0" - -indent-string@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" - integrity sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok= - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -ini@^1.3.4, ini@~1.3.0: - version "1.3.5" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" - integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== - -inquirer@^3.0.6: - version "3.3.0" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" - integrity sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ== - dependencies: - ansi-escapes "^3.0.0" - chalk "^2.0.0" - cli-cursor "^2.1.0" - cli-width "^2.0.0" - external-editor "^2.0.4" - figures "^2.0.0" - lodash "^4.3.0" - mute-stream "0.0.7" - run-async "^2.2.0" - rx-lite "^4.0.8" - rx-lite-aggregates "^4.0.8" - string-width "^2.1.0" - strip-ansi "^4.0.0" - through "^2.3.6" - -inquirer@^7.0.0: - version "7.0.6" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-7.0.6.tgz#ee4ff0ea7ecda5324656fe665878790f66df7d0c" - integrity sha512-7SVO4h+QIdMq6XcqIqrNte3gS5MzCCKZdsq9DO4PJziBFNYzP3PGFbDjgadDb//MCahzgjCxvQ/O2wa7kx9o4w== - dependencies: - ansi-escapes "^4.2.1" - chalk "^3.0.0" - cli-cursor "^3.1.0" - cli-width "^2.0.0" - external-editor "^3.0.3" - figures "^3.0.0" - lodash "^4.17.15" - mute-stream "0.0.8" - run-async "^2.4.0" - rxjs "^6.5.3" - string-width "^4.1.0" - strip-ansi "^6.0.0" - through "^2.3.6" - -internal-slot@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.2.tgz#9c2e9fb3cd8e5e4256c6f45fe310067fcfa378a3" - integrity sha512-2cQNfwhAfJIkU4KZPkDI+Gj5yNNnbqi40W9Gge6dfnk4TocEVm00B3bdiL+JINrbGJil2TeHvM4rETGzk/f/0g== - dependencies: - es-abstract "^1.17.0-next.1" - has "^1.0.3" - side-channel "^1.0.2" - -invariant@2.2.4, invariant@^2.2.2, invariant@^2.2.4: - version "2.2.4" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" - integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== - dependencies: - loose-envify "^1.0.0" - -invert-kv@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" - integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= - -invert-kv@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" - integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== - -ip@^1.1.4: - version "1.1.5" - resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" - integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= - -is-accessor-descriptor@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" - integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= - dependencies: - kind-of "^3.0.2" - -is-accessor-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" - integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== - dependencies: - kind-of "^6.0.0" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= - -is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== - -is-callable@^1.1.4, is-callable@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab" - integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q== - -is-ci@^1.0.10: - version "1.2.1" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" - integrity sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg== - dependencies: - ci-info "^1.5.0" - -is-ci@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" - integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== - dependencies: - ci-info "^2.0.0" - -is-data-descriptor@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" - integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= - dependencies: - kind-of "^3.0.2" - -is-data-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" - integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== - dependencies: - kind-of "^6.0.0" - -is-date-object@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" - integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== - -is-descriptor@^0.1.0: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" - integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== - dependencies: - is-accessor-descriptor "^0.1.6" - is-data-descriptor "^0.1.4" - kind-of "^5.0.0" - -is-descriptor@^1.0.0, is-descriptor@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" - integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== - dependencies: - is-accessor-descriptor "^1.0.0" - is-data-descriptor "^1.0.0" - kind-of "^6.0.2" - -is-directory@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" - integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= - -is-extendable@^0.1.0, is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= - -is-extendable@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" - integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== - dependencies: - is-plain-object "^2.0.4" - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= - -is-finite@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" - integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - -is-glob@^4.0.0, is-glob@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" - integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== - dependencies: - is-extglob "^2.1.1" - -is-installed-globally@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" - integrity sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA= - dependencies: - global-dirs "^0.1.0" - is-path-inside "^1.0.0" - -is-npm@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" - integrity sha1-8vtjpl5JBbQGyGBydloaTceTufQ= - -is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= - dependencies: - kind-of "^3.0.2" - -is-obj@^1.0.0, is-obj@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" - integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= - -is-observable@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-1.1.0.tgz#b3e986c8f44de950867cab5403f5a3465005975e" - integrity sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA== - dependencies: - symbol-observable "^1.1.0" - -is-path-inside@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" - integrity sha1-jvW33lBDej/cprToZe96pVy0gDY= - dependencies: - path-is-inside "^1.0.1" - -is-plain-object@^2.0.3, is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== - dependencies: - isobject "^3.0.1" - -is-promise@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" - integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= - -is-redirect@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" - integrity sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ= - -is-regex@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" - integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ== - dependencies: - has "^1.0.3" - -is-regexp@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" - integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk= - -is-retry-allowed@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" - integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg== - -is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= - -is-string@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.5.tgz#40493ed198ef3ff477b8c7f92f644ec82a5cd3a6" - integrity sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ== - -is-symbol@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" - integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== - dependencies: - has-symbols "^1.0.1" - -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= - -is-utf8@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" - integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= - -is-windows@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" - integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== - -is-wsl@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" - integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= - -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= - -isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= - -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= - dependencies: - isarray "1.0.0" - -isobject@^3.0.0, isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= - -isomorphic-fetch@^2.1.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" - integrity sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk= - dependencies: - node-fetch "^1.0.1" - whatwg-fetch ">=0.10.0" - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= - -jest-docblock@^21.0.0: - version "21.2.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-21.2.0.tgz#51529c3b30d5fd159da60c27ceedc195faf8d414" - integrity sha512-5IZ7sY9dBAYSV+YjQ0Ovb540Ku7AO9Z5o2Cg789xj167iQuZ2cG+z0f3Uct6WeYLbU6aQiM2pCs7sZ+4dotydw== - -jest-get-type@^22.1.0: - version "22.4.3" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.4.3.tgz#e3a8504d8479342dd4420236b322869f18900ce4" - integrity sha512-/jsz0Y+V29w1chdXVygEKSz2nBoHoYqNShPe+QgxSNjAuP1i8+k4LbQNrfoliKej0P45sivkSCh7yiD6ubHS3w== - -jest-get-type@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.9.0.tgz#1684a0c8a50f2e4901b6644ae861f579eed2ef0e" - integrity sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q== - -jest-haste-map@^24.7.1: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.9.0.tgz#b38a5d64274934e21fa417ae9a9fbeb77ceaac7d" - integrity sha512-kfVFmsuWui2Sj1Rp1AJ4D9HqJwE4uwTlS/vO+eRUaMmd54BFpli2XhMQnPC2k4cHFVbB2Q2C+jtI1AGLgEnCjQ== - dependencies: - "@jest/types" "^24.9.0" - anymatch "^2.0.0" - fb-watchman "^2.0.0" - graceful-fs "^4.1.15" - invariant "^2.2.4" - jest-serializer "^24.9.0" - jest-util "^24.9.0" - jest-worker "^24.9.0" - micromatch "^3.1.10" - sane "^4.0.3" - walker "^1.0.7" - optionalDependencies: - fsevents "^1.2.7" - -jest-message-util@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.9.0.tgz#527f54a1e380f5e202a8d1149b0ec872f43119e3" - integrity sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw== - dependencies: - "@babel/code-frame" "^7.0.0" - "@jest/test-result" "^24.9.0" - "@jest/types" "^24.9.0" - "@types/stack-utils" "^1.0.1" - chalk "^2.0.1" - micromatch "^3.1.10" - slash "^2.0.0" - stack-utils "^1.0.1" - -jest-mock@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.9.0.tgz#c22835541ee379b908673ad51087a2185c13f1c6" - integrity sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w== - dependencies: - "@jest/types" "^24.9.0" - -jest-serializer@^24.4.0, jest-serializer@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.9.0.tgz#e6d7d7ef96d31e8b9079a714754c5d5c58288e73" - integrity sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ== - -jest-util@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.9.0.tgz#7396814e48536d2e85a37de3e4c431d7cb140162" - integrity sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg== - dependencies: - "@jest/console" "^24.9.0" - "@jest/fake-timers" "^24.9.0" - "@jest/source-map" "^24.9.0" - "@jest/test-result" "^24.9.0" - "@jest/types" "^24.9.0" - callsites "^3.0.0" - chalk "^2.0.1" - graceful-fs "^4.1.15" - is-ci "^2.0.0" - mkdirp "^0.5.1" - slash "^2.0.0" - source-map "^0.6.0" - -jest-validate@^23.5.0: - version "23.6.0" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-23.6.0.tgz#36761f99d1ed33fcd425b4e4c5595d62b6597474" - integrity sha512-OFKapYxe72yz7agrDAWi8v2WL8GIfVqcbKRCLbRG9PAxtzF9b1SEDdTpytNDN12z2fJynoBwpMpvj2R39plI2A== - dependencies: - chalk "^2.0.1" - jest-get-type "^22.1.0" - leven "^2.1.0" - pretty-format "^23.6.0" - -jest-validate@^24.7.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-24.9.0.tgz#0775c55360d173cd854e40180756d4ff52def8ab" - integrity sha512-HPIt6C5ACwiqSiwi+OfSSHbK8sG7akG8eATl+IPKaeIjtPOeBUd/g3J7DghugzxrGjI93qS/+RPKe1H6PqvhRQ== - dependencies: - "@jest/types" "^24.9.0" - camelcase "^5.3.1" - chalk "^2.0.1" - jest-get-type "^24.9.0" - leven "^3.1.0" - pretty-format "^24.9.0" - -jest-worker@^24.6.0, jest-worker@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.9.0.tgz#5dbfdb5b2d322e98567898238a9697bcce67b3e5" - integrity sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw== - dependencies: - merge-stream "^2.0.0" - supports-color "^6.1.0" - -jetifier@^1.6.2: - version "1.6.5" - resolved "https://registry.yarnpkg.com/jetifier/-/jetifier-1.6.5.tgz#ea87324a4230bef20a9651178ecab978ee54a8cb" - integrity sha512-T7yzBSu9PR+DqjYt+I0KVO1XTb1QhAfHnXV5Nd3xpbXM6Xg4e3vP60Q4qkNU8Fh6PHC2PivPUNN3rY7G2MxcDQ== - -"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-tokens@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" - integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= - -js-yaml@^3.13.1: - version "3.13.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" - integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= - -jsc-android@^245459.0.0: - version "245459.0.0" - resolved "https://registry.yarnpkg.com/jsc-android/-/jsc-android-245459.0.0.tgz#e584258dd0b04c9159a27fb104cd5d491fd202c9" - integrity sha512-wkjURqwaB1daNkDi2OYYbsLnIdC/lUM2nPXQKRs5pqEU9chDg435bjvo+LSaHotDENygHQDHe+ntUkkw2gwMtg== - -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== - -jsesc@~0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" - integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= - -json-parse-better-errors@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= - -json-stable-stringify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" - integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= - dependencies: - jsonify "~0.0.0" - -json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= - -json5@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" - integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= - -json5@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.1.tgz#81b6cb04e9ba496f1c7005d07b4368a2638f90b6" - integrity sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ== - dependencies: - minimist "^1.2.0" - -jsonfile@^2.1.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" - integrity sha1-NzaitCi4e72gzIO1P6PWM6NcKug= - optionalDependencies: - graceful-fs "^4.1.6" - -jsonfile@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" - integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= - optionalDependencies: - graceful-fs "^4.1.6" - -jsonify@~0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" - integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= - -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" - -jsx-ast-utils@^2.0.1, jsx-ast-utils@^2.2.3: - version "2.2.3" - resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.2.3.tgz#8a9364e402448a3ce7f14d357738310d9248054f" - integrity sha512-EdIHFMm+1BPynpKOpdPqiOsvnIrInRGJD7bzPZdPkjitQEqpdpUuFpq4T0npZFKTiB3RhWFdGN+oqOJIdhDhQA== - dependencies: - array-includes "^3.0.3" - object.assign "^4.1.0" - -keymirror@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/keymirror/-/keymirror-0.1.1.tgz#918889ea13f8d0a42e7c557250eee713adc95c35" - integrity sha1-kYiJ6hP40KQufFVyUO7nE63JXDU= - -kind-of@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-1.1.0.tgz#140a3d2d41a36d2efcfa9377b62c24f8495a5c44" - integrity sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ= - -kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= - dependencies: - is-buffer "^1.1.5" - -kind-of@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" - integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= - dependencies: - is-buffer "^1.1.5" - -kind-of@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" - integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== - -kind-of@^6.0.0, kind-of@^6.0.2: - version "6.0.3" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" - integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== - -klaw@^1.0.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" - integrity sha1-QIhDO0azsbolnXh4XY6W9zugJDk= - optionalDependencies: - graceful-fs "^4.1.9" - -latest-version@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" - integrity sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU= - dependencies: - package-json "^4.0.0" - -lbry-redux@lbryio/lbry-redux#69ffd110dbf3633e5847f61f008751edec033017: - version "0.0.1" - resolved "https://codeload.github.com/lbryio/lbry-redux/tar.gz/69ffd110dbf3633e5847f61f008751edec033017" - dependencies: - proxy-polyfill "0.1.6" - reselect "^3.0.0" - uuid "^3.3.2" - -lbryinc@lbryio/lbryinc#667024ebb7cb207609273174ca422cee47469270: - version "0.0.1" - resolved "https://codeload.github.com/lbryio/lbryinc/tar.gz/667024ebb7cb207609273174ca422cee47469270" - dependencies: - reselect "^3.0.0" - -lcid@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" - integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= - dependencies: - invert-kv "^1.0.0" - -lcid@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" - integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== - dependencies: - invert-kv "^2.0.0" - -leven@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" - integrity sha1-wuep93IJTe6dNCAq6KzORoeHVYA= - -leven@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" - integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== - -levn@^0.3.0, levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - -lint-staged@^7.0.4: - version "7.3.0" - resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-7.3.0.tgz#90ff33e5ca61ed3dbac35b6f6502dbefdc0db58d" - integrity sha512-AXk40M9DAiPi7f4tdJggwuKIViUplYtVj1os1MVEteW7qOkU50EOehayCfO9TsoGK24o/EsWb41yrEgfJDDjCw== - dependencies: - chalk "^2.3.1" - commander "^2.14.1" - cosmiconfig "^5.0.2" - debug "^3.1.0" - dedent "^0.7.0" - execa "^0.9.0" - find-parent-dir "^0.3.0" - is-glob "^4.0.0" - is-windows "^1.0.2" - jest-validate "^23.5.0" - listr "^0.14.1" - lodash "^4.17.5" - log-symbols "^2.2.0" - micromatch "^3.1.8" - npm-which "^3.0.1" - p-map "^1.1.1" - path-is-inside "^1.0.2" - pify "^3.0.0" - please-upgrade-node "^3.0.2" - staged-git-files "1.1.1" - string-argv "^0.0.2" - stringify-object "^3.2.2" - -listr-silent-renderer@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e" - integrity sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4= - -listr-update-renderer@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz#4ea8368548a7b8aecb7e06d8c95cb45ae2ede6a2" - integrity sha512-tKRsZpKz8GSGqoI/+caPmfrypiaq+OQCbd+CovEC24uk1h952lVj5sC7SqyFUm+OaJ5HN/a1YLt5cit2FMNsFA== - dependencies: - chalk "^1.1.3" - cli-truncate "^0.2.1" - elegant-spinner "^1.0.1" - figures "^1.7.0" - indent-string "^3.0.0" - log-symbols "^1.0.2" - log-update "^2.3.0" - strip-ansi "^3.0.1" - -listr-verbose-renderer@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz#f1132167535ea4c1261102b9f28dac7cba1e03db" - integrity sha512-04PDPqSlsqIOaaaGZ+41vq5FejI9auqTInicFRndCBgE3bXG8D6W1I+mWhk+1nqbHmyhla/6BUrd5OSiHwKRXw== - dependencies: - chalk "^2.4.1" - cli-cursor "^2.1.0" - date-fns "^1.27.2" - figures "^2.0.0" - -listr@^0.14.1: - version "0.14.3" - resolved "https://registry.yarnpkg.com/listr/-/listr-0.14.3.tgz#2fea909604e434be464c50bddba0d496928fa586" - integrity sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA== - dependencies: - "@samverschueren/stream-to-observable" "^0.3.0" - is-observable "^1.1.0" - is-promise "^2.1.0" - is-stream "^1.1.0" - listr-silent-renderer "^1.1.1" - listr-update-renderer "^0.5.0" - listr-verbose-renderer "^0.5.0" - p-map "^2.0.0" - rxjs "^6.3.3" - -load-json-file@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" - integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - pinkie-promise "^2.0.0" - strip-bom "^2.0.0" - -load-json-file@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" - integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - strip-bom "^3.0.0" - -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" - integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== - dependencies: - p-locate "^4.1.0" - -lodash.clonedeep@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" - integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= - -lodash.forin@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.forin/-/lodash.forin-4.4.0.tgz#5d3f20ae564011fbe88381f7d98949c9c9519731" - integrity sha1-XT8grlZAEfvog4H32YlJyclRlzE= - -lodash.get@^4.4.2: - version "4.4.2" - resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" - integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= - -lodash.isempty@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.isempty/-/lodash.isempty-4.4.0.tgz#6f86cbedd8be4ec987be9aaf33c9684db1b31e7e" - integrity sha1-b4bL7di+TsmHvpqvM8loTbGzHn4= - -lodash.merge@^4.6.0: - version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" - integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== - -lodash.pickby@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.pickby/-/lodash.pickby-4.6.0.tgz#7dea21d8c18d7703a27c704c15d3b84a67e33aff" - integrity sha1-feoh2MGNdwOifHBMFdO4SmfjOv8= - -lodash.set@^4.3.2: - version "4.3.2" - resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23" - integrity sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM= - -lodash.throttle@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" - integrity sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ= - -lodash.toarray@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.toarray/-/lodash.toarray-4.4.0.tgz#24c4bfcd6b2fba38bfd0594db1179d8e9b656561" - integrity sha1-JMS/zWsvuji/0FlNsRedjptlZWE= - -lodash.unescape@4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/lodash.unescape/-/lodash.unescape-4.0.1.tgz#bf2249886ce514cda112fae9218cdc065211fc9c" - integrity sha1-vyJJiGzlFM2hEvrpIYzcBlIR/Jw= - -lodash.unset@^4.5.2: - version "4.5.2" - resolved "https://registry.yarnpkg.com/lodash.unset/-/lodash.unset-4.5.2.tgz#370d1d3e85b72a7e1b0cdf2d272121306f23e4ed" - integrity sha1-Nw0dPoW3Kn4bDN8tJyEhMG8j5O0= - -lodash@>=4.17.11, lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0: - version "4.17.15" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" - integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== - -log-symbols@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" - integrity sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg= - dependencies: - chalk "^1.0.0" - -log-symbols@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" - integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== - dependencies: - chalk "^2.0.1" - -log-update@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/log-update/-/log-update-2.3.0.tgz#88328fd7d1ce7938b29283746f0b1bc126b24708" - integrity sha1-iDKP19HOeTiykoN0bwsbwSayRwg= - dependencies: - ansi-escapes "^3.0.0" - cli-cursor "^2.0.0" - wrap-ansi "^3.0.1" - -logkitty@^0.6.0: - version "0.6.1" - resolved "https://registry.yarnpkg.com/logkitty/-/logkitty-0.6.1.tgz#fe29209669d261539cbd6bb998a136fc92a1a05c" - integrity sha512-cHuXN8qUZuzX/7kB6VyS7kB4xyD24e8gyHXIFNhIv+fjW3P+jEXNUhj0o/7qWJtv7UZpbnPgUqzu/AZQ8RAqxQ== - dependencies: - ansi-fragments "^0.2.1" - dayjs "^1.8.15" - yargs "^12.0.5" - -loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1, loose-envify@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - -loud-rejection@^1.0.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" - integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= - dependencies: - currently-unhandled "^0.4.1" - signal-exit "^3.0.0" - -lowercase-keys@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" - integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== - -lru-cache@^4.0.1: - version "4.1.5" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" - integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - -lz-string@^1.4.4: - version "1.4.4" - resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.4.4.tgz#c0d8eaf36059f705796e1e344811cf4c498d3a26" - integrity sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY= - -make-dir@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" - integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== - dependencies: - pify "^3.0.0" - -make-dir@^2.0.0, make-dir@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" - integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== - dependencies: - pify "^4.0.1" - semver "^5.6.0" - -makeerror@1.0.x: - version "1.0.11" - resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" - integrity sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw= - dependencies: - tmpl "1.0.x" - -map-age-cleaner@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" - integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== - dependencies: - p-defer "^1.0.0" - -map-cache@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= - -map-obj@^1.0.0, map-obj@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" - integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= - -map-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" - integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= - dependencies: - object-visit "^1.0.0" - -mem@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" - integrity sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y= - dependencies: - mimic-fn "^1.0.0" - -mem@^4.0.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" - integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== - dependencies: - map-age-cleaner "^0.1.1" - mimic-fn "^2.0.0" - p-is-promise "^2.0.0" - -meow@^3.1.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" - integrity sha1-cstmi0JSKCkKu/qFaJJYcwioAfs= - dependencies: - camelcase-keys "^2.0.0" - decamelize "^1.1.2" - loud-rejection "^1.0.0" - map-obj "^1.0.1" - minimist "^1.1.3" - normalize-package-data "^2.3.4" - object-assign "^4.0.1" - read-pkg-up "^1.0.1" - redent "^1.0.0" - trim-newlines "^1.0.0" - -merge-stream@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-1.0.1.tgz#4041202d508a342ba00174008df0c251b8c135e1" - integrity sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE= - dependencies: - readable-stream "^2.0.1" - -merge-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" - integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== - -merge@>=1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145" - integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ== - -metro-babel-register@^0.56.0, metro-babel-register@^0.56.4: - version "0.56.4" - resolved "https://registry.yarnpkg.com/metro-babel-register/-/metro-babel-register-0.56.4.tgz#b0c627a1cfdd1bdd768f81af79481754e833a902" - integrity sha512-Phm6hMluOWYqfykftjJ1jsTpWvbgb49AC/1taxEctxUdRCZlFgZwBleJZAhQYxJD5J+ikFkEbHDzePEXb29KVA== - dependencies: - "@babel/core" "^7.0.0" - "@babel/plugin-proposal-class-properties" "^7.0.0" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.0.0" - "@babel/plugin-proposal-object-rest-spread" "^7.0.0" - "@babel/plugin-proposal-optional-catch-binding" "^7.0.0" - "@babel/plugin-proposal-optional-chaining" "^7.0.0" - "@babel/plugin-transform-async-to-generator" "^7.0.0" - "@babel/plugin-transform-flow-strip-types" "^7.0.0" - "@babel/plugin-transform-modules-commonjs" "^7.0.0" - "@babel/register" "^7.0.0" - core-js "^2.2.2" - escape-string-regexp "^1.0.5" - -metro-babel-transformer@^0.56.4: - version "0.56.4" - resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.56.4.tgz#fe1d0dc600fcf90201a5bea4d42caea10b801057" - integrity sha512-IOi4ILgZvaX7GCGHBJp79paNVOq5QxhhbyqAdEJgDP8bHfl/OVHoVKSypfrsMSKSiBrqxhIjyc4XjkXsQtkx5g== - dependencies: - "@babel/core" "^7.0.0" - metro-source-map "^0.56.4" - -metro-cache@^0.56.4: - version "0.56.4" - resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.56.4.tgz#542f9f8a35f8fb9d5576f46fd3ab4d4f42851a7e" - integrity sha512-d1hiUSKwtRsuMxUhHVJ3tjK2BbpUlJGvTyMWohK8Wxx+0GbnWRWWFcI4vlCzlZfoK0VtZK2MJEl5t7Du1mIniQ== - dependencies: - jest-serializer "^24.4.0" - metro-core "^0.56.4" - mkdirp "^0.5.1" - rimraf "^2.5.4" - -metro-config@^0.56.0, metro-config@^0.56.4: - version "0.56.4" - resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.56.4.tgz#338fd8165fba59424cec427c1a881757945e57e9" - integrity sha512-O85QDHwWdMn/8ERe13y4a6vbZL0AHyO8atTvL+9BCulLEO+FQBi1iJjr3+ViLa8cf0m5dRftDsa7P47m5euk4A== - dependencies: - cosmiconfig "^5.0.5" - jest-validate "^24.7.0" - metro "^0.56.4" - metro-cache "^0.56.4" - metro-core "^0.56.4" - pretty-format "^24.7.0" - -metro-core@^0.56.0, metro-core@^0.56.4: - version "0.56.4" - resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.56.4.tgz#67cc41b3c0bf66e9c2306f50239a1080b1e82312" - integrity sha512-hMzkBdgPt5Zm9nr/1KtIT+A6H7TNiLVCEGG5OiAXj8gTRsA2yy7wAdQpwy0xbE+zi88t/pLOzXpd3ClG/YxyWg== - dependencies: - jest-haste-map "^24.7.1" - lodash.throttle "^4.1.1" - metro-resolver "^0.56.4" - wordwrap "^1.0.0" - -metro-inspector-proxy@^0.56.4: - version "0.56.4" - resolved "https://registry.yarnpkg.com/metro-inspector-proxy/-/metro-inspector-proxy-0.56.4.tgz#7343ff3c5908af4fd99e96b6d646e24e99816be4" - integrity sha512-E1S3MO25mWKmcLn1UQuCDiS0hf9P2Fwq8sEAX5lBLoZbehepNH+4xJ3xXSY51JX4dozBrE8GGoKL4ll3II40LA== - dependencies: - connect "^3.6.5" - debug "^2.2.0" - rxjs "^5.4.3" - ws "^1.1.5" - yargs "^9.0.0" - -metro-minify-uglify@^0.56.4: - version "0.56.4" - resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.56.4.tgz#13589dfb1d43343608aacb7f78ddfcc052daa63c" - integrity sha512-BHgj7+BKEK2pHvWHUR730bIrsZwl8DPtr49x9L0j2grPZ5/UROWXzEr8VZgIss7fl64t845uu1HXNNyuSj2EhA== - dependencies: - uglify-es "^3.1.9" - -metro-react-native-babel-preset@0.56.3: - version "0.56.3" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.56.3.tgz#5a1097c2f94e8ee0797a8ba2ab8f86d096f4c093" - integrity sha512-tGPzX2ZwI8vQ8SiNVBPUIgKqmaRNVB6rtJtHCBQZAYRiMbxh0NHCUoFfKBej6U5qVgxiYYHyN8oB23evG4/Oow== - dependencies: - "@babel/plugin-proposal-class-properties" "^7.0.0" - "@babel/plugin-proposal-export-default-from" "^7.0.0" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.0.0" - "@babel/plugin-proposal-object-rest-spread" "^7.0.0" - "@babel/plugin-proposal-optional-catch-binding" "^7.0.0" - "@babel/plugin-proposal-optional-chaining" "^7.0.0" - "@babel/plugin-syntax-dynamic-import" "^7.0.0" - "@babel/plugin-syntax-export-default-from" "^7.0.0" - "@babel/plugin-syntax-flow" "^7.2.0" - "@babel/plugin-transform-arrow-functions" "^7.0.0" - "@babel/plugin-transform-block-scoping" "^7.0.0" - "@babel/plugin-transform-classes" "^7.0.0" - "@babel/plugin-transform-computed-properties" "^7.0.0" - "@babel/plugin-transform-destructuring" "^7.0.0" - "@babel/plugin-transform-exponentiation-operator" "^7.0.0" - "@babel/plugin-transform-flow-strip-types" "^7.0.0" - "@babel/plugin-transform-for-of" "^7.0.0" - "@babel/plugin-transform-function-name" "^7.0.0" - "@babel/plugin-transform-literals" "^7.0.0" - "@babel/plugin-transform-modules-commonjs" "^7.0.0" - "@babel/plugin-transform-object-assign" "^7.0.0" - "@babel/plugin-transform-parameters" "^7.0.0" - "@babel/plugin-transform-react-display-name" "^7.0.0" - "@babel/plugin-transform-react-jsx" "^7.0.0" - "@babel/plugin-transform-react-jsx-source" "^7.0.0" - "@babel/plugin-transform-regenerator" "^7.0.0" - "@babel/plugin-transform-runtime" "^7.0.0" - "@babel/plugin-transform-shorthand-properties" "^7.0.0" - "@babel/plugin-transform-spread" "^7.0.0" - "@babel/plugin-transform-sticky-regex" "^7.0.0" - "@babel/plugin-transform-template-literals" "^7.0.0" - "@babel/plugin-transform-typescript" "^7.0.0" - "@babel/plugin-transform-unicode-regex" "^7.0.0" - "@babel/template" "^7.0.0" - react-refresh "^0.4.0" - -metro-react-native-babel-preset@^0.56.4: - version "0.56.4" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.56.4.tgz#dcedc64b7ff5c0734839458e70eb0ebef6d063a8" - integrity sha512-CzbBDM9Rh6w8s1fq+ZqihAh7DDqUAcfo9pPww25+N/eJ7UK436Q7JdfxwdIPpBwLFn6o6MyYn+uwL9OEWBJarA== - dependencies: - "@babel/plugin-proposal-class-properties" "^7.0.0" - "@babel/plugin-proposal-export-default-from" "^7.0.0" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.0.0" - "@babel/plugin-proposal-object-rest-spread" "^7.0.0" - "@babel/plugin-proposal-optional-catch-binding" "^7.0.0" - "@babel/plugin-proposal-optional-chaining" "^7.0.0" - "@babel/plugin-syntax-dynamic-import" "^7.0.0" - "@babel/plugin-syntax-export-default-from" "^7.0.0" - "@babel/plugin-syntax-flow" "^7.2.0" - "@babel/plugin-transform-arrow-functions" "^7.0.0" - "@babel/plugin-transform-block-scoping" "^7.0.0" - "@babel/plugin-transform-classes" "^7.0.0" - "@babel/plugin-transform-computed-properties" "^7.0.0" - "@babel/plugin-transform-destructuring" "^7.0.0" - "@babel/plugin-transform-exponentiation-operator" "^7.0.0" - "@babel/plugin-transform-flow-strip-types" "^7.0.0" - "@babel/plugin-transform-for-of" "^7.0.0" - "@babel/plugin-transform-function-name" "^7.0.0" - "@babel/plugin-transform-literals" "^7.0.0" - "@babel/plugin-transform-modules-commonjs" "^7.0.0" - "@babel/plugin-transform-object-assign" "^7.0.0" - "@babel/plugin-transform-parameters" "^7.0.0" - "@babel/plugin-transform-react-display-name" "^7.0.0" - "@babel/plugin-transform-react-jsx" "^7.0.0" - "@babel/plugin-transform-react-jsx-source" "^7.0.0" - "@babel/plugin-transform-regenerator" "^7.0.0" - "@babel/plugin-transform-runtime" "^7.0.0" - "@babel/plugin-transform-shorthand-properties" "^7.0.0" - "@babel/plugin-transform-spread" "^7.0.0" - "@babel/plugin-transform-sticky-regex" "^7.0.0" - "@babel/plugin-transform-template-literals" "^7.0.0" - "@babel/plugin-transform-typescript" "^7.0.0" - "@babel/plugin-transform-unicode-regex" "^7.0.0" - "@babel/template" "^7.0.0" - react-refresh "^0.4.0" - -metro-react-native-babel-transformer@^0.56.0: - version "0.56.4" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.56.4.tgz#3c6e48b605c305362ee624e45ff338656e35fc1d" - integrity sha512-ng74eutuy1nyGI9+TDzzVAVfEmNPDlapV4msTQMKPi4EFqo/fBn7Ct33ME9l5E51pQBBnxt/UwcpTvd13b29kQ== - dependencies: - "@babel/core" "^7.0.0" - babel-preset-fbjs "^3.1.2" - metro-babel-transformer "^0.56.4" - metro-react-native-babel-preset "^0.56.4" - metro-source-map "^0.56.4" - -metro-resolver@^0.56.4: - version "0.56.4" - resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.56.4.tgz#9876f57bca37fd1bfcffd733541e2ee4a89fad7f" - integrity sha512-Ug4ulVfpkKZ1Wu7mdYj9XLGuOqZTuWCqEhyx3siKTc/2eBwKZQXmiNo5d/IxWNvmwL/87Abeb724I6CMzMfjiQ== - dependencies: - absolute-path "^0.0.0" - -metro-source-map@^0.56.0, metro-source-map@^0.56.4: - version "0.56.4" - resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.56.4.tgz#868ccac3f3519fe14eca358bc186f63651b2b9bc" - integrity sha512-f1P9/rpFmG3Z0Jatiw2zvLItx1TwR7mXTSDj4qLDCWeVMB3kEXAr3R0ucumTW8c6HfpJljeRBWzYFXF33fd81g== - dependencies: - "@babel/traverse" "^7.0.0" - "@babel/types" "^7.0.0" - invariant "^2.2.4" - metro-symbolicate "^0.56.4" - ob1 "^0.56.4" - source-map "^0.5.6" - vlq "^1.0.0" - -metro-symbolicate@^0.56.4: - version "0.56.4" - resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.56.4.tgz#53e9d40beac9049fa75a3e620ddd47d4907ff015" - integrity sha512-8mCNNn6zV5FFKCIcRgI7736Xl+owgvYuy8qanPxZN36f7utiWRYeB+PirEBPcglBk4qQvoy2lT6oPULNXZQbbQ== - dependencies: - invariant "^2.2.4" - metro-source-map "^0.56.4" - source-map "^0.5.6" - through2 "^2.0.1" - vlq "^1.0.0" - -metro@^0.56.0, metro@^0.56.4: - version "0.56.4" - resolved "https://registry.yarnpkg.com/metro/-/metro-0.56.4.tgz#be7e1380ee6ac3552c25ead8098eab261029e4d7" - integrity sha512-Kt3OQJQtQdts0JrKnyGdLpKHDjqYBgIfzvYrvfhmFCkKuZ8aqRlVnvpfjQ4/OBm0Fmm9NyyxbNRD9VIbj7WjnA== - dependencies: - "@babel/core" "^7.0.0" - "@babel/generator" "^7.0.0" - "@babel/parser" "^7.0.0" - "@babel/plugin-external-helpers" "^7.0.0" - "@babel/template" "^7.0.0" - "@babel/traverse" "^7.0.0" - "@babel/types" "^7.0.0" - absolute-path "^0.0.0" - async "^2.4.0" - babel-preset-fbjs "^3.1.2" - buffer-crc32 "^0.2.13" - chalk "^2.4.1" - concat-stream "^1.6.0" - connect "^3.6.5" - debug "^2.2.0" - denodeify "^1.2.1" - eventemitter3 "^3.0.0" - fbjs "^1.0.0" - fs-extra "^1.0.0" - graceful-fs "^4.1.3" - image-size "^0.6.0" - invariant "^2.2.4" - jest-haste-map "^24.7.1" - jest-worker "^24.6.0" - json-stable-stringify "^1.0.1" - lodash.throttle "^4.1.1" - merge-stream "^1.0.1" - metro-babel-register "^0.56.4" - metro-babel-transformer "^0.56.4" - metro-cache "^0.56.4" - metro-config "^0.56.4" - metro-core "^0.56.4" - metro-inspector-proxy "^0.56.4" - metro-minify-uglify "^0.56.4" - metro-react-native-babel-preset "^0.56.4" - metro-resolver "^0.56.4" - metro-source-map "^0.56.4" - metro-symbolicate "^0.56.4" - mime-types "2.1.11" - mkdirp "^0.5.1" - node-fetch "^2.2.0" - nullthrows "^1.1.0" - resolve "^1.5.0" - rimraf "^2.5.4" - serialize-error "^2.1.0" - source-map "^0.5.6" - temp "0.8.3" - throat "^4.1.0" - wordwrap "^1.0.0" - write-file-atomic "^1.2.0" - ws "^1.1.5" - xpipe "^1.0.5" - yargs "^9.0.0" - -micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8: - version "3.1.10" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" - integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== - dependencies: - 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" - -mime-db@1.43.0, "mime-db@>= 1.43.0 < 2": - version "1.43.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58" - integrity sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ== - -mime-db@~1.23.0: - version "1.23.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.23.0.tgz#a31b4070adaea27d732ea333740a64d0ec9a6659" - integrity sha1-oxtAcK2uon1zLqMzdApk0OyaZlk= - -mime-types@2.1.11: - version "2.1.11" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.11.tgz#c259c471bda808a85d6cd193b430a5fae4473b3c" - integrity sha1-wlnEcb2oCKhdbNGTtDCl+uRHOzw= - dependencies: - mime-db "~1.23.0" - -mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24: - version "2.1.26" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06" - integrity sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ== - dependencies: - mime-db "1.43.0" - -mime@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - -mime@^2.4.1: - version "2.4.4" - resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.4.tgz#bd7b91135fc6b01cde3e9bae33d659b63d8857e5" - integrity sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA== - -mimic-fn@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" - integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== - -mimic-fn@^2.0.0, mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -minimatch@^3.0.2, minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimist@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" - integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= - -minimist@^1.1.0, minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" - integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= - -mitt@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/mitt/-/mitt-1.1.3.tgz#528c506238a05dce11cd914a741ea2cc332da9b8" - integrity sha512-mUDCnVNsAi+eD6qA0HkRkwYczbLHJ49z17BGe2PYRhZL4wpZUFZGJHU7/5tmvohoma+Hdn0Vh/oJTiPEmgSruA== - -mixin-deep@^1.2.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" - integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== - dependencies: - for-in "^1.0.2" - is-extendable "^1.0.1" - -mkdirp@0.5.1, mkdirp@^0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" - integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= - dependencies: - minimist "0.0.8" - -modal-react-native-web@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/modal-react-native-web/-/modal-react-native-web-0.2.0.tgz#5daaa76213218fd25df739a267b11aed37e8c0c2" - integrity sha512-sC0/jL3ZL4bGtv1VS43TnrH7/FHUqgb7IU3VYWNDzuR223fYlpG5Gc974GsTP172Vi+lnnBL/G70xONmaggxeQ== - dependencies: - warning "^4.0.1" - -moment@^2.22.1: - version "2.24.0" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" - integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== - -morgan@^1.9.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.9.1.tgz#0a8d16734a1d9afbc824b99df87e738e58e2da59" - integrity sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA== - dependencies: - basic-auth "~2.0.0" - debug "2.6.9" - depd "~1.1.2" - on-finished "~2.3.0" - on-headers "~1.0.1" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= - -ms@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" - integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== - -ms@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -mute-stream@0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" - integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= - -mute-stream@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" - integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== - -nan@^2.12.1: - version "2.14.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" - integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== - -nanomatch@^1.2.9: - version "1.2.13" - resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" - integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== - dependencies: - 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" - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= - -negotiator@0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" - integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== - -nice-try@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== - -node-emoji@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.10.0.tgz#8886abd25d9c7bb61802a658523d1f8d2a89b2da" - integrity sha512-Yt3384If5H6BYGVHiHwTL+99OzJKHhgp82S8/dktEK73T26BazdgZ4JZh92xSVtGNJvz9UbXdNAc5hcrXV42vw== - dependencies: - lodash.toarray "^4.4.0" - -node-fetch@^1.0.1: - version "1.7.3" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" - integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ== - dependencies: - encoding "^0.1.11" - is-stream "^1.0.1" - -node-fetch@^2.2.0, node-fetch@^2.5.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd" - integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA== - -node-int64@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" - integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= - -node-modules-regexp@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" - integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= - -node-notifier@^5.2.1: - version "5.4.3" - resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.4.3.tgz#cb72daf94c93904098e28b9c590fd866e464bd50" - integrity sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q== - dependencies: - growly "^1.3.0" - is-wsl "^1.1.0" - semver "^5.5.0" - shellwords "^0.1.1" - which "^1.3.0" - -normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: - version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" - integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -normalize-path@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-1.0.0.tgz#32d0e472f91ff345701c15a8311018d3b0a90379" - integrity sha1-MtDkcvkf80VwHBWoMRAY07CpA3k= - -normalize-path@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= - dependencies: - remove-trailing-separator "^1.0.1" - -npm-path@^2.0.2: - version "2.0.4" - resolved "https://registry.yarnpkg.com/npm-path/-/npm-path-2.0.4.tgz#c641347a5ff9d6a09e4d9bce5580c4f505278e64" - integrity sha512-IFsj0R9C7ZdR5cP+ET342q77uSRdtWOlWpih5eC+lu29tIDbNEgDbzgVJ5UFvYHWhxDZ5TFkJafFioO0pPQjCw== - dependencies: - which "^1.2.10" - -npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= - dependencies: - path-key "^2.0.0" - -npm-which@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/npm-which/-/npm-which-3.0.1.tgz#9225f26ec3a285c209cae67c3b11a6b4ab7140aa" - integrity sha1-kiXybsOihcIJyuZ8OxGmtKtxQKo= - dependencies: - commander "^2.9.0" - npm-path "^2.0.2" - which "^1.2.10" - -nugget@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/nugget/-/nugget-2.0.1.tgz#201095a487e1ad36081b3432fa3cada4f8d071b0" - integrity sha1-IBCVpIfhrTYIGzQy+jytpPjQcbA= - dependencies: - debug "^2.1.3" - minimist "^1.1.0" - pretty-bytes "^1.0.2" - progress-stream "^1.1.0" - request "^2.45.0" - single-line-log "^1.1.2" - throttleit "0.0.2" - -nullthrows@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/nullthrows/-/nullthrows-1.1.1.tgz#7818258843856ae971eae4208ad7d7eb19a431b1" - integrity sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw== - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= - -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - -ob1@^0.56.4: - version "0.56.4" - resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.56.4.tgz#c4acb3baa42f4993a44b35b2da7c8ef443dcccec" - integrity sha512-URgFof9z2wotiYFsqlydXtQfGV81gvBI2ODy64xfd3vPo+AYom5PVDX4t4zn23t/O+S2IxqApSQM8uJAybmz7w== - -object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= - -object-copy@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" - integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= - dependencies: - copy-descriptor "^0.1.0" - define-property "^0.2.5" - kind-of "^3.0.3" - -object-inspect@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" - integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== - -object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object-keys@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336" - integrity sha1-KKaq50KN0sOpLz2V8hM13SBOAzY= - -object-visit@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" - integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= - dependencies: - isobject "^3.0.0" - -object.assign@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" - integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== - dependencies: - define-properties "^1.1.2" - function-bind "^1.1.1" - has-symbols "^1.0.0" - object-keys "^1.0.11" - -object.entries@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.1.tgz#ee1cf04153de02bb093fec33683900f57ce5399b" - integrity sha512-ilqR7BgdyZetJutmDPfXCDffGa0/Yzl2ivVNpbx/g4UeWrCdRnFDUBrKJGLhGieRHDATnyZXWBeCb29k9CJysQ== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - function-bind "^1.1.1" - has "^1.0.3" - -object.fromentries@^2.0.0, object.fromentries@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.2.tgz#4a09c9b9bb3843dd0f89acdb517a794d4f355ac9" - integrity sha512-r3ZiBH7MQppDJVLx6fhD618GKNG40CZYH9wgwdhKxBDDbQgjeWGGd4AtkZad84d291YxvWe7bJGuE65Anh0dxQ== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - function-bind "^1.1.1" - has "^1.0.3" - -object.pick@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" - integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= - dependencies: - isobject "^3.0.1" - -object.values@^1.1.0, object.values@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.1.tgz#68a99ecde356b7e9295a3c5e0ce31dc8c953de5e" - integrity sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - function-bind "^1.1.1" - has "^1.0.3" - -on-finished@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" - integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= - dependencies: - ee-first "1.1.1" - -on-headers@~1.0.1, on-headers@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" - integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== - -once@^1.3.0, once@^1.3.1, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= - dependencies: - wrappy "1" - -onetime@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" - integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= - dependencies: - mimic-fn "^1.0.0" - -onetime@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.0.tgz#fff0f3c91617fe62bb50189636e99ac8a6df7be5" - integrity sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q== - dependencies: - mimic-fn "^2.1.0" - -open@^6.2.0: - version "6.4.0" - resolved "https://registry.yarnpkg.com/open/-/open-6.4.0.tgz#5c13e96d0dc894686164f18965ecfe889ecfc8a9" - integrity sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg== - dependencies: - is-wsl "^1.1.0" - -optionator@^0.8.3: - version "0.8.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" - integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.6" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - word-wrap "~1.2.3" - -options@>=0.0.5: - version "0.0.6" - resolved "https://registry.yarnpkg.com/options/-/options-0.0.6.tgz#ec22d312806bb53e731773e7cdaefcf1c643128f" - integrity sha1-7CLTEoBrtT5zF3Pnza788cZDEo8= - -ora@^3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/ora/-/ora-3.4.0.tgz#bf0752491059a3ef3ed4c85097531de9fdbcd318" - integrity sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg== - dependencies: - chalk "^2.4.2" - cli-cursor "^2.1.0" - cli-spinners "^2.0.0" - log-symbols "^2.2.0" - strip-ansi "^5.2.0" - wcwidth "^1.0.1" - -os-locale@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" - integrity sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA== - dependencies: - execa "^0.7.0" - lcid "^1.0.0" - mem "^1.1.0" - -os-locale@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" - integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== - dependencies: - execa "^1.0.0" - lcid "^2.0.0" - mem "^4.0.0" - -os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= - -p-defer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" - integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= - -p-is-promise@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" - integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== - -p-limit@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== - dependencies: - p-try "^1.0.0" - -p-limit@^2.0.0, p-limit@^2.2.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.2.tgz#61279b67721f5287aa1c13a9a7fbbc48c9291b1e" - integrity sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ== - dependencies: - p-try "^2.0.0" - -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= - dependencies: - p-limit "^1.1.0" - -p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== - dependencies: - p-limit "^2.0.0" - -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" - integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== - dependencies: - p-limit "^2.2.0" - -p-map@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" - integrity sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA== - -p-map@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" - integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== - -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -package-json@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" - integrity sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0= - dependencies: - got "^6.7.1" - registry-auth-token "^3.0.1" - registry-url "^3.0.3" - semver "^5.1.0" - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" - integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== - dependencies: - callsites "^3.0.0" - -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= - dependencies: - error-ex "^1.2.0" - -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - -parse-node-version@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parse-node-version/-/parse-node-version-1.0.1.tgz#e2b5dbede00e7fa9bc363607f53327e8b073189b" - integrity sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA== - -parseurl@~1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" - integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== - -pascalcase@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" - integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= - -path-exists@^2.0.0, path-exists@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= - dependencies: - pinkie-promise "^2.0.0" - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= - -path-is-inside@^1.0.1, path-is-inside@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" - integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= - -path-key@^2.0.0, path-key@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= - -path-parse@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" - integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== - -path-to-regexp@^1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" - integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== - dependencies: - isarray "0.0.1" - -path-type@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" - integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= - dependencies: - graceful-fs "^4.1.2" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -path-type@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" - integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= - dependencies: - pify "^2.0.0" - -pend@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" - integrity sha1-elfrVQpng/kRUzH89GY9XI4AelA= - -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= - -pify@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= - -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= - -pify@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" - integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== - -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= - dependencies: - pinkie "^2.0.0" - -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= - -pirates@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" - integrity sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA== - dependencies: - node-modules-regexp "^1.0.0" - -pkg-dir@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" - integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= - dependencies: - find-up "^2.1.0" - -pkg-dir@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" - integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== - dependencies: - find-up "^3.0.0" - -pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" - integrity sha1-yBmscoBZpGHKscOImivjxJoATX8= - dependencies: - find-up "^2.1.0" - -please-upgrade-node@^3.0.2: - version "3.2.0" - resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942" - integrity sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg== - dependencies: - semver-compare "^1.0.0" - -plist@^3.0.0, plist@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/plist/-/plist-3.0.1.tgz#a9b931d17c304e8912ef0ba3bdd6182baf2e1f8c" - integrity sha512-GpgvHHocGRyQm74b6FWEZZVRroHKE1I0/BTjAmySaohK+cUn+hZpbqXkc3KWgW3gQYkqcQej35FohcT0FRlkRQ== - dependencies: - base64-js "^1.2.3" - xmlbuilder "^9.0.7" - xmldom "0.1.x" - -plugin-error@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-0.1.2.tgz#3b9bb3335ccf00f425e07437e19276967da47ace" - integrity sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4= - dependencies: - ansi-cyan "^0.1.1" - ansi-red "^0.1.1" - arr-diff "^1.0.1" - arr-union "^2.0.1" - extend-shallow "^1.1.2" - -posix-character-classes@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" - integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= - -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= - -prepend-http@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" - integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= - -prettier@1.16.4: - version "1.16.4" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.16.4.tgz#73e37e73e018ad2db9c76742e2647e21790c9717" - integrity sha512-ZzWuos7TI5CKUeQAtFd6Zhm2s6EpAD/ZLApIhsF9pRvRtM1RFo61dM/4MSRUA0SuLugA/zgrZD8m0BaY46Og7g== - -prettier@^1.11.1: - version "1.19.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb" - integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew== - -pretty-bytes@^1.0.2: - version "1.0.4" - resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-1.0.4.tgz#0a22e8210609ad35542f8c8d5d2159aff0751c84" - integrity sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ= - dependencies: - get-stdin "^4.0.1" - meow "^3.1.0" - -pretty-format@^23.6.0: - version "23.6.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-23.6.0.tgz#5eaac8eeb6b33b987b7fe6097ea6a8a146ab5760" - integrity sha512-zf9NV1NSlDLDjycnwm6hpFATCGl/K1lt0R/GdkAK2O5LN/rwJoB+Mh93gGJjut4YbmecbfgLWVGSTCr0Ewvvbw== - dependencies: - ansi-regex "^3.0.0" - ansi-styles "^3.2.0" - -pretty-format@^24.7.0, pretty-format@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.9.0.tgz#12fac31b37019a4eea3c11aa9a959eb7628aa7c9" - integrity sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA== - dependencies: - "@jest/types" "^24.9.0" - ansi-regex "^4.0.0" - ansi-styles "^3.2.0" - react-is "^16.8.4" - -pretty-format@^25.1.0: - version "25.1.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-25.1.0.tgz#ed869bdaec1356fc5ae45de045e2c8ec7b07b0c8" - integrity sha512-46zLRSGLd02Rp+Lhad9zzuNZ+swunitn8zIpfD2B4OPCRLXbM87RJT2aBLBWYOznNUML/2l/ReMyWNC80PJBUQ== - dependencies: - "@jest/types" "^25.1.0" - ansi-regex "^5.0.0" - ansi-styles "^4.0.0" - react-is "^16.12.0" - -private@^0.1.6, private@^0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" - integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== - -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - -progress-stream@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/progress-stream/-/progress-stream-1.2.0.tgz#2cd3cfea33ba3a89c9c121ec3347abe9ab125f77" - integrity sha1-LNPP6jO6OonJwSHsM0er6asSX3c= - dependencies: - speedometer "~0.1.2" - through2 "~0.2.3" - -progress@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== - -promise@^7.1.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" - integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg== - dependencies: - asap "~2.0.3" - -prop-types@15.7.2, prop-types@^15.5.10, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: - version "15.7.2" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" - integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== - dependencies: - loose-envify "^1.4.0" - object-assign "^4.1.1" - react-is "^16.8.1" - -proxy-polyfill@0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/proxy-polyfill/-/proxy-polyfill-0.1.6.tgz#ef41ec6c66f534db15db36c54493a62d184b364e" - integrity sha1-70HsbGb1NNsV2zbFRJOmLRhLNk4= - -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= - -psl@^1.1.28: - version "1.7.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.7.0.tgz#f1c4c47a8ef97167dea5d6bbf4816d736e884a3c" - integrity sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ== - -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -punycode@^2.1.0, punycode@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== - -qs@~6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== - -query-string@6.8.1: - version "6.8.1" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.8.1.tgz#62c54a7ef37d01b538c8fd56f95740c81d438a26" - integrity sha512-g6y0Lbq10a5pPQpjlFuojfMfV1Pd2Jw9h75ypiYPPia3Gcq2rgkKiIwbkS6JxH7c5f5u/B/sB+d13PU+g1eu4Q== - dependencies: - decode-uri-component "^0.2.0" - split-on-first "^1.0.0" - strict-uri-encode "^2.0.0" - -query-string@^6.11.0: - version "6.11.1" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.11.1.tgz#ab021f275d463ce1b61e88f0ce6988b3e8fe7c2c" - integrity sha512-1ZvJOUl8ifkkBxu2ByVM/8GijMIPx+cef7u3yroO3Ogm4DOdZcF5dcrWTIlSHe3Pg/mtlt6/eFjObDfJureZZA== - dependencies: - decode-uri-component "^0.2.0" - split-on-first "^1.0.0" - strict-uri-encode "^2.0.0" - -range-parser@~1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== - -rc@^1.0.1, rc@^1.1.2, rc@^1.1.6: - version "1.2.8" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - -react-async-hook@3.6.1: - version "3.6.1" - resolved "https://registry.yarnpkg.com/react-async-hook/-/react-async-hook-3.6.1.tgz#aed3e492d87319392865c83ed7cef3609e2a7fef" - integrity sha512-YWBB2feVQF79t5u2raMPHlZ8975Jds+guCvkWVC4kRLDlSCouLsYpQm4DGSqPeHvoHYVVcDfqNayLZAXQmnxnw== - -react-devtools-core@^3.6.0, react-devtools-core@^3.6.3: - version "3.6.3" - resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-3.6.3.tgz#977d95b684c6ad28205f0c62e1e12c5f16675814" - integrity sha512-+P+eFy/yo8Z/UH9J0DqHZuUM5+RI2wl249TNvMx3J2jpUomLQa4Zxl56GEotGfw3PIP1eI+hVf1s53FlUONStQ== - dependencies: - shell-quote "^1.6.1" - ws "^3.3.1" - -react-devtools@^3.6.3: - version "3.6.3" - resolved "https://registry.yarnpkg.com/react-devtools/-/react-devtools-3.6.3.tgz#47fcedbd2306724909b6ec76cd51392e93493c3f" - integrity sha512-7JrGlKHvyamqDfDi7EEoIC8BHygKC1Mc8PmAAYm0aokwYuam/42bO1gnF5y2K7K1MbO+6f7J93s1N4VK0YdmEw== - dependencies: - cross-spawn "^5.0.1" - electron "^1.8.7" - ip "^1.1.4" - minimist "^1.2.0" - react-devtools-core "^3.6.0" - update-notifier "^2.1.0" - -react-is@^16.12.0, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.8.6: - version "16.13.0" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.0.tgz#0f37c3613c34fe6b37cd7f763a0d6293ab15c527" - integrity sha512-GFMtL0vHkiBv9HluwNZTggSn/sCyEt9n02aM0dSAjGGyqyNlAyftYm4phPxdvCigG15JreC5biwxCgTAJZ7yAA== - -react-lifecycles-compat@^3.0.0, react-lifecycles-compat@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" - integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== - -react-native-camera@^3.15.0: - version "3.19.0" - resolved "https://registry.yarnpkg.com/react-native-camera/-/react-native-camera-3.19.0.tgz#32c43908d3ba398c89d21437a9dba2ebb17f3896" - integrity sha512-ef3ccKUu5nYRvc2fXlnRDsrBPBygkXoMvk0c/mrgfLYgr4X0G/8Qg7t+MOAisQ0V6RastHVygpjgAW+dxcZnyA== - dependencies: - prop-types "^15.6.2" - -react-native-country-picker-modal@^1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/react-native-country-picker-modal/-/react-native-country-picker-modal-1.10.0.tgz#ff4a3b73f08d5241f75f9edfaa2ad4cc0b1823f7" - integrity sha512-NkPBF7GJRp1FONiirN0vOLb9q6HKA/S1oIVNQUNGk9lVv5OLJ5Op3XhY7f+Dg4g7tF/M3kMXZWuvRWmKoHrMMQ== - dependencies: - "@callstack/react-theme-provider" "3.0.3" - fuse.js "3.4.5" - modal-react-native-web "0.2.0" - node-emoji "1.10.0" - prop-types "15.7.2" - react-async-hook "3.6.1" - -react-native-exception-handler@2.10.8: - version "2.10.8" - resolved "https://registry.yarnpkg.com/react-native-exception-handler/-/react-native-exception-handler-2.10.8.tgz#1a7f846592d888d23adaf797e31802585f1d9ff0" - integrity sha512-ZN+jwpADRkCUNdad/50k0mZdMoICGrGdtaxgvRU+pNcWRRBAXJhuo4+jY0eQaoVpx1ghycGE6tBu9ka8gL2NOQ== - -react-native-fast-image@^7.0.2: - version "7.0.2" - resolved "https://registry.yarnpkg.com/react-native-fast-image/-/react-native-fast-image-7.0.2.tgz#e06b21f42f4a9786eaa86f3db35d919070fb8403" - integrity sha512-MfuzJbC0RjYobR2gFCdqe1I7jvNOCfDkjQ7VGOHXniqjohhULMkcWNBE9Umovi9Dx93lJ6t5utcE2wf/09zvlg== - -react-native-fs@^2.16.6: - version "2.16.6" - resolved "https://registry.yarnpkg.com/react-native-fs/-/react-native-fs-2.16.6.tgz#2901789a43210a35a0ef0a098019bbef3af395fd" - integrity sha512-ZWOooD1AuFoAGY3HS2GY7Qx2LZo4oIg6AK0wbC68detxwvX75R/q9lRqThXNKP6vIo2VHWa0fYUo/SrLw80E8w== - dependencies: - base-64 "^0.1.0" - utf8 "^3.0.0" - -react-native-gesture-handler@1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-1.5.2.tgz#281111550bf1eee10b7feba5278d142169892731" - integrity sha512-Xp03dq4XYVTD0xmWx4DW4eX+ox1NQLjHmbykspTdS5FCNIVIOekVXRLFCw1698/v8dYUHApNo6K3s3BCD8fqPA== - dependencies: - hammerjs "^2.0.8" - hoist-non-react-statics "^2.3.1" - invariant "^2.2.4" - prop-types "^15.7.2" - -react-native-image-pan-zoom@^2.1.9: - version "2.1.11" - resolved "https://registry.yarnpkg.com/react-native-image-pan-zoom/-/react-native-image-pan-zoom-2.1.11.tgz#61bcb69219d95e76a9797d23e4a2e8e0bd654ae9" - integrity sha512-ZCisGUFpPchHXsjT7ZI0anlSLPgcTmjRKXqpVnPu3RDWFXfKjuL4zpY57DX4Y8YgGZCpbf9fApN7KjVYody2Mw== - -react-native-image-zoom-viewer@^2.2.5: - version "2.2.27" - resolved "https://registry.yarnpkg.com/react-native-image-zoom-viewer/-/react-native-image-zoom-viewer-2.2.27.tgz#fb3314c5dc86ac33da48cb31bf4920d97eecb6eb" - integrity sha512-BMA8ZGe6dub9mPbGhFn14eAnq8H5ig32nY9vPqTjsJluLTcwjkMjupu47dha1ikK7vFo0zpGDFKlv2WHbtf+EQ== - dependencies: - react-native-image-pan-zoom "^2.1.9" - -react-native-password-strength-meter@^0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/react-native-password-strength-meter/-/react-native-password-strength-meter-0.0.2.tgz#55504518eaffb5d6a738f79f8692aa6783fd5f29" - integrity sha512-jONkwnbznl2xJnJK3/eGa/EL87darI6n+/FtVFXRdyGqypWy6lFJALn/C6m9FyodVArrrpXJ60Ke8nWaGmPALw== - dependencies: - prop-types "^15.6.2" - react-native-speedometer "^1.0.0" - -react-native-phone-input@lbryio/react-native-phone-input: - version "0.2.0" - resolved "https://codeload.github.com/lbryio/react-native-phone-input/tar.gz/60fdef484e8bf27328c7fb6a203baab9eb9cd4a1" - dependencies: - google-libphonenumber "^2.0.9" - lodash "^4.17.4" - prop-types "^15.5.10" - -react-native-progress-circle@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/react-native-progress-circle/-/react-native-progress-circle-2.1.0.tgz#62bdf31c76962d10c5c14446b61ff7d05cf0d0ec" - integrity sha512-VP0s92bgbTMQy4hQzPU4LlGyFj3z5u7i1HYFG8/yzXXfGkX1cxKS4xOlE+OTaObWC99w7Bodi3h8R7En2nQPYw== - -react-native-reanimated@1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-1.4.0.tgz#7f1acbf9be08492d834f512700570978052be2f9" - integrity sha512-tO7nSNNP+iRLVbkcSS5GXyDBb7tSI02+XuRL3/S39EAr35rnvUy2JfeLUQG+fWSObJjnMVhasUDEUwlENk8IXw== - -react-native-safe-area-context@^0.6.2: - version "0.6.4" - resolved "https://registry.yarnpkg.com/react-native-safe-area-context/-/react-native-safe-area-context-0.6.4.tgz#624bd50cebc9f47853f179373501511931d2a0c3" - integrity sha512-xj8Mv8ZHfc8RquBgVYt+4+nOJaexTblLsQJpyx4Dh4qFUG+3QtbNlfOF7/ITj/qY5LNdlfafKoDsVgFz0WIU1w== - -react-native-safe-area-view@^0.14.6, react-native-safe-area-view@^0.14.8: - version "0.14.8" - resolved "https://registry.yarnpkg.com/react-native-safe-area-view/-/react-native-safe-area-view-0.14.8.tgz#ef33c46ff8164ae77acad48c3039ec9c34873e5b" - integrity sha512-MtRSIcZNstxv87Jet+UsPhEd1tpGe8cVskDXlP657x6rHpSrbrc+y13ZNXrwAgGNNhqQNX7UJT68ZIq//ZRmvw== - dependencies: - hoist-non-react-statics "^2.3.1" - -react-native-screens@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/react-native-screens/-/react-native-screens-2.2.0.tgz#cc4cdf17426fdda97ad93a5e812a1899390f1978" - integrity sha512-a0VzxOWot7F9B/GQyDSssBRd3jUJazFnTQS61IiyReWB6aHlFhf3Xz10jBRoURXy1EMCDCHgenmTVTkKHpKyqQ== - dependencies: - debounce "^1.2.0" - -react-native-snackbar@2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/react-native-snackbar/-/react-native-snackbar-2.0.4.tgz#cc9587600b6c67267b5a96eb74e693d2e3eee054" - integrity sha512-q0NhXYV3uBebN4z9MenR8SIycFGM7QN8NWgwcbJn1zuEiRp49jaJRR/KX7ucS385BvqzBdUu+QqF7SrFN7HiRA== - -react-native-speedometer@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/react-native-speedometer/-/react-native-speedometer-1.0.3.tgz#d4fc26861f3882aa008b8c1b349e0c1e667bd588" - integrity sha512-34Ne/ptaWv97jbSOq87b+gKHvGKeZ4AjYXZvovbEnQMnYNzCBWZbQNJqWWzOxyFZXbzeDsfiQ6d4xpq2pc1Tfw== - dependencies: - prop-types "^15.6.2" - -react-native-super-grid@^3.0.4: - version "3.1.2" - resolved "https://registry.yarnpkg.com/react-native-super-grid/-/react-native-super-grid-3.1.2.tgz#55deb3cd52173c487b76c868e7f794044fc0c6cd" - integrity sha512-H7dB2j0ZGH6i//2oOy1xtdLam1k3Y41jIdLwv1ukSTuSe9j/de++GrrCLqZvjAaHx2JNHgrqQRQy3kqzKos3DQ== - dependencies: - prop-types "^15.6.0" - -react-native-tab-view@^2.11.0: - version "2.13.0" - resolved "https://registry.yarnpkg.com/react-native-tab-view/-/react-native-tab-view-2.13.0.tgz#23037aa43b0f8f682ddc20415a4baaaf6f82ae8f" - integrity sha512-AeYbp/u91+D/C9+PmVEPBmFb3ixv8IkLMC3Sc5MajJ/fg0Zl3Of+BcEknBvTnKoe7Fj2y8+Qf9zorBbh5xzh4A== - -react-native-vector-icons@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/react-native-vector-icons/-/react-native-vector-icons-6.0.0.tgz#3a7076dbe244ea94c6d5e92802a870e64a4283c5" - integrity sha512-uF3oWb3TV42uXi2apVOZHw9oy9Nr5SXDVwOo1umQWo/yYCrDzXyVfq14DzezgEbJ9jfc/yghBelj0agkXmOKlg== - dependencies: - lodash "^4.0.0" - prop-types "^15.6.2" - yargs "^8.0.2" - -react-native-vector-icons@^6.6.0: - version "6.6.0" - resolved "https://registry.yarnpkg.com/react-native-vector-icons/-/react-native-vector-icons-6.6.0.tgz#66cf004918eb05d90778d64bd42077c1800d481b" - integrity sha512-MImKVx8JEvVVBnaShMr7/yTX4Y062JZMupht1T+IEgbqBj4aQeQ1z2SH4VHWKNtWtppk4kz9gYyUiMWqx6tNSw== - dependencies: - lodash "^4.0.0" - prop-types "^15.6.2" - yargs "^13.2.2" - -react-native-video@lbryio/react-native-video#7992ff945872f9bd00a3736d9ff1318f343abf47: - version "5.1.0-alpha1" - resolved "https://codeload.github.com/lbryio/react-native-video/tar.gz/7992ff945872f9bd00a3736d9ff1318f343abf47" - dependencies: - keymirror "^0.1.1" - prop-types "^15.5.10" - shaka-player "^2.4.4" - -react-native-webview@^8.0.2: - version "8.1.2" - resolved "https://registry.yarnpkg.com/react-native-webview/-/react-native-webview-8.1.2.tgz#c2ddb1e82d1c294f8f68a13be5d0536f7808f377" - integrity sha512-UnGQDttXcgp9JuexidYVu3KIQn1V9xG93yKIs7u6OMdORD5EM4lm7Z1fqqBa59LBeEii5M546kh1/rm0rDA0cA== - dependencies: - escape-string-regexp "2.0.0" - invariant "2.2.4" - -react-native@0.61.5: - version "0.61.5" - resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.61.5.tgz#6e21acb56cbd75a3baeb1f70201a66f42600bba8" - integrity sha512-MXqE3NoGO0T3dUKIKkIppijBhRRMpfN6ANbhMXHDuyfA+fSilRWgCwYgR/YNCC7ntECoJYikKaNTUBB0DeQy6Q== - dependencies: - "@babel/runtime" "^7.0.0" - "@react-native-community/cli" "^3.0.0" - "@react-native-community/cli-platform-android" "^3.0.0" - "@react-native-community/cli-platform-ios" "^3.0.0" - abort-controller "^3.0.0" - art "^0.10.0" - base64-js "^1.1.2" - connect "^3.6.5" - create-react-class "^15.6.3" - escape-string-regexp "^1.0.5" - event-target-shim "^5.0.1" - fbjs "^1.0.0" - fbjs-scripts "^1.1.0" - hermes-engine "^0.2.1" - invariant "^2.2.4" - jsc-android "^245459.0.0" - metro-babel-register "^0.56.0" - metro-react-native-babel-transformer "^0.56.0" - metro-source-map "^0.56.0" - nullthrows "^1.1.0" - pretty-format "^24.7.0" - promise "^7.1.1" - prop-types "^15.7.2" - react-devtools-core "^3.6.3" - react-refresh "^0.4.0" - regenerator-runtime "^0.13.2" - scheduler "0.15.0" - stacktrace-parser "^0.1.3" - whatwg-fetch "^3.0.0" - -react-navigation-drawer@2.3.3: - version "2.3.3" - resolved "https://registry.yarnpkg.com/react-navigation-drawer/-/react-navigation-drawer-2.3.3.tgz#d7e607d5e10f2b3c40ab7dc9720228ce3f888a0f" - integrity sha512-d/rA8Slqv7HoMfONKVDBQUrRF7YQH796Gzal/KOhaY4VOwUUqIwfxMRJ3WrsdL2OkDPixtkXJE2Fz6KAj658uA== - -react-navigation-redux-helpers@^3.0.2: - version "3.0.8" - resolved "https://registry.yarnpkg.com/react-navigation-redux-helpers/-/react-navigation-redux-helpers-3.0.8.tgz#a49024717e5af2d910679afec778743098445367" - integrity sha512-6UQcTXo0V3Q3XkUptXUgd9DFmKJchvw0H5vrNoAaM6Il/37ZkGhF42UGtX4+Lt9QNyQ7+XM4GAeWPuDAreJMsA== - dependencies: - invariant "^2.2.2" - -react-navigation-stack@^1.10.3: - version "1.10.3" - resolved "https://registry.yarnpkg.com/react-navigation-stack/-/react-navigation-stack-1.10.3.tgz#e714e442b20427f0d2d3c18fce1f9e8cfe69be0b" - integrity sha512-1gksFi/g/Lg9sBhgLlD0OiEB5xnatHb4C0eNMA5tli9cTVlhq375XNPIqOiTyftibBmjdApAsZFj5srUCoOu/w== - dependencies: - prop-types "^15.7.2" - -react-navigation-tabs@^2.7.0: - version "2.8.2" - resolved "https://registry.yarnpkg.com/react-navigation-tabs/-/react-navigation-tabs-2.8.2.tgz#b49534a77a6b15fd7f681a33007e3fff7faf3f84" - integrity sha512-eLoLh2DetaXdrKkb4wR8e6+npi0E7UGn6iHmDKHdV5M6SFdsgz5CaEXW/tg+pgvGDb/8iG6syTUV1KrUtFCZ4Q== - dependencies: - hoist-non-react-statics "^3.3.2" - react-lifecycles-compat "^3.0.4" - react-native-safe-area-view "^0.14.6" - react-native-tab-view "^2.11.0" - -react-navigation@^4.0.10: - version "4.2.2" - resolved "https://registry.yarnpkg.com/react-navigation/-/react-navigation-4.2.2.tgz#8183f47c1b0c7c2350e970aa652c0fee4160ef9e" - integrity sha512-/CdQsDkUEJWyKKK68txvFUJDO79+MYFX6DYTVbQ23YtSw/GD5J5pQ/E08IJy8PJNYgnWP/OhiOYg2UpNoh96RQ== - dependencies: - "@react-navigation/core" "^3.6.1" - "@react-navigation/native" "^3.7.3" - -react-redux@^5.0.3: - version "5.1.2" - resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-5.1.2.tgz#b19cf9e21d694422727bf798e934a916c4080f57" - integrity sha512-Ns1G0XXc8hDyH/OcBHOxNgQx9ayH3SPxBnFCOidGKSle8pKihysQw2rG/PmciUQRoclhVBO8HMhiRmGXnDja9Q== - dependencies: - "@babel/runtime" "^7.1.2" - hoist-non-react-statics "^3.3.0" - invariant "^2.2.4" - loose-envify "^1.1.0" - prop-types "^15.6.1" - react-is "^16.6.0" - react-lifecycles-compat "^3.0.0" - -react-refresh@^0.4.0: - version "0.4.2" - resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.4.2.tgz#54a277a6caaac2803d88f1d6f13c1dcfbd81e334" - integrity sha512-kv5QlFFSZWo7OlJFNYbxRtY66JImuP2LcrFgyJfQaf85gSP+byzG21UbDQEYjU7f//ny8rwiEkO6py2Y+fEgAQ== - -react@16.9.0: - version "16.9.0" - resolved "https://registry.yarnpkg.com/react/-/react-16.9.0.tgz#40ba2f9af13bc1a38d75dbf2f4359a5185c4f7aa" - integrity sha512-+7LQnFBwkiw+BobzOF6N//BdoNw0ouwmSJTEm9cglOOmsg/TMiFHZLe2sEoN5M7LgJTj9oHH0gxklfnQe66S1w== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - prop-types "^15.6.2" - -reactotron-core-client@2.8.6: - version "2.8.6" - resolved "https://registry.yarnpkg.com/reactotron-core-client/-/reactotron-core-client-2.8.6.tgz#c3e02aca1af6246d033f2946c38562e2c7a4df09" - integrity sha512-xgg6dusfgQHC98f4iRH/Zak/PNvA46znupEd2U7DSCmmhZbfCpSSveKUsYok0OW0HiSCSvi41tNELj+QU6pRVQ== - -reactotron-react-native@4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/reactotron-react-native/-/reactotron-react-native-4.0.2.tgz#b44185e95186c89617f69484bc056e9284425057" - integrity sha512-zY5m0TV9y52h31/Vvd/Zs3jneEKYWbJ6vGrBeZ/d6Z2gVvwI3su+7B2qh8s00KHStIF4MTg0MrKc0FYRFWmmoQ== - dependencies: - mitt "1.1.3" - query-string "6.8.1" - reactotron-core-client "2.8.6" - rn-host-detect "1.1.5" - -reactotron-redux@3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/reactotron-redux/-/reactotron-redux-3.1.2.tgz#37301687d4e2a5548664d21fc7447d1171e08ab2" - integrity sha512-2ScTmE2+kxjKPc7+vsYuw+igkhd4tjoftn4ouugVudQCO7B5vXVyQwLkNv/feaFfFoPlCQSVeJVg7PdzDFOsEQ== - -read-pkg-up@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" - integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= - dependencies: - find-up "^1.0.0" - read-pkg "^1.0.0" - -read-pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" - integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= - dependencies: - find-up "^2.0.0" - read-pkg "^2.0.0" - -read-pkg@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" - integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= - dependencies: - load-json-file "^1.0.0" - normalize-package-data "^2.3.2" - path-type "^1.0.0" - -read-pkg@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" - integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= - dependencies: - load-json-file "^2.0.0" - normalize-package-data "^2.3.2" - path-type "^2.0.0" - -readable-stream@^2.0.1, readable-stream@^2.2.2, readable-stream@~2.3.6: - version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" - integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== - dependencies: - 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" - -readable-stream@~1.1.9: - version "1.1.14" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" - integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.1" - isarray "0.0.1" - string_decoder "~0.10.x" - -redent@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" - integrity sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94= - dependencies: - indent-string "^2.1.0" - strip-indent "^1.0.1" - -redux-persist-filesystem-storage@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/redux-persist-filesystem-storage/-/redux-persist-filesystem-storage-2.1.0.tgz#418d6b7cf22f060766c110e9a3fd11ffaaa09485" - integrity sha512-KFj4opJCu8WXUveNV8YKZ1OMGiQm0kiTjWHSSYJ2hmQNrhEa7MOMiIcTImfNDO3vfRl9U+bidKDhQebtCeWrCw== - dependencies: - rn-fetch-blob "^0.10.16" - -redux-persist-transform-compress@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/redux-persist-transform-compress/-/redux-persist-transform-compress-4.2.0.tgz#5089e299df7130878fca45f97ffe82888ba02690" - integrity sha1-UInimd9xMIePykX5f/6CiIugJpA= - dependencies: - json-stringify-safe "^5.0.1" - lz-string "^1.4.4" - -redux-persist-transform-filter@0.0.18: - version "0.0.18" - resolved "https://registry.yarnpkg.com/redux-persist-transform-filter/-/redux-persist-transform-filter-0.0.18.tgz#bc9901a0267bd64631099b4e7bb4d48c00647418" - integrity sha512-x9NxuHNDnK/THLLBqwP1tqw0yIcuxuVYXBssgGcmm5anxL0flbpLQGB5CbFYHWGG68VdQKr1vUneVnttxWJDtA== - dependencies: - lodash.clonedeep "^4.5.0" - lodash.forin "^4.4.0" - lodash.get "^4.4.2" - lodash.isempty "^4.4.0" - lodash.pickby "^4.6.0" - lodash.set "^4.3.2" - lodash.unset "^4.5.2" - -redux-persist@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/redux-persist/-/redux-persist-6.0.0.tgz#b4d2972f9859597c130d40d4b146fecdab51b3a8" - integrity sha512-71LLMbUq2r02ng2We9S215LtPu3fY0KgaGE0k8WRgl6RkqxtGfl7HUozz1Dftwsb0D/5mZ8dwAaPbtnzfvbEwQ== - -redux-thunk@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.3.0.tgz#51c2c19a185ed5187aaa9a2d08b666d0d6467622" - integrity sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw== - -redux@^4.0.4: - version "4.0.5" - resolved "https://registry.yarnpkg.com/redux/-/redux-4.0.5.tgz#4db5de5816e17891de8a80c424232d06f051d93f" - integrity sha512-VSz1uMAH24DM6MF72vcojpYPtrTUu3ByVWfPL1nPfVRb5mZVTve5GnNCUV53QM/BZ66xfWrm0CTWoM+Xlz8V1w== - dependencies: - loose-envify "^1.4.0" - symbol-observable "^1.2.0" - -regenerate-unicode-properties@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz#ef51e0f0ea4ad424b77bf7cb41f3e015c70a3f0e" - integrity sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA== - dependencies: - regenerate "^1.4.0" - -regenerate@^1.2.1, regenerate@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" - integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg== - -regenerator-runtime@^0.11.0: - version "0.11.1" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" - integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== - -regenerator-runtime@^0.13.2: - version "0.13.3" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz#7cf6a77d8f5c6f60eb73c5fc1955b2ceb01e6bf5" - integrity sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw== - -regenerator-runtime@^0.13.4: - version "0.13.4" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.4.tgz#e96bf612a3362d12bb69f7e8f74ffeab25c7ac91" - integrity sha512-plpwicqEzfEyTQohIKktWigcLzmNStMGwbOUbykx51/29Z3JOGYldaaNGK7ngNXV+UcoqvIMmloZ48Sr74sd+g== - -regenerator-transform@^0.10.0: - version "0.10.1" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" - integrity sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q== - dependencies: - babel-runtime "^6.18.0" - babel-types "^6.19.0" - private "^0.1.6" - -regenerator-transform@^0.14.2: - version "0.14.2" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.2.tgz#949d9d87468ff88d5a7e4734ebb994a892de1ff2" - integrity sha512-V4+lGplCM/ikqi5/mkkpJ06e9Bujq1NFmNLvsCs56zg3ZbzrnUzAtizZ24TXxtRX/W2jcdScwQCnbL0CICTFkQ== - dependencies: - "@babel/runtime" "^7.8.4" - private "^0.1.8" - -regex-not@^1.0.0, regex-not@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" - integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== - dependencies: - extend-shallow "^3.0.2" - safe-regex "^1.1.0" - -regexp.prototype.flags@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz#7aba89b3c13a64509dabcf3ca8d9fbb9bdf5cb75" - integrity sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - -regexpp@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" - integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== - -regexpu-core@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" - integrity sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA= - dependencies: - regenerate "^1.2.1" - regjsgen "^0.2.0" - regjsparser "^0.1.4" - -regexpu-core@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.6.0.tgz#2037c18b327cfce8a6fea2a4ec441f2432afb8b6" - integrity sha512-YlVaefl8P5BnFYOITTNzDvan1ulLOiXJzCNZxduTIosN17b87h3bvG9yHMoHaRuo88H4mQ06Aodj5VtYGGGiTg== - dependencies: - regenerate "^1.4.0" - regenerate-unicode-properties "^8.1.0" - regjsgen "^0.5.0" - regjsparser "^0.6.0" - unicode-match-property-ecmascript "^1.0.4" - unicode-match-property-value-ecmascript "^1.1.0" - -registry-auth-token@^3.0.1: - version "3.4.0" - resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.4.0.tgz#d7446815433f5d5ed6431cd5dca21048f66b397e" - integrity sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A== - dependencies: - rc "^1.1.6" - safe-buffer "^5.0.1" - -registry-url@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" - integrity sha1-PU74cPc93h138M+aOBQyRE4XSUI= - dependencies: - rc "^1.0.1" - -regjsgen@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" - integrity sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc= - -regjsgen@^0.5.0: - version "0.5.1" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.1.tgz#48f0bf1a5ea205196929c0d9798b42d1ed98443c" - integrity sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg== - -regjsparser@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" - integrity sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw= - dependencies: - jsesc "~0.5.0" - -regjsparser@^0.6.0: - version "0.6.3" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.3.tgz#74192c5805d35e9f5ebe3c1fb5b40d40a8a38460" - integrity sha512-8uZvYbnfAtEm9Ab8NTb3hdLwL4g/LQzEYP7Xs27T96abJCCE2d6r3cPZPQEsLKy0vRSGVNG+/zVGtLr86HQduA== - dependencies: - jsesc "~0.5.0" - -remove-trailing-separator@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= - -repeat-element@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" - integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== - -repeat-string@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= - -repeating@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" - integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= - dependencies: - is-finite "^1.0.0" - -request@^2.45.0: - version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= - -require-main-filename@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" - integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= - -require-main-filename@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" - integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== - -reselect@^3.0.0, reselect@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/reselect/-/reselect-3.0.1.tgz#efdaa98ea7451324d092b2b2163a6a1d7a9a2147" - integrity sha1-79qpjqdFEyTQkrKyFjpqHXqaIUc= - -resolve-from@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" - integrity sha1-six699nWiBvItuZTM17rywoYh0g= - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -resolve-url@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= - -resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.14.2, resolve@^1.3.2, resolve@^1.4.0, resolve@^1.5.0, resolve@^1.8.1, resolve@^1.9.0: - version "1.15.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8" - integrity sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w== - dependencies: - path-parse "^1.0.6" - -restore-cursor@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" - integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= - dependencies: - onetime "^2.0.0" - signal-exit "^3.0.2" - -restore-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" - integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== - dependencies: - onetime "^5.1.0" - signal-exit "^3.0.2" - -ret@~0.1.10: - version "0.1.15" - resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" - integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== - -rimraf@2.6.3: - version "2.6.3" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" - integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== - dependencies: - glob "^7.1.3" - -rimraf@^2.2.8, rimraf@^2.5.4: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== - dependencies: - glob "^7.1.3" - -rimraf@~2.2.6: - version "2.2.8" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582" - integrity sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI= - -rn-fetch-blob@0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/rn-fetch-blob/-/rn-fetch-blob-0.12.0.tgz#ec610d2f9b3f1065556b58ab9c106eeb256f3cba" - integrity sha512-+QnR7AsJ14zqpVVUbzbtAjq0iI8c9tCg49tIoKO2ezjzRunN7YL6zFSFSWZm6d+mE/l9r+OeDM3jmb2tBb2WbA== - dependencies: - base-64 "0.1.0" - glob "7.0.6" - -rn-fetch-blob@^0.10.16: - version "0.10.16" - resolved "https://registry.yarnpkg.com/rn-fetch-blob/-/rn-fetch-blob-0.10.16.tgz#bd54f66c94f7a8e06c213077483646478ae8d230" - integrity sha512-hZV+nF0HK4CWmspXGMw7/G8Q8qugpS/wbKiNLsFpdBZR8XYzjFZNvBWgGyC0F5JWQn3sjmK2w/FJjBlwdQWNQg== - dependencies: - base-64 "0.1.0" - glob "7.0.6" - -rn-host-detect@1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/rn-host-detect/-/rn-host-detect-1.1.5.tgz#fbecb982b73932f34529e97932b9a63e58d8deb6" - integrity sha512-ufk2dFT3QeP9HyZ/xTuMtW27KnFy815CYitJMqQm+pgG3ZAtHBsrU8nXizNKkqXGy3bQmhEoloVbrfbvMJMqkg== - -rsvp@^4.8.4: - version "4.8.5" - resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" - integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA== - -run-async@^2.2.0, run-async@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.0.tgz#e59054a5b86876cfae07f431d18cbaddc594f1e8" - integrity sha512-xJTbh/d7Lm7SBhc1tNvTpeCHaEzoyxPrqNlvSdMfBTYwaY++UJFyXUOxAtsRUXjlqOfj8luNaR9vjCh4KeV+pg== - dependencies: - is-promise "^2.1.0" - -rx-lite-aggregates@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" - integrity sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74= - dependencies: - rx-lite "*" - -rx-lite@*, rx-lite@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" - integrity sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ= - -rxjs@^5.4.3: - version "5.5.12" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.12.tgz#6fa61b8a77c3d793dbaf270bee2f43f652d741cc" - integrity sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw== - dependencies: - symbol-observable "1.0.1" - -rxjs@^6.3.3, rxjs@^6.5.3: - version "6.5.4" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.4.tgz#e0777fe0d184cec7872df147f303572d414e211c" - integrity sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q== - dependencies: - tslib "^1.9.0" - -safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-buffer@^5.0.1, safe-buffer@^5.1.2: - version "5.2.0" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" - integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== - -safe-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" - integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= - dependencies: - ret "~0.1.10" - -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -sane@^4.0.3: - version "4.1.0" - resolved "https://registry.yarnpkg.com/sane/-/sane-4.1.0.tgz#ed881fd922733a6c461bc189dc2b6c006f3ffded" - integrity sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA== - dependencies: - "@cnakazawa/watch" "^1.0.3" - anymatch "^2.0.0" - capture-exit "^2.0.0" - exec-sh "^0.3.2" - execa "^1.0.0" - fb-watchman "^2.0.0" - micromatch "^3.1.4" - minimist "^1.1.1" - walker "~1.0.5" - -sax@^1.2.1: - version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== - -scheduler@0.15.0: - version "0.15.0" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.15.0.tgz#6bfcf80ff850b280fed4aeecc6513bc0b4f17f8e" - integrity sha512-xAefmSfN6jqAa7Kuq7LIJY0bwAPG3xlCj0HMEBQk1lxYiDKZscY2xJ5U/61ZTrYbmNQbXa+gc7czPkVo11tnCg== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - -seedrandom@3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-3.0.3.tgz#74efcc324533b417b8f3e2cf2a70797aa4a94441" - integrity sha512-PJLhhxIMjlMJaiIRtqiVW061EZn3cS+waZkbFe7eCa2R3g88HbNdWmw4NTFG1w5unxd0GeNaUUxZJP7gPAzSDQ== - -semver-compare@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" - integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= - -semver-diff@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" - integrity sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY= - dependencies: - semver "^5.0.3" - -"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - -semver@5.5.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" - integrity sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA== - -semver@^6.1.2, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== - -send@0.17.1: - version "0.17.1" - resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" - integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== - dependencies: - debug "2.6.9" - depd "~1.1.2" - destroy "~1.0.4" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "~1.7.2" - mime "1.6.0" - ms "2.1.1" - on-finished "~2.3.0" - range-parser "~1.2.1" - statuses "~1.5.0" - -serialize-error@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-2.1.0.tgz#50b679d5635cdf84667bdc8e59af4e5b81d5f60a" - integrity sha1-ULZ51WNc34Rme9yOWa9OW4HV9go= - -serve-static@^1.13.1: - version "1.14.1" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" - integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== - dependencies: - encodeurl "~1.0.2" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.17.1" - -set-blocking@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= - -set-value@^2.0.0, set-value@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" - integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.3" - split-string "^3.0.1" - -setimmediate@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= - -setprototypeof@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" - integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== - -shaka-player@^2.4.4: - version "2.5.9" - resolved "https://registry.yarnpkg.com/shaka-player/-/shaka-player-2.5.9.tgz#007dc19df2bb5d3d959d278b2d894af05adffe38" - integrity sha512-XavLBqxvIbvLOPfk7VKZu5fbMJyVko9bBfzxmMWdX5bvQwUSjU7ZhV8v2tHqXQYafpHml1hlGHzKkLs7idouNQ== - dependencies: - eme-encryption-scheme-polyfill "^2.0.0" - -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= - dependencies: - shebang-regex "^1.0.0" - -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= - -shell-quote@1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767" - integrity sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c= - dependencies: - array-filter "~0.0.0" - array-map "~0.0.0" - array-reduce "~0.0.0" - jsonify "~0.0.0" - -shell-quote@^1.6.1: - version "1.7.2" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2" - integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg== - -shellwords@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" - integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== - -showdown@1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/showdown/-/showdown-1.9.1.tgz#134e148e75cd4623e09c21b0511977d79b5ad0ef" - integrity sha512-9cGuS382HcvExtf5AHk7Cb4pAeQQ+h0eTr33V1mu+crYWV4KvWAw6el92bDrqGEk5d46Ai/fhbEUwqJ/mTCNEA== - dependencies: - yargs "^14.2" - -side-channel@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.2.tgz#df5d1abadb4e4bf4af1cd8852bf132d2f7876947" - integrity sha512-7rL9YlPHg7Ancea1S96Pa8/QWb4BtXL/TZvS6B8XFetGBeuhAsfmUspK6DokBeZ64+Kj9TCNRD/30pVz1BvQNA== - dependencies: - es-abstract "^1.17.0-next.1" - object-inspect "^1.7.0" - -signal-exit@^3.0.0, signal-exit@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" - integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= - -simple-plist@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/simple-plist/-/simple-plist-1.1.0.tgz#8354ab63eb3922a054c78ce96c209c532e907a23" - integrity sha512-2i5Tc0BYAqppM7jVzmNrI+aEUntPolIq4fDgji6WuNNn1D/qYdn2KwoLhZdzQkE04lu9L5tUoeJsjuJAvd+lFg== - dependencies: - bplist-creator "0.0.8" - bplist-parser "0.2.0" - plist "^3.0.1" - -single-line-log@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/single-line-log/-/single-line-log-1.1.2.tgz#c2f83f273a3e1a16edb0995661da0ed5ef033364" - integrity sha1-wvg/Jzo+GhbtsJlWYdoO1e8DM2Q= - dependencies: - string-width "^1.0.1" - -slash@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" - integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== - -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - -slice-ansi@0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" - integrity sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU= - -slice-ansi@^2.0.0, slice-ansi@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" - integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== - dependencies: - ansi-styles "^3.2.0" - astral-regex "^1.0.0" - is-fullwidth-code-point "^2.0.0" - -slide@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" - integrity sha1-VusCfWW00tzmyy4tMsTUr8nh1wc= - -snapdragon-node@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" - integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== - dependencies: - define-property "^1.0.0" - isobject "^3.0.0" - snapdragon-util "^3.0.1" - -snapdragon-util@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" - integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== - dependencies: - kind-of "^3.2.0" - -snapdragon@^0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" - integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== - dependencies: - 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" - -source-map-resolve@^0.5.0: - version "0.5.3" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" - integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== - dependencies: - 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@^0.5.16: - version "0.5.16" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042" - integrity sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map-url@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" - integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= - -source-map@^0.5.0, source-map@^0.5.6: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= - -source-map@^0.6.0, source-map@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -spdx-correct@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" - integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q== - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" - integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== - -spdx-expression-parse@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" - integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.5" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz#3694b5804567a458d3c8045842a6358632f62654" - integrity sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q== - -speedometer@~0.1.2: - version "0.1.4" - resolved "https://registry.yarnpkg.com/speedometer/-/speedometer-0.1.4.tgz#9876dbd2a169d3115402d48e6ea6329c8816a50d" - integrity sha1-mHbb0qFp0xFUAtSObqYynIgWpQ0= - -split-on-first@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" - integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw== - -split-string@^3.0.1, split-string@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" - integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== - dependencies: - extend-shallow "^3.0.0" - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - -sshpk@^1.7.0: - version "1.16.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" - integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - -stack-utils@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8" - integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA== - -stacktrace-parser@^0.1.3: - version "0.1.9" - resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.9.tgz#11e6d61d42e8cfc87293143d0766408b7a87b00f" - integrity sha512-DRy03ljj0367Ud3OAJHD6eVS/+CvMK2u/djVYuU37fHYcYHoZ8tkFyhbRf7PNG1h3bWLsw+SNTSXrPFe07A7aQ== - dependencies: - type-fest "^0.7.1" - -staged-git-files@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/staged-git-files/-/staged-git-files-1.1.1.tgz#37c2218ef0d6d26178b1310719309a16a59f8f7b" - integrity sha512-H89UNKr1rQJvI1c/PIR3kiAMBV23yvR7LItZiV74HWZwzt7f3YHuujJ9nJZlt58WlFox7XQsOahexwk7nTe69A== - -static-extend@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" - integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= - dependencies: - define-property "^0.2.5" - object-copy "^0.1.0" - -"statuses@>= 1.5.0 < 2", statuses@~1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= - -stream-buffers@~2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/stream-buffers/-/stream-buffers-2.2.0.tgz#91d5f5130d1cef96dcfa7f726945188741d09ee4" - integrity sha1-kdX1Ew0c75bc+n9yaUUYh0HQnuQ= - -strict-uri-encode@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" - integrity sha1-ucczDHBChi9rFC3CdLvMWGbONUY= - -string-argv@^0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.0.2.tgz#dac30408690c21f3c3630a3ff3a05877bdcbd736" - integrity sha1-2sMECGkMIfPDYwo/86BYd73L1zY= - -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string-width@^3.0.0, string-width@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" - integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== - dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" - -string-width@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" - integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.0" - -string.prototype.matchall@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.2.tgz#48bb510326fb9fdeb6a33ceaa81a6ea04ef7648e" - integrity sha512-N/jp6O5fMf9os0JU3E72Qhf590RSRZU/ungsL/qJUYVTNv7hTG0P/dbPjxINVN9jpscu3nzYwKESU3P3RY5tOg== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0" - has-symbols "^1.0.1" - internal-slot "^1.0.2" - regexp.prototype.flags "^1.3.0" - side-channel "^1.0.2" - -string.prototype.trimleft@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz#9bdb8ac6abd6d602b17a4ed321870d2f8dcefc74" - integrity sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag== - dependencies: - define-properties "^1.1.3" - function-bind "^1.1.1" - -string.prototype.trimright@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz#440314b15996c866ce8a0341894d45186200c5d9" - integrity sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g== - dependencies: - define-properties "^1.1.3" - function-bind "^1.1.1" - -string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" - integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -stringify-object@^3.2.2: - version "3.3.0" - resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" - integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== - dependencies: - get-own-enumerable-property-symbols "^3.0.0" - is-obj "^1.0.1" - is-regexp "^1.0.0" - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= - dependencies: - ansi-regex "^3.0.0" - -strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== - dependencies: - ansi-regex "^4.1.0" - -strip-ansi@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" - integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== - dependencies: - ansi-regex "^5.0.0" - -strip-bom@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" - integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= - dependencies: - is-utf8 "^0.2.0" - -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= - -strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= - -strip-indent@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" - integrity sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI= - dependencies: - get-stdin "^4.0.1" - -strip-indent@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" - integrity sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g= - -strip-json-comments@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.0.1.tgz#85713975a91fb87bf1b305cca77395e40d2a64a7" - integrity sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw== - -strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= - -sudo-prompt@^9.0.0: - version "9.1.1" - resolved "https://registry.yarnpkg.com/sudo-prompt/-/sudo-prompt-9.1.1.tgz#73853d729770392caec029e2470db9c221754db0" - integrity sha512-es33J1g2HjMpyAhz8lOR+ICmXXAqTuKbuXuUWLhOLew20oN9oUCgCJx615U/v7aioZg7IX5lIh9x34vwneu4pA== - -sumchecker@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/sumchecker/-/sumchecker-1.3.1.tgz#79bb3b4456dd04f18ebdbc0d703a1d1daec5105d" - integrity sha1-ebs7RFbdBPGOvbwNcDodHa7FEF0= - dependencies: - debug "^2.2.0" - es6-promise "^4.0.5" - -supports-color@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" - integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.1.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" - integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g== - dependencies: - has-flag "^4.0.0" - -symbol-observable@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4" - integrity sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ= - -symbol-observable@^1.1.0, symbol-observable@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" - integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== - -table@^5.2.3: - version "5.4.6" - resolved "https://registry.yarnpkg.com/table/-/table-5.4.6.tgz#1292d19500ce3f86053b05f0e8e7e4a3bb21079e" - integrity sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug== - dependencies: - ajv "^6.10.2" - lodash "^4.17.14" - slice-ansi "^2.1.0" - string-width "^3.0.0" - -temp@0.8.3: - version "0.8.3" - resolved "https://registry.yarnpkg.com/temp/-/temp-0.8.3.tgz#e0c6bc4d26b903124410e4fed81103014dfc1f59" - integrity sha1-4Ma8TSa5AxJEEOT+2BEDAU38H1k= - dependencies: - os-tmpdir "^1.0.0" - rimraf "~2.2.6" - -term-size@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" - integrity sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk= - dependencies: - execa "^0.7.0" - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= - -throat@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" - integrity sha1-iQN8vJLFarGJJua6TLsgDhVnKmo= - -throttleit@0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-0.0.2.tgz#cfedf88e60c00dd9697b61fdd2a8343a9b680eaf" - integrity sha1-z+34jmDADdlpe2H90qg0OptoDq8= - -through2@^2.0.0, through2@^2.0.1: - version "2.0.5" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" - integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== - dependencies: - readable-stream "~2.3.6" - xtend "~4.0.1" - -through2@~0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/through2/-/through2-0.2.3.tgz#eb3284da4ea311b6cc8ace3653748a52abf25a3f" - integrity sha1-6zKE2k6jEbbMis42U3SKUqvyWj8= - dependencies: - readable-stream "~1.1.9" - xtend "~2.1.1" - -through@^2.3.6: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= - -time-stamp@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" - integrity sha1-dkpaEa9QVhkhsTPztE5hhofg9cM= - -timed-out@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" - integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= - -tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== - dependencies: - os-tmpdir "~1.0.2" - -tmpl@1.0.x: - version "1.0.4" - resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" - integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE= - -to-fast-properties@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" - integrity sha1-uDVx+k2MJbguIxsG46MFXeTKGkc= - -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= - -to-object-path@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" - integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= - dependencies: - kind-of "^3.0.2" - -to-regex-range@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" - integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= - dependencies: - is-number "^3.0.0" - repeat-string "^1.6.1" - -to-regex@^3.0.1, to-regex@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" - integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== - dependencies: - define-property "^2.0.2" - extend-shallow "^3.0.2" - regex-not "^1.0.2" - safe-regex "^1.1.0" - -toidentifier@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" - integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== - -tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - -trim-newlines@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" - integrity sha1-WIeWa7WCpFA6QetST301ARgVphM= - -tslib@^1.8.1, tslib@^1.9.0: - version "1.11.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35" - integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA== - -tsutils@^3.7.0: - version "3.17.1" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" - integrity sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g== - dependencies: - tslib "^1.8.1" - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= - dependencies: - safe-buffer "^5.0.1" - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= - -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= - dependencies: - prelude-ls "~1.1.2" - -type-fest@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.11.0.tgz#97abf0872310fed88a5c466b25681576145e33f1" - integrity sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ== - -type-fest@^0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" - integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== - -type-fest@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" - integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== - -typedarray@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= - -ua-parser-js@^0.7.18: - version "0.7.21" - resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.21.tgz#853cf9ce93f642f67174273cc34565ae6f308777" - integrity sha512-+O8/qh/Qj8CgC6eYBVBykMrNtp5Gebn4dlGD/kKXVkJNDwyrAwSIqwz8CDf+tsAIWVycKcku6gIXJ0qwx/ZXaQ== - -uglify-es@^3.1.9: - version "3.3.9" - resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.9.tgz#0c1c4f0700bed8dbc124cdb304d2592ca203e677" - integrity sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ== - dependencies: - commander "~2.13.0" - source-map "~0.6.1" - -ultron@1.0.x: - version "1.0.2" - resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.0.2.tgz#ace116ab557cd197386a4e88f4685378c8b2e4fa" - integrity sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po= - -ultron@~1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" - integrity sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og== - -unicode-canonical-property-names-ecmascript@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" - integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ== - -unicode-match-property-ecmascript@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" - integrity sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg== - dependencies: - unicode-canonical-property-names-ecmascript "^1.0.4" - unicode-property-aliases-ecmascript "^1.0.4" - -unicode-match-property-value-ecmascript@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz#5b4b426e08d13a80365e0d657ac7a6c1ec46a277" - integrity sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g== - -unicode-property-aliases-ecmascript@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz#a9cc6cc7ce63a0a3023fc99e341b94431d405a57" - integrity sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw== - -union-value@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" - integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== - dependencies: - arr-union "^3.1.0" - get-value "^2.0.6" - is-extendable "^0.1.1" - set-value "^2.0.1" - -unique-string@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" - integrity sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo= - dependencies: - crypto-random-string "^1.0.0" - -universalify@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== - -unpipe@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= - -unset-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" - integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= - dependencies: - has-value "^0.3.1" - isobject "^3.0.0" - -unzip-response@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" - integrity sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c= - -update-notifier@^2.1.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.5.0.tgz#d0744593e13f161e406acb1d9408b72cad08aff6" - integrity sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw== - dependencies: - boxen "^1.2.1" - chalk "^2.0.1" - configstore "^3.0.0" - import-lazy "^2.1.0" - is-ci "^1.0.10" - is-installed-globally "^0.1.0" - is-npm "^1.0.0" - latest-version "^3.0.0" - semver-diff "^2.0.0" - xdg-basedir "^3.0.0" - -uri-js@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" - integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== - dependencies: - punycode "^2.1.0" - -urix@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= - -url-parse-lax@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" - integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM= - dependencies: - prepend-http "^1.0.1" - -use@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" - integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== - -utf8@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" - integrity sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ== - -util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= - -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= - -uuid@^3.3.2: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - -v8-compile-cache@^2.0.3: - version "2.1.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz#e14de37b31a6d194f5690d67efc4e7f6fc6ab30e" - integrity sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g== - -validate-npm-package-license@^3.0.1: - version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" - -vary@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -vlq@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/vlq/-/vlq-1.0.1.tgz#c003f6e7c0b4c1edd623fd6ee50bbc0d6a1de468" - integrity sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w== - -walker@^1.0.7, walker@~1.0.5: - version "1.0.7" - resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" - integrity sha1-L3+bj9ENZ3JisYqITijRlhjgKPs= - dependencies: - makeerror "1.0.x" - -warning@^4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" - integrity sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w== - dependencies: - loose-envify "^1.0.0" - -wcwidth@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" - integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= - dependencies: - defaults "^1.0.3" - -whatwg-fetch@>=0.10.0, whatwg-fetch@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb" - integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q== - -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= - -which@^1.2.10, which@^1.2.9, which@^1.3.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - -widest-line@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc" - integrity sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA== - dependencies: - string-width "^2.1.1" - -word-wrap@~1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== - -wordwrap@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= - -wrap-ansi@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" - integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - -wrap-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-3.0.1.tgz#288a04d87eda5c286e060dfe8f135ce8d007f8ba" - integrity sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo= - dependencies: - string-width "^2.1.1" - strip-ansi "^4.0.0" - -wrap-ansi@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" - integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== - dependencies: - ansi-styles "^3.2.0" - string-width "^3.0.0" - strip-ansi "^5.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= - -write-file-atomic@^1.2.0: - version "1.3.4" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.3.4.tgz#f807a4f0b1d9e913ae7a48112e6cc3af1991b45f" - integrity sha1-+Aek8LHZ6ROuekgRLmzDrxmRtF8= - dependencies: - graceful-fs "^4.1.11" - imurmurhash "^0.1.4" - slide "^1.1.5" - -write-file-atomic@^2.0.0: - version "2.4.3" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.3.tgz#1fd2e9ae1df3e75b8d8c367443c692d4ca81f481" - integrity sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ== - dependencies: - graceful-fs "^4.1.11" - imurmurhash "^0.1.4" - signal-exit "^3.0.2" - -write@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" - integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== - dependencies: - mkdirp "^0.5.1" - -ws@^1.1.0, ws@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/ws/-/ws-1.1.5.tgz#cbd9e6e75e09fc5d2c90015f21f0c40875e0dd51" - integrity sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w== - dependencies: - options ">=0.0.5" - ultron "1.0.x" - -ws@^3.3.1: - version "3.3.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" - integrity sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA== - dependencies: - async-limiter "~1.0.0" - safe-buffer "~5.1.0" - ultron "~1.1.0" - -xcode@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/xcode/-/xcode-2.1.0.tgz#bab64a7e954bb50ca8d19da7e09531c65a43ecfe" - integrity sha512-uCrmPITrqTEzhn0TtT57fJaNaw8YJs1aCzs+P/QqxsDbvPZSv7XMPPwXrKvHtD6pLjBM/NaVwraWJm8q83Y4iQ== - dependencies: - simple-plist "^1.0.0" - uuid "^3.3.2" - -xdg-basedir@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" - integrity sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ= - -xmlbuilder@^9.0.7: - version "9.0.7" - resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" - integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0= - -xmldoc@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/xmldoc/-/xmldoc-1.1.2.tgz#6666e029fe25470d599cd30e23ff0d1ed50466d7" - integrity sha512-ruPC/fyPNck2BD1dpz0AZZyrEwMOrWTO5lDdIXS91rs3wtm4j+T8Rp2o+zoOYkkAxJTZRPOSnOGei1egoRmKMQ== - dependencies: - sax "^1.2.1" - -xmldom@0.1.x: - version "0.1.31" - resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.31.tgz#b76c9a1bd9f0a9737e5a72dc37231cf38375e2ff" - integrity sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ== - -xpipe@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/xpipe/-/xpipe-1.0.5.tgz#8dd8bf45fc3f7f55f0e054b878f43a62614dafdf" - integrity sha1-jdi/Rfw/f1Xw4FS4ePQ6YmFNr98= - -xtend@~2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-2.1.2.tgz#6efecc2a4dad8e6962c4901b337ce7ba87b5d28b" - integrity sha1-bv7MKk2tjmlixJAbM3znuoe10os= - dependencies: - object-keys "~0.4.0" - -xtend@~4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - -y18n@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" - integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= - -"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" - integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== - -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= - -yargs-parser@^11.1.1: - version "11.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4" - integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs-parser@^13.1.1: - version "13.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0" - integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs-parser@^15.0.0: - version "15.0.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-15.0.0.tgz#cdd7a97490ec836195f59f3f4dbe5ea9e8f75f08" - integrity sha512-xLTUnCMc4JhxrPEPUYD5IBR1mWCK/aT6+RJ/K29JY2y1vD+FhtgKK0AXRWvI262q3QSffAQuTouFIKUuHX89wQ== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs-parser@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9" - integrity sha1-jQrELxbqVd69MyyvTEA4s+P139k= - dependencies: - camelcase "^4.1.0" - -yargs@^12.0.5: - version "12.0.5" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" - integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== - dependencies: - cliui "^4.0.0" - decamelize "^1.2.0" - find-up "^3.0.0" - get-caller-file "^1.0.1" - os-locale "^3.0.0" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^2.0.0" - which-module "^2.0.0" - y18n "^3.2.1 || ^4.0.0" - yargs-parser "^11.1.1" - -yargs@^13.2.2: - version "13.3.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.0.tgz#4c657a55e07e5f2cf947f8a366567c04a0dedc83" - integrity sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA== - dependencies: - 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.1" - -yargs@^14.2: - version "14.2.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-14.2.2.tgz#2769564379009ff8597cdd38fba09da9b493c4b5" - integrity sha512-/4ld+4VV5RnrynMhPZJ/ZpOCGSCeghMykZ3BhdFBDa9Wy/RH6uEGNWDJog+aUlq+9OM1CFTgtYRW5Is1Po9NOA== - dependencies: - cliui "^5.0.0" - decamelize "^1.2.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 "^15.0.0" - -yargs@^8.0.2: - version "8.0.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-8.0.2.tgz#6299a9055b1cefc969ff7e79c1d918dceb22c360" - integrity sha1-YpmpBVsc78lp/355wdkY3Osiw2A= - dependencies: - camelcase "^4.1.0" - cliui "^3.2.0" - decamelize "^1.1.1" - get-caller-file "^1.0.1" - os-locale "^2.0.0" - read-pkg-up "^2.0.0" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^2.0.0" - which-module "^2.0.0" - y18n "^3.2.1" - yargs-parser "^7.0.0" - -yargs@^9.0.0: - version "9.0.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-9.0.1.tgz#52acc23feecac34042078ee78c0c007f5085db4c" - integrity sha1-UqzCP+7Kw0BCB47njAwAf1CF20w= - dependencies: - camelcase "^4.1.0" - cliui "^3.2.0" - decamelize "^1.1.1" - get-caller-file "^1.0.1" - os-locale "^2.0.0" - read-pkg-up "^2.0.0" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^2.0.0" - which-module "^2.0.0" - y18n "^3.2.1" - yargs-parser "^7.0.0" - -yauzl@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.4.1.tgz#9528f442dab1b2284e58b4379bb194e22e0c4005" - integrity sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU= - dependencies: - fd-slicer "~1.0.1"